|
- /*
- ==============================================================================
-
- This file is part of the JUCE library - "Jules' Utility Class Extensions"
- Copyright 2004-7 by Raw Material Software ltd.
-
- ------------------------------------------------------------------------------
-
- JUCE can be redistributed and/or modified 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.
-
- JUCE 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 JUCE; if not, visit www.gnu.org/licenses or write to the
- Free Software Foundation, Inc., 59 Temple Place, Suite 330,
- Boston, MA 02111-1307 USA
-
- ------------------------------------------------------------------------------
-
- If you'd like to release a closed-source product which uses JUCE, commercial
- licenses are also available: visit www.rawmaterialsoftware.com/juce for
- more information.
-
- ==============================================================================
- */
-
- /*
- This monolithic file contains the entire Juce source tree!
-
- To build an app which uses Juce, all you need to do is to add this
- file to your project, and include juce.h in your own cpp files.
-
- */
-
- //==============================================================================
- #ifdef _WIN32
-
- /********* Start of inlined file: win32_headers.h *********/
- #ifndef __WIN32_HEADERS_JUCEHEADER__
- #define __WIN32_HEADERS_JUCEHEADER__
-
- #ifndef STRICT
- #define STRICT 1
- #endif
- #define WIN32_LEAN_AND_MEAN
-
- // don't want to get told about microsoft's mistakes..
- #ifdef _MSC_VER
- #pragma warning (push)
- #pragma warning (disable : 4100 4201)
- #endif
-
- // use Platform SDK as win2000 unless this is disabled
- #ifndef DISABLE_TRANSPARENT_WINDOWS
- #define _WIN32_WINNT 0x0500
- #endif
-
- #define _UNICODE 1
- #define UNICODE 1
-
- #include <windows.h>
- #include <commdlg.h>
- #include <shellapi.h>
- #include <mmsystem.h>
- #include <vfw.h>
- #include <tchar.h>
-
- #undef PACKED
-
- #ifdef _MSC_VER
- #pragma warning (pop)
- #endif
-
- #endif // __WIN32_HEADERS_JUCEHEADER__
- /********* End of inlined file: win32_headers.h *********/
-
- #include <winsock2.h>
- #include <mapi.h>
- #include <ctime>
-
- #if JUCE_QUICKTIME
- #include <Movies.h>
- #include <QTML.h>
- #include <QuickTimeComponents.h>
- #include <MediaHandlers.h>
- #include <ImageCodec.h>
- #undef TARGET_OS_MAC // quicktime sets these, but they confuse some of the 3rd party libs
- #undef MACOS
- #endif
-
- #elif defined (LINUX)
-
- #else
- #include <Carbon/Carbon.h>
- #include <CoreAudio/HostTime.h>
- #define __Point__
- #include <IOKit/IOKitLib.h>
- #include <IOKit/graphics/IOGraphicsTypes.h>
- #include <IOKit/network/IOEthernetInterface.h>
- #include <IOKit/network/IONetworkInterface.h>
- #include <IOKit/network/IOEthernetController.h>
- #include <IOKit/IOCFPlugIn.h>
- #include <IOKit/hid/IOHIDLib.h>
- #include <IOKit/hid/IOHIDKeys.h>
-
- #include <sys/filedesc.h>
- #include <sys/time.h>
- #include <sys/proc.h>
- #include <Kernel/libkern/OSTypes.h>
- #endif
-
- //==============================================================================
- #define DONT_SET_USING_JUCE_NAMESPACE 1
-
- #include "juce_amalgamated.h"
-
- #define NO_DUMMY_DECL
-
- #if (defined(_MSC_VER) && (_MSC_VER <= 1200))
- #pragma warning (disable: 4309 4305)
- #endif
-
- //==============================================================================
-
- /********* Start of inlined file: juce_FileLogger.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- FileLogger::FileLogger (const File& logFile_,
- const String& welcomeMessage,
- const int maxInitialFileSizeBytes)
- : logFile (logFile_)
- {
- if (maxInitialFileSizeBytes >= 0)
- trimFileSize (maxInitialFileSizeBytes);
-
- if (! logFile_.exists())
- {
- // do this so that the parent directories get created..
- logFile_.create();
- }
-
- logStream = logFile_.createOutputStream (256);
- jassert (logStream != 0);
-
- String welcome;
- welcome << "\r\n**********************************************************\r\n"
- << welcomeMessage
- << "\r\nLog started: " << Time::getCurrentTime().toString (true, true)
- << "\r\n";
-
- logMessage (welcome);
- }
-
- FileLogger::~FileLogger()
- {
- deleteAndZero (logStream);
- }
-
- void FileLogger::logMessage (const String& message)
- {
- if (logStream != 0)
- {
- Logger::outputDebugString (message);
-
- const ScopedLock sl (logLock);
- (*logStream) << message << T("\r\n");
- logStream->flush();
- }
- }
-
- void FileLogger::trimFileSize (int maxFileSizeBytes) const
- {
- if (maxFileSizeBytes <= 0)
- {
- logFile.deleteFile();
- }
- else
- {
- const int64 fileSize = logFile.getSize();
-
- if (fileSize > maxFileSizeBytes)
- {
- FileInputStream* const in = logFile.createInputStream();
- jassert (in != 0);
-
- if (in != 0)
- {
- in->setPosition (fileSize - maxFileSizeBytes);
- String content;
-
- {
- MemoryBlock contentToSave;
- contentToSave.setSize (maxFileSizeBytes + 4);
- contentToSave.fillWith (0);
-
- in->read (contentToSave.getData(), maxFileSizeBytes);
- delete in;
-
- content = contentToSave.toString();
- }
-
- int newStart = 0;
-
- while (newStart < fileSize
- && content[newStart] != '\n'
- && content[newStart] != '\r')
- ++newStart;
-
- logFile.deleteFile();
- logFile.appendText (content.substring (newStart), false, false);
- }
- }
- }
- }
-
- FileLogger* FileLogger::createDefaultAppLogger (const String& logFileSubDirectoryName,
- const String& logFileName,
- const String& welcomeMessage,
- const int maxInitialFileSizeBytes)
- {
- #if JUCE_MAC
- File logFile ("~/Library/Logs");
- logFile = logFile.getChildFile (logFileName);
-
- #else
- File logFile (File::getSpecialLocation (File::userApplicationDataDirectory));
-
- if (logFile.isDirectory())
- {
- logFile = logFile.getChildFile (logFileSubDirectoryName)
- .getChildFile (logFileName);
- }
- #endif
-
- return new FileLogger (logFile, welcomeMessage, maxInitialFileSizeBytes);
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_FileLogger.cpp *********/
-
- /********* Start of inlined file: juce_Logger.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- Logger::Logger()
- {
- }
-
- Logger::~Logger()
- {
- }
-
- static Logger* currentLogger = 0;
-
- void Logger::setCurrentLogger (Logger* const newLogger,
- const bool deleteOldLogger)
- {
- Logger* const oldLogger = currentLogger;
- currentLogger = newLogger;
-
- if (deleteOldLogger && (oldLogger != 0))
- delete oldLogger;
- }
-
- void Logger::writeToLog (const String& message)
- {
- if (currentLogger != 0)
- currentLogger->logMessage (message);
- else
- outputDebugString (message);
- }
-
- #if JUCE_LOG_ASSERTIONS
- void JUCE_API juce_LogAssertion (const char* filename, const int lineNum) throw()
- {
- String m ("JUCE Assertion failure in ");
- m << filename << ", line " << lineNum;
-
- Logger::writeToLog (m);
- }
- #endif
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_Logger.cpp *********/
-
- /********* Start of inlined file: juce_Random.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- Random::Random (const int64 seedValue) throw()
- : seed (seedValue)
- {
- }
-
- Random::~Random() throw()
- {
- }
-
- void Random::setSeed (const int64 newSeed) throw()
- {
- seed = newSeed;
- }
-
- int Random::nextInt() throw()
- {
- seed = (seed * literal64bit (0x5deece66d) + 11) & literal64bit (0xffffffffffff);
-
- return (int) (seed >> 16);
- }
-
- int Random::nextInt (const int maxValue) throw()
- {
- jassert (maxValue > 0);
- return (nextInt() & 0x7fffffff) % maxValue;
- }
-
- int64 Random::nextInt64() throw()
- {
- return (((int64) nextInt()) << 32) | (int64) (uint64) (uint32) nextInt();
- }
-
- bool Random::nextBool() throw()
- {
- return (nextInt() & 0x80000000) != 0;
- }
-
- float Random::nextFloat() throw()
- {
- return ((uint32) nextInt()) / (float) 0xffffffff;
- }
-
- double Random::nextDouble() throw()
- {
- return ((uint32) nextInt()) / (double) 0xffffffff;
- }
-
- static Random sysRand (1);
-
- Random& Random::getSystemRandom() throw()
- {
- return sysRand;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_Random.cpp *********/
-
- /********* Start of inlined file: juce_RelativeTime.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- RelativeTime::RelativeTime (const double seconds_) throw()
- : seconds (seconds_)
- {
- }
-
- RelativeTime::RelativeTime (const RelativeTime& other) throw()
- : seconds (other.seconds)
- {
- }
-
- RelativeTime::~RelativeTime() throw()
- {
- }
-
- const RelativeTime RelativeTime::milliseconds (const int milliseconds) throw()
- {
- return RelativeTime (milliseconds * 0.001);
- }
-
- const RelativeTime RelativeTime::milliseconds (const int64 milliseconds) throw()
- {
- return RelativeTime (milliseconds * 0.001);
- }
-
- const RelativeTime RelativeTime::minutes (const double numberOfMinutes) throw()
- {
- return RelativeTime (numberOfMinutes * 60.0);
- }
-
- const RelativeTime RelativeTime::hours (const double numberOfHours) throw()
- {
- return RelativeTime (numberOfHours * (60.0 * 60.0));
- }
-
- const RelativeTime RelativeTime::days (const double numberOfDays) throw()
- {
- return RelativeTime (numberOfDays * (60.0 * 60.0 * 24.0));
- }
-
- const RelativeTime RelativeTime::weeks (const double numberOfWeeks) throw()
- {
- return RelativeTime (numberOfWeeks * (60.0 * 60.0 * 24.0 * 7.0));
- }
-
- int64 RelativeTime::inMilliseconds() const throw()
- {
- return (int64)(seconds * 1000.0);
- }
-
- double RelativeTime::inMinutes() const throw()
- {
- return seconds / 60.0;
- }
-
- double RelativeTime::inHours() const throw()
- {
- return seconds / (60.0 * 60.0);
- }
-
- double RelativeTime::inDays() const throw()
- {
- return seconds / (60.0 * 60.0 * 24.0);
- }
-
- double RelativeTime::inWeeks() const throw()
- {
- return seconds / (60.0 * 60.0 * 24.0 * 7.0);
- }
-
- const String RelativeTime::getDescription (const String& returnValueForZeroTime) const throw()
- {
- if (seconds < 0.001 && seconds > -0.001)
- return returnValueForZeroTime;
-
- String result;
-
- if (seconds < 0)
- result = T("-");
-
- int fieldsShown = 0;
- int n = abs ((int) inWeeks());
- if (n > 0)
- {
- result << n << ((n == 1) ? TRANS(" week ")
- : TRANS(" weeks "));
- ++fieldsShown;
- }
-
- n = abs ((int) inDays()) % 7;
- if (n > 0)
- {
- result << n << ((n == 1) ? TRANS(" day ")
- : TRANS(" days "));
- ++fieldsShown;
- }
-
- if (fieldsShown < 2)
- {
- n = abs ((int) inHours()) % 24;
- if (n > 0)
- {
- result << n << ((n == 1) ? TRANS(" hr ")
- : TRANS(" hrs "));
- ++fieldsShown;
- }
-
- if (fieldsShown < 2)
- {
- n = abs ((int) inMinutes()) % 60;
- if (n > 0)
- {
- result << n << ((n == 1) ? TRANS(" min ")
- : TRANS(" mins "));
- ++fieldsShown;
- }
-
- if (fieldsShown < 2)
- {
- n = abs ((int) inSeconds()) % 60;
- if (n > 0)
- {
- result << n << ((n == 1) ? TRANS(" sec ")
- : TRANS(" secs "));
- ++fieldsShown;
- }
-
- if (fieldsShown < 1)
- {
- n = abs ((int) inMilliseconds()) % 1000;
- if (n > 0)
- {
- result << n << TRANS(" ms");
- ++fieldsShown;
- }
- }
- }
- }
- }
-
- return result.trimEnd();
- }
-
- const RelativeTime& RelativeTime::operator= (const RelativeTime& other) throw()
- {
- seconds = other.seconds;
- return *this;
- }
-
- bool RelativeTime::operator== (const RelativeTime& other) const throw()
- {
- return seconds == other.seconds;
- }
-
- bool RelativeTime::operator!= (const RelativeTime& other) const throw()
- {
- return seconds != other.seconds;
- }
-
- bool RelativeTime::operator> (const RelativeTime& other) const throw()
- {
- return seconds > other.seconds;
- }
-
- bool RelativeTime::operator< (const RelativeTime& other) const throw()
- {
- return seconds < other.seconds;
- }
-
- bool RelativeTime::operator>= (const RelativeTime& other) const throw()
- {
- return seconds >= other.seconds;
- }
-
- bool RelativeTime::operator<= (const RelativeTime& other) const throw()
- {
- return seconds <= other.seconds;
- }
-
- const RelativeTime RelativeTime::operator+ (const RelativeTime& timeToAdd) const throw()
- {
- return RelativeTime (seconds + timeToAdd.seconds);
- }
-
- const RelativeTime RelativeTime::operator- (const RelativeTime& timeToSubtract) const throw()
- {
- return RelativeTime (seconds - timeToSubtract.seconds);
- }
-
- const RelativeTime RelativeTime::operator+ (const double secondsToAdd) const throw()
- {
- return RelativeTime (seconds + secondsToAdd);
- }
-
- const RelativeTime RelativeTime::operator- (const double secondsToSubtract) const throw()
- {
- return RelativeTime (seconds - secondsToSubtract);
- }
-
- const RelativeTime& RelativeTime::operator+= (const RelativeTime& timeToAdd) throw()
- {
- seconds += timeToAdd.seconds;
- return *this;
- }
-
- const RelativeTime& RelativeTime::operator-= (const RelativeTime& timeToSubtract) throw()
- {
- seconds -= timeToSubtract.seconds;
- return *this;
- }
-
- const RelativeTime& RelativeTime::operator+= (const double secondsToAdd) throw()
- {
- seconds += secondsToAdd;
- return *this;
- }
-
- const RelativeTime& RelativeTime::operator-= (const double secondsToSubtract) throw()
- {
- seconds -= secondsToSubtract;
- return *this;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_RelativeTime.cpp *********/
-
- /********* Start of inlined file: juce_SystemStats.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- void juce_initialiseStrings();
-
- const String SystemStats::getJUCEVersion() throw()
- {
- return "JUCE v" + String (JUCE_MAJOR_VERSION) + "." + String (JUCE_MINOR_VERSION);
- }
-
- static bool juceInitialisedNonGUI = false;
-
- void JUCE_PUBLIC_FUNCTION initialiseJuce_NonGUI()
- {
- if (! juceInitialisedNonGUI)
- {
- #ifdef JUCE_DEBUG
- // Some simple test code to keep an eye on things and make sure these functions
- // work ok on all platforms. Let me know if any of these assertions fail!
- int n = 1;
- atomicIncrement (n);
- jassert (atomicIncrementAndReturn (n) == 3);
- atomicDecrement (n);
- jassert (atomicDecrementAndReturn (n) == 1);
-
- jassert (swapByteOrder ((uint32) 0x11223344) == 0x44332211);
-
- // quick test to make sure the run-time lib doesn't crash on freeing a null-pointer.
- SystemStats* nullPointer = 0;
- juce_free (nullPointer);
- delete[] nullPointer;
- delete nullPointer;
- #endif
- // Now the real initialisation..
-
- juceInitialisedNonGUI = true;
-
- DBG (SystemStats::getJUCEVersion());
- juce_initialiseStrings();
- SystemStats::initialiseStats();
- Random::getSystemRandom().setSeed (Time::currentTimeMillis());
- }
- }
-
- #if JUCE_WIN32
- // This is imported from the sockets code..
- typedef int (__stdcall juce_CloseWin32SocketLibCall) (void);
- extern juce_CloseWin32SocketLibCall* juce_CloseWin32SocketLib;
- #endif
-
- #if JUCE_DEBUG
- extern void juce_CheckForDanglingStreams();
- #endif
-
- void JUCE_PUBLIC_FUNCTION shutdownJuce_NonGUI()
- {
- if (juceInitialisedNonGUI)
- {
- #if JUCE_WIN32
- // need to shut down sockets if they were used..
- if (juce_CloseWin32SocketLib != 0)
- (*juce_CloseWin32SocketLib)();
- #endif
-
- LocalisedStrings::setCurrentMappings (0);
- Thread::stopAllThreads (3000);
-
- #if JUCE_DEBUG
- juce_CheckForDanglingStreams();
- #endif
-
- juceInitialisedNonGUI = false;
- }
- }
-
- #ifdef JUCE_DLL
-
- void* juce_Malloc (const int size)
- {
- return malloc (size);
- }
-
- void* juce_Calloc (const int size)
- {
- return calloc (1, size);
- }
-
- void* juce_Realloc (void* const block, const int size)
- {
- return realloc (block, size);
- }
-
- void juce_Free (void* const block)
- {
- free (block);
- }
-
- #if defined (JUCE_DEBUG) && JUCE_MSVC && JUCE_CHECK_MEMORY_LEAKS
-
- void* juce_DebugMalloc (const int size, const char* file, const int line)
- {
- return _malloc_dbg (size, _NORMAL_BLOCK, file, line);
- }
-
- void* juce_DebugCalloc (const int size, const char* file, const int line)
- {
- return _calloc_dbg (1, size, _NORMAL_BLOCK, file, line);
- }
-
- void* juce_DebugRealloc (void* const block, const int size, const char* file, const int line)
- {
- return _realloc_dbg (block, size, _NORMAL_BLOCK, file, line);
- }
-
- void juce_DebugFree (void* const block)
- {
- _free_dbg (block, _NORMAL_BLOCK);
- }
-
- #endif
- #endif
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_SystemStats.cpp *********/
-
- /********* Start of inlined file: juce_Time.cpp *********/
- #ifdef _MSC_VER
- #pragma warning (disable: 4514)
- #pragma warning (push)
- #endif
-
- #ifndef JUCE_WIN32
- #include <sys/time.h>
- #else
- #include <ctime>
- #endif
-
- #include <sys/timeb.h>
-
- BEGIN_JUCE_NAMESPACE
-
- #ifdef _MSC_VER
- #pragma warning (pop)
-
- #ifdef _INC_TIME_INL
- #define USE_NEW_SECURE_TIME_FNS
- #endif
- #endif
-
- static void millisToLocal (const int64 millis, struct tm& result) throw()
- {
- const int64 seconds = millis / 1000;
-
- if (seconds < literal64bit (86400) || seconds >= literal64bit (2145916800))
- {
- // use extended maths for dates beyond 1970 to 2037..
- const int timeZoneAdjustment = 31536000 - (int) (Time (1971, 0, 1, 0, 0).toMilliseconds() / 1000);
- const int64 jdm = seconds + timeZoneAdjustment + literal64bit (210866803200);
-
- const int days = (int) (jdm / literal64bit (86400));
- const int a = 32044 + days;
- const int b = (4 * a + 3) / 146097;
- const int c = a - (b * 146097) / 4;
- const int d = (4 * c + 3) / 1461;
- const int e = c - (d * 1461) / 4;
- const int m = (5 * e + 2) / 153;
-
- result.tm_mday = e - (153 * m + 2) / 5 + 1;
- result.tm_mon = m + 2 - 12 * (m / 10);
- result.tm_year = b * 100 + d - 6700 + (m / 10);
- result.tm_wday = (days + 1) % 7;
- result.tm_yday = -1;
-
- int t = (int) (jdm % literal64bit (86400));
- result.tm_hour = t / 3600;
- t %= 3600;
- result.tm_min = t / 60;
- result.tm_sec = t % 60;
- result.tm_isdst = -1;
- }
- else
- {
- time_t now = (time_t) (seconds);
-
- #if JUCE_WIN32
- #ifdef USE_NEW_SECURE_TIME_FNS
- if (now >= 0 && now <= 0x793406fff)
- localtime_s (&result, &now);
- else
- zeromem (&result, sizeof (result));
- #else
- result = *localtime (&now);
- #endif
- #else
- // more thread-safe
- localtime_r (&now, &result);
- #endif
- }
- }
-
- Time::Time() throw()
- : millisSinceEpoch (0)
- {
- }
-
- Time::Time (const Time& other) throw()
- : millisSinceEpoch (other.millisSinceEpoch)
- {
- }
-
- Time::Time (const int64 ms) throw()
- : millisSinceEpoch (ms)
- {
- }
-
- Time::Time (const int year,
- const int month,
- const int day,
- const int hours,
- const int minutes,
- const int seconds,
- const int milliseconds,
- const bool useLocalTime) throw()
- {
- jassert (year > 100); // year must be a 4-digit version
-
- if (year < 1971 || year >= 2038 || ! useLocalTime)
- {
- // use extended maths for dates beyond 1970 to 2037..
- const int timeZoneAdjustment = useLocalTime ? (31536000 - (int) (Time (1971, 0, 1, 0, 0).toMilliseconds() / 1000))
- : 0;
- const int a = (13 - month) / 12;
- const int y = year + 4800 - a;
- const int jd = day + (153 * (month + 12 * a - 2) + 2) / 5
- + (y * 365) + (y / 4) - (y / 100) + (y / 400)
- - 32045;
-
- const int64 s = ((int64) jd) * literal64bit (86400) - literal64bit (210866803200);
-
- millisSinceEpoch = 1000 * (s + (hours * 3600 + minutes * 60 + seconds - timeZoneAdjustment))
- + milliseconds;
- }
- else
- {
- struct tm t;
- t.tm_year = year - 1900;
- t.tm_mon = month;
- t.tm_mday = day;
- t.tm_hour = hours;
- t.tm_min = minutes;
- t.tm_sec = seconds;
- t.tm_isdst = -1;
-
- millisSinceEpoch = 1000 * (int64) mktime (&t);
-
- if (millisSinceEpoch < 0)
- millisSinceEpoch = 0;
- else
- millisSinceEpoch += milliseconds;
- }
- }
-
- Time::~Time() throw()
- {
- }
-
- const Time& Time::operator= (const Time& other) throw()
- {
- millisSinceEpoch = other.millisSinceEpoch;
- return *this;
- }
-
- int64 Time::currentTimeMillis() throw()
- {
- static uint32 lastCounterResult = 0xffffffff;
- static int64 correction = 0;
-
- const uint32 now = getMillisecondCounter();
-
- // check the counter hasn't wrapped (also triggered the first time this function is called)
- if (now < lastCounterResult)
- {
- // double-check it's actually wrapped, in case multi-cpu machines have timers that drift a bit.
- if (lastCounterResult == 0xffffffff || now < lastCounterResult - 10)
- {
- // get the time once using normal library calls, and store the difference needed to
- // turn the millisecond counter into a real time.
- #if JUCE_WIN32
- struct _timeb t;
- #ifdef USE_NEW_SECURE_TIME_FNS
- _ftime_s (&t);
- #else
- _ftime (&t);
- #endif
- correction = (((int64) t.time) * 1000 + t.millitm) - now;
- #else
- struct timeval tv;
- struct timezone tz;
- gettimeofday (&tv, &tz);
- correction = (((int64) tv.tv_sec) * 1000 + tv.tv_usec / 1000) - now;
- #endif
- }
- }
-
- lastCounterResult = now;
-
- return correction + now;
- }
-
- uint32 juce_millisecondsSinceStartup() throw();
- static uint32 lastMSCounterValue = 0;
-
- uint32 Time::getMillisecondCounter() throw()
- {
- const uint32 now = juce_millisecondsSinceStartup();
-
- if (now < lastMSCounterValue)
- {
- // in multi-threaded apps this might be called concurrently, so
- // make sure that our last counter value only increases and doesn't
- // go backwards..
- if (now < lastMSCounterValue - 1000)
- lastMSCounterValue = now;
- }
- else
- {
- lastMSCounterValue = now;
- }
-
- return now;
- }
-
- uint32 Time::getApproximateMillisecondCounter() throw()
- {
- jassert (lastMSCounterValue != 0);
- return lastMSCounterValue;
- }
-
- void Time::waitForMillisecondCounter (const uint32 targetTime) throw()
- {
- for (;;)
- {
- const uint32 now = getMillisecondCounter();
-
- if (now >= targetTime)
- break;
-
- const int toWait = targetTime - now;
-
- if (toWait > 2)
- {
- Thread::sleep (jmin (20, toWait >> 1));
- }
- else
- {
- // xxx should consider using mutex_pause on the mac as it apparently
- // makes it seem less like a spinlock and avoids lowering the thread pri.
- for (int i = 10; --i >= 0;)
- Thread::yield();
- }
- }
- }
-
- double Time::highResolutionTicksToSeconds (const int64 ticks) throw()
- {
- return ticks / (double) getHighResolutionTicksPerSecond();
- }
-
- int64 Time::secondsToHighResolutionTicks (const double seconds) throw()
- {
- return (int64) (seconds * (double) getHighResolutionTicksPerSecond());
- }
-
- const Time JUCE_CALLTYPE Time::getCurrentTime() throw()
- {
- return Time (currentTimeMillis());
- }
-
- const String Time::toString (const bool includeDate,
- const bool includeTime,
- const bool includeSeconds,
- const bool use24HourClock) const throw()
- {
- String result;
-
- if (includeDate)
- {
- result << getDayOfMonth() << ' '
- << getMonthName (true) << ' '
- << getYear();
-
- if (includeTime)
- result << ' ';
- }
-
- if (includeTime)
- {
- if (includeSeconds)
- {
- result += String::formatted (T("%d:%02d:%02d "),
- (use24HourClock) ? getHours()
- : getHoursInAmPmFormat(),
- getMinutes(),
- getSeconds());
- }
- else
- {
- result += String::formatted (T("%d.%02d"),
- (use24HourClock) ? getHours()
- : getHoursInAmPmFormat(),
- getMinutes());
- }
-
- if (! use24HourClock)
- result << (isAfternoon() ? "pm" : "am");
- }
-
- return result.trimEnd();
- }
-
- const String Time::formatted (const tchar* const format) const throw()
- {
- tchar buffer[80];
-
- struct tm t;
- millisToLocal (millisSinceEpoch, t);
-
- if (CharacterFunctions::ftime (buffer, 79, format, &t) <= 0)
- {
- int bufferSize = 128;
-
- for (;;)
- {
- MemoryBlock mb (bufferSize * sizeof (tchar));
- tchar* const b = (tchar*) mb.getData();
-
- if (CharacterFunctions::ftime (b, bufferSize, format, &t) > 0)
- return String (b);
-
- bufferSize += 128;
- }
- }
-
- return String (buffer);
- }
-
- int Time::getYear() const throw()
- {
- struct tm t;
- millisToLocal (millisSinceEpoch, t);
- return t.tm_year + 1900;
- }
-
- int Time::getMonth() const throw()
- {
- struct tm t;
- millisToLocal (millisSinceEpoch, t);
- return t.tm_mon;
- }
-
- int Time::getDayOfMonth() const throw()
- {
- struct tm t;
- millisToLocal (millisSinceEpoch, t);
- return t.tm_mday;
- }
-
- int Time::getDayOfWeek() const throw()
- {
- struct tm t;
- millisToLocal (millisSinceEpoch, t);
- return t.tm_wday;
- }
-
- int Time::getHours() const throw()
- {
- struct tm t;
- millisToLocal (millisSinceEpoch, t);
- return t.tm_hour;
- }
-
- int Time::getHoursInAmPmFormat() const throw()
- {
- const int hours = getHours();
-
- if (hours == 0)
- return 12;
- else if (hours <= 12)
- return hours;
- else
- return hours - 12;
- }
-
- bool Time::isAfternoon() const throw()
- {
- return getHours() >= 12;
- }
-
- static int extendedModulo (const int64 value, const int modulo) throw()
- {
- return (int) (value >= 0 ? (value % modulo)
- : (value - ((value / modulo) + 1) * modulo));
- }
-
- int Time::getMinutes() const throw()
- {
- return extendedModulo (millisSinceEpoch / 60000, 60);
- }
-
- int Time::getSeconds() const throw()
- {
- return extendedModulo (millisSinceEpoch / 1000, 60);
- }
-
- int Time::getMilliseconds() const throw()
- {
- return extendedModulo (millisSinceEpoch, 1000);
- }
-
- bool Time::isDaylightSavingTime() const throw()
- {
- struct tm t;
- millisToLocal (millisSinceEpoch, t);
- return t.tm_isdst != 0;
- }
-
- const String Time::getTimeZone() const throw()
- {
- String zone[2];
-
- #if JUCE_WIN32
- _tzset();
-
- #ifdef USE_NEW_SECURE_TIME_FNS
- {
- char name [128];
- size_t length;
-
- for (int i = 0; i < 2; ++i)
- {
- zeromem (name, sizeof (name));
- _get_tzname (&length, name, 127, i);
- zone[i] = name;
- }
- }
- #else
- const char** const zonePtr = (const char**) _tzname;
- zone[0] = zonePtr[0];
- zone[1] = zonePtr[1];
- #endif
- #else
- tzset();
- const char** const zonePtr = (const char**) tzname;
- zone[0] = zonePtr[0];
- zone[1] = zonePtr[1];
- #endif
-
- if (isDaylightSavingTime())
- {
- zone[0] = zone[1];
-
- if (zone[0].length() > 3
- && zone[0].containsIgnoreCase (T("daylight"))
- && zone[0].contains (T("GMT")))
- zone[0] = "BST";
- }
-
- return zone[0].substring (0, 3);
- }
-
- const String Time::getMonthName (const bool threeLetterVersion) const throw()
- {
- return getMonthName (getMonth(), threeLetterVersion);
- }
-
- const String Time::getWeekdayName (const bool threeLetterVersion) const throw()
- {
- return getWeekdayName (getDayOfWeek(), threeLetterVersion);
- }
-
- const String Time::getMonthName (int monthNumber,
- const bool threeLetterVersion) throw()
- {
- const char* const shortMonthNames[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
- const char* const longMonthNames[] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" };
-
- monthNumber %= 12;
-
- return TRANS (threeLetterVersion ? shortMonthNames [monthNumber]
- : longMonthNames [monthNumber]);
- }
-
- const String Time::getWeekdayName (int day,
- const bool threeLetterVersion) throw()
- {
- const char* const shortDayNames[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
- const char* const longDayNames[] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };
-
- day %= 7;
-
- return TRANS (threeLetterVersion ? shortDayNames [day]
- : longDayNames [day]);
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_Time.cpp *********/
-
- /********* Start of inlined file: juce_BitArray.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- BitArray::BitArray() throw()
- : numValues (4),
- highestBit (-1),
- negative (false)
- {
- values = (unsigned int*) juce_calloc (sizeof (unsigned int) * (numValues + 1));
- }
-
- BitArray::BitArray (const int value) throw()
- : numValues (4),
- highestBit (31),
- negative (value < 0)
- {
- values = (unsigned int*) juce_calloc (sizeof (unsigned int) * (numValues + 1));
- values[0] = abs (value);
- highestBit = getHighestBit();
- }
-
- BitArray::BitArray (int64 value) throw()
- : numValues (4),
- highestBit (63),
- negative (value < 0)
- {
- values = (unsigned int*) juce_calloc (sizeof (unsigned int) * (numValues + 1));
-
- if (value < 0)
- value = -value;
-
- values[0] = (unsigned int) value;
- values[1] = (unsigned int) (value >> 32);
- highestBit = getHighestBit();
- }
-
- BitArray::BitArray (const unsigned int value) throw()
- : numValues (4),
- highestBit (31),
- negative (false)
- {
- values = (unsigned int*) juce_calloc (sizeof (unsigned int) * (numValues + 1));
- values[0] = value;
- highestBit = getHighestBit();
- }
-
- BitArray::BitArray (const BitArray& other) throw()
- : numValues (jmax (4, (other.highestBit >> 5) + 1)),
- highestBit (other.getHighestBit()),
- negative (other.negative)
- {
- const int bytes = sizeof (unsigned int) * (numValues + 1);
- values = (unsigned int*) juce_malloc (bytes);
- memcpy (values, other.values, bytes);
- }
-
- BitArray::~BitArray() throw()
- {
- juce_free (values);
- }
-
- const BitArray& BitArray::operator= (const BitArray& other) throw()
- {
- if (this != &other)
- {
- juce_free (values);
-
- highestBit = other.getHighestBit();
- numValues = jmax (4, (highestBit >> 5) + 1);
- negative = other.negative;
- const int memSize = sizeof (unsigned int) * (numValues + 1);
- values = (unsigned int*)juce_malloc (memSize);
- memcpy (values, other.values, memSize);
- }
-
- return *this;
- }
-
- // result == 0 = the same
- // result < 0 = this number is smaller
- // result > 0 = this number is bigger
- int BitArray::compare (const BitArray& other) const throw()
- {
- if (isNegative() == other.isNegative())
- {
- const int absComp = compareAbsolute (other);
- return isNegative() ? -absComp : absComp;
- }
- else
- {
- return isNegative() ? -1 : 1;
- }
- }
-
- int BitArray::compareAbsolute (const BitArray& other) const throw()
- {
- const int h1 = getHighestBit();
- const int h2 = other.getHighestBit();
-
- if (h1 > h2)
- return 1;
- else if (h1 < h2)
- return -1;
-
- for (int i = (h1 >> 5) + 1; --i >= 0;)
- if (values[i] != other.values[i])
- return (values[i] > other.values[i]) ? 1 : -1;
-
- return 0;
- }
-
- bool BitArray::operator== (const BitArray& other) const throw()
- {
- return compare (other) == 0;
- }
-
- bool BitArray::operator!= (const BitArray& other) const throw()
- {
- return compare (other) != 0;
- }
-
- bool BitArray::operator[] (const int bit) const throw()
- {
- return bit >= 0 && bit <= highestBit
- && ((values [bit >> 5] & (1 << (bit & 31))) != 0);
- }
-
- bool BitArray::isEmpty() const throw()
- {
- return getHighestBit() < 0;
- }
-
- void BitArray::clear() throw()
- {
- if (numValues > 16)
- {
- juce_free (values);
- numValues = 4;
- values = (unsigned int*) juce_calloc (sizeof (unsigned int) * (numValues + 1));
- }
- else
- {
- zeromem (values, sizeof (unsigned int) * (numValues + 1));
- }
-
- highestBit = -1;
- negative = false;
- }
-
- void BitArray::setBit (const int bit) throw()
- {
- if (bit >= 0)
- {
- if (bit > highestBit)
- {
- ensureSize (bit >> 5);
- highestBit = bit;
- }
-
- values [bit >> 5] |= (1 << (bit & 31));
- }
- }
-
- void BitArray::setBit (const int bit,
- const bool shouldBeSet) throw()
- {
- if (shouldBeSet)
- setBit (bit);
- else
- clearBit (bit);
- }
-
- void BitArray::clearBit (const int bit) throw()
- {
- if (bit >= 0 && bit <= highestBit)
- values [bit >> 5] &= ~(1 << (bit & 31));
- }
-
- void BitArray::setRange (int startBit,
- int numBits,
- const bool shouldBeSet) throw()
- {
- while (--numBits >= 0)
- setBit (startBit++, shouldBeSet);
- }
-
- void BitArray::insertBit (const int bit,
- const bool shouldBeSet) throw()
- {
- if (bit >= 0)
- shiftBits (1, bit);
-
- setBit (bit, shouldBeSet);
- }
-
- void BitArray::andWith (const BitArray& other) throw()
- {
- // this operation will only work with the absolute values
- jassert (isNegative() == other.isNegative());
-
- int n = numValues;
-
- while (n > other.numValues)
- values[--n] = 0;
-
- while (--n >= 0)
- values[n] &= other.values[n];
-
- if (other.highestBit < highestBit)
- highestBit = other.highestBit;
-
- highestBit = getHighestBit();
- }
-
- void BitArray::orWith (const BitArray& other) throw()
- {
- if (other.highestBit < 0)
- return;
-
- // this operation will only work with the absolute values
- jassert (isNegative() == other.isNegative());
-
- ensureSize (other.highestBit >> 5);
-
- int n = (other.highestBit >> 5) + 1;
-
- while (--n >= 0)
- values[n] |= other.values[n];
-
- if (other.highestBit > highestBit)
- highestBit = other.highestBit;
-
- highestBit = getHighestBit();
- }
-
- void BitArray::xorWith (const BitArray& other) throw()
- {
- if (other.highestBit < 0)
- return;
-
- // this operation will only work with the absolute values
- jassert (isNegative() == other.isNegative());
-
- ensureSize (other.highestBit >> 5);
-
- int n = (other.highestBit >> 5) + 1;
-
- while (--n >= 0)
- values[n] ^= other.values[n];
-
- if (other.highestBit > highestBit)
- highestBit = other.highestBit;
-
- highestBit = getHighestBit();
- }
-
- void BitArray::add (const BitArray& other) throw()
- {
- if (other.isNegative())
- {
- BitArray o (other);
- o.negate();
- subtract (o);
- return;
- }
-
- if (isNegative())
- {
- if (compareAbsolute (other) < 0)
- {
- BitArray temp (*this);
- temp.negate();
- *this = other;
- subtract (temp);
- }
- else
- {
- negate();
- subtract (other);
- negate();
- }
-
- return;
- }
-
- if (other.highestBit > highestBit)
- highestBit = other.highestBit;
-
- ++highestBit;
-
- const int numInts = (highestBit >> 5) + 1;
- ensureSize (numInts);
-
- int64 remainder = 0;
-
- for (int i = 0; i <= numInts; ++i)
- {
- if (i < numValues)
- remainder += values[i];
-
- if (i < other.numValues)
- remainder += other.values[i];
-
- values[i] = (unsigned int) remainder;
- remainder >>= 32;
- }
-
- jassert (remainder == 0);
- highestBit = getHighestBit();
- }
-
- void BitArray::subtract (const BitArray& other) throw()
- {
- if (other.isNegative())
- {
- BitArray o (other);
- o.negate();
- add (o);
- return;
- }
-
- if (! isNegative())
- {
- if (compareAbsolute (other) < 0)
- {
- BitArray temp (*this);
- *this = other;
- subtract (temp);
- negate();
- return;
- }
- }
- else
- {
- negate();
- add (other);
- negate();
- return;
- }
-
- const int numInts = (highestBit >> 5) + 1;
- const int maxOtherInts = (other.highestBit >> 5) + 1;
- int64 amountToSubtract = 0;
-
- for (int i = 0; i <= numInts; ++i)
- {
- if (i <= maxOtherInts)
- amountToSubtract += (int64)other.values[i];
-
- if (values[i] >= amountToSubtract)
- {
- values[i] = (unsigned int) (values[i] - amountToSubtract);
- amountToSubtract = 0;
- }
- else
- {
- const int64 n = ((int64) values[i] + (((int64) 1) << 32)) - amountToSubtract;
- values[i] = (unsigned int) n;
- amountToSubtract = 1;
- }
- }
- }
-
- void BitArray::multiplyBy (const BitArray& other) throw()
- {
- BitArray total;
- highestBit = getHighestBit();
- const bool wasNegative = isNegative();
- setNegative (false);
-
- for (int i = 0; i <= highestBit; ++i)
- {
- if (operator[](i))
- {
- BitArray n (other);
- n.setNegative (false);
- n.shiftBits (i);
- total.add (n);
- }
- }
-
- *this = total;
- negative = wasNegative ^ other.isNegative();
- }
-
- void BitArray::divideBy (const BitArray& divisor, BitArray& remainder) throw()
- {
- jassert (this != &remainder); // (can't handle passing itself in to get the remainder)
-
- const int divHB = divisor.getHighestBit();
- const int ourHB = getHighestBit();
-
- if (divHB < 0 || ourHB < 0)
- {
- // division by zero
- remainder.clear();
- clear();
- }
- else
- {
- remainder = *this;
- remainder.setNegative (false);
- const bool wasNegative = isNegative();
- clear();
-
- BitArray temp (divisor);
- temp.setNegative (false);
-
- int leftShift = ourHB - divHB;
- temp.shiftBits (leftShift);
-
- while (leftShift >= 0)
- {
- if (remainder.compareAbsolute (temp) >= 0)
- {
- remainder.subtract (temp);
- setBit (leftShift);
- }
-
- if (--leftShift >= 0)
- temp.shiftBits (-1);
- }
-
- negative = wasNegative ^ divisor.isNegative();
- remainder.setNegative (wasNegative);
- }
- }
-
- void BitArray::modulo (const BitArray& divisor) throw()
- {
- BitArray remainder;
- divideBy (divisor, remainder);
- *this = remainder;
- }
-
- static const BitArray simpleGCD (BitArray* m, BitArray* n) throw()
- {
- while (! m->isEmpty())
- {
- if (n->compareAbsolute (*m) > 0)
- swapVariables (m, n);
-
- m->subtract (*n);
- }
-
- return *n;
- }
-
- const BitArray BitArray::findGreatestCommonDivisor (BitArray n) const throw()
- {
- BitArray m (*this);
-
- while (! n.isEmpty())
- {
- if (abs (m.getHighestBit() - n.getHighestBit()) <= 16)
- return simpleGCD (&m, &n);
-
- BitArray temp1 (m), temp2;
- temp1.divideBy (n, temp2);
-
- m = n;
- n = temp2;
- }
-
- return m;
- }
-
- void BitArray::exponentModulo (const BitArray& exponent,
- const BitArray& modulus) throw()
- {
- BitArray exp (exponent);
- exp.modulo (modulus);
-
- BitArray value (*this);
- value.modulo (modulus);
-
- clear();
- setBit (0);
-
- while (! exp.isEmpty())
- {
- if (exp [0])
- {
- multiplyBy (value);
- this->modulo (modulus);
- }
-
- value.multiplyBy (value);
- value.modulo (modulus);
-
- exp.shiftBits (-1);
- }
- }
-
- void BitArray::inverseModulo (const BitArray& modulus) throw()
- {
- const BitArray one (1);
-
- if (modulus == one || modulus.isNegative())
- {
- clear();
- return;
- }
-
- if (isNegative() || compareAbsolute (modulus) >= 0)
- this->modulo (modulus);
-
- if (*this == one)
- return;
-
- if (! (*this)[0])
- {
- // not invertible
- clear();
- return;
- }
-
- BitArray a1 (modulus);
- BitArray a2 (*this);
- BitArray b1 (modulus);
- BitArray b2 (1);
-
- while (a2 != one)
- {
- BitArray temp1, temp2, multiplier (a1);
- multiplier.divideBy (a2, temp1);
-
- temp1 = a2;
- temp1.multiplyBy (multiplier);
- temp2 = a1;
- temp2.subtract (temp1);
- a1 = a2;
- a2 = temp2;
-
- temp1 = b2;
- temp1.multiplyBy (multiplier);
- temp2 = b1;
- temp2.subtract (temp1);
- b1 = b2;
- b2 = temp2;
- }
-
- while (b2.isNegative())
- b2.add (modulus);
-
- b2.modulo (modulus);
- *this = b2;
- }
-
- void BitArray::shiftBits (int bits, const int startBit) throw()
- {
- if (highestBit < 0)
- return;
-
- if (startBit > 0)
- {
- if (bits < 0)
- {
- // right shift
- for (int i = startBit; i <= highestBit; ++i)
- setBit (i, operator[] (i - bits));
-
- highestBit = getHighestBit();
- }
- else if (bits > 0)
- {
- // left shift
- for (int i = highestBit + 1; --i >= startBit;)
- setBit (i + bits, operator[] (i));
-
- while (--bits >= 0)
- clearBit (bits + startBit);
- }
- }
- else
- {
- if (bits < 0)
- {
- // right shift
- bits = -bits;
-
- if (bits > highestBit)
- {
- clear();
- }
- else
- {
- const int wordsToMove = bits >> 5;
- int top = 1 + (highestBit >> 5) - wordsToMove;
- highestBit -= bits;
-
- if (wordsToMove > 0)
- {
- int i;
- for (i = 0; i < top; ++i)
- values [i] = values [i + wordsToMove];
-
- for (i = 0; i < wordsToMove; ++i)
- values [top + i] = 0;
-
- bits &= 31;
- }
-
- if (bits != 0)
- {
- const int invBits = 32 - bits;
-
- --top;
- for (int i = 0; i < top; ++i)
- values[i] = (values[i] >> bits) | (values [i + 1] << invBits);
-
- values[top] = (values[top] >> bits);
- }
-
- highestBit = getHighestBit();
- }
- }
- else if (bits > 0)
- {
- // left shift
- ensureSize (((highestBit + bits) >> 5) + 1);
-
- const int wordsToMove = bits >> 5;
- int top = 1 + (highestBit >> 5);
- highestBit += bits;
-
- if (wordsToMove > 0)
- {
- int i;
- for (i = top; --i >= 0;)
- values [i + wordsToMove] = values [i];
-
- for (i = 0; i < wordsToMove; ++i)
- values [i] = 0;
-
- bits &= 31;
- }
-
- if (bits != 0)
- {
- const int invBits = 32 - bits;
-
- for (int i = top + 1 + wordsToMove; --i > wordsToMove;)
- values[i] = (values[i] << bits) | (values [i - 1] >> invBits);
-
- values [wordsToMove] = values [wordsToMove] << bits;
- }
-
- highestBit = getHighestBit();
- }
- }
- }
-
- int BitArray::getBitRangeAsInt (const int startBit, int numBits) const throw()
- {
- if (numBits > 32)
- {
- jassertfalse
- numBits = 32;
- }
-
- if (startBit == 0)
- {
- if (numBits < 32)
- return values[0] & ((1 << numBits) - 1);
-
- return values[0];
- }
-
- int n = 0;
- for (int i = numBits; --i >= 0;)
- {
- n <<= 1;
-
- if (operator[] (startBit + i))
- n |= 1;
- }
-
- return n;
- }
-
- void BitArray::setBitRangeAsInt (const int startBit, int numBits, unsigned int valueToSet) throw()
- {
- if (numBits > 32)
- {
- jassertfalse
- numBits = 32;
- }
-
- for (int i = 0; i < numBits; ++i)
- {
- setBit (startBit + i, (valueToSet & 1) != 0);
- valueToSet >>= 1;
- }
- }
-
- void BitArray::fillBitsRandomly (int startBit, int numBits) throw()
- {
- highestBit = jmax (highestBit, startBit + numBits);
- ensureSize (((startBit + numBits) >> 5) + 1);
-
- while ((startBit & 31) != 0 && numBits > 0)
- {
- setBit (startBit++, Random::getSystemRandom().nextBool());
-
- --numBits;
- }
-
- while (numBits >= 32)
- {
- values [startBit >> 5] = (unsigned int) Random::getSystemRandom().nextInt();
-
- startBit += 32;
- numBits -= 32;
- }
-
- while (--numBits >= 0)
- {
- setBit (startBit + numBits, Random::getSystemRandom().nextBool());
- }
-
- highestBit = getHighestBit();
- }
-
- void BitArray::createRandomNumber (const BitArray& maximumValue) throw()
- {
- clear();
-
- do
- {
- fillBitsRandomly (0, maximumValue.getHighestBit() + 1);
- }
- while (compare (maximumValue) >= 0);
- }
-
- bool BitArray::isNegative() const throw()
- {
- return negative && ! isEmpty();
- }
-
- void BitArray::setNegative (const bool neg) throw()
- {
- negative = neg;
- }
-
- void BitArray::negate() throw()
- {
- negative = (! negative) && ! isEmpty();
- }
-
- int BitArray::countNumberOfSetBits() const throw()
- {
- int total = 0;
-
- for (int i = (highestBit >> 5) + 1; --i >= 0;)
- {
- unsigned int n = values[i];
-
- if (n == 0xffffffff)
- {
- total += 32;
- }
- else
- {
- while (n != 0)
- {
- total += (n & 1);
- n >>= 1;
- }
- }
- }
-
- return total;
- }
-
- int BitArray::getHighestBit() const throw()
- {
- for (int i = highestBit + 1; --i >= 0;)
- if ((values [i >> 5] & (1 << (i & 31))) != 0)
- return i;
-
- return -1;
- }
-
- int BitArray::findNextSetBit (int i) const throw()
- {
- for (; i <= highestBit; ++i)
- if ((values [i >> 5] & (1 << (i & 31))) != 0)
- return i;
-
- return -1;
- }
-
- int BitArray::findNextClearBit (int i) const throw()
- {
- for (; i <= highestBit; ++i)
- if ((values [i >> 5] & (1 << (i & 31))) == 0)
- break;
-
- return i;
- }
-
- void BitArray::ensureSize (const int numVals) throw()
- {
- if (numVals + 2 >= numValues)
- {
- int oldSize = numValues;
- numValues = ((numVals + 2) * 3) / 2;
- values = (unsigned int*) juce_realloc (values, sizeof (unsigned int) * numValues + 4);
-
- while (oldSize < numValues)
- values [oldSize++] = 0;
- }
- }
-
- const String BitArray::toString (const int base) const throw()
- {
- String s;
- BitArray v (*this);
-
- if (base == 2 || base == 8 || base == 16)
- {
- const int bits = (base == 2) ? 1 : (base == 8 ? 3 : 4);
- static const tchar* const hexDigits = T("0123456789abcdef");
-
- for (;;)
- {
- const int remainder = v.getBitRangeAsInt (0, bits);
-
- v.shiftBits (-bits);
-
- if (remainder == 0 && v.isEmpty())
- break;
-
- s = String::charToString (hexDigits [remainder]) + s;
- }
- }
- else if (base == 10)
- {
- const BitArray ten (10);
- BitArray remainder;
-
- for (;;)
- {
- v.divideBy (ten, remainder);
-
- if (remainder.isEmpty() && v.isEmpty())
- break;
-
- s = String (remainder.getBitRangeAsInt (0, 8)) + s;
- }
- }
- else
- {
- jassertfalse // can't do the specified base
- return String::empty;
- }
-
- if (s.isEmpty())
- return T("0");
-
- return isNegative() ? T("-") + s : s;
- }
-
- void BitArray::parseString (const String& text,
- const int base) throw()
- {
- clear();
- const tchar* t = (const tchar*) text;
-
- if (base == 2 || base == 8 || base == 16)
- {
- const int bits = (base == 2) ? 1 : (base == 8 ? 3 : 4);
-
- for (;;)
- {
- const tchar c = *t++;
- const int digit = CharacterFunctions::getHexDigitValue (c);
-
- if (((unsigned int) digit) < (unsigned int) base)
- {
- shiftBits (bits);
- add (digit);
- }
- else if (c == 0)
- {
- break;
- }
- }
- }
- else if (base == 10)
- {
- const BitArray ten ((unsigned int) 10);
-
- for (;;)
- {
- const tchar c = *t++;
-
- if (c >= T('0') && c <= T('9'))
- {
- multiplyBy (ten);
- add ((int) (c - T('0')));
- }
- else if (c == 0)
- {
- break;
- }
- }
- }
-
- setNegative (text.trimStart().startsWithChar (T('-')));
- }
-
- const MemoryBlock BitArray::toMemoryBlock() const throw()
- {
- const int numBytes = (getHighestBit() + 7) >> 3;
- MemoryBlock mb (numBytes);
-
- for (int i = 0; i < numBytes; ++i)
- mb[i] = (uint8) getBitRangeAsInt (i << 3, 8);
-
- return mb;
- }
-
- void BitArray::loadFromMemoryBlock (const MemoryBlock& data) throw()
- {
- clear();
-
- for (int i = data.getSize(); --i >= 0;)
- this->setBitRangeAsInt (i << 3, 8, data [i]);
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_BitArray.cpp *********/
-
- /********* Start of inlined file: juce_MemoryBlock.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- MemoryBlock::MemoryBlock() throw()
- : data (0),
- size (0)
- {
- }
-
- MemoryBlock::MemoryBlock (const int initialSize,
- const bool initialiseToZero) throw()
- {
- if (initialSize > 0)
- {
- size = initialSize;
-
- if (initialiseToZero)
- data = (char*) juce_calloc (initialSize);
- else
- data = (char*) juce_malloc (initialSize);
- }
- else
- {
- data = 0;
- size = 0;
- }
- }
-
- MemoryBlock::MemoryBlock (const MemoryBlock& other) throw()
- : data (0),
- size (other.size)
- {
- if (size > 0)
- {
- jassert (other.data != 0);
- data = (char*) juce_malloc (size);
- memcpy (data, other.data, size);
- }
- }
-
- MemoryBlock::MemoryBlock (const void* const dataToInitialiseFrom,
- const int sizeInBytes) throw()
- : data (0),
- size (jmax (0, sizeInBytes))
- {
- jassert (sizeInBytes >= 0);
-
- if (size > 0)
- {
- jassert (dataToInitialiseFrom != 0); // non-zero size, but a zero pointer passed-in?
-
- data = (char*) juce_malloc (size);
-
- if (dataToInitialiseFrom != 0)
- memcpy (data, dataToInitialiseFrom, size);
- }
- }
-
- MemoryBlock::~MemoryBlock() throw()
- {
- jassert (size >= 0); // should never happen
- jassert (size == 0 || data != 0); // non-zero size but no data allocated?
-
- juce_free (data);
- }
-
- const MemoryBlock& MemoryBlock::operator= (const MemoryBlock& other) throw()
- {
- if (this != &other)
- {
- setSize (other.size, false);
- memcpy (data, other.data, size);
- }
-
- return *this;
- }
-
- bool MemoryBlock::operator== (const MemoryBlock& other) const throw()
- {
- return (size == other.size)
- && (memcmp (data, other.data, size) == 0);
- }
-
- bool MemoryBlock::operator!= (const MemoryBlock& other) const throw()
- {
- return ! operator== (other);
- }
-
- // this will resize the block to this size
- void MemoryBlock::setSize (const int newSize,
- const bool initialiseToZero) throw()
- {
- if (size != newSize)
- {
- if (newSize <= 0)
- {
- juce_free (data);
- data = 0;
- size = 0;
- }
- else
- {
- if (data != 0)
- {
- data = (char*) juce_realloc (data, newSize);
-
- if (initialiseToZero && (newSize > size))
- zeromem (data + size, newSize - size);
- }
- else
- {
- if (initialiseToZero)
- data = (char*) juce_calloc (newSize);
- else
- data = (char*) juce_malloc (newSize);
- }
-
- size = newSize;
- }
- }
- }
-
- void MemoryBlock::ensureSize (const int minimumSize,
- const bool initialiseToZero) throw()
- {
- if (size < minimumSize)
- setSize (minimumSize, initialiseToZero);
- }
-
- void MemoryBlock::fillWith (const uint8 value) throw()
- {
- memset (data, (int) value, size);
- }
-
- void MemoryBlock::append (const void* const srcData,
- const int numBytes) throw()
- {
- if (numBytes > 0)
- {
- const int oldSize = size;
- setSize (size + numBytes);
- memcpy (data + oldSize, srcData, numBytes);
- }
- }
-
- void MemoryBlock::copyFrom (const void* const src, int offset, int num) throw()
- {
- const char* d = (const char*) src;
-
- if (offset < 0)
- {
- d -= offset;
- num -= offset;
- offset = 0;
- }
-
- if (offset + num > size)
- num = size - offset;
-
- if (num > 0)
- memcpy (data + offset, d, num);
- }
-
- void MemoryBlock::copyTo (void* const dst, int offset, int num) const throw()
- {
- char* d = (char*) dst;
-
- if (offset < 0)
- {
- zeromem (d, -offset);
- d -= offset;
-
- num += offset;
- offset = 0;
- }
-
- if (offset + num > size)
- {
- const int newNum = size - offset;
- zeromem (d + newNum, num - newNum);
- num = newNum;
- }
-
- if (num > 0)
- memcpy (d, data + offset, num);
- }
-
- void MemoryBlock::removeSection (int startByte, int numBytesToRemove) throw()
- {
- if (startByte < 0)
- {
- numBytesToRemove += startByte;
- startByte = 0;
- }
-
- if (startByte + numBytesToRemove >= size)
- {
- setSize (startByte);
- }
- else if (numBytesToRemove > 0)
- {
- memmove (data + startByte,
- data + startByte + numBytesToRemove,
- size - (startByte + numBytesToRemove));
-
- setSize (size - numBytesToRemove);
- }
- }
-
- const String MemoryBlock::toString() const throw()
- {
- return String (data, size);
- }
-
- int MemoryBlock::getBitRange (const int bitRangeStart, int numBits) const throw()
- {
- int res = 0;
-
- int byte = bitRangeStart >> 3;
- int offsetInByte = bitRangeStart & 7;
- int bitsSoFar = 0;
-
- while (numBits > 0 && byte < size)
- {
- const int bitsThisTime = jmin (numBits, 8 - offsetInByte);
- const int mask = (0xff >> (8 - bitsThisTime)) << offsetInByte;
-
- res |= (((data[byte] & mask) >> offsetInByte) << bitsSoFar);
-
- bitsSoFar += bitsThisTime;
- numBits -= bitsThisTime;
- ++byte;
- offsetInByte = 0;
- }
-
- return res;
- }
-
- void MemoryBlock::setBitRange (const int bitRangeStart, int numBits, int bitsToSet) throw()
- {
- int byte = bitRangeStart >> 3;
- int offsetInByte = bitRangeStart & 7;
- unsigned int mask = ~((((unsigned int)0xffffffff) << (32 - numBits)) >> (32 - numBits));
-
- while (numBits > 0 && byte < size)
- {
- const int bitsThisTime = jmin (numBits, 8 - offsetInByte);
-
- const unsigned int tempMask = (mask << offsetInByte) | ~((((unsigned int)0xffffffff) >> offsetInByte) << offsetInByte);
- const unsigned int tempBits = bitsToSet << offsetInByte;
-
- data[byte] = (char)((data[byte] & tempMask) | tempBits);
-
- ++byte;
- numBits -= bitsThisTime;
- bitsToSet >>= bitsThisTime;
- mask >>= bitsThisTime;
- offsetInByte = 0;
- }
- }
-
- void MemoryBlock::loadFromHexString (const String& hex) throw()
- {
- ensureSize (hex.length() >> 1);
- char* dest = data;
- int i = 0;
-
- for (;;)
- {
- int byte = 0;
-
- for (int loop = 2; --loop >= 0;)
- {
- byte <<= 4;
-
- for (;;)
- {
- const tchar c = hex [i++];
-
- if (c >= T('0') && c <= T('9'))
- {
- byte |= c - T('0');
- break;
- }
- else if (c >= T('a') && c <= T('z'))
- {
- byte |= c - (T('a') - 10);
- break;
- }
- else if (c >= T('A') && c <= T('Z'))
- {
- byte |= c - (T('A') - 10);
- break;
- }
- else if (c == 0)
- {
- setSize ((int) (dest - data));
- return;
- }
- }
- }
-
- *dest++ = (char) byte;
- }
- }
-
- static const char* const encodingTable
- = ".ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+";
-
- const String MemoryBlock::toBase64Encoding() const throw()
- {
- const int numChars = ((size << 3) + 5) / 6;
-
- String destString (size); // store the length, followed by a '.', and then the data.
- const int initialLen = destString.length();
- destString.preallocateStorage (initialLen + 2 + numChars);
-
- tchar* d = const_cast <tchar*> (((const tchar*) destString) + initialLen);
- *d++ = T('.');
-
- for (int i = 0; i < numChars; ++i)
- *d++ = encodingTable [getBitRange (i * 6, 6)];
-
- *d++ = 0;
-
- return destString;
- }
-
- bool MemoryBlock::fromBase64Encoding (const String& s) throw()
- {
- const int startPos = s.indexOfChar (T('.')) + 1;
-
- if (startPos <= 0)
- return false;
-
- const int numBytesNeeded = s.substring (0, startPos - 1).getIntValue();
-
- setSize (numBytesNeeded, true);
-
- const int numChars = s.length() - startPos;
- const tchar* const srcChars = ((const tchar*) s) + startPos;
-
- for (int i = 0; i < numChars; ++i)
- {
- const char c = (char) srcChars[i];
-
- for (int j = 0; j < 64; ++j)
- {
- if (encodingTable[j] == c)
- {
- setBitRange (i * 6, 6, j);
- break;
- }
- }
- }
-
- return true;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_MemoryBlock.cpp *********/
-
- /********* Start of inlined file: juce_PropertySet.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- PropertySet::PropertySet (const bool ignoreCaseOfKeyNames) throw()
- : properties (ignoreCaseOfKeyNames),
- fallbackProperties (0),
- ignoreCaseOfKeys (ignoreCaseOfKeyNames)
- {
- }
-
- PropertySet::PropertySet (const PropertySet& other) throw()
- : properties (other.properties),
- fallbackProperties (other.fallbackProperties),
- ignoreCaseOfKeys (other.ignoreCaseOfKeys)
- {
- }
-
- const PropertySet& PropertySet::operator= (const PropertySet& other) throw()
- {
- properties = other.properties;
- fallbackProperties = other.fallbackProperties;
- ignoreCaseOfKeys = other.ignoreCaseOfKeys;
-
- propertyChanged();
- return *this;
- }
-
- PropertySet::~PropertySet()
- {
- }
-
- void PropertySet::clear()
- {
- const ScopedLock sl (lock);
-
- if (properties.size() > 0)
- {
- properties.clear();
- propertyChanged();
- }
- }
-
- const String PropertySet::getValue (const String& keyName,
- const String& defaultValue) const throw()
- {
- const ScopedLock sl (lock);
-
- const int index = properties.getAllKeys().indexOf (keyName, ignoreCaseOfKeys);
-
- if (index >= 0)
- return properties.getAllValues() [index];
-
- return fallbackProperties != 0 ? fallbackProperties->getValue (keyName, defaultValue)
- : defaultValue;
- }
-
- int PropertySet::getIntValue (const String& keyName,
- const int defaultValue) const throw()
- {
- const ScopedLock sl (lock);
- const int index = properties.getAllKeys().indexOf (keyName, ignoreCaseOfKeys);
-
- if (index >= 0)
- return properties.getAllValues() [index].getIntValue();
-
- return fallbackProperties != 0 ? fallbackProperties->getIntValue (keyName, defaultValue)
- : defaultValue;
- }
-
- double PropertySet::getDoubleValue (const String& keyName,
- const double defaultValue) const throw()
- {
- const ScopedLock sl (lock);
- const int index = properties.getAllKeys().indexOf (keyName, ignoreCaseOfKeys);
-
- if (index >= 0)
- return properties.getAllValues()[index].getDoubleValue();
-
- return fallbackProperties != 0 ? fallbackProperties->getDoubleValue (keyName, defaultValue)
- : defaultValue;
- }
-
- bool PropertySet::getBoolValue (const String& keyName,
- const bool defaultValue) const throw()
- {
- const ScopedLock sl (lock);
- const int index = properties.getAllKeys().indexOf (keyName, ignoreCaseOfKeys);
-
- if (index >= 0)
- return properties.getAllValues() [index].getIntValue() != 0;
-
- return fallbackProperties != 0 ? fallbackProperties->getBoolValue (keyName, defaultValue)
- : defaultValue;
- }
-
- XmlElement* PropertySet::getXmlValue (const String& keyName) const
- {
- XmlDocument doc (getValue (keyName));
-
- return doc.getDocumentElement();
- }
-
- void PropertySet::setValue (const String& keyName,
- const String& value) throw()
- {
- jassert (keyName.isNotEmpty()); // shouldn't use an empty key name!
-
- if (keyName.isNotEmpty())
- {
- const ScopedLock sl (lock);
-
- const int index = properties.getAllKeys().indexOf (keyName, ignoreCaseOfKeys);
-
- if (index < 0 || properties.getAllValues() [index] != value)
- {
- properties.set (keyName, value);
- propertyChanged();
- }
- }
- }
-
- void PropertySet::removeValue (const String& keyName) throw()
- {
- if (keyName.isNotEmpty())
- {
- const ScopedLock sl (lock);
- const int index = properties.getAllKeys().indexOf (keyName, ignoreCaseOfKeys);
-
- if (index >= 0)
- {
- properties.remove (keyName);
- propertyChanged();
- }
- }
- }
-
- void PropertySet::setValue (const String& keyName, const tchar* const value) throw()
- {
- setValue (keyName, String (value));
- }
-
- void PropertySet::setValue (const String& keyName, const int value) throw()
- {
- setValue (keyName, String (value));
- }
-
- void PropertySet::setValue (const String& keyName, const double value) throw()
- {
- setValue (keyName, String (value));
- }
-
- void PropertySet::setValue (const String& keyName, const bool value) throw()
- {
- setValue (keyName, String ((value) ? T("1") : T("0")));
- }
-
- void PropertySet::setValue (const String& keyName, const XmlElement* const xml)
- {
- setValue (keyName, (xml == 0) ? String::empty
- : xml->createDocument (String::empty, true));
- }
-
- bool PropertySet::containsKey (const String& keyName) const throw()
- {
- const ScopedLock sl (lock);
- return properties.getAllKeys().contains (keyName, ignoreCaseOfKeys);
- }
-
- void PropertySet::setFallbackPropertySet (PropertySet* fallbackProperties_) throw()
- {
- const ScopedLock sl (lock);
- fallbackProperties = fallbackProperties_;
- }
-
- XmlElement* PropertySet::createXml (const String& nodeName) const throw()
- {
- const ScopedLock sl (lock);
- XmlElement* const xml = new XmlElement (nodeName);
-
- for (int i = 0; i < properties.getAllKeys().size(); ++i)
- {
- XmlElement* const e = new XmlElement (T("VALUE"));
-
- e->setAttribute (T("name"), properties.getAllKeys()[i]);
- e->setAttribute (T("val"), properties.getAllValues()[i]);
-
- xml->addChildElement (e);
- }
-
- return xml;
- }
-
- void PropertySet::restoreFromXml (const XmlElement& xml) throw()
- {
- const ScopedLock sl (lock);
- clear();
-
- forEachXmlChildElementWithTagName (xml, e, T("VALUE"))
- {
- if (e->hasAttribute (T("name"))
- && e->hasAttribute (T("val")))
- {
- properties.set (e->getStringAttribute (T("name")),
- e->getStringAttribute (T("val")));
- }
- }
-
- if (properties.size() > 0)
- propertyChanged();
- }
-
- void PropertySet::propertyChanged()
- {
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_PropertySet.cpp *********/
-
- /********* Start of inlined file: juce_BlowFish.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- static const uint32 initialPValues [18] =
- {
- 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344,
- 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
- 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
- 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
- 0x9216d5d9, 0x8979fb1b
- };
-
- static const uint32 initialSValues [4 * 256] =
- {
- 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7,
- 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
- 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
- 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
- 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee,
- 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
- 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef,
- 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
- 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
- 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
- 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce,
- 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
- 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e,
- 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
- 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
- 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
- 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88,
- 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
- 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e,
- 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
- 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,
- 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
- 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88,
- 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
- 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6,
- 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
- 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
- 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
- 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba,
- 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
- 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f,
- 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
- 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,
- 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
- 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279,
- 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
- 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab,
- 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
- 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,
- 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
- 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0,
- 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
- 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790,
- 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
- 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
- 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
- 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7,
- 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
- 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad,
- 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
- 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,
- 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
- 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477,
- 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
- 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49,
- 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
- 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,
- 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
- 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41,
- 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
- 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400,
- 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
- 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
- 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a,
- 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623,
- 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
- 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,
- 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
- 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6,
- 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
- 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e,
- 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
- 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737,
- 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
- 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff,
- 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
- 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701,
- 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
- 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41,
- 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
- 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf,
- 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
- 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e,
- 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
- 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c,
- 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
- 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16,
- 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
- 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b,
- 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
- 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e,
- 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
- 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f,
- 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
- 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4,
- 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
- 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66,
- 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
- 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802,
- 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
- 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510,
- 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
- 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14,
- 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
- 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50,
- 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
- 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8,
- 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
- 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99,
- 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
- 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128,
- 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
- 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0,
- 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
- 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105,
- 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
- 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3,
- 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
- 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00,
- 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
- 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb,
- 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,
- 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735,
- 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
- 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9,
- 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
- 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,
- 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7,
- 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934,
- 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
- 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af,
- 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
- 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45,
- 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
- 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a,
- 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,
- 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee,
- 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
- 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42,
- 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
- 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2,
- 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,
- 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527,
- 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
- 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33,
- 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
- 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3,
- 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,
- 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17,
- 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
- 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b,
- 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
- 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922,
- 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,
- 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0,
- 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
- 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37,
- 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
- 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804,
- 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
- 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3,
- 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
- 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d,
- 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
- 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350,
- 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
- 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a,
- 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
- 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d,
- 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
- 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f,
- 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
- 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2,
- 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
- 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2,
- 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
- 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e,
- 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
- 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10,
- 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
- 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52,
- 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
- 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5,
- 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
- 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634,
- 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
- 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24,
- 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
- 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4,
- 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
- 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,
- 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0,
- 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b,
- 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
- 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
- 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
- 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8,
- 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
- 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304,
- 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
- 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,
- 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
- 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9,
- 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
- 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593,
- 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
- 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,
- 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
- 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b,
- 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
- 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c,
- 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
- 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,
- 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
- 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb,
- 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
- 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991,
- 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
- 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,
- 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
- 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae,
- 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
- 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5,
- 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
- 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
- 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
- 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84,
- 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
- 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8,
- 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
- 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,
- 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
- 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38,
- 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
- 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c,
- 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
- 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,
- 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
- 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964,
- 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
- 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8,
- 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
- 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,
- 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
- 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02,
- 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
- 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614,
- 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
- 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,
- 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
- 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0,
- 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
- 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e,
- 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
- 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
- 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6
- };
-
- BlowFish::BlowFish (const uint8* keyData, int keyBytes)
- {
- memcpy (p, initialPValues, sizeof (p));
-
- int i, j;
- for (i = 4; --i >= 0;)
- {
- s[i] = (uint32*) juce_malloc (256 * sizeof (uint32));
- memcpy (s[i], initialSValues + i * 256, 256 * sizeof (uint32));
- }
-
- j = 0;
-
- for (i = 0; i < 18; ++i)
- {
- uint32 d = 0;
-
- for (int k = 0; k < 4; ++k)
- {
- d = (d << 8) | keyData[j];
-
- if (++j >= keyBytes)
- j = 0;
- }
-
- p[i] = initialPValues[i] ^ d;
- }
-
- uint32 l = 0, r = 0;
-
- for (i = 0; i < 18; i += 2)
- {
- encrypt (l, r);
-
- p[i] = l;
- p[i + 1] = r;
- }
-
- for (i = 0; i < 4; ++i)
- {
- for (j = 0; j < 256; j += 2)
- {
- encrypt (l, r);
-
- s[i][j] = l;
- s[i][j + 1] = r;
- }
- }
- }
-
- BlowFish::BlowFish (const BlowFish& other)
- {
- for (int i = 4; --i >= 0;)
- s[i] = (uint32*) juce_malloc (256 * sizeof (uint32));
-
- operator= (other);
- }
-
- const BlowFish& BlowFish::operator= (const BlowFish& other)
- {
- memcpy (p, other.p, sizeof (p));
-
- for (int i = 4; --i >= 0;)
- memcpy (s[i], other.s[i], 256 * sizeof (uint32));
-
- return *this;
- }
-
- BlowFish::~BlowFish()
- {
- for (int i = 4; --i >= 0;)
- juce_free (s[i]);
- }
-
- uint32 BlowFish::F (uint32 x) const
- {
- uint16 a, b, c, d;
- uint32 y;
-
- d = (uint16) (x & 0xff);
- x >>= 8;
- c = (uint16) (x & 0xff);
- x >>= 8;
- b = (uint16) (x & 0xff);
- x >>= 8;
- a = (uint16) (x & 0xff);
-
- y = s[0][a] + s[1][b];
- y = y ^ s[2][c];
- y = y + s[3][d];
-
- return y;
- }
-
- void BlowFish::encrypt (uint32& data1,
- uint32& data2) const
- {
- uint32 l = data1;
- uint32 r = data2;
-
- for (int i = 0; i < 16; ++i)
- {
- l = l ^ p[i];
- r = F (l) ^ r;
-
- const uint32 temp = l;
- l = r;
- r = temp;
- }
-
- const uint32 temp = l;
- l = r;
- r = temp;
-
- r = r ^ p[16];
- l = l ^ p[17];
-
- data1 = l;
- data2 = r;
- }
-
- void BlowFish::decrypt (uint32& data1,
- uint32& data2) const
- {
- uint32 l = data1;
- uint32 r = data2;
-
- for (int i = 17; i > 1; --i)
- {
- l =l ^ p[i];
- r = F (l) ^ r;
-
- const uint32 temp = l;
- l = r;
- r = temp;
- }
-
- const uint32 temp = l;
- l = r;
- r = temp;
-
- r = r ^ p[1];
- l = l ^ p[0];
-
- data1 = l;
- data2 = r;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_BlowFish.cpp *********/
-
- /********* Start of inlined file: juce_MD5.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- MD5::MD5()
- {
- zeromem (result, sizeof (result));
- }
-
- MD5::MD5 (const MD5& other)
- {
- memcpy (result, other.result, sizeof (result));
- }
-
- const MD5& MD5::operator= (const MD5& other)
- {
- memcpy (result, other.result, sizeof (result));
- return *this;
- }
-
- MD5::MD5 (const MemoryBlock& data)
- {
- ProcessContext context;
- context.processBlock ((const uint8*) data.getData(), data.getSize());
- context.finish (result);
- }
-
- MD5::MD5 (const char* data, const int numBytes)
- {
- ProcessContext context;
- context.processBlock ((const uint8*) data, numBytes);
- context.finish (result);
- }
-
- MD5::MD5 (const String& text)
- {
- ProcessContext context;
-
- const int len = text.length();
- const juce_wchar* const t = text;
-
- for (int i = 0; i < len; ++i)
- {
- // force the string into integer-sized unicode characters, to try to make it
- // get the same results on all platforms + compilers.
- uint32 unicodeChar = (uint32) t[i];
- swapIfBigEndian (unicodeChar);
-
- context.processBlock ((const uint8*) &unicodeChar,
- sizeof (unicodeChar));
- }
-
- context.finish (result);
- }
-
- void MD5::processStream (InputStream& input, int numBytesToRead)
- {
- ProcessContext context;
-
- if (numBytesToRead < 0)
- numBytesToRead = INT_MAX;
-
- while (numBytesToRead > 0)
- {
- char tempBuffer [512];
- const int bytesRead = input.read (tempBuffer, jmin (numBytesToRead, sizeof (tempBuffer)));
-
- if (bytesRead <= 0)
- break;
-
- numBytesToRead -= bytesRead;
-
- context.processBlock ((const uint8*) tempBuffer, bytesRead);
- }
-
- context.finish (result);
- }
-
- MD5::MD5 (InputStream& input, int numBytesToRead)
- {
- processStream (input, numBytesToRead);
- }
-
- MD5::MD5 (const File& file)
- {
- FileInputStream* const fin = file.createInputStream();
-
- if (fin != 0)
- {
- processStream (*fin, -1);
- delete fin;
- }
- else
- {
- zeromem (result, sizeof (result));
- }
- }
-
- MD5::~MD5()
- {
- }
-
- MD5::ProcessContext::ProcessContext()
- {
- state[0] = 0x67452301;
- state[1] = 0xefcdab89;
- state[2] = 0x98badcfe;
- state[3] = 0x10325476;
-
- count[0] = 0;
- count[1] = 0;
- }
-
- void MD5::ProcessContext::processBlock (const uint8* const data, int dataSize)
- {
- int bufferPos = ((count[0] >> 3) & 0x3F);
-
- count[0] += (dataSize << 3);
-
- if (count[0] < ((uint32) dataSize << 3))
- count[1]++;
-
- count[1] += (dataSize >> 29);
-
- const int spaceLeft = 64 - bufferPos;
-
- int i = 0;
-
- if (dataSize >= spaceLeft)
- {
- memcpy (buffer + bufferPos, data, spaceLeft);
-
- transform (buffer);
-
- i = spaceLeft;
-
- while (i < dataSize - 63)
- {
- transform (data + i);
- i += 64;
- }
-
- bufferPos = 0;
- }
-
- memcpy (buffer + bufferPos, data + i, dataSize - i);
- }
-
- static void encode (uint8* const output,
- const uint32* const input,
- const int numBytes)
- {
- uint32* const o = (uint32*) output;
-
- for (int i = 0; i < (numBytes >> 2); ++i)
- o[i] = swapIfBigEndian (input [i]);
- }
-
- static void decode (uint32* const output,
- const uint8* const input,
- const int numBytes)
- {
- for (int i = 0; i < (numBytes >> 2); ++i)
- output[i] = littleEndianInt ((const char*) input + (i << 2));
- }
-
- void MD5::ProcessContext::finish (uint8* const result)
- {
- unsigned char encodedLength[8];
- encode (encodedLength, count, 8);
-
- // Pad out to 56 mod 64.
- const int index = (uint32) ((count[0] >> 3) & 0x3f);
-
- const int paddingLength = (index < 56) ? (56 - index)
- : (120 - index);
-
- uint8 paddingBuffer [64];
- zeromem (paddingBuffer, paddingLength);
- paddingBuffer [0] = 0x80;
- processBlock (paddingBuffer, paddingLength);
-
- processBlock (encodedLength, 8);
-
- encode (result, state, 16);
-
- zeromem (buffer, sizeof (buffer));
- }
-
- #define S11 7
- #define S12 12
- #define S13 17
- #define S14 22
- #define S21 5
- #define S22 9
- #define S23 14
- #define S24 20
- #define S31 4
- #define S32 11
- #define S33 16
- #define S34 23
- #define S41 6
- #define S42 10
- #define S43 15
- #define S44 21
-
- static inline uint32 F (const uint32 x, const uint32 y, const uint32 z) { return (x & y) | (~x & z); }
- static inline uint32 G (const uint32 x, const uint32 y, const uint32 z) { return (x & z) | (y & ~z); }
- static inline uint32 H (const uint32 x, const uint32 y, const uint32 z) { return x ^ y ^ z; }
- static inline uint32 I (const uint32 x, const uint32 y, const uint32 z) { return y ^ (x | ~z); }
-
- static inline uint32 rotateLeft (const uint32 x, const uint32 n) { return (x << n) | (x >> (32 - n)); }
-
- static inline void FF (uint32& a, const uint32 b, const uint32 c, const uint32 d, const uint32 x, const uint32 s, const uint32 ac)
- {
- a += F (b, c, d) + x + ac;
- a = rotateLeft (a, s) + b;
- }
-
- static inline void GG (uint32& a, const uint32 b, const uint32 c, const uint32 d, const uint32 x, const uint32 s, const uint32 ac)
- {
- a += G (b, c, d) + x + ac;
- a = rotateLeft (a, s) + b;
- }
-
- static inline void HH (uint32& a, const uint32 b, const uint32 c, const uint32 d, const uint32 x, const uint32 s, const uint32 ac)
- {
- a += H (b, c, d) + x + ac;
- a = rotateLeft (a, s) + b;
- }
-
- static inline void II (uint32& a, const uint32 b, const uint32 c, const uint32 d, const uint32 x, const uint32 s, const uint32 ac)
- {
- a += I (b, c, d) + x + ac;
- a = rotateLeft (a, s) + b;
- }
-
- void MD5::ProcessContext::transform (const uint8* const buffer)
- {
- uint32 a = state[0];
- uint32 b = state[1];
- uint32 c = state[2];
- uint32 d = state[3];
- uint32 x[16];
-
- decode (x, buffer, 64);
-
- FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
- FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
- FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
- FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
- FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
- FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
- FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
- FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
- FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
- FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
- FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
- FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
- FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
- FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
- FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
- FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
-
- GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
- GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
- GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
- GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
- GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
- GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
- GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
- GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
- GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
- GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
- GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
- GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
- GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
- GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
- GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
- GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
-
- HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
- HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
- HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
- HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
- HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
- HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
- HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
- HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
- HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
- HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
- HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
- HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
- HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
- HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
- HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
- HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
-
- II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
- II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
- II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
- II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
- II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
- II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
- II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
- II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
- II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
- II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
- II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
- II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
- II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
- II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
- II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
- II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
-
- state[0] += a;
- state[1] += b;
- state[2] += c;
- state[3] += d;
-
- zeromem (x, sizeof (x));
- }
-
- const MemoryBlock MD5::getRawChecksumData() const
- {
- return MemoryBlock (result, 16);
- }
-
- const String MD5::toHexString() const
- {
- return String::toHexString (result, 16, 0);
- }
-
- bool MD5::operator== (const MD5& other) const
- {
- return memcmp (result, other.result, 16) == 0;
- }
-
- bool MD5::operator!= (const MD5& other) const
- {
- return ! operator== (other);
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_MD5.cpp *********/
-
- /********* Start of inlined file: juce_Primes.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- static void createSmallSieve (const int numBits, BitArray& result) throw()
- {
- result.setBit (numBits);
- result.clearBit (numBits); // to enlarge the array
-
- result.setBit (0);
- int n = 2;
-
- do
- {
- for (int i = n + n; i < numBits; i += n)
- result.setBit (i);
-
- n = result.findNextClearBit (n + 1);
- }
- while (n <= (numBits >> 1));
- }
-
- static void bigSieve (const BitArray& base,
- const int numBits,
- BitArray& result,
- const BitArray& smallSieve,
- const int smallSieveSize) throw()
- {
- jassert (! base[0]); // must be even!
-
- result.setBit (numBits);
- result.clearBit (numBits); // to enlarge the array
-
- int index = smallSieve.findNextClearBit (0);
-
- do
- {
- const int prime = (index << 1) + 1;
-
- BitArray r (base);
- BitArray remainder;
- r.divideBy (prime, remainder);
-
- int i = prime - remainder.getBitRangeAsInt (0, 32);
-
- if (r.isEmpty())
- i += prime;
-
- if ((i & 1) == 0)
- i += prime;
-
- i = (i - 1) >> 1;
-
- while (i < numBits)
- {
- result.setBit (i);
- i += prime;
- }
-
- index = smallSieve.findNextClearBit (index + 1);
- }
- while (index < smallSieveSize);
- }
-
- static bool findCandidate (const BitArray& base,
- const BitArray& sieve,
- const int numBits,
- BitArray& result,
- const int certainty) throw()
- {
- for (int i = 0; i < numBits; ++i)
- {
- if (! sieve[i])
- {
- result = base;
- result.add (BitArray ((unsigned int) ((i << 1) + 1)));
-
- if (Primes::isProbablyPrime (result, certainty))
- return true;
- }
- }
-
- return false;
- }
-
- const BitArray Primes::createProbablePrime (const int bitLength,
- const int certainty) throw()
- {
- BitArray smallSieve;
- const int smallSieveSize = 15000;
- createSmallSieve (smallSieveSize, smallSieve);
-
- BitArray p;
- p.fillBitsRandomly (0, bitLength);
- p.setBit (bitLength - 1);
- p.clearBit (0);
-
- const int searchLen = jmax (1024, (bitLength / 20) * 64);
-
- while (p.getHighestBit() < bitLength)
- {
- p.add (2 * searchLen);
-
- BitArray sieve;
- bigSieve (p, searchLen, sieve,
- smallSieve, smallSieveSize);
-
- BitArray candidate;
-
- if (findCandidate (p, sieve, searchLen, candidate, certainty))
- return candidate;
- }
-
- jassertfalse
- return BitArray();
- }
-
- static bool passesMillerRabin (const BitArray& n, int iterations) throw()
- {
- const BitArray one (1);
- const BitArray two (2);
-
- BitArray nMinusOne (n);
- nMinusOne.subtract (one);
-
- BitArray d (nMinusOne);
- const int s = d.findNextSetBit (0);
- d.shiftBits (-s);
-
- BitArray smallPrimes;
- int numBitsInSmallPrimes = 0;
-
- for (;;)
- {
- numBitsInSmallPrimes += 256;
- createSmallSieve (numBitsInSmallPrimes, smallPrimes);
-
- const int numPrimesFound = numBitsInSmallPrimes - smallPrimes.countNumberOfSetBits();
-
- if (numPrimesFound > iterations + 1)
- break;
- }
-
- int smallPrime = 2;
-
- while (--iterations >= 0)
- {
- smallPrime = smallPrimes.findNextClearBit (smallPrime + 1);
-
- BitArray r (smallPrime);
- //r.createRandomNumber (nMinusOne);
- r.exponentModulo (d, n);
-
- if (! (r == one || r == nMinusOne))
- {
- for (int j = 0; j < s; ++j)
- {
- r.exponentModulo (two, n);
-
- if (r == nMinusOne)
- break;
- }
-
- if (r != nMinusOne)
- return false;
- }
- }
-
- return true;
- }
-
- bool Primes::isProbablyPrime (const BitArray& number,
- const int certainty) throw()
- {
- if (! number[0])
- return false;
-
- if (number.getHighestBit() <= 10)
- {
- const int num = number.getBitRangeAsInt (0, 10);
-
- for (int i = num / 2; --i > 1;)
- if (num % i == 0)
- return false;
-
- return true;
- }
- else
- {
- const BitArray screen (2 * 3 * 5 * 7 * 11 * 13 * 17 * 19 * 23);
-
- if (number.findGreatestCommonDivisor (screen) != BitArray (1))
- return false;
-
- return passesMillerRabin (number, certainty);
- }
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_Primes.cpp *********/
-
- /********* Start of inlined file: juce_RSAKey.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- RSAKey::RSAKey() throw()
- {
- }
-
- RSAKey::RSAKey (const String& s) throw()
- {
- if (s.containsChar (T(',')))
- {
- part1.parseString (s.upToFirstOccurrenceOf (T(","), false, false), 16);
- part2.parseString (s.fromFirstOccurrenceOf (T(","), false, false), 16);
- }
- else
- {
- // the string needs to be two hex numbers, comma-separated..
- jassertfalse;
- }
- }
-
- RSAKey::~RSAKey() throw()
- {
- }
-
- const String RSAKey::toString() const throw()
- {
- return part1.toString (16) + T(",") + part2.toString (16);
- }
-
- bool RSAKey::applyToValue (BitArray& value) const throw()
- {
- if (part1.isEmpty() || part2.isEmpty()
- || value.compare (0) <= 0)
- {
- jassertfalse // using an uninitialised key
- value.clear();
- return false;
- }
-
- BitArray result;
-
- while (! value.isEmpty())
- {
- result.multiplyBy (part2);
-
- BitArray remainder;
- value.divideBy (part2, remainder);
-
- remainder.exponentModulo (part1, part2);
-
- result.add (remainder);
- }
-
- value = result;
-
- return true;
- }
-
- static const BitArray findBestCommonDivisor (const BitArray& p,
- const BitArray& q) throw()
- {
- const BitArray one (1);
-
- // try 3, 5, 9, 17, etc first because these only contain 2 bits and so
- // are fast to divide + multiply
- for (int i = 2; i <= 65536; i *= 2)
- {
- const BitArray e (1 + i);
-
- if (e.findGreatestCommonDivisor (p) == one
- && e.findGreatestCommonDivisor (q) == one)
- {
- return e;
- }
- }
-
- BitArray e (4);
-
- while (! (e.findGreatestCommonDivisor (p) == one
- && e.findGreatestCommonDivisor (q) == one))
- {
- e.add (one);
- }
-
- return e;
- }
-
- void RSAKey::createKeyPair (RSAKey& publicKey,
- RSAKey& privateKey,
- const int numBits) throw()
- {
- jassert (numBits > 16); // not much point using less than this..
-
- BitArray p (Primes::createProbablePrime (numBits / 2, 30));
- BitArray q (Primes::createProbablePrime (numBits - numBits / 2, 30));
-
- BitArray n (p);
- n.multiplyBy (q); // n = pq
-
- const BitArray one (1);
- p.subtract (one);
- q.subtract (one);
-
- BitArray m (p);
- m.multiplyBy (q); // m = (p - 1)(q - 1)
-
- const BitArray e (findBestCommonDivisor (p, q));
-
- BitArray d (e);
- d.inverseModulo (m);
-
- publicKey.part1 = e;
- publicKey.part2 = n;
-
- privateKey.part1 = d;
- privateKey.part2 = n;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_RSAKey.cpp *********/
-
- /********* Start of inlined file: juce_InputStream.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- char InputStream::readByte()
- {
- char temp = 0;
- read (&temp, 1);
- return temp;
- }
-
- bool InputStream::readBool()
- {
- return readByte() != 0;
- }
-
- short InputStream::readShort()
- {
- char temp [2];
-
- if (read (temp, 2) == 2)
- return (short) littleEndianShort (temp);
- else
- return 0;
- }
-
- short InputStream::readShortBigEndian()
- {
- char temp [2];
-
- if (read (temp, 2) == 2)
- return (short) bigEndianShort (temp);
- else
- return 0;
- }
-
- int InputStream::readInt()
- {
- char temp [4];
-
- if (read (temp, 4) == 4)
- return (int) littleEndianInt (temp);
- else
- return 0;
- }
-
- int InputStream::readIntBigEndian()
- {
- char temp [4];
-
- if (read (temp, 4) == 4)
- return (int) bigEndianInt (temp);
- else
- return 0;
- }
-
- int InputStream::readCompressedInt()
- {
- int num = 0;
-
- if (! isExhausted())
- {
- unsigned char numBytes = readByte();
- const bool negative = (numBytes & 0x80) != 0;
- numBytes &= 0x7f;
-
- if (numBytes <= 4)
- {
- if (read (&num, numBytes) != numBytes)
- return 0;
-
- if (negative)
- num = -num;
- }
- }
-
- return num;
- }
-
- int64 InputStream::readInt64()
- {
- char temp [8];
-
- if (read (temp, 8) == 8)
- return (int64) swapIfBigEndian (*(uint64*)temp);
- else
- return 0;
- }
-
- int64 InputStream::readInt64BigEndian()
- {
- char temp [8];
-
- if (read (temp, 8) == 8)
- return (int64) swapIfLittleEndian (*(uint64*)temp);
- else
- return 0;
- }
-
- float InputStream::readFloat()
- {
- union { int asInt; float asFloat; } n;
- n.asInt = readInt();
- return n.asFloat;
- }
-
- float InputStream::readFloatBigEndian()
- {
- union { int asInt; float asFloat; } n;
- n.asInt = readIntBigEndian();
- return n.asFloat;
- }
-
- double InputStream::readDouble()
- {
- union { int64 asInt; double asDouble; } n;
- n.asInt = readInt64();
- return n.asDouble;
- }
-
- double InputStream::readDoubleBigEndian()
- {
- union { int64 asInt; double asDouble; } n;
- n.asInt = readInt64BigEndian();
- return n.asDouble;
- }
-
- const String InputStream::readString()
- {
- const int tempBufferSize = 256;
- uint8 temp [tempBufferSize];
- int i = 0;
-
- while ((temp [i++] = readByte()) != 0)
- {
- if (i == tempBufferSize)
- {
- // too big for our quick buffer, so read it in blocks..
- String result (String::fromUTF8 (temp, i));
- i = 0;
-
- for (;;)
- {
- if ((temp [i++] = readByte()) == 0)
- {
- result += String::fromUTF8 (temp, i - 1);
- break;
- }
- else if (i == tempBufferSize)
- {
- result += String::fromUTF8 (temp, i);
- i = 0;
- }
- }
-
- return result;
- }
- }
-
- return String::fromUTF8 (temp, i - 1);
- }
-
- const String InputStream::readNextLine()
- {
- String s;
- const int maxChars = 256;
- tchar buffer [maxChars];
- int charsInBuffer = 0;
-
- while (! isExhausted())
- {
- const uint8 c = readByte();
- const int64 lastPos = getPosition();
-
- if (c == '\n')
- {
- break;
- }
- else if (c == '\r')
- {
- if (readByte() != '\n')
- setPosition (lastPos);
-
- break;
- }
-
- buffer [charsInBuffer++] = c;
-
- if (charsInBuffer == maxChars)
- {
- s.append (buffer, maxChars);
- charsInBuffer = 0;
- }
- }
-
- if (charsInBuffer > 0)
- s.append (buffer, charsInBuffer);
-
- return s;
- }
-
- int InputStream::readIntoMemoryBlock (MemoryBlock& block,
- int numBytes)
- {
- const int64 totalLength = getTotalLength();
-
- if (totalLength >= 0)
- {
- const int totalBytesRemaining = (int) jmin ((int64) 0x7fffffff,
- totalLength - getPosition());
-
- if (numBytes < 0)
- numBytes = totalBytesRemaining;
- else if (numBytes > 0)
- numBytes = jmin (numBytes, totalBytesRemaining);
- else
- return 0;
- }
-
- const int originalBlockSize = block.getSize();
- int totalBytesRead = 0;
-
- if (numBytes > 0)
- {
- // know how many bytes we want, so we can resize the block first..
- block.setSize (originalBlockSize + numBytes, false);
- totalBytesRead = read (((char*) block.getData()) + originalBlockSize, numBytes);
- }
- else
- {
- // read until end of stram..
- const int chunkSize = 32768;
-
- for (;;)
- {
- block.ensureSize (originalBlockSize + totalBytesRead + chunkSize, false);
-
- const int bytesJustIn = read (((char*) block.getData())
- + originalBlockSize
- + totalBytesRead,
- chunkSize);
-
- if (bytesJustIn == 0)
- break;
-
- totalBytesRead += bytesJustIn;
- }
- }
-
- // trim off any excess left at the end
- block.setSize (originalBlockSize + totalBytesRead, false);
- return totalBytesRead;
- }
-
- const String InputStream::readEntireStreamAsString()
- {
- MemoryBlock mb;
- const int size = readIntoMemoryBlock (mb);
-
- return String::createStringFromData ((const char*) mb.getData(), size);
- }
-
- void InputStream::skipNextBytes (int64 numBytesToSkip)
- {
- if (numBytesToSkip > 0)
- {
- const int skipBufferSize = (int) jmin (numBytesToSkip, (int64) 16384);
- MemoryBlock temp (skipBufferSize);
-
- while ((numBytesToSkip > 0) && ! isExhausted())
- {
- numBytesToSkip -= read (temp.getData(), (int) jmin (numBytesToSkip, (int64) skipBufferSize));
- }
- }
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_InputStream.cpp *********/
-
- /********* Start of inlined file: juce_OutputStream.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- #if JUCE_DEBUG
- static CriticalSection activeStreamLock;
- static VoidArray activeStreams;
-
- void juce_CheckForDanglingStreams()
- {
- /*
- It's always a bad idea to leak any object, but if you're leaking output
- streams, then there's a good chance that you're failing to flush a file
- to disk properly, which could result in corrupted data and other similar
- nastiness..
- */
- jassert (activeStreams.size() == 0);
- };
- #endif
-
- OutputStream::OutputStream() throw()
- {
- #if JUCE_DEBUG
- activeStreamLock.enter();
- activeStreams.add (this);
- activeStreamLock.exit();
- #endif
- }
-
- OutputStream::~OutputStream()
- {
- #if JUCE_DEBUG
- activeStreamLock.enter();
- activeStreams.removeValue (this);
- activeStreamLock.exit();
- #endif
- }
-
- void OutputStream::writeBool (bool b)
- {
- writeByte ((b) ? (char) 1
- : (char) 0);
- }
-
- void OutputStream::writeByte (char byte)
- {
- write (&byte, 1);
- }
-
- void OutputStream::writeShort (short value)
- {
- const unsigned short v = swapIfBigEndian ((unsigned short) value);
- write (&v, 2);
- }
-
- void OutputStream::writeShortBigEndian (short value)
- {
- const unsigned short v = swapIfLittleEndian ((unsigned short) value);
- write (&v, 2);
- }
-
- void OutputStream::writeInt (int value)
- {
- const unsigned int v = swapIfBigEndian ((unsigned int) value);
- write (&v, 4);
- }
-
- void OutputStream::writeIntBigEndian (int value)
- {
- const unsigned int v = swapIfLittleEndian ((unsigned int) value);
- write (&v, 4);
- }
-
- void OutputStream::writeCompressedInt (int value)
- {
- unsigned int un = (value < 0) ? (unsigned int) -value
- : (unsigned int) value;
- unsigned int tn = un;
-
- int numSigBytes = 0;
-
- do
- {
- tn >>= 8;
- numSigBytes++;
-
- } while (tn & 0xff);
-
- if (value < 0)
- numSigBytes |= 0x80;
-
- writeByte ((char) numSigBytes);
- write (&un, numSigBytes);
- }
-
- void OutputStream::writeInt64 (int64 value)
- {
- const uint64 v = swapIfBigEndian ((uint64) value);
- write (&v, 8);
- }
-
- void OutputStream::writeInt64BigEndian (int64 value)
- {
- const uint64 v = swapIfLittleEndian ((uint64) value);
- write (&v, 8);
- }
-
- void OutputStream::writeFloat (float value)
- {
- union { int asInt; float asFloat; } n;
- n.asFloat = value;
- writeInt (n.asInt);
- }
-
- void OutputStream::writeFloatBigEndian (float value)
- {
- union { int asInt; float asFloat; } n;
- n.asFloat = value;
- writeIntBigEndian (n.asInt);
- }
-
- void OutputStream::writeDouble (double value)
- {
- union { int64 asInt; double asDouble; } n;
- n.asDouble = value;
- writeInt64 (n.asInt);
- }
-
- void OutputStream::writeDoubleBigEndian (double value)
- {
- union { int64 asInt; double asDouble; } n;
- n.asDouble = value;
- writeInt64BigEndian (n.asInt);
- }
-
- void OutputStream::writeString (const String& text)
- {
- const int numBytes = text.copyToUTF8 (0);
- uint8* const temp = (uint8*) juce_malloc (numBytes);
-
- text.copyToUTF8 (temp);
- write (temp, numBytes); // (numBytes includes the terminating null).
-
- juce_free (temp);
- }
-
- void OutputStream::printf (const char* pf, ...)
- {
- unsigned int bufSize = 256;
- char* buf = (char*) juce_malloc (bufSize);
-
- for (;;)
- {
- va_list list;
- va_start (list, pf);
-
- const int num = CharacterFunctions::vprintf (buf, bufSize, pf, list);
-
- va_end (list);
-
- if (num > 0)
- {
- write (buf, num);
- break;
- }
- else if (num == 0)
- {
- break;
- }
-
- juce_free (buf);
- bufSize += 256;
- buf = (char*) juce_malloc (bufSize);
- }
-
- juce_free (buf);
- }
-
- OutputStream& OutputStream::operator<< (const int number)
- {
- const String s (number);
- write ((const char*) s, s.length());
- return *this;
- }
-
- OutputStream& OutputStream::operator<< (const double number)
- {
- const String s (number);
- write ((const char*) s, s.length());
- return *this;
- }
-
- OutputStream& OutputStream::operator<< (const char character)
- {
- writeByte (character);
- return *this;
- }
-
- OutputStream& OutputStream::operator<< (const char* const text)
- {
- write (text, (int) strlen (text));
- return *this;
- }
-
- OutputStream& OutputStream::operator<< (const juce_wchar* const text)
- {
- const String s (text);
- write ((const char*) s, s.length());
- return *this;
- }
-
- OutputStream& OutputStream::operator<< (const String& text)
- {
- write ((const char*) text,
- text.length());
-
- return *this;
- }
-
- void OutputStream::writeText (const String& text,
- const bool asUnicode,
- const bool writeUnicodeHeaderBytes)
- {
- if (asUnicode)
- {
- if (writeUnicodeHeaderBytes)
- write ("\x0ff\x0fe", 2);
-
- const juce_wchar* src = (const juce_wchar*) text;
- bool lastCharWasReturn = false;
-
- while (*src != 0)
- {
- if (*src == L'\n' && ! lastCharWasReturn)
- writeShort ((short) L'\r');
-
- lastCharWasReturn = (*src == L'\r');
- writeShort ((short) *src++);
- }
- }
- else
- {
- const char* src = (const char*) text;
- const char* t = src;
-
- for (;;)
- {
- if (*t == '\n')
- {
- if (t > src)
- write (src, (int) (t - src));
-
- write ("\r\n", 2);
- src = t + 1;
- }
- else if (*t == '\r')
- {
- if (t[1] == '\n')
- ++t;
- }
- else if (*t == 0)
- {
- if (t > src)
- write (src, (int) (t - src));
-
- break;
- }
-
- ++t;
- }
- }
- }
-
- int OutputStream::writeFromInputStream (InputStream& source,
- int numBytesToWrite)
- {
- if (numBytesToWrite < 0)
- numBytesToWrite = 0x7fffffff;
-
- int numWritten = 0;
-
- while (numBytesToWrite > 0 && ! source.isExhausted())
- {
- char buffer [8192];
-
- const int num = source.read (buffer, jmin (numBytesToWrite, sizeof (buffer)));
-
- if (num == 0)
- break;
-
- write (buffer, num);
-
- numBytesToWrite -= num;
- numWritten += num;
- }
-
- return numWritten;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_OutputStream.cpp *********/
-
- /********* Start of inlined file: juce_DirectoryIterator.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- void* juce_findFileStart (const String& directory, const String& wildCard, String& firstResultFile,
- bool* isDirectory, bool* isHidden, int64* fileSize,
- Time* modTime, Time* creationTime, bool* isReadOnly) throw();
- bool juce_findFileNext (void* handle, String& resultFile,
- bool* isDirectory, bool* isHidden, int64* fileSize,
- Time* modTime, Time* creationTime, bool* isReadOnly) throw();
- void juce_findFileClose (void* handle) throw();
-
- DirectoryIterator::DirectoryIterator (const File& directory,
- bool isRecursive,
- const String& wc,
- const int whatToLookFor_) throw()
- : wildCard (wc),
- index (-1),
- whatToLookFor (whatToLookFor_),
- subIterator (0)
- {
- // you have to specify the type of files you're looking for!
- jassert ((whatToLookFor_ & (File::findFiles | File::findDirectories)) != 0);
- jassert (whatToLookFor_ > 0 && whatToLookFor_ <= 7);
-
- String path (directory.getFullPathName());
- if (! path.endsWithChar (File::separator))
- path += File::separator;
-
- String filename;
- bool isDirectory, isHidden;
-
- void* const handle = juce_findFileStart (path,
- isRecursive ? T("*") : wc,
- filename, &isDirectory, &isHidden, 0, 0, 0, 0);
-
- if (handle != 0)
- {
- do
- {
- if (! filename.containsOnly (T(".")))
- {
- bool addToList = false;
-
- if (isDirectory)
- {
- if (isRecursive
- && ((whatToLookFor_ & File::ignoreHiddenFiles) == 0
- || ! isHidden))
- {
- dirsFound.add (new File (path + filename, 0));
- }
-
- addToList = (whatToLookFor_ & File::findDirectories) != 0;
- }
- else
- {
- addToList = (whatToLookFor_ & File::findFiles) != 0;
- }
-
- // if it's recursive, we're not relying on the OS iterator
- // to do the wildcard match, so do it now..
- if (isRecursive && addToList)
- addToList = filename.matchesWildcard (wc, true);
-
- if (addToList && (whatToLookFor_ & File::ignoreHiddenFiles) != 0)
- addToList = ! isHidden;
-
- if (addToList)
- filesFound.add (new File (path + filename, 0));
- }
-
- } while (juce_findFileNext (handle, filename, &isDirectory, &isHidden, 0, 0, 0, 0));
-
- juce_findFileClose (handle);
- }
- }
-
- DirectoryIterator::~DirectoryIterator() throw()
- {
- if (subIterator != 0)
- delete subIterator;
- }
-
- bool DirectoryIterator::next() throw()
- {
- if (subIterator != 0)
- {
- if (subIterator->next())
- return true;
-
- deleteAndZero (subIterator);
- }
-
- if (index >= filesFound.size() + dirsFound.size() - 1)
- return false;
-
- ++index;
-
- if (index >= filesFound.size())
- {
- subIterator = new DirectoryIterator (*(dirsFound [index - filesFound.size()]),
- true, wildCard, whatToLookFor);
- return next();
- }
-
- return true;
- }
-
- const File DirectoryIterator::getFile() const throw()
- {
- if (subIterator != 0)
- return subIterator->getFile();
-
- const File* const f = filesFound [index];
-
- return (f != 0) ? *f
- : File::nonexistent;
- }
-
- float DirectoryIterator::getEstimatedProgress() const throw()
- {
- if (filesFound.size() + dirsFound.size() == 0)
- {
- return 0.0f;
- }
- else
- {
- const float detailedIndex = (subIterator != 0) ? index + subIterator->getEstimatedProgress()
- : (float) index;
-
- return detailedIndex / (filesFound.size() + dirsFound.size());
- }
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_DirectoryIterator.cpp *********/
-
- /********* Start of inlined file: juce_File.cpp *********/
- #ifdef _MSC_VER
- #pragma warning (disable: 4514)
- #pragma warning (push)
- #endif
-
- #ifndef JUCE_WIN32
- #include <pwd.h>
- #endif
-
- BEGIN_JUCE_NAMESPACE
-
- #ifdef _MSC_VER
- #pragma warning (pop)
- #endif
-
- void* juce_fileOpen (const String& path, bool forWriting) throw();
- void juce_fileClose (void* handle) throw();
- int juce_fileWrite (void* handle, const void* buffer, int size) throw();
- int64 juce_fileGetPosition (void* handle) throw();
- int64 juce_fileSetPosition (void* handle, int64 pos) throw();
- void juce_fileFlush (void* handle) throw();
-
- bool juce_fileExists (const String& fileName, const bool dontCountDirectories) throw();
- bool juce_isDirectory (const String& fileName) throw();
- int64 juce_getFileSize (const String& fileName) throw();
- bool juce_canWriteToFile (const String& fileName) throw();
- bool juce_setFileReadOnly (const String& fileName, bool isReadOnly) throw();
-
- void juce_getFileTimes (const String& fileName, int64& modificationTime, int64& accessTime, int64& creationTime) throw();
- bool juce_setFileTimes (const String& fileName, int64 modificationTime, int64 accessTime, int64 creationTime) throw();
-
- bool juce_deleteFile (const String& fileName) throw();
- bool juce_copyFile (const String& source, const String& dest) throw();
- bool juce_moveFile (const String& source, const String& dest) throw();
-
- // this must also create all paths involved in the directory.
- void juce_createDirectory (const String& fileName) throw();
-
- bool juce_launchFile (const String& fileName, const String& parameters) throw();
-
- const StringArray juce_getFileSystemRoots() throw();
- const String juce_getVolumeLabel (const String& filenameOnVolume, int& volumeSerialNumber) throw();
-
- // starts a directory search operation with a wildcard, returning a handle for
- // use in calls to juce_findFileNext.
- // juce_firstResultFile gets the name of the file (not the whole pathname) and
- // the other pointers, if non-null, are set based on the properties of the file.
- void* juce_findFileStart (const String& directory, const String& wildCard, String& firstResultFile,
- bool* isDirectory, bool* isHidden, int64* fileSize, Time* modTime,
- Time* creationTime, bool* isReadOnly) throw();
-
- // returns false when no more files are found
- bool juce_findFileNext (void* handle, String& resultFile,
- bool* isDirectory, bool* isHidden, int64* fileSize,
- Time* modTime, Time* creationTime, bool* isReadOnly) throw();
-
- void juce_findFileClose (void* handle) throw();
-
- static const String parseAbsolutePath (String path) throw()
- {
- if (path.isEmpty())
- return String::empty;
-
- #if JUCE_WIN32
- // Windows..
- path = path.replaceCharacter (T('/'), T('\\')).unquoted();
-
- if (path.startsWithChar (File::separator))
- {
- if (path[1] != File::separator)
- {
- jassertfalse // using a filename that starts with a slash is a bit dodgy on
- // Windows, because it needs a drive letter, which in this case
- // we'll take from the CWD.. but this is a bit of an assumption that
- // could be wrong..
-
- path = File::getCurrentWorkingDirectory().getFullPathName().substring (0, 2) + path;
- }
- }
- else if (path.indexOfChar (T(':')) < 0)
- {
- if (path.isEmpty())
- return String::empty;
-
- jassertfalse // using a partial filename is a bad way to initialise a file, because
- // we don't know what directory to put it in.
- // Here we'll assume it's in the CWD, but this might not be what was
- // intended..
-
- return File::getCurrentWorkingDirectory().getChildFile (path).getFullPathName();
- }
- #else
- // Mac or Linux..
- path = path.replaceCharacter (T('\\'), T('/')).unquoted();
-
- if (path.startsWithChar (T('~')))
- {
- const char* homeDir = 0;
-
- if (path[1] == File::separator || path[1] == 0)
- {
- // expand a name of the form "~/abc"
- path = File::getSpecialLocation (File::userHomeDirectory).getFullPathName()
- + path.substring (1);
- }
- else
- {
- // expand a name of type "~dave/abc"
- const String userName (path.substring (1)
- .upToFirstOccurrenceOf (T("/"), false, false));
-
- struct passwd* const pw = getpwnam (userName);
- if (pw != 0)
- {
- String home (homeDir);
-
- if (home.endsWithChar (File::separator))
- home [home.length() - 1] = 0;
-
- path = String (pw->pw_dir)
- + path.substring (userName.length());
- }
- }
- }
- else if (! path.startsWithChar (File::separator))
- {
- while (path.startsWith (T("./")))
- path = path.substring (2);
-
- if (path.isEmpty())
- return String::empty;
-
- jassertfalse // using a partial filename is a bad way to initialise a file, because
- // we don't know what directory to put it in.
- // Here we'll assume it's in the CWD, but this might not be what was
- // intended..
-
- return File::getCurrentWorkingDirectory().getChildFile (path).getFullPathName();
- }
- #endif
-
- int len = path.length();
- while (--len > 0 && path [len] == File::separator)
- path [len] = 0;
-
- return path;
- }
-
- const File File::nonexistent;
-
- File::File (const String& fullPathName) throw()
- : fullPath (parseAbsolutePath (fullPathName))
- {
- }
-
- File::File (const String& path, int) throw()
- : fullPath (path)
- {
- }
-
- File::File (const File& other) throw()
- : fullPath (other.fullPath)
- {
- }
-
- const File& File::operator= (const String& newPath) throw()
- {
- fullPath = parseAbsolutePath (newPath);
- return *this;
- }
-
- const File& File::operator= (const File& other) throw()
- {
- fullPath = other.fullPath;
- return *this;
- }
-
- #if JUCE_LINUX
- #define NAMES_ARE_CASE_SENSITIVE 1
- #endif
-
- bool File::areFileNamesCaseSensitive()
- {
- #if NAMES_ARE_CASE_SENSITIVE
- return true;
- #else
- return false;
- #endif
- }
-
- bool File::operator== (const File& other) const throw()
- {
- // case-insensitive on Windows, but not on linux.
- #if NAMES_ARE_CASE_SENSITIVE
- return fullPath == other.fullPath;
- #else
- return fullPath.equalsIgnoreCase (other.fullPath);
- #endif
- }
-
- bool File::operator!= (const File& other) const throw()
- {
- return ! operator== (other);
- }
-
- bool File::exists() const throw()
- {
- return juce_fileExists (fullPath, false);
- }
-
- bool File::existsAsFile() const throw()
- {
- return juce_fileExists (fullPath, true);
- }
-
- bool File::isDirectory() const throw()
- {
- return juce_isDirectory (fullPath);
- }
-
- bool File::hasWriteAccess() const throw()
- {
- if (exists())
- return juce_canWriteToFile (fullPath);
-
- #ifndef JUCE_WIN32
- else if ((! isDirectory()) && fullPath.containsChar (separator))
- return getParentDirectory().hasWriteAccess();
- else
- return false;
- #else
- // on windows, it seems that even read-only directories can still be written into,
- // so checking the parent directory's permissions would return the wrong result..
- else
- return true;
- #endif
- }
-
- bool File::setReadOnly (const bool shouldBeReadOnly,
- const bool applyRecursively) const throw()
- {
- bool worked = true;
-
- if (applyRecursively && isDirectory())
- {
- OwnedArray <File> subFiles;
- findChildFiles (subFiles, File::findFilesAndDirectories, false);
-
- for (int i = subFiles.size(); --i >= 0;)
- worked = subFiles[i]->setReadOnly (shouldBeReadOnly, true) && worked;
- }
-
- return juce_setFileReadOnly (fullPath, shouldBeReadOnly) && worked;
- }
-
- bool File::deleteFile() const throw()
- {
- return (! exists())
- || juce_deleteFile (fullPath);
- }
-
- bool File::deleteRecursively() const throw()
- {
- bool worked = true;
-
- if (isDirectory())
- {
- OwnedArray<File> subFiles;
- findChildFiles (subFiles, File::findFilesAndDirectories, false);
-
- for (int i = subFiles.size(); --i >= 0;)
- worked = subFiles[i]->deleteRecursively() && worked;
- }
-
- return deleteFile() && worked;
- }
-
- bool File::moveFileTo (const File& newFile) const throw()
- {
- if (newFile.fullPath == fullPath)
- return true;
-
- #if ! NAMES_ARE_CASE_SENSITIVE
- if (*this != newFile)
- #endif
- if (! newFile.deleteFile())
- return false;
-
- return juce_moveFile (fullPath, newFile.fullPath);
- }
-
- bool File::copyFileTo (const File& newFile) const throw()
- {
- if (*this == newFile)
- return true;
-
- if (! newFile.deleteFile())
- return false;
-
- return juce_copyFile (fullPath, newFile.fullPath);
- }
-
- bool File::copyDirectoryTo (const File& newDirectory) const throw()
- {
- if (isDirectory() && newDirectory.createDirectory())
- {
- OwnedArray<File> subFiles;
- findChildFiles (subFiles, File::findFiles, false);
-
- int i;
- for (i = 0; i < subFiles.size(); ++i)
- if (! subFiles[i]->copyFileTo (newDirectory.getChildFile (subFiles[i]->getFileName())))
- return false;
-
- subFiles.clear();
- findChildFiles (subFiles, File::findDirectories, false);
-
- for (i = 0; i < subFiles.size(); ++i)
- if (! subFiles[i]->copyDirectoryTo (newDirectory.getChildFile (subFiles[i]->getFileName())))
- return false;
-
- return true;
- }
-
- return false;
- }
-
- const String File::getPathUpToLastSlash() const throw()
- {
- const int lastSlash = fullPath.lastIndexOfChar (separator);
-
- if (lastSlash > 0)
- return fullPath.substring (0, lastSlash);
- else if (lastSlash == 0)
- return separatorString;
- else
- return fullPath;
- }
-
- const File File::getParentDirectory() const throw()
- {
- return File (getPathUpToLastSlash());
- }
-
- const String File::getFileName() const throw()
- {
- return fullPath.substring (fullPath.lastIndexOfChar (separator) + 1);
- }
-
- int File::hashCode() const throw()
- {
- return fullPath.hashCode();
- }
-
- int64 File::hashCode64() const throw()
- {
- return fullPath.hashCode64();
- }
-
- const String File::getFileNameWithoutExtension() const throw()
- {
- const int lastSlash = fullPath.lastIndexOfChar (separator) + 1;
- const int lastDot = fullPath.lastIndexOfChar (T('.'));
-
- if (lastDot > lastSlash)
- return fullPath.substring (lastSlash, lastDot);
- else
- return fullPath.substring (lastSlash);
- }
-
- bool File::isAChildOf (const File& potentialParent) const throw()
- {
- const String ourPath (getPathUpToLastSlash());
-
- #if NAMES_ARE_CASE_SENSITIVE
- if (potentialParent.fullPath == ourPath)
- #else
- if (potentialParent.fullPath.equalsIgnoreCase (ourPath))
- #endif
- {
- return true;
- }
- else if (potentialParent.fullPath.length() >= ourPath.length())
- {
- return false;
- }
- else
- {
- return getParentDirectory().isAChildOf (potentialParent);
- }
- }
-
- bool File::isAbsolutePath (const String& path) throw()
- {
- return path.startsWithChar (T('/')) || path.startsWithChar (T('\\'))
- #if JUCE_WIN32
- || (path.isNotEmpty() && ((const String&) path)[1] == T(':'));
- #else
- || path.startsWithChar (T('~'));
- #endif
- }
-
- const File File::getChildFile (String relativePath) const throw()
- {
- if (isAbsolutePath (relativePath))
- {
- // the path is really absolute..
- return File (relativePath);
- }
- else
- {
- // it's relative, so remove any ../ or ./ bits at the start.
- String path (fullPath);
-
- if (relativePath[0] == T('.'))
- {
- #if JUCE_WIN32
- relativePath = relativePath.replaceCharacter (T('/'), T('\\')).trimStart();
- #else
- relativePath = relativePath.replaceCharacter (T('\\'), T('/')).trimStart();
- #endif
- while (relativePath[0] == T('.'))
- {
- if (relativePath[1] == T('.'))
- {
- if (relativePath [2] == 0 || relativePath[2] == separator)
- {
- const int lastSlash = path.lastIndexOfChar (separator);
- if (lastSlash > 0)
- path = path.substring (0, lastSlash);
-
- relativePath = relativePath.substring (3);
- }
- else
- {
- break;
- }
- }
- else if (relativePath[1] == separator)
- {
- relativePath = relativePath.substring (2);
- }
- else
- {
- break;
- }
- }
- }
-
- if (! path.endsWithChar (separator))
- path += separator;
-
- return File (path + relativePath);
- }
- }
-
- const File File::getSiblingFile (const String& fileName) const throw()
- {
- return getParentDirectory().getChildFile (fileName);
- }
-
- int64 File::getSize() const throw()
- {
- return juce_getFileSize (fullPath);
- }
-
- const String File::descriptionOfSizeInBytes (const int64 bytes)
- {
- if (bytes == 1)
- {
- return "1 byte";
- }
- else if (bytes < 1024)
- {
- return String ((int) bytes) + " bytes";
- }
- else if (bytes < 1024 * 1024)
- {
- return String (bytes / 1024.0, 1) + " KB";
- }
- else if (bytes < 1024 * 1024 * 1024)
- {
- return String (bytes / (1024.0 * 1024.0), 1) + " MB";
- }
- else
- {
- return String (bytes / (1024.0 * 1024.0 * 1024.0), 1) + " GB";
- }
- }
-
- bool File::create() const throw()
- {
- if (! exists())
- {
- const File parentDir (getParentDirectory());
-
- if (parentDir == *this || ! parentDir.createDirectory())
- return false;
-
- void* const fh = juce_fileOpen (fullPath, true);
-
- if (fh == 0)
- return false;
-
- juce_fileClose (fh);
- }
-
- return true;
- }
-
- bool File::createDirectory() const throw()
- {
- if (! isDirectory())
- {
- const File parentDir (getParentDirectory());
-
- if (parentDir == *this || ! parentDir.createDirectory())
- return false;
-
- String dir (fullPath);
-
- while (dir.endsWithChar (separator))
- dir [dir.length() - 1] = 0;
-
- juce_createDirectory (dir);
-
- return isDirectory();
- }
-
- return true;
- }
-
- const Time File::getCreationTime() const throw()
- {
- int64 m, a, c;
- juce_getFileTimes (fullPath, m, a, c);
- return Time (c);
- }
-
- bool File::setCreationTime (const Time& t) const throw()
- {
- return juce_setFileTimes (fullPath, 0, 0, t.toMilliseconds());
- }
-
- const Time File::getLastModificationTime() const throw()
- {
- int64 m, a, c;
- juce_getFileTimes (fullPath, m, a, c);
- return Time (m);
- }
-
- bool File::setLastModificationTime (const Time& t) const throw()
- {
- return juce_setFileTimes (fullPath, t.toMilliseconds(), 0, 0);
- }
-
- const Time File::getLastAccessTime() const throw()
- {
- int64 m, a, c;
- juce_getFileTimes (fullPath, m, a, c);
- return Time (a);
- }
-
- bool File::setLastAccessTime (const Time& t) const throw()
- {
- return juce_setFileTimes (fullPath, 0, t.toMilliseconds(), 0);
- }
-
- bool File::loadFileAsData (MemoryBlock& destBlock) const throw()
- {
- if (! existsAsFile())
- return false;
-
- FileInputStream in (*this);
- return getSize() == in.readIntoMemoryBlock (destBlock);
- }
-
- const String File::loadFileAsString() const throw()
- {
- if (! existsAsFile())
- return String::empty;
-
- FileInputStream in (*this);
- return in.readEntireStreamAsString();
- }
-
- static inline bool fileTypeMatches (const int whatToLookFor,
- const bool isDir,
- const bool isHidden)
- {
- return (whatToLookFor & (isDir ? File::findDirectories
- : File::findFiles)) != 0
- && ((! isHidden)
- || (whatToLookFor & File::ignoreHiddenFiles) == 0);
- }
-
- int File::findChildFiles (OwnedArray<File>& results,
- const int whatToLookFor,
- const bool searchRecursively,
- const String& wildCardPattern) const throw()
- {
- // you have to specify the type of files you're looking for!
- jassert ((whatToLookFor & (findFiles | findDirectories)) != 0);
-
- int total = 0;
-
- // find child files or directories in this directory first..
- if (isDirectory())
- {
- String path (fullPath);
- if (! path.endsWithChar (separator))
- path += separator;
-
- String filename;
- bool isDirectory, isHidden;
-
- void* const handle = juce_findFileStart (path,
- wildCardPattern,
- filename,
- &isDirectory, &isHidden,
- 0, 0, 0, 0);
-
- if (handle != 0)
- {
- do
- {
- if (fileTypeMatches (whatToLookFor, isDirectory, isHidden)
- && ! filename.containsOnly (T(".")))
- {
- results.add (new File (path + filename, 0));
- ++total;
- }
-
- } while (juce_findFileNext (handle, filename, &isDirectory, &isHidden, 0, 0, 0, 0));
-
- juce_findFileClose (handle);
- }
- }
- else
- {
- // trying to search for files inside a non-directory?
- //jassertfalse
- }
-
- // and recurse down if required.
- if (searchRecursively)
- {
- OwnedArray <File> subDirectories;
- findChildFiles (subDirectories, File::findDirectories, false);
-
- for (int i = 0; i < subDirectories.size(); ++i)
- {
- total += subDirectories.getUnchecked(i)
- ->findChildFiles (results,
- whatToLookFor,
- true,
- wildCardPattern);
- }
- }
-
- return total;
- }
-
- int File::getNumberOfChildFiles (const int whatToLookFor,
- const String& wildCardPattern) const throw()
- {
- // you have to specify the type of files you're looking for!
- jassert (whatToLookFor > 0 && whatToLookFor <= 3);
-
- int count = 0;
-
- if (isDirectory())
- {
- String filename;
- bool isDirectory, isHidden;
-
- void* const handle = juce_findFileStart (fullPath,
- wildCardPattern,
- filename,
- &isDirectory, &isHidden,
- 0, 0, 0, 0);
-
- if (handle != 0)
- {
- do
- {
- if (fileTypeMatches (whatToLookFor, isDirectory, isHidden)
- && ! filename.containsOnly (T(".")))
- {
- ++count;
- }
-
- } while (juce_findFileNext (handle, filename, &isDirectory, &isHidden, 0, 0, 0, 0));
-
- juce_findFileClose (handle);
- }
- }
- else
- {
- // trying to search for files inside a non-directory?
- jassertfalse
- }
-
- return count;
- }
-
- const File File::getNonexistentChildFile (const String& prefix_,
- const String& suffix,
- bool putNumbersInBrackets) const throw()
- {
- File f (getChildFile (prefix_ + suffix));
-
- if (f.exists())
- {
- int num = 2;
- String prefix (prefix_);
-
- // remove any bracketed numbers that may already be on the end..
- if (prefix.trim().endsWithChar (T(')')))
- {
- putNumbersInBrackets = true;
-
- const int openBracks = prefix.lastIndexOfChar (T('('));
- const int closeBracks = prefix.lastIndexOfChar (T(')'));
-
- if (openBracks > 0
- && closeBracks > openBracks
- && prefix.substring (openBracks + 1, closeBracks).containsOnly (T("0123456789")))
- {
- num = prefix.substring (openBracks + 1, closeBracks).getIntValue() + 1;
- prefix = prefix.substring (0, openBracks);
- }
- }
-
- // also use brackets if it ends in a digit.
- putNumbersInBrackets = putNumbersInBrackets
- || CharacterFunctions::isDigit (prefix.getLastCharacter());
-
- do
- {
- if (putNumbersInBrackets)
- f = getChildFile (prefix + T('(') + String (num++) + T(')') + suffix);
- else
- f = getChildFile (prefix + String (num++) + suffix);
-
- } while (f.exists());
- }
-
- return f;
- }
-
- const File File::getNonexistentSibling (const bool putNumbersInBrackets) const throw()
- {
- if (exists())
- {
- return getParentDirectory()
- .getNonexistentChildFile (getFileNameWithoutExtension(),
- getFileExtension(),
- putNumbersInBrackets);
- }
- else
- {
- return *this;
- }
- }
-
- const String File::getFileExtension() const throw()
- {
- String ext;
-
- if (! isDirectory())
- {
- const int indexOfDot = fullPath.lastIndexOfChar (T('.'));
-
- if (indexOfDot > fullPath.lastIndexOfChar (separator))
- ext = fullPath.substring (indexOfDot);
- }
-
- return ext;
- }
-
- bool File::hasFileExtension (const String& possibleSuffix) const throw()
- {
- if (possibleSuffix.isEmpty())
- return fullPath.lastIndexOfChar (T('.')) <= fullPath.lastIndexOfChar (separator);
-
- if (fullPath.endsWithIgnoreCase (possibleSuffix))
- {
- if (possibleSuffix.startsWithChar (T('.')))
- return true;
-
- const int dotPos = fullPath.length() - possibleSuffix.length() - 1;
-
- if (dotPos >= 0)
- return fullPath [dotPos] == T('.');
- }
-
- return false;
- }
-
- const File File::withFileExtension (const String& newExtension) const throw()
- {
- if (fullPath.isEmpty())
- return File::nonexistent;
-
- String filePart (getFileName());
-
- int i = filePart.lastIndexOfChar (T('.'));
- if (i < 0)
- i = filePart.length();
-
- String newExt (newExtension);
-
- if (newExt.isNotEmpty() && ! newExt.startsWithChar (T('.')))
- newExt = T(".") + newExt;
-
- return getSiblingFile (filePart.substring (0, i) + newExt);
- }
-
- bool File::startAsProcess (const String& parameters) const throw()
- {
- return exists()
- && juce_launchFile (fullPath, parameters);
- }
-
- FileInputStream* File::createInputStream() const throw()
- {
- if (existsAsFile())
- return new FileInputStream (*this);
- else
- return 0;
- }
-
- FileOutputStream* File::createOutputStream (const int bufferSize) const throw()
- {
- FileOutputStream* const out = new FileOutputStream (*this, bufferSize);
-
- if (out->failedToOpen())
- {
- delete out;
- return 0;
- }
- else
- {
- return out;
- }
- }
-
- bool File::appendData (const void* const dataToAppend,
- const int numberOfBytes) const throw()
- {
- if (numberOfBytes > 0)
- {
- FileOutputStream* const out = createOutputStream();
-
- if (out == 0)
- return false;
-
- out->write (dataToAppend, numberOfBytes);
- delete out;
- }
-
- return true;
- }
-
- bool File::replaceWithData (const void* const dataToWrite,
- const int numberOfBytes) const throw()
- {
- jassert (numberOfBytes >= 0); // a negative number of bytes??
-
- if (numberOfBytes <= 0)
- return deleteFile();
-
- const File tempFile (getSiblingFile (T(".") + getFileName()).getNonexistentSibling (false));
-
- if (tempFile.appendData (dataToWrite, numberOfBytes)
- && tempFile.moveFileTo (*this))
- {
- return true;
- }
-
- tempFile.deleteFile();
- return false;
- }
-
- bool File::appendText (const String& text,
- const bool asUnicode,
- const bool writeUnicodeHeaderBytes) const throw()
- {
- FileOutputStream* const out = createOutputStream();
-
- if (out != 0)
- {
- out->writeText (text, asUnicode, writeUnicodeHeaderBytes);
- delete out;
-
- return true;
- }
-
- return false;
- }
-
- bool File::printf (const tchar* pf, ...) const throw()
- {
- va_list list;
- va_start (list, pf);
-
- String text;
- text.vprintf (pf, list);
-
- return appendData ((const char*) text, text.length());
- }
-
- bool File::replaceWithText (const String& textToWrite,
- const bool asUnicode,
- const bool writeUnicodeHeaderBytes) const throw()
- {
- const File tempFile (getSiblingFile (T(".") + getFileName()).getNonexistentSibling (false));
-
- if (tempFile.appendText (textToWrite, asUnicode, writeUnicodeHeaderBytes)
- && tempFile.moveFileTo (*this))
- {
- return true;
- }
-
- tempFile.deleteFile();
- return false;
- }
-
- const String File::createLegalPathName (const String& original) throw()
- {
- String s (original);
- String start;
-
- if (s[1] == T(':'))
- {
- start = s.substring (0, 2);
- s = s.substring (2);
- }
-
- return start + s.removeCharacters (T("\"#@,;:<>*^|?"))
- .substring (0, 1024);
- }
-
- const String File::createLegalFileName (const String& original) throw()
- {
- String s (original.removeCharacters (T("\"#@,;:<>*^|?\\/")));
-
- const int maxLength = 128; // only the length of the filename, not the whole path
- const int len = s.length();
-
- if (len > maxLength)
- {
- const int lastDot = s.lastIndexOfChar (T('.'));
-
- if (lastDot > jmax (0, len - 12))
- {
- s = s.substring (0, maxLength - (len - lastDot))
- + s.substring (lastDot);
- }
- else
- {
- s = s.substring (0, maxLength);
- }
- }
-
- return s;
- }
-
- const String File::getRelativePathFrom (const File& dir) const throw()
- {
- String thisPath (fullPath);
-
- {
- int len = thisPath.length();
- while (--len >= 0 && thisPath [len] == File::separator)
- thisPath [len] = 0;
- }
-
- String dirPath ((dir.existsAsFile()) ? dir.getParentDirectory().getFullPathName()
- : dir.fullPath);
-
- if (! dirPath.endsWithChar (separator))
- dirPath += separator;
-
- const int len = jmin (thisPath.length(), dirPath.length());
- int commonBitLength = 0;
-
- for (int i = 0; i < len; ++i)
- {
- #if NAMES_ARE_CASE_SENSITIVE
- if (thisPath[i] != dirPath[i])
- #else
- if (CharacterFunctions::toLowerCase (thisPath[i])
- != CharacterFunctions::toLowerCase (dirPath[i]))
- #endif
- {
- break;
- }
-
- ++commonBitLength;
- }
-
- while (commonBitLength > 0 && thisPath [commonBitLength - 1] != File::separator)
- --commonBitLength;
-
- // if the only common bit is the root, then just return the full path..
- #if JUCE_WIN32
- if (commonBitLength <= 0
- || (commonBitLength == 1 && thisPath [1] == File::separator)
- || (commonBitLength <= 3 && thisPath [1] == T(':')))
- #else
- if (commonBitLength <= 0
- || (commonBitLength == 1 && thisPath [1] == File::separator))
- #endif
- return fullPath;
-
- thisPath = thisPath.substring (commonBitLength);
- dirPath = dirPath.substring (commonBitLength);
-
- while (dirPath.isNotEmpty())
- {
- #if JUCE_WIN32
- thisPath = T("..\\") + thisPath;
- #else
- thisPath = T("../") + thisPath;
- #endif
-
- const int sep = dirPath.indexOfChar (separator);
-
- if (sep >= 0)
- dirPath = dirPath.substring (sep + 1);
- else
- dirPath = String::empty;
- }
-
- return thisPath;
- }
-
- void File::findFileSystemRoots (OwnedArray<File>& destArray) throw()
- {
- const StringArray roots (juce_getFileSystemRoots());
-
- for (int i = 0; i < roots.size(); ++i)
- destArray.add (new File (roots[i]));
- }
-
- const String File::getVolumeLabel() const throw()
- {
- int serialNum;
- return juce_getVolumeLabel (fullPath, serialNum);
- }
-
- int File::getVolumeSerialNumber() const throw()
- {
- int serialNum;
- juce_getVolumeLabel (fullPath, serialNum);
-
- return serialNum;
- }
-
- const File File::createTempFile (const String& fileNameEnding) throw()
- {
- String tempName (T("temp"));
- static int tempNum = 0;
- tempName << tempNum++ << fileNameEnding;
-
- const File tempFile (getSpecialLocation (tempDirectory)
- .getChildFile (tempName));
-
- if (tempFile.exists())
- return createTempFile (fileNameEnding);
- else
- return tempFile;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_File.cpp *********/
-
- /********* Start of inlined file: juce_FileInputStream.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- void* juce_fileOpen (const String& path, bool forWriting) throw();
- void juce_fileClose (void* handle) throw();
- int juce_fileRead (void* handle, void* buffer, int size) throw();
- int64 juce_fileSetPosition (void* handle, int64 pos) throw();
-
- FileInputStream::FileInputStream (const File& f)
- : file (f),
- currentPosition (0),
- needToSeek (true)
- {
- totalSize = f.getSize();
-
- fileHandle = juce_fileOpen (f.getFullPathName(), false);
- }
-
- FileInputStream::~FileInputStream()
- {
- juce_fileClose (fileHandle);
- }
-
- int64 FileInputStream::getTotalLength()
- {
- return totalSize;
- }
-
- int FileInputStream::read (void* buffer, int bytesToRead)
- {
- int num = 0;
-
- if (needToSeek)
- {
- if (juce_fileSetPosition (fileHandle, currentPosition) < 0)
- return 0;
-
- needToSeek = false;
- }
-
- num = juce_fileRead (fileHandle, buffer, bytesToRead);
- currentPosition += num;
-
- return num;
- }
-
- bool FileInputStream::isExhausted()
- {
- return currentPosition >= totalSize;
- }
-
- int64 FileInputStream::getPosition()
- {
- return currentPosition;
- }
-
- bool FileInputStream::setPosition (int64 pos)
- {
- pos = jlimit ((int64) 0, totalSize, pos);
-
- needToSeek |= (currentPosition != pos);
- currentPosition = pos;
-
- return true;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_FileInputStream.cpp *********/
-
- /********* Start of inlined file: juce_FileOutputStream.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- void* juce_fileOpen (const String& path, bool forWriting) throw();
- void juce_fileClose (void* handle) throw();
- int juce_fileWrite (void* handle, const void* buffer, int size) throw();
- void juce_fileFlush (void* handle) throw();
- int64 juce_fileGetPosition (void* handle) throw();
- int64 juce_fileSetPosition (void* handle, int64 pos) throw();
-
- FileOutputStream::FileOutputStream (const File& f,
- const int bufferSize_)
- : file (f),
- bufferSize (bufferSize_),
- bytesInBuffer (0)
- {
- fileHandle = juce_fileOpen (f.getFullPathName(), true);
-
- if (fileHandle != 0)
- {
- currentPosition = juce_fileGetPosition (fileHandle);
-
- if (currentPosition < 0)
- {
- jassertfalse
- juce_fileClose (fileHandle);
- fileHandle = 0;
- }
- }
-
- buffer = (char*) juce_malloc (jmax (bufferSize_, 16));
- }
-
- FileOutputStream::~FileOutputStream()
- {
- flush();
-
- juce_fileClose (fileHandle);
- juce_free (buffer);
- }
-
- int64 FileOutputStream::getPosition()
- {
- return currentPosition;
- }
-
- bool FileOutputStream::setPosition (int64 newPosition)
- {
- if (newPosition != currentPosition)
- {
- flush();
- currentPosition = juce_fileSetPosition (fileHandle, newPosition);
- }
-
- return newPosition == currentPosition;
- }
-
- void FileOutputStream::flush()
- {
- if (bytesInBuffer > 0)
- {
- juce_fileWrite (fileHandle, buffer, bytesInBuffer);
- bytesInBuffer = 0;
- }
-
- juce_fileFlush (fileHandle);
- }
-
- bool FileOutputStream::write (const void* const src, const int numBytes)
- {
- if (bytesInBuffer + numBytes < bufferSize)
- {
- memcpy (buffer + bytesInBuffer, src, numBytes);
- bytesInBuffer += numBytes;
- currentPosition += numBytes;
- }
- else
- {
- if (bytesInBuffer > 0)
- {
- // flush the reservoir
- const bool wroteOk = (juce_fileWrite (fileHandle, buffer, bytesInBuffer) == bytesInBuffer);
- bytesInBuffer = 0;
-
- if (! wroteOk)
- return false;
- }
-
- if (numBytes < bufferSize)
- {
- memcpy (buffer + bytesInBuffer, src, numBytes);
- bytesInBuffer += numBytes;
- currentPosition += numBytes;
- }
- else
- {
- const int bytesWritten = juce_fileWrite (fileHandle, src, numBytes);
- currentPosition += bytesWritten;
-
- return bytesWritten == numBytes;
- }
- }
-
- return true;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_FileOutputStream.cpp *********/
-
- /********* Start of inlined file: juce_FileSearchPath.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- FileSearchPath::FileSearchPath()
- {
- }
-
- FileSearchPath::FileSearchPath (const String& path)
- {
- init (path);
- }
-
- FileSearchPath::FileSearchPath (const FileSearchPath& other)
- : directories (other.directories)
- {
- }
-
- FileSearchPath::~FileSearchPath()
- {
- }
-
- const FileSearchPath& FileSearchPath::operator= (const String& path)
- {
- init (path);
- return *this;
- }
-
- void FileSearchPath::init (const String& path)
- {
- directories.clear();
- directories.addTokens (path, T(";"), T("\""));
- directories.trim();
- directories.removeEmptyStrings();
-
- for (int i = directories.size(); --i >= 0;)
- directories.set (i, directories[i].unquoted());
- }
-
- int FileSearchPath::getNumPaths() const
- {
- return directories.size();
- }
-
- const File FileSearchPath::operator[] (const int index) const
- {
- return File (directories [index]);
- }
-
- const String FileSearchPath::toString() const
- {
- StringArray directories2 (directories);
- for (int i = directories2.size(); --i >= 0;)
- if (directories2[i].containsChar (T(';')))
- directories2.set (i, directories2[i].quoted());
-
- return directories2.joinIntoString (T(";"));
- }
-
- void FileSearchPath::add (const File& dir, const int insertIndex)
- {
- directories.insert (insertIndex, dir.getFullPathName());
- }
-
- void FileSearchPath::addIfNotAlreadyThere (const File& dir)
- {
- for (int i = 0; i < directories.size(); ++i)
- if (File (directories[i]) == dir)
- return;
-
- add (dir);
- }
-
- void FileSearchPath::remove (const int index)
- {
- directories.remove (index);
- }
-
- void FileSearchPath::addPath (const FileSearchPath& other)
- {
- for (int i = 0; i < other.getNumPaths(); ++i)
- addIfNotAlreadyThere (other[i]);
- }
-
- void FileSearchPath::removeRedundantPaths()
- {
- for (int i = directories.size(); --i >= 0;)
- {
- const File d1 (directories[i]);
-
- for (int j = directories.size(); --j >= 0;)
- {
- const File d2 (directories[j]);
-
- if ((i != j) && (d1.isAChildOf (d2) || d1 == d2))
- {
- directories.remove (i);
- break;
- }
- }
- }
- }
-
- void FileSearchPath::removeNonExistentPaths()
- {
- for (int i = directories.size(); --i >= 0;)
- if (! File (directories[i]).isDirectory())
- directories.remove (i);
- }
-
- int FileSearchPath::findChildFiles (OwnedArray<File>& results,
- const int whatToLookFor,
- const bool searchRecursively,
- const String& wildCardPattern) const
- {
- int total = 0;
-
- for (int i = 0; i < directories.size(); ++i)
- total += operator[] (i).findChildFiles (results,
- whatToLookFor,
- searchRecursively,
- wildCardPattern);
-
- return total;
- }
-
- bool FileSearchPath::isFileInPath (const File& fileToCheck,
- const bool checkRecursively) const
- {
- for (int i = directories.size(); --i >= 0;)
- {
- const File d (directories[i]);
-
- if (checkRecursively)
- {
- if (fileToCheck.isAChildOf (d))
- return true;
- }
- else
- {
- if (fileToCheck.getParentDirectory() == d)
- return true;
- }
- }
-
- return false;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_FileSearchPath.cpp *********/
-
- /********* Start of inlined file: juce_NamedPipe.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- NamedPipe::NamedPipe()
- : internal (0)
- {
- }
-
- NamedPipe::~NamedPipe()
- {
- close();
- }
-
- bool NamedPipe::openExisting (const String& pipeName)
- {
- currentPipeName = pipeName;
- return openInternal (pipeName, false);
- }
-
- bool NamedPipe::createNewPipe (const String& pipeName)
- {
- currentPipeName = pipeName;
- return openInternal (pipeName, true);
- }
-
- bool NamedPipe::isOpen() const throw()
- {
- return internal != 0;
- }
-
- const String NamedPipe::getName() const throw()
- {
- return currentPipeName;
- }
-
- // other methods for this class are implemented in the platform-specific files
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_NamedPipe.cpp *********/
-
- /********* Start of inlined file: juce_Socket.cpp *********/
- #ifdef _WIN32
-
- #include <winsock2.h>
-
- #ifdef _MSC_VER
- #pragma warning (disable : 4127 4389 4018)
- #endif
-
- #else
- #ifndef LINUX
- #include <Carbon/Carbon.h>
- #endif
-
- #include <sys/types.h>
- #include <netdb.h>
- #include <sys/socket.h>
- #include <arpa/inet.h>
- #include <sys/errno.h>
- #include <netinet/tcp.h>
- #include <netinet/in.h>
- #include <fcntl.h>
- #include <unistd.h>
- #endif
-
- BEGIN_JUCE_NAMESPACE
-
- #if JUCE_WIN32
-
- typedef int (__stdcall juce_CloseWin32SocketLibCall) (void);
- juce_CloseWin32SocketLibCall* juce_CloseWin32SocketLib = 0;
-
- static void initWin32Sockets()
- {
- static CriticalSection lock;
- const ScopedLock sl (lock);
-
- if (juce_CloseWin32SocketLib == 0)
- {
- WSADATA wsaData;
- const WORD wVersionRequested = MAKEWORD (1, 1);
- WSAStartup (wVersionRequested, &wsaData);
-
- juce_CloseWin32SocketLib = &WSACleanup;
- }
- }
-
- #endif
-
- static bool resetSocketOptions (const int handle, const bool isDatagram) throw()
- {
- if (handle <= 0)
- return false;
-
- const int sndBufSize = 65536;
- const int rcvBufSize = 65536;
- const int one = 1;
-
- return setsockopt (handle, SOL_SOCKET, SO_RCVBUF, (const char*) &rcvBufSize, sizeof (int)) == 0
- && setsockopt (handle, SOL_SOCKET, SO_SNDBUF, (const char*) &sndBufSize, sizeof (int)) == 0
- && (isDatagram || (setsockopt (handle, IPPROTO_TCP, TCP_NODELAY, (const char*) &one, sizeof (int)) == 0));
- }
-
- static bool bindSocketToPort (const int handle, const int port) throw()
- {
- if (handle == 0 || port <= 0)
- return false;
-
- struct sockaddr_in servTmpAddr;
- zerostruct (servTmpAddr);
- servTmpAddr.sin_family = PF_INET;
- servTmpAddr.sin_addr.s_addr = htonl (INADDR_ANY);
- servTmpAddr.sin_port = htons ((uint16) port);
-
- return bind (handle, (struct sockaddr*) &servTmpAddr, sizeof (struct sockaddr_in)) >= 0;
- }
-
- static int readSocket (const int handle,
- void* const destBuffer, const int maxBytesToRead,
- bool volatile& connected) throw()
- {
- int bytesRead = 0;
-
- while (bytesRead < maxBytesToRead)
- {
- int bytesThisTime;
-
- #if JUCE_WIN32
- bytesThisTime = recv (handle, ((char*) destBuffer) + bytesRead, maxBytesToRead - bytesRead, 0);
- #else
- while ((bytesThisTime = ::read (handle, ((char*) destBuffer) + bytesRead, maxBytesToRead - bytesRead)) < 0
- && errno == EINTR
- && connected)
- {
- }
- #endif
-
- if (bytesThisTime <= 0 || ! connected)
- {
- if (bytesRead == 0)
- bytesRead = -1;
-
- break;
- }
-
- bytesRead += bytesThisTime;
- }
-
- return bytesRead;
- }
-
- static int waitForReadiness (const int handle, const bool forReading,
- const int timeoutMsecs) throw()
- {
- struct timeval timeout;
- struct timeval* timeoutp;
-
- if (timeoutMsecs >= 0)
- {
- timeout.tv_sec = timeoutMsecs / 1000;
- timeout.tv_usec = (timeoutMsecs % 1000) * 1000;
- timeoutp = &timeout;
- }
- else
- {
- timeoutp = 0;
- }
-
- fd_set rset, wset;
- FD_ZERO (&rset);
- FD_SET (handle, &rset);
- FD_ZERO (&wset);
- FD_SET (handle, &wset);
-
- fd_set* const prset = forReading ? &rset : 0;
- fd_set* const pwset = forReading ? 0 : &wset;
-
- #if JUCE_WIN32
- if (select (handle + 1, prset, pwset, 0, timeoutp) < 0)
- return -1;
- #else
- {
- int result;
- while ((result = select (handle + 1, prset, pwset, 0, timeoutp)) < 0
- && errno == EINTR)
- {
- }
-
- if (result < 0)
- return -1;
- }
- #endif
-
- {
- int opt;
-
- #if defined (JUCE_LINUX) || (defined (JUCE_MAC) && ! MACOS_10_2_OR_EARLIER)
- socklen_t len = sizeof (opt);
- #else
- int len = sizeof (opt);
- #endif
-
- if (getsockopt (handle, SOL_SOCKET, SO_ERROR, (char*) &opt, &len) < 0
- || opt != 0)
- return -1;
- }
-
- if ((forReading && FD_ISSET (handle, &rset))
- || ((! forReading) && FD_ISSET (handle, &wset)))
- return 1;
-
- return 0;
- }
-
- static bool setSocketBlockingState (const int handle, const bool shouldBlock) throw()
- {
- #if JUCE_WIN32
- u_long nonBlocking = shouldBlock ? 0 : 1;
-
- if (ioctlsocket (handle, FIONBIO, &nonBlocking) != 0)
- return false;
- #else
- int socketFlags = fcntl (handle, F_GETFL, 0);
-
- if (socketFlags == -1)
- return false;
-
- if (shouldBlock)
- socketFlags &= ~O_NONBLOCK;
- else
- socketFlags |= O_NONBLOCK;
-
- if (fcntl (handle, F_SETFL, socketFlags) != 0)
- return false;
- #endif
-
- return true;
- }
-
- static bool connectSocket (int volatile& handle,
- const bool isDatagram,
- void** serverAddress,
- const String& hostName,
- const int portNumber,
- const int timeOutMillisecs) throw()
- {
- struct hostent* const hostEnt = gethostbyname (hostName);
-
- if (hostEnt == 0)
- return false;
-
- struct in_addr targetAddress;
- memcpy (&targetAddress.s_addr,
- *(hostEnt->h_addr_list),
- sizeof (targetAddress.s_addr));
-
- struct sockaddr_in servTmpAddr;
- zerostruct (servTmpAddr);
- servTmpAddr.sin_family = PF_INET;
- servTmpAddr.sin_addr = targetAddress;
- servTmpAddr.sin_port = htons ((uint16) portNumber);
-
- if (handle < 0)
- handle = (int) socket (AF_INET, isDatagram ? SOCK_DGRAM : SOCK_STREAM, 0);
-
- if (handle < 0)
- return false;
-
- if (isDatagram)
- {
- *serverAddress = new struct sockaddr_in();
- *((struct sockaddr_in*) *serverAddress) = servTmpAddr;
-
- return true;
- }
-
- setSocketBlockingState (handle, false);
-
- const int result = ::connect (handle, (struct sockaddr*) &servTmpAddr, sizeof (struct sockaddr_in));
-
- if (result < 0)
- {
- #if JUCE_WIN32
- if (result == SOCKET_ERROR && WSAGetLastError() == WSAEWOULDBLOCK)
- #else
- if (errno == EINPROGRESS)
- #endif
- {
- if (waitForReadiness (handle, false, timeOutMillisecs) != 1)
- {
- setSocketBlockingState (handle, true);
- return false;
- }
- }
- }
-
- setSocketBlockingState (handle, true);
- resetSocketOptions (handle, false);
-
- return true;
- }
-
- StreamingSocket::StreamingSocket()
- : portNumber (0),
- handle (-1),
- connected (false),
- isListener (false)
- {
- #if JUCE_WIN32
- initWin32Sockets();
- #endif
- }
-
- StreamingSocket::StreamingSocket (const String& hostName_,
- const int portNumber_,
- const int handle_)
- : hostName (hostName_),
- portNumber (portNumber_),
- handle (handle_),
- connected (true),
- isListener (false)
- {
- #if JUCE_WIN32
- initWin32Sockets();
- #endif
-
- resetSocketOptions (handle_, false);
- }
-
- StreamingSocket::~StreamingSocket()
- {
- close();
- }
-
- int StreamingSocket::read (void* destBuffer, const int maxBytesToRead)
- {
- return (connected && ! isListener) ? readSocket (handle, destBuffer, maxBytesToRead, connected)
- : -1;
- }
-
- int StreamingSocket::write (const void* sourceBuffer, const int numBytesToWrite)
- {
- if (isListener || ! connected)
- return -1;
-
- #if JUCE_WIN32
- return send (handle, (const char*) sourceBuffer, numBytesToWrite, 0);
- #else
- int result;
-
- while ((result = ::write (handle, sourceBuffer, numBytesToWrite)) < 0
- && errno == EINTR)
- {
- }
-
- return result;
- #endif
- }
-
- int StreamingSocket::waitUntilReady (const bool readyForReading,
- const int timeoutMsecs) const
- {
- return connected ? waitForReadiness (handle, readyForReading, timeoutMsecs)
- : -1;
- }
-
- bool StreamingSocket::bindToPort (const int port)
- {
- return bindSocketToPort (handle, port);
- }
-
- bool StreamingSocket::connect (const String& remoteHostName,
- const int remotePortNumber,
- const int timeOutMillisecs)
- {
- if (isListener)
- {
- jassertfalse // a listener socket can't connect to another one!
- return false;
- }
-
- if (connected)
- close();
-
- hostName = remoteHostName;
- portNumber = remotePortNumber;
- isListener = false;
-
- connected = connectSocket (handle, false, 0, remoteHostName,
- remotePortNumber, timeOutMillisecs);
-
- if (! (connected && resetSocketOptions (handle, false)))
- {
- close();
- return false;
- }
-
- return true;
- }
-
- void StreamingSocket::close()
- {
- #if JUCE_WIN32
- closesocket (handle);
- connected = false;
- #else
- if (connected)
- {
- connected = false;
-
- if (isListener)
- {
- // need to do this to interrupt the accept() function..
- StreamingSocket temp;
- temp.connect ("localhost", portNumber, 1000);
- }
- }
-
- ::close (handle);
- #endif
-
- hostName = String::empty;
- portNumber = 0;
- handle = -1;
- isListener = false;
- }
-
- bool StreamingSocket::createListener (const int newPortNumber)
- {
- if (connected)
- close();
-
- hostName = "listener";
- portNumber = newPortNumber;
- isListener = true;
-
- struct sockaddr_in servTmpAddr;
- zerostruct (servTmpAddr);
- servTmpAddr.sin_family = PF_INET;
- servTmpAddr.sin_addr.s_addr = htonl (INADDR_ANY);
- servTmpAddr.sin_port = htons ((uint16) portNumber);
-
- handle = (int) socket (AF_INET, SOCK_STREAM, 0);
-
- if (handle < 0)
- return false;
-
- const int reuse = 1;
- setsockopt (handle, SOL_SOCKET, SO_REUSEADDR, (const char*) &reuse, sizeof (reuse));
-
- if (bind (handle, (struct sockaddr*) &servTmpAddr, sizeof (struct sockaddr_in)) < 0
- || listen (handle, SOMAXCONN) < 0)
- {
- close();
- return false;
- }
-
- connected = true;
- return true;
- }
-
- StreamingSocket* StreamingSocket::waitForNextConnection() const
- {
- jassert (isListener || ! connected); // to call this method, you first have to use createListener() to
- // prepare this socket as a listener.
-
- if (connected && isListener)
- {
- struct sockaddr address;
-
- #if defined (JUCE_LINUX) || (defined (JUCE_MAC) && ! MACOS_10_2_OR_EARLIER)
- socklen_t len = sizeof (sockaddr);
- #else
- int len = sizeof (sockaddr);
- #endif
- const int newSocket = (int) accept (handle, &address, &len);
-
- if (newSocket >= 0 && connected)
- return new StreamingSocket (inet_ntoa (((struct sockaddr_in*) &address)->sin_addr),
- portNumber, newSocket);
- }
-
- return 0;
- }
-
- bool StreamingSocket::isLocal() const throw()
- {
- return hostName == T("127.0.0.1");
- }
-
- DatagramSocket::DatagramSocket (const int localPortNumber)
- : portNumber (0),
- handle (-1),
- connected (false),
- serverAddress (0)
- {
- #if JUCE_WIN32
- initWin32Sockets();
- #endif
-
- handle = (int) socket (AF_INET, SOCK_DGRAM, 0);
- bindToPort (localPortNumber);
- }
-
- DatagramSocket::DatagramSocket (const String& hostName_, const int portNumber_,
- const int handle_, const int localPortNumber)
- : hostName (hostName_),
- portNumber (portNumber_),
- handle (handle_),
- connected (true),
- serverAddress (0)
- {
- #if JUCE_WIN32
- initWin32Sockets();
- #endif
-
- resetSocketOptions (handle_, true);
- bindToPort (localPortNumber);
- }
-
- DatagramSocket::~DatagramSocket()
- {
- close();
-
- delete ((struct sockaddr_in*) serverAddress);
- serverAddress = 0;
- }
-
- void DatagramSocket::close()
- {
- #if JUCE_WIN32
- closesocket (handle);
- connected = false;
- #else
- connected = false;
- ::close (handle);
- #endif
-
- hostName = String::empty;
- portNumber = 0;
- handle = -1;
- }
-
- bool DatagramSocket::bindToPort (const int port)
- {
- return bindSocketToPort (handle, port);
- }
-
- bool DatagramSocket::connect (const String& remoteHostName,
- const int remotePortNumber,
- const int timeOutMillisecs)
- {
- if (connected)
- close();
-
- hostName = remoteHostName;
- portNumber = remotePortNumber;
-
- connected = connectSocket (handle, true, &serverAddress,
- remoteHostName, remotePortNumber,
- timeOutMillisecs);
-
- if (! (connected && resetSocketOptions (handle, true)))
- {
- close();
- return false;
- }
-
- return true;
- }
-
- DatagramSocket* DatagramSocket::waitForNextConnection() const
- {
- struct sockaddr address;
-
- #if defined (JUCE_LINUX) || (defined (JUCE_MAC) && ! MACOS_10_2_OR_EARLIER)
- socklen_t len = sizeof (sockaddr);
- #else
- int len = sizeof (sockaddr);
- #endif
-
- while (waitUntilReady (true, -1) == 1)
- {
- char buf[1];
-
- if (recvfrom (handle, buf, 0, 0, &address, &len) > 0)
- {
- return new DatagramSocket (inet_ntoa (((struct sockaddr_in*) &address)->sin_addr),
- ntohs (((struct sockaddr_in*) &address)->sin_port),
- -1, -1);
- }
- }
-
- return 0;
- }
-
- int DatagramSocket::waitUntilReady (const bool readyForReading,
- const int timeoutMsecs) const
- {
- return connected ? waitForReadiness (handle, readyForReading, timeoutMsecs)
- : -1;
- }
-
- int DatagramSocket::read (void* destBuffer, const int maxBytesToRead)
- {
- return connected ? readSocket (handle, destBuffer, maxBytesToRead, connected)
- : -1;
- }
-
- int DatagramSocket::write (const void* sourceBuffer, const int numBytesToWrite)
- {
- // You need to call connect() first to set the server address..
- jassert (serverAddress != 0 && connected);
-
- return connected ? sendto (handle, (const char*) sourceBuffer,
- numBytesToWrite, 0,
- (const struct sockaddr*) serverAddress,
- sizeof (struct sockaddr_in))
- : -1;
- }
-
- bool DatagramSocket::isLocal() const throw()
- {
- return hostName == T("127.0.0.1");
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_Socket.cpp *********/
-
- /********* Start of inlined file: juce_URL.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- URL::URL() throw()
- {
- }
-
- URL::URL (const String& url_)
- : url (url_)
- {
- int i = url.indexOfChar (T('?'));
-
- if (i >= 0)
- {
- do
- {
- const int nextAmp = url.indexOfChar (i + 1, T('&'));
- const int equalsPos = url.indexOfChar (i + 1, T('='));
-
- if (equalsPos > i + 1)
- {
- if (nextAmp < 0)
- {
- parameters.set (removeEscapeChars (url.substring (i + 1, equalsPos)),
- removeEscapeChars (url.substring (equalsPos + 1)));
- }
- else if (nextAmp > 0 && equalsPos < nextAmp)
- {
- parameters.set (removeEscapeChars (url.substring (i + 1, equalsPos)),
- removeEscapeChars (url.substring (equalsPos + 1, nextAmp)));
- }
- }
-
- i = nextAmp;
- }
- while (i >= 0);
-
- url = url.upToFirstOccurrenceOf (T("?"), false, false);
- }
- }
-
- URL::URL (const URL& other)
- : url (other.url),
- parameters (other.parameters),
- filesToUpload (other.filesToUpload),
- mimeTypes (other.mimeTypes)
- {
- }
-
- const URL& URL::operator= (const URL& other)
- {
- url = other.url;
- parameters = other.parameters;
- filesToUpload = other.filesToUpload;
- mimeTypes = other.mimeTypes;
-
- return *this;
- }
-
- URL::~URL() throw()
- {
- }
-
- static const String getMangledParameters (const StringPairArray& parameters)
- {
- String p;
-
- for (int i = 0; i < parameters.size(); ++i)
- {
- if (i > 0)
- p += T("&");
-
- p << URL::addEscapeChars (parameters.getAllKeys() [i])
- << T("=")
- << URL::addEscapeChars (parameters.getAllValues() [i]);
- }
-
- return p;
- }
-
- const String URL::toString (const bool includeGetParameters) const
- {
- if (includeGetParameters && parameters.size() > 0)
- return url + T("?") + getMangledParameters (parameters);
- else
- return url;
- }
-
- bool URL::isWellFormed() const
- {
- //xxx TODO
- return url.isNotEmpty();
- }
-
- bool URL::isProbablyAWebsiteURL (const String& possibleURL)
- {
- return (possibleURL.containsChar (T('.'))
- && (! possibleURL.containsChar (T('@')))
- && (! possibleURL.endsWithChar (T('.')))
- && (possibleURL.startsWithIgnoreCase (T("www."))
- || possibleURL.startsWithIgnoreCase (T("http:"))
- || possibleURL.startsWithIgnoreCase (T("ftp:"))
- || possibleURL.endsWithIgnoreCase (T(".com"))
- || possibleURL.endsWithIgnoreCase (T(".net"))
- || possibleURL.endsWithIgnoreCase (T(".org"))
- || possibleURL.endsWithIgnoreCase (T(".co.uk")))
- || possibleURL.startsWithIgnoreCase (T("file:")));
- }
-
- bool URL::isProbablyAnEmailAddress (const String& possibleEmailAddress)
- {
- const int atSign = possibleEmailAddress.indexOfChar (T('@'));
-
- return atSign > 0
- && possibleEmailAddress.lastIndexOfChar (T('.')) > (atSign + 1)
- && (! possibleEmailAddress.endsWithChar (T('.')));
- }
-
- void* juce_openInternetFile (const String& url,
- const String& headers,
- const MemoryBlock& optionalPostData,
- const bool isPost,
- URL::OpenStreamProgressCallback* callback,
- void* callbackContext,
- int timeOutMs);
-
- void juce_closeInternetFile (void* handle);
- int juce_readFromInternetFile (void* handle, void* dest, int bytesToRead);
- int juce_seekInInternetFile (void* handle, int newPosition);
-
- class WebInputStream : public InputStream
- {
- public:
-
- WebInputStream (const URL& url,
- const bool isPost_,
- URL::OpenStreamProgressCallback* const progressCallback_,
- void* const progressCallbackContext_,
- const String& extraHeaders,
- int timeOutMs_)
- : position (0),
- finished (false),
- isPost (isPost_),
- progressCallback (progressCallback_),
- progressCallbackContext (progressCallbackContext_),
- timeOutMs (timeOutMs_)
- {
- server = url.toString (! isPost);
-
- if (isPost_)
- createHeadersAndPostData (url);
-
- headers += extraHeaders;
-
- if (! headers.endsWithChar (T('\n')))
- headers << "\r\n";
-
- handle = juce_openInternetFile (server, headers, postData, isPost,
- progressCallback_, progressCallbackContext_,
- timeOutMs);
- }
-
- ~WebInputStream()
- {
- juce_closeInternetFile (handle);
- }
-
- bool isError() const throw()
- {
- return handle == 0;
- }
-
- int64 getTotalLength()
- {
- return -1;
- }
-
- bool isExhausted()
- {
- return finished;
- }
-
- int read (void* dest, int bytes)
- {
- if (finished || isError())
- {
- return 0;
- }
- else
- {
- const int bytesRead = juce_readFromInternetFile (handle, dest, bytes);
- position += bytesRead;
-
- if (bytesRead == 0)
- finished = true;
-
- return bytesRead;
- }
- }
-
- int64 getPosition()
- {
- return position;
- }
-
- bool setPosition (int64 wantedPos)
- {
- if (wantedPos != position)
- {
- finished = false;
-
- const int actualPos = juce_seekInInternetFile (handle, (int) wantedPos);
-
- if (actualPos == wantedPos)
- {
- position = wantedPos;
- }
- else
- {
- if (wantedPos < position)
- {
- juce_closeInternetFile (handle);
-
- position = 0;
- finished = false;
-
- handle = juce_openInternetFile (server, headers, postData, isPost,
- progressCallback, progressCallbackContext,
- timeOutMs);
- }
-
- skipNextBytes (wantedPos - position);
- }
- }
-
- return true;
- }
-
- juce_UseDebuggingNewOperator
-
- private:
- String server, headers;
- MemoryBlock postData;
- int64 position;
- bool finished;
- const bool isPost;
- void* handle;
- URL::OpenStreamProgressCallback* const progressCallback;
- void* const progressCallbackContext;
- const int timeOutMs;
-
- void createHeadersAndPostData (const URL& url)
- {
- if (url.getFilesToUpload().size() > 0)
- {
- // need to upload some files, so do it as multi-part...
- String boundary (String::toHexString (Random::getSystemRandom().nextInt64()));
-
- headers << "Content-Type: multipart/form-data; boundary=" << boundary << "\r\n";
-
- appendUTF8ToPostData ("--" + boundary);
-
- int i;
- for (i = 0; i < url.getParameters().size(); ++i)
- {
- String s;
- s << "\r\nContent-Disposition: form-data; name=\""
- << url.getParameters().getAllKeys() [i]
- << "\"\r\n\r\n"
- << url.getParameters().getAllValues() [i]
- << "\r\n--"
- << boundary;
-
- appendUTF8ToPostData (s);
- }
-
- for (i = 0; i < url.getFilesToUpload().size(); ++i)
- {
- const File f (url.getFilesToUpload().getAllValues() [i]);
- const String paramName (url.getFilesToUpload().getAllKeys() [i]);
-
- String s;
- s << "\r\nContent-Disposition: form-data; name=\""
- << paramName
- << "\"; filename=\""
- << f.getFileName()
- << "\"\r\n";
-
- const String mimeType (url.getMimeTypesOfUploadFiles()
- .getValue (paramName, String::empty));
-
- if (mimeType.isNotEmpty())
- s << "Content-Type: " << mimeType << "\r\n";
-
- s << "Content-Transfer-Encoding: binary\r\n\r\n";
-
- appendUTF8ToPostData (s);
-
- f.loadFileAsData (postData);
-
- s = "\r\n--" + boundary;
-
- appendUTF8ToPostData (s);
- }
-
- appendUTF8ToPostData ("--\r\n");
- }
- else
- {
- // just a short text attachment, so use simple url encoding..
- const String params (getMangledParameters (url.getParameters()));
-
- headers = "Content-Type: application/x-www-form-urlencoded\r\nContent-length: "
- + String ((int) strlen (params.toUTF8()))
- + "\r\n";
-
- appendUTF8ToPostData (params);
- }
- }
-
- void appendUTF8ToPostData (const String& text) throw()
- {
- postData.append (text.toUTF8(),
- (int) strlen (text.toUTF8()));
- }
-
- WebInputStream (const WebInputStream&);
- const WebInputStream& operator= (const WebInputStream&);
- };
-
- InputStream* URL::createInputStream (const bool usePostCommand,
- OpenStreamProgressCallback* const progressCallback,
- void* const progressCallbackContext,
- const String& extraHeaders,
- const int timeOutMs) const
- {
- WebInputStream* wi = new WebInputStream (*this, usePostCommand,
- progressCallback, progressCallbackContext,
- extraHeaders,
- timeOutMs);
-
- if (wi->isError())
- {
- delete wi;
- wi = 0;
- }
-
- return wi;
- }
-
- bool URL::readEntireBinaryStream (MemoryBlock& destData,
- const bool usePostCommand) const
- {
- InputStream* const in = createInputStream (usePostCommand);
-
- if (in != 0)
- {
- in->readIntoMemoryBlock (destData, -1);
- delete in;
-
- return true;
- }
-
- return false;
- }
-
- const String URL::readEntireTextStream (const bool usePostCommand) const
- {
- String result;
- InputStream* const in = createInputStream (usePostCommand);
-
- if (in != 0)
- {
- result = in->readEntireStreamAsString();
- delete in;
- }
-
- return result;
- }
-
- XmlElement* URL::readEntireXmlStream (const bool usePostCommand) const
- {
- XmlDocument doc (readEntireTextStream (usePostCommand));
- return doc.getDocumentElement();
- }
-
- const URL URL::withParameter (const String& parameterName,
- const String& parameterValue) const
- {
- URL u (*this);
- u.parameters.set (parameterName, parameterValue);
- return u;
- }
-
- const URL URL::withFileToUpload (const String& parameterName,
- const File& fileToUpload,
- const String& mimeType) const
- {
- URL u (*this);
- u.filesToUpload.set (parameterName, fileToUpload.getFullPathName());
- u.mimeTypes.set (parameterName, mimeType);
- return u;
- }
-
- const StringPairArray& URL::getParameters() const throw()
- {
- return parameters;
- }
-
- const StringPairArray& URL::getFilesToUpload() const throw()
- {
- return filesToUpload;
- }
-
- const StringPairArray& URL::getMimeTypesOfUploadFiles() const throw()
- {
- return mimeTypes;
- }
-
- const String URL::removeEscapeChars (const String& s)
- {
- const int len = s.length();
- uint8* const resultUTF8 = (uint8*) juce_calloc (len * 4);
- uint8* r = resultUTF8;
-
- for (int i = 0; i < len; ++i)
- {
- char c = (char) s[i];
- if (c == 0)
- break;
-
- if (c == '+')
- {
- c = ' ';
- }
- else if (c == '%')
- {
- c = (char) s.substring (i + 1, i + 3).getHexValue32();
- i += 2;
- }
-
- *r++ = c;
- }
-
- const String stringResult (String::fromUTF8 (resultUTF8));
- juce_free (resultUTF8);
- return stringResult;
- }
-
- const String URL::addEscapeChars (const String& s)
- {
- String result;
- result.preallocateStorage (s.length() + 8);
- const char* utf8 = s.toUTF8();
-
- while (*utf8 != 0)
- {
- const char c = *utf8++;
-
- if (c == ' ')
- {
- result += T('+');
- }
- else if (CharacterFunctions::isLetterOrDigit (c)
- || CharacterFunctions::indexOfChar ("_-$.*!'(),", c, false) >= 0)
- {
- result << c;
- }
- else
- {
- const int v = (int) (uint8) c;
-
- if (v < 0x10)
- result << T("%0");
- else
- result << T('%');
-
- result << String::toHexString (v);
- }
- }
-
- return result;
- }
-
- extern bool juce_launchFile (const String& fileName,
- const String& parameters) throw();
-
- bool URL::launchInDefaultBrowser() const
- {
- String u (toString (true));
-
- if (u.contains (T("@")) && ! u.contains (T(":")))
- u = "mailto:" + u;
-
- return juce_launchFile (u, String::empty);
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_URL.cpp *********/
-
- /********* Start of inlined file: juce_BufferedInputStream.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- BufferedInputStream::BufferedInputStream (InputStream* const source_,
- const int bufferSize_,
- const bool deleteSourceWhenDestroyed_) throw()
- : source (source_),
- deleteSourceWhenDestroyed (deleteSourceWhenDestroyed_),
- bufferSize (jmax (256, bufferSize_)),
- position (source_->getPosition()),
- lastReadPos (0),
- bufferOverlap (128)
- {
- const int sourceSize = (int) source_->getTotalLength();
- if (sourceSize >= 0)
- bufferSize = jmin (jmax (32, sourceSize), bufferSize);
-
- bufferStart = position;
- buffer = (char*) juce_malloc (bufferSize);
- }
-
- BufferedInputStream::~BufferedInputStream() throw()
- {
- if (deleteSourceWhenDestroyed)
- delete source;
-
- juce_free (buffer);
- }
-
- int64 BufferedInputStream::getTotalLength()
- {
- return source->getTotalLength();
- }
-
- int64 BufferedInputStream::getPosition()
- {
- return position;
- }
-
- bool BufferedInputStream::setPosition (int64 newPosition)
- {
- position = jmax ((int64) 0, newPosition);
- return true;
- }
-
- bool BufferedInputStream::isExhausted()
- {
- return (position >= lastReadPos)
- && source->isExhausted();
- }
-
- void BufferedInputStream::ensureBuffered()
- {
- const int64 bufferEndOverlap = lastReadPos - bufferOverlap;
-
- if (position < bufferStart || position >= bufferEndOverlap)
- {
- int bytesRead;
-
- if (position < lastReadPos
- && position >= bufferEndOverlap
- && position >= bufferStart)
- {
- const int bytesToKeep = (int) (lastReadPos - position);
- memmove (buffer, buffer + position - bufferStart, bytesToKeep);
-
- bufferStart = position;
-
- bytesRead = source->read (buffer + bytesToKeep,
- bufferSize - bytesToKeep);
-
- lastReadPos += bytesRead;
- bytesRead += bytesToKeep;
- }
- else
- {
- bufferStart = position;
- source->setPosition (bufferStart);
- bytesRead = source->read (buffer, bufferSize);
- lastReadPos = bufferStart + bytesRead;
- }
-
- while (bytesRead < bufferSize)
- buffer [bytesRead++] = 0;
- }
- }
-
- int BufferedInputStream::read (void* destBuffer, int maxBytesToRead)
- {
- if (position >= bufferStart
- && position + maxBytesToRead <= lastReadPos)
- {
- memcpy (destBuffer, buffer + (position - bufferStart), maxBytesToRead);
- position += maxBytesToRead;
-
- return maxBytesToRead;
- }
- else
- {
- if (position < bufferStart || position >= lastReadPos)
- ensureBuffered();
-
- int bytesRead = 0;
-
- while (maxBytesToRead > 0)
- {
- const int bytesAvailable = jmin (maxBytesToRead, (int) (lastReadPos - position));
-
- if (bytesAvailable > 0)
- {
- memcpy (destBuffer, buffer + (position - bufferStart), bytesAvailable);
- maxBytesToRead -= bytesAvailable;
- bytesRead += bytesAvailable;
- position += bytesAvailable;
- destBuffer = (void*) (((char*) destBuffer) + bytesAvailable);
- }
-
- ensureBuffered();
-
- if (isExhausted())
- break;
- }
-
- return bytesRead;
- }
- }
-
- const String BufferedInputStream::readString()
- {
- if (position >= bufferStart
- && position < lastReadPos)
- {
- const int maxChars = (int) (lastReadPos - position);
-
- const char* const src = buffer + (position - bufferStart);
-
- for (int i = 0; i < maxChars; ++i)
- {
- if (src[i] == 0)
- {
- position += i + 1;
-
- return String::fromUTF8 ((const uint8*) src, i);
- }
- }
- }
-
- return InputStream::readString();
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_BufferedInputStream.cpp *********/
-
- /********* Start of inlined file: juce_FileInputSource.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- FileInputSource::FileInputSource (const File& file_) throw()
- : file (file_)
- {
- }
-
- FileInputSource::~FileInputSource()
- {
- }
-
- InputStream* FileInputSource::createInputStream()
- {
- return file.createInputStream();
- }
-
- InputStream* FileInputSource::createInputStreamFor (const String& relatedItemPath)
- {
- return file.getSiblingFile (relatedItemPath).createInputStream();
- }
-
- int64 FileInputSource::hashCode() const
- {
- return file.hashCode();
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_FileInputSource.cpp *********/
-
- /********* Start of inlined file: juce_MemoryInputStream.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- MemoryInputStream::MemoryInputStream (const void* const sourceData,
- const int sourceDataSize,
- const bool keepInternalCopy) throw()
- : data ((const char*) sourceData),
- dataSize (sourceDataSize),
- position (0)
- {
- if (keepInternalCopy)
- {
- internalCopy.append (data, sourceDataSize);
- data = (const char*) internalCopy.getData();
- }
- }
-
- MemoryInputStream::~MemoryInputStream() throw()
- {
- }
-
- int64 MemoryInputStream::getTotalLength()
- {
- return dataSize;
- }
-
- int MemoryInputStream::read (void* buffer, int howMany)
- {
- const int num = jmin (howMany, dataSize - position);
- memcpy (buffer, data + position, num);
- position += num;
- return num;
- }
-
- bool MemoryInputStream::isExhausted()
- {
- return (position >= dataSize);
- }
-
- bool MemoryInputStream::setPosition (int64 pos)
- {
- position = (int) jlimit ((int64) 0, (int64) dataSize, pos);
-
- return true;
- }
-
- int64 MemoryInputStream::getPosition()
- {
- return position;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_MemoryInputStream.cpp *********/
-
- /********* Start of inlined file: juce_MemoryOutputStream.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- MemoryOutputStream::MemoryOutputStream (const int initialSize,
- const int blockSizeToIncreaseBy,
- MemoryBlock* const memoryBlockToWriteTo) throw()
- : data (memoryBlockToWriteTo),
- position (0),
- size (0),
- blockSize (jmax (16, blockSizeToIncreaseBy)),
- ownsMemoryBlock (memoryBlockToWriteTo == 0)
- {
- if (memoryBlockToWriteTo == 0)
- data = new MemoryBlock (initialSize);
- else
- memoryBlockToWriteTo->setSize (initialSize, false);
- }
-
- MemoryOutputStream::~MemoryOutputStream() throw()
- {
- if (ownsMemoryBlock)
- delete data;
- else
- flush();
- }
-
- void MemoryOutputStream::flush()
- {
- if (! ownsMemoryBlock)
- data->setSize (size, false);
- }
-
- void MemoryOutputStream::reset() throw()
- {
- position = 0;
- size = 0;
- }
-
- bool MemoryOutputStream::write (const void* buffer, int howMany)
- {
- int storageNeeded = position + howMany + 1;
- storageNeeded = storageNeeded - (storageNeeded % blockSize) + blockSize;
-
- data->ensureSize (storageNeeded);
- data->copyFrom (buffer, position, howMany);
- position += howMany;
- size = jmax (size, position);
-
- return true;
- }
-
- const char* MemoryOutputStream::getData() throw()
- {
- if (data->getSize() > size)
- ((char*) data->getData()) [size] = 0;
-
- return (const char*) data->getData();
- }
-
- int MemoryOutputStream::getDataSize() const throw()
- {
- return size;
- }
-
- int64 MemoryOutputStream::getPosition()
- {
- return position;
- }
-
- bool MemoryOutputStream::setPosition (int64 newPosition)
- {
- if (newPosition <= size)
- {
- // ok to seek backwards
- position = jlimit (0, size, (int) newPosition);
- return true;
- }
- else
- {
- // trying to make it bigger isn't a good thing to do..
- return false;
- }
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_MemoryOutputStream.cpp *********/
-
- /********* Start of inlined file: juce_SubregionStream.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- SubregionStream::SubregionStream (InputStream* const sourceStream,
- const int64 startPositionInSourceStream_,
- const int64 lengthOfSourceStream_,
- const bool deleteSourceWhenDestroyed_) throw()
- : source (sourceStream),
- deleteSourceWhenDestroyed (deleteSourceWhenDestroyed_),
- startPositionInSourceStream (startPositionInSourceStream_),
- lengthOfSourceStream (lengthOfSourceStream_)
- {
- setPosition (0);
- }
-
- SubregionStream::~SubregionStream() throw()
- {
- if (deleteSourceWhenDestroyed)
- delete source;
- }
-
- int64 SubregionStream::getTotalLength()
- {
- const int64 srcLen = source->getTotalLength() - startPositionInSourceStream;
-
- return (lengthOfSourceStream >= 0) ? jmin (lengthOfSourceStream, srcLen)
- : srcLen;
- }
-
- int64 SubregionStream::getPosition()
- {
- return source->getPosition() - startPositionInSourceStream;
- }
-
- bool SubregionStream::setPosition (int64 newPosition)
- {
- return source->setPosition (jmax ((int64) 0, newPosition + startPositionInSourceStream));
- }
-
- int SubregionStream::read (void* destBuffer, int maxBytesToRead)
- {
- if (lengthOfSourceStream < 0)
- {
- return source->read (destBuffer, maxBytesToRead);
- }
- else
- {
- maxBytesToRead = (int) jmin ((int64) maxBytesToRead, lengthOfSourceStream - getPosition());
-
- if (maxBytesToRead <= 0)
- return 0;
-
- return source->read (destBuffer, maxBytesToRead);
- }
- }
-
- bool SubregionStream::isExhausted()
- {
- if (lengthOfSourceStream >= 0)
- return (getPosition() >= lengthOfSourceStream) || source->isExhausted();
- else
- return source->isExhausted();
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_SubregionStream.cpp *********/
-
- /********* Start of inlined file: juce_PerformanceCounter.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- PerformanceCounter::PerformanceCounter (const String& name_,
- int runsPerPrintout,
- const File& loggingFile)
- : name (name_),
- numRuns (0),
- runsPerPrint (runsPerPrintout),
- totalTime (0),
- outputFile (loggingFile)
- {
- if (outputFile != File::nonexistent)
- {
- String s ("**** Counter for \"");
- s << name_ << "\" started at: "
- << Time::getCurrentTime().toString (true, true)
- << "\r\n";
-
- outputFile.appendText (s, false, false);
- }
- }
-
- PerformanceCounter::~PerformanceCounter()
- {
- printStatistics();
- }
-
- void PerformanceCounter::start()
- {
- started = Time::getHighResolutionTicks();
- }
-
- void PerformanceCounter::stop()
- {
- const int64 now = Time::getHighResolutionTicks();
-
- totalTime += 1000.0 * Time::highResolutionTicksToSeconds (now - started);
-
- if (++numRuns == runsPerPrint)
- printStatistics();
- }
-
- void PerformanceCounter::printStatistics()
- {
- if (numRuns > 0)
- {
- String s ("Performance count for \"");
- s << name << "\" - average over " << numRuns << " run(s) = ";
-
- const int micros = (int) (totalTime * (1000.0 / numRuns));
-
- if (micros > 10000)
- s << (micros/1000) << " millisecs";
- else
- s << micros << " microsecs";
-
- s << ", total = " << String (totalTime / 1000, 5) << " seconds";
-
- Logger::outputDebugString (s);
-
- s << "\r\n";
-
- if (outputFile != File::nonexistent)
- outputFile.appendText (s, false, false);
-
- numRuns = 0;
- totalTime = 0;
- }
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_PerformanceCounter.cpp *********/
-
- /********* Start of inlined file: juce_Uuid.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- Uuid::Uuid()
- {
- // do some serious mixing up of our MAC addresses and different types of time info,
- // plus a couple of passes of pseudo-random numbers over the whole thing.
- SystemStats::getMACAddresses (value.asInt64, 2);
-
- int i;
- for (i = 16; --i >= 0;)
- {
- Random r (Time::getHighResolutionTicks()
- + Random::getSystemRandom().nextInt()
- + value.asInt [i & 3]);
-
- value.asBytes[i] ^= (uint8) r.nextInt();
- }
-
- value.asInt64 [0] ^= Time::getHighResolutionTicks();
- value.asInt64 [1] ^= Time::currentTimeMillis();
-
- for (i = 4; --i >= 0;)
- {
- Random r (Time::getHighResolutionTicks() ^ value.asInt[i]);
- value.asInt[i] ^= r.nextInt();
- }
- }
-
- Uuid::~Uuid() throw()
- {
- }
-
- Uuid::Uuid (const Uuid& other)
- : value (other.value)
- {
- }
-
- Uuid& Uuid::operator= (const Uuid& other)
- {
- if (this != &other)
- value = other.value;
-
- return *this;
- }
-
- bool Uuid::operator== (const Uuid& other) const
- {
- return memcmp (value.asBytes, other.value.asBytes, 16) == 0;
- }
-
- bool Uuid::operator!= (const Uuid& other) const
- {
- return ! operator== (other);
- }
-
- bool Uuid::isNull() const throw()
- {
- return (value.asInt64 [0] == 0) && (value.asInt64 [1] == 0);
- }
-
- const String Uuid::toString() const
- {
- return String::toHexString (value.asBytes, 16, 0);
- }
-
- Uuid::Uuid (const String& uuidString)
- {
- operator= (uuidString);
- }
-
- Uuid& Uuid::operator= (const String& uuidString)
- {
- int destIndex = 0;
- int i = 0;
-
- for (;;)
- {
- int byte = 0;
-
- for (int loop = 2; --loop >= 0;)
- {
- byte <<= 4;
-
- for (;;)
- {
- const tchar c = uuidString [i++];
-
- if (c >= T('0') && c <= T('9'))
- {
- byte |= c - T('0');
- break;
- }
- else if (c >= T('a') && c <= T('z'))
- {
- byte |= c - (T('a') - 10);
- break;
- }
- else if (c >= T('A') && c <= T('Z'))
- {
- byte |= c - (T('A') - 10);
- break;
- }
- else if (c == 0)
- {
- while (destIndex < 16)
- value.asBytes [destIndex++] = 0;
-
- return *this;
- }
- }
- }
-
- value.asBytes [destIndex++] = (uint8) byte;
- }
- }
-
- Uuid::Uuid (const uint8* const rawData)
- {
- operator= (rawData);
- }
-
- Uuid& Uuid::operator= (const uint8* const rawData)
- {
- if (rawData != 0)
- memcpy (value.asBytes, rawData, 16);
- else
- zeromem (value.asBytes, 16);
-
- return *this;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_Uuid.cpp *********/
-
- /********* Start of inlined file: juce_ZipFile.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- struct ZipEntryInfo
- {
- ZipFile::ZipEntry entry;
- int streamOffset;
- int compressedSize;
- bool compressed;
- };
-
- class ZipInputStream : public InputStream
- {
- public:
-
- ZipInputStream (ZipFile& file_,
- ZipEntryInfo& zei) throw()
- : file (file_),
- zipEntryInfo (zei),
- pos (0),
- headerSize (0),
- inputStream (0)
- {
- inputStream = file_.inputStream;
-
- if (file_.inputSource != 0)
- {
- inputStream = file.inputSource->createInputStream();
- }
- else
- {
- #ifdef JUCE_DEBUG
- file_.numOpenStreams++;
- #endif
- }
-
- char buffer [30];
-
- if (inputStream != 0
- && inputStream->setPosition (zei.streamOffset)
- && inputStream->read (buffer, 30) == 30
- && littleEndianInt (buffer) == 0x04034b50)
- {
- headerSize = 30 + littleEndianShort (buffer + 26)
- + littleEndianShort (buffer + 28);
- }
- }
-
- ~ZipInputStream() throw()
- {
- #ifdef JUCE_DEBUG
- if (inputStream != 0 && inputStream == file.inputStream)
- file.numOpenStreams--;
- #endif
-
- if (inputStream != file.inputStream)
- delete inputStream;
- }
-
- int64 getTotalLength() throw()
- {
- return zipEntryInfo.compressedSize;
- }
-
- int read (void* buffer, int howMany) throw()
- {
- if (headerSize <= 0)
- return 0;
-
- howMany = (int) jmin ((int64) howMany, zipEntryInfo.compressedSize - pos);
-
- if (inputStream == 0)
- return 0;
-
- int num;
-
- if (inputStream == file.inputStream)
- {
- const ScopedLock sl (file.lock);
- inputStream->setPosition (pos + zipEntryInfo.streamOffset + headerSize);
- num = inputStream->read (buffer, howMany);
- }
- else
- {
- inputStream->setPosition (pos + zipEntryInfo.streamOffset + headerSize);
- num = inputStream->read (buffer, howMany);
- }
-
- pos += num;
- return num;
- }
-
- bool isExhausted() throw()
- {
- return pos >= zipEntryInfo.compressedSize;
- }
-
- int64 getPosition() throw()
- {
- return pos;
- }
-
- bool setPosition (int64 newPos) throw()
- {
- pos = jlimit ((int64) 0, (int64) zipEntryInfo.compressedSize, newPos);
- return true;
- }
-
- private:
-
- ZipFile& file;
- ZipEntryInfo zipEntryInfo;
- int64 pos;
- int headerSize;
- InputStream* inputStream;
-
- ZipInputStream (const ZipInputStream&);
- const ZipInputStream& operator= (const ZipInputStream&);
- };
-
- ZipFile::ZipFile (InputStream* const source_,
- const bool deleteStreamWhenDestroyed_) throw()
- : inputStream (source_),
- inputSource (0),
- deleteStreamWhenDestroyed (deleteStreamWhenDestroyed_)
- #ifdef JUCE_DEBUG
- , numOpenStreams (0)
- #endif
- {
- init();
- }
-
- ZipFile::ZipFile (const File& file)
- : inputStream (0),
- deleteStreamWhenDestroyed (false)
- #ifdef JUCE_DEBUG
- , numOpenStreams (0)
- #endif
- {
- inputSource = new FileInputSource (file);
- init();
- }
-
- ZipFile::ZipFile (InputSource* const inputSource_)
- : inputStream (0),
- inputSource (inputSource_),
- deleteStreamWhenDestroyed (false)
- #ifdef JUCE_DEBUG
- , numOpenStreams (0)
- #endif
- {
- init();
- }
-
- ZipFile::~ZipFile() throw()
- {
- for (int i = entries.size(); --i >= 0;)
- {
- ZipEntryInfo* const zei = (ZipEntryInfo*) entries [i];
- delete zei;
- }
-
- if (deleteStreamWhenDestroyed)
- delete inputStream;
-
- delete inputSource;
-
- #ifdef JUCE_DEBUG
- // If you hit this assertion, it means you've created a stream to read
- // one of the items in the zipfile, but you've forgotten to delete that
- // stream object before deleting the file.. Streams can't be kept open
- // after the file is deleted because they need to share the input
- // stream that the file uses to read itself.
- jassert (numOpenStreams == 0);
- #endif
- }
-
- int ZipFile::getNumEntries() const throw()
- {
- return entries.size();
- }
-
- const ZipFile::ZipEntry* ZipFile::getEntry (const int index) const throw()
- {
- ZipEntryInfo* const zei = (ZipEntryInfo*) entries [index];
-
- return (zei != 0) ? &(zei->entry)
- : 0;
- }
-
- int ZipFile::getIndexOfFileName (const String& fileName) const throw()
- {
- for (int i = 0; i < entries.size(); ++i)
- if (((ZipEntryInfo*) entries.getUnchecked (i))->entry.filename == fileName)
- return i;
-
- return -1;
- }
-
- const ZipFile::ZipEntry* ZipFile::getEntry (const String& fileName) const throw()
- {
- return getEntry (getIndexOfFileName (fileName));
- }
-
- InputStream* ZipFile::createStreamForEntry (const int index)
- {
- ZipEntryInfo* const zei = (ZipEntryInfo*) entries[index];
-
- InputStream* stream = 0;
-
- if (zei != 0)
- {
- stream = new ZipInputStream (*this, *zei);
-
- if (zei->compressed)
- {
- stream = new GZIPDecompressorInputStream (stream, true, true,
- zei->entry.uncompressedSize);
-
- // (much faster to unzip in big blocks using a buffer..)
- stream = new BufferedInputStream (stream, 32768, true);
- }
- }
-
- return stream;
- }
-
- class ZipFilenameComparator
- {
- public:
- static int compareElements (const void* const first, const void* const second) throw()
- {
- return ((const ZipEntryInfo*) first)->entry.filename
- .compare (((const ZipEntryInfo*) second)->entry.filename);
- }
- };
-
- void ZipFile::sortEntriesByFilename()
- {
- ZipFilenameComparator sorter;
- entries.sort (sorter);
- }
-
- void ZipFile::init()
- {
- InputStream* in = inputStream;
- bool deleteInput = false;
-
- if (inputSource != 0)
- {
- deleteInput = true;
- in = inputSource->createInputStream();
- }
-
- if (in != 0)
- {
- numEntries = 0;
- int pos = findEndOfZipEntryTable (in);
-
- if (pos >= 0 && pos < in->getTotalLength())
- {
- const int size = (int) (in->getTotalLength() - pos);
-
- in->setPosition (pos);
- MemoryBlock headerData;
-
- if (in->readIntoMemoryBlock (headerData, size) == size)
- {
- pos = 0;
-
- for (int i = 0; i < numEntries; ++i)
- {
- if (pos + 46 > size)
- break;
-
- const char* const buffer = ((const char*) headerData.getData()) + pos;
-
- const int fileNameLen = littleEndianShort (buffer + 28);
-
- if (pos + 46 + fileNameLen > size)
- break;
-
- ZipEntryInfo* const zei = new ZipEntryInfo();
- zei->entry.filename = String (buffer + 46, fileNameLen);
-
- const int time = littleEndianShort (buffer + 12);
- const int date = littleEndianShort (buffer + 14);
-
- const int year = 1980 + (date >> 9);
- const int month = ((date >> 5) & 15) - 1;
- const int day = date & 31;
- const int hours = time >> 11;
- const int minutes = (time >> 5) & 63;
- const int seconds = (time & 31) << 1;
-
- zei->entry.fileTime = Time (year, month, day, hours, minutes, seconds);
-
- zei->compressed = littleEndianShort (buffer + 10) != 0;
- zei->compressedSize = littleEndianInt (buffer + 20);
- zei->entry.uncompressedSize = littleEndianInt (buffer + 24);
-
- zei->streamOffset = littleEndianInt (buffer + 42);
- entries.add (zei);
-
- pos += 46 + fileNameLen
- + littleEndianShort (buffer + 30)
- + littleEndianShort (buffer + 32);
- }
- }
- }
-
- if (deleteInput)
- delete in;
- }
- }
-
- int ZipFile::findEndOfZipEntryTable (InputStream* input)
- {
- BufferedInputStream in (input, 8192, false);
-
- in.setPosition (in.getTotalLength());
- int64 pos = in.getPosition();
- const int64 lowestPos = jmax ((int64) 0, pos - 1024);
-
- char buffer [32];
- zeromem (buffer, sizeof (buffer));
-
- while (pos > lowestPos)
- {
- in.setPosition (pos - 22);
- pos = in.getPosition();
- memcpy (buffer + 22, buffer, 4);
-
- if (in.read (buffer, 22) != 22)
- return 0;
-
- for (int i = 0; i < 22; ++i)
- {
- if (littleEndianInt (buffer + i) == 0x06054b50)
- {
- in.setPosition (pos + i);
- in.read (buffer, 22);
- numEntries = littleEndianShort (buffer + 10);
-
- return littleEndianInt (buffer + 16);
- }
- }
- }
-
- return 0;
- }
-
- void ZipFile::uncompressTo (const File& targetDirectory,
- const bool shouldOverwriteFiles)
- {
- for (int i = 0; i < entries.size(); ++i)
- {
- const ZipEntryInfo& zei = *(ZipEntryInfo*) entries[i];
-
- const File targetFile (targetDirectory.getChildFile (zei.entry.filename));
-
- if (zei.entry.filename.endsWithChar (T('/')))
- {
- targetFile.createDirectory(); // (entry is a directory, not a file)
- }
- else
- {
- InputStream* const in = createStreamForEntry (i);
-
- if (in != 0)
- {
- if (shouldOverwriteFiles)
- targetFile.deleteFile();
-
- if ((! targetFile.exists())
- && targetFile.getParentDirectory().createDirectory())
- {
- FileOutputStream* const out = targetFile.createOutputStream();
-
- if (out != 0)
- {
- out->writeFromInputStream (*in, -1);
- delete out;
-
- targetFile.setCreationTime (zei.entry.fileTime);
- targetFile.setLastModificationTime (zei.entry.fileTime);
- targetFile.setLastAccessTime (zei.entry.fileTime);
- }
- }
-
- delete in;
- }
- }
- }
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_ZipFile.cpp *********/
-
- /********* Start of inlined file: juce_CharacterFunctions.cpp *********/
- #ifdef _MSC_VER
- #pragma warning (disable: 4514 4996)
- #pragma warning (push)
- #endif
-
- #include <cwctype>
- #include <cctype>
- #include <ctime>
-
- #ifdef _MSC_VER
- #pragma warning (pop)
- #endif
-
- BEGIN_JUCE_NAMESPACE
-
- int CharacterFunctions::length (const char* const s) throw()
- {
- return (int) strlen (s);
- }
-
- int CharacterFunctions::length (const juce_wchar* const s) throw()
- {
- #if MACOS_10_2_OR_EARLIER
- int n = 0;
- while (s[n] != 0)
- ++n;
-
- return n;
- #else
- return (int) wcslen (s);
- #endif
- }
-
- void CharacterFunctions::copy (char* dest, const char* src, const int maxChars) throw()
- {
- strncpy (dest, src, maxChars);
- }
-
- void CharacterFunctions::copy (juce_wchar* dest, const juce_wchar* src, int maxChars) throw()
- {
- #if MACOS_10_2_OR_EARLIER
- while (--maxChars >= 0 && *src != 0)
- *dest++ = *src++;
-
- *dest = 0;
- #else
- wcsncpy (dest, src, maxChars);
- #endif
- }
-
- void CharacterFunctions::copy (juce_wchar* dest, const char* src, const int maxChars) throw()
- {
- mbstowcs (dest, src, maxChars);
- }
-
- void CharacterFunctions::copy (char* dest, const juce_wchar* src, const int maxChars) throw()
- {
- wcstombs (dest, src, maxChars);
- }
-
- int CharacterFunctions::bytesRequiredForCopy (const juce_wchar* src) throw()
- {
- return (int) wcstombs (0, src, 0);
- }
-
- void CharacterFunctions::append (char* dest, const char* src) throw()
- {
- strcat (dest, src);
- }
-
- void CharacterFunctions::append (juce_wchar* dest, const juce_wchar* src) throw()
- {
- #if MACOS_10_2_OR_EARLIER
- while (*dest != 0)
- ++dest;
-
- while (*src != 0)
- *dest++ = *src++;
-
- *dest = 0;
- #else
- wcscat (dest, src);
- #endif
- }
-
- int CharacterFunctions::compare (const char* const s1, const char* const s2) throw()
- {
- return strcmp (s1, s2);
- }
-
- int CharacterFunctions::compare (const juce_wchar* s1, const juce_wchar* s2) throw()
- {
- jassert (s1 != 0 && s2 != 0);
-
- #if MACOS_10_2_OR_EARLIER
- for (;;)
- {
- if (*s1 != *s2)
- {
- const int diff = *s1 - *s2;
-
- if (diff != 0)
- return diff < 0 ? -1 : 1;
- }
- else if (*s1 == 0)
- break;
-
- ++s1;
- ++s2;
- }
-
- return 0;
- #else
- return wcscmp (s1, s2);
- #endif
- }
-
- int CharacterFunctions::compare (const char* const s1, const char* const s2, const int maxChars) throw()
- {
- jassert (s1 != 0 && s2 != 0);
-
- return strncmp (s1, s2, maxChars);
- }
-
- int CharacterFunctions::compare (const juce_wchar* s1, const juce_wchar* s2, int maxChars) throw()
- {
- jassert (s1 != 0 && s2 != 0);
-
- #if MACOS_10_2_OR_EARLIER
- while (--maxChars >= 0)
- {
- if (*s1 != *s2)
- return (*s1 < *s2) ? -1 : 1;
- else if (*s1 == 0)
- break;
-
- ++s1;
- ++s2;
- }
-
- return 0;
- #else
- return wcsncmp (s1, s2, maxChars);
- #endif
- }
-
- int CharacterFunctions::compareIgnoreCase (const char* const s1, const char* const s2) throw()
- {
- jassert (s1 != 0 && s2 != 0);
-
- #if JUCE_WIN32
- return stricmp (s1, s2);
- #else
- return strcasecmp (s1, s2);
- #endif
- }
-
- int CharacterFunctions::compareIgnoreCase (const juce_wchar* s1, const juce_wchar* s2) throw()
- {
- jassert (s1 != 0 && s2 != 0);
-
- #if JUCE_WIN32
- return _wcsicmp (s1, s2);
- #else
- for (;;)
- {
- if (*s1 != *s2)
- {
- const int diff = toUpperCase (*s1) - toUpperCase (*s2);
-
- if (diff != 0)
- return diff < 0 ? -1 : 1;
- }
- else if (*s1 == 0)
- break;
-
- ++s1;
- ++s2;
- }
-
- return 0;
- #endif
- }
-
- int CharacterFunctions::compareIgnoreCase (const char* const s1, const char* const s2, const int maxChars) throw()
- {
- jassert (s1 != 0 && s2 != 0);
-
- #if JUCE_WIN32
- return strnicmp (s1, s2, maxChars);
- #else
- return strncasecmp (s1, s2, maxChars);
- #endif
- }
-
- int CharacterFunctions::compareIgnoreCase (const juce_wchar* s1, const juce_wchar* s2, int maxChars) throw()
- {
- jassert (s1 != 0 && s2 != 0);
-
- #if JUCE_WIN32
- return _wcsnicmp (s1, s2, maxChars);
- #else
- while (--maxChars >= 0)
- {
- if (*s1 != *s2)
- {
- const int diff = toUpperCase (*s1) - toUpperCase (*s2);
-
- if (diff != 0)
- return diff < 0 ? -1 : 1;
- }
- else if (*s1 == 0)
- break;
-
- ++s1;
- ++s2;
- }
-
- return 0;
- #endif
- }
-
- const char* CharacterFunctions::find (const char* const haystack, const char* const needle) throw()
- {
- return strstr (haystack, needle);
- }
-
- const juce_wchar* CharacterFunctions::find (const juce_wchar* haystack, const juce_wchar* const needle) throw()
- {
- #if MACOS_10_2_OR_EARLIER
- while (*haystack != 0)
- {
- const juce_wchar* s1 = haystack;
- const juce_wchar* s2 = needle;
-
- for (;;)
- {
- if (*s2 == 0)
- return haystack;
-
- if (*s1 != *s2 || *s2 == 0)
- break;
-
- ++s1;
- ++s2;
- }
-
- ++haystack;
- }
-
- return 0;
- #else
- return wcsstr (haystack, needle);
- #endif
- }
-
- int CharacterFunctions::indexOfChar (const char* const haystack, const char needle, const bool ignoreCase) throw()
- {
- if (haystack != 0)
- {
- int i = 0;
-
- if (ignoreCase)
- {
- const char n1 = toLowerCase (needle);
- const char n2 = toUpperCase (needle);
-
- if (n1 != n2) // if the char is the same in upper/lower case, fall through to the normal search
- {
- while (haystack[i] != 0)
- {
- if (haystack[i] == n1 || haystack[i] == n2)
- return i;
-
- ++i;
- }
-
- return -1;
- }
-
- jassert (n1 == needle);
- }
-
- while (haystack[i] != 0)
- {
- if (haystack[i] == needle)
- return i;
-
- ++i;
- }
- }
-
- return -1;
- }
-
- int CharacterFunctions::indexOfChar (const juce_wchar* const haystack, const juce_wchar needle, const bool ignoreCase) throw()
- {
- if (haystack != 0)
- {
- int i = 0;
-
- if (ignoreCase)
- {
- const juce_wchar n1 = toLowerCase (needle);
- const juce_wchar n2 = toUpperCase (needle);
-
- if (n1 != n2) // if the char is the same in upper/lower case, fall through to the normal search
- {
- while (haystack[i] != 0)
- {
- if (haystack[i] == n1 || haystack[i] == n2)
- return i;
-
- ++i;
- }
-
- return -1;
- }
-
- jassert (n1 == needle);
- }
-
- while (haystack[i] != 0)
- {
- if (haystack[i] == needle)
- return i;
-
- ++i;
- }
- }
-
- return -1;
- }
-
- int CharacterFunctions::indexOfCharFast (const char* const haystack, const char needle) throw()
- {
- jassert (haystack != 0);
-
- int i = 0;
- while (haystack[i] != 0)
- {
- if (haystack[i] == needle)
- return i;
-
- ++i;
- }
-
- return -1;
- }
-
- int CharacterFunctions::indexOfCharFast (const juce_wchar* const haystack, const juce_wchar needle) throw()
- {
- jassert (haystack != 0);
-
- int i = 0;
- while (haystack[i] != 0)
- {
- if (haystack[i] == needle)
- return i;
-
- ++i;
- }
-
- return -1;
- }
-
- int CharacterFunctions::getIntialSectionContainingOnly (const char* const text, const char* const allowedChars) throw()
- {
- return allowedChars == 0 ? 0 : (int) strspn (text, allowedChars);
- }
-
- int CharacterFunctions::getIntialSectionContainingOnly (const juce_wchar* const text, const juce_wchar* const allowedChars) throw()
- {
- if (allowedChars == 0)
- return 0;
-
- int i = 0;
-
- for (;;)
- {
- if (indexOfCharFast (allowedChars, text[i]) < 0)
- break;
-
- ++i;
- }
-
- return i;
- }
-
- int CharacterFunctions::ftime (char* const dest, const int maxChars, const char* const format, const struct tm* const tm) throw()
- {
- return (int) strftime (dest, maxChars, format, tm);
- }
-
- int CharacterFunctions::ftime (juce_wchar* const dest, const int maxChars, const juce_wchar* const format, const struct tm* const tm) throw()
- {
- #if MACOS_10_2_OR_EARLIER
- const String formatTemp (format);
- size_t num = strftime ((char*) dest, maxChars, (const char*) formatTemp, tm);
- String temp ((char*) dest);
- temp.copyToBuffer (dest, num);
- dest [num] = 0;
- return (int) num;
- #else
- return (int) wcsftime (dest, maxChars, format, tm);
- #endif
- }
-
- int CharacterFunctions::getIntValue (const char* const s) throw()
- {
- return atoi (s);
- }
-
- int CharacterFunctions::getIntValue (const juce_wchar* s) throw()
- {
- #if JUCE_WIN32
- return _wtoi (s);
- #else
- int v = 0;
-
- while (isWhitespace (*s))
- ++s;
-
- const bool isNeg = *s == T('-');
- if (isNeg)
- ++s;
-
- for (;;)
- {
- const wchar_t c = *s++;
-
- if (c >= T('0') && c <= T('9'))
- v = v * 10 + (int) (c - T('0'));
- else
- break;
- }
-
- return isNeg ? -v : v;
- #endif
- }
-
- int64 CharacterFunctions::getInt64Value (const char* s) throw()
- {
- #if JUCE_LINUX
- return atoll (s);
- #elif defined (JUCE_WIN32)
- return _atoi64 (s);
- #else
- int64 v = 0;
-
- while (isWhitespace (*s))
- ++s;
-
- const bool isNeg = *s == T('-');
- if (isNeg)
- ++s;
-
- for (;;)
- {
- const char c = *s++;
-
- if (c >= '0' && c <= '9')
- v = v * 10 + (int64) (c - '0');
- else
- break;
- }
-
- return isNeg ? -v : v;
- #endif
- }
-
- int64 CharacterFunctions::getInt64Value (const juce_wchar* s) throw()
- {
- #if JUCE_WIN32
- return _wtoi64 (s);
- #else
- int64 v = 0;
-
- while (isWhitespace (*s))
- ++s;
-
- const bool isNeg = *s == T('-');
- if (isNeg)
- ++s;
-
- for (;;)
- {
- const juce_wchar c = *s++;
-
- if (c >= T('0') && c <= T('9'))
- v = v * 10 + (int64) (c - T('0'));
- else
- break;
- }
-
- return isNeg ? -v : v;
- #endif
- }
-
- double CharacterFunctions::getDoubleValue (const char* const s) throw()
- {
- return atof (s);
- }
-
- double CharacterFunctions::getDoubleValue (const juce_wchar* const s) throw()
- {
- #if MACOS_10_2_OR_EARLIER
- String temp (s);
- return atof ((const char*) temp);
- #else
- wchar_t* endChar;
- return wcstod (s, &endChar);
- #endif
- }
-
- char CharacterFunctions::toUpperCase (const char character) throw()
- {
- return (char) toupper (character);
- }
-
- juce_wchar CharacterFunctions::toUpperCase (const juce_wchar character) throw()
- {
- #if MACOS_10_2_OR_EARLIER
- return toupper ((char) character);
- #else
- return towupper (character);
- #endif
- }
-
- void CharacterFunctions::toUpperCase (char* s) throw()
- {
- #if JUCE_WIN32
- strupr (s);
- #else
- while (*s != 0)
- {
- *s = toUpperCase (*s);
- ++s;
- }
- #endif
- }
-
- void CharacterFunctions::toUpperCase (juce_wchar* s) throw()
- {
- #if JUCE_WIN32
- _wcsupr (s);
- #else
- while (*s != 0)
- {
- *s = toUpperCase (*s);
- ++s;
- }
- #endif
- }
-
- bool CharacterFunctions::isUpperCase (const char character) throw()
- {
- return isupper (character) != 0;
- }
-
- bool CharacterFunctions::isUpperCase (const juce_wchar character) throw()
- {
- #if JUCE_WIN32
- return iswupper (character) != 0;
- #else
- return toLowerCase (character) != character;
- #endif
- }
-
- char CharacterFunctions::toLowerCase (const char character) throw()
- {
- return (char) tolower (character);
- }
-
- juce_wchar CharacterFunctions::toLowerCase (const juce_wchar character) throw()
- {
- #if MACOS_10_2_OR_EARLIER
- return tolower ((char) character);
- #else
- return towlower (character);
- #endif
- }
-
- void CharacterFunctions::toLowerCase (char* s) throw()
- {
- #if JUCE_WIN32
- strlwr (s);
- #else
- while (*s != 0)
- {
- *s = toLowerCase (*s);
- ++s;
- }
- #endif
- }
-
- void CharacterFunctions::toLowerCase (juce_wchar* s) throw()
- {
- #if JUCE_WIN32
- _wcslwr (s);
- #else
- while (*s != 0)
- {
- *s = toLowerCase (*s);
- ++s;
- }
- #endif
- }
-
- bool CharacterFunctions::isLowerCase (const char character) throw()
- {
- return islower (character) != 0;
- }
-
- bool CharacterFunctions::isLowerCase (const juce_wchar character) throw()
- {
- #if JUCE_WIN32
- return iswlower (character) != 0;
- #else
- return toUpperCase (character) != character;
- #endif
- }
-
- bool CharacterFunctions::isWhitespace (const char character) throw()
- {
- return character == T(' ') || (character <= 13 && character >= 9);
- }
-
- bool CharacterFunctions::isWhitespace (const juce_wchar character) throw()
- {
- #if MACOS_10_2_OR_EARLIER
- return isWhitespace ((char) character);
- #else
- return iswspace (character) != 0;
- #endif
- }
-
- bool CharacterFunctions::isDigit (const char character) throw()
- {
- return (character >= '0' && character <= '9');
- }
-
- bool CharacterFunctions::isDigit (const juce_wchar character) throw()
- {
- #if MACOS_10_2_OR_EARLIER
- return isdigit ((char) character) != 0;
- #else
- return iswdigit (character) != 0;
- #endif
- }
-
- bool CharacterFunctions::isLetter (const char character) throw()
- {
- return (character >= 'a' && character <= 'z')
- || (character >= 'A' && character <= 'Z');
- }
-
- bool CharacterFunctions::isLetter (const juce_wchar character) throw()
- {
- #if MACOS_10_2_OR_EARLIER
- return isLetter ((char) character);
- #else
- return iswalpha (character) != 0;
- #endif
- }
-
- bool CharacterFunctions::isLetterOrDigit (const char character) throw()
- {
- return (character >= 'a' && character <= 'z')
- || (character >= 'A' && character <= 'Z')
- || (character >= '0' && character <= '9');
- }
-
- bool CharacterFunctions::isLetterOrDigit (const juce_wchar character) throw()
- {
- #if MACOS_10_2_OR_EARLIER
- return isLetterOrDigit ((char) character);
- #else
- return iswalnum (character) != 0;
- #endif
- }
-
- int CharacterFunctions::getHexDigitValue (const tchar digit) throw()
- {
- if (digit >= T('0') && digit <= T('9'))
- return digit - T('0');
- else if (digit >= T('a') && digit <= T('f'))
- return digit - (T('a') - 10);
- else if (digit >= T('A') && digit <= T('F'))
- return digit - (T('A') - 10);
-
- return -1;
- }
-
- int CharacterFunctions::printf (char* const dest, const int maxLength, const char* const format, ...) throw()
- {
- va_list list;
- va_start (list, format);
- return vprintf (dest, maxLength, format, list);
- }
-
- int CharacterFunctions::printf (juce_wchar* const dest, const int maxLength, const juce_wchar* const format, ...) throw()
- {
- va_list list;
- va_start (list, format);
- return vprintf (dest, maxLength, format, list);
- }
-
- int CharacterFunctions::vprintf (char* const dest, const int maxLength, const char* const format, va_list& args) throw()
- {
- #if JUCE_WIN32
- return (int) _vsnprintf (dest, maxLength, format, args);
- #else
- return (int) vsnprintf (dest, maxLength, format, args);
- #endif
- }
-
- int CharacterFunctions::vprintf (juce_wchar* const dest, const int maxLength, const juce_wchar* const format, va_list& args) throw()
- {
- #if MACOS_10_3_OR_EARLIER
- const String formatTemp (format);
- size_t num = vprintf ((char*) dest, maxLength, formatTemp, args);
- String temp ((char*) dest);
- temp.copyToBuffer (dest, num);
- dest [num] = 0;
- return (int) num;
- #elif defined (JUCE_WIN32)
- return (int) _vsnwprintf (dest, maxLength, format, args);
- #else
- return (int) vswprintf (dest, maxLength, format, args);
- #endif
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_CharacterFunctions.cpp *********/
-
- /********* Start of inlined file: juce_LocalisedStrings.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- LocalisedStrings::LocalisedStrings (const String& fileContents) throw()
- {
- loadFromText (fileContents);
- }
-
- LocalisedStrings::LocalisedStrings (const File& fileToLoad) throw()
- {
- loadFromText (fileToLoad.loadFileAsString());
- }
-
- LocalisedStrings::~LocalisedStrings() throw()
- {
- }
-
- const String LocalisedStrings::translate (const String& text) const throw()
- {
- return translations.getValue (text, text);
- }
-
- static int findCloseQuote (const String& text, int startPos) throw()
- {
- tchar lastChar = 0;
-
- for (;;)
- {
- const tchar c = text [startPos];
-
- if (c == 0 || (c == T('"') && lastChar != T('\\')))
- break;
-
- lastChar = c;
- ++startPos;
- }
-
- return startPos;
- }
-
- static const String unescapeString (const String& s) throw()
- {
- return s.replace (T("\\\""), T("\""))
- .replace (T("\\\'"), T("\'"))
- .replace (T("\\t"), T("\t"))
- .replace (T("\\r"), T("\r"))
- .replace (T("\\n"), T("\n"));
- }
-
- void LocalisedStrings::loadFromText (const String& fileContents) throw()
- {
- StringArray lines;
- lines.addLines (fileContents);
-
- for (int i = 0; i < lines.size(); ++i)
- {
- String line (lines[i].trim());
-
- if (line.startsWithChar (T('"')))
- {
- int closeQuote = findCloseQuote (line, 1);
-
- const String originalText (unescapeString (line.substring (1, closeQuote)));
-
- if (originalText.isNotEmpty())
- {
- const int openingQuote = findCloseQuote (line, closeQuote + 1);
- closeQuote = findCloseQuote (line, openingQuote + 1);
-
- const String newText (unescapeString (line.substring (openingQuote + 1, closeQuote)));
-
- if (newText.isNotEmpty())
- translations.set (originalText, newText);
- }
- }
- else if (line.startsWithIgnoreCase (T("language:")))
- {
- languageName = line.substring (9).trim();
- }
- else if (line.startsWithIgnoreCase (T("countries:")))
- {
- countryCodes.addTokens (line.substring (10).trim(), true);
- countryCodes.trim();
- countryCodes.removeEmptyStrings();
- }
- }
- }
-
- static CriticalSection currentMappingsLock;
- static LocalisedStrings* currentMappings = 0;
-
- void LocalisedStrings::setCurrentMappings (LocalisedStrings* newTranslations) throw()
- {
- const ScopedLock sl (currentMappingsLock);
-
- delete currentMappings;
- currentMappings = newTranslations;
- }
-
- LocalisedStrings* LocalisedStrings::getCurrentMappings() throw()
- {
- return currentMappings;
- }
-
- const String LocalisedStrings::translateWithCurrentMappings (const String& text) throw()
- {
- const ScopedLock sl (currentMappingsLock);
-
- if (currentMappings != 0)
- return currentMappings->translate (text);
-
- return text;
- }
-
- const String LocalisedStrings::translateWithCurrentMappings (const char* text) throw()
- {
- return translateWithCurrentMappings (String (text));
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_LocalisedStrings.cpp *********/
-
- /********* Start of inlined file: juce_String.cpp *********/
- #ifdef _MSC_VER
- #pragma warning (disable: 4514)
- #pragma warning (push)
- #endif
- #include <locale>
-
- #if JUCE_MSVC
- #include <float.h>
- #endif
-
- BEGIN_JUCE_NAMESPACE
-
- #ifdef _MSC_VER
- #pragma warning (pop)
- #endif
-
- static const char* const emptyCharString = "\0\0\0\0JUCE";
- static const int safeEmptyStringRefCount = 0x3fffffff;
- String::InternalRefCountedStringHolder String::emptyString = { safeEmptyStringRefCount, 0, { 0 } };
- static tchar decimalPoint = T('.');
-
- void juce_initialiseStrings()
- {
- decimalPoint = String::fromUTF8 ((const uint8*) localeconv()->decimal_point) [0];
- }
-
- void String::deleteInternal() throw()
- {
- if (atomicDecrementAndReturn (text->refCount) == 0)
- juce_free (text);
- }
-
- void String::createInternal (const int numChars) throw()
- {
- jassert (numChars > 0);
-
- text = (InternalRefCountedStringHolder*) juce_malloc (sizeof (InternalRefCountedStringHolder)
- + numChars * sizeof (tchar));
- text->refCount = 1;
- text->allocatedNumChars = numChars;
- text->text[0] = 0;
- }
-
- void String::createInternal (const tchar* const t, const tchar* const textEnd) throw()
- {
- jassert (*(textEnd - 1) == 0); // must have a null terminator
-
- const int numChars = (int) (textEnd - t);
- createInternal (numChars - 1);
- memcpy (text->text, t, numChars * sizeof (tchar));
- }
-
- void String::appendInternal (const tchar* const newText,
- const int numExtraChars) throw()
- {
- if (numExtraChars > 0)
- {
- const int oldLen = CharacterFunctions::length (text->text);
- const int newTotalLen = oldLen + numExtraChars;
-
- if (text->refCount > 1)
- {
- // it's in use by other strings as well, so we need to make a private copy before messing with it..
- InternalRefCountedStringHolder* const newTextHolder
- = (InternalRefCountedStringHolder*) juce_malloc (sizeof (InternalRefCountedStringHolder)
- + newTotalLen * sizeof (tchar));
- newTextHolder->refCount = 1;
- newTextHolder->allocatedNumChars = newTotalLen;
-
- memcpy (newTextHolder->text, text->text, oldLen * sizeof (tchar));
- memcpy (newTextHolder->text + oldLen, newText, numExtraChars * sizeof (tchar));
-
- InternalRefCountedStringHolder* const old = text;
- text = newTextHolder;
-
- if (atomicDecrementAndReturn (old->refCount) == 0)
- juce_free (old);
- }
- else
- {
- // no other strings using it, so just expand it if needed..
- if (newTotalLen > text->allocatedNumChars)
- {
- text = (InternalRefCountedStringHolder*)
- juce_realloc (text, sizeof (InternalRefCountedStringHolder)
- + newTotalLen * sizeof (tchar));
-
- text->allocatedNumChars = newTotalLen;
- }
-
- memcpy (text->text + oldLen, newText, numExtraChars * sizeof (tchar));
- }
-
- text->text [newTotalLen] = 0;
- }
- }
-
- void String::dupeInternalIfMultiplyReferenced() throw()
- {
- if (text->refCount > 1)
- {
- InternalRefCountedStringHolder* const old = text;
- const int len = old->allocatedNumChars;
-
- InternalRefCountedStringHolder* const newTextHolder
- = (InternalRefCountedStringHolder*) juce_malloc (sizeof (InternalRefCountedStringHolder)
- + len * sizeof (tchar));
-
- newTextHolder->refCount = 1;
- newTextHolder->allocatedNumChars = len;
-
- memcpy (newTextHolder->text, old->text, (len + 1) * sizeof (tchar));
-
- text = newTextHolder;
-
- if (atomicDecrementAndReturn (old->refCount) == 0)
- juce_free (old);
- }
- }
-
- const String String::empty;
-
- String::String() throw()
- : text (&emptyString)
- {
- }
-
- String::String (const String& other) throw()
- : text (other.text)
- {
- atomicIncrement (text->refCount);
- }
-
- String::String (const int numChars,
- const int /*dummyVariable*/) throw()
- {
- createInternal (numChars);
- }
-
- String::String (const char* const t) throw()
- {
- if (t != 0 && *t != 0)
- {
- const int len = CharacterFunctions::length (t);
- createInternal (len);
-
- #if JUCE_STRINGS_ARE_UNICODE
- CharacterFunctions::copy (text->text, t, len + 1);
- #else
- memcpy (text->text, t, len + 1);
- #endif
- }
- else
- {
- text = &emptyString;
- emptyString.refCount = safeEmptyStringRefCount;
- }
- }
-
- String::String (const juce_wchar* const t) throw()
- {
- if (t != 0 && *t != 0)
- {
- #if JUCE_STRINGS_ARE_UNICODE
- const int len = CharacterFunctions::length (t);
- createInternal (len);
-
- memcpy (text->text, t, (len + 1) * sizeof (tchar));
- #else
- const int len = CharacterFunctions::bytesRequiredForCopy (t);
- createInternal (len);
-
- CharacterFunctions::copy (text->text, t, len + 1);
- #endif
- }
- else
- {
- text = &emptyString;
- emptyString.refCount = safeEmptyStringRefCount;
- }
- }
-
- String::String (const char* const t,
- const int maxChars) throw()
- {
- int i;
- for (i = 0; i < maxChars; ++i)
- if (t[i] == 0)
- break;
-
- if (i > 0)
- {
- createInternal (i);
-
- #if JUCE_STRINGS_ARE_UNICODE
- CharacterFunctions::copy (text->text, t, i);
- #else
- memcpy (text->text, t, i);
- #endif
-
- text->text [i] = 0;
- }
- else
- {
- text = &emptyString;
- emptyString.refCount = safeEmptyStringRefCount;
- }
- }
-
- String::String (const juce_wchar* const t,
- const int maxChars) throw()
- {
- int i;
- for (i = 0; i < maxChars; ++i)
- if (t[i] == 0)
- break;
-
- if (i > 0)
- {
- createInternal (i);
-
- #if JUCE_STRINGS_ARE_UNICODE
- memcpy (text->text, t, i * sizeof (tchar));
- #else
- CharacterFunctions::copy (text->text, t, i);
- #endif
- text->text [i] = 0;
- }
- else
- {
- text = &emptyString;
- emptyString.refCount = safeEmptyStringRefCount;
- }
- }
-
- const String String::charToString (const tchar character) throw()
- {
- tchar temp[2];
- temp[0] = character;
- temp[1] = 0;
-
- return String (temp);
- }
-
- // pass in a pointer to the END of a buffer..
- static tchar* int64ToCharString (tchar* t, const int64 n) throw()
- {
- *--t = 0;
- int64 v = (n >= 0) ? n : -n;
-
- do
- {
- *--t = (tchar) (T('0') + (int) (v % 10));
- v /= 10;
-
- } while (v > 0);
-
- if (n < 0)
- *--t = T('-');
-
- return t;
- }
-
- static tchar* intToCharString (tchar* t, const int n) throw()
- {
- if (n == (int) 0x80000000) // (would cause an overflow)
- return int64ToCharString (t, n);
-
- *--t = 0;
- int v = abs (n);
-
- do
- {
- *--t = (tchar) (T('0') + (v % 10));
- v /= 10;
-
- } while (v > 0);
-
- if (n < 0)
- *--t = T('-');
-
- return t;
- }
-
- static tchar* uintToCharString (tchar* t, unsigned int v) throw()
- {
- *--t = 0;
-
- do
- {
- *--t = (tchar) (T('0') + (v % 10));
- v /= 10;
-
- } while (v > 0);
-
- return t;
- }
-
- String::String (const int number) throw()
- {
- tchar buffer [16];
- tchar* const end = buffer + 16;
-
- createInternal (intToCharString (end, number), end);
- }
-
- String::String (const unsigned int number) throw()
- {
- tchar buffer [16];
- tchar* const end = buffer + 16;
-
- createInternal (uintToCharString (end, number), end);
- }
-
- String::String (const short number) throw()
- {
- tchar buffer [16];
- tchar* const end = buffer + 16;
-
- createInternal (intToCharString (end, (int) number), end);
- }
-
- String::String (const unsigned short number) throw()
- {
- tchar buffer [16];
- tchar* const end = buffer + 16;
-
- createInternal (uintToCharString (end, (unsigned int) number), end);
- }
-
- String::String (const int64 number) throw()
- {
- tchar buffer [32];
- tchar* const end = buffer + 32;
-
- createInternal (int64ToCharString (end, number), end);
- }
-
- String::String (const uint64 number) throw()
- {
- tchar buffer [32];
- tchar* const end = buffer + 32;
- tchar* t = end;
-
- *--t = 0;
- int64 v = number;
-
- do
- {
- *--t = (tchar) (T('0') + (int) (v % 10));
- v /= 10;
-
- } while (v > 0);
-
- createInternal (t, end);
- }
-
- // a double-to-string routine that actually uses the number of dec. places you asked for
- // without resorting to exponent notation if the number's too big or small (which is what printf does).
- void String::doubleToStringWithDecPlaces (double n, int numDecPlaces) throw()
- {
- const int bufSize = 80;
- tchar buffer [bufSize];
- int len;
- tchar* t;
-
- if (numDecPlaces > 0 && n > -1.0e20 && n < 1.0e20)
- {
- int64 v = (int64) (pow (10.0, numDecPlaces) * fabs (n) + 0.5);
-
- t = buffer + bufSize;
- *--t = (tchar) 0;
-
- while (numDecPlaces >= 0 || v > 0)
- {
- if (numDecPlaces == 0)
- *--t = decimalPoint;
-
- *--t = (tchar) (T('0') + (v % 10));
-
- v /= 10;
- --numDecPlaces;
- }
-
- if (n < 0)
- *--t = T('-');
-
- len = (int) ((buffer + bufSize) - t);
- }
- else
- {
- len = CharacterFunctions::printf (buffer, bufSize, T("%.9g"), n) + 1;
- t = buffer;
- }
-
- if (len > 1)
- {
- jassert (len < numElementsInArray (buffer));
-
- createInternal (len - 1);
- memcpy (text->text, t, len * sizeof (tchar));
- }
- else
- {
- jassert (*t == 0);
- text = &emptyString;
- emptyString.refCount = safeEmptyStringRefCount;
- }
- }
-
- String::String (const float number,
- const int numberOfDecimalPlaces) throw()
- {
- doubleToStringWithDecPlaces ((double) number,
- numberOfDecimalPlaces);
- }
-
- String::String (const double number,
- const int numberOfDecimalPlaces) throw()
- {
- doubleToStringWithDecPlaces (number,
- numberOfDecimalPlaces);
- }
-
- String::~String() throw()
- {
- if (atomicDecrementAndReturn (text->refCount) == 0)
- juce_free (text);
- }
-
- void String::preallocateStorage (const int numChars) throw()
- {
- if (numChars > text->allocatedNumChars)
- {
- dupeInternalIfMultiplyReferenced();
-
- text = (InternalRefCountedStringHolder*) juce_realloc (text, sizeof (InternalRefCountedStringHolder)
- + numChars * sizeof (tchar));
- text->allocatedNumChars = numChars;
- }
- }
-
- #if JUCE_STRINGS_ARE_UNICODE
- String::operator const char*() const throw()
- {
- if (isEmpty())
- {
- return (const char*) emptyCharString;
- }
- else
- {
- String* const mutableThis = const_cast <String*> (this);
-
- mutableThis->dupeInternalIfMultiplyReferenced();
- int len = CharacterFunctions::bytesRequiredForCopy (text->text) + 1;
- mutableThis->text = (InternalRefCountedStringHolder*)
- juce_realloc (text, sizeof (InternalRefCountedStringHolder)
- + (len * sizeof (juce_wchar) + len));
- char* otherCopy = (char*) (text->text + len);
- --len;
-
- CharacterFunctions::copy (otherCopy, text->text, len);
- otherCopy [len] = 0;
- return otherCopy;
- }
- }
-
- #else
-
- String::operator const juce_wchar*() const throw()
- {
- if (isEmpty())
- {
- return (const juce_wchar*) emptyCharString;
- }
- else
- {
- String* const mutableThis = const_cast <String*> (this);
-
- mutableThis->dupeInternalIfMultiplyReferenced();
- int len = CharacterFunctions::length (text->text) + 1;
- mutableThis->text = (InternalRefCountedStringHolder*)
- juce_realloc (text, sizeof (InternalRefCountedStringHolder)
- + (len * sizeof (juce_wchar) + len));
-
- juce_wchar* otherCopy = (juce_wchar*) (text->text + len);
- --len;
-
- CharacterFunctions::copy (otherCopy, text->text, len);
- otherCopy [len] = 0;
- return otherCopy;
- }
- }
-
- #endif
-
- void String::copyToBuffer (char* const destBuffer,
- const int bufferSizeBytes) const throw()
- {
- #if JUCE_STRINGS_ARE_UNICODE
- const int len = jmin (bufferSizeBytes, CharacterFunctions::bytesRequiredForCopy (text->text));
- CharacterFunctions::copy (destBuffer, text->text, len);
- #else
- const int len = jmin (bufferSizeBytes, length());
- memcpy (destBuffer, text->text, len * sizeof (tchar));
- #endif
-
- destBuffer [len] = 0;
- }
-
- void String::copyToBuffer (juce_wchar* const destBuffer,
- const int maxCharsToCopy) const throw()
- {
- const int len = jmin (maxCharsToCopy, length());
-
- #if JUCE_STRINGS_ARE_UNICODE
- memcpy (destBuffer, text->text, len * sizeof (juce_wchar));
- #else
- CharacterFunctions::copy (destBuffer, text->text, len);
- #endif
-
- destBuffer [len] = 0;
- }
-
- int String::length() const throw()
- {
- return CharacterFunctions::length (text->text);
- }
-
- int String::hashCode() const throw()
- {
- const tchar* t = text->text;
- int result = 0;
-
- while (*t != (tchar) 0)
- result = 31 * result + *t++;
-
- return result;
- }
-
- int64 String::hashCode64() const throw()
- {
- const tchar* t = text->text;
- int64 result = 0;
-
- while (*t != (tchar) 0)
- result = 101 * result + *t++;
-
- return result;
- }
-
- const String& String::operator= (const tchar* const otherText) throw()
- {
- if (otherText != 0 && *otherText != 0)
- {
- const int otherLen = CharacterFunctions::length (otherText);
-
- if (otherLen > 0)
- {
- // avoid resizing the memory block if the string is
- // shrinking..
- if (text->refCount > 1
- || otherLen > text->allocatedNumChars
- || otherLen <= (text->allocatedNumChars >> 1))
- {
- deleteInternal();
- createInternal (otherLen);
- }
-
- memcpy (text->text, otherText, (otherLen + 1) * sizeof (tchar));
-
- return *this;
- }
- }
-
- deleteInternal();
- text = &emptyString;
- emptyString.refCount = safeEmptyStringRefCount;
-
- return *this;
- }
-
- const String& String::operator= (const String& other) throw()
- {
- if (this != &other)
- {
- atomicIncrement (other.text->refCount);
-
- if (atomicDecrementAndReturn (text->refCount) == 0)
- juce_free (text);
-
- text = other.text;
- }
-
- return *this;
- }
-
- bool String::operator== (const String& other) const throw()
- {
- return text == other.text
- || CharacterFunctions::compare (text->text, other.text->text) == 0;
- }
-
- bool String::operator== (const tchar* const t) const throw()
- {
- return t != 0 ? CharacterFunctions::compare (text->text, t) == 0
- : isEmpty();
- }
-
- bool String::equalsIgnoreCase (const tchar* t) const throw()
- {
- return t != 0 ? CharacterFunctions::compareIgnoreCase (text->text, t) == 0
- : isEmpty();
- }
-
- bool String::equalsIgnoreCase (const String& other) const throw()
- {
- return text == other.text
- || CharacterFunctions::compareIgnoreCase (text->text, other.text->text) == 0;
- }
-
- bool String::operator!= (const String& other) const throw()
- {
- return text != other.text
- && CharacterFunctions::compare (text->text, other.text->text) != 0;
- }
-
- bool String::operator!= (const tchar* const t) const throw()
- {
- return t != 0 ? (CharacterFunctions::compare (text->text, t) != 0)
- : isNotEmpty();
- }
-
- bool String::operator> (const String& other) const throw()
- {
- return compare (other) > 0;
- }
-
- bool String::operator< (const tchar* const other) const throw()
- {
- return compare (other) < 0;
- }
-
- bool String::operator>= (const String& other) const throw()
- {
- return compare (other) >= 0;
- }
-
- bool String::operator<= (const tchar* const other) const throw()
- {
- return compare (other) <= 0;
- }
-
- int String::compare (const tchar* const other) const throw()
- {
- return other != 0 ? CharacterFunctions::compare (text->text, other)
- : isEmpty();
- }
-
- int String::compareIgnoreCase (const tchar* const other) const throw()
- {
- return other != 0 ? CharacterFunctions::compareIgnoreCase (text->text, other)
- : isEmpty();
- }
-
- int String::compareLexicographically (const tchar* other) const throw()
- {
- if (other == 0)
- return isEmpty();
-
- const tchar* s1 = text->text;
- while (*s1 != 0 && ! CharacterFunctions::isLetterOrDigit (*s1))
- ++s1;
-
- while (*other != 0 && ! CharacterFunctions::isLetterOrDigit (*other))
- ++other;
-
- return CharacterFunctions::compareIgnoreCase (s1, other);
- }
-
- const String String::operator+ (const String& other) const throw()
- {
- if (*(other.text->text) == 0)
- return *this;
-
- if (isEmpty())
- return other;
-
- const int len = CharacterFunctions::length (text->text);
- const int otherLen = CharacterFunctions::length (other.text->text);
-
- String result (len + otherLen, (int) 0);
- memcpy (result.text->text, text->text, len * sizeof (tchar));
- memcpy (result.text->text + len, other.text->text, otherLen * sizeof (tchar));
- result.text->text [len + otherLen] = 0;
-
- return result;
- }
-
- const String String::operator+ (const tchar* const textToAppend) const throw()
- {
- if (textToAppend == 0 || *textToAppend == 0)
- return *this;
-
- const int len = CharacterFunctions::length (text->text);
- const int otherLen = CharacterFunctions::length (textToAppend);
-
- String result (len + otherLen, (int) 0);
- memcpy (result.text->text, text->text, len * sizeof (tchar));
- memcpy (result.text->text + len, textToAppend, otherLen * sizeof (tchar));
- result.text->text [len + otherLen] = 0;
-
- return result;
- }
-
- const String String::operator+ (const tchar characterToAppend) const throw()
- {
- if (characterToAppend == 0)
- return *this;
-
- const int len = CharacterFunctions::length (text->text);
- String result ((int) (len + 1), (int) 0);
-
- memcpy (result.text->text, text->text, len * sizeof (tchar));
- result.text->text[len] = characterToAppend;
- result.text->text[len + 1] = 0;
-
- return result;
- }
-
- const String JUCE_PUBLIC_FUNCTION operator+ (const char* const string1,
- const String& string2) throw()
- {
- String s (string1);
- s += string2;
- return s;
- }
-
- const String JUCE_PUBLIC_FUNCTION operator+ (const juce_wchar* const string1,
- const String& string2) throw()
- {
- String s (string1);
- s += string2;
- return s;
- }
-
- const String& String::operator+= (const tchar* const t) throw()
- {
- if (t != 0)
- appendInternal (t, CharacterFunctions::length (t));
-
- return *this;
- }
-
- const String& String::operator+= (const String& other) throw()
- {
- if (isEmpty())
- operator= (other);
- else
- appendInternal (other.text->text,
- CharacterFunctions::length (other.text->text));
-
- return *this;
- }
-
- const String& String::operator+= (const char ch) throw()
- {
- char asString[2];
- asString[0] = ch;
- asString[1] = 0;
-
- #if JUCE_STRINGS_ARE_UNICODE
- operator+= (String (asString));
- #else
- appendInternal (asString, 1);
- #endif
-
- return *this;
- }
-
- const String& String::operator+= (const juce_wchar ch) throw()
- {
- juce_wchar asString[2];
- asString[0] = ch;
- asString[1] = 0;
-
- #if JUCE_STRINGS_ARE_UNICODE
- appendInternal (asString, 1);
- #else
- operator+= (String (asString));
- #endif
-
- return *this;
- }
-
- void String::append (const tchar* const other,
- const int howMany) throw()
- {
- if (howMany > 0)
- {
- int i;
- for (i = 0; i < howMany; ++i)
- if (other[i] == 0)
- break;
-
- appendInternal (other, i);
- }
- }
-
- String& String::operator<< (const int number) throw()
- {
- tchar buffer [64];
- tchar* const end = buffer + 64;
- const tchar* const t = intToCharString (end, number);
- appendInternal (t, (int) (end - t) - 1);
-
- return *this;
- }
-
- String& String::operator<< (const unsigned int number) throw()
- {
- tchar buffer [64];
- tchar* const end = buffer + 64;
- const tchar* const t = uintToCharString (end, number);
- appendInternal (t, (int) (end - t) - 1);
-
- return *this;
- }
-
- String& String::operator<< (const short number) throw()
- {
- tchar buffer [64];
- tchar* const end = buffer + 64;
- const tchar* const t = intToCharString (end, (int) number);
- appendInternal (t, (int) (end - t) - 1);
-
- return *this;
- }
-
- String& String::operator<< (const double number) throw()
- {
- operator+= (String (number));
- return *this;
- }
-
- String& String::operator<< (const float number) throw()
- {
- operator+= (String (number));
- return *this;
- }
-
- String& String::operator<< (const char character) throw()
- {
- operator+= (character);
- return *this;
- }
-
- String& String::operator<< (const juce_wchar character) throw()
- {
- operator+= (character);
- return *this;
- }
-
- String& String::operator<< (const char* const t) throw()
- {
- #if JUCE_STRINGS_ARE_UNICODE
- operator+= (String (t));
- #else
- operator+= (t);
- #endif
- return *this;
- }
-
- String& String::operator<< (const juce_wchar* const t) throw()
- {
- #if JUCE_STRINGS_ARE_UNICODE
- operator+= (t);
- #else
- operator+= (String (t));
- #endif
- return *this;
- }
-
- String& String::operator<< (const String& t) throw()
- {
- operator+= (t);
- return *this;
- }
-
- int String::indexOfChar (const tchar character) const throw()
- {
- const tchar* t = text->text;
-
- for (;;)
- {
- if (*t == character)
- return (int) (t - text->text);
-
- if (*t++ == 0)
- return -1;
- }
- }
-
- int String::lastIndexOfChar (const tchar character) const throw()
- {
- for (int i = CharacterFunctions::length (text->text); --i >= 0;)
- if (text->text[i] == character)
- return i;
-
- return -1;
- }
-
- int String::indexOf (const tchar* const t) const throw()
- {
- const tchar* const r = CharacterFunctions::find (text->text, t);
- return (r == 0) ? -1
- : (int) (r - text->text);
- }
-
- int String::indexOfChar (const int startIndex,
- const tchar character) const throw()
- {
- if (startIndex >= 0 && startIndex >= CharacterFunctions::length (text->text))
- return -1;
-
- const tchar* t = text->text + jmax (0, startIndex);
-
- for (;;)
- {
- if (*t == character)
- return (int) (t - text->text);
-
- if (*t++ == 0)
- return -1;
- }
- }
-
- int String::indexOfAnyOf (const tchar* const charactersToLookFor,
- const int startIndex,
- const bool ignoreCase) const throw()
- {
- if (charactersToLookFor == 0
- || (startIndex >= 0 && startIndex >= CharacterFunctions::length (text->text)))
- return -1;
-
- const tchar* t = text->text + jmax (0, startIndex);
-
- while (*t != 0)
- {
- if (CharacterFunctions::indexOfChar (charactersToLookFor, *t, ignoreCase) >= 0)
- return (int) (t - text->text);
-
- ++t;
- }
-
- return -1;
- }
-
- int String::indexOf (const int startIndex,
- const tchar* const other) const throw()
- {
- if (other == 0 || startIndex >= CharacterFunctions::length (text->text))
- return -1;
-
- const tchar* const found = CharacterFunctions::find (text->text + jmax (0, startIndex),
- other);
-
- return (found == 0) ? -1
- : (int) (found - text->text);
- }
-
- int String::indexOfIgnoreCase (const tchar* const other) const throw()
- {
- if (other != 0 && *other != 0)
- {
- const int len = CharacterFunctions::length (other);
- const int end = CharacterFunctions::length (text->text) - len;
-
- for (int i = 0; i <= end; ++i)
- if (CharacterFunctions::compareIgnoreCase (text->text + i, other, len) == 0)
- return i;
- }
-
- return -1;
- }
-
- int String::indexOfIgnoreCase (const int startIndex,
- const tchar* const other) const throw()
- {
- if (other != 0 && *other != 0)
- {
- const int len = CharacterFunctions::length (other);
- const int end = length() - len;
-
- for (int i = jmax (0, startIndex); i <= end; ++i)
- if (CharacterFunctions::compareIgnoreCase (text->text + i, other, len) == 0)
- return i;
- }
-
- return -1;
- }
-
- int String::lastIndexOf (const tchar* const other) const throw()
- {
- if (other != 0 && *other != 0)
- {
- const int len = CharacterFunctions::length (other);
- int i = length() - len;
-
- if (i >= 0)
- {
- const tchar* n = text->text + i;
-
- while (i >= 0)
- {
- if (CharacterFunctions::compare (n--, other, len) == 0)
- return i;
-
- --i;
- }
- }
- }
-
- return -1;
- }
-
- int String::lastIndexOfIgnoreCase (const tchar* const other) const throw()
- {
- if (other != 0 && *other != 0)
- {
- const int len = CharacterFunctions::length (other);
- int i = length() - len;
-
- if (i >= 0)
- {
- const tchar* n = text->text + i;
-
- while (i >= 0)
- {
- if (CharacterFunctions::compareIgnoreCase (n--, other, len) == 0)
- return i;
-
- --i;
- }
- }
- }
-
- return -1;
- }
-
- int String::lastIndexOfAnyOf (const tchar* const charactersToLookFor,
- const bool ignoreCase) const throw()
- {
- for (int i = CharacterFunctions::length (text->text); --i >= 0;)
- if (CharacterFunctions::indexOfChar (charactersToLookFor, text->text [i], ignoreCase) >= 0)
- return i;
-
- return -1;
- }
-
- bool String::contains (const tchar* const other) const throw()
- {
- return indexOf (other) >= 0;
- }
-
- bool String::containsChar (const tchar character) const throw()
- {
- return indexOfChar (character) >= 0;
- }
-
- bool String::containsIgnoreCase (const tchar* const t) const throw()
- {
- return indexOfIgnoreCase (t) >= 0;
- }
-
- int String::indexOfWholeWord (const tchar* const word) const throw()
- {
- if (word != 0 && *word != 0)
- {
- const int wordLen = CharacterFunctions::length (word);
- const int end = length() - wordLen;
- const tchar* t = text->text;
-
- for (int i = 0; i <= end; ++i)
- {
- if (CharacterFunctions::compare (t, word, wordLen) == 0
- && (i == 0 || ! CharacterFunctions::isLetterOrDigit (* (t - 1)))
- && ! CharacterFunctions::isLetterOrDigit (t [wordLen]))
- {
- return i;
- }
-
- ++t;
- }
- }
-
- return -1;
- }
-
- int String::indexOfWholeWordIgnoreCase (const tchar* const word) const throw()
- {
- if (word != 0 && *word != 0)
- {
- const int wordLen = CharacterFunctions::length (word);
- const int end = length() - wordLen;
- const tchar* t = text->text;
-
- for (int i = 0; i <= end; ++i)
- {
- if (CharacterFunctions::compareIgnoreCase (t, word, wordLen) == 0
- && (i == 0 || ! CharacterFunctions::isLetterOrDigit (* (t - 1)))
- && ! CharacterFunctions::isLetterOrDigit (t [wordLen]))
- {
- return i;
- }
-
- ++t;
- }
- }
-
- return -1;
- }
-
- bool String::containsWholeWord (const tchar* const wordToLookFor) const throw()
- {
- return indexOfWholeWord (wordToLookFor) >= 0;
- }
-
- bool String::containsWholeWordIgnoreCase (const tchar* const wordToLookFor) const throw()
- {
- return indexOfWholeWordIgnoreCase (wordToLookFor) >= 0;
- }
-
- static int indexOfMatch (const tchar* const wildcard,
- const tchar* const test,
- const bool ignoreCase) throw()
- {
- int start = 0;
-
- while (test [start] != 0)
- {
- int i = 0;
-
- for (;;)
- {
- const tchar wc = wildcard [i];
- const tchar c = test [i + start];
-
- if (wc == c
- || (ignoreCase && CharacterFunctions::toLowerCase (wc) == CharacterFunctions::toLowerCase (c))
- || (wc == T('?') && c != 0))
- {
- if (wc == 0)
- return start;
-
- ++i;
- }
- else
- {
- if (wc == T('*') && (wildcard [i + 1] == 0
- || indexOfMatch (wildcard + i + 1,
- test + start + i,
- ignoreCase) >= 0))
- {
- return start;
- }
-
- break;
- }
- }
-
- ++start;
- }
-
- return -1;
- }
-
- bool String::matchesWildcard (const tchar* wildcard, const bool ignoreCase) const throw()
- {
- int i = 0;
-
- for (;;)
- {
- const tchar wc = wildcard [i];
- const tchar c = text->text [i];
-
- if (wc == c
- || (ignoreCase && CharacterFunctions::toLowerCase (wc) == CharacterFunctions::toLowerCase (c))
- || (wc == T('?') && c != 0))
- {
- if (wc == 0)
- return true;
-
- ++i;
- }
- else
- {
- return wc == T('*') && (wildcard [i + 1] == 0
- || indexOfMatch (wildcard + i + 1,
- text->text + i,
- ignoreCase) >= 0);
- }
- }
- }
-
- void String::printf (const tchar* const pf, ...) throw()
- {
- va_list list;
- va_start (list, pf);
-
- vprintf (pf, list);
- }
-
- const String String::formatted (const tchar* const pf, ...) throw()
- {
- va_list list;
- va_start (list, pf);
-
- String result;
- result.vprintf (pf, list);
- return result;
- }
-
- void String::vprintf (const tchar* const pf, va_list& args) throw()
- {
- tchar stackBuf [256];
- unsigned int bufSize = 256;
- tchar* buf = stackBuf;
-
- deleteInternal();
-
- do
- {
- #if JUCE_LINUX && JUCE_64BIT
- va_list tempArgs;
- va_copy (tempArgs, args);
- const int num = CharacterFunctions::vprintf (buf, bufSize - 1, pf, tempArgs);
- va_end (tempArgs);
- #else
- const int num = CharacterFunctions::vprintf (buf, bufSize - 1, pf, args);
- #endif
-
- if (num > 0)
- {
- createInternal (num);
- memcpy (text->text, buf, (num + 1) * sizeof (tchar));
- break;
- }
- else if (num == 0)
- {
- text = &emptyString;
- emptyString.refCount = safeEmptyStringRefCount;
- break;
- }
-
- if (buf != stackBuf)
- juce_free (buf);
-
- bufSize += 256;
- buf = (tchar*) juce_malloc (bufSize * sizeof (tchar));
- }
- while (bufSize < 65536); // this is a sanity check to avoid situations where vprintf repeatedly
- // returns -1 because of an error rather than because it needs more space.
-
- if (buf != stackBuf)
- juce_free (buf);
- }
-
- const String String::repeatedString (const tchar* const stringToRepeat,
- int numberOfTimesToRepeat) throw()
- {
- const int len = CharacterFunctions::length (stringToRepeat);
- String result ((int) (len * numberOfTimesToRepeat + 1), (int) 0);
-
- tchar* n = result.text->text;
- n[0] = 0;
-
- while (--numberOfTimesToRepeat >= 0)
- {
- CharacterFunctions::append (n, stringToRepeat);
- n += len;
- }
-
- return result;
- }
-
- const String String::replaceSection (int index,
- int numCharsToReplace,
- const tchar* const stringToInsert) const throw()
- {
- if (index < 0)
- {
- // a negative index to replace from?
- jassertfalse
- index = 0;
- }
-
- if (numCharsToReplace < 0)
- {
- // replacing a negative number of characters?
- numCharsToReplace = 0;
- jassertfalse;
- }
-
- const int len = length();
-
- if (index + numCharsToReplace > len)
- {
- if (index > len)
- {
- // replacing beyond the end of the string?
- index = len;
- jassertfalse
- }
-
- numCharsToReplace = len - index;
- }
-
- const int newStringLen = (stringToInsert != 0) ? CharacterFunctions::length (stringToInsert) : 0;
- const int newTotalLen = len + newStringLen - numCharsToReplace;
-
- String result (newTotalLen, (int) 0);
-
- memcpy (result.text->text,
- text->text,
- index * sizeof (tchar));
-
- if (newStringLen > 0)
- memcpy (result.text->text + index,
- stringToInsert,
- newStringLen * sizeof (tchar));
-
- const int endStringLen = newTotalLen - (index + newStringLen);
-
- if (endStringLen > 0)
- memcpy (result.text->text + (index + newStringLen),
- text->text + (index + numCharsToReplace),
- endStringLen * sizeof (tchar));
-
- result.text->text [newTotalLen] = 0;
-
- return result;
- }
-
- const String String::replace (const tchar* const stringToReplace,
- const tchar* const stringToInsert,
- const bool ignoreCase) const throw()
- {
- const int stringToReplaceLen = CharacterFunctions::length (stringToReplace);
- const int stringToInsertLen = CharacterFunctions::length (stringToInsert);
-
- int i = 0;
- String result (*this);
-
- while ((i = (ignoreCase ? result.indexOfIgnoreCase (i, stringToReplace)
- : result.indexOf (i, stringToReplace))) >= 0)
- {
- result = result.replaceSection (i, stringToReplaceLen, stringToInsert);
- i += stringToInsertLen;
- }
-
- return result;
- }
-
- const String String::replaceCharacter (const tchar charToReplace,
- const tchar charToInsert) const throw()
- {
- const int index = indexOfChar (charToReplace);
-
- if (index < 0)
- return *this;
-
- String result (*this);
- result.dupeInternalIfMultiplyReferenced();
-
- tchar* t = result.text->text + index;
-
- while (*t != 0)
- {
- if (*t == charToReplace)
- *t = charToInsert;
-
- ++t;
- }
-
- return result;
- }
-
- const String String::replaceCharacters (const String& charactersToReplace,
- const tchar* const charactersToInsertInstead) const throw()
- {
- String result (*this);
- result.dupeInternalIfMultiplyReferenced();
-
- tchar* t = result.text->text;
- const int len2 = CharacterFunctions::length (charactersToInsertInstead);
-
- // the two strings passed in are supposed to be the same length!
- jassert (len2 == charactersToReplace.length());
-
- while (*t != 0)
- {
- const int index = charactersToReplace.indexOfChar (*t);
-
- if (((unsigned int) index) < (unsigned int) len2)
- *t = charactersToInsertInstead [index];
-
- ++t;
- }
-
- return result;
- }
-
- bool String::startsWith (const tchar* const other) const throw()
- {
- return other != 0
- && CharacterFunctions::compare (text->text, other, CharacterFunctions::length (other)) == 0;
- }
-
- bool String::startsWithIgnoreCase (const tchar* const other) const throw()
- {
- return other != 0
- && CharacterFunctions::compareIgnoreCase (text->text, other, CharacterFunctions::length (other)) == 0;
- }
-
- bool String::startsWithChar (const tchar character) const throw()
- {
- return text->text[0] == character;
- }
-
- bool String::endsWithChar (const tchar character) const throw()
- {
- return text->text[0] != 0
- && text->text [length() - 1] == character;
- }
-
- bool String::endsWith (const tchar* const other) const throw()
- {
- if (other == 0)
- return false;
-
- const int thisLen = length();
- const int otherLen = CharacterFunctions::length (other);
-
- return thisLen >= otherLen
- && CharacterFunctions::compare (text->text + thisLen - otherLen, other) == 0;
- }
-
- bool String::endsWithIgnoreCase (const tchar* const other) const throw()
- {
- if (other == 0)
- return false;
-
- const int thisLen = length();
- const int otherLen = CharacterFunctions::length (other);
-
- return thisLen >= otherLen
- && CharacterFunctions::compareIgnoreCase (text->text + thisLen - otherLen, other) == 0;
- }
-
- const String String::toUpperCase() const throw()
- {
- String result (*this);
- result.dupeInternalIfMultiplyReferenced();
- CharacterFunctions::toUpperCase (result.text->text);
- return result;
- }
-
- const String String::toLowerCase() const throw()
- {
- String result (*this);
- result.dupeInternalIfMultiplyReferenced();
- CharacterFunctions::toLowerCase (result.text->text);
- return result;
- }
-
- tchar& String::operator[] (const int index) throw()
- {
- jassert (((unsigned int) index) <= (unsigned int) length());
-
- dupeInternalIfMultiplyReferenced();
-
- return text->text [index];
- }
-
- tchar String::getLastCharacter() const throw()
- {
- return (isEmpty()) ? ((tchar) 0)
- : text->text [CharacterFunctions::length (text->text) - 1];
- }
-
- const String String::substring (int start, int end) const throw()
- {
- if (start < 0)
- start = 0;
- else if (end <= start)
- return empty;
-
- int len = 0;
- const tchar* const t = text->text;
-
- while (len <= end && t [len] != 0)
- ++len;
-
- if (end >= len)
- {
- if (start == 0)
- return *this;
-
- end = len;
- }
-
- return String (text->text + start,
- end - start);
- }
-
- const String String::substring (const int start) const throw()
- {
- if (start <= 0)
- return *this;
-
- const int len = CharacterFunctions::length (text->text);
-
- if (start >= len)
- return empty;
- else
- return String (text->text + start,
- len - start);
- }
-
- const String String::dropLastCharacters (const int numberToDrop) const throw()
- {
- return String (text->text,
- jmax (0, CharacterFunctions::length (text->text) - numberToDrop));
- }
-
- const String String::fromFirstOccurrenceOf (const tchar* const sub,
- const bool includeSubString,
- const bool ignoreCase) const throw()
- {
- const int i = ignoreCase ? indexOf (sub)
- : indexOfIgnoreCase (sub);
-
- if (i < 0)
- return empty;
- else
- return substring ((includeSubString) ? i : i + CharacterFunctions::length (sub));
- }
-
- const String String::fromLastOccurrenceOf (const tchar* const sub,
- const bool includeSubString,
- const bool ignoreCase) const throw()
- {
- const int i = ignoreCase ? lastIndexOf (sub)
- : lastIndexOfIgnoreCase (sub);
-
- if (i < 0)
- return *this;
- else
- return substring ((includeSubString) ? i : i + CharacterFunctions::length (sub));
- }
-
- const String String::upToFirstOccurrenceOf (const tchar* const sub,
- const bool includeSubString,
- const bool ignoreCase) const throw()
- {
- const int i = ignoreCase ? indexOfIgnoreCase (sub)
- : indexOf (sub);
-
- if (i < 0)
- return *this;
- else
- return substring (0, (includeSubString) ? i + CharacterFunctions::length (sub) : i);
- }
-
- const String String::upToLastOccurrenceOf (const tchar* const sub,
- const bool includeSubString,
- const bool ignoreCase) const throw()
- {
- const int i = ignoreCase ? lastIndexOfIgnoreCase (sub)
- : lastIndexOf (sub);
- if (i < 0)
- return *this;
-
- return substring (0, (includeSubString) ? i + CharacterFunctions::length (sub) : i);
- }
-
- bool String::isQuotedString() const throw()
- {
- const String trimmed (trimStart());
-
- return trimmed[0] == T('"')
- || trimmed[0] == T('\'');
- }
-
- const String String::unquoted() const throw()
- {
- String s (*this);
-
- if (s[0] == T('"') || s[0] == T('\''))
- s = s.substring (1);
-
- const int lastCharIndex = s.length() - 1;
-
- if (lastCharIndex >= 0
- && (s [lastCharIndex] == T('"') || s[lastCharIndex] == T('\'')))
- s [lastCharIndex] = 0;
-
- return s;
- }
-
- const String String::quoted (const tchar quoteCharacter) const throw()
- {
- if (isEmpty())
- return charToString (quoteCharacter) + quoteCharacter;
-
- String t (*this);
-
- if (! t.startsWithChar (quoteCharacter))
- t = charToString (quoteCharacter) + t;
-
- if (! t.endsWithChar (quoteCharacter))
- t += quoteCharacter;
-
- return t;
- }
-
- const String String::trim() const throw()
- {
- if (isEmpty())
- return empty;
-
- int start = 0;
-
- while (CharacterFunctions::isWhitespace (text->text [start]))
- ++start;
-
- const int len = CharacterFunctions::length (text->text);
- int end = len - 1;
-
- while ((end >= start) && CharacterFunctions::isWhitespace (text->text [end]))
- --end;
-
- ++end;
-
- if (end <= start)
- return empty;
- else if (start > 0 || end < len)
- return String (text->text + start, end - start);
- else
- return *this;
- }
-
- const String String::trimStart() const throw()
- {
- if (isEmpty())
- return empty;
-
- const tchar* t = text->text;
-
- while (CharacterFunctions::isWhitespace (*t))
- ++t;
-
- if (t == text->text)
- return *this;
- else
- return String (t);
- }
-
- const String String::trimEnd() const throw()
- {
- if (isEmpty())
- return empty;
-
- const tchar* endT = text->text + (CharacterFunctions::length (text->text) - 1);
-
- while ((endT >= text->text) && CharacterFunctions::isWhitespace (*endT))
- --endT;
-
- return String (text->text, (int) (++endT - text->text));
- }
-
- const String String::retainCharacters (const tchar* const charactersToRetain) const throw()
- {
- jassert (charactersToRetain != 0);
-
- if (isEmpty())
- return empty;
-
- String result (text->allocatedNumChars, (int) 0);
- tchar* dst = result.text->text;
- const tchar* src = text->text;
-
- while (*src != 0)
- {
- if (CharacterFunctions::indexOfCharFast (charactersToRetain, *src) >= 0)
- *dst++ = *src;
-
- ++src;
- }
-
- *dst = 0;
- return result;
- }
-
- const String String::removeCharacters (const tchar* const charactersToRemove) const throw()
- {
- jassert (charactersToRemove != 0);
-
- if (isEmpty())
- return empty;
-
- String result (text->allocatedNumChars, (int) 0);
- tchar* dst = result.text->text;
- const tchar* src = text->text;
-
- while (*src != 0)
- {
- if (CharacterFunctions::indexOfCharFast (charactersToRemove, *src) < 0)
- *dst++ = *src;
-
- ++src;
- }
-
- *dst = 0;
- return result;
- }
-
- const String String::initialSectionContainingOnly (const tchar* const permittedCharacters) const throw()
- {
- return substring (0, CharacterFunctions::getIntialSectionContainingOnly (text->text, permittedCharacters));
- }
-
- const String String::initialSectionNotContaining (const tchar* const charactersToStopAt) const throw()
- {
- jassert (charactersToStopAt != 0);
-
- const tchar* const t = text->text;
- int i = 0;
-
- while (t[i] != 0)
- {
- if (CharacterFunctions::indexOfCharFast (charactersToStopAt, t[i]) >= 0)
- return String (text->text, i);
-
- ++i;
- }
-
- return empty;
- }
-
- bool String::containsOnly (const tchar* const chars) const throw()
- {
- jassert (chars != 0);
-
- const tchar* t = text->text;
-
- while (*t != 0)
- if (CharacterFunctions::indexOfCharFast (chars, *t++) < 0)
- return false;
-
- return true;
- }
-
- bool String::containsAnyOf (const tchar* const chars) const throw()
- {
- jassert (chars != 0);
-
- const tchar* t = text->text;
-
- while (*t != 0)
- if (CharacterFunctions::indexOfCharFast (chars, *t++) >= 0)
- return true;
-
- return false;
- }
-
- int String::getIntValue() const throw()
- {
- return CharacterFunctions::getIntValue (text->text);
- }
-
- int String::getTrailingIntValue() const throw()
- {
- int n = 0;
- int mult = 1;
- const tchar* t = text->text + length();
-
- while (--t >= text->text)
- {
- const tchar c = *t;
-
- if (! CharacterFunctions::isDigit (c))
- {
- if (c == T('-'))
- n = -n;
-
- break;
- }
-
- n += mult * (c - T('0'));
- mult *= 10;
- }
-
- return n;
- }
-
- int64 String::getLargeIntValue() const throw()
- {
- return CharacterFunctions::getInt64Value (text->text);
- }
-
- float String::getFloatValue() const throw()
- {
- return (float) CharacterFunctions::getDoubleValue (text->text);
- }
-
- double String::getDoubleValue() const throw()
- {
- return CharacterFunctions::getDoubleValue (text->text);
- }
-
- static const tchar* const hexDigits = T("0123456789abcdef");
-
- const String String::toHexString (const int number) throw()
- {
- tchar buffer[32];
- tchar* const end = buffer + 32;
- tchar* t = end;
- *--t = 0;
- unsigned int v = (unsigned int) number;
-
- do
- {
- *--t = hexDigits [v & 15];
- v >>= 4;
-
- } while (v != 0);
-
- return String (t, (int) (((char*) end) - (char*) t) - 1);
- }
-
- const String String::toHexString (const int64 number) throw()
- {
- tchar buffer[32];
- tchar* const end = buffer + 32;
- tchar* t = end;
- *--t = 0;
- uint64 v = (uint64) number;
-
- do
- {
- *--t = hexDigits [(int) (v & 15)];
- v >>= 4;
-
- } while (v != 0);
-
- return String (t, (int) (((char*) end) - (char*) t));
- }
-
- const String String::toHexString (const short number) throw()
- {
- return toHexString ((int) (unsigned short) number);
- }
-
- const String String::toHexString (const unsigned char* data,
- const int size,
- const int groupSize) throw()
- {
- if (size <= 0)
- return empty;
-
- int numChars = (size * 2) + 2;
- if (groupSize > 0)
- numChars += size / groupSize;
-
- String s (numChars, (int) 0);
-
- tchar* d = s.text->text;
-
- for (int i = 0; i < size; ++i)
- {
- *d++ = hexDigits [(*data) >> 4];
- *d++ = hexDigits [(*data) & 0xf];
- ++data;
-
- if (groupSize > 0 && (i % groupSize) == 0)
- *d++ = T(' ');
- }
-
- if (groupSize > 0)
- --d;
-
- *d = 0;
-
- return s;
- }
-
- int String::getHexValue32() const throw()
- {
- int result = 0;
- const tchar* c = text->text;
-
- for (;;)
- {
- const int hexValue = CharacterFunctions::getHexDigitValue (*c);
-
- if (hexValue >= 0)
- result = (result << 4) | hexValue;
- else if (*c == 0)
- break;
-
- ++c;
- }
-
- return result;
- }
-
- int64 String::getHexValue64() const throw()
- {
- int64 result = 0;
- const tchar* c = text->text;
-
- for (;;)
- {
- const int hexValue = CharacterFunctions::getHexDigitValue (*c);
-
- if (hexValue >= 0)
- result = (result << 4) | hexValue;
- else if (*c == 0)
- break;
-
- ++c;
- }
-
- return result;
- }
-
- const String String::createStringFromData (const void* const data_,
- const int size) throw()
- {
- const char* const data = (const char*) data_;
-
- if (size <= 0 || data == 0)
- {
- return empty;
- }
- else if (size < 2)
- {
- return charToString (data[0]);
- }
- else if ((data[0] == (char)-2 && data[1] == (char)-1)
- || (data[0] == (char)-1 && data[1] == (char)-2))
- {
- // assume it's 16-bit unicode
- const bool bigEndian = (data[0] == (char)-2);
- const int numChars = size / 2 - 1;
-
- String result;
- result.preallocateStorage (numChars + 2);
-
- const uint16* const src = (const uint16*) (data + 2);
- tchar* const dst = const_cast <tchar*> ((const tchar*) result);
-
- if (bigEndian)
- {
- for (int i = 0; i < numChars; ++i)
- dst[i] = (tchar) swapIfLittleEndian (src[i]);
- }
- else
- {
- for (int i = 0; i < numChars; ++i)
- dst[i] = (tchar) swapIfBigEndian (src[i]);
- }
-
- dst [numChars] = 0;
- return result;
- }
- else
- {
- #if JUCE_STRINGS_ARE_UNICODE && JUCE_LINUX
- // (workaround for strange behaviour of mbstowcs)
- int i;
- for (i = 0; i < size; ++i)
- if (data[i] == 0)
- break;
-
- String result;
- result.preallocateStorage (i + 1);
- tchar* const dst = const_cast <tchar*> ((const tchar*) result);
-
- for (int j = 0; j < i; ++j)
- dst[j] = (juce_wchar) (unsigned char) data[j];
-
- dst[i] = 0;
-
- return result;
- #else
- return String (data, size);
- #endif
- }
- }
-
- const char* String::toUTF8() const throw()
- {
- if (isEmpty())
- {
- return (const char*) emptyCharString;
- }
- else
- {
- String* const mutableThis = const_cast <String*> (this);
-
- mutableThis->dupeInternalIfMultiplyReferenced();
-
- const int currentLen = CharacterFunctions::length (text->text) + 1;
- const int utf8BytesNeeded = copyToUTF8 (0);
-
- mutableThis->text = (InternalRefCountedStringHolder*)
- juce_realloc (text, sizeof (InternalRefCountedStringHolder)
- + (currentLen * sizeof (juce_wchar) + utf8BytesNeeded));
-
- char* const otherCopy = (char*) (text->text + currentLen);
- copyToUTF8 ((uint8*) otherCopy);
-
- return otherCopy;
- }
- }
-
- int String::copyToUTF8 (uint8* const buffer) const throw()
- {
- #if JUCE_STRINGS_ARE_UNICODE
- int num = 0, index = 0;
-
- for (;;)
- {
- const uint32 c = (uint32) text->text [index++];
-
- if (c >= 0x80)
- {
- int numExtraBytes = 1;
-
- if (c >= 0x800)
- {
- ++numExtraBytes;
-
- if (c >= 0x10000)
- {
- ++numExtraBytes;
-
- if (c >= 0x200000)
- {
- ++numExtraBytes;
-
- if (c >= 0x4000000)
- ++numExtraBytes;
- }
- }
- }
-
- if (buffer != 0)
- {
- buffer [num++] = (uint8) ((0xff << (7 - numExtraBytes)) | (c >> (numExtraBytes * 6)));
-
- while (--numExtraBytes >= 0)
- buffer [num++] = (uint8) (0x80 | (0x3f & (c >> (numExtraBytes * 6))));
- }
- else
- {
- num += numExtraBytes + 1;
- }
- }
- else
- {
- if (buffer != 0)
- buffer [num] = (uint8) c;
-
- ++num;
- }
-
- if (c == 0)
- break;
- }
-
- return num;
-
- #else
- const int numBytes = length() + 1;
-
- if (buffer != 0)
- copyToBuffer ((char*) buffer, numBytes);
-
- return numBytes;
- #endif
- }
-
- const String String::fromUTF8 (const uint8* const buffer, int bufferSizeBytes) throw()
- {
- if (buffer == 0)
- return empty;
-
- if (bufferSizeBytes < 0)
- bufferSizeBytes = INT_MAX;
-
- int numBytes;
- for (numBytes = 0; numBytes < bufferSizeBytes; ++numBytes)
- if (buffer [numBytes] == 0)
- break;
-
- String result (numBytes + 1, 0);
- tchar* dest = result.text->text;
-
- int i = 0;
- while (i < numBytes)
- {
- const uint8 c = buffer [i++];
-
- if ((c & 0x80) != 0)
- {
- int mask = 0x7f;
- int bit = 0x40;
- int numExtraValues = 0;
-
- while (bit != 0 && (c & bit) != 0)
- {
- bit >>= 1;
- mask >>= 1;
- ++numExtraValues;
- }
-
- int n = (c & mask);
-
- while (--numExtraValues >= 0 && i < bufferSizeBytes)
- {
- const uint8 c = buffer[i];
-
- if ((c & 0xc0) != 0x80)
- break;
-
- n <<= 6;
- n |= (c & 0x3f);
- ++i;
- }
-
- *dest++ = (tchar) n;
- }
- else
- {
- *dest++ = (tchar) c;
- }
- }
-
- *dest = 0;
- return result;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_String.cpp *********/
-
- /********* Start of inlined file: juce_StringArray.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- StringArray::StringArray() throw()
- {
- }
-
- StringArray::StringArray (const StringArray& other) throw()
- {
- addArray (other);
- }
-
- StringArray::StringArray (const juce_wchar** const strings,
- const int numberOfStrings) throw()
- {
- for (int i = 0; i < numberOfStrings; ++i)
- add (strings [i]);
- }
-
- StringArray::StringArray (const char** const strings,
- const int numberOfStrings) throw()
- {
- for (int i = 0; i < numberOfStrings; ++i)
- add (strings [i]);
- }
-
- StringArray::StringArray (const juce_wchar** const strings) throw()
- {
- int i = 0;
-
- while (strings[i] != 0)
- add (strings [i++]);
- }
-
- StringArray::StringArray (const char** const strings) throw()
- {
- int i = 0;
-
- while (strings[i] != 0)
- add (strings [i++]);
- }
-
- const StringArray& StringArray::operator= (const StringArray& other) throw()
- {
- if (this != &other)
- {
- clear();
- addArray (other);
- }
-
- return *this;
- }
-
- StringArray::~StringArray() throw()
- {
- clear();
- }
-
- bool StringArray::operator== (const StringArray& other) const throw()
- {
- if (other.size() != size())
- return false;
-
- for (int i = size(); --i >= 0;)
- {
- if (*(String*) other.strings.getUnchecked(i)
- != *(String*) strings.getUnchecked(i))
- {
- return false;
- }
- }
-
- return true;
- }
-
- bool StringArray::operator!= (const StringArray& other) const throw()
- {
- return ! operator== (other);
- }
-
- void StringArray::clear() throw()
- {
- for (int i = size(); --i >= 0;)
- {
- String* const s = (String*) strings.getUnchecked(i);
- delete s;
- }
-
- strings.clear();
- }
-
- const String& StringArray::operator[] (const int index) const throw()
- {
- if (((unsigned int) index) < (unsigned int) strings.size())
- return *(const String*) (strings.getUnchecked (index));
-
- return String::empty;
- }
-
- void StringArray::add (const String& newString) throw()
- {
- strings.add (new String (newString));
- }
-
- void StringArray::insert (const int index,
- const String& newString) throw()
- {
- strings.insert (index, new String (newString));
- }
-
- void StringArray::addIfNotAlreadyThere (const String& newString,
- const bool ignoreCase) throw()
- {
- if (! contains (newString, ignoreCase))
- add (newString);
- }
-
- void StringArray::addArray (const StringArray& otherArray,
- int startIndex,
- int numElementsToAdd) throw()
- {
- if (startIndex < 0)
- {
- jassertfalse
- startIndex = 0;
- }
-
- if (numElementsToAdd < 0 || startIndex + numElementsToAdd > otherArray.size())
- numElementsToAdd = otherArray.size() - startIndex;
-
- while (--numElementsToAdd >= 0)
- strings.add (new String (*(const String*) otherArray.strings.getUnchecked (startIndex++)));
- }
-
- void StringArray::set (const int index,
- const String& newString) throw()
- {
- String* const s = (String*) strings [index];
-
- if (s != 0)
- {
- *s = newString;
- }
- else if (index >= 0)
- {
- add (newString);
- }
- }
-
- bool StringArray::contains (const String& stringToLookFor,
- const bool ignoreCase) const throw()
- {
- if (ignoreCase)
- {
- for (int i = size(); --i >= 0;)
- if (stringToLookFor.equalsIgnoreCase (*(const String*)(strings.getUnchecked(i))))
- return true;
- }
- else
- {
- for (int i = size(); --i >= 0;)
- if (stringToLookFor == *(const String*)(strings.getUnchecked(i)))
- return true;
- }
-
- return false;
- }
-
- int StringArray::indexOf (const String& stringToLookFor,
- const bool ignoreCase,
- int i) const throw()
- {
- if (i < 0)
- i = 0;
-
- const int numElements = size();
-
- if (ignoreCase)
- {
- while (i < numElements)
- {
- if (stringToLookFor.equalsIgnoreCase (*(const String*) strings.getUnchecked (i)))
- return i;
-
- ++i;
- }
- }
- else
- {
- while (i < numElements)
- {
- if (stringToLookFor == *(const String*) strings.getUnchecked (i))
- return i;
-
- ++i;
- }
- }
-
- return -1;
- }
-
- void StringArray::remove (const int index) throw()
- {
- String* const s = (String*) strings [index];
-
- if (s != 0)
- {
- strings.remove (index);
- delete s;
- }
- }
-
- void StringArray::removeString (const String& stringToRemove,
- const bool ignoreCase) throw()
- {
- if (ignoreCase)
- {
- for (int i = size(); --i >= 0;)
- if (stringToRemove.equalsIgnoreCase (*(const String*) strings.getUnchecked (i)))
- remove (i);
- }
- else
- {
- for (int i = size(); --i >= 0;)
- if (stringToRemove == *(const String*) strings.getUnchecked (i))
- remove (i);
- }
- }
-
- void StringArray::removeEmptyStrings (const bool removeWhitespaceStrings) throw()
- {
- if (removeWhitespaceStrings)
- {
- for (int i = size(); --i >= 0;)
- if (((const String*) strings.getUnchecked(i))->trim().isEmpty())
- remove (i);
- }
- else
- {
- for (int i = size(); --i >= 0;)
- if (((const String*) strings.getUnchecked(i))->isEmpty())
- remove (i);
- }
- }
-
- void StringArray::trim() throw()
- {
- for (int i = size(); --i >= 0;)
- {
- String& s = *(String*) strings.getUnchecked(i);
- s = s.trim();
- }
- }
-
- class InternalStringArrayComparator
- {
- public:
- static int compareElements (void* const first, void* const second) throw()
- {
- return ((const String*) first)->compare (*(const String*) second);
- }
- };
-
- class InsensitiveInternalStringArrayComparator
- {
- public:
- static int compareElements (void* const first, void* const second) throw()
- {
- return ((const String*) first)->compareIgnoreCase (*(const String*) second);
- }
- };
-
- void StringArray::sort (const bool ignoreCase) throw()
- {
- if (ignoreCase)
- {
- InsensitiveInternalStringArrayComparator comp;
- strings.sort (comp);
- }
- else
- {
- InternalStringArrayComparator comp;
- strings.sort (comp);
- }
- }
-
- void StringArray::move (const int currentIndex, int newIndex) throw()
- {
- strings.move (currentIndex, newIndex);
- }
-
- const String StringArray::joinIntoString (const String& separator,
- int start,
- int numberToJoin) const throw()
- {
- const int last = (numberToJoin < 0) ? size()
- : jmin (size(), start + numberToJoin);
-
- if (start < 0)
- start = 0;
-
- if (start >= last)
- return String::empty;
-
- if (start == last - 1)
- return *(const String*) strings.getUnchecked (start);
-
- const int separatorLen = separator.length();
- int charsNeeded = separatorLen * (last - start - 1);
-
- for (int i = start; i < last; ++i)
- charsNeeded += ((const String*) strings.getUnchecked(i))->length();
-
- String result;
- result.preallocateStorage (charsNeeded);
-
- tchar* dest = (tchar*) (const tchar*) result;
-
- while (start < last)
- {
- const String& s = *(const String*) strings.getUnchecked (start);
- const int len = s.length();
-
- if (len > 0)
- {
- s.copyToBuffer (dest, len);
- dest += len;
- }
-
- if (++start < last && separatorLen > 0)
- {
- separator.copyToBuffer (dest, separatorLen);
- dest += separatorLen;
- }
- }
-
- *dest = 0;
-
- return result;
- }
-
- int StringArray::addTokens (const tchar* const text,
- const bool preserveQuotedStrings) throw()
- {
- return addTokens (text,
- T(" \n\r\t"),
- preserveQuotedStrings ? T("\"") : 0);
- }
-
- int StringArray::addTokens (const tchar* const text,
- const tchar* breakCharacters,
- const tchar* quoteCharacters) throw()
- {
- int num = 0;
-
- if (text != 0 && *text != 0)
- {
- if (breakCharacters == 0)
- breakCharacters = T("");
-
- if (quoteCharacters == 0)
- quoteCharacters = T("");
-
- bool insideQuotes = false;
- tchar currentQuoteChar = 0;
-
- int i = 0;
- int tokenStart = 0;
-
- for (;;)
- {
- const tchar c = text[i];
-
- bool isBreak = (c == 0);
-
- if (! (insideQuotes || isBreak))
- {
- const tchar* b = breakCharacters;
- while (*b != 0)
- {
- if (*b++ == c)
- {
- isBreak = true;
- break;
- }
- }
- }
-
- if (! isBreak)
- {
- bool isQuote = false;
- const tchar* q = quoteCharacters;
- while (*q != 0)
- {
- if (*q++ == c)
- {
- isQuote = true;
- break;
- }
- }
-
- if (isQuote)
- {
- if (insideQuotes)
- {
- // only break out of quotes-mode if we find a matching quote to the
- // one that we opened with..
- if (currentQuoteChar == c)
- insideQuotes = false;
- }
- else
- {
- insideQuotes = true;
- currentQuoteChar = c;
- }
- }
- }
- else
- {
- add (String (text + tokenStart, i - tokenStart));
-
- ++num;
- tokenStart = i + 1;
- }
-
- if (c == 0)
- break;
-
- ++i;
- }
- }
-
- return num;
- }
-
- int StringArray::addLines (const tchar* text) throw()
- {
- int numLines = 0;
-
- if (text != 0)
- {
- while (*text != 0)
- {
- const tchar* const startOfLine = text;
-
- while (*text != 0)
- {
- if (*text == T('\r'))
- {
- ++text;
- if (*text == T('\n'))
- ++text;
-
- break;
- }
-
- if (*text == T('\n'))
- {
- ++text;
- break;
- }
-
- ++text;
- }
-
- const tchar* endOfLine = text;
- if (endOfLine > startOfLine && (*(endOfLine - 1) == T('\r') || *(endOfLine - 1) == T('\n')))
- --endOfLine;
-
- if (endOfLine > startOfLine && (*(endOfLine - 1) == T('\r') || *(endOfLine - 1) == T('\n')))
- --endOfLine;
-
- add (String (startOfLine, jmax (0, (int) (endOfLine - startOfLine))));
-
- ++numLines;
- }
- }
-
- return numLines;
- }
-
- void StringArray::removeDuplicates (const bool ignoreCase) throw()
- {
- for (int i = 0; i < size() - 1; ++i)
- {
- const String& s = *(String*) strings.getUnchecked(i);
-
- int nextIndex = i + 1;
-
- for (;;)
- {
- nextIndex = indexOf (s, ignoreCase, nextIndex);
-
- if (nextIndex < 0)
- break;
-
- remove (nextIndex);
- }
- }
- }
-
- void StringArray::appendNumbersToDuplicates (const bool ignoreCase,
- const bool appendNumberToFirstInstance,
- const tchar* const preNumberString,
- const tchar* const postNumberString) throw()
- {
- for (int i = 0; i < size() - 1; ++i)
- {
- String& s = *(String*) strings.getUnchecked(i);
-
- int nextIndex = indexOf (s, ignoreCase, i + 1);
-
- if (nextIndex >= 0)
- {
- const String original (s);
-
- int number = 0;
-
- if (appendNumberToFirstInstance)
- s = original + preNumberString + String (++number) + postNumberString;
- else
- ++number;
-
- while (nextIndex >= 0)
- {
- set (nextIndex, (*this)[nextIndex] + preNumberString + String (++number) + postNumberString);
- nextIndex = indexOf (original, ignoreCase, nextIndex + 1);
- }
- }
- }
- }
-
- void StringArray::minimiseStorageOverheads() throw()
- {
- strings.minimiseStorageOverheads();
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_StringArray.cpp *********/
-
- /********* Start of inlined file: juce_StringPairArray.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- StringPairArray::StringPairArray (const bool ignoreCase_) throw()
- : ignoreCase (ignoreCase_)
- {
- }
-
- StringPairArray::StringPairArray (const StringPairArray& other) throw()
- : keys (other.keys),
- values (other.values),
- ignoreCase (other.ignoreCase)
- {
- }
-
- StringPairArray::~StringPairArray() throw()
- {
- }
-
- const StringPairArray& StringPairArray::operator= (const StringPairArray& other) throw()
- {
- keys = other.keys;
- values = other.values;
-
- return *this;
- }
-
- bool StringPairArray::operator== (const StringPairArray& other) const throw()
- {
- for (int i = keys.size(); --i >= 0;)
- if (other [keys[i]] != values[i])
- return false;
-
- return true;
- }
-
- bool StringPairArray::operator!= (const StringPairArray& other) const throw()
- {
- return ! operator== (other);
- }
-
- const String& StringPairArray::operator[] (const String& key) const throw()
- {
- return values [keys.indexOf (key, ignoreCase)];
- }
-
- const String StringPairArray::getValue (const String& key, const String& defaultReturnValue) const
- {
- const int i = keys.indexOf (key, ignoreCase);
-
- if (i >= 0)
- return values[i];
-
- return defaultReturnValue;
- }
-
- void StringPairArray::set (const String& key,
- const String& value) throw()
- {
- const int i = keys.indexOf (key, ignoreCase);
-
- if (i >= 0)
- {
- values.set (i, value);
- }
- else
- {
- keys.add (key);
- values.add (value);
- }
- }
-
- void StringPairArray::addArray (const StringPairArray& other)
- {
- for (int i = 0; i < other.size(); ++i)
- set (other.keys[i], other.values[i]);
- }
-
- void StringPairArray::clear() throw()
- {
- keys.clear();
- values.clear();
- }
-
- void StringPairArray::remove (const String& key) throw()
- {
- remove (keys.indexOf (key, ignoreCase));
- }
-
- void StringPairArray::remove (const int index) throw()
- {
- keys.remove (index);
- values.remove (index);
- }
-
- void StringPairArray::minimiseStorageOverheads() throw()
- {
- keys.minimiseStorageOverheads();
- values.minimiseStorageOverheads();
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_StringPairArray.cpp *********/
-
- /********* Start of inlined file: juce_XmlDocument.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- static bool isXmlIdentifierChar_Slow (const tchar c) throw()
- {
- return CharacterFunctions::isLetterOrDigit (c)
- || c == T('_')
- || c == T('-')
- || c == T(':')
- || c == T('.');
- }
-
- #define isXmlIdentifierChar(c) \
- ((c > 0 && c <= 127) ? identifierLookupTable [(int) c] : isXmlIdentifierChar_Slow (c))
-
- XmlDocument::XmlDocument (const String& documentText) throw()
- : originalText (documentText),
- inputSource (0)
- {
- }
-
- XmlDocument::XmlDocument (const File& file)
- {
- inputSource = new FileInputSource (file);
- }
-
- XmlDocument::~XmlDocument() throw()
- {
- delete inputSource;
- }
-
- void XmlDocument::setInputSource (InputSource* const newSource) throw()
- {
- if (inputSource != newSource)
- {
- delete inputSource;
- inputSource = newSource;
- }
- }
-
- XmlElement* XmlDocument::getDocumentElement (const bool onlyReadOuterDocumentElement)
- {
- String textToParse (originalText);
-
- if (textToParse.isEmpty() && inputSource != 0)
- {
- InputStream* const in = inputSource->createInputStream();
-
- if (in != 0)
- {
- MemoryBlock data;
-
- in->readIntoMemoryBlock (data, onlyReadOuterDocumentElement ? 8192 : -1);
- delete in;
-
- if (data.getSize() >= 2
- && ((data[0] == (char)-2 && data[1] == (char)-1)
- || (data[0] == (char)-1 && data[1] == (char)-2)))
- {
- textToParse = String::createStringFromData ((const char*) data.getData(), data.getSize());
- }
- else
- {
- textToParse = String::fromUTF8 ((const uint8*) data.getData(), data.getSize());
- }
-
- if (! onlyReadOuterDocumentElement)
- originalText = textToParse;
- }
- }
-
- input = textToParse;
- lastError = String::empty;
- errorOccurred = false;
- outOfData = false;
- needToLoadDTD = true;
-
- for (int i = 0; i < 128; ++i)
- identifierLookupTable[i] = isXmlIdentifierChar_Slow ((tchar) i);
-
- if (textToParse.isEmpty())
- {
- lastError = "not enough input";
- }
- else
- {
- skipHeader();
-
- if (input != 0)
- {
- XmlElement* const result = readNextElement (! onlyReadOuterDocumentElement);
-
- if (errorOccurred)
- delete result;
- else
- return result;
- }
- else
- {
- lastError = "incorrect xml header";
- }
- }
-
- return 0;
- }
-
- const String& XmlDocument::getLastParseError() const throw()
- {
- return lastError;
- }
-
- void XmlDocument::setLastError (const String& desc, const bool carryOn) throw()
- {
- lastError = desc;
- errorOccurred = ! carryOn;
- }
-
- const String XmlDocument::getFileContents (const String& filename) const
- {
- String result;
-
- if (inputSource != 0)
- {
- InputStream* const in = inputSource->createInputStreamFor (filename.trim().unquoted());
-
- if (in != 0)
- {
- result = in->readEntireStreamAsString();
- delete in;
- }
- }
-
- return result;
- }
-
- tchar XmlDocument::readNextChar() throw()
- {
- if (*input != 0)
- {
- return *input++;
- }
- else
- {
- outOfData = true;
- return 0;
- }
- }
-
- int XmlDocument::findNextTokenLength() throw()
- {
- int len = 0;
- tchar c = *input;
-
- while (isXmlIdentifierChar (c))
- c = input [++len];
-
- return len;
- }
-
- void XmlDocument::skipHeader() throw()
- {
- const tchar* const found = CharacterFunctions::find (input, T("<?xml"));
-
- if (found != 0)
- {
- input = found;
- input = CharacterFunctions::find (input, T("?>"));
-
- if (input == 0)
- return;
-
- input += 2;
- }
-
- skipNextWhiteSpace();
- const tchar* docType = CharacterFunctions::find (input, T("<!DOCTYPE"));
-
- if (docType == 0)
- return;
-
- input = docType + 9;
-
- int n = 1;
-
- while (n > 0)
- {
- const tchar c = readNextChar();
-
- if (outOfData)
- return;
-
- if (c == T('<'))
- ++n;
- else if (c == T('>'))
- --n;
- }
-
- docType += 9;
- dtdText = String (docType, (int) (input - (docType + 1))).trim();
- }
-
- void XmlDocument::skipNextWhiteSpace() throw()
- {
- for (;;)
- {
- tchar c = *input;
-
- while (CharacterFunctions::isWhitespace (c))
- c = *++input;
-
- if (c == 0)
- {
- outOfData = true;
- break;
- }
- else if (c == T('<'))
- {
- if (input[1] == T('!')
- && input[2] == T('-')
- && input[3] == T('-'))
- {
- const tchar* const closeComment = CharacterFunctions::find (input, T("-->"));
-
- if (closeComment == 0)
- {
- outOfData = true;
- break;
- }
-
- input = closeComment + 3;
- continue;
- }
- else if (input[1] == T('?'))
- {
- const tchar* const closeBracket = CharacterFunctions::find (input, T("?>"));
-
- if (closeBracket == 0)
- {
- outOfData = true;
- break;
- }
-
- input = closeBracket + 2;
- continue;
- }
- }
-
- break;
- }
- }
-
- void XmlDocument::readQuotedString (String& result) throw()
- {
- const tchar quote = readNextChar();
-
- while (! outOfData)
- {
- const tchar character = readNextChar();
-
- if (character == quote)
- break;
-
- if (character == T('&'))
- {
- --input;
- readEntity (result);
- }
- else
- {
- --input;
- const tchar* const start = input;
-
- for (;;)
- {
- const tchar character = *input;
-
- if (character == quote)
- {
- result.append (start, (int) (input - start));
- ++input;
-
- return;
- }
- else if (character == T('&'))
- {
- result.append (start, (int) (input - start));
- break;
- }
- else if (character == 0)
- {
- outOfData = true;
- setLastError ("unmatched quotes", false);
- break;
- }
-
- ++input;
- }
- }
- }
- }
-
- XmlElement* XmlDocument::readNextElement (const bool alsoParseSubElements) throw()
- {
- XmlElement* node = 0;
-
- skipNextWhiteSpace();
- if (outOfData)
- return 0;
-
- input = CharacterFunctions::find (input, T("<"));
-
- if (input != 0)
- {
- ++input;
- int tagLen = findNextTokenLength();
-
- if (tagLen == 0)
- {
- // no tag name - but allow for a gap after the '<' before giving an error
- skipNextWhiteSpace();
- tagLen = findNextTokenLength();
-
- if (tagLen == 0)
- {
- setLastError ("tag name missing", false);
- return node;
- }
- }
-
- node = new XmlElement (input, tagLen);
- input += tagLen;
- XmlElement::XmlAttributeNode* lastAttribute = 0;
-
- // look for attributes
- for (;;)
- {
- skipNextWhiteSpace();
-
- const tchar c = *input;
-
- // empty tag..
- if (c == T('/') && input[1] == T('>'))
- {
- input += 2;
- break;
- }
-
- // parse the guts of the element..
- if (c == T('>'))
- {
- ++input;
- skipNextWhiteSpace();
-
- if (alsoParseSubElements)
- readChildElements (node);
-
- break;
- }
-
- // get an attribute..
- if (isXmlIdentifierChar (c))
- {
- const int attNameLen = findNextTokenLength();
-
- if (attNameLen > 0)
- {
- const tchar* attNameStart = input;
- input += attNameLen;
-
- skipNextWhiteSpace();
-
- if (readNextChar() == T('='))
- {
- skipNextWhiteSpace();
-
- const tchar c = *input;
-
- if (c == T('"') || c == T('\''))
- {
- XmlElement::XmlAttributeNode* const newAtt
- = new XmlElement::XmlAttributeNode (String (attNameStart, attNameLen),
- String::empty);
-
- readQuotedString (newAtt->value);
-
- if (lastAttribute == 0)
- node->attributes = newAtt;
- else
- lastAttribute->next = newAtt;
-
- lastAttribute = newAtt;
-
- continue;
- }
- }
- }
- }
- else
- {
- if (! outOfData)
- setLastError ("illegal character found in " + node->getTagName() + ": '" + c + "'", false);
- }
-
- break;
- }
- }
-
- return node;
- }
-
- void XmlDocument::readChildElements (XmlElement* parent) throw()
- {
- XmlElement* lastChildNode = 0;
-
- for (;;)
- {
- skipNextWhiteSpace();
-
- if (outOfData)
- {
- setLastError ("unmatched tags", false);
- break;
- }
-
- if (*input == T('<'))
- {
- if (input[1] == T('/'))
- {
- // our close tag..
- input = CharacterFunctions::find (input, T(">"));
- ++input;
- break;
- }
- else if (input[1] == T('!')
- && input[2] == T('[')
- && input[3] == T('C')
- && input[4] == T('D')
- && input[5] == T('A')
- && input[6] == T('T')
- && input[7] == T('A')
- && input[8] == T('['))
- {
- input += 9;
- const tchar* const inputStart = input;
-
- int len = 0;
-
- for (;;)
- {
- if (*input == 0)
- {
- setLastError ("unterminated CDATA section", false);
- outOfData = true;
- break;
- }
- else if (input[0] == T(']')
- && input[1] == T(']')
- && input[2] == T('>'))
- {
- input += 3;
- break;
- }
-
- ++input;
- ++len;
- }
-
- XmlElement* const e = new XmlElement ((int) 0);
- e->setText (String (inputStart, len));
-
- if (lastChildNode != 0)
- lastChildNode->nextElement = e;
- else
- parent->addChildElement (e);
-
- lastChildNode = e;
- }
- else
- {
- // this is some other element, so parse and add it..
- XmlElement* const n = readNextElement (true);
-
- if (n != 0)
- {
- if (lastChildNode == 0)
- parent->addChildElement (n);
- else
- lastChildNode->nextElement = n;
-
- lastChildNode = n;
- }
- else
- {
- return;
- }
- }
- }
- else
- {
- // read character block..
- XmlElement* const e = new XmlElement ((int)0);
-
- if (lastChildNode != 0)
- lastChildNode->nextElement = e;
- else
- parent->addChildElement (e);
-
- lastChildNode = e;
-
- String textElementContent;
-
- for (;;)
- {
- const tchar c = *input;
-
- if (c == T('<'))
- break;
-
- if (c == 0)
- {
- setLastError ("unmatched tags", false);
- outOfData = true;
- return;
- }
-
- if (c == T('&'))
- {
- String entity;
- readEntity (entity);
-
- if (entity.startsWithChar (T('<')) && entity [1] != 0)
- {
- const tchar* const oldInput = input;
- const bool oldOutOfData = outOfData;
-
- input = (const tchar*) entity;
- outOfData = false;
-
- for (;;)
- {
- XmlElement* const n = readNextElement (true);
-
- if (n == 0)
- break;
-
- if (lastChildNode == 0)
- parent->addChildElement (n);
- else
- lastChildNode->nextElement = n;
-
- lastChildNode = n;
- }
-
- input = oldInput;
- outOfData = oldOutOfData;
- }
- else
- {
- textElementContent += entity;
- }
- }
- else
- {
- const tchar* start = input;
- int len = 0;
-
- for (;;)
- {
- const tchar c = *input;
-
- if (c == T('<') || c == T('&'))
- {
- break;
- }
- else if (c == 0)
- {
- setLastError ("unmatched tags", false);
- outOfData = true;
- return;
- }
-
- ++input;
- ++len;
- }
-
- textElementContent.append (start, len);
- }
- }
-
- textElementContent = textElementContent.trim();
-
- if (textElementContent.isNotEmpty())
- e->setText (textElementContent);
- }
- }
- }
-
- void XmlDocument::readEntity (String& result) throw()
- {
- // skip over the ampersand
- ++input;
-
- if (CharacterFunctions::compareIgnoreCase (input, T("amp;"), 4) == 0)
- {
- input += 4;
- result += T("&");
- }
- else if (CharacterFunctions::compareIgnoreCase (input, T("quot;"), 5) == 0)
- {
- input += 5;
- result += T("\"");
- }
- else if (CharacterFunctions::compareIgnoreCase (input, T("apos;"), 5) == 0)
- {
- input += 5;
- result += T("\'");
- }
- else if (CharacterFunctions::compareIgnoreCase (input, T("lt;"), 3) == 0)
- {
- input += 3;
- result += T("<");
- }
- else if (CharacterFunctions::compareIgnoreCase (input, T("gt;"), 3) == 0)
- {
- input += 3;
- result += T(">");
- }
- else if (*input == T('#'))
- {
- int charCode = 0;
- ++input;
-
- if (*input == T('x') || *input == T('X'))
- {
- ++input;
- int numChars = 0;
-
- while (input[0] != T(';'))
- {
- const int hexValue = CharacterFunctions::getHexDigitValue (input[0]);
-
- if (hexValue < 0 || ++numChars > 8)
- {
- setLastError ("illegal escape sequence", true);
- break;
- }
-
- charCode = (charCode << 4) | hexValue;
- ++input;
- }
-
- ++input;
- }
- else if (input[0] >= T('0') && input[0] <= T('9'))
- {
- int numChars = 0;
-
- while (input[0] != T(';'))
- {
- if (++numChars > 12)
- {
- setLastError ("illegal escape sequence", true);
- break;
- }
-
- charCode = charCode * 10 + (input[0] - T('0'));
- ++input;
- }
-
- ++input;
- }
- else
- {
- setLastError ("illegal escape sequence", true);
- result += T("&");
- return;
- }
-
- result << (tchar) charCode;
- }
- else
- {
- const tchar* const entityNameStart = input;
- const tchar* const closingSemiColon = CharacterFunctions::find (input, T(";"));
-
- if (closingSemiColon == 0)
- {
- outOfData = true;
- result += T("&");
- }
- else
- {
- input = closingSemiColon + 1;
-
- result += expandExternalEntity (String (entityNameStart,
- (int) (closingSemiColon - entityNameStart)));
- }
- }
- }
-
- const String XmlDocument::expandEntity (const String& ent)
- {
- if (ent.equalsIgnoreCase (T("amp")))
- {
- return T("&");
- }
- else if (ent.equalsIgnoreCase (T("quot")))
- {
- return T("\"");
- }
- else if (ent.equalsIgnoreCase (T("apos")))
- {
- return T("\'");
- }
- else if (ent.equalsIgnoreCase (T("lt")))
- {
- return T("<");
- }
- else if (ent.equalsIgnoreCase (T("gt")))
- {
- return T(">");
- }
- else if (ent[0] == T('#'))
- {
- if (ent[1] == T('x') || ent[1] == T('X'))
- {
- return String::charToString ((tchar) ent.substring (2).getHexValue32());
- }
- else if (ent[1] >= T('0') && ent[1] <= T('9'))
- {
- return String::charToString ((tchar) ent.substring (1).getIntValue());
- }
-
- setLastError ("illegal escape sequence", false);
- return T("&");
- }
- else
- {
- return expandExternalEntity (ent);
- }
- }
-
- const String XmlDocument::expandExternalEntity (const String& entity)
- {
- if (needToLoadDTD)
- {
- if (dtdText.isNotEmpty())
- {
- while (dtdText.endsWithChar (T('>')))
- dtdText = dtdText.dropLastCharacters (1);
-
- tokenisedDTD.addTokens (dtdText, true);
-
- if (tokenisedDTD [tokenisedDTD.size() - 2].equalsIgnoreCase (T("system"))
- && tokenisedDTD [tokenisedDTD.size() - 1].isQuotedString())
- {
- const String fn (tokenisedDTD [tokenisedDTD.size() - 1]);
-
- tokenisedDTD.clear();
- tokenisedDTD.addTokens (getFileContents (fn), true);
- }
- else
- {
- tokenisedDTD.clear();
- const int openBracket = dtdText.indexOfChar (T('['));
-
- if (openBracket > 0)
- {
- const int closeBracket = dtdText.lastIndexOfChar (T(']'));
-
- if (closeBracket > openBracket)
- tokenisedDTD.addTokens (dtdText.substring (openBracket + 1,
- closeBracket), true);
- }
- }
-
- for (int i = tokenisedDTD.size(); --i >= 0;)
- {
- if (tokenisedDTD[i].startsWithChar (T('%'))
- && tokenisedDTD[i].endsWithChar (T(';')))
- {
- const String parsed (getParameterEntity (tokenisedDTD[i].substring (1, tokenisedDTD[i].length() - 1)));
- StringArray newToks;
- newToks.addTokens (parsed, true);
-
- tokenisedDTD.remove (i);
-
- for (int j = newToks.size(); --j >= 0;)
- tokenisedDTD.insert (i, newToks[j]);
- }
- }
- }
-
- needToLoadDTD = false;
- }
-
- for (int i = 0; i < tokenisedDTD.size(); ++i)
- {
- if (tokenisedDTD[i] == entity)
- {
- if (tokenisedDTD[i - 1].equalsIgnoreCase (T("<!entity")))
- {
- String ent (tokenisedDTD [i + 1]);
-
- while (ent.endsWithChar (T('>')))
- ent = ent.dropLastCharacters (1);
-
- ent = ent.trim().unquoted();
-
- // check for sub-entities..
- int ampersand = ent.indexOfChar (T('&'));
-
- while (ampersand >= 0)
- {
- const int semiColon = ent.indexOf (i + 1, T(";"));
-
- if (semiColon < 0)
- {
- setLastError ("entity without terminating semi-colon", false);
- break;
- }
-
- const String resolved (expandEntity (ent.substring (i + 1, semiColon)));
-
- ent = ent.substring (0, ampersand)
- + resolved
- + ent.substring (semiColon + 1);
-
- ampersand = ent.indexOfChar (semiColon + 1, T('&'));
- }
-
- return ent;
- }
- }
- }
-
- setLastError ("unknown entity", true);
-
- return entity;
- }
-
- const String XmlDocument::getParameterEntity (const String& entity)
- {
- for (int i = 0; i < tokenisedDTD.size(); ++i)
- {
- if (tokenisedDTD[i] == entity)
- {
- if (tokenisedDTD [i - 1] == T("%")
- && tokenisedDTD [i - 2].equalsIgnoreCase (T("<!entity")))
- {
- String ent (tokenisedDTD [i + 1]);
-
- while (ent.endsWithChar (T('>')))
- ent = ent.dropLastCharacters (1);
-
- if (ent.equalsIgnoreCase (T("system")))
- {
- String filename (tokenisedDTD [i + 2]);
-
- while (filename.endsWithChar (T('>')))
- filename = filename.dropLastCharacters (1);
-
- return getFileContents (filename);
- }
- else
- {
- return ent.trim().unquoted();
- }
- }
- }
- }
-
- return entity;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_XmlDocument.cpp *********/
-
- /********* Start of inlined file: juce_XmlElement.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- XmlElement::XmlAttributeNode::XmlAttributeNode (const XmlAttributeNode& other) throw()
- : name (other.name),
- value (other.value),
- next (0)
- {
- }
-
- XmlElement::XmlAttributeNode::XmlAttributeNode (const String& name_,
- const String& value_) throw()
- : name (name_),
- value (value_),
- next (0)
- {
- }
-
- XmlElement::XmlElement (const String& tagName_) throw()
- : tagName (tagName_),
- firstChildElement (0),
- nextElement (0),
- attributes (0)
- {
- // the tag name mustn't be empty, or it'll look like a text element!
- jassert (tagName_.trim().isNotEmpty())
- }
-
- XmlElement::XmlElement (int /*dummy*/) throw()
- : firstChildElement (0),
- nextElement (0),
- attributes (0)
- {
- }
-
- XmlElement::XmlElement (const tchar* const tagName_,
- const int nameLen) throw()
- : tagName (tagName_, nameLen),
- firstChildElement (0),
- nextElement (0),
- attributes (0)
- {
- }
-
- XmlElement::XmlElement (const XmlElement& other) throw()
- : tagName (other.tagName),
- firstChildElement (0),
- nextElement (0),
- attributes (0)
- {
- copyChildrenAndAttributesFrom (other);
- }
-
- const XmlElement& XmlElement::operator= (const XmlElement& other) throw()
- {
- if (this != &other)
- {
- removeAllAttributes();
- deleteAllChildElements();
-
- tagName = other.tagName;
-
- copyChildrenAndAttributesFrom (other);
- }
-
- return *this;
- }
-
- void XmlElement::copyChildrenAndAttributesFrom (const XmlElement& other) throw()
- {
- XmlElement* child = other.firstChildElement;
- XmlElement* lastChild = 0;
-
- while (child != 0)
- {
- XmlElement* const copiedChild = new XmlElement (*child);
-
- if (lastChild != 0)
- lastChild->nextElement = copiedChild;
- else
- firstChildElement = copiedChild;
-
- lastChild = copiedChild;
- child = child->nextElement;
- }
-
- const XmlAttributeNode* att = other.attributes;
- XmlAttributeNode* lastAtt = 0;
-
- while (att != 0)
- {
- XmlAttributeNode* const newAtt = new XmlAttributeNode (*att);
-
- if (lastAtt != 0)
- lastAtt->next = newAtt;
- else
- attributes = newAtt;
-
- lastAtt = newAtt;
- att = att->next;
- }
- }
-
- XmlElement::~XmlElement() throw()
- {
- XmlElement* child = firstChildElement;
-
- while (child != 0)
- {
- XmlElement* const nextChild = child->nextElement;
- delete child;
- child = nextChild;
- }
-
- XmlAttributeNode* att = attributes;
-
- while (att != 0)
- {
- XmlAttributeNode* const nextAtt = att->next;
- delete att;
- att = nextAtt;
- }
- }
-
- static bool isLegalXmlChar (const juce_wchar character)
- {
- if ((character >= 'a' && character <= 'z')
- || (character >= 'A' && character <= 'Z')
- || (character >= '0' && character <= '9'))
- return true;
-
- const char* t = " .,;:-()_+=?!'#@[]/\\*%~{}";
-
- do
- {
- if (((juce_wchar) (uint8) *t) == character)
- return true;
- }
- while (*++t != 0);
-
- return false;
- }
-
- static void escapeIllegalXmlChars (OutputStream& outputStream,
- const String& text,
- const bool changeNewLines) throw()
- {
- const juce_wchar* t = (const juce_wchar*) text;
-
- for (;;)
- {
- const juce_wchar character = *t++;
-
- if (character == 0)
- {
- break;
- }
- else if (isLegalXmlChar (character))
- {
- outputStream.writeByte ((char) character);
- }
- else
- {
- switch (character)
- {
- case '&':
- outputStream.write ("&", 5);
- break;
-
- case '"':
- outputStream.write (""", 6);
- break;
-
- case '>':
- outputStream.write (">", 4);
- break;
-
- case '<':
- outputStream.write ("<", 4);
- break;
-
- case '\n':
- if (changeNewLines)
- outputStream.write (" ", 5);
- else
- outputStream.writeByte ((char) character);
-
- break;
-
- case '\r':
- if (changeNewLines)
- outputStream.write (" ", 5);
- else
- outputStream.writeByte ((char) character);
-
- break;
-
- default:
- {
- String encoded (T("&#"));
- encoded << String ((int) (unsigned int) character).trim()
- << T(';');
-
- outputStream.write ((const char*) encoded, encoded.length());
- }
- }
- }
- }
- }
-
- static void writeSpaces (OutputStream& out, int numSpaces) throw()
- {
- if (numSpaces > 0)
- {
- const char* const blanks = " ";
- const int blankSize = (int) sizeof (blanks) - 1;
-
- while (numSpaces > blankSize)
- {
- out.write (blanks, blankSize);
- numSpaces -= blankSize;
- }
-
- out.write (blanks, numSpaces);
- }
- }
-
- void XmlElement::writeElementAsText (OutputStream& outputStream,
- const int indentationLevel) const throw()
- {
- writeSpaces (outputStream, indentationLevel);
-
- if (! isTextElement())
- {
- outputStream.writeByte ('<');
- const int nameLen = tagName.length();
- outputStream.write ((const char*) tagName, nameLen);
-
- const int attIndent = indentationLevel + nameLen + 1;
- int lineLen = 0;
-
- const XmlAttributeNode* att = attributes;
- while (att != 0)
- {
- if (lineLen > 60 && indentationLevel >= 0)
- {
- outputStream.write ("\r\n", 2);
- writeSpaces (outputStream, attIndent);
- lineLen = 0;
- }
-
- const int attNameLen = att->name.length();
- outputStream.writeByte (' ');
- outputStream.write ((const char*) (att->name), attNameLen);
- outputStream.write ("=\"", 2);
- escapeIllegalXmlChars (outputStream, att->value, true);
- outputStream.writeByte ('"');
- lineLen += 4 + attNameLen + att->value.length();
-
- att = att->next;
- }
-
- if (firstChildElement != 0)
- {
- XmlElement* child = firstChildElement;
-
- if (child->nextElement == 0 && child->isTextElement())
- {
- outputStream.writeByte ('>');
- escapeIllegalXmlChars (outputStream, child->getText(), false);
- }
- else
- {
- if (indentationLevel >= 0)
- outputStream.write (">\r\n", 3);
- else
- outputStream.writeByte ('>');
-
- bool lastWasTextNode = false;
-
- while (child != 0)
- {
- if (child->isTextElement())
- {
- if ((! lastWasTextNode) && (indentationLevel >= 0))
- writeSpaces (outputStream, indentationLevel + 2);
-
- escapeIllegalXmlChars (outputStream, child->getText(), false);
- lastWasTextNode = true;
- }
- else
- {
- if (indentationLevel >= 0)
- {
- if (lastWasTextNode)
- outputStream.write ("\r\n", 2);
-
- child->writeElementAsText (outputStream, indentationLevel + 2);
- }
- else
- {
- child->writeElementAsText (outputStream, indentationLevel);
- }
-
- lastWasTextNode = false;
- }
-
- child = child->nextElement;
- }
-
- if (indentationLevel >= 0)
- {
- if (lastWasTextNode)
- outputStream.write ("\r\n", 2);
-
- writeSpaces (outputStream, indentationLevel);
- }
- }
-
- outputStream.write ("</", 2);
- outputStream.write ((const char*) tagName, nameLen);
-
- if (indentationLevel >= 0)
- outputStream.write (">\r\n", 3);
- else
- outputStream.writeByte ('>');
- }
- else
- {
- if (indentationLevel >= 0)
- outputStream.write ("/>\r\n", 4);
- else
- outputStream.write ("/>", 2);
- }
- }
- else
- {
- if (indentationLevel >= 0)
- writeSpaces (outputStream, indentationLevel + 2);
-
- escapeIllegalXmlChars (outputStream, getText(), false);
- }
- }
-
- const String XmlElement::createDocument (const String& dtd,
- const bool allOnOneLine,
- const bool includeXmlHeader,
- const tchar* const encoding) const throw()
- {
- String doc;
- doc.preallocateStorage (1024);
-
- if (includeXmlHeader)
- {
- doc << "<?xml version=\"1.0\" encoding=\""
- << encoding;
-
- if (allOnOneLine)
- doc += "\"?> ";
- else
- doc += "\"?>\n\n";
- }
-
- if (dtd.isNotEmpty())
- {
- if (allOnOneLine)
- doc << dtd << " ";
- else
- doc << dtd << "\r\n";
- }
-
- MemoryOutputStream mem (2048, 4096);
- writeElementAsText (mem, allOnOneLine ? -1 : 0);
-
- return doc + String (mem.getData(),
- mem.getDataSize());
- }
-
- bool XmlElement::writeToFile (const File& f,
- const String& dtd,
- const tchar* const encoding) const throw()
- {
- if (f.hasWriteAccess())
- {
- const File tempFile (f.getNonexistentSibling());
-
- FileOutputStream* const out = tempFile.createOutputStream();
-
- if (out != 0)
- {
- *out << "<?xml version=\"1.0\" encoding=\"" << encoding << "\"?>\r\n\r\n"
- << dtd << "\r\n";
-
- writeElementAsText (*out, 0);
-
- delete out;
-
- if (tempFile.moveFileTo (f))
- return true;
-
- tempFile.deleteFile();
- }
- }
-
- return false;
- }
-
- bool XmlElement::hasTagName (const tchar* const tagNameWanted) const throw()
- {
- #ifdef JUCE_DEBUG
- // if debugging, check that the case is actually the same, because
- // valid xml is case-sensitive, and although this lets it pass, it's
- // better not to..
- if (tagName.equalsIgnoreCase (tagNameWanted))
- {
- jassert (tagName == tagNameWanted);
- return true;
- }
- else
- {
- return false;
- }
- #else
- return tagName.equalsIgnoreCase (tagNameWanted);
- #endif
- }
-
- XmlElement* XmlElement::getNextElementWithTagName (const tchar* const requiredTagName) const
- {
- XmlElement* e = nextElement;
-
- while (e != 0 && ! e->hasTagName (requiredTagName))
- e = e->nextElement;
-
- return e;
- }
-
- int XmlElement::getNumAttributes() const throw()
- {
- const XmlAttributeNode* att = attributes;
- int count = 0;
-
- while (att != 0)
- {
- att = att->next;
- ++count;
- }
-
- return count;
- }
-
- const String& XmlElement::getAttributeName (const int index) const throw()
- {
- const XmlAttributeNode* att = attributes;
- int count = 0;
-
- while (att != 0)
- {
- if (count == index)
- return att->name;
-
- att = att->next;
- ++count;
- }
-
- return String::empty;
- }
-
- const String& XmlElement::getAttributeValue (const int index) const throw()
- {
- const XmlAttributeNode* att = attributes;
- int count = 0;
-
- while (att != 0)
- {
- if (count == index)
- return att->value;
-
- att = att->next;
- ++count;
- }
-
- return String::empty;
- }
-
- bool XmlElement::hasAttribute (const tchar* const attributeName) const throw()
- {
- const XmlAttributeNode* att = attributes;
-
- while (att != 0)
- {
- if (att->name.equalsIgnoreCase (attributeName))
- return true;
-
- att = att->next;
- }
-
- return false;
- }
-
- const String XmlElement::getStringAttribute (const tchar* const attributeName,
- const tchar* const defaultReturnValue) const throw()
- {
- const XmlAttributeNode* att = attributes;
-
- while (att != 0)
- {
- if (att->name.equalsIgnoreCase (attributeName))
- return att->value;
-
- att = att->next;
- }
-
- return defaultReturnValue;
- }
-
- int XmlElement::getIntAttribute (const tchar* const attributeName,
- const int defaultReturnValue) const throw()
- {
- const XmlAttributeNode* att = attributes;
-
- while (att != 0)
- {
- if (att->name.equalsIgnoreCase (attributeName))
- return att->value.getIntValue();
-
- att = att->next;
- }
-
- return defaultReturnValue;
- }
-
- double XmlElement::getDoubleAttribute (const tchar* const attributeName,
- const double defaultReturnValue) const throw()
- {
- const XmlAttributeNode* att = attributes;
-
- while (att != 0)
- {
- if (att->name.equalsIgnoreCase (attributeName))
- return att->value.getDoubleValue();
-
- att = att->next;
- }
-
- return defaultReturnValue;
- }
-
- bool XmlElement::getBoolAttribute (const tchar* const attributeName,
- const bool defaultReturnValue) const throw()
- {
- const XmlAttributeNode* att = attributes;
-
- while (att != 0)
- {
- if (att->name.equalsIgnoreCase (attributeName))
- {
- tchar firstChar = att->value[0];
-
- if (CharacterFunctions::isWhitespace (firstChar))
- firstChar = att->value.trimStart() [0];
-
- return firstChar == T('1')
- || firstChar == T('t')
- || firstChar == T('y')
- || firstChar == T('T')
- || firstChar == T('Y');
- }
-
- att = att->next;
- }
-
- return defaultReturnValue;
- }
-
- bool XmlElement::compareAttribute (const tchar* const attributeName,
- const tchar* const stringToCompareAgainst,
- const bool ignoreCase) const throw()
- {
- const XmlAttributeNode* att = attributes;
-
- while (att != 0)
- {
- if (att->name.equalsIgnoreCase (attributeName))
- {
- if (ignoreCase)
- return att->value.equalsIgnoreCase (stringToCompareAgainst);
- else
- return att->value == stringToCompareAgainst;
- }
-
- att = att->next;
- }
-
- return false;
- }
-
- void XmlElement::setAttribute (const tchar* const attributeName,
- const String& value) throw()
- {
- #ifdef JUCE_DEBUG
- // check the identifier being passed in is legal..
- const tchar* t = attributeName;
- while (*t != 0)
- {
- jassert (CharacterFunctions::isLetterOrDigit (*t)
- || *t == T('_')
- || *t == T('-')
- || *t == T(':'));
- ++t;
- }
- #endif
-
- if (attributes == 0)
- {
- attributes = new XmlAttributeNode (attributeName, value);
- }
- else
- {
- XmlAttributeNode* att = attributes;
-
- for (;;)
- {
- if (att->name.equalsIgnoreCase (attributeName))
- {
- att->value = value;
- break;
- }
- else if (att->next == 0)
- {
- att->next = new XmlAttributeNode (attributeName, value);
- break;
- }
-
- att = att->next;
- }
- }
- }
-
- void XmlElement::setAttribute (const tchar* const attributeName,
- const tchar* const text) throw()
- {
- setAttribute (attributeName, String (text));
- }
-
- void XmlElement::setAttribute (const tchar* const attributeName,
- const int number) throw()
- {
- setAttribute (attributeName, String (number));
- }
-
- void XmlElement::setAttribute (const tchar* const attributeName,
- const double number) throw()
- {
- tchar buffer [40];
- CharacterFunctions::printf (buffer, numElementsInArray (buffer), T("%.9g"), number);
-
- setAttribute (attributeName, buffer);
- }
-
- void XmlElement::removeAttribute (const tchar* const attributeName) throw()
- {
- XmlAttributeNode* att = attributes;
- XmlAttributeNode* lastAtt = 0;
-
- while (att != 0)
- {
- if (att->name.equalsIgnoreCase (attributeName))
- {
- if (lastAtt == 0)
- attributes = att->next;
- else
- lastAtt->next = att->next;
-
- delete att;
- break;
- }
-
- lastAtt = att;
- att = att->next;
- }
- }
-
- void XmlElement::removeAllAttributes() throw()
- {
- while (attributes != 0)
- {
- XmlAttributeNode* const nextAtt = attributes->next;
- delete attributes;
- attributes = nextAtt;
- }
- }
-
- int XmlElement::getNumChildElements() const throw()
- {
- int count = 0;
- const XmlElement* child = firstChildElement;
-
- while (child != 0)
- {
- ++count;
- child = child->nextElement;
- }
-
- return count;
- }
-
- XmlElement* XmlElement::getChildElement (const int index) const throw()
- {
- int count = 0;
- XmlElement* child = firstChildElement;
-
- while (child != 0 && count < index)
- {
- child = child->nextElement;
- ++count;
- }
-
- return child;
- }
-
- XmlElement* XmlElement::getChildByName (const tchar* const childName) const throw()
- {
- XmlElement* child = firstChildElement;
-
- while (child != 0)
- {
- if (child->hasTagName (childName))
- break;
-
- child = child->nextElement;
- }
-
- return child;
- }
-
- void XmlElement::addChildElement (XmlElement* const newNode) throw()
- {
- if (newNode != 0)
- {
- if (firstChildElement == 0)
- {
- firstChildElement = newNode;
- }
- else
- {
- XmlElement* child = firstChildElement;
-
- while (child->nextElement != 0)
- child = child->nextElement;
-
- child->nextElement = newNode;
-
- // if this is non-zero, then something's probably
- // gone wrong..
- jassert (newNode->nextElement == 0);
- }
- }
- }
-
- void XmlElement::insertChildElement (XmlElement* const newNode,
- int indexToInsertAt) throw()
- {
- if (newNode != 0)
- {
- removeChildElement (newNode, false);
-
- if (indexToInsertAt == 0)
- {
- newNode->nextElement = firstChildElement;
- firstChildElement = newNode;
- }
- else
- {
- if (firstChildElement == 0)
- {
- firstChildElement = newNode;
- }
- else
- {
- if (indexToInsertAt < 0)
- indexToInsertAt = INT_MAX;
-
- XmlElement* child = firstChildElement;
-
- while (child->nextElement != 0 && --indexToInsertAt > 0)
- child = child->nextElement;
-
- newNode->nextElement = child->nextElement;
- child->nextElement = newNode;
- }
- }
- }
- }
-
- bool XmlElement::replaceChildElement (XmlElement* const currentChildElement,
- XmlElement* const newNode) throw()
- {
- if (newNode != 0)
- {
- XmlElement* child = firstChildElement;
- XmlElement* previousNode = 0;
-
- while (child != 0)
- {
- if (child == currentChildElement)
- {
- if (child != newNode)
- {
- if (previousNode == 0)
- firstChildElement = newNode;
- else
- previousNode->nextElement = newNode;
-
- newNode->nextElement = child->nextElement;
-
- delete child;
- }
-
- return true;
- }
-
- previousNode = child;
- child = child->nextElement;
- }
- }
-
- return false;
- }
-
- void XmlElement::removeChildElement (XmlElement* const childToRemove,
- const bool shouldDeleteTheChild) throw()
- {
- if (childToRemove != 0)
- {
- if (firstChildElement == childToRemove)
- {
- firstChildElement = childToRemove->nextElement;
- childToRemove->nextElement = 0;
- }
- else
- {
- XmlElement* child = firstChildElement;
- XmlElement* last = 0;
-
- while (child != 0)
- {
- if (child == childToRemove)
- {
- if (last == 0)
- firstChildElement = child->nextElement;
- else
- last->nextElement = child->nextElement;
-
- childToRemove->nextElement = 0;
- break;
- }
-
- last = child;
- child = child->nextElement;
- }
- }
-
- if (shouldDeleteTheChild)
- delete childToRemove;
- }
- }
-
- bool XmlElement::isEquivalentTo (const XmlElement* const other,
- const bool ignoreOrderOfAttributes) const throw()
- {
- if (this != other)
- {
- if (other == 0 || tagName != other->tagName)
- {
- return false;
- }
-
- if (ignoreOrderOfAttributes)
- {
- int totalAtts = 0;
- const XmlAttributeNode* att = attributes;
-
- while (att != 0)
- {
- if (! other->compareAttribute (att->name, att->value))
- return false;
-
- att = att->next;
- ++totalAtts;
- }
-
- if (totalAtts != other->getNumAttributes())
- return false;
- }
- else
- {
- const XmlAttributeNode* thisAtt = attributes;
- const XmlAttributeNode* otherAtt = other->attributes;
-
- for (;;)
- {
- if (thisAtt == 0 || otherAtt == 0)
- {
- if (thisAtt == otherAtt) // both 0, so it's a match
- break;
-
- return false;
- }
-
- if (thisAtt->name != otherAtt->name
- || thisAtt->value != otherAtt->value)
- {
- return false;
- }
-
- thisAtt = thisAtt->next;
- otherAtt = otherAtt->next;
- }
- }
-
- const XmlElement* thisChild = firstChildElement;
- const XmlElement* otherChild = other->firstChildElement;
-
- for (;;)
- {
- if (thisChild == 0 || otherChild == 0)
- {
- if (thisChild == otherChild) // both 0, so it's a match
- break;
-
- return false;
- }
-
- if (! thisChild->isEquivalentTo (otherChild, ignoreOrderOfAttributes))
- return false;
-
- thisChild = thisChild->nextElement;
- otherChild = otherChild->nextElement;
- }
- }
-
- return true;
- }
-
- void XmlElement::deleteAllChildElements() throw()
- {
- while (firstChildElement != 0)
- {
- XmlElement* const nextChild = firstChildElement->nextElement;
- delete firstChildElement;
- firstChildElement = nextChild;
- }
- }
-
- void XmlElement::deleteAllChildElementsWithTagName (const tchar* const name) throw()
- {
- XmlElement* child = firstChildElement;
-
- while (child != 0)
- {
- if (child->hasTagName (name))
- {
- XmlElement* const nextChild = child->nextElement;
- removeChildElement (child, true);
- child = nextChild;
- }
- else
- {
- child = child->nextElement;
- }
- }
- }
-
- bool XmlElement::containsChildElement (const XmlElement* const possibleChild) const throw()
- {
- const XmlElement* child = firstChildElement;
-
- while (child != 0)
- {
- if (child == possibleChild)
- return true;
-
- child = child->nextElement;
- }
-
- return false;
- }
-
- XmlElement* XmlElement::findParentElementOf (const XmlElement* const elementToLookFor) throw()
- {
- if (this == elementToLookFor || elementToLookFor == 0)
- return 0;
-
- XmlElement* child = firstChildElement;
-
- while (child != 0)
- {
- if (elementToLookFor == child)
- return this;
-
- XmlElement* const found = child->findParentElementOf (elementToLookFor);
-
- if (found != 0)
- return found;
-
- child = child->nextElement;
- }
-
- return 0;
- }
-
- XmlElement** XmlElement::getChildElementsAsArray (const int num) const throw()
- {
- XmlElement** const elems = new XmlElement* [num];
-
- XmlElement* e = firstChildElement;
- int i = 0;
-
- while (e != 0)
- {
- elems [i++] = e;
- e = e->nextElement;
- }
-
- return elems;
- }
-
- void XmlElement::reorderChildElements (XmlElement** const elems, const int num) throw()
- {
- XmlElement* e = firstChildElement = elems[0];
-
- for (int i = 1; i < num; ++i)
- {
- e->nextElement = elems[i];
- e = e->nextElement;
- }
-
- e->nextElement = 0;
- }
-
- bool XmlElement::isTextElement() const throw()
- {
- return tagName.isEmpty();
- }
-
- static const tchar* const juce_xmltextContentAttributeName = T("text");
-
- const String XmlElement::getText() const throw()
- {
- jassert (isTextElement()); // you're trying to get the text from an element that
- // isn't actually a text element.. If this contains text sub-nodes, you
- // can use getAllSubText instead to
-
- return getStringAttribute (juce_xmltextContentAttributeName);
- }
-
- void XmlElement::setText (const String& newText) throw()
- {
- if (isTextElement())
- {
- setAttribute (juce_xmltextContentAttributeName, newText);
- }
- else
- {
- jassertfalse // you can only change the text in a text element, not a normal one.
- }
- }
-
- const String XmlElement::getAllSubText() const throw()
- {
- String result;
- const XmlElement* child = firstChildElement;
-
- while (child != 0)
- {
- if (child->isTextElement())
- result += child->getText();
-
- child = child->nextElement;
- }
-
- return result;
- }
-
- const String XmlElement::getChildElementAllSubText (const tchar* const childTagName,
- const String& defaultReturnValue) const throw()
- {
- const XmlElement* const child = getChildByName (childTagName);
-
- if (child != 0)
- return child->getAllSubText();
-
- return defaultReturnValue;
- }
-
- XmlElement* XmlElement::createTextElement (const String& text) throw()
- {
- XmlElement* const e = new XmlElement ((int) 0);
- e->setAttribute (juce_xmltextContentAttributeName, text);
- return e;
- }
-
- void XmlElement::addTextElement (const String& text) throw()
- {
- addChildElement (createTextElement (text));
- }
-
- void XmlElement::deleteAllTextElements() throw()
- {
- XmlElement* child = firstChildElement;
-
- while (child != 0)
- {
- XmlElement* const next = child->nextElement;
-
- if (child->isTextElement())
- removeChildElement (child, true);
-
- child = next;
- }
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_XmlElement.cpp *********/
-
- /********* Start of inlined file: juce_InterProcessLock.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- // (implemented in the platform-specific code files)
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_InterProcessLock.cpp *********/
-
- /********* Start of inlined file: juce_ReadWriteLock.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- ReadWriteLock::ReadWriteLock() throw()
- : numWaitingWriters (0),
- numWriters (0),
- writerThreadId (0)
- {
- }
-
- ReadWriteLock::~ReadWriteLock() throw()
- {
- jassert (readerThreads.size() == 0);
- jassert (numWriters == 0);
- }
-
- void ReadWriteLock::enterRead() const throw()
- {
- const int threadId = Thread::getCurrentThreadId();
- const ScopedLock sl (accessLock);
-
- for (;;)
- {
- jassert (readerThreads.size() % 2 == 0);
-
- int i;
- for (i = 0; i < readerThreads.size(); i += 2)
- if (readerThreads.getUnchecked(i) == threadId)
- break;
-
- if (i < readerThreads.size()
- || numWriters + numWaitingWriters == 0
- || (threadId == writerThreadId && numWriters > 0))
- {
- if (i < readerThreads.size())
- {
- readerThreads.set (i + 1, readerThreads.getUnchecked (i + 1) + 1);
- }
- else
- {
- readerThreads.add (threadId);
- readerThreads.add (1);
- }
-
- return;
- }
-
- const ScopedUnlock ul (accessLock);
- waitEvent.wait (100);
- }
- }
-
- void ReadWriteLock::exitRead() const throw()
- {
- const int threadId = Thread::getCurrentThreadId();
- const ScopedLock sl (accessLock);
-
- for (int i = 0; i < readerThreads.size(); i += 2)
- {
- if (readerThreads.getUnchecked(i) == threadId)
- {
- const int newCount = readerThreads.getUnchecked (i + 1) - 1;
-
- if (newCount == 0)
- {
- readerThreads.removeRange (i, 2);
- waitEvent.signal();
- }
- else
- {
- readerThreads.set (i + 1, newCount);
- }
-
- return;
- }
- }
-
- jassertfalse // unlocking a lock that wasn't locked..
- }
-
- void ReadWriteLock::enterWrite() const throw()
- {
- const int threadId = Thread::getCurrentThreadId();
- const ScopedLock sl (accessLock);
-
- for (;;)
- {
- if (readerThreads.size() + numWriters == 0
- || threadId == writerThreadId
- || (readerThreads.size() == 2
- && readerThreads.getUnchecked(0) == threadId))
- {
- writerThreadId = threadId;
- ++numWriters;
- break;
- }
-
- ++numWaitingWriters;
- accessLock.exit();
- waitEvent.wait (100);
- accessLock.enter();
- --numWaitingWriters;
- }
- }
-
- bool ReadWriteLock::tryEnterWrite() const throw()
- {
- const int threadId = Thread::getCurrentThreadId();
- const ScopedLock sl (accessLock);
-
- if (readerThreads.size() + numWriters == 0
- || threadId == writerThreadId
- || (readerThreads.size() == 2
- && readerThreads.getUnchecked(0) == threadId))
- {
- writerThreadId = threadId;
- ++numWriters;
- return true;
- }
-
- return false;
- }
-
- void ReadWriteLock::exitWrite() const throw()
- {
- const ScopedLock sl (accessLock);
-
- // check this thread actually had the lock..
- jassert (numWriters > 0 && writerThreadId == Thread::getCurrentThreadId());
-
- if (--numWriters == 0)
- {
- writerThreadId = 0;
- waitEvent.signal();
- }
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_ReadWriteLock.cpp *********/
-
- /********* Start of inlined file: juce_Thread.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- // these functions are implemented in the platform-specific code.
- void* juce_createThread (void* userData) throw();
- void juce_killThread (void* handle) throw();
- void juce_setThreadPriority (void* handle, int priority) throw();
- void juce_setCurrentThreadName (const String& name) throw();
- #if JUCE_WIN32
- void juce_CloseThreadHandle (void* handle) throw();
- #endif
-
- static VoidArray runningThreads (4);
- static CriticalSection runningThreadsLock;
-
- void Thread::threadEntryPoint (Thread* const thread) throw()
- {
- runningThreadsLock.enter();
- runningThreads.add (thread);
- runningThreadsLock.exit();
-
- JUCE_TRY
- {
- thread->threadId_ = Thread::getCurrentThreadId();
-
- if (thread->threadName_.isNotEmpty())
- juce_setCurrentThreadName (thread->threadName_);
-
- if (thread->startSuspensionEvent_.wait (10000))
- {
- if (thread->affinityMask_ != 0)
- setCurrentThreadAffinityMask (thread->affinityMask_);
-
- thread->run();
- }
- }
- JUCE_CATCH_ALL_ASSERT
-
- runningThreadsLock.enter();
- jassert (runningThreads.contains (thread));
- runningThreads.removeValue (thread);
- runningThreadsLock.exit();
-
- #if JUCE_WIN32
- juce_CloseThreadHandle (thread->threadHandle_);
- #endif
-
- thread->threadHandle_ = 0;
- thread->threadId_ = 0;
- }
-
- // used to wrap the incoming call from the platform-specific code
- void JUCE_API juce_threadEntryPoint (void* userData)
- {
- Thread::threadEntryPoint ((Thread*) userData);
- }
-
- Thread::Thread (const String& threadName)
- : threadName_ (threadName),
- threadHandle_ (0),
- threadPriority_ (5),
- threadId_ (0),
- affinityMask_ (0),
- threadShouldExit_ (false)
- {
- }
-
- Thread::~Thread()
- {
- stopThread (100);
- }
-
- void Thread::startThread() throw()
- {
- const ScopedLock sl (startStopLock);
-
- threadShouldExit_ = false;
-
- if (threadHandle_ == 0)
- {
- threadHandle_ = juce_createThread ((void*) this);
- juce_setThreadPriority (threadHandle_, threadPriority_);
- startSuspensionEvent_.signal();
- }
- }
-
- void Thread::startThread (const int priority) throw()
- {
- const ScopedLock sl (startStopLock);
-
- if (threadHandle_ == 0)
- {
- threadPriority_ = priority;
- startThread();
- }
- else
- {
- setPriority (priority);
- }
- }
-
- bool Thread::isThreadRunning() const throw()
- {
- return threadHandle_ != 0;
- }
-
- void Thread::signalThreadShouldExit() throw()
- {
- threadShouldExit_ = true;
- }
-
- bool Thread::waitForThreadToExit (const int timeOutMilliseconds) const throw()
- {
- // Doh! So how exactly do you expect this thread to wait for itself to stop??
- jassert (getThreadId() != getCurrentThreadId());
-
- const int sleepMsPerIteration = 5;
- int count = timeOutMilliseconds / sleepMsPerIteration;
-
- while (isThreadRunning())
- {
- if (timeOutMilliseconds > 0 && --count < 0)
- return false;
-
- sleep (sleepMsPerIteration);
- }
-
- return true;
- }
-
- void Thread::stopThread (const int timeOutMilliseconds) throw()
- {
- // agh! You can't stop the thread that's calling this method! How on earth
- // would that work??
- jassert (getCurrentThreadId() != getThreadId());
-
- const ScopedLock sl (startStopLock);
-
- if (isThreadRunning())
- {
- signalThreadShouldExit();
- notify();
-
- if (timeOutMilliseconds != 0)
- waitForThreadToExit (timeOutMilliseconds);
-
- if (isThreadRunning())
- {
- // very bad karma if this point is reached, as
- // there are bound to be locks and events left in
- // silly states when a thread is killed by force..
- jassertfalse
- Logger::writeToLog ("!! killing thread by force !!");
-
- juce_killThread (threadHandle_);
- threadHandle_ = 0;
- threadId_ = 0;
-
- const ScopedLock sl (runningThreadsLock);
- runningThreads.removeValue (this);
- }
- }
- }
-
- void Thread::setPriority (const int priority) throw()
- {
- const ScopedLock sl (startStopLock);
-
- threadPriority_ = priority;
- juce_setThreadPriority (threadHandle_, priority);
- }
-
- void Thread::setCurrentThreadPriority (const int priority) throw()
- {
- juce_setThreadPriority (0, priority);
- }
-
- void Thread::setAffinityMask (const uint32 affinityMask) throw()
- {
- affinityMask_ = affinityMask;
- }
-
- int Thread::getThreadId() const throw()
- {
- return threadId_;
- }
-
- bool Thread::wait (const int timeOutMilliseconds) const throw()
- {
- return defaultEvent_.wait (timeOutMilliseconds);
- }
-
- void Thread::notify() const throw()
- {
- defaultEvent_.signal();
- }
-
- int Thread::getNumRunningThreads() throw()
- {
- return runningThreads.size();
- }
-
- Thread* Thread::getCurrentThread() throw()
- {
- const int thisId = getCurrentThreadId();
- Thread* result = 0;
-
- runningThreadsLock.enter();
-
- for (int i = runningThreads.size(); --i >= 0;)
- {
- Thread* const t = (Thread*) (runningThreads.getUnchecked(i));
-
- if (t->threadId_ == thisId)
- {
- result = t;
- break;
- }
- }
-
- runningThreadsLock.exit();
-
- return result;
- }
-
- void Thread::stopAllThreads (const int timeOutMilliseconds) throw()
- {
- runningThreadsLock.enter();
-
- for (int i = runningThreads.size(); --i >= 0;)
- ((Thread*) runningThreads.getUnchecked(i))->signalThreadShouldExit();
-
- runningThreadsLock.exit();
-
- for (;;)
- {
- runningThreadsLock.enter();
- Thread* const t = (Thread*) runningThreads[0];
- runningThreadsLock.exit();
-
- if (t == 0)
- break;
-
- t->stopThread (timeOutMilliseconds);
- }
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_Thread.cpp *********/
-
- /********* Start of inlined file: juce_ThreadPool.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- ThreadPoolJob::ThreadPoolJob (const String& name)
- : jobName (name),
- pool (0),
- shouldStop (false),
- isActive (false),
- shouldBeDeleted (false)
- {
- }
-
- ThreadPoolJob::~ThreadPoolJob()
- {
- // you mustn't delete a job while it's still in a pool! Use ThreadPool::removeJob()
- // to remove it first!
- jassert (pool == 0 || ! pool->contains (this));
- }
-
- const String ThreadPoolJob::getJobName() const
- {
- return jobName;
- }
-
- void ThreadPoolJob::setJobName (const String& newName)
- {
- jobName = newName;
- }
-
- void ThreadPoolJob::signalJobShouldExit()
- {
- shouldStop = true;
- }
-
- class ThreadPoolThread : public Thread
- {
- ThreadPool& pool;
- bool volatile busy;
-
- ThreadPoolThread (const ThreadPoolThread&);
- const ThreadPoolThread& operator= (const ThreadPoolThread&);
-
- public:
- ThreadPoolThread (ThreadPool& pool_)
- : Thread (T("Pool")),
- pool (pool_),
- busy (false)
- {
- }
-
- ~ThreadPoolThread()
- {
- }
-
- void run()
- {
- while (! threadShouldExit())
- {
- if (! pool.runNextJob())
- wait (500);
- }
- }
- };
-
- ThreadPool::ThreadPool (const int numThreads_,
- const bool startThreadsOnlyWhenNeeded,
- const int stopThreadsWhenNotUsedTimeoutMs)
- : numThreads (jmax (1, numThreads_)),
- threadStopTimeout (stopThreadsWhenNotUsedTimeoutMs),
- priority (5)
- {
- jassert (numThreads_ > 0); // not much point having one of these with no threads in it.
-
- threads = (Thread**) juce_calloc (sizeof (Thread*) * numThreads);
-
- for (int i = numThreads; --i >= 0;)
- {
- threads[i] = new ThreadPoolThread (*this);
-
- if (! startThreadsOnlyWhenNeeded)
- threads[i]->startThread();
- }
- }
-
- ThreadPool::~ThreadPool()
- {
- removeAllJobs (true, 4000);
-
- int i;
- for (i = numThreads; --i >= 0;)
- threads[i]->signalThreadShouldExit();
-
- for (i = numThreads; --i >= 0;)
- {
- threads[i]->stopThread (500);
- delete threads[i];
- }
-
- juce_free (threads);
- }
-
- void ThreadPool::addJob (ThreadPoolJob* const job)
- {
- jassert (job->pool == 0);
-
- if (job->pool == 0)
- {
- job->pool = this;
- job->shouldStop = false;
- job->isActive = false;
-
- lock.enter();
- jobs.add (job);
-
- int numRunning = 0;
-
- int i;
- for (i = numThreads; --i >= 0;)
- if (threads[i]->isThreadRunning() && ! threads[i]->threadShouldExit())
- ++numRunning;
-
- if (numRunning < numThreads)
- {
- bool startedOne = false;
- int n = 1000;
-
- while (--n >= 0 && ! startedOne)
- {
- for (int i = numThreads; --i >= 0;)
- {
- if (! threads[i]->isThreadRunning())
- {
- threads[i]->startThread();
- startedOne = true;
- }
- }
-
- if (! startedOne)
- Thread::sleep (5);
- }
- }
-
- lock.exit();
-
- for (i = numThreads; --i >= 0;)
- threads[i]->notify();
- }
- }
-
- int ThreadPool::getNumJobs() const throw()
- {
- return jobs.size();
- }
-
- ThreadPoolJob* ThreadPool::getJob (const int index) const
- {
- const ScopedLock sl (lock);
- return (ThreadPoolJob*) jobs [index];
- }
-
- bool ThreadPool::contains (const ThreadPoolJob* const job) const throw()
- {
- const ScopedLock sl (lock);
-
- return jobs.contains ((void*) job);
- }
-
- bool ThreadPool::isJobRunning (const ThreadPoolJob* const job) const
- {
- const ScopedLock sl (lock);
-
- return jobs.contains ((void*) job) && job->isActive;
- }
-
- bool ThreadPool::waitForJobToFinish (const ThreadPoolJob* const job,
- const int timeOutMs) const
- {
- if (job != 0)
- {
- const uint32 start = Time::getMillisecondCounter();
-
- while (contains (job))
- {
- if (timeOutMs >= 0 && Time::getMillisecondCounter() >= start + timeOutMs)
- return false;
-
- Thread::sleep (2);
- }
- }
-
- return true;
- }
-
- bool ThreadPool::removeJob (ThreadPoolJob* const job,
- const bool interruptIfRunning,
- const int timeOutMs)
- {
- if (job != 0)
- {
- lock.enter();
-
- if (jobs.contains (job))
- {
- if (job->isActive)
- {
- if (interruptIfRunning)
- job->signalJobShouldExit();
-
- lock.exit();
-
- return waitForJobToFinish (job, timeOutMs);
- }
- else
- {
- jobs.removeValue (job);
- }
- }
-
- lock.exit();
- }
-
- return true;
- }
-
- bool ThreadPool::removeAllJobs (const bool interruptRunningJobs,
- const int timeOutMs)
- {
- lock.enter();
-
- for (int i = jobs.size(); --i >= 0;)
- {
- ThreadPoolJob* const job = (ThreadPoolJob*) jobs.getUnchecked(i);
-
- if (job->isActive)
- {
- if (interruptRunningJobs)
- job->signalJobShouldExit();
- }
- else
- {
- jobs.remove (i);
- }
- }
-
- lock.exit();
-
- const uint32 start = Time::getMillisecondCounter();
-
- while (jobs.size() > 0)
- {
- if (timeOutMs >= 0 && Time::getMillisecondCounter() >= start + timeOutMs)
- return false;
-
- Thread::sleep (2);
- }
-
- return true;
- }
-
- const StringArray ThreadPool::getNamesOfAllJobs (const bool onlyReturnActiveJobs) const
- {
- StringArray s;
- const ScopedLock sl (lock);
-
- for (int i = 0; i < jobs.size(); ++i)
- {
- const ThreadPoolJob* const job = (const ThreadPoolJob*) jobs.getUnchecked(i);
- if (job->isActive || ! onlyReturnActiveJobs)
- s.add (job->getJobName());
- }
-
- return s;
- }
-
- void ThreadPool::setThreadPriorities (const int newPriority)
- {
- if (priority != newPriority)
- {
- priority = newPriority;
-
- for (int i = numThreads; --i >= 0;)
- threads[i]->setPriority (newPriority);
- }
- }
-
- bool ThreadPool::runNextJob()
- {
- lock.enter();
- ThreadPoolJob* job = 0;
-
- for (int i = 0; i < jobs.size(); ++i)
- {
- job = (ThreadPoolJob*) jobs [i];
-
- if (job != 0 && ! (job->isActive || job->shouldStop))
- break;
-
- job = 0;
- }
-
- if (job != 0)
- {
- job->isActive = true;
- lock.exit();
-
- JUCE_TRY
- {
- ThreadPoolJob::JobStatus result = job->runJob();
-
- lastJobEndTime = Time::getApproximateMillisecondCounter();
-
- const ScopedLock sl (lock);
-
- if (jobs.contains (job))
- {
- job->isActive = false;
-
- if (result != ThreadPoolJob::jobNeedsRunningAgain || job->shouldStop)
- {
- job->pool = 0;
- job->shouldStop = true;
- jobs.removeValue (job);
-
- if (result == ThreadPoolJob::jobHasFinishedAndShouldBeDeleted)
- delete job;
- }
- else
- {
- // move the job to the end of the queue if it wants another go
- jobs.move (jobs.indexOf (job), -1);
- }
- }
- }
- #if JUCE_CATCH_UNHANDLED_EXCEPTIONS
- catch (...)
- {
- lock.enter();
- jobs.removeValue (job);
- lock.exit();
- }
- #endif
- }
- else
- {
- lock.exit();
-
- if (threadStopTimeout > 0
- && Time::getApproximateMillisecondCounter() > lastJobEndTime + threadStopTimeout)
- {
- lock.enter();
-
- if (jobs.size() == 0)
- {
- for (int i = numThreads; --i >= 0;)
- threads[i]->signalThreadShouldExit();
- }
-
- lock.exit();
- }
- else
- {
- return false;
- }
- }
-
- return true;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_ThreadPool.cpp *********/
-
- /********* Start of inlined file: juce_TimeSliceThread.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- TimeSliceThread::TimeSliceThread (const String& threadName)
- : Thread (threadName),
- index (0),
- clientBeingCalled (0),
- clientsChanged (false)
- {
- }
-
- TimeSliceThread::~TimeSliceThread()
- {
- stopThread (2000);
- }
-
- void TimeSliceThread::addTimeSliceClient (TimeSliceClient* const client)
- {
- const ScopedLock sl (listLock);
- clients.addIfNotAlreadyThere (client);
- clientsChanged = true;
- notify();
- }
-
- void TimeSliceThread::removeTimeSliceClient (TimeSliceClient* const client)
- {
- const ScopedLock sl1 (listLock);
- clientsChanged = true;
-
- // if there's a chance we're in the middle of calling this client, we need to
- // also lock the outer lock..
- if (clientBeingCalled == client)
- {
- const ScopedUnlock ul (listLock); // unlock first to get the order right..
-
- const ScopedLock sl1 (callbackLock);
- const ScopedLock sl2 (listLock);
-
- clients.removeValue (client);
- }
- else
- {
- clients.removeValue (client);
- }
- }
-
- int TimeSliceThread::getNumClients() const throw()
- {
- return clients.size();
- }
-
- TimeSliceClient* TimeSliceThread::getClient (const int index) const throw()
- {
- const ScopedLock sl (listLock);
- return clients [index];
- }
-
- void TimeSliceThread::run()
- {
- int numCallsSinceBusy = 0;
-
- while (! threadShouldExit())
- {
- int timeToWait = 500;
-
- {
- const ScopedLock sl (callbackLock);
-
- {
- const ScopedLock sl (listLock);
-
- if (clients.size() > 0)
- {
- index = (index + 1) % clients.size();
-
- clientBeingCalled = clients [index];
- }
- else
- {
- index = 0;
- clientBeingCalled = 0;
- }
-
- if (clientsChanged)
- {
- clientsChanged = false;
- numCallsSinceBusy = 0;
- }
- }
-
- if (clientBeingCalled != 0)
- {
- if (clientBeingCalled->useTimeSlice())
- numCallsSinceBusy = 0;
- else
- ++numCallsSinceBusy;
-
- if (numCallsSinceBusy >= clients.size())
- timeToWait = 500;
- else if (index == 0)
- timeToWait = 1; // throw in an occasional pause, to stop everything locking up
- else
- timeToWait = 0;
- }
- }
-
- if (timeToWait > 0)
- wait (timeToWait);
- }
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_TimeSliceThread.cpp *********/
-
- #if ! JUCE_ONLY_BUILD_CORE_LIBRARY
-
- /********* Start of inlined file: juce_Application.cpp *********/
-
- #if JUCE_MSVC
- #pragma warning (push)
- #pragma warning (disable: 4245 4514 4100)
- #include <crtdbg.h>
- #pragma warning (pop)
- #endif
-
- BEGIN_JUCE_NAMESPACE
-
- void juce_setCurrentExecutableFileName (const String& filename) throw();
- void juce_setCurrentThreadName (const String& name) throw();
-
- static JUCEApplication* appInstance = 0;
-
- JUCEApplication::JUCEApplication()
- : appReturnValue (0),
- stillInitialising (true)
- {
- }
-
- JUCEApplication::~JUCEApplication()
- {
- }
-
- JUCEApplication* JUCEApplication::getInstance() throw()
- {
- return appInstance;
- }
-
- bool JUCEApplication::isInitialising() const throw()
- {
- return stillInitialising;
- }
-
- const String JUCEApplication::getApplicationVersion()
- {
- return String::empty;
- }
-
- bool JUCEApplication::moreThanOneInstanceAllowed()
- {
- return true;
- }
-
- void JUCEApplication::anotherInstanceStarted (const String&)
- {
- }
-
- void JUCEApplication::systemRequestedQuit()
- {
- quit();
- }
-
- void JUCEApplication::quit (const bool useMaximumForce)
- {
- MessageManager::getInstance()->postQuitMessage (useMaximumForce);
- }
-
- void JUCEApplication::setApplicationReturnValue (const int newReturnValue) throw()
- {
- appReturnValue = newReturnValue;
- }
-
- void JUCEApplication::unhandledException (const std::exception*,
- const String&,
- const int)
- {
- jassertfalse
- }
-
- void JUCEApplication::sendUnhandledException (const std::exception* const e,
- const char* const sourceFile,
- const int lineNumber)
- {
- if (appInstance != 0)
- appInstance->unhandledException (e, sourceFile, lineNumber);
- }
-
- ApplicationCommandTarget* JUCEApplication::getNextCommandTarget()
- {
- return 0;
- }
-
- void JUCEApplication::getAllCommands (Array <CommandID>& commands)
- {
- commands.add (StandardApplicationCommandIDs::quit);
- }
-
- void JUCEApplication::getCommandInfo (const CommandID commandID, ApplicationCommandInfo& result)
- {
- if (commandID == StandardApplicationCommandIDs::quit)
- {
- result.setInfo ("Quit",
- "Quits the application",
- "Application",
- 0);
-
- result.defaultKeypresses.add (KeyPress (T('q'), ModifierKeys::commandModifier, 0));
- }
- }
-
- bool JUCEApplication::perform (const InvocationInfo& info)
- {
- if (info.commandID == StandardApplicationCommandIDs::quit)
- {
- systemRequestedQuit();
- return true;
- }
-
- return false;
- }
-
- int JUCEApplication::main (String& commandLine, JUCEApplication* const app)
- {
- jassert (appInstance == 0);
- appInstance = app;
- bool useForce = true;
-
- initialiseJuce_GUI();
-
- InterProcessLock* appLock = 0;
-
- if (! app->moreThanOneInstanceAllowed())
- {
- appLock = new InterProcessLock ("juceAppLock_" + app->getApplicationName());
-
- if (! appLock->enter(0))
- {
- MessageManager::broadcastMessage (app->getApplicationName() + "/" + commandLine);
-
- delete appInstance;
- appInstance = 0;
- commandLine = String::empty;
-
- DBG ("Another instance is running - quitting...");
- return 0;
- }
- }
-
- JUCE_TRY
- {
- juce_setCurrentThreadName ("Juce Message Thread");
-
- // let the app do its setting-up..
- app->initialise (commandLine.trim());
-
- commandLine = String::empty;
-
- // register for broadcast new app messages
- MessageManager::getInstance()->registerBroadcastListener (app);
-
- app->stillInitialising = false;
-
- // now loop until a quit message is received..
- useForce = MessageManager::getInstance()->runDispatchLoop();
-
- MessageManager::getInstance()->deregisterBroadcastListener (app);
-
- if (appLock != 0)
- {
- appLock->exit();
- delete appLock;
- }
- }
- #if JUCE_CATCH_UNHANDLED_EXCEPTIONS
- catch (const std::exception& e)
- {
- app->unhandledException (&e, __FILE__, __LINE__);
- }
- catch (...)
- {
- app->unhandledException (0, __FILE__, __LINE__);
- }
- #endif
-
- return shutdownAppAndClearUp (useForce);
- }
-
- int JUCEApplication::shutdownAppAndClearUp (const bool useMaximumForce)
- {
- jassert (appInstance != 0);
- JUCEApplication* const app = appInstance;
- int returnValue = 0;
-
- static bool reentrancyCheck = false;
-
- if (! reentrancyCheck)
- {
- reentrancyCheck = true;
-
- JUCE_TRY
- {
- // give the app a chance to clean up..
- app->shutdown();
- }
- #if JUCE_CATCH_UNHANDLED_EXCEPTIONS
- catch (const std::exception& e)
- {
- app->unhandledException (&e, __FILE__, __LINE__);
- }
- catch (...)
- {
- app->unhandledException (0, __FILE__, __LINE__);
- }
- #endif
-
- JUCE_TRY
- {
- shutdownJuce_GUI();
-
- returnValue = app->getApplicationReturnValue();
-
- appInstance = 0;
- delete app;
- }
- JUCE_CATCH_ALL_ASSERT
-
- if (useMaximumForce)
- {
- Process::terminate();
- }
-
- reentrancyCheck = false;
- }
-
- return returnValue;
- }
-
- int JUCEApplication::main (int argc, char* argv[],
- JUCEApplication* const newApp)
- {
- juce_setCurrentExecutableFileName (String::fromUTF8 ((const uint8*) argv[0]));
-
- String cmd;
- for (int i = 1; i < argc; ++i)
- cmd << String::fromUTF8 ((const uint8*) argv[i]) << T(' ');
-
- return JUCEApplication::main (cmd, newApp);
- }
-
- void JUCEApplication::actionListenerCallback (const String& message)
- {
- if (message.startsWith (getApplicationName() + "/"))
- anotherInstanceStarted (message.substring (getApplicationName().length() + 1));
- }
-
- static bool juceInitialisedGUI = false;
-
- void JUCE_PUBLIC_FUNCTION initialiseJuce_GUI()
- {
- if (! juceInitialisedGUI)
- {
- juceInitialisedGUI = true;
-
- initialiseJuce_NonGUI();
- MessageManager::getInstance();
- Font::initialiseDefaultFontNames();
- LookAndFeel::setDefaultLookAndFeel (0);
-
- #if JUCE_WIN32 && JUCE_DEBUG
- // This section is just for catching people who mess up their project settings and
- // turn RTTI off..
- try
- {
- TextButton tb (String::empty);
- Component* c = &tb;
-
- // Got an exception here? Then TURN ON RTTI in your compiler settings!!
- c = dynamic_cast <Button*> (c);
- }
- catch (...)
- {
- // Ended up here? If so, TURN ON RTTI in your compiler settings!! And if you
- // got as far as this catch statement, then why haven't you got exception catching
- // turned on in the debugger???
- jassertfalse
- }
- #endif
- }
- }
-
- void JUCE_PUBLIC_FUNCTION shutdownJuce_GUI()
- {
- if (juceInitialisedGUI)
- {
- DeletedAtShutdown::deleteAll();
-
- LookAndFeel::clearDefaultLookAndFeel();
- shutdownJuce_NonGUI();
-
- juceInitialisedGUI = false;
- }
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_Application.cpp *********/
-
- /********* Start of inlined file: juce_ApplicationCommandInfo.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- ApplicationCommandInfo::ApplicationCommandInfo (const CommandID commandID_) throw()
- : commandID (commandID_),
- flags (0)
- {
- }
-
- void ApplicationCommandInfo::setInfo (const String& shortName_,
- const String& description_,
- const String& categoryName_,
- const int flags_) throw()
- {
- shortName = shortName_;
- description = description_;
- categoryName = categoryName_;
- flags = flags_;
- }
-
- void ApplicationCommandInfo::setActive (const bool b) throw()
- {
- if (b)
- flags &= ~isDisabled;
- else
- flags |= isDisabled;
- }
-
- void ApplicationCommandInfo::setTicked (const bool b) throw()
- {
- if (b)
- flags |= isTicked;
- else
- flags &= ~isTicked;
- }
-
- void ApplicationCommandInfo::addDefaultKeypress (const int keyCode, const ModifierKeys& modifiers) throw()
- {
- defaultKeypresses.add (KeyPress (keyCode, modifiers, 0));
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_ApplicationCommandInfo.cpp *********/
-
- /********* Start of inlined file: juce_ApplicationCommandManager.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- ApplicationCommandManager::ApplicationCommandManager()
- : listeners (8),
- firstTarget (0)
- {
- keyMappings = new KeyPressMappingSet (this);
-
- Desktop::getInstance().addFocusChangeListener (this);
- }
-
- ApplicationCommandManager::~ApplicationCommandManager()
- {
- Desktop::getInstance().removeFocusChangeListener (this);
- deleteAndZero (keyMappings);
- }
-
- void ApplicationCommandManager::clearCommands()
- {
- commands.clear();
- keyMappings->clearAllKeyPresses();
- triggerAsyncUpdate();
- }
-
- void ApplicationCommandManager::registerCommand (const ApplicationCommandInfo& newCommand)
- {
- // zero isn't a valid command ID!
- jassert (newCommand.commandID != 0);
-
- // the name isn't optional!
- jassert (newCommand.shortName.isNotEmpty());
-
- if (getCommandForID (newCommand.commandID) == 0)
- {
- ApplicationCommandInfo* const newInfo = new ApplicationCommandInfo (newCommand);
- newInfo->flags &= ~ApplicationCommandInfo::isTicked;
- commands.add (newInfo);
-
- keyMappings->resetToDefaultMapping (newCommand.commandID);
-
- triggerAsyncUpdate();
- }
- else
- {
- // trying to re-register the same command with different parameters?
- jassert (newCommand.shortName == getCommandForID (newCommand.commandID)->shortName
- && (newCommand.description == getCommandForID (newCommand.commandID)->description || newCommand.description.isEmpty())
- && newCommand.categoryName == getCommandForID (newCommand.commandID)->categoryName
- && newCommand.defaultKeypresses == getCommandForID (newCommand.commandID)->defaultKeypresses
- && (newCommand.flags & (ApplicationCommandInfo::wantsKeyUpDownCallbacks | ApplicationCommandInfo::hiddenFromKeyEditor | ApplicationCommandInfo::readOnlyInKeyEditor))
- == (getCommandForID (newCommand.commandID)->flags & (ApplicationCommandInfo::wantsKeyUpDownCallbacks | ApplicationCommandInfo::hiddenFromKeyEditor | ApplicationCommandInfo::readOnlyInKeyEditor)));
- }
- }
-
- void ApplicationCommandManager::registerAllCommandsForTarget (ApplicationCommandTarget* target)
- {
- if (target != 0)
- {
- Array <CommandID> commandIDs;
- target->getAllCommands (commandIDs);
-
- for (int i = 0; i < commandIDs.size(); ++i)
- {
- ApplicationCommandInfo info (commandIDs.getUnchecked(i));
- target->getCommandInfo (info.commandID, info);
-
- registerCommand (info);
- }
- }
- }
-
- void ApplicationCommandManager::removeCommand (const CommandID commandID)
- {
- for (int i = commands.size(); --i >= 0;)
- {
- if (commands.getUnchecked (i)->commandID == commandID)
- {
- commands.remove (i);
- triggerAsyncUpdate();
-
- const Array <KeyPress> keys (keyMappings->getKeyPressesAssignedToCommand (commandID));
-
- for (int j = keys.size(); --j >= 0;)
- keyMappings->removeKeyPress (keys.getReference (j));
- }
- }
- }
-
- void ApplicationCommandManager::commandStatusChanged()
- {
- triggerAsyncUpdate();
- }
-
- const ApplicationCommandInfo* ApplicationCommandManager::getCommandForID (const CommandID commandID) const throw()
- {
- for (int i = commands.size(); --i >= 0;)
- if (commands.getUnchecked(i)->commandID == commandID)
- return commands.getUnchecked(i);
-
- return 0;
- }
-
- const String ApplicationCommandManager::getNameOfCommand (const CommandID commandID) const throw()
- {
- const ApplicationCommandInfo* const ci = getCommandForID (commandID);
-
- return (ci != 0) ? ci->shortName : String::empty;
- }
-
- const String ApplicationCommandManager::getDescriptionOfCommand (const CommandID commandID) const throw()
- {
- const ApplicationCommandInfo* const ci = getCommandForID (commandID);
-
- return (ci != 0) ? (ci->description.isNotEmpty() ? ci->description : ci->shortName)
- : String::empty;
- }
-
- const StringArray ApplicationCommandManager::getCommandCategories() const throw()
- {
- StringArray s;
-
- for (int i = 0; i < commands.size(); ++i)
- s.addIfNotAlreadyThere (commands.getUnchecked(i)->categoryName, false);
-
- return s;
- }
-
- const Array <CommandID> ApplicationCommandManager::getCommandsInCategory (const String& categoryName) const throw()
- {
- Array <CommandID> results (4);
-
- for (int i = 0; i < commands.size(); ++i)
- if (commands.getUnchecked(i)->categoryName == categoryName)
- results.add (commands.getUnchecked(i)->commandID);
-
- return results;
- }
-
- bool ApplicationCommandManager::invokeDirectly (const CommandID commandID, const bool asynchronously)
- {
- ApplicationCommandTarget::InvocationInfo info (commandID);
- info.invocationMethod = ApplicationCommandTarget::InvocationInfo::direct;
-
- return invoke (info, asynchronously);
- }
-
- bool ApplicationCommandManager::invoke (const ApplicationCommandTarget::InvocationInfo& info_, const bool asynchronously)
- {
- // This call isn't thread-safe for use from a non-UI thread without locking the message
- // manager first..
- jassert (MessageManager::getInstance()->currentThreadHasLockedMessageManager());
-
- ApplicationCommandTarget* const target = getFirstCommandTarget (info_.commandID);
-
- if (target == 0)
- return false;
-
- ApplicationCommandInfo commandInfo (0);
- target->getCommandInfo (info_.commandID, commandInfo);
-
- ApplicationCommandTarget::InvocationInfo info (info_);
- info.commandFlags = commandInfo.flags;
-
- sendListenerInvokeCallback (info);
-
- const bool ok = target->invoke (info, asynchronously);
-
- commandStatusChanged();
-
- return ok;
- }
-
- ApplicationCommandTarget* ApplicationCommandManager::getFirstCommandTarget (const CommandID)
- {
- return firstTarget != 0 ? firstTarget
- : findDefaultComponentTarget();
- }
-
- void ApplicationCommandManager::setFirstCommandTarget (ApplicationCommandTarget* const newTarget) throw()
- {
- firstTarget = newTarget;
- }
-
- ApplicationCommandTarget* ApplicationCommandManager::getTargetForCommand (const CommandID commandID,
- ApplicationCommandInfo& upToDateInfo)
- {
- ApplicationCommandTarget* target = getFirstCommandTarget (commandID);
-
- if (target == 0)
- target = JUCEApplication::getInstance();
-
- if (target != 0)
- target = target->getTargetForCommand (commandID);
-
- if (target != 0)
- target->getCommandInfo (commandID, upToDateInfo);
-
- return target;
- }
-
- ApplicationCommandTarget* ApplicationCommandManager::findTargetForComponent (Component* c)
- {
- ApplicationCommandTarget* target = dynamic_cast <ApplicationCommandTarget*> (c);
-
- if (target == 0 && c != 0)
- // (unable to use the syntax findParentComponentOfClass <ApplicationCommandTarget> () because of a VC6 compiler bug)
- target = c->findParentComponentOfClass ((ApplicationCommandTarget*) 0);
-
- return target;
- }
-
- ApplicationCommandTarget* ApplicationCommandManager::findDefaultComponentTarget()
- {
- Component* c = Component::getCurrentlyFocusedComponent();
-
- if (c == 0)
- {
- TopLevelWindow* const activeWindow = TopLevelWindow::getActiveTopLevelWindow();
-
- if (activeWindow != 0)
- {
- c = activeWindow->getPeer()->getLastFocusedSubcomponent();
-
- if (c == 0)
- c = activeWindow;
- }
- }
-
- if (c == 0)
- {
- // getting a bit desperate now - try all desktop comps..
- for (int i = Desktop::getInstance().getNumComponents(); --i >= 0;)
- {
- ApplicationCommandTarget* const target
- = findTargetForComponent (Desktop::getInstance().getComponent (i)
- ->getPeer()->getLastFocusedSubcomponent());
-
- if (target != 0)
- return target;
- }
- }
-
- if (c != 0)
- {
- ResizableWindow* const resizableWindow = dynamic_cast <ResizableWindow*> (c);
-
- // if we're focused on a ResizableWindow, chances are that it's the content
- // component that really should get the event. And if not, the event will
- // still be passed up to the top level window anyway, so let's send it to the
- // content comp.
- if (resizableWindow != 0 && resizableWindow->getContentComponent() != 0)
- c = resizableWindow->getContentComponent();
-
- ApplicationCommandTarget* const target = findTargetForComponent (c);
-
- if (target != 0)
- return target;
- }
-
- return JUCEApplication::getInstance();
- }
-
- void ApplicationCommandManager::addListener (ApplicationCommandManagerListener* const listener) throw()
- {
- jassert (listener != 0);
- if (listener != 0)
- listeners.add (listener);
- }
-
- void ApplicationCommandManager::removeListener (ApplicationCommandManagerListener* const listener) throw()
- {
- listeners.removeValue (listener);
- }
-
- void ApplicationCommandManager::sendListenerInvokeCallback (const ApplicationCommandTarget::InvocationInfo& info) const
- {
- for (int i = listeners.size(); --i >= 0;)
- {
- ((ApplicationCommandManagerListener*) listeners.getUnchecked (i))->applicationCommandInvoked (info);
- i = jmin (i, listeners.size());
- }
- }
-
- void ApplicationCommandManager::handleAsyncUpdate()
- {
- for (int i = listeners.size(); --i >= 0;)
- {
- ((ApplicationCommandManagerListener*) listeners.getUnchecked (i))->applicationCommandListChanged();
- i = jmin (i, listeners.size());
- }
- }
-
- void ApplicationCommandManager::globalFocusChanged (Component*)
- {
- commandStatusChanged();
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_ApplicationCommandManager.cpp *********/
-
- /********* Start of inlined file: juce_ApplicationCommandTarget.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- ApplicationCommandTarget::ApplicationCommandTarget()
- : messageInvoker (0)
- {
- }
-
- ApplicationCommandTarget::~ApplicationCommandTarget()
- {
- deleteAndZero (messageInvoker);
- }
-
- bool ApplicationCommandTarget::tryToInvoke (const InvocationInfo& info, const bool async)
- {
- if (isCommandActive (info.commandID))
- {
- if (async)
- {
- if (messageInvoker == 0)
- messageInvoker = new CommandTargetMessageInvoker (this);
-
- messageInvoker->postMessage (new Message (0, 0, 0, new ApplicationCommandTarget::InvocationInfo (info)));
- return true;
- }
- else
- {
- const bool success = perform (info);
-
- jassert (success); // hmm - your target should have been able to perform this command. If it can't
- // do it at the moment for some reason, it should clear the 'isActive' flag when it
- // returns the command's info.
- return success;
- }
- }
-
- return false;
- }
-
- ApplicationCommandTarget* ApplicationCommandTarget::findFirstTargetParentComponent()
- {
- Component* c = dynamic_cast <Component*> (this);
-
- if (c != 0)
- // (unable to use the syntax findParentComponentOfClass <ApplicationCommandTarget> () because of a VC6 compiler bug)
- return c->findParentComponentOfClass ((ApplicationCommandTarget*) 0);
-
- return 0;
- }
-
- ApplicationCommandTarget* ApplicationCommandTarget::getTargetForCommand (const CommandID commandID)
- {
- ApplicationCommandTarget* target = this;
- int depth = 0;
-
- while (target != 0)
- {
- Array <CommandID> commandIDs;
- target->getAllCommands (commandIDs);
-
- if (commandIDs.contains (commandID))
- return target;
-
- target = target->getNextCommandTarget();
-
- ++depth;
- jassert (depth < 100); // could be a recursive command chain??
- jassert (target != this); // definitely a recursive command chain!
-
- if (depth > 100 || target == this)
- break;
- }
-
- if (target == 0)
- {
- target = JUCEApplication::getInstance();
-
- if (target != 0)
- {
- Array <CommandID> commandIDs;
- target->getAllCommands (commandIDs);
-
- if (commandIDs.contains (commandID))
- return target;
- }
- }
-
- return 0;
- }
-
- bool ApplicationCommandTarget::isCommandActive (const CommandID commandID)
- {
- ApplicationCommandInfo info (commandID);
- info.flags = ApplicationCommandInfo::isDisabled;
-
- getCommandInfo (commandID, info);
-
- return (info.flags & ApplicationCommandInfo::isDisabled) == 0;
- }
-
- bool ApplicationCommandTarget::invoke (const InvocationInfo& info, const bool async)
- {
- ApplicationCommandTarget* target = this;
- int depth = 0;
-
- while (target != 0)
- {
- if (target->tryToInvoke (info, async))
- return true;
-
- target = target->getNextCommandTarget();
-
- ++depth;
- jassert (depth < 100); // could be a recursive command chain??
- jassert (target != this); // definitely a recursive command chain!
-
- if (depth > 100 || target == this)
- break;
- }
-
- if (target == 0)
- {
- target = JUCEApplication::getInstance();
-
- if (target != 0)
- return target->tryToInvoke (info, async);
- }
-
- return false;
- }
-
- bool ApplicationCommandTarget::invokeDirectly (const CommandID commandID, const bool asynchronously)
- {
- ApplicationCommandTarget::InvocationInfo info (commandID);
- info.invocationMethod = ApplicationCommandTarget::InvocationInfo::direct;
-
- return invoke (info, asynchronously);
- }
-
- ApplicationCommandTarget::InvocationInfo::InvocationInfo (const CommandID commandID_) throw()
- : commandID (commandID_),
- commandFlags (0),
- invocationMethod (direct),
- originatingComponent (0),
- isKeyDown (false),
- millisecsSinceKeyPressed (0)
- {
- }
-
- ApplicationCommandTarget::CommandTargetMessageInvoker::CommandTargetMessageInvoker (ApplicationCommandTarget* const owner_)
- : owner (owner_)
- {
- }
-
- ApplicationCommandTarget::CommandTargetMessageInvoker::~CommandTargetMessageInvoker()
- {
- }
-
- void ApplicationCommandTarget::CommandTargetMessageInvoker::handleMessage (const Message& message)
- {
- InvocationInfo* const info = (InvocationInfo*) message.pointerParameter;
- owner->tryToInvoke (*info, false);
- delete info;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_ApplicationCommandTarget.cpp *********/
-
- /********* Start of inlined file: juce_ApplicationProperties.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- juce_ImplementSingleton (ApplicationProperties)
-
- ApplicationProperties::ApplicationProperties() throw()
- : userProps (0),
- commonProps (0),
- msBeforeSaving (3000),
- options (PropertiesFile::storeAsBinary),
- commonSettingsAreReadOnly (0)
- {
- }
-
- ApplicationProperties::~ApplicationProperties()
- {
- closeFiles();
- clearSingletonInstance();
- }
-
- void ApplicationProperties::setStorageParameters (const String& applicationName,
- const String& fileNameSuffix,
- const String& folderName_,
- const int millisecondsBeforeSaving,
- const int propertiesFileOptions) throw()
- {
- appName = applicationName;
- fileSuffix = fileNameSuffix;
- folderName = folderName_;
- msBeforeSaving = millisecondsBeforeSaving;
- options = propertiesFileOptions;
- }
-
- bool ApplicationProperties::testWriteAccess (const bool testUserSettings,
- const bool testCommonSettings,
- const bool showWarningDialogOnFailure)
- {
- const bool userOk = (! testUserSettings) || getUserSettings()->save();
- const bool commonOk = (! testCommonSettings) || getCommonSettings (false)->save();
-
- if (! (userOk && commonOk))
- {
- if (showWarningDialogOnFailure)
- {
- String filenames;
-
- if (userProps != 0 && ! userOk)
- filenames << '\n' << userProps->getFile().getFullPathName();
-
- if (commonProps != 0 && ! commonOk)
- filenames << '\n' << commonProps->getFile().getFullPathName();
-
- AlertWindow::showMessageBox (AlertWindow::WarningIcon,
- appName + TRANS(" - Unable to save settings"),
- TRANS("An error occurred when trying to save the application's settings file...\n\nIn order to save and restore its settings, ")
- + appName + TRANS(" needs to be able to write to the following files:\n")
- + filenames
- + TRANS("\n\nMake sure that these files aren't read-only, and that the disk isn't full."));
- }
-
- return false;
- }
-
- return true;
- }
-
- void ApplicationProperties::openFiles() throw()
- {
- // You need to call setStorageParameters() before trying to get hold of the
- // properties!
- jassert (appName.isNotEmpty());
-
- if (appName.isNotEmpty())
- {
- if (userProps == 0)
- userProps = PropertiesFile::createDefaultAppPropertiesFile (appName, fileSuffix, folderName,
- false, msBeforeSaving, options);
-
- if (commonProps == 0)
- commonProps = PropertiesFile::createDefaultAppPropertiesFile (appName, fileSuffix, folderName,
- true, msBeforeSaving, options);
-
- userProps->setFallbackPropertySet (commonProps);
- }
- }
-
- PropertiesFile* ApplicationProperties::getUserSettings() throw()
- {
- if (userProps == 0)
- openFiles();
-
- return userProps;
- }
-
- PropertiesFile* ApplicationProperties::getCommonSettings (const bool returnUserPropsIfReadOnly) throw()
- {
- if (commonProps == 0)
- openFiles();
-
- if (returnUserPropsIfReadOnly)
- {
- if (commonSettingsAreReadOnly == 0)
- commonSettingsAreReadOnly = commonProps->save() ? -1 : 1;
-
- if (commonSettingsAreReadOnly > 0)
- return userProps;
- }
-
- return commonProps;
- }
-
- bool ApplicationProperties::saveIfNeeded()
- {
- return (userProps == 0 || userProps->saveIfNeeded())
- && (commonProps == 0 || commonProps->saveIfNeeded());
- }
-
- void ApplicationProperties::closeFiles()
- {
- deleteAndZero (userProps);
- deleteAndZero (commonProps);
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_ApplicationProperties.cpp *********/
-
- /********* Start of inlined file: juce_DeletedAtShutdown.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- static VoidArray objectsToDelete (16);
- static CriticalSection lock;
-
- DeletedAtShutdown::DeletedAtShutdown() throw()
- {
- const ScopedLock sl (lock);
- objectsToDelete.add (this);
- }
-
- DeletedAtShutdown::~DeletedAtShutdown()
- {
- const ScopedLock sl (lock);
- objectsToDelete.removeValue (this);
- }
-
- void DeletedAtShutdown::deleteAll()
- {
- // make a local copy of the array, so it can't get into a loop if something
- // creates another DeletedAtShutdown object during its destructor.
- lock.enter();
- const VoidArray localCopy (objectsToDelete);
- lock.exit();
-
- for (int i = localCopy.size(); --i >= 0;)
- {
- JUCE_TRY
- {
- DeletedAtShutdown* const deletee = (DeletedAtShutdown*) localCopy.getUnchecked(i);
-
- // double-check that it's not already been deleted during another object's destructor.
- lock.enter();
- const bool okToDelete = objectsToDelete.contains (deletee);
- lock.exit();
-
- if (okToDelete)
- delete deletee;
- }
- JUCE_CATCH_EXCEPTION
- }
-
- // if no objects got re-created during shutdown, this should have been emptied by their
- // destructors
- jassert (objectsToDelete.size() == 0);
-
- objectsToDelete.clear(); // just to make sure the array doesn't have any memory still allocated
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_DeletedAtShutdown.cpp *********/
-
- /********* Start of inlined file: juce_PropertiesFile.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- static const int propFileMagicNumber = ((int) littleEndianInt ("PROP"));
- static const int propFileMagicNumberCompressed = ((int) littleEndianInt ("CPRP"));
-
- static const tchar* const propertyFileXmlTag = T("PROPERTIES");
- static const tchar* const propertyTagName = T("VALUE");
-
- PropertiesFile::PropertiesFile (const File& f,
- const int millisecondsBeforeSaving,
- const int options_) throw()
- : PropertySet (ignoreCaseOfKeyNames),
- file (f),
- timerInterval (millisecondsBeforeSaving),
- options (options_),
- needsWriting (false)
- {
- // You need to correctly specify just one storage format for the file
- jassert ((options_ & (storeAsBinary | storeAsCompressedBinary | storeAsXML)) == storeAsBinary
- || (options_ & (storeAsBinary | storeAsCompressedBinary | storeAsXML)) == storeAsCompressedBinary
- || (options_ & (storeAsBinary | storeAsCompressedBinary | storeAsXML)) == storeAsXML);
-
- InputStream* fileStream = f.createInputStream();
-
- if (fileStream != 0)
- {
- int magicNumber = fileStream->readInt();
-
- if (magicNumber == propFileMagicNumberCompressed)
- {
- fileStream = new SubregionStream (fileStream, 4, -1, true);
- fileStream = new GZIPDecompressorInputStream (fileStream, true);
-
- magicNumber = propFileMagicNumber;
- }
-
- if (magicNumber == propFileMagicNumber)
- {
- BufferedInputStream in (fileStream, 2048, true);
-
- int numValues = in.readInt();
-
- while (--numValues >= 0 && ! in.isExhausted())
- {
- const String key (in.readString());
- const String value (in.readString());
-
- jassert (key.isNotEmpty());
- if (key.isNotEmpty())
- getAllProperties().set (key, value);
- }
- }
- else
- {
- // Not a binary props file - let's see if it's XML..
- delete fileStream;
-
- XmlDocument parser (f);
- XmlElement* doc = parser.getDocumentElement (true);
-
- if (doc != 0 && doc->hasTagName (propertyFileXmlTag))
- {
- delete doc;
- doc = parser.getDocumentElement();
-
- if (doc != 0)
- {
- forEachXmlChildElementWithTagName (*doc, e, propertyTagName)
- {
- const String name (e->getStringAttribute (T("name")));
-
- if (name.isNotEmpty())
- {
- getAllProperties().set (name,
- e->getFirstChildElement() != 0
- ? e->getFirstChildElement()->createDocument (String::empty, true)
- : e->getStringAttribute (T("val")));
- }
- }
- }
- else
- {
- // must be a pretty broken XML file we're trying to parse here!
- jassertfalse
- }
-
- delete doc;
- }
- }
- }
- }
-
- PropertiesFile::~PropertiesFile()
- {
- saveIfNeeded();
- }
-
- bool PropertiesFile::saveIfNeeded()
- {
- const ScopedLock sl (getLock());
-
- return (! needsWriting) || save();
- }
-
- bool PropertiesFile::needsToBeSaved() const throw()
- {
- const ScopedLock sl (getLock());
-
- return needsWriting;
- }
-
- bool PropertiesFile::save()
- {
- const ScopedLock sl (getLock());
-
- stopTimer();
-
- if (file == File::nonexistent
- || file.isDirectory()
- || ! file.getParentDirectory().createDirectory())
- return false;
-
- if ((options & storeAsXML) != 0)
- {
- XmlElement* const doc = new XmlElement (propertyFileXmlTag);
-
- for (int i = 0; i < getAllProperties().size(); ++i)
- {
- XmlElement* const e = new XmlElement (propertyTagName);
- e->setAttribute (T("name"), getAllProperties().getAllKeys() [i]);
-
- // if the value seems to contain xml, store it as such..
- XmlDocument xmlContent (getAllProperties().getAllValues() [i]);
- XmlElement* const childElement = xmlContent.getDocumentElement();
-
- if (childElement != 0)
- e->addChildElement (childElement);
- else
- e->setAttribute (T("val"), getAllProperties().getAllValues() [i]);
-
- doc->addChildElement (e);
- }
-
- const bool ok = doc->writeToFile (file, String::empty);
-
- delete doc;
-
- return ok;
- }
- else
- {
- const File tempFile (file.getNonexistentSibling (false));
- OutputStream* out = tempFile.createOutputStream();
-
- if (out != 0)
- {
- if ((options & storeAsCompressedBinary) != 0)
- {
- out->writeInt (propFileMagicNumberCompressed);
- out->flush();
-
- out = new GZIPCompressorOutputStream (out, 9, true);
- }
- else
- {
- // have you set up the storage option flags correctly?
- jassert ((options & storeAsBinary) != 0);
-
- out->writeInt (propFileMagicNumber);
- }
-
- const int numProperties = getAllProperties().size();
-
- out->writeInt (numProperties);
-
- for (int i = 0; i < numProperties; ++i)
- {
- out->writeString (getAllProperties().getAllKeys() [i]);
- out->writeString (getAllProperties().getAllValues() [i]);
- }
-
- out->flush();
- delete out;
-
- if (tempFile.moveFileTo (file))
- {
- needsWriting = false;
- return true;
- }
-
- tempFile.deleteFile();
- }
- }
-
- return false;
- }
-
- void PropertiesFile::timerCallback()
- {
- saveIfNeeded();
- }
-
- void PropertiesFile::propertyChanged()
- {
- sendChangeMessage (this);
-
- needsWriting = true;
-
- if (timerInterval > 0)
- startTimer (timerInterval);
- else if (timerInterval == 0)
- saveIfNeeded();
- }
-
- const File PropertiesFile::getFile() const throw()
- {
- return file;
- }
-
- const File PropertiesFile::getDefaultAppSettingsFile (const String& applicationName,
- const String& fileNameSuffix,
- const String& folderName,
- const bool commonToAllUsers)
- {
- // mustn't have illegal characters in this name..
- jassert (applicationName == File::createLegalFileName (applicationName));
-
- #if JUCE_MAC
- File dir (commonToAllUsers ? "/Library/Preferences"
- : "~/Library/Preferences");
-
- if (folderName.isNotEmpty())
- dir = dir.getChildFile (folderName);
- #endif
-
- #ifdef JUCE_LINUX
- const File dir ((commonToAllUsers ? T("/var/") : T("~/"))
- + (folderName.isNotEmpty() ? folderName
- : (T(".") + applicationName)));
- #endif
-
- #if JUCE_WIN32
- File dir (File::getSpecialLocation (commonToAllUsers ? File::commonApplicationDataDirectory
- : File::userApplicationDataDirectory));
-
- if (dir == File::nonexistent)
- return File::nonexistent;
-
- dir = dir.getChildFile (folderName.isNotEmpty() ? folderName
- : applicationName);
-
- #endif
-
- return dir.getChildFile (applicationName)
- .withFileExtension (fileNameSuffix);
- }
-
- PropertiesFile* PropertiesFile::createDefaultAppPropertiesFile (const String& applicationName,
- const String& fileNameSuffix,
- const String& folderName,
- const bool commonToAllUsers,
- const int millisecondsBeforeSaving,
- const int propertiesFileOptions)
- {
- const File file (getDefaultAppSettingsFile (applicationName,
- fileNameSuffix,
- folderName,
- commonToAllUsers));
-
- jassert (file != File::nonexistent);
-
- if (file == File::nonexistent)
- return 0;
-
- return new PropertiesFile (file, millisecondsBeforeSaving, propertiesFileOptions);
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_PropertiesFile.cpp *********/
-
- /********* Start of inlined file: juce_AiffAudioFormat.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- #undef chunkName
- #define chunkName(a) (int)littleEndianInt(a)
-
- #define aiffFormatName TRANS("AIFF file")
- static const tchar* const aiffExtensions[] = { T(".aiff"), T(".aif"), 0 };
-
- class AiffAudioFormatReader : public AudioFormatReader
- {
- public:
- int bytesPerFrame;
- int64 dataChunkStart;
- bool littleEndian;
-
- AiffAudioFormatReader (InputStream* in)
- : AudioFormatReader (in, aiffFormatName)
- {
- if (input->readInt() == chunkName ("FORM"))
- {
- const int len = input->readIntBigEndian();
- const int64 end = input->getPosition() + len;
-
- const int nextType = input->readInt();
- if (nextType == chunkName ("AIFF") || nextType == chunkName ("AIFC"))
- {
- bool hasGotVer = false;
- bool hasGotData = false;
- bool hasGotType = false;
-
- while (input->getPosition() < end)
- {
- const int type = input->readInt();
- const uint32 length = (uint32) input->readIntBigEndian();
- const int64 chunkEnd = input->getPosition() + length;
-
- if (type == chunkName ("FVER"))
- {
- hasGotVer = true;
-
- const int ver = input->readIntBigEndian();
- if (ver != 0 && ver != (int)0xa2805140)
- break;
- }
- else if (type == chunkName ("COMM"))
- {
- hasGotType = true;
-
- numChannels = (unsigned int)input->readShortBigEndian();
- lengthInSamples = input->readIntBigEndian();
- bitsPerSample = input->readShortBigEndian();
- bytesPerFrame = (numChannels * bitsPerSample) >> 3;
-
- unsigned char sampleRateBytes[10];
- input->read (sampleRateBytes, 10);
- const int byte0 = sampleRateBytes[0];
-
- if ((byte0 & 0x80) != 0
- || byte0 <= 0x3F || byte0 > 0x40
- || (byte0 == 0x40 && sampleRateBytes[1] > 0x1C))
- break;
-
- unsigned int sampRate = bigEndianInt ((char*) sampleRateBytes + 2);
- sampRate >>= (16414 - bigEndianShort ((char*) sampleRateBytes));
- sampleRate = (int)sampRate;
-
- if (length <= 18)
- {
- // some types don't have a chunk large enough to include a compression
- // type, so assume it's just big-endian pcm
- littleEndian = false;
- }
- else
- {
- const int compType = input->readInt();
-
- if (compType == chunkName ("NONE") || compType == chunkName ("twos"))
- {
- littleEndian = false;
- }
- else if (compType == chunkName ("sowt"))
- {
- littleEndian = true;
- }
- else
- {
- sampleRate = 0;
- break;
- }
- }
- }
- else if (type == chunkName ("SSND"))
- {
- hasGotData = true;
-
- const int offset = input->readIntBigEndian();
- dataChunkStart = input->getPosition() + 4 + offset;
- lengthInSamples = (bytesPerFrame > 0) ? jmin (lengthInSamples, (int64) (length / bytesPerFrame)) : 0;
- }
- else if ((hasGotVer && hasGotData && hasGotType)
- || chunkEnd < input->getPosition()
- || input->isExhausted())
- {
- break;
- }
-
- input->setPosition (chunkEnd);
- }
- }
- }
- }
-
- ~AiffAudioFormatReader()
- {
- }
-
- bool read (int** destSamples,
- int64 startSampleInFile,
- int numSamples)
- {
- int64 start = startSampleInFile;
- int startOffsetInDestBuffer = 0;
-
- if (startSampleInFile < 0)
- {
- const int silence = (int) jmin (-startSampleInFile, (int64) numSamples);
-
- int** destChan = destSamples;
-
- for (int i = 2; --i >= 0;)
- {
- if (*destChan != 0)
- {
- zeromem (*destChan, sizeof (int) * silence);
- ++destChan;
- }
- }
-
- startOffsetInDestBuffer += silence;
- numSamples -= silence;
- start = 0;
- }
-
- int numToDo = jlimit (0, numSamples, (int) (lengthInSamples - start));
-
- if (numToDo > 0)
- {
- input->setPosition (dataChunkStart + start * bytesPerFrame);
-
- int num = numToDo;
- int* left = destSamples[0];
- if (left != 0)
- left += startOffsetInDestBuffer;
-
- int* right = destSamples[1];
- if (right != 0)
- right += startOffsetInDestBuffer;
-
- // (keep this a multiple of 3)
- const int tempBufSize = 1440 * 4;
- char tempBuffer [tempBufSize];
-
- while (num > 0)
- {
- const int numThisTime = jmin (tempBufSize / bytesPerFrame, num);
- const int bytesRead = input->read (tempBuffer, numThisTime * bytesPerFrame);
-
- if (bytesRead < numThisTime * bytesPerFrame)
- zeromem (tempBuffer + bytesRead, numThisTime * bytesPerFrame - bytesRead);
-
- if (bitsPerSample == 16)
- {
- if (littleEndian)
- {
- const short* src = (const short*) tempBuffer;
-
- if (numChannels > 1)
- {
- if (left == 0)
- {
- for (int i = numThisTime; --i >= 0;)
- {
- *right++ = (int) swapIfBigEndian ((unsigned short) *src++) << 16;
- ++src;
- }
- }
- else if (right == 0)
- {
- for (int i = numThisTime; --i >= 0;)
- {
- ++src;
- *left++ = (int) swapIfBigEndian ((unsigned short) *src++) << 16;
- }
- }
- else
- {
- for (int i = numThisTime; --i >= 0;)
- {
- *left++ = (int) swapIfBigEndian ((unsigned short) *src++) << 16;
- *right++ = (int) swapIfBigEndian ((unsigned short) *src++) << 16;
- }
- }
- }
- else
- {
- for (int i = numThisTime; --i >= 0;)
- {
- *left++ = (int) swapIfBigEndian ((unsigned short) *src++) << 16;
- }
- }
- }
- else
- {
- const char* src = (const char*) tempBuffer;
-
- if (numChannels > 1)
- {
- if (left == 0)
- {
- for (int i = numThisTime; --i >= 0;)
- {
- *right++ = bigEndianShort (src) << 16;
- src += 4;
- }
- }
- else if (right == 0)
- {
- for (int i = numThisTime; --i >= 0;)
- {
- src += 2;
- *left++ = bigEndianShort (src) << 16;
- src += 2;
- }
- }
- else
- {
- for (int i = numThisTime; --i >= 0;)
- {
- *left++ = bigEndianShort (src) << 16;
- src += 2;
- *right++ = bigEndianShort (src) << 16;
- src += 2;
- }
- }
- }
- else
- {
- for (int i = numThisTime; --i >= 0;)
- {
- *left++ = bigEndianShort (src) << 16;
- src += 2;
- }
- }
- }
- }
- else if (bitsPerSample == 24)
- {
- const char* src = (const char*)tempBuffer;
-
- if (littleEndian)
- {
- if (numChannels > 1)
- {
- if (left == 0)
- {
- for (int i = numThisTime; --i >= 0;)
- {
- *right++ = littleEndian24Bit (src) << 8;
- src += 6;
- }
- }
- else if (right == 0)
- {
- for (int i = numThisTime; --i >= 0;)
- {
- src += 3;
- *left++ = littleEndian24Bit (src) << 8;
- src += 3;
- }
- }
- else
- {
- for (int i = numThisTime; --i >= 0;)
- {
- *left++ = littleEndian24Bit (src) << 8;
- src += 3;
- *right++ = littleEndian24Bit (src) << 8;
- src += 3;
- }
- }
- }
- else
- {
- for (int i = numThisTime; --i >= 0;)
- {
- *left++ = littleEndian24Bit (src) << 8;
- src += 3;
- }
- }
- }
- else
- {
- if (numChannels > 1)
- {
- if (left == 0)
- {
- for (int i = numThisTime; --i >= 0;)
- {
- *right++ = bigEndian24Bit (src) << 8;
- src += 6;
- }
- }
- else if (right == 0)
- {
- for (int i = numThisTime; --i >= 0;)
- {
- src += 3;
- *left++ = bigEndian24Bit (src) << 8;
- src += 3;
- }
- }
- else
- {
- for (int i = numThisTime; --i >= 0;)
- {
- *left++ = bigEndian24Bit (src) << 8;
- src += 3;
- *right++ = bigEndian24Bit (src) << 8;
- src += 3;
- }
- }
- }
- else
- {
- for (int i = numThisTime; --i >= 0;)
- {
- *left++ = bigEndian24Bit (src) << 8;
- src += 3;
- }
- }
- }
- }
- else if (bitsPerSample == 32)
- {
- const unsigned int* src = (const unsigned int*) tempBuffer;
- unsigned int* l = (unsigned int*) left;
- unsigned int* r = (unsigned int*) right;
-
- if (littleEndian)
- {
- if (numChannels > 1)
- {
- if (l == 0)
- {
- for (int i = numThisTime; --i >= 0;)
- {
- ++src;
- *r++ = swapIfBigEndian (*src++);
- }
- }
- else if (r == 0)
- {
- for (int i = numThisTime; --i >= 0;)
- {
- *l++ = swapIfBigEndian (*src++);
- ++src;
- }
- }
- else
- {
- for (int i = numThisTime; --i >= 0;)
- {
- *l++ = swapIfBigEndian (*src++);
- *r++ = swapIfBigEndian (*src++);
- }
- }
- }
- else
- {
- for (int i = numThisTime; --i >= 0;)
- {
- *l++ = swapIfBigEndian (*src++);
- }
- }
- }
- else
- {
- if (numChannels > 1)
- {
- if (l == 0)
- {
- for (int i = numThisTime; --i >= 0;)
- {
- ++src;
- *r++ = swapIfLittleEndian (*src++);
- }
- }
- else if (r == 0)
- {
- for (int i = numThisTime; --i >= 0;)
- {
- *l++ = swapIfLittleEndian (*src++);
- ++src;
- }
- }
- else
- {
- for (int i = numThisTime; --i >= 0;)
- {
- *l++ = swapIfLittleEndian (*src++);
- *r++ = swapIfLittleEndian (*src++);
- }
- }
- }
- else
- {
- for (int i = numThisTime; --i >= 0;)
- {
- *l++ = swapIfLittleEndian (*src++);
- }
- }
- }
-
- left = (int*) l;
- right = (int*) r;
- }
- else if (bitsPerSample == 8)
- {
- const char* src = (const char*) tempBuffer;
-
- if (numChannels > 1)
- {
- if (left == 0)
- {
- for (int i = numThisTime; --i >= 0;)
- {
- *right++ = ((int) *src++) << 24;
- ++src;
- }
- }
- else if (right == 0)
- {
- for (int i = numThisTime; --i >= 0;)
- {
- ++src;
- *left++ = ((int) *src++) << 24;
- }
- }
- else
- {
- for (int i = numThisTime; --i >= 0;)
- {
- *left++ = ((int) *src++) << 24;
- *right++ = ((int) *src++) << 24;
- }
- }
- }
- else
- {
- for (int i = numThisTime; --i >= 0;)
- {
- *left++ = ((int) *src++) << 24;
- }
- }
- }
-
- num -= numThisTime;
- }
- }
-
- if (numToDo < numSamples)
- {
- int** destChan = destSamples;
- while (*destChan != 0)
- {
- zeromem ((*destChan) + (startOffsetInDestBuffer + numToDo),
- sizeof (int) * (numSamples - numToDo));
- ++destChan;
- }
- }
-
- return true;
- }
-
- juce_UseDebuggingNewOperator
-
- private:
- AiffAudioFormatReader (const AiffAudioFormatReader&);
- const AiffAudioFormatReader& operator= (const AiffAudioFormatReader&);
- };
-
- class AiffAudioFormatWriter : public AudioFormatWriter
- {
- MemoryBlock tempBlock;
- uint32 lengthInSamples, bytesWritten;
- int64 headerPosition;
- bool writeFailed;
-
- AiffAudioFormatWriter (const AiffAudioFormatWriter&);
- const AiffAudioFormatWriter& operator= (const AiffAudioFormatWriter&);
-
- void writeHeader()
- {
- const bool couldSeekOk = output->setPosition (headerPosition);
- (void) couldSeekOk;
-
- // if this fails, you've given it an output stream that can't seek! It needs
- // to be able to seek back to write the header
- jassert (couldSeekOk);
-
- const int headerLen = 54;
- int audioBytes = lengthInSamples * ((bitsPerSample * numChannels) / 8);
- audioBytes += (audioBytes & 1);
-
- output->writeInt (chunkName ("FORM"));
- output->writeIntBigEndian (headerLen + audioBytes - 8);
- output->writeInt (chunkName ("AIFF"));
- output->writeInt (chunkName ("COMM"));
- output->writeIntBigEndian (18);
- output->writeShortBigEndian ((short) numChannels);
- output->writeIntBigEndian (lengthInSamples);
- output->writeShortBigEndian ((short) bitsPerSample);
-
- uint8 sampleRateBytes[10];
- zeromem (sampleRateBytes, 10);
-
- if (sampleRate <= 1)
- {
- sampleRateBytes[0] = 0x3f;
- sampleRateBytes[1] = 0xff;
- sampleRateBytes[2] = 0x80;
- }
- else
- {
- int mask = 0x40000000;
- sampleRateBytes[0] = 0x40;
-
- if (sampleRate >= mask)
- {
- jassertfalse
- sampleRateBytes[1] = 0x1d;
- }
- else
- {
- int n = (int) sampleRate;
-
- int i;
- for (i = 0; i <= 32 ; ++i)
- {
- if ((n & mask) != 0)
- break;
-
- mask >>= 1;
- }
-
- n = n << (i + 1);
-
- sampleRateBytes[1] = (uint8) (29 - i);
- sampleRateBytes[2] = (uint8) ((n >> 24) & 0xff);
- sampleRateBytes[3] = (uint8) ((n >> 16) & 0xff);
- sampleRateBytes[4] = (uint8) ((n >> 8) & 0xff);
- sampleRateBytes[5] = (uint8) (n & 0xff);
- }
- }
-
- output->write (sampleRateBytes, 10);
-
- output->writeInt (chunkName ("SSND"));
- output->writeIntBigEndian (audioBytes + 8);
- output->writeInt (0);
- output->writeInt (0);
-
- jassert (output->getPosition() == headerLen);
- }
-
- public:
-
- AiffAudioFormatWriter (OutputStream* out,
- const double sampleRate,
- const unsigned int chans,
- const int bits)
- : AudioFormatWriter (out,
- aiffFormatName,
- sampleRate,
- chans,
- bits),
- lengthInSamples (0),
- bytesWritten (0),
- writeFailed (false)
- {
- headerPosition = out->getPosition();
- writeHeader();
- }
-
- ~AiffAudioFormatWriter()
- {
- if ((bytesWritten & 1) != 0)
- output->writeByte (0);
-
- writeHeader();
- }
-
- bool write (const int** data, int numSamples)
- {
- if (writeFailed)
- return false;
-
- const int bytes = numChannels * numSamples * bitsPerSample / 8;
- tempBlock.ensureSize (bytes, false);
- char* buffer = (char*) tempBlock.getData();
-
- const int* left = data[0];
- const int* right = data[1];
- if (right == 0)
- right = left;
-
- if (bitsPerSample == 16)
- {
- short* b = (short*) buffer;
-
- if (numChannels > 1)
- {
- for (int i = numSamples; --i >= 0;)
- {
- *b++ = (short) swapIfLittleEndian ((unsigned short) (*left++ >> 16));
- *b++ = (short) swapIfLittleEndian ((unsigned short) (*right++ >> 16));
- }
- }
- else
- {
- for (int i = numSamples; --i >= 0;)
- {
- *b++ = (short) swapIfLittleEndian ((unsigned short) (*left++ >> 16));
- }
- }
- }
- else if (bitsPerSample == 24)
- {
- char* b = (char*) buffer;
-
- if (numChannels > 1)
- {
- for (int i = numSamples; --i >= 0;)
- {
- bigEndian24BitToChars (*left++ >> 8, b);
- b += 3;
- bigEndian24BitToChars (*right++ >> 8, b);
- b += 3;
- }
- }
- else
- {
- for (int i = numSamples; --i >= 0;)
- {
- bigEndian24BitToChars (*left++ >> 8, b);
- b += 3;
- }
- }
- }
- else if (bitsPerSample == 32)
- {
- unsigned int* b = (unsigned int*) buffer;
-
- if (numChannels > 1)
- {
- for (int i = numSamples; --i >= 0;)
- {
- *b++ = swapIfLittleEndian ((unsigned int) *left++);
- *b++ = swapIfLittleEndian ((unsigned int) *right++);
- }
- }
- else
- {
- for (int i = numSamples; --i >= 0;)
- {
- *b++ = swapIfLittleEndian ((unsigned int) *left++);
- }
- }
- }
- else if (bitsPerSample == 8)
- {
- char* b = (char*)buffer;
-
- if (numChannels > 1)
- {
- for (int i = numSamples; --i >= 0;)
- {
- *b++ = (char) (*left++ >> 24);
- *b++ = (char) (*right++ >> 24);
- }
- }
- else
- {
- for (int i = numSamples; --i >= 0;)
- {
- *b++ = (char) (*left++ >> 24);
- }
- }
- }
-
- if (bytesWritten + bytes >= (uint32) 0xfff00000
- || ! output->write (buffer, bytes))
- {
- // failed to write to disk, so let's try writing the header.
- // If it's just run out of disk space, then if it does manage
- // to write the header, we'll still have a useable file..
- writeHeader();
- writeFailed = true;
- return false;
- }
- else
- {
- bytesWritten += bytes;
- lengthInSamples += numSamples;
-
- return true;
- }
- }
-
- juce_UseDebuggingNewOperator
- };
-
- AiffAudioFormat::AiffAudioFormat()
- : AudioFormat (aiffFormatName, (const tchar**) aiffExtensions)
- {
- }
-
- AiffAudioFormat::~AiffAudioFormat()
- {
- }
-
- const Array <int> AiffAudioFormat::getPossibleSampleRates()
- {
- const int rates[] = { 22050, 32000, 44100, 48000, 88200, 96000, 176400, 192000, 0 };
- return Array <int> (rates);
- }
-
- const Array <int> AiffAudioFormat::getPossibleBitDepths()
- {
- const int depths[] = { 8, 16, 24, 0 };
- return Array <int> (depths);
- }
-
- bool AiffAudioFormat::canDoStereo()
- {
- return true;
- }
-
- bool AiffAudioFormat::canDoMono()
- {
- return true;
- }
-
- #if JUCE_MAC
- bool AiffAudioFormat::canHandleFile (const File& f)
- {
- if (AudioFormat::canHandleFile (f))
- return true;
-
- const OSType type = PlatformUtilities::getTypeOfFile (f.getFullPathName());
- return type == 'AIFF' || type == 'AIFC'
- || type == 'aiff' || type == 'aifc';
- }
- #endif
-
- AudioFormatReader* AiffAudioFormat::createReaderFor (InputStream* sourceStream,
- const bool deleteStreamIfOpeningFails)
- {
- AiffAudioFormatReader* w = new AiffAudioFormatReader (sourceStream);
-
- if (w->sampleRate == 0)
- {
- if (! deleteStreamIfOpeningFails)
- w->input = 0;
-
- deleteAndZero (w);
- }
-
- return w;
- }
-
- AudioFormatWriter* AiffAudioFormat::createWriterFor (OutputStream* out,
- double sampleRate,
- unsigned int chans,
- int bitsPerSample,
- const StringPairArray& /*metadataValues*/,
- int /*qualityOptionIndex*/)
- {
- if (getPossibleBitDepths().contains (bitsPerSample))
- {
- return new AiffAudioFormatWriter (out,
- sampleRate,
- chans,
- bitsPerSample);
- }
-
- return 0;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_AiffAudioFormat.cpp *********/
-
- /********* Start of inlined file: juce_AudioCDReader.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- #if JUCE_MAC
-
- // Mac version doesn't need any native code because it's all done with files..
- // Windows + Linux versions are in the platform-dependent code sections.
-
- static void findCDs (OwnedArray<File>& cds)
- {
- File volumes ("/Volumes");
- volumes.findChildFiles (cds, File::findDirectories, false);
-
- for (int i = cds.size(); --i >= 0;)
- if (! cds[i]->getChildFile (".TOC.plist").exists())
- cds.remove (i);
- }
-
- const StringArray AudioCDReader::getAvailableCDNames()
- {
- OwnedArray<File> cds;
- findCDs (cds);
-
- StringArray names;
-
- for (int i = 0; i < cds.size(); ++i)
- names.add (cds[i]->getFileName());
-
- return names;
- }
-
- AudioCDReader* AudioCDReader::createReaderForCD (const int index)
- {
- OwnedArray<File> cds;
- findCDs (cds);
-
- if (cds[index] != 0)
- return new AudioCDReader (*cds[index]);
- else
- return 0;
- }
-
- AudioCDReader::AudioCDReader (const File& volume)
- : AudioFormatReader (0, "CD Audio"),
- volumeDir (volume),
- currentReaderTrack (-1),
- reader (0)
- {
- sampleRate = 44100.0;
- bitsPerSample = 16;
- numChannels = 2;
- usesFloatingPointData = false;
-
- refreshTrackLengths();
- }
-
- AudioCDReader::~AudioCDReader()
- {
- if (reader != 0)
- delete reader;
- }
-
- static int getTrackNumber (const File& file)
- {
- return file.getFileName()
- .initialSectionContainingOnly (T("0123456789"))
- .getIntValue();
- }
-
- int AudioCDReader::compareElements (const File* const first, const File* const second) throw()
- {
- const int firstTrack = getTrackNumber (*first);
- const int secondTrack = getTrackNumber (*second);
-
- jassert (firstTrack > 0 && secondTrack > 0);
-
- return firstTrack - secondTrack;
- }
-
- void AudioCDReader::refreshTrackLengths()
- {
- tracks.clear();
- trackStartSamples.clear();
- volumeDir.findChildFiles (tracks, File::findFiles | File::ignoreHiddenFiles, false, T("*.aiff"));
-
- tracks.sort (*this);
-
- AiffAudioFormat format;
- int sample = 0;
-
- for (int i = 0; i < tracks.size(); ++i)
- {
- trackStartSamples.add (sample);
-
- FileInputStream* const in = tracks[i]->createInputStream();
-
- if (in != 0)
- {
- AudioFormatReader* const r = format.createReaderFor (in, true);
-
- if (r != 0)
- {
- sample += r->lengthInSamples;
- delete r;
- }
- }
- }
-
- trackStartSamples.add (sample);
- lengthInSamples = sample;
- }
-
- bool AudioCDReader::read (int** destSamples,
- int64 startSampleInFile,
- int numSamples)
- {
- while (numSamples > 0)
- {
- int track = -1;
-
- for (int i = 0; i < trackStartSamples.size() - 1; ++i)
- {
- if (startSampleInFile < trackStartSamples.getUnchecked (i + 1))
- {
- track = i;
- break;
- }
- }
-
- if (track < 0)
- return false;
-
- if (track != currentReaderTrack)
- {
- deleteAndZero (reader);
-
- if (tracks [track] != 0)
- {
- FileInputStream* const in = tracks [track]->createInputStream();
-
- if (in != 0)
- {
- BufferedInputStream* const bin = new BufferedInputStream (in, 65536, true);
-
- AiffAudioFormat format;
- reader = format.createReaderFor (bin, true);
-
- if (reader == 0)
- currentReaderTrack = -1;
- else
- currentReaderTrack = track;
- }
- }
- }
-
- if (reader == 0)
- return false;
-
- const int startPos = (int) (startSampleInFile - trackStartSamples.getUnchecked (track));
- const int numAvailable = (int) jmin ((int64) numSamples, reader->lengthInSamples - startPos);
-
- reader->read (destSamples, startPos, numAvailable);
-
- numSamples -= numAvailable;
- startSampleInFile += numAvailable;
- }
-
- return true;
- }
-
- bool AudioCDReader::isCDStillPresent() const
- {
- return volumeDir.exists();
- }
-
- int AudioCDReader::getNumTracks() const
- {
- return tracks.size();
- }
-
- int AudioCDReader::getPositionOfTrackStart (int trackNum) const
- {
- return trackStartSamples [trackNum];
- }
-
- bool AudioCDReader::isTrackAudio (int trackNum) const
- {
- return tracks [trackNum] != 0;
- }
-
- void AudioCDReader::enableIndexScanning (bool b)
- {
- // any way to do this on a Mac??
- }
-
- int AudioCDReader::getLastIndex() const
- {
- return 0;
- }
-
- const Array <int> AudioCDReader::findIndexesInTrack (const int trackNumber)
- {
- return Array <int>();
- }
-
- int AudioCDReader::getCDDBId()
- {
- return 0; //xxx
- }
-
- #endif
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_AudioCDReader.cpp *********/
-
- /********* Start of inlined file: juce_AudioFormat.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- AudioFormatReader::AudioFormatReader (InputStream* const in,
- const String& formatName_)
- : sampleRate (0),
- bitsPerSample (0),
- lengthInSamples (0),
- numChannels (0),
- usesFloatingPointData (false),
- input (in),
- formatName (formatName_)
- {
- }
-
- AudioFormatReader::~AudioFormatReader()
- {
- delete input;
- }
-
- static void findMaxMin (const float* src, const int num,
- float& maxVal, float& minVal)
- {
- float mn = src[0];
- float mx = mn;
-
- for (int i = 1; i < num; ++i)
- {
- const float s = src[i];
- if (s > mx)
- mx = s;
- if (s < mn)
- mn = s;
- }
-
- maxVal = mx;
- minVal = mn;
- }
-
- void AudioFormatReader::readMaxLevels (int64 startSampleInFile,
- int64 numSamples,
- float& lowestLeft, float& highestLeft,
- float& lowestRight, float& highestRight)
- {
- if (numSamples <= 0)
- {
- lowestLeft = 0;
- lowestRight = 0;
- highestLeft = 0;
- highestRight = 0;
- return;
- }
-
- const int bufferSize = (int) jmin (numSamples, (int64) 4096);
- MemoryBlock tempSpace (bufferSize * sizeof (int) * 2 + 64);
-
- int* tempBuffer[3];
- tempBuffer[0] = (int*) tempSpace.getData();
- tempBuffer[1] = ((int*) tempSpace.getData()) + bufferSize;
- tempBuffer[2] = 0;
-
- if (usesFloatingPointData)
- {
- float lmin = 1.0e6;
- float lmax = -lmin;
- float rmin = lmin;
- float rmax = lmax;
-
- while (numSamples > 0)
- {
- const int numToDo = (int) jmin (numSamples, (int64) bufferSize);
- read ((int**) tempBuffer, startSampleInFile, numToDo);
-
- numSamples -= numToDo;
-
- float bufmin, bufmax;
- findMaxMin ((float*) tempBuffer[0], numToDo, bufmax, bufmin);
- lmin = jmin (lmin, bufmin);
- lmax = jmax (lmax, bufmax);
-
- if (numChannels > 1)
- {
- findMaxMin ((float*) tempBuffer[1], numToDo, bufmax, bufmin);
- rmin = jmin (rmin, bufmin);
- rmax = jmax (rmax, bufmax);
- }
- }
-
- if (numChannels <= 1)
- {
- rmax = lmax;
- rmin = lmin;
- }
-
- lowestLeft = lmin;
- highestLeft = lmax;
- lowestRight = rmin;
- highestRight = rmax;
- }
- else
- {
- int lmax = INT_MIN;
- int lmin = INT_MAX;
- int rmax = INT_MIN;
- int rmin = INT_MAX;
-
- while (numSamples > 0)
- {
- const int numToDo = (int) jmin (numSamples, (int64) bufferSize);
- read ((int**) tempBuffer, startSampleInFile, numToDo);
-
- numSamples -= numToDo;
-
- for (int j = numChannels; --j >= 0;)
- {
- int bufMax = INT_MIN;
- int bufMin = INT_MAX;
-
- const int* const b = tempBuffer[j];
-
- for (int i = 0; i < numToDo; ++i)
- {
- const int samp = b[i];
-
- if (samp < bufMin)
- bufMin = samp;
-
- if (samp > bufMax)
- bufMax = samp;
- }
-
- if (j == 0)
- {
- lmax = jmax (lmax, bufMax);
- lmin = jmin (lmin, bufMin);
- }
- else
- {
- rmax = jmax (rmax, bufMax);
- rmin = jmin (rmin, bufMin);
- }
- }
- }
-
- if (numChannels <= 1)
- {
- rmax = lmax;
- rmin = lmin;
- }
-
- lowestLeft = lmin / (float)INT_MAX;
- highestLeft = lmax / (float)INT_MAX;
- lowestRight = rmin / (float)INT_MAX;
- highestRight = rmax / (float)INT_MAX;
- }
- }
-
- int64 AudioFormatReader::searchForLevel (int64 startSample,
- int64 numSamplesToSearch,
- const double magnitudeRangeMinimum,
- const double magnitudeRangeMaximum,
- const int minimumConsecutiveSamples)
- {
- if (numSamplesToSearch == 0)
- return -1;
-
- const int bufferSize = 4096;
- MemoryBlock tempSpace (bufferSize * sizeof (int) * 2 + 64);
-
- int* tempBuffer[3];
- tempBuffer[0] = (int*) tempSpace.getData();
- tempBuffer[1] = ((int*) tempSpace.getData()) + bufferSize;
- tempBuffer[2] = 0;
-
- int consecutive = 0;
- int64 firstMatchPos = -1;
-
- jassert (magnitudeRangeMaximum > magnitudeRangeMinimum);
-
- const double doubleMin = jlimit (0.0, (double) INT_MAX, magnitudeRangeMinimum * INT_MAX);
- const double doubleMax = jlimit (doubleMin, (double) INT_MAX, magnitudeRangeMaximum * INT_MAX);
- const int intMagnitudeRangeMinimum = roundDoubleToInt (doubleMin);
- const int intMagnitudeRangeMaximum = roundDoubleToInt (doubleMax);
-
- while (numSamplesToSearch != 0)
- {
- const int numThisTime = (int) jmin (abs64 (numSamplesToSearch), (int64) bufferSize);
- int64 bufferStart = startSample;
-
- if (numSamplesToSearch < 0)
- bufferStart -= numThisTime;
-
- if (bufferStart >= (int) lengthInSamples)
- break;
-
- read ((int**) tempBuffer, bufferStart, numThisTime);
-
- int num = numThisTime;
- while (--num >= 0)
- {
- if (numSamplesToSearch < 0)
- --startSample;
-
- bool matches = false;
- const int index = (int) (startSample - bufferStart);
-
- if (usesFloatingPointData)
- {
- const float sample1 = fabsf (((float*) tempBuffer[0]) [index]);
-
- if (sample1 >= magnitudeRangeMinimum
- && sample1 <= magnitudeRangeMaximum)
- {
- matches = true;
- }
- else if (numChannels > 1)
- {
- const float sample2 = fabsf (((float*) tempBuffer[1]) [index]);
-
- matches = (sample2 >= magnitudeRangeMinimum
- && sample2 <= magnitudeRangeMaximum);
- }
- }
- else
- {
- const int sample1 = abs (tempBuffer[0] [index]);
-
- if (sample1 >= intMagnitudeRangeMinimum
- && sample1 <= intMagnitudeRangeMaximum)
- {
- matches = true;
- }
- else if (numChannels > 1)
- {
- const int sample2 = abs (tempBuffer[1][index]);
-
- matches = (sample2 >= intMagnitudeRangeMinimum
- && sample2 <= intMagnitudeRangeMaximum);
- }
- }
-
- if (matches)
- {
- if (firstMatchPos < 0)
- firstMatchPos = startSample;
-
- if (++consecutive >= minimumConsecutiveSamples)
- {
- if (firstMatchPos < 0 || firstMatchPos >= lengthInSamples)
- return -1;
-
- return firstMatchPos;
- }
- }
- else
- {
- consecutive = 0;
- firstMatchPos = -1;
- }
-
- if (numSamplesToSearch > 0)
- ++startSample;
- }
-
- if (numSamplesToSearch > 0)
- numSamplesToSearch -= numThisTime;
- else
- numSamplesToSearch += numThisTime;
- }
-
- return -1;
- }
-
- AudioFormatWriter::AudioFormatWriter (OutputStream* const out,
- const String& formatName_,
- const double rate,
- const unsigned int numChannels_,
- const unsigned int bitsPerSample_)
- : sampleRate (rate),
- numChannels (numChannels_),
- bitsPerSample (bitsPerSample_),
- usesFloatingPointData (false),
- output (out),
- formatName (formatName_)
- {
- }
-
- AudioFormatWriter::~AudioFormatWriter()
- {
- delete output;
- }
-
- bool AudioFormatWriter::writeFromAudioReader (AudioFormatReader& reader,
- int64 startSample,
- int numSamplesToRead)
- {
- const int bufferSize = 16384;
- const int maxChans = 128;
- AudioSampleBuffer tempBuffer (reader.numChannels, bufferSize);
- int* buffers [maxChans];
-
- for (int i = maxChans; --i >= 0;)
- buffers[i] = 0;
-
- while (numSamplesToRead > 0)
- {
- const int numToDo = jmin (numSamplesToRead, bufferSize);
-
- for (int i = tempBuffer.getNumChannels(); --i >= 0;)
- buffers[i] = (int*) tempBuffer.getSampleData (i, 0);
-
- if (! reader.read (buffers, startSample, numToDo))
- return false;
-
- if (reader.usesFloatingPointData != isFloatingPoint())
- {
- int** bufferChan = buffers;
-
- while (*bufferChan != 0)
- {
- int* b = *bufferChan++;
-
- if (isFloatingPoint())
- {
- // int -> float
- const double factor = 1.0 / INT_MAX;
-
- for (int i = 0; i < numToDo; ++i)
- ((float*)b)[i] = (float) (factor * b[i]);
- }
- else
- {
- // float -> int
- for (int i = 0; i < numToDo; ++i)
- {
- const double samp = *(const float*) b;
-
- if (samp <= -1.0)
- *b++ = INT_MIN;
- else if (samp >= 1.0)
- *b++ = INT_MAX;
- else
- *b++ = roundDoubleToInt (INT_MAX * samp);
- }
- }
- }
- }
-
- if (! write ((const int**) buffers, numToDo))
- return false;
-
- numSamplesToRead -= numToDo;
- startSample += numToDo;
- }
-
- return true;
- }
-
- bool AudioFormatWriter::writeFromAudioSource (AudioSource& source,
- int numSamplesToRead,
- const int samplesPerBlock)
- {
- const int maxChans = 128;
- AudioSampleBuffer tempBuffer (getNumChannels(), samplesPerBlock);
- int* buffers [maxChans];
-
- while (numSamplesToRead > 0)
- {
- const int numToDo = jmin (numSamplesToRead, samplesPerBlock);
-
- AudioSourceChannelInfo info;
- info.buffer = &tempBuffer;
- info.startSample = 0;
- info.numSamples = numToDo;
- info.clearActiveBufferRegion();
-
- source.getNextAudioBlock (info);
-
- int i;
- for (i = maxChans; --i >= 0;)
- buffers[i] = 0;
-
- for (i = tempBuffer.getNumChannels(); --i >= 0;)
- buffers[i] = (int*) tempBuffer.getSampleData (i, 0);
-
- if (! isFloatingPoint())
- {
- int** bufferChan = buffers;
-
- while (*bufferChan != 0)
- {
- int* b = *bufferChan++;
-
- // float -> int
- for (int j = numToDo; --j >= 0;)
- {
- const double samp = *(const float*) b;
-
- if (samp <= -1.0)
- *b++ = INT_MIN;
- else if (samp >= 1.0)
- *b++ = INT_MAX;
- else
- *b++ = roundDoubleToInt (INT_MAX * samp);
- }
- }
- }
-
- if (! write ((const int**) buffers, numToDo))
- return false;
-
- numSamplesToRead -= numToDo;
- }
-
- return true;
- }
-
- AudioFormat::AudioFormat (const String& name,
- const tchar** const extensions)
- : formatName (name),
- fileExtensions (extensions)
- {
- }
-
- AudioFormat::~AudioFormat()
- {
- }
-
- const String& AudioFormat::getFormatName() const
- {
- return formatName;
- }
-
- const StringArray& AudioFormat::getFileExtensions() const
- {
- return fileExtensions;
- }
-
- bool AudioFormat::canHandleFile (const File& f)
- {
- for (int i = 0; i < fileExtensions.size(); ++i)
- if (f.hasFileExtension (fileExtensions[i]))
- return true;
-
- return false;
- }
-
- bool AudioFormat::isCompressed()
- {
- return false;
- }
-
- const StringArray AudioFormat::getQualityOptions()
- {
- return StringArray();
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_AudioFormat.cpp *********/
-
- /********* Start of inlined file: juce_AudioFormatManager.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- AudioFormatManager::AudioFormatManager()
- : knownFormats (4),
- defaultFormatIndex (0)
- {
- }
-
- AudioFormatManager::~AudioFormatManager()
- {
- clearFormats();
- clearSingletonInstance();
- }
-
- juce_ImplementSingleton (AudioFormatManager);
-
- void AudioFormatManager::registerFormat (AudioFormat* newFormat,
- const bool makeThisTheDefaultFormat)
- {
- jassert (newFormat != 0);
-
- if (newFormat != 0)
- {
- #ifdef JUCE_DEBUG
- for (int i = getNumKnownFormats(); --i >= 0;)
- {
- if (getKnownFormat (i)->getFormatName() == newFormat->getFormatName())
- {
- jassertfalse // trying to add the same format twice!
- }
- }
- #endif
-
- if (makeThisTheDefaultFormat)
- defaultFormatIndex = knownFormats.size();
-
- knownFormats.add (newFormat);
- }
- }
-
- void AudioFormatManager::registerBasicFormats()
- {
- #if JUCE_MAC
- registerFormat (new AiffAudioFormat(), true);
- registerFormat (new WavAudioFormat(), false);
- #else
- registerFormat (new WavAudioFormat(), true);
- registerFormat (new AiffAudioFormat(), false);
- #endif
-
- #if JUCE_USE_FLAC
- registerFormat (new FlacAudioFormat(), false);
- #endif
-
- #if JUCE_USE_OGGVORBIS
- registerFormat (new OggVorbisAudioFormat(), false);
- #endif
- }
-
- void AudioFormatManager::clearFormats()
- {
- for (int i = getNumKnownFormats(); --i >= 0;)
- {
- AudioFormat* const af = getKnownFormat(i);
- delete af;
- }
-
- knownFormats.clear();
- defaultFormatIndex = 0;
- }
-
- int AudioFormatManager::getNumKnownFormats() const
- {
- return knownFormats.size();
- }
-
- AudioFormat* AudioFormatManager::getKnownFormat (const int index) const
- {
- return (AudioFormat*) knownFormats [index];
- }
-
- AudioFormat* AudioFormatManager::getDefaultFormat() const
- {
- return getKnownFormat (defaultFormatIndex);
- }
-
- AudioFormat* AudioFormatManager::findFormatForFileExtension (const String& fileExtension) const
- {
- String e (fileExtension);
- if (! e.startsWithChar (T('.')))
- e = T(".") + e;
-
- for (int i = 0; i < getNumKnownFormats(); ++i)
- if (getKnownFormat(i)->getFileExtensions().contains (e, true))
- return getKnownFormat(i);
-
- return 0;
- }
-
- const String AudioFormatManager::getWildcardForAllFormats() const
- {
- StringArray allExtensions;
-
- int i;
- for (i = 0; i < getNumKnownFormats(); ++i)
- allExtensions.addArray (getKnownFormat (i)->getFileExtensions());
-
- allExtensions.trim();
- allExtensions.removeEmptyStrings();
-
- String s;
- for (i = 0; i < allExtensions.size(); ++i)
- {
- s << T('*');
-
- if (! allExtensions[i].startsWithChar (T('.')))
- s << T('.');
-
- s << allExtensions[i];
-
- if (i < allExtensions.size() - 1)
- s << T(';');
- }
-
- return s;
- }
-
- AudioFormatReader* AudioFormatManager::createReaderFor (const File& file)
- {
- // you need to actually register some formats before the manager can
- // use them to open a file!
- jassert (knownFormats.size() > 0);
-
- for (int i = 0; i < getNumKnownFormats(); ++i)
- {
- AudioFormat* const af = getKnownFormat(i);
-
- if (af->canHandleFile (file))
- {
- InputStream* const in = file.createInputStream();
-
- if (in != 0)
- {
- AudioFormatReader* const r = af->createReaderFor (in, true);
-
- if (r != 0)
- return r;
- }
- }
- }
-
- return 0;
- }
-
- AudioFormatReader* AudioFormatManager::createReaderFor (InputStream* in)
- {
- // you need to actually register some formats before the manager can
- // use them to open a file!
- jassert (knownFormats.size() > 0);
-
- if (in != 0)
- {
- const int64 originalStreamPos = in->getPosition();
-
- for (int i = 0; i < getNumKnownFormats(); ++i)
- {
- AudioFormatReader* const r = getKnownFormat(i)->createReaderFor (in, false);
-
- if (r != 0)
- return r;
-
- in->setPosition (originalStreamPos);
-
- // the stream that is passed-in must be capable of being repositioned so
- // that all the formats can have a go at opening it.
- jassert (in->getPosition() == originalStreamPos);
- }
-
- delete in;
- }
-
- return 0;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_AudioFormatManager.cpp *********/
-
- /********* Start of inlined file: juce_AudioSubsectionReader.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- AudioSubsectionReader::AudioSubsectionReader (AudioFormatReader* const source_,
- const int64 startSample_,
- const int64 length_,
- const bool deleteSourceWhenDeleted_)
- : AudioFormatReader (0, source_->getFormatName()),
- source (source_),
- startSample (startSample_),
- deleteSourceWhenDeleted (deleteSourceWhenDeleted_)
- {
- length = jmin (jmax ((int64) 0, source->lengthInSamples - startSample), length_);
-
- sampleRate = source->sampleRate;
- bitsPerSample = source->bitsPerSample;
- lengthInSamples = length;
- numChannels = source->numChannels;
- usesFloatingPointData = source->usesFloatingPointData;
- }
-
- AudioSubsectionReader::~AudioSubsectionReader()
- {
- if (deleteSourceWhenDeleted)
- delete source;
- }
-
- bool AudioSubsectionReader::read (int** destSamples,
- int64 startSampleInFile,
- int numSamples)
- {
- if (startSampleInFile < 0 || startSampleInFile + numSamples > length)
- {
- int** d = destSamples;
- while (*d != 0)
- {
- zeromem (*d, sizeof (int) * numSamples);
- ++d;
- }
-
- startSampleInFile = jmax ((int64) 0, startSampleInFile);
- numSamples = jmax (0, jmin (numSamples, (int) (length - startSampleInFile)));
- }
-
- return source->read (destSamples,
- startSampleInFile + startSample,
- numSamples);
- }
-
- void AudioSubsectionReader::readMaxLevels (int64 startSampleInFile,
- int64 numSamples,
- float& lowestLeft,
- float& highestLeft,
- float& lowestRight,
- float& highestRight)
- {
- startSampleInFile = jmax ((int64) 0, startSampleInFile);
- numSamples = jmax ((int64) 0, jmin (numSamples, length - startSampleInFile));
-
- source->readMaxLevels (startSampleInFile + startSample,
- numSamples,
- lowestLeft,
- highestLeft,
- lowestRight,
- highestRight);
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_AudioSubsectionReader.cpp *********/
-
- /********* Start of inlined file: juce_AudioThumbnail.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- const int timeBeforeDeletingReader = 2000;
-
- struct AudioThumbnailDataFormat
- {
- char thumbnailMagic[4];
- int samplesPerThumbSample;
- int64 totalSamples; // source samples
- int64 numFinishedSamples; // source samples
- int numThumbnailSamples;
- int numChannels;
- int sampleRate;
- char future[16];
- char data[1];
- };
-
- #if JUCE_BIG_ENDIAN
- static void swap (int& n) { n = (int) swapByteOrder ((uint32) n); }
- static void swap (int64& n) { n = (int64) swapByteOrder ((uint64) n); }
- #endif
-
- static void swapEndiannessIfNeeded (AudioThumbnailDataFormat* const d)
- {
- (void) d;
-
- #if JUCE_BIG_ENDIAN
- swap (d->samplesPerThumbSample);
- swap (d->totalSamples);
- swap (d->numFinishedSamples);
- swap (d->numThumbnailSamples);
- swap (d->numChannels);
- swap (d->sampleRate);
- #endif
- }
-
- AudioThumbnail::AudioThumbnail (const int orginalSamplesPerThumbnailSample_,
- AudioFormatManager& formatManagerToUse_,
- AudioThumbnailCache& cacheToUse)
- : formatManagerToUse (formatManagerToUse_),
- cache (cacheToUse),
- source (0),
- reader (0),
- orginalSamplesPerThumbnailSample (orginalSamplesPerThumbnailSample_)
- {
- clear();
- }
-
- AudioThumbnail::~AudioThumbnail()
- {
- cache.removeThumbnail (this);
-
- const ScopedLock sl (readerLock);
- deleteAndZero (reader);
-
- delete source;
- }
-
- void AudioThumbnail::setSource (InputSource* const newSource)
- {
- cache.removeThumbnail (this);
- timerCallback(); // stops the timer and deletes the reader
-
- delete source;
- source = newSource;
-
- clear();
-
- if (! (cache.loadThumb (*this, newSource->hashCode())
- && isFullyLoaded()))
- {
- {
- const ScopedLock sl (readerLock);
- reader = createReader();
- }
-
- if (reader != 0)
- {
- initialiseFromAudioFile (*reader);
- cache.addThumbnail (this);
- }
- }
-
- sendChangeMessage (this);
- }
-
- bool AudioThumbnail::useTimeSlice()
- {
- const ScopedLock sl (readerLock);
-
- if (isFullyLoaded())
- {
- if (reader != 0)
- startTimer (timeBeforeDeletingReader);
-
- cache.removeThumbnail (this);
- return false;
- }
-
- if (reader == 0)
- reader = createReader();
-
- if (reader != 0)
- {
- readNextBlockFromAudioFile (*reader);
- stopTimer();
-
- sendChangeMessage (this);
-
- const bool justFinished = isFullyLoaded();
-
- if (justFinished)
- cache.storeThumb (*this, source->hashCode());
-
- return ! justFinished;
- }
-
- return false;
- }
-
- AudioFormatReader* AudioThumbnail::createReader() const
- {
- if (source != 0)
- {
- InputStream* const audioFileStream = source->createInputStream();
-
- if (audioFileStream != 0)
- return formatManagerToUse.createReaderFor (audioFileStream);
- }
-
- return 0;
- }
-
- void AudioThumbnail::timerCallback()
- {
- stopTimer();
-
- const ScopedLock sl (readerLock);
- deleteAndZero (reader);
- }
-
- void AudioThumbnail::clear()
- {
- data.setSize (sizeof (AudioThumbnailDataFormat) + 3);
-
- AudioThumbnailDataFormat* const d = (AudioThumbnailDataFormat*) data.getData();
-
- d->thumbnailMagic[0] = 'j';
- d->thumbnailMagic[1] = 'a';
- d->thumbnailMagic[2] = 't';
- d->thumbnailMagic[3] = 'm';
-
- d->samplesPerThumbSample = orginalSamplesPerThumbnailSample;
- d->totalSamples = 0;
- d->numFinishedSamples = 0;
- d->numThumbnailSamples = 0;
- d->numChannels = 0;
- d->sampleRate = 0;
-
- numSamplesCached = 0;
- cacheNeedsRefilling = true;
- }
-
- void AudioThumbnail::loadFrom (InputStream& input)
- {
- data.setSize (0);
- input.readIntoMemoryBlock (data);
-
- AudioThumbnailDataFormat* const d = (AudioThumbnailDataFormat*) data.getData();
- swapEndiannessIfNeeded (d);
-
- if (! (d->thumbnailMagic[0] == 'j'
- && d->thumbnailMagic[1] == 'a'
- && d->thumbnailMagic[2] == 't'
- && d->thumbnailMagic[3] == 'm'))
- {
- clear();
- }
-
- numSamplesCached = 0;
- cacheNeedsRefilling = true;
- }
-
- void AudioThumbnail::saveTo (OutputStream& output) const
- {
- AudioThumbnailDataFormat* const d = (AudioThumbnailDataFormat*) data.getData();
- swapEndiannessIfNeeded (d);
- output.write (data.getData(), data.getSize());
- swapEndiannessIfNeeded (d);
- }
-
- bool AudioThumbnail::initialiseFromAudioFile (AudioFormatReader& reader)
- {
- AudioThumbnailDataFormat* d = (AudioThumbnailDataFormat*) data.getData();
-
- d->totalSamples = reader.lengthInSamples;
- d->numChannels = jmin (2, reader.numChannels);
- d->numFinishedSamples = 0;
- d->sampleRate = roundDoubleToInt (reader.sampleRate);
- d->numThumbnailSamples = (int) (d->totalSamples / d->samplesPerThumbSample) + 1;
-
- data.setSize (sizeof (AudioThumbnailDataFormat) + 3 + d->numThumbnailSamples * d->numChannels * 2);
-
- d = (AudioThumbnailDataFormat*) data.getData();
- zeromem (&(d->data[0]), d->numThumbnailSamples * d->numChannels * 2);
-
- return d->totalSamples > 0;
- }
-
- bool AudioThumbnail::readNextBlockFromAudioFile (AudioFormatReader& reader)
- {
- AudioThumbnailDataFormat* const d = (AudioThumbnailDataFormat*) data.getData();
-
- if (d->numFinishedSamples < d->totalSamples)
- {
- const int numToDo = (int) jmin ((int64) 65536, d->totalSamples - d->numFinishedSamples);
-
- generateSection (reader,
- d->numFinishedSamples,
- numToDo);
-
- d->numFinishedSamples += numToDo;
- }
-
- cacheNeedsRefilling = true;
- return (d->numFinishedSamples < d->totalSamples);
- }
-
- int AudioThumbnail::getNumChannels() const throw()
- {
- const AudioThumbnailDataFormat* const d = (const AudioThumbnailDataFormat*) data.getData();
- jassert (d != 0);
-
- return d->numChannels;
- }
-
- double AudioThumbnail::getTotalLength() const throw()
- {
- const AudioThumbnailDataFormat* const d = (const AudioThumbnailDataFormat*) data.getData();
- jassert (d != 0);
-
- if (d->sampleRate > 0)
- return d->totalSamples / (double)d->sampleRate;
- else
- return 0.0;
- }
-
- void AudioThumbnail::generateSection (AudioFormatReader& reader,
- int64 startSample,
- int numSamples)
- {
- AudioThumbnailDataFormat* const d = (AudioThumbnailDataFormat*) data.getData();
- jassert (d != 0);
-
- int firstDataPos = (int) (startSample / d->samplesPerThumbSample);
- int lastDataPos = (int) ((startSample + numSamples) / d->samplesPerThumbSample);
-
- char* l = getChannelData (0);
- char* r = getChannelData (1);
-
- for (int i = firstDataPos; i < lastDataPos; ++i)
- {
- const int sourceStart = i * d->samplesPerThumbSample;
- const int sourceEnd = sourceStart + d->samplesPerThumbSample;
-
- float lowestLeft, highestLeft, lowestRight, highestRight;
-
- reader.readMaxLevels (sourceStart,
- sourceEnd - sourceStart,
- lowestLeft,
- highestLeft,
- lowestRight,
- highestRight);
-
- int n = i * 2;
-
- if (r != 0)
- {
- l [n] = (char) jlimit (-128.0f, 127.0f, lowestLeft * 127.0f);
- r [n++] = (char) jlimit (-128.0f, 127.0f, lowestRight * 127.0f);
- l [n] = (char) jlimit (-128.0f, 127.0f, highestLeft * 127.0f);
- r [n++] = (char) jlimit (-128.0f, 127.0f, highestRight * 127.0f);
- }
- else
- {
- l [n++] = (char) jlimit (-128.0f, 127.0f, lowestLeft * 127.0f);
- l [n++] = (char) jlimit (-128.0f, 127.0f, highestLeft * 127.0f);
- }
- }
- }
-
- char* AudioThumbnail::getChannelData (int channel) const
- {
- AudioThumbnailDataFormat* const d = (AudioThumbnailDataFormat*) data.getData();
- jassert (d != 0);
-
- if (channel >= 0 && channel < d->numChannels)
- return d->data + (channel * 2 * d->numThumbnailSamples);
-
- return 0;
- }
-
- bool AudioThumbnail::isFullyLoaded() const throw()
- {
- const AudioThumbnailDataFormat* const d = (const AudioThumbnailDataFormat*) data.getData();
- jassert (d != 0);
-
- return d->numFinishedSamples >= d->totalSamples;
- }
-
- void AudioThumbnail::refillCache (const int numSamples,
- double startTime,
- const double timePerPixel)
- {
- const AudioThumbnailDataFormat* const d = (const AudioThumbnailDataFormat*) data.getData();
- jassert (d != 0);
-
- if (numSamples <= 0
- || timePerPixel <= 0.0
- || d->sampleRate <= 0)
- {
- numSamplesCached = 0;
- cacheNeedsRefilling = true;
- return;
- }
-
- if (numSamples == numSamplesCached
- && numChannelsCached == d->numChannels
- && startTime == cachedStart
- && timePerPixel == cachedTimePerPixel
- && ! cacheNeedsRefilling)
- {
- return;
- }
-
- numSamplesCached = numSamples;
- numChannelsCached = d->numChannels;
- cachedStart = startTime;
- cachedTimePerPixel = timePerPixel;
-
- cachedLevels.ensureSize (2 * numChannelsCached * numSamples);
-
- const bool needExtraDetail = (timePerPixel * d->sampleRate <= d->samplesPerThumbSample);
-
- const ScopedLock sl (readerLock);
-
- cacheNeedsRefilling = false;
-
- if (needExtraDetail && reader == 0)
- reader = createReader();
-
- if (reader != 0 && timePerPixel * d->sampleRate <= d->samplesPerThumbSample)
- {
- startTimer (timeBeforeDeletingReader);
-
- char* cacheData = (char*) cachedLevels.getData();
- int sample = roundDoubleToInt (startTime * d->sampleRate);
-
- for (int i = numSamples; --i >= 0;)
- {
- const int nextSample = roundDoubleToInt ((startTime + timePerPixel) * d->sampleRate);
-
- if (sample >= 0)
- {
- if (sample >= reader->lengthInSamples)
- break;
-
- float lmin, lmax, rmin, rmax;
-
- reader->readMaxLevels (sample,
- jmax (1, nextSample - sample),
- lmin, lmax, rmin, rmax);
-
- cacheData[0] = (char) jlimit (-128, 127, roundFloatToInt (lmin * 127.0f));
- cacheData[1] = (char) jlimit (-128, 127, roundFloatToInt (lmax * 127.0f));
-
- if (numChannelsCached > 1)
- {
- cacheData[2] = (char) jlimit (-128, 127, roundFloatToInt (rmin * 127.0f));
- cacheData[3] = (char) jlimit (-128, 127, roundFloatToInt (rmax * 127.0f));
- }
-
- cacheData += 2 * numChannelsCached;
- }
-
- startTime += timePerPixel;
- sample = nextSample;
- }
- }
- else
- {
- for (int channelNum = 0; channelNum < numChannelsCached; ++channelNum)
- {
- char* const data = getChannelData (channelNum);
- char* cacheData = ((char*) cachedLevels.getData()) + channelNum * 2;
-
- const double timeToThumbSampleFactor = d->sampleRate / (double) d->samplesPerThumbSample;
-
- startTime = cachedStart;
- int sample = roundDoubleToInt (startTime * timeToThumbSampleFactor);
- const int numFinished = (int) (d->numFinishedSamples / d->samplesPerThumbSample);
-
- for (int i = numSamples; --i >= 0;)
- {
- const int nextSample = roundDoubleToInt ((startTime + timePerPixel) * timeToThumbSampleFactor);
-
- if (sample >= 0 && data != 0)
- {
- char mx = -128;
- char mn = 127;
-
- while (sample <= nextSample)
- {
- if (sample >= numFinished)
- break;
-
- const int n = sample << 1;
- const char sampMin = data [n];
- const char sampMax = data [n + 1];
-
- if (sampMin < mn)
- mn = sampMin;
-
- if (sampMax > mx)
- mx = sampMax;
-
- ++sample;
- }
-
- if (mn <= mx)
- {
- cacheData[0] = mn;
- cacheData[1] = mx;
- }
- else
- {
- cacheData[0] = 1;
- cacheData[1] = 0;
- }
- }
- else
- {
- cacheData[0] = 1;
- cacheData[1] = 0;
- }
-
- cacheData += numChannelsCached * 2;
- startTime += timePerPixel;
- sample = nextSample;
- }
- }
- }
- }
-
- void AudioThumbnail::drawChannel (Graphics& g,
- int x, int y, int w, int h,
- double startTime,
- double endTime,
- int channelNum,
- const float verticalZoomFactor)
- {
- refillCache (w, startTime, (endTime - startTime) / w);
-
- if (numSamplesCached >= w
- && channelNum >= 0
- && channelNum < numChannelsCached)
- {
- const float topY = (float) y;
- const float bottomY = topY + h;
- const float midY = topY + h * 0.5f;
- const float vscale = verticalZoomFactor * h / 256.0f;
-
- const Rectangle clip (g.getClipBounds());
- const int skipLeft = clip.getX() - x;
- w -= skipLeft;
- x += skipLeft;
-
- const char* cacheData = ((const char*) cachedLevels.getData())
- + (channelNum << 1)
- + skipLeft * (numChannelsCached << 1);
-
- while (--w >= 0)
- {
- const char mn = cacheData[0];
- const char mx = cacheData[1];
- cacheData += numChannelsCached << 1;
-
- if (mn <= mx) // if the wrong way round, signifies that the sample's not yet known
- g.drawLine ((float) x, jmax (midY - mx * vscale - 0.3f, topY),
- (float) x, jmin (midY - mn * vscale + 0.3f, bottomY));
-
- ++x;
-
- if (x >= clip.getRight())
- break;
- }
- }
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_AudioThumbnail.cpp *********/
-
- /********* Start of inlined file: juce_AudioThumbnailCache.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- struct ThumbnailCacheEntry
- {
- int64 hash;
- uint32 lastUsed;
- MemoryBlock data;
-
- juce_UseDebuggingNewOperator
- };
-
- AudioThumbnailCache::AudioThumbnailCache (const int maxNumThumbsToStore_)
- : TimeSliceThread (T("thumb cache")),
- maxNumThumbsToStore (maxNumThumbsToStore_)
- {
- startThread (2);
- }
-
- AudioThumbnailCache::~AudioThumbnailCache()
- {
- }
-
- bool AudioThumbnailCache::loadThumb (AudioThumbnail& thumb, const int64 hashCode)
- {
- for (int i = thumbs.size(); --i >= 0;)
- {
- if (thumbs[i]->hash == hashCode)
- {
- MemoryInputStream in ((const char*) thumbs[i]->data.getData(),
- thumbs[i]->data.getSize(),
- false);
-
- thumb.loadFrom (in);
-
- thumbs[i]->lastUsed = Time::getMillisecondCounter();
- return true;
- }
- }
-
- return false;
- }
-
- void AudioThumbnailCache::storeThumb (const AudioThumbnail& thumb,
- const int64 hashCode)
- {
- MemoryOutputStream out;
- thumb.saveTo (out);
-
- ThumbnailCacheEntry* te = 0;
-
- for (int i = thumbs.size(); --i >= 0;)
- {
- if (thumbs[i]->hash == hashCode)
- {
- te = thumbs[i];
- break;
- }
- }
-
- if (te == 0)
- {
- te = new ThumbnailCacheEntry();
- te->hash = hashCode;
-
- if (thumbs.size() < maxNumThumbsToStore)
- {
- thumbs.add (te);
- }
- else
- {
- int oldest = 0;
- unsigned int oldestTime = Time::getMillisecondCounter() + 1;
-
- int i;
- for (i = thumbs.size(); --i >= 0;)
- if (thumbs[i]->lastUsed < oldestTime)
- oldest = i;
-
- thumbs.set (i, te);
- }
- }
-
- te->lastUsed = Time::getMillisecondCounter();
- te->data.setSize (0);
- te->data.append (out.getData(), out.getDataSize());
- }
-
- void AudioThumbnailCache::clear()
- {
- thumbs.clear();
- }
-
- void AudioThumbnailCache::addThumbnail (AudioThumbnail* const thumb)
- {
- addTimeSliceClient (thumb);
- }
-
- void AudioThumbnailCache::removeThumbnail (AudioThumbnail* const thumb)
- {
- removeTimeSliceClient (thumb);
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_AudioThumbnailCache.cpp *********/
-
- /********* Start of inlined file: juce_QuickTimeAudioFormat.cpp *********/
-
- #if JUCE_QUICKTIME
-
- #if ! defined (_WIN32)
- #include <Quicktime/Movies.h>
- #include <Quicktime/QTML.h>
- #include <Quicktime/QuickTimeComponents.h>
- #include <Quicktime/MediaHandlers.h>
- #include <Quicktime/ImageCodec.h>
- #else
- #ifdef _MSC_VER
- #pragma warning (push)
- #pragma warning (disable : 4100)
- #endif
-
- /* If you've got an include error here, you probably need to install the QuickTime SDK and
- add its header directory to your include path.
-
- Alternatively, if you don't need any QuickTime services, just turn off the JUC_QUICKTIME
- flag in juce_Config.h
- */
- #include <Movies.h>
- #include <QTML.h>
- #include <QuickTimeComponents.h>
- #include <MediaHandlers.h>
- #include <ImageCodec.h>
-
- #ifdef _MSC_VER
- #pragma warning (pop)
- #endif
- #endif
-
- BEGIN_JUCE_NAMESPACE
-
- bool juce_OpenQuickTimeMovieFromStream (InputStream* input, Movie& movie, Handle& dataHandle);
-
- #define quickTimeFormatName TRANS("QuickTime file")
- static const tchar* const quickTimeExtensions[] = { T(".mov"), T(".mp3"), T(".mp4"), 0 };
-
- class QTAudioReader : public AudioFormatReader
- {
- public:
- QTAudioReader (InputStream* const input_, const int trackNum_)
- : AudioFormatReader (input_, quickTimeFormatName),
- ok (false),
- movie (0),
- trackNum (trackNum_),
- extractor (0),
- lastSampleRead (0),
- lastThreadId (0),
- dataHandle (0)
- {
- bufferList = (AudioBufferList*) juce_calloc (256);
-
- #ifdef WIN32
- if (InitializeQTML (0) != noErr)
- return;
- #elif JUCE_MAC
- EnterMoviesOnThread (0);
- #endif
- if (EnterMovies() != noErr)
- return;
-
- bool opened = juce_OpenQuickTimeMovieFromStream (input_, movie, dataHandle);
-
- if (! opened)
- return;
-
- {
- const int numTracks = GetMovieTrackCount (movie);
- int trackCount = 0;
-
- for (int i = 1; i <= numTracks; ++i)
- {
- track = GetMovieIndTrack (movie, i);
- media = GetTrackMedia (track);
-
- OSType mediaType;
- GetMediaHandlerDescription (media, &mediaType, 0, 0);
-
- if (mediaType == SoundMediaType
- && trackCount++ == trackNum_)
- {
- ok = true;
- break;
- }
- }
- }
-
- if (! ok)
- return;
-
- ok = false;
-
- lengthInSamples = GetMediaDecodeDuration (media);
- usesFloatingPointData = false;
-
- samplesPerFrame = (int) (GetMediaDecodeDuration (media) / GetMediaSampleCount (media));
-
- trackUnitsPerFrame = GetMovieTimeScale (movie) * samplesPerFrame
- / GetMediaTimeScale (media);
-
- OSStatus err = MovieAudioExtractionBegin (movie, 0, &extractor);
-
- unsigned long output_layout_size;
- err = MovieAudioExtractionGetPropertyInfo (extractor,
- kQTPropertyClass_MovieAudioExtraction_Audio,
- kQTMovieAudioExtractionAudioPropertyID_AudioChannelLayout,
- 0, &output_layout_size, 0);
- if (err != noErr)
- return;
-
- AudioChannelLayout* const qt_audio_channel_layout
- = (AudioChannelLayout*) juce_calloc (output_layout_size);
-
- err = MovieAudioExtractionGetProperty (extractor,
- kQTPropertyClass_MovieAudioExtraction_Audio,
- kQTMovieAudioExtractionAudioPropertyID_AudioChannelLayout,
- output_layout_size, qt_audio_channel_layout, 0);
-
- qt_audio_channel_layout->mChannelLayoutTag = kAudioChannelLayoutTag_Stereo;
-
- err = MovieAudioExtractionSetProperty (extractor,
- kQTPropertyClass_MovieAudioExtraction_Audio,
- kQTMovieAudioExtractionAudioPropertyID_AudioChannelLayout,
- sizeof (qt_audio_channel_layout),
- qt_audio_channel_layout);
-
- juce_free (qt_audio_channel_layout);
-
- err = MovieAudioExtractionGetProperty (extractor,
- kQTPropertyClass_MovieAudioExtraction_Audio,
- kQTMovieAudioExtractionAudioPropertyID_AudioStreamBasicDescription,
- sizeof (inputStreamDesc),
- &inputStreamDesc, 0);
- if (err != noErr)
- return;
-
- inputStreamDesc.mFormatFlags = kAudioFormatFlagIsSignedInteger
- | kAudioFormatFlagIsPacked
- | kAudioFormatFlagsNativeEndian;
- inputStreamDesc.mBitsPerChannel = sizeof (SInt16) * 8;
- inputStreamDesc.mChannelsPerFrame = jmin (2, inputStreamDesc.mChannelsPerFrame);
- inputStreamDesc.mBytesPerFrame = sizeof (SInt16) * inputStreamDesc.mChannelsPerFrame;
- inputStreamDesc.mBytesPerPacket = inputStreamDesc.mBytesPerFrame;
-
- err = MovieAudioExtractionSetProperty (extractor,
- kQTPropertyClass_MovieAudioExtraction_Audio,
- kQTMovieAudioExtractionAudioPropertyID_AudioStreamBasicDescription,
- sizeof (inputStreamDesc),
- &inputStreamDesc);
- if (err != noErr)
- return;
-
- Boolean allChannelsDiscrete = false;
- err = MovieAudioExtractionSetProperty (extractor,
- kQTPropertyClass_MovieAudioExtraction_Movie,
- kQTMovieAudioExtractionMoviePropertyID_AllChannelsDiscrete,
- sizeof (allChannelsDiscrete),
- &allChannelsDiscrete);
-
- if (err != noErr)
- return;
-
- bufferList->mNumberBuffers = 1;
- bufferList->mBuffers[0].mNumberChannels = inputStreamDesc.mChannelsPerFrame;
- bufferList->mBuffers[0].mDataByteSize = (UInt32) (samplesPerFrame * inputStreamDesc.mBytesPerFrame) + 16;
- bufferList->mBuffers[0].mData = malloc (bufferList->mBuffers[0].mDataByteSize);
-
- sampleRate = inputStreamDesc.mSampleRate;
- bitsPerSample = 16;
- numChannels = inputStreamDesc.mChannelsPerFrame;
-
- detachThread();
- ok = true;
- }
-
- ~QTAudioReader()
- {
- if (dataHandle != 0)
- DisposeHandle (dataHandle);
-
- if (extractor != 0)
- {
- MovieAudioExtractionEnd (extractor);
- extractor = 0;
- }
-
- checkThreadIsAttached();
- DisposeMovie (movie);
-
- juce_free (bufferList->mBuffers[0].mData);
- juce_free (bufferList);
-
- #if JUCE_MAC
- ExitMoviesOnThread ();
- #endif
- }
-
- bool read (int** destSamples,
- int64 startSample,
- int numSamples)
- {
- checkThreadIsAttached();
- int done = 0;
-
- while (numSamples > 0)
- {
- if (! loadFrame ((int) startSample))
- return false;
-
- const int numToDo = jmin (numSamples, samplesPerFrame);
-
- for (unsigned int j = 0; j < inputStreamDesc.mChannelsPerFrame; ++j)
- {
- if (destSamples[j] != 0)
- {
- const short* const src = ((const short*) bufferList->mBuffers[0].mData) + j;
-
- for (int i = 0; i < numToDo; ++i)
- destSamples[j][done + i] = src [i << 1] << 16;
- }
- }
-
- done += numToDo;
- startSample += numToDo;
- numSamples -= numToDo;
- }
-
- detachThread();
- return true;
- }
-
- bool loadFrame (const int sampleNum)
- {
- if (lastSampleRead != sampleNum)
- {
- TimeRecord time;
- time.scale = (TimeScale) inputStreamDesc.mSampleRate;
- time.base = 0;
- time.value.hi = 0;
- time.value.lo = (UInt32) sampleNum;
-
- OSStatus err = MovieAudioExtractionSetProperty (extractor,
- kQTPropertyClass_MovieAudioExtraction_Movie,
- kQTMovieAudioExtractionMoviePropertyID_CurrentTime,
- sizeof (time), &time);
-
- if (err != noErr)
- return false;
- }
-
- bufferList->mBuffers[0].mDataByteSize = inputStreamDesc.mBytesPerFrame * samplesPerFrame;
-
- UInt32 outFlags = 0;
- UInt32 actualNumSamples = samplesPerFrame;
- OSStatus err = MovieAudioExtractionFillBuffer (extractor, &actualNumSamples,
- bufferList, &outFlags);
-
- lastSampleRead = sampleNum + samplesPerFrame;
-
- return err == noErr;
- }
-
- juce_UseDebuggingNewOperator
-
- bool ok;
-
- private:
- Movie movie;
- Media media;
- Track track;
- const int trackNum;
- double trackUnitsPerFrame;
- int samplesPerFrame;
- int lastSampleRead, lastThreadId;
- MovieAudioExtractionRef extractor;
- AudioStreamBasicDescription inputStreamDesc;
- AudioBufferList* bufferList;
- Handle dataHandle;
-
- /*OSErr readMovieStream (long offset, long size, void* dataPtr)
- {
- input->setPosition (offset);
- input->read (dataPtr, size);
- return noErr;
- }
-
- static OSErr readMovieStreamProc (long offset, long size, void* dataPtr, void* userRef)
- {
- return ((QTAudioReader*) userRef)->readMovieStream (offset, size, dataPtr);
- }*/
-
- void checkThreadIsAttached()
- {
- #if JUCE_MAC
- if (Thread::getCurrentThreadId() != lastThreadId)
- EnterMoviesOnThread (0);
- AttachMovieToCurrentThread (movie);
- #endif
- }
-
- void detachThread()
- {
- #if JUCE_MAC
- DetachMovieFromCurrentThread (movie);
- #endif
- }
- };
-
- QuickTimeAudioFormat::QuickTimeAudioFormat()
- : AudioFormat (quickTimeFormatName, (const tchar**) quickTimeExtensions)
- {
- }
-
- QuickTimeAudioFormat::~QuickTimeAudioFormat()
- {
- }
-
- const Array <int> QuickTimeAudioFormat::getPossibleSampleRates()
- {
- return Array<int>();
- }
-
- const Array <int> QuickTimeAudioFormat::getPossibleBitDepths()
- {
- return Array<int>();
- }
-
- bool QuickTimeAudioFormat::canDoStereo()
- {
- return true;
- }
-
- bool QuickTimeAudioFormat::canDoMono()
- {
- return true;
- }
-
- AudioFormatReader* QuickTimeAudioFormat::createReaderFor (InputStream* sourceStream,
- const bool deleteStreamIfOpeningFails)
- {
- QTAudioReader* r = new QTAudioReader (sourceStream, 0);
-
- if (! r->ok)
- {
- if (! deleteStreamIfOpeningFails)
- r->input = 0;
-
- deleteAndZero (r);
- }
-
- return r;
- }
-
- AudioFormatWriter* QuickTimeAudioFormat::createWriterFor (OutputStream* /*streamToWriteTo*/,
- double /*sampleRateToUse*/,
- unsigned int /*numberOfChannels*/,
- int /*bitsPerSample*/,
- const StringPairArray& /*metadataValues*/,
- int /*qualityOptionIndex*/)
- {
- jassertfalse // not yet implemented!
- return 0;
- }
-
- END_JUCE_NAMESPACE
-
- #endif
- /********* End of inlined file: juce_QuickTimeAudioFormat.cpp *********/
-
- /********* Start of inlined file: juce_WavAudioFormat.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- #define wavFormatName TRANS("WAV file")
- static const tchar* const wavExtensions[] = { T(".wav"), T(".bwf"), 0 };
-
- const tchar* const WavAudioFormat::bwavDescription = T("bwav description");
- const tchar* const WavAudioFormat::bwavOriginator = T("bwav originator");
- const tchar* const WavAudioFormat::bwavOriginatorRef = T("bwav originator ref");
- const tchar* const WavAudioFormat::bwavOriginationDate = T("bwav origination date");
- const tchar* const WavAudioFormat::bwavOriginationTime = T("bwav origination time");
- const tchar* const WavAudioFormat::bwavTimeReference = T("bwav time reference");
- const tchar* const WavAudioFormat::bwavCodingHistory = T("bwav coding history");
-
- const StringPairArray WavAudioFormat::createBWAVMetadata (const String& description,
- const String& originator,
- const String& originatorRef,
- const Time& date,
- const int64 timeReferenceSamples,
- const String& codingHistory)
- {
- StringPairArray m;
-
- m.set (bwavDescription, description);
- m.set (bwavOriginator, originator);
- m.set (bwavOriginatorRef, originatorRef);
- m.set (bwavOriginationDate, date.formatted (T("%Y-%m-%d")));
- m.set (bwavOriginationTime, date.formatted (T("%H:%M:%S")));
- m.set (bwavTimeReference, String (timeReferenceSamples));
- m.set (bwavCodingHistory, codingHistory);
-
- return m;
- }
-
- #if JUCE_MSVC
- #pragma pack (push, 1)
- #define PACKED
- #elif defined (JUCE_GCC)
- #define PACKED __attribute__((packed))
- #else
- #define PACKED
- #endif
-
- struct BWAVChunk
- {
- char description [256];
- char originator [32];
- char originatorRef [32];
- char originationDate [10];
- char originationTime [8];
- uint32 timeRefLow;
- uint32 timeRefHigh;
- uint16 version;
- uint8 umid[64];
- uint8 reserved[190];
- char codingHistory[1];
-
- void copyTo (StringPairArray& values) const
- {
- values.set (WavAudioFormat::bwavDescription, String (description, 256));
- values.set (WavAudioFormat::bwavOriginator, String (originator, 32));
- values.set (WavAudioFormat::bwavOriginatorRef, String (originatorRef, 32));
- values.set (WavAudioFormat::bwavOriginationDate, String (originationDate, 10));
- values.set (WavAudioFormat::bwavOriginationTime, String (originationTime, 8));
-
- const uint32 timeLow = swapIfBigEndian (timeRefLow);
- const uint32 timeHigh = swapIfBigEndian (timeRefHigh);
- const int64 time = (((int64)timeHigh) << 32) + timeLow;
-
- values.set (WavAudioFormat::bwavTimeReference, String (time));
- values.set (WavAudioFormat::bwavCodingHistory, String (codingHistory));
- }
-
- static MemoryBlock createFrom (const StringPairArray& values)
- {
- const int sizeNeeded = sizeof (BWAVChunk) + values [WavAudioFormat::bwavCodingHistory].length();
- MemoryBlock data ((sizeNeeded + 3) & ~3);
- data.fillWith (0);
-
- BWAVChunk* b = (BWAVChunk*) data.getData();
-
- // although copyToBuffer may overrun by one byte, that's ok as long as these
- // operations get done in the right order
- values [WavAudioFormat::bwavDescription].copyToBuffer (b->description, 256);
- values [WavAudioFormat::bwavOriginator].copyToBuffer (b->originator, 32);
- values [WavAudioFormat::bwavOriginatorRef].copyToBuffer (b->originatorRef, 32);
- values [WavAudioFormat::bwavOriginationDate].copyToBuffer (b->originationDate, 10);
- values [WavAudioFormat::bwavOriginationTime].copyToBuffer (b->originationTime, 8);
-
- const int64 time = values [WavAudioFormat::bwavTimeReference].getLargeIntValue();
- b->timeRefLow = swapIfBigEndian ((uint32) (time & 0xffffffff));
- b->timeRefHigh = swapIfBigEndian ((uint32) (time >> 32));
-
- values [WavAudioFormat::bwavCodingHistory].copyToBuffer (b->codingHistory, 256 * 1024);
-
- if (b->description[0] != 0
- || b->originator[0] != 0
- || b->originationDate[0] != 0
- || b->originationTime[0] != 0
- || b->codingHistory[0] != 0
- || time != 0)
- {
- return data;
- }
-
- return MemoryBlock();
- }
-
- } PACKED;
-
- #if JUCE_MSVC
- #pragma pack (pop)
- #endif
-
- #undef PACKED
-
- #undef chunkName
- #define chunkName(a) ((int) littleEndianInt(a))
-
- class WavAudioFormatReader : public AudioFormatReader
- {
- int bytesPerFrame;
- int64 dataChunkStart, dataLength;
-
- WavAudioFormatReader (const WavAudioFormatReader&);
- const WavAudioFormatReader& operator= (const WavAudioFormatReader&);
-
- public:
-
- WavAudioFormatReader (InputStream* const in)
- : AudioFormatReader (in, wavFormatName),
- dataLength (0)
- {
- if (input->readInt() == chunkName ("RIFF"))
- {
- const uint32 len = (uint32) input->readInt();
- const int64 end = input->getPosition() + len;
- bool hasGotType = false;
- bool hasGotData = false;
-
- if (input->readInt() == chunkName ("WAVE"))
- {
- while (input->getPosition() < end
- && ! input->isExhausted())
- {
- const int chunkType = input->readInt();
- uint32 length = (uint32) input->readInt();
- const int64 chunkEnd = input->getPosition() + length + (length & 1);
-
- if (chunkType == chunkName ("fmt "))
- {
- // read the format chunk
- const short format = input->readShort();
- const short numChans = input->readShort();
- sampleRate = input->readInt();
- const int bytesPerSec = input->readInt();
-
- numChannels = numChans;
- bytesPerFrame = bytesPerSec / (int)sampleRate;
- bitsPerSample = 8 * bytesPerFrame / numChans;
-
- if (format == 3)
- usesFloatingPointData = true;
- else if (format != 1)
- bytesPerFrame = 0;
-
- hasGotType = true;
- }
- else if (chunkType == chunkName ("data"))
- {
- // get the data chunk's position
- dataLength = length;
- dataChunkStart = input->getPosition();
- lengthInSamples = (bytesPerFrame > 0) ? (dataLength / bytesPerFrame) : 0;
-
- hasGotData = true;
- }
- else if (chunkType == chunkName ("bext"))
- {
- // Broadcast-wav extension chunk..
- BWAVChunk* const bwav = (BWAVChunk*) juce_calloc (jmax (length + 1, (int) sizeof (BWAVChunk)));
-
- if (bwav != 0)
- {
- input->read (bwav, length);
- bwav->copyTo (metadataValues);
- juce_free (bwav);
- }
- }
- else if ((hasGotType && hasGotData) || chunkEnd <= input->getPosition())
- {
- break;
- }
-
- input->setPosition (chunkEnd);
- }
- }
- }
- }
-
- ~WavAudioFormatReader()
- {
- }
-
- bool read (int** destSamples,
- int64 startSampleInFile,
- int numSamples)
- {
- int64 start = startSampleInFile;
- int startOffsetInDestBuffer = 0;
-
- if (startSampleInFile < 0)
- {
- const int silence = (int) jmin (-startSampleInFile, (int64) numSamples);
-
- int** destChan = destSamples;
-
- for (int i = 2; --i >= 0;)
- {
- if (*destChan != 0)
- {
- zeromem (*destChan, sizeof (int) * silence);
- ++destChan;
- }
- }
-
- startOffsetInDestBuffer += silence;
- numSamples -= silence;
- start = 0;
- }
-
- const int numToDo = (int) jlimit ((int64) 0, (int64) numSamples, lengthInSamples - start);
-
- if (numToDo > 0)
- {
- input->setPosition (dataChunkStart + start * bytesPerFrame);
-
- int num = numToDo;
- int* left = destSamples[0];
- if (left != 0)
- left += startOffsetInDestBuffer;
-
- int* right = destSamples[1];
- if (right != 0)
- right += startOffsetInDestBuffer;
-
- // (keep this a multiple of 3)
- const int tempBufSize = 1440 * 4;
- char tempBuffer [tempBufSize];
-
- while (num > 0)
- {
- const int numThisTime = jmin (tempBufSize / bytesPerFrame, num);
- const int bytesRead = input->read (tempBuffer, numThisTime * bytesPerFrame);
-
- if (bytesRead < numThisTime * bytesPerFrame)
- zeromem (tempBuffer + bytesRead, numThisTime * bytesPerFrame - bytesRead);
-
- if (bitsPerSample == 16)
- {
- const short* src = (const short*) tempBuffer;
-
- if (numChannels > 1)
- {
- if (left == 0)
- {
- for (int i = numThisTime; --i >= 0;)
- {
- ++src;
- *right++ = (int) swapIfBigEndian ((unsigned short) *src++) << 16;
- }
- }
- else if (right == 0)
- {
- for (int i = numThisTime; --i >= 0;)
- {
- *left++ = (int) swapIfBigEndian ((unsigned short) *src++) << 16;
- ++src;
- }
- }
- else
- {
- for (int i = numThisTime; --i >= 0;)
- {
- *left++ = (int) swapIfBigEndian ((unsigned short) *src++) << 16;
- *right++ = (int) swapIfBigEndian ((unsigned short) *src++) << 16;
- }
- }
- }
- else
- {
- for (int i = numThisTime; --i >= 0;)
- {
- *left++ = (int) swapIfBigEndian ((unsigned short) *src++) << 16;
- }
- }
- }
- else if (bitsPerSample == 24)
- {
- const char* src = (const char*) tempBuffer;
-
- if (numChannels > 1)
- {
- if (left == 0)
- {
- for (int i = numThisTime; --i >= 0;)
- {
- src += 6;
- *right++ = littleEndian24Bit (src) << 8;
- }
- }
- else if (right == 0)
- {
- for (int i = numThisTime; --i >= 0;)
- {
- *left++ = littleEndian24Bit (src) << 8;
- src += 6;
- }
- }
- else
- {
- for (int i = 0; i < numThisTime; ++i)
- {
- *left++ = littleEndian24Bit (src) << 8;
- src += 3;
- *right++ = littleEndian24Bit (src) << 8;
- src += 3;
- }
- }
- }
- else
- {
- for (int i = 0; i < numThisTime; ++i)
- {
- *left++ = littleEndian24Bit (src) << 8;
- src += 3;
- }
- }
- }
- else if (bitsPerSample == 32)
- {
- const unsigned int* src = (const unsigned int*) tempBuffer;
- unsigned int* l = (unsigned int*) left;
- unsigned int* r = (unsigned int*) right;
-
- if (numChannels > 1)
- {
- if (l == 0)
- {
- for (int i = numThisTime; --i >= 0;)
- {
- ++src;
- *r++ = swapIfBigEndian (*src++);
- }
- }
- else if (r == 0)
- {
- for (int i = numThisTime; --i >= 0;)
- {
- *l++ = swapIfBigEndian (*src++);
- ++src;
- }
- }
- else
- {
- for (int i = numThisTime; --i >= 0;)
- {
- *l++ = swapIfBigEndian (*src++);
- *r++ = swapIfBigEndian (*src++);
- }
- }
- }
- else
- {
- for (int i = numThisTime; --i >= 0;)
- {
- *l++ = swapIfBigEndian (*src++);
- }
- }
-
- left = (int*)l;
- right = (int*)r;
- }
- else if (bitsPerSample == 8)
- {
- const unsigned char* src = (const unsigned char*) tempBuffer;
-
- if (numChannels > 1)
- {
- if (left == 0)
- {
- for (int i = numThisTime; --i >= 0;)
- {
- ++src;
- *right++ = ((int) *src++ - 128) << 24;
- }
- }
- else if (right == 0)
- {
- for (int i = numThisTime; --i >= 0;)
- {
- *left++ = ((int) *src++ - 128) << 24;
- ++src;
- }
- }
- else
- {
- for (int i = numThisTime; --i >= 0;)
- {
- *left++ = ((int) *src++ - 128) << 24;
- *right++ = ((int) *src++ - 128) << 24;
- }
- }
- }
- else
- {
- for (int i = numThisTime; --i >= 0;)
- {
- *left++ = ((int)*src++ - 128) << 24;
- }
- }
- }
-
- num -= numThisTime;
- }
- }
-
- if (numToDo < numSamples)
- {
- int** destChan = destSamples;
-
- while (*destChan != 0)
- {
- zeromem ((*destChan) + (startOffsetInDestBuffer + numToDo),
- sizeof (int) * (numSamples - numToDo));
- ++destChan;
- }
- }
-
- return true;
- }
-
- juce_UseDebuggingNewOperator
- };
-
- class WavAudioFormatWriter : public AudioFormatWriter
- {
- MemoryBlock tempBlock, bwavChunk;
- uint32 lengthInSamples, bytesWritten;
- int64 headerPosition;
- bool writeFailed;
-
- WavAudioFormatWriter (const WavAudioFormatWriter&);
- const WavAudioFormatWriter& operator= (const WavAudioFormatWriter&);
-
- void writeHeader()
- {
- const bool seekedOk = output->setPosition (headerPosition);
- (void) seekedOk;
-
- // if this fails, you've given it an output stream that can't seek! It needs
- // to be able to seek back to write the header
- jassert (seekedOk);
-
- const int bytesPerFrame = numChannels * bitsPerSample / 8;
- output->writeInt (chunkName ("RIFF"));
- output->writeInt (lengthInSamples * bytesPerFrame
- + ((bwavChunk.getSize() > 0) ? (44 + bwavChunk.getSize()) : 36));
-
- output->writeInt (chunkName ("WAVE"));
- output->writeInt (chunkName ("fmt "));
- output->writeInt (16);
- output->writeShort ((bitsPerSample < 32) ? (short) 1 /*WAVE_FORMAT_PCM*/
- : (short) 3 /*WAVE_FORMAT_IEEE_FLOAT*/);
- output->writeShort ((short) numChannels);
- output->writeInt ((int) sampleRate);
- output->writeInt (bytesPerFrame * (int) sampleRate);
- output->writeShort ((short) bytesPerFrame);
- output->writeShort ((short) bitsPerSample);
-
- if (bwavChunk.getSize() > 0)
- {
- output->writeInt (chunkName ("bext"));
- output->writeInt (bwavChunk.getSize());
- output->write (bwavChunk.getData(), bwavChunk.getSize());
- }
-
- output->writeInt (chunkName ("data"));
- output->writeInt (lengthInSamples * bytesPerFrame);
-
- usesFloatingPointData = (bitsPerSample == 32);
- }
-
- public:
-
- WavAudioFormatWriter (OutputStream* const out,
- const double sampleRate,
- const unsigned int numChannels_,
- const int bits,
- const StringPairArray& metadataValues)
- : AudioFormatWriter (out,
- wavFormatName,
- sampleRate,
- numChannels_,
- bits),
- lengthInSamples (0),
- bytesWritten (0),
- writeFailed (false)
- {
- if (metadataValues.size() > 0)
- bwavChunk = BWAVChunk::createFrom (metadataValues);
-
- headerPosition = out->getPosition();
- writeHeader();
- }
-
- ~WavAudioFormatWriter()
- {
- writeHeader();
- }
-
- bool write (const int** data, int numSamples)
- {
- if (writeFailed)
- return false;
-
- const int bytes = numChannels * numSamples * bitsPerSample / 8;
- tempBlock.ensureSize (bytes, false);
- char* buffer = (char*) tempBlock.getData();
-
- const int* left = data[0];
- const int* right = data[1];
- if (right == 0)
- right = left;
-
- if (bitsPerSample == 16)
- {
- short* b = (short*) buffer;
-
- if (numChannels > 1)
- {
- for (int i = numSamples; --i >= 0;)
- {
- *b++ = (short) swapIfBigEndian ((unsigned short) (*left++ >> 16));
- *b++ = (short) swapIfBigEndian ((unsigned short) (*right++ >> 16));
- }
- }
- else
- {
- for (int i = numSamples; --i >= 0;)
- {
- *b++ = (short) swapIfBigEndian ((unsigned short) (*left++ >> 16));
- }
- }
- }
- else if (bitsPerSample == 24)
- {
- char* b = (char*) buffer;
-
- if (numChannels > 1)
- {
- for (int i = numSamples; --i >= 0;)
- {
- littleEndian24BitToChars ((*left++) >> 8, b);
- b += 3;
- littleEndian24BitToChars ((*right++) >> 8, b);
- b += 3;
- }
- }
- else
- {
- for (int i = numSamples; --i >= 0;)
- {
- littleEndian24BitToChars ((*left++) >> 8, b);
- b += 3;
- }
- }
- }
- else if (bitsPerSample == 32)
- {
- unsigned int* b = (unsigned int*) buffer;
-
- if (numChannels > 1)
- {
- for (int i = numSamples; --i >= 0;)
- {
- *b++ = swapIfBigEndian ((unsigned int) *left++);
- *b++ = swapIfBigEndian ((unsigned int) *right++);
- }
- }
- else
- {
- for (int i = numSamples; --i >= 0;)
- {
- *b++ = swapIfBigEndian ((unsigned int) *left++);
- }
- }
- }
- else if (bitsPerSample == 8)
- {
- unsigned char* b = (unsigned char*) buffer;
-
- if (numChannels > 1)
- {
- for (int i = numSamples; --i >= 0;)
- {
- *b++ = (unsigned char) (128 + (*left++ >> 24));
- *b++ = (unsigned char) (128 + (*right++ >> 24));
- }
- }
- else
- {
- for (int i = numSamples; --i >= 0;)
- {
- *b++ = (unsigned char) (128 + (*left++ >> 24));
- }
- }
- }
-
- if (bytesWritten + bytes >= (uint32) 0xfff00000
- || ! output->write (buffer, bytes))
- {
- // failed to write to disk, so let's try writing the header.
- // If it's just run out of disk space, then if it does manage
- // to write the header, we'll still have a useable file..
- writeHeader();
- writeFailed = true;
- return false;
- }
- else
- {
- bytesWritten += bytes;
- lengthInSamples += numSamples;
-
- return true;
- }
- }
-
- juce_UseDebuggingNewOperator
- };
-
- WavAudioFormat::WavAudioFormat()
- : AudioFormat (wavFormatName, (const tchar**) wavExtensions)
- {
- }
-
- WavAudioFormat::~WavAudioFormat()
- {
- }
-
- const Array <int> WavAudioFormat::getPossibleSampleRates()
- {
- const int rates[] = { 22050, 32000, 44100, 48000, 88200, 96000, 176400, 192000, 0 };
- return Array <int> (rates);
- }
-
- const Array <int> WavAudioFormat::getPossibleBitDepths()
- {
- const int depths[] = { 8, 16, 24, 32, 0 };
- return Array <int> (depths);
- }
-
- bool WavAudioFormat::canDoStereo()
- {
- return true;
- }
-
- bool WavAudioFormat::canDoMono()
- {
- return true;
- }
-
- AudioFormatReader* WavAudioFormat::createReaderFor (InputStream* sourceStream,
- const bool deleteStreamIfOpeningFails)
- {
- WavAudioFormatReader* r = new WavAudioFormatReader (sourceStream);
-
- if (r->sampleRate == 0)
- {
- if (! deleteStreamIfOpeningFails)
- r->input = 0;
-
- deleteAndZero (r);
- }
-
- return r;
- }
-
- AudioFormatWriter* WavAudioFormat::createWriterFor (OutputStream* out,
- double sampleRate,
- unsigned int numChannels,
- int bitsPerSample,
- const StringPairArray& metadataValues,
- int /*qualityOptionIndex*/)
- {
- if (getPossibleBitDepths().contains (bitsPerSample))
- {
- return new WavAudioFormatWriter (out,
- sampleRate,
- numChannels,
- bitsPerSample,
- metadataValues);
- }
-
- return 0;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_WavAudioFormat.cpp *********/
-
- /********* Start of inlined file: juce_AudioFormatReaderSource.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- AudioFormatReaderSource::AudioFormatReaderSource (AudioFormatReader* const reader_,
- const bool deleteReaderWhenThisIsDeleted)
- : reader (reader_),
- deleteReader (deleteReaderWhenThisIsDeleted),
- nextPlayPos (0),
- looping (false)
- {
- jassert (reader != 0);
- }
-
- AudioFormatReaderSource::~AudioFormatReaderSource()
- {
- releaseResources();
-
- if (deleteReader)
- delete reader;
- }
-
- void AudioFormatReaderSource::setNextReadPosition (int newPosition)
- {
- nextPlayPos = newPosition;
- }
-
- void AudioFormatReaderSource::setLooping (const bool shouldLoop) throw()
- {
- looping = shouldLoop;
- }
-
- int AudioFormatReaderSource::getNextReadPosition() const
- {
- return (looping) ? (nextPlayPos % (int) reader->lengthInSamples)
- : nextPlayPos;
- }
-
- int AudioFormatReaderSource::getTotalLength() const
- {
- return (int) reader->lengthInSamples;
- }
-
- void AudioFormatReaderSource::prepareToPlay (int /*samplesPerBlockExpected*/,
- double /*sampleRate*/)
- {
- }
-
- void AudioFormatReaderSource::releaseResources()
- {
- }
-
- void AudioFormatReaderSource::getNextAudioBlock (const AudioSourceChannelInfo& info)
- {
- if (info.numSamples > 0)
- {
- const int start = nextPlayPos;
-
- if (looping)
- {
- const int newStart = start % (int) reader->lengthInSamples;
- const int newEnd = (start + info.numSamples) % (int) reader->lengthInSamples;
-
- if (newEnd > newStart)
- {
- info.buffer->readFromAudioReader (reader,
- info.startSample,
- newEnd - newStart,
- newStart,
- true, true);
- }
- else
- {
- const int endSamps = (int) reader->lengthInSamples - newStart;
-
- info.buffer->readFromAudioReader (reader,
- info.startSample,
- endSamps,
- newStart,
- true, true);
-
- info.buffer->readFromAudioReader (reader,
- info.startSample + endSamps,
- newEnd,
- 0,
- true, true);
- }
-
- nextPlayPos = newEnd;
- }
- else
- {
- info.buffer->readFromAudioReader (reader,
- info.startSample,
- info.numSamples,
- start,
- true, true);
-
- nextPlayPos += info.numSamples;
- }
- }
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_AudioFormatReaderSource.cpp *********/
-
- /********* Start of inlined file: juce_AudioSourcePlayer.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- AudioSourcePlayer::AudioSourcePlayer()
- : source (0),
- sampleRate (0),
- bufferSize (0),
- tempBuffer (2, 8),
- lastGain (1.0f),
- gain (1.0f)
- {
- }
-
- AudioSourcePlayer::~AudioSourcePlayer()
- {
- setSource (0);
- }
-
- void AudioSourcePlayer::setSource (AudioSource* newSource)
- {
- if (source != newSource)
- {
- AudioSource* const oldSource = source;
-
- if (newSource != 0 && bufferSize > 0 && sampleRate > 0)
- newSource->prepareToPlay (bufferSize, sampleRate);
-
- {
- const ScopedLock sl (readLock);
- source = newSource;
- }
-
- if (oldSource != 0)
- oldSource->releaseResources();
- }
- }
-
- void AudioSourcePlayer::setGain (const float newGain) throw()
- {
- gain = newGain;
- }
-
- void AudioSourcePlayer::audioDeviceIOCallback (const float** inputChannelData,
- int totalNumInputChannels,
- float** outputChannelData,
- int totalNumOutputChannels,
- int numSamples)
- {
- // these should have been prepared by audioDeviceAboutToStart()...
- jassert (sampleRate > 0 && bufferSize > 0);
-
- const ScopedLock sl (readLock);
-
- if (source != 0)
- {
- AudioSourceChannelInfo info;
- int i, numActiveChans = 0, numInputs = 0, numOutputs = 0;
-
- // messy stuff needed to compact the channels down into an array
- // of non-zero pointers..
- for (i = 0; i < totalNumInputChannels; ++i)
- {
- if (inputChannelData[i] != 0)
- {
- inputChans [numInputs++] = inputChannelData[i];
- if (numInputs >= numElementsInArray (inputChans))
- break;
- }
- }
-
- for (i = 0; i < totalNumOutputChannels; ++i)
- {
- if (outputChannelData[i] != 0)
- {
- outputChans [numOutputs++] = outputChannelData[i];
- if (numOutputs >= numElementsInArray (outputChans))
- break;
- }
- }
-
- if (numInputs > numOutputs)
- {
- // if there aren't enough output channels for the number of
- // inputs, we need to create some temporary extra ones (can't
- // use the input data in case it gets written to)
- tempBuffer.setSize (numInputs - numOutputs, numSamples,
- false, false, true);
-
- for (i = 0; i < numOutputs; ++i)
- {
- channels[numActiveChans] = outputChans[i];
- memcpy (channels[numActiveChans], inputChans[i], sizeof (float) * numSamples);
- ++numActiveChans;
- }
-
- for (i = numOutputs; i < numInputs; ++i)
- {
- channels[numActiveChans] = tempBuffer.getSampleData (i - numOutputs, 0);
- memcpy (channels[numActiveChans], inputChans[i], sizeof (float) * numSamples);
- ++numActiveChans;
- }
- }
- else
- {
- for (i = 0; i < numInputs; ++i)
- {
- channels[numActiveChans] = outputChans[i];
- memcpy (channels[numActiveChans], inputChans[i], sizeof (float) * numSamples);
- ++numActiveChans;
- }
-
- for (i = numInputs; i < numOutputs; ++i)
- {
- channels[numActiveChans] = outputChans[i];
- zeromem (channels[numActiveChans], sizeof (float) * numSamples);
- ++numActiveChans;
- }
- }
-
- AudioSampleBuffer buffer (channels, numActiveChans, numSamples);
-
- info.buffer = &buffer;
- info.startSample = 0;
- info.numSamples = numSamples;
-
- source->getNextAudioBlock (info);
-
- for (i = info.buffer->getNumChannels(); --i >= 0;)
- info.buffer->applyGainRamp (i, info.startSample, info.numSamples, lastGain, gain);
-
- lastGain = gain;
- }
- else
- {
- for (int i = 0; i < totalNumOutputChannels; ++i)
- if (outputChannelData[i] != 0)
- zeromem (outputChannelData[i], sizeof (float) * numSamples);
- }
- }
-
- void AudioSourcePlayer::audioDeviceAboutToStart (AudioIODevice* device)
- {
- sampleRate = device->getCurrentSampleRate();
- bufferSize = device->getCurrentBufferSizeSamples();
- zeromem (channels, sizeof (channels));
-
- if (source != 0)
- source->prepareToPlay (bufferSize, sampleRate);
- }
-
- void AudioSourcePlayer::audioDeviceStopped()
- {
- if (source != 0)
- source->releaseResources();
-
- sampleRate = 0.0;
- bufferSize = 0;
-
- tempBuffer.setSize (2, 8);
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_AudioSourcePlayer.cpp *********/
-
- /********* Start of inlined file: juce_AudioTransportSource.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- AudioTransportSource::AudioTransportSource()
- : source (0),
- resamplerSource (0),
- bufferingSource (0),
- positionableSource (0),
- masterSource (0),
- gain (1.0f),
- lastGain (1.0f),
- playing (false),
- stopped (true),
- sampleRate (44100.0),
- sourceSampleRate (0.0),
- blockSize (128),
- readAheadBufferSize (0),
- isPrepared (false),
- inputStreamEOF (false)
- {
- }
-
- AudioTransportSource::~AudioTransportSource()
- {
- setSource (0);
-
- releaseResources();
- }
-
- void AudioTransportSource::setSource (PositionableAudioSource* const newSource,
- int readAheadBufferSize_,
- double sourceSampleRateToCorrectFor)
- {
- if (source == newSource)
- {
- if (source == 0)
- return;
-
- setSource (0, 0, 0); // deselect and reselect to avoid releasing resources wrongly
- }
-
- readAheadBufferSize = readAheadBufferSize_;
- sourceSampleRate = sourceSampleRateToCorrectFor;
-
- ResamplingAudioSource* newResamplerSource = 0;
- BufferingAudioSource* newBufferingSource = 0;
- PositionableAudioSource* newPositionableSource = 0;
- AudioSource* newMasterSource = 0;
-
- ResamplingAudioSource* oldResamplerSource = resamplerSource;
- BufferingAudioSource* oldBufferingSource = bufferingSource;
- AudioSource* oldMasterSource = masterSource;
-
- if (newSource != 0)
- {
- newPositionableSource = newSource;
-
- if (readAheadBufferSize_ > 0)
- newPositionableSource = newBufferingSource
- = new BufferingAudioSource (newPositionableSource, false, readAheadBufferSize_);
-
- newPositionableSource->setNextReadPosition (0);
-
- if (sourceSampleRateToCorrectFor != 0)
- newMasterSource = newResamplerSource
- = new ResamplingAudioSource (newPositionableSource, false);
- else
- newMasterSource = newPositionableSource;
-
- if (isPrepared)
- {
- if (newResamplerSource != 0 && sourceSampleRate > 0 && sampleRate > 0)
- newResamplerSource->setResamplingRatio (sourceSampleRate / sampleRate);
-
- newMasterSource->prepareToPlay (blockSize, sampleRate);
- }
- }
-
- {
- const ScopedLock sl (callbackLock);
-
- source = newSource;
- resamplerSource = newResamplerSource;
- bufferingSource = newBufferingSource;
- masterSource = newMasterSource;
- positionableSource = newPositionableSource;
-
- playing = false;
- }
-
- if (oldMasterSource != 0)
- oldMasterSource->releaseResources();
-
- if (oldResamplerSource != 0)
- delete oldResamplerSource;
-
- if (oldBufferingSource != 0)
- delete oldBufferingSource;
- }
-
- void AudioTransportSource::start()
- {
- if ((! playing) && masterSource != 0)
- {
- callbackLock.enter();
- playing = true;
- stopped = false;
- inputStreamEOF = false;
- callbackLock.exit();
-
- sendChangeMessage (this);
- }
- }
-
- void AudioTransportSource::stop()
- {
- if (playing)
- {
- callbackLock.enter();
- playing = false;
- callbackLock.exit();
-
- int n = 500;
- while (--n >= 0 && ! stopped)
- Thread::sleep (2);
-
- sendChangeMessage (this);
- }
- }
-
- void AudioTransportSource::setPosition (double newPosition)
- {
- if (sampleRate > 0.0)
- setNextReadPosition (roundDoubleToInt (newPosition * sampleRate));
- }
-
- double AudioTransportSource::getCurrentPosition() const
- {
- if (sampleRate > 0.0)
- return getNextReadPosition() / sampleRate;
- else
- return 0.0;
- }
-
- void AudioTransportSource::setNextReadPosition (int newPosition)
- {
- if (positionableSource != 0)
- {
- if (sampleRate > 0 && sourceSampleRate > 0)
- newPosition = roundDoubleToInt (newPosition * sourceSampleRate / sampleRate);
-
- positionableSource->setNextReadPosition (newPosition);
- }
- }
-
- int AudioTransportSource::getNextReadPosition() const
- {
- if (positionableSource != 0)
- {
- const double ratio = (sampleRate > 0 && sourceSampleRate > 0) ? sampleRate / sourceSampleRate : 1.0;
-
- return roundDoubleToInt (positionableSource->getNextReadPosition() * ratio);
- }
-
- return 0;
- }
-
- int AudioTransportSource::getTotalLength() const
- {
- const ScopedLock sl (callbackLock);
-
- if (positionableSource != 0)
- {
- const double ratio = (sampleRate > 0 && sourceSampleRate > 0) ? sampleRate / sourceSampleRate : 1.0;
-
- return roundDoubleToInt (positionableSource->getTotalLength() * ratio);
- }
-
- return 0;
- }
-
- bool AudioTransportSource::isLooping() const
- {
- const ScopedLock sl (callbackLock);
-
- return positionableSource != 0
- && positionableSource->isLooping();
- }
-
- void AudioTransportSource::setGain (const float newGain) throw()
- {
- gain = newGain;
- }
-
- void AudioTransportSource::prepareToPlay (int samplesPerBlockExpected,
- double sampleRate_)
- {
- const ScopedLock sl (callbackLock);
-
- sampleRate = sampleRate_;
- blockSize = samplesPerBlockExpected;
-
- if (masterSource != 0)
- masterSource->prepareToPlay (samplesPerBlockExpected, sampleRate);
-
- if (resamplerSource != 0 && sourceSampleRate != 0)
- resamplerSource->setResamplingRatio (sourceSampleRate / sampleRate);
-
- isPrepared = true;
- }
-
- void AudioTransportSource::releaseResources()
- {
- const ScopedLock sl (callbackLock);
-
- if (masterSource != 0)
- masterSource->releaseResources();
-
- isPrepared = false;
- }
-
- void AudioTransportSource::getNextAudioBlock (const AudioSourceChannelInfo& info)
- {
- const ScopedLock sl (callbackLock);
-
- inputStreamEOF = false;
-
- if (masterSource != 0 && ! stopped)
- {
- masterSource->getNextAudioBlock (info);
-
- if (! playing)
- {
- // just stopped playing, so fade out the last block..
- for (int i = info.buffer->getNumChannels(); --i >= 0;)
- info.buffer->applyGainRamp (i, info.startSample, jmin (256, info.numSamples), 1.0f, 0.0f);
-
- if (info.numSamples > 256)
- info.buffer->clear (info.startSample + 256, info.numSamples - 256);
- }
-
- if (positionableSource->getNextReadPosition() > positionableSource->getTotalLength() + 1
- && ! positionableSource->isLooping())
- {
- playing = false;
- inputStreamEOF = true;
- sendChangeMessage (this);
- }
-
- stopped = ! playing;
-
- for (int i = info.buffer->getNumChannels(); --i >= 0;)
- {
- info.buffer->applyGainRamp (i, info.startSample, info.numSamples,
- lastGain, gain);
- }
- }
- else
- {
- info.clearActiveBufferRegion();
- stopped = true;
- }
-
- lastGain = gain;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_AudioTransportSource.cpp *********/
-
- /********* Start of inlined file: juce_BufferingAudioSource.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- class SharedBufferingAudioSourceThread : public DeletedAtShutdown,
- public Thread,
- private Timer
- {
- public:
- SharedBufferingAudioSourceThread()
- : Thread ("Audio Buffer"),
- sources (8)
- {
- }
-
- ~SharedBufferingAudioSourceThread()
- {
- stopThread (10000);
- clearSingletonInstance();
- }
-
- juce_DeclareSingleton (SharedBufferingAudioSourceThread, false)
-
- void addSource (BufferingAudioSource* source)
- {
- const ScopedLock sl (lock);
-
- if (! sources.contains ((void*) source))
- {
- sources.add ((void*) source);
- startThread();
-
- stopTimer();
- }
-
- notify();
- }
-
- void removeSource (BufferingAudioSource* source)
- {
- const ScopedLock sl (lock);
- sources.removeValue ((void*) source);
-
- if (sources.size() == 0)
- startTimer (5000);
- }
-
- private:
- VoidArray sources;
- CriticalSection lock;
-
- void run()
- {
- while (! threadShouldExit())
- {
- bool busy = false;
-
- for (int i = sources.size(); --i >= 0;)
- {
- if (threadShouldExit())
- return;
-
- const ScopedLock sl (lock);
-
- BufferingAudioSource* const b = (BufferingAudioSource*) sources[i];
-
- if (b != 0 && b->readNextBufferChunk())
- busy = true;
- }
-
- if (! busy)
- wait (500);
- }
- }
-
- void timerCallback()
- {
- stopTimer();
-
- if (sources.size() == 0)
- deleteInstance();
- }
-
- SharedBufferingAudioSourceThread (const SharedBufferingAudioSourceThread&);
- const SharedBufferingAudioSourceThread& operator= (const SharedBufferingAudioSourceThread&);
- };
-
- juce_ImplementSingleton (SharedBufferingAudioSourceThread)
-
- BufferingAudioSource::BufferingAudioSource (PositionableAudioSource* source_,
- const bool deleteSourceWhenDeleted_,
- int numberOfSamplesToBuffer_)
- : source (source_),
- deleteSourceWhenDeleted (deleteSourceWhenDeleted_),
- numberOfSamplesToBuffer (jmax (1024, numberOfSamplesToBuffer_)),
- buffer (2, 0),
- bufferValidStart (0),
- bufferValidEnd (0),
- nextPlayPos (0),
- wasSourceLooping (false)
- {
- jassert (source_ != 0);
-
- jassert (numberOfSamplesToBuffer_ > 1024); // not much point using this class if you're
- // not using a larger buffer..
- }
-
- BufferingAudioSource::~BufferingAudioSource()
- {
- SharedBufferingAudioSourceThread* const thread = SharedBufferingAudioSourceThread::getInstanceWithoutCreating();
-
- if (thread != 0)
- thread->removeSource (this);
-
- if (deleteSourceWhenDeleted)
- delete source;
- }
-
- void BufferingAudioSource::prepareToPlay (int samplesPerBlockExpected, double sampleRate_)
- {
- source->prepareToPlay (samplesPerBlockExpected, sampleRate_);
-
- sampleRate = sampleRate_;
-
- buffer.setSize (2, jmax (samplesPerBlockExpected * 2, numberOfSamplesToBuffer));
- buffer.clear();
-
- bufferValidStart = 0;
- bufferValidEnd = 0;
-
- SharedBufferingAudioSourceThread::getInstance()->addSource (this);
-
- while (bufferValidEnd - bufferValidStart < jmin (((int) sampleRate_) / 4,
- buffer.getNumSamples() / 2))
- {
- SharedBufferingAudioSourceThread::getInstance()->notify();
- Thread::sleep (5);
- }
- }
-
- void BufferingAudioSource::releaseResources()
- {
- SharedBufferingAudioSourceThread* const thread = SharedBufferingAudioSourceThread::getInstanceWithoutCreating();
-
- if (thread != 0)
- thread->removeSource (this);
-
- buffer.setSize (2, 0);
- source->releaseResources();
- }
-
- void BufferingAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& info)
- {
- const ScopedLock sl (bufferStartPosLock);
-
- const int validStart = jlimit (bufferValidStart, bufferValidEnd, nextPlayPos) - nextPlayPos;
- const int validEnd = jlimit (bufferValidStart, bufferValidEnd, nextPlayPos + info.numSamples) - nextPlayPos;
-
- if (validStart == validEnd)
- {
- // total cache miss
- info.clearActiveBufferRegion();
- }
- else
- {
- if (validStart > 0)
- info.buffer->clear (info.startSample, validStart); // partial cache miss at start
-
- if (validEnd < info.numSamples)
- info.buffer->clear (info.startSample + validEnd,
- info.numSamples - validEnd); // partial cache miss at end
-
- if (validStart < validEnd)
- {
- for (int chan = jmin (2, info.buffer->getNumChannels()); --chan >= 0;)
- {
- const int startBufferIndex = (validStart + nextPlayPos) % buffer.getNumSamples();
- const int endBufferIndex = (validEnd + nextPlayPos) % buffer.getNumSamples();
-
- if (startBufferIndex < endBufferIndex)
- {
- info.buffer->copyFrom (chan, info.startSample + validStart,
- buffer,
- chan, startBufferIndex,
- validEnd - validStart);
- }
- else
- {
- const int initialSize = buffer.getNumSamples() - startBufferIndex;
-
- info.buffer->copyFrom (chan, info.startSample + validStart,
- buffer,
- chan, startBufferIndex,
- initialSize);
-
- info.buffer->copyFrom (chan, info.startSample + validStart + initialSize,
- buffer,
- chan, 0,
- (validEnd - validStart) - initialSize);
- }
- }
- }
-
- nextPlayPos += info.numSamples;
- }
-
- SharedBufferingAudioSourceThread* const thread = SharedBufferingAudioSourceThread::getInstanceWithoutCreating();
-
- if (thread != 0)
- thread->notify();
- }
-
- int BufferingAudioSource::getNextReadPosition() const
- {
- return (source->isLooping() && nextPlayPos > 0)
- ? nextPlayPos % source->getTotalLength()
- : nextPlayPos;
- }
-
- void BufferingAudioSource::setNextReadPosition (int newPosition)
- {
- const ScopedLock sl (bufferStartPosLock);
-
- nextPlayPos = newPosition;
-
- SharedBufferingAudioSourceThread* const thread = SharedBufferingAudioSourceThread::getInstanceWithoutCreating();
-
- if (thread != 0)
- thread->notify();
- }
-
- bool BufferingAudioSource::readNextBufferChunk()
- {
- bufferStartPosLock.enter();
-
- if (wasSourceLooping != isLooping())
- {
- wasSourceLooping = isLooping();
- bufferValidStart = 0;
- bufferValidEnd = 0;
- }
-
- int newBVS = jmax (0, nextPlayPos);
- int newBVE = newBVS + buffer.getNumSamples() - 4;
- int sectionToReadStart = 0;
- int sectionToReadEnd = 0;
-
- const int maxChunkSize = 2048;
-
- if (newBVS < bufferValidStart || newBVS >= bufferValidEnd)
- {
- newBVE = jmin (newBVE, newBVS + maxChunkSize);
-
- sectionToReadStart = newBVS;
- sectionToReadEnd = newBVE;
-
- bufferValidStart = 0;
- bufferValidEnd = 0;
- }
- else if (abs (newBVS - bufferValidStart) > 512
- || abs (newBVE - bufferValidEnd) > 512)
- {
- newBVE = jmin (newBVE, bufferValidEnd + maxChunkSize);
-
- sectionToReadStart = bufferValidEnd;
- sectionToReadEnd = newBVE;
-
- bufferValidStart = newBVS;
- bufferValidEnd = jmin (bufferValidEnd, newBVE);
- }
-
- bufferStartPosLock.exit();
-
- if (sectionToReadStart != sectionToReadEnd)
- {
- const int bufferIndexStart = sectionToReadStart % buffer.getNumSamples();
- const int bufferIndexEnd = sectionToReadEnd % buffer.getNumSamples();
-
- if (bufferIndexStart < bufferIndexEnd)
- {
- readBufferSection (sectionToReadStart,
- sectionToReadEnd - sectionToReadStart,
- bufferIndexStart);
- }
- else
- {
- const int initialSize = buffer.getNumSamples() - bufferIndexStart;
-
- readBufferSection (sectionToReadStart,
- initialSize,
- bufferIndexStart);
-
- readBufferSection (sectionToReadStart + initialSize,
- (sectionToReadEnd - sectionToReadStart) - initialSize,
- 0);
- }
-
- const ScopedLock sl2 (bufferStartPosLock);
-
- bufferValidStart = newBVS;
- bufferValidEnd = newBVE;
-
- return true;
- }
- else
- {
- return false;
- }
- }
-
- void BufferingAudioSource::readBufferSection (int start, int length, int bufferOffset)
- {
- if (source->getNextReadPosition() != start)
- source->setNextReadPosition (start);
-
- AudioSourceChannelInfo info;
- info.buffer = &buffer;
- info.startSample = bufferOffset;
- info.numSamples = length;
-
- source->getNextAudioBlock (info);
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_BufferingAudioSource.cpp *********/
-
- /********* Start of inlined file: juce_ChannelRemappingAudioSource.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- ChannelRemappingAudioSource::ChannelRemappingAudioSource (AudioSource* const source_,
- const bool deleteSourceWhenDeleted_)
- : requiredNumberOfChannels (2),
- source (source_),
- deleteSourceWhenDeleted (deleteSourceWhenDeleted_),
- buffer (2, 16)
- {
- remappedInfo.buffer = &buffer;
- remappedInfo.startSample = 0;
- }
-
- ChannelRemappingAudioSource::~ChannelRemappingAudioSource()
- {
- if (deleteSourceWhenDeleted)
- delete source;
- }
-
- void ChannelRemappingAudioSource::setNumberOfChannelsToProduce (const int requiredNumberOfChannels_) throw()
- {
- const ScopedLock sl (lock);
- requiredNumberOfChannels = requiredNumberOfChannels_;
- }
-
- void ChannelRemappingAudioSource::clearAllMappings() throw()
- {
- const ScopedLock sl (lock);
-
- remappedInputs.clear();
- remappedOutputs.clear();
- }
-
- void ChannelRemappingAudioSource::setInputChannelMapping (const int destIndex, const int sourceIndex) throw()
- {
- const ScopedLock sl (lock);
-
- while (remappedInputs.size() < destIndex)
- remappedInputs.add (-1);
-
- remappedInputs.set (destIndex, sourceIndex);
- }
-
- void ChannelRemappingAudioSource::setOutputChannelMapping (const int sourceIndex, const int destIndex) throw()
- {
- const ScopedLock sl (lock);
-
- while (remappedOutputs.size() < sourceIndex)
- remappedOutputs.add (-1);
-
- remappedOutputs.set (sourceIndex, destIndex);
- }
-
- int ChannelRemappingAudioSource::getRemappedInputChannel (const int inputChannelIndex) const throw()
- {
- const ScopedLock sl (lock);
-
- if (inputChannelIndex >= 0 && inputChannelIndex < remappedInputs.size())
- return remappedInputs.getUnchecked (inputChannelIndex);
-
- return -1;
- }
-
- int ChannelRemappingAudioSource::getRemappedOutputChannel (const int outputChannelIndex) const throw()
- {
- const ScopedLock sl (lock);
-
- if (outputChannelIndex >= 0 && outputChannelIndex < remappedOutputs.size())
- return remappedOutputs .getUnchecked (outputChannelIndex);
-
- return -1;
- }
-
- void ChannelRemappingAudioSource::prepareToPlay (int samplesPerBlockExpected, double sampleRate)
- {
- source->prepareToPlay (samplesPerBlockExpected, sampleRate);
- }
-
- void ChannelRemappingAudioSource::releaseResources()
- {
- source->releaseResources();
- }
-
- void ChannelRemappingAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill)
- {
- const ScopedLock sl (lock);
-
- buffer.setSize (requiredNumberOfChannels, bufferToFill.numSamples, false, false, true);
-
- const int numChans = bufferToFill.buffer->getNumChannels();
-
- int i;
- for (i = 0; i < buffer.getNumChannels(); ++i)
- {
- const int remappedChan = getRemappedInputChannel (i);
-
- if (remappedChan >= 0 && remappedChan < numChans)
- {
- buffer.copyFrom (i, 0, *bufferToFill.buffer,
- remappedChan,
- bufferToFill.startSample,
- bufferToFill.numSamples);
- }
- else
- {
- buffer.clear (i, 0, bufferToFill.numSamples);
- }
- }
-
- remappedInfo.numSamples = bufferToFill.numSamples;
-
- source->getNextAudioBlock (remappedInfo);
-
- bufferToFill.clearActiveBufferRegion();
-
- for (i = 0; i < requiredNumberOfChannels; ++i)
- {
- const int remappedChan = getRemappedOutputChannel (i);
-
- if (remappedChan >= 0 && remappedChan < numChans)
- {
- bufferToFill.buffer->addFrom (remappedChan, bufferToFill.startSample,
- buffer, i, 0, bufferToFill.numSamples);
-
- }
- }
- }
-
- XmlElement* ChannelRemappingAudioSource::createXml() const throw()
- {
- XmlElement* e = new XmlElement (T("MAPPINGS"));
-
- String ins, outs;
- int i;
-
- const ScopedLock sl (lock);
-
- for (i = 0; i < remappedInputs.size(); ++i)
- ins << remappedInputs.getUnchecked(i) << T(' ');
-
- for (i = 0; i < remappedOutputs.size(); ++i)
- outs << remappedOutputs.getUnchecked(i) << T(' ');
-
- e->setAttribute (T("inputs"), ins.trimEnd());
- e->setAttribute (T("outputs"), outs.trimEnd());
-
- return e;
- }
-
- void ChannelRemappingAudioSource::restoreFromXml (const XmlElement& e) throw()
- {
- if (e.hasTagName (T("MAPPINGS")))
- {
- const ScopedLock sl (lock);
-
- clearAllMappings();
-
- StringArray ins, outs;
- ins.addTokens (e.getStringAttribute (T("inputs")), false);
- outs.addTokens (e.getStringAttribute (T("outputs")), false);
-
- int i;
- for (i = 0; i < ins.size(); ++i)
- remappedInputs.add (ins[i].getIntValue());
-
- for (i = 0; i < outs.size(); ++i)
- remappedOutputs.add (outs[i].getIntValue());
- }
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_ChannelRemappingAudioSource.cpp *********/
-
- /********* Start of inlined file: juce_IIRFilterAudioSource.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- IIRFilterAudioSource::IIRFilterAudioSource (AudioSource* const inputSource,
- const bool deleteInputWhenDeleted_)
- : input (inputSource),
- deleteInputWhenDeleted (deleteInputWhenDeleted_)
- {
- jassert (inputSource != 0);
-
- for (int i = 2; --i >= 0;)
- iirFilters.add (new IIRFilter());
- }
-
- IIRFilterAudioSource::~IIRFilterAudioSource()
- {
- if (deleteInputWhenDeleted)
- delete input;
- }
-
- void IIRFilterAudioSource::setFilterParameters (const IIRFilter& newSettings)
- {
- for (int i = iirFilters.size(); --i >= 0;)
- iirFilters.getUnchecked(i)->copyCoefficientsFrom (newSettings);
- }
-
- void IIRFilterAudioSource::prepareToPlay (int samplesPerBlockExpected, double sampleRate)
- {
- input->prepareToPlay (samplesPerBlockExpected, sampleRate);
-
- for (int i = iirFilters.size(); --i >= 0;)
- iirFilters.getUnchecked(i)->reset();
- }
-
- void IIRFilterAudioSource::releaseResources()
- {
- input->releaseResources();
- }
-
- void IIRFilterAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill)
- {
- input->getNextAudioBlock (bufferToFill);
-
- const int numChannels = bufferToFill.buffer->getNumChannels();
-
- while (numChannels > iirFilters.size())
- iirFilters.add (new IIRFilter (*iirFilters.getUnchecked (0)));
-
- for (int i = 0; i < numChannels; ++i)
- iirFilters.getUnchecked(i)
- ->processSamples (bufferToFill.buffer->getSampleData (i, bufferToFill.startSample),
- bufferToFill.numSamples);
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_IIRFilterAudioSource.cpp *********/
-
- /********* Start of inlined file: juce_MixerAudioSource.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- MixerAudioSource::MixerAudioSource()
- : tempBuffer (2, 0),
- currentSampleRate (0.0),
- bufferSizeExpected (0)
- {
- }
-
- MixerAudioSource::~MixerAudioSource()
- {
- removeAllInputs();
- }
-
- void MixerAudioSource::addInputSource (AudioSource* input, const bool deleteWhenRemoved)
- {
- if (input != 0 && ! inputs.contains (input))
- {
- lock.enter();
- double localRate = currentSampleRate;
- int localBufferSize = bufferSizeExpected;
- lock.exit();
-
- if (localRate != 0.0)
- input->prepareToPlay (localBufferSize, localRate);
-
- const ScopedLock sl (lock);
-
- inputsToDelete.setBit (inputs.size(), deleteWhenRemoved);
- inputs.add (input);
- }
- }
-
- void MixerAudioSource::removeInputSource (AudioSource* input, const bool deleteInput)
- {
- if (input != 0)
- {
- lock.enter();
- const int index = inputs.indexOf ((void*) input);
-
- if (index >= 0)
- {
- inputsToDelete.shiftBits (index, 1);
- inputs.remove (index);
- }
-
- lock.exit();
-
- if (index >= 0)
- {
- input->releaseResources();
-
- if (deleteInput)
- delete input;
- }
- }
- }
-
- void MixerAudioSource::removeAllInputs()
- {
- lock.enter();
- VoidArray inputsCopy (inputs);
- BitArray inputsToDeleteCopy (inputsToDelete);
- inputs.clear();
- lock.exit();
-
- for (int i = inputsCopy.size(); --i >= 0;)
- if (inputsToDeleteCopy[i])
- delete (AudioSource*) inputsCopy[i];
- }
-
- void MixerAudioSource::prepareToPlay (int samplesPerBlockExpected, double sampleRate)
- {
- tempBuffer.setSize (2, samplesPerBlockExpected);
-
- const ScopedLock sl (lock);
-
- currentSampleRate = sampleRate;
- bufferSizeExpected = samplesPerBlockExpected;
-
- for (int i = inputs.size(); --i >= 0;)
- ((AudioSource*) inputs.getUnchecked(i))->prepareToPlay (samplesPerBlockExpected,
- sampleRate);
- }
-
- void MixerAudioSource::releaseResources()
- {
- const ScopedLock sl (lock);
-
- for (int i = inputs.size(); --i >= 0;)
- ((AudioSource*) inputs.getUnchecked(i))->releaseResources();
-
- tempBuffer.setSize (2, 0);
-
- currentSampleRate = 0;
- bufferSizeExpected = 0;
- }
-
- void MixerAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& info)
- {
- const ScopedLock sl (lock);
-
- if (inputs.size() > 0)
- {
- ((AudioSource*) inputs.getUnchecked(0))->getNextAudioBlock (info);
-
- if (inputs.size() > 1)
- {
- tempBuffer.setSize (jmax (1, info.buffer->getNumChannels()),
- info.buffer->getNumSamples());
-
- AudioSourceChannelInfo info2;
- info2.buffer = &tempBuffer;
- info2.numSamples = info.numSamples;
- info2.startSample = 0;
-
- for (int i = 1; i < inputs.size(); ++i)
- {
- ((AudioSource*) inputs.getUnchecked(i))->getNextAudioBlock (info2);
-
- for (int chan = 0; chan < info.buffer->getNumChannels(); ++chan)
- info.buffer->addFrom (chan, info.startSample, tempBuffer, chan, 0, info.numSamples);
- }
- }
- }
- else
- {
- info.clearActiveBufferRegion();
- }
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_MixerAudioSource.cpp *********/
-
- /********* Start of inlined file: juce_ResamplingAudioSource.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- ResamplingAudioSource::ResamplingAudioSource (AudioSource* const inputSource,
- const bool deleteInputWhenDeleted_)
- : input (inputSource),
- deleteInputWhenDeleted (deleteInputWhenDeleted_),
- ratio (1.0),
- lastRatio (1.0),
- buffer (2, 0),
- sampsInBuffer (0)
- {
- jassert (input != 0);
- }
-
- ResamplingAudioSource::~ResamplingAudioSource()
- {
- if (deleteInputWhenDeleted)
- delete input;
- }
-
- void ResamplingAudioSource::setResamplingRatio (const double samplesInPerOutputSample)
- {
- jassert (samplesInPerOutputSample > 0);
-
- const ScopedLock sl (ratioLock);
- ratio = jmax (0.0, samplesInPerOutputSample);
- }
-
- void ResamplingAudioSource::prepareToPlay (int samplesPerBlockExpected,
- double sampleRate)
- {
- const ScopedLock sl (ratioLock);
-
- input->prepareToPlay (samplesPerBlockExpected, sampleRate);
-
- buffer.setSize (2, roundDoubleToInt (samplesPerBlockExpected * ratio) + 32);
- buffer.clear();
- sampsInBuffer = 0;
- bufferPos = 0;
- subSampleOffset = 0.0;
-
- createLowPass (ratio);
- resetFilters();
- }
-
- void ResamplingAudioSource::releaseResources()
- {
- input->releaseResources();
- buffer.setSize (2, 0);
- }
-
- void ResamplingAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& info)
- {
- const ScopedLock sl (ratioLock);
-
- if (lastRatio != ratio)
- {
- createLowPass (ratio);
- lastRatio = ratio;
- }
-
- const int sampsNeeded = roundDoubleToInt (info.numSamples * ratio) + 2;
-
- int bufferSize = buffer.getNumSamples();
-
- if (bufferSize < sampsNeeded + 8)
- {
- bufferPos %= bufferSize;
- bufferSize = sampsNeeded + 32;
- buffer.setSize (buffer.getNumChannels(), bufferSize, true, true);
- }
-
- bufferPos %= bufferSize;
-
- int endOfBufferPos = bufferPos + sampsInBuffer;
-
- while (sampsNeeded > sampsInBuffer)
- {
- endOfBufferPos %= bufferSize;
-
- int numToDo = jmin (sampsNeeded - sampsInBuffer,
- bufferSize - endOfBufferPos);
-
- AudioSourceChannelInfo readInfo;
- readInfo.buffer = &buffer;
- readInfo.numSamples = numToDo;
- readInfo.startSample = endOfBufferPos;
-
- input->getNextAudioBlock (readInfo);
-
- if (ratio > 1.0)
- {
- // for down-sampling, pre-apply the filter..
-
- for (int i = jmin (2, info.buffer->getNumChannels()); --i >= 0;)
- applyFilter (buffer.getSampleData (i, endOfBufferPos), numToDo, filterStates[i]);
- }
-
- sampsInBuffer += numToDo;
- endOfBufferPos += numToDo;
- }
-
- float* dl = info.buffer->getSampleData (0, info.startSample);
- float* dr = (info.buffer->getNumChannels() > 1) ? info.buffer->getSampleData (1, info.startSample) : 0;
-
- const float* const bl = buffer.getSampleData (0, 0);
- const float* const br = buffer.getSampleData (1, 0);
-
- int nextPos = (bufferPos + 1) % bufferSize;
-
- for (int m = info.numSamples; --m >= 0;)
- {
- const float alpha = (float) subSampleOffset;
- const float invAlpha = 1.0f - alpha;
-
- *dl++ = bl [bufferPos] * invAlpha + bl [nextPos] * alpha;
-
- if (dr != 0)
- *dr++ = br [bufferPos] * invAlpha + br [nextPos] * alpha;
-
- subSampleOffset += ratio;
-
- jassert (sampsInBuffer > 0);
-
- while (subSampleOffset >= 1.0)
- {
- if (++bufferPos >= bufferSize)
- bufferPos = 0;
-
- --sampsInBuffer;
-
- nextPos = (bufferPos + 1) % bufferSize;
- subSampleOffset -= 1.0;
- }
- }
-
- if (ratio < 1.0)
- {
- // for up-sampling, apply the filter after transposing..
-
- for (int i = jmin (2, info.buffer->getNumChannels()); --i >= 0;)
- applyFilter (info.buffer->getSampleData (i, info.startSample), info.numSamples, filterStates[i]);
- }
-
- jassert (sampsInBuffer >= 0);
- }
-
- void ResamplingAudioSource::createLowPass (const double ratio)
- {
- const double proportionalRate = (ratio > 1.0) ? 0.5 / ratio
- : 0.5 * ratio;
-
- const double n = 1.0 / tan (double_Pi * jmax (0.001, proportionalRate));
- const double nSquared = n * n;
- const double c1 = 1.0 / (1.0 + sqrt (2.0) * n + nSquared);
-
- setFilterCoefficients (c1,
- c1 * 2.0f,
- c1,
- 1.0,
- c1 * 2.0 * (1.0 - nSquared),
- c1 * (1.0 - sqrt (2.0) * n + nSquared));
- }
-
- void ResamplingAudioSource::setFilterCoefficients (double c1, double c2, double c3, double c4, double c5, double c6)
- {
- const double a = 1.0 / c4;
-
- c1 *= a;
- c2 *= a;
- c3 *= a;
- c5 *= a;
- c6 *= a;
-
- coefficients[0] = c1;
- coefficients[1] = c2;
- coefficients[2] = c3;
- coefficients[3] = c4;
- coefficients[4] = c5;
- coefficients[5] = c6;
- }
-
- void ResamplingAudioSource::resetFilters()
- {
- zeromem (filterStates, sizeof (filterStates));
- }
-
- void ResamplingAudioSource::applyFilter (float* samples, int num, FilterState& fs)
- {
- while (--num >= 0)
- {
- const double in = *samples;
-
- double out = coefficients[0] * in
- + coefficients[1] * fs.x1
- + coefficients[2] * fs.x2
- - coefficients[4] * fs.y1
- - coefficients[5] * fs.y2;
-
- #if JUCE_INTEL
- if (! (out < -1.0e-8 || out > 1.0e-8))
- out = 0;
- #endif
-
- fs.x2 = fs.x1;
- fs.x1 = in;
- fs.y2 = fs.y1;
- fs.y1 = out;
-
- *samples++ = (float) out;
- }
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_ResamplingAudioSource.cpp *********/
-
- /********* Start of inlined file: juce_ToneGeneratorAudioSource.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- ToneGeneratorAudioSource::ToneGeneratorAudioSource()
- : frequency (1000.0),
- sampleRate (44100.0),
- currentPhase (0.0),
- phasePerSample (0.0),
- amplitude (0.5f)
- {
- }
-
- ToneGeneratorAudioSource::~ToneGeneratorAudioSource()
- {
- }
-
- void ToneGeneratorAudioSource::setAmplitude (const float newAmplitude)
- {
- amplitude = newAmplitude;
- }
-
- void ToneGeneratorAudioSource::setFrequency (const double newFrequencyHz)
- {
- frequency = newFrequencyHz;
- phasePerSample = 0.0;
- }
-
- void ToneGeneratorAudioSource::prepareToPlay (int /*samplesPerBlockExpected*/,
- double sampleRate_)
- {
- currentPhase = 0.0;
- phasePerSample = 0.0;
- sampleRate = sampleRate_;
- }
-
- void ToneGeneratorAudioSource::releaseResources()
- {
- }
-
- void ToneGeneratorAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& info)
- {
- if (phasePerSample == 0.0)
- phasePerSample = double_Pi * 2.0 / (sampleRate / frequency);
-
- for (int i = 0; i < info.numSamples; ++i)
- {
- const float sample = amplitude * (float) sin (currentPhase);
- currentPhase += phasePerSample;
-
- for (int j = info.buffer->getNumChannels(); --j >= 0;)
- *info.buffer->getSampleData (j, info.startSample + i) = sample;
- }
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_ToneGeneratorAudioSource.cpp *********/
-
- /********* Start of inlined file: juce_AudioDeviceManager.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- AudioDeviceManager::AudioDeviceSetup::AudioDeviceSetup()
- : sampleRate (0),
- bufferSize (0),
- useDefaultInputChannels (true),
- useDefaultOutputChannels (true)
- {
- }
-
- bool AudioDeviceManager::AudioDeviceSetup::operator== (const AudioDeviceManager::AudioDeviceSetup& other) const
- {
- return outputDeviceName == other.outputDeviceName
- && inputDeviceName == other.inputDeviceName
- && sampleRate == other.sampleRate
- && bufferSize == other.bufferSize
- && inputChannels == other.inputChannels
- && useDefaultInputChannels == other.useDefaultInputChannels
- && outputChannels == other.outputChannels
- && useDefaultOutputChannels == other.useDefaultOutputChannels;
- }
-
- AudioDeviceManager::AudioDeviceManager()
- : currentAudioDevice (0),
- currentCallback (0),
- numInputChansNeeded (0),
- numOutputChansNeeded (2),
- lastExplicitSettings (0),
- listNeedsScanning (true),
- useInputNames (false),
- inputLevelMeasurementEnabled (false),
- inputLevel (0),
- testSound (0),
- enabledMidiInputs (4),
- midiCallbacks (4),
- midiCallbackDevices (4),
- defaultMidiOutput (0),
- cpuUsageMs (0),
- timeToCpuScale (0)
- {
- callbackHandler.owner = this;
- }
-
- AudioDeviceManager::~AudioDeviceManager()
- {
- deleteAndZero (currentAudioDevice);
- deleteAndZero (defaultMidiOutput);
- delete lastExplicitSettings;
- delete testSound;
- }
-
- void AudioDeviceManager::createDeviceTypesIfNeeded()
- {
- if (availableDeviceTypes.size() == 0)
- {
- createAudioDeviceTypes (availableDeviceTypes);
-
- while (lastDeviceTypeConfigs.size() < availableDeviceTypes.size())
- lastDeviceTypeConfigs.add (new AudioDeviceSetup());
-
- if (availableDeviceTypes.size() > 0)
- currentDeviceType = availableDeviceTypes.getUnchecked(0)->getTypeName();
- }
- }
-
- const OwnedArray <AudioIODeviceType>& AudioDeviceManager::getAvailableDeviceTypes()
- {
- scanDevicesIfNeeded();
- return availableDeviceTypes;
- }
-
- extern AudioIODeviceType* juce_createDefaultAudioIODeviceType();
-
- #if JUCE_WIN32 && JUCE_ASIO
- extern AudioIODeviceType* juce_createASIOAudioIODeviceType();
- #endif
-
- #if JUCE_WIN32 && JUCE_WDM_AUDIO
- extern AudioIODeviceType* juce_createWDMAudioIODeviceType();
- #endif
-
- void AudioDeviceManager::createAudioDeviceTypes (OwnedArray <AudioIODeviceType>& list)
- {
- AudioIODeviceType* const defaultDeviceType = juce_createDefaultAudioIODeviceType();
-
- if (defaultDeviceType != 0)
- list.add (defaultDeviceType);
-
- #if JUCE_WIN32 && JUCE_ASIO
- list.add (juce_createASIOAudioIODeviceType());
- #endif
-
- #if JUCE_WIN32 && JUCE_WDM_AUDIO
- list.add (juce_createWDMAudioIODeviceType());
- #endif
- }
-
- const String AudioDeviceManager::initialise (const int numInputChannelsNeeded,
- const int numOutputChannelsNeeded,
- const XmlElement* const e,
- const bool selectDefaultDeviceOnFailure,
- const String& preferredDefaultDeviceName)
- {
- scanDevicesIfNeeded();
-
- numInputChansNeeded = numInputChannelsNeeded;
- numOutputChansNeeded = numOutputChannelsNeeded;
-
- if (e != 0 && e->hasTagName (T("DEVICESETUP")))
- {
- delete lastExplicitSettings;
- lastExplicitSettings = new XmlElement (*e);
-
- String error;
- AudioDeviceSetup setup;
-
- if (e->getStringAttribute (T("audioDeviceName")).isNotEmpty())
- {
- setup.inputDeviceName = setup.outputDeviceName
- = e->getStringAttribute (T("audioDeviceName"));
- }
- else
- {
- setup.inputDeviceName = e->getStringAttribute (T("audioInputDeviceName"));
- setup.outputDeviceName = e->getStringAttribute (T("audioOutputDeviceName"));
- }
-
- currentDeviceType = e->getStringAttribute (T("deviceType"));
- if (currentDeviceType.isEmpty())
- {
- AudioIODeviceType* const type = findType (setup.inputDeviceName, setup.outputDeviceName);
-
- if (type != 0)
- currentDeviceType = type->getTypeName();
- else if (availableDeviceTypes.size() > 0)
- currentDeviceType = availableDeviceTypes[0]->getTypeName();
- }
-
- setup.bufferSize = e->getIntAttribute (T("audioDeviceBufferSize"));
- setup.sampleRate = e->getDoubleAttribute (T("audioDeviceRate"));
-
- setup.inputChannels.parseString (e->getStringAttribute (T("audioDeviceInChans"), T("11")), 2);
- setup.outputChannels.parseString (e->getStringAttribute (T("audioDeviceOutChans"), T("11")), 2);
-
- setup.useDefaultInputChannels = ! e->hasAttribute (T("audioDeviceInChans"));
- setup.useDefaultOutputChannels = ! e->hasAttribute (T("audioDeviceOutChans"));
-
- error = setAudioDeviceSetup (setup, true);
-
- midiInsFromXml.clear();
- forEachXmlChildElementWithTagName (*e, c, T("MIDIINPUT"))
- midiInsFromXml.add (c->getStringAttribute (T("name")));
-
- const StringArray allMidiIns (MidiInput::getDevices());
-
- for (int i = allMidiIns.size(); --i >= 0;)
- setMidiInputEnabled (allMidiIns[i], midiInsFromXml.contains (allMidiIns[i]));
-
- if (error.isNotEmpty() && selectDefaultDeviceOnFailure)
- error = initialise (numInputChannelsNeeded, numOutputChannelsNeeded, 0,
- false, preferredDefaultDeviceName);
-
- setDefaultMidiOutput (e->getStringAttribute (T("defaultMidiOutput")));
-
- return error;
- }
- else
- {
- AudioDeviceSetup setup;
-
- if (preferredDefaultDeviceName.isNotEmpty())
- {
- for (int j = availableDeviceTypes.size(); --j >= 0;)
- {
- AudioIODeviceType* const type = availableDeviceTypes.getUnchecked(j);
-
- StringArray outs (type->getDeviceNames (false));
-
- int i;
- for (i = 0; i < outs.size(); ++i)
- {
- if (outs[i].matchesWildcard (preferredDefaultDeviceName, true))
- {
- setup.outputDeviceName = outs[i];
- break;
- }
- }
-
- StringArray ins (type->getDeviceNames (true));
-
- for (i = 0; i < ins.size(); ++i)
- {
- if (ins[i].matchesWildcard (preferredDefaultDeviceName, true))
- {
- setup.inputDeviceName = ins[i];
- break;
- }
- }
- }
- }
-
- insertDefaultDeviceNames (setup);
- return setAudioDeviceSetup (setup, false);
- }
- }
-
- void AudioDeviceManager::insertDefaultDeviceNames (AudioDeviceSetup& setup) const
- {
- AudioIODeviceType* type = getCurrentDeviceTypeObject();
- if (type != 0)
- {
- if (setup.outputDeviceName.isEmpty())
- setup.outputDeviceName = type->getDeviceNames (false) [type->getDefaultDeviceIndex (false)];
-
- if (setup.inputDeviceName.isEmpty())
- setup.inputDeviceName = type->getDeviceNames (true) [type->getDefaultDeviceIndex (true)];
- }
- }
-
- XmlElement* AudioDeviceManager::createStateXml() const
- {
- return lastExplicitSettings != 0 ? new XmlElement (*lastExplicitSettings) : 0;
- }
-
- void AudioDeviceManager::scanDevicesIfNeeded()
- {
- if (listNeedsScanning)
- {
- listNeedsScanning = false;
-
- createDeviceTypesIfNeeded();
-
- for (int i = availableDeviceTypes.size(); --i >= 0;)
- availableDeviceTypes.getUnchecked(i)->scanForDevices();
- }
- }
-
- AudioIODeviceType* AudioDeviceManager::findType (const String& inputName, const String& outputName)
- {
- scanDevicesIfNeeded();
-
- for (int i = availableDeviceTypes.size(); --i >= 0;)
- {
- AudioIODeviceType* const type = availableDeviceTypes.getUnchecked(i);
-
- if ((inputName.isNotEmpty() && type->getDeviceNames (true).contains (inputName, true))
- || (outputName.isNotEmpty() && type->getDeviceNames (false).contains (outputName, true)))
- {
- return type;
- }
- }
-
- return 0;
- }
-
- void AudioDeviceManager::getAudioDeviceSetup (AudioDeviceSetup& setup)
- {
- setup = currentSetup;
- }
-
- void AudioDeviceManager::deleteCurrentDevice()
- {
- deleteAndZero (currentAudioDevice);
- currentSetup.inputDeviceName = String::empty;
- currentSetup.outputDeviceName = String::empty;
- }
-
- void AudioDeviceManager::setCurrentAudioDeviceType (const String& type,
- const bool treatAsChosenDevice)
- {
- for (int i = 0; i < availableDeviceTypes.size(); ++i)
- {
- if (availableDeviceTypes.getUnchecked(i)->getTypeName() == type
- && currentDeviceType != type)
- {
- currentDeviceType = type;
-
- AudioDeviceSetup s (*lastDeviceTypeConfigs.getUnchecked(i));
- insertDefaultDeviceNames (s);
-
- setAudioDeviceSetup (s, treatAsChosenDevice);
-
- sendChangeMessage (this);
- break;
- }
- }
- }
-
- AudioIODeviceType* AudioDeviceManager::getCurrentDeviceTypeObject() const
- {
- for (int i = 0; i < availableDeviceTypes.size(); ++i)
- if (availableDeviceTypes[i]->getTypeName() == currentDeviceType)
- return availableDeviceTypes[i];
-
- return availableDeviceTypes[0];
- }
-
- const String AudioDeviceManager::setAudioDeviceSetup (const AudioDeviceSetup& newSetup,
- const bool treatAsChosenDevice)
- {
- jassert (&newSetup != ¤tSetup); // this will have no effect
-
- if (newSetup == currentSetup && currentAudioDevice != 0)
- return String::empty;
-
- if (! (newSetup == currentSetup))
- sendChangeMessage (this);
-
- stopDevice();
- String error;
- AudioIODeviceType* type = getCurrentDeviceTypeObject();
-
- if (type == 0 || (newSetup.inputDeviceName.isEmpty()
- && newSetup.outputDeviceName.isEmpty()))
- {
- deleteCurrentDevice();
-
- if (treatAsChosenDevice)
- updateXml();
-
- return String::empty;
- }
-
- if (currentSetup.inputDeviceName != newSetup.inputDeviceName
- || currentSetup.outputDeviceName != newSetup.outputDeviceName
- || currentAudioDevice == 0)
- {
- deleteCurrentDevice();
- scanDevicesIfNeeded();
-
- if (newSetup.outputDeviceName.isNotEmpty()
- && ! type->getDeviceNames (false).contains (newSetup.outputDeviceName))
- {
- return "No such device: " + newSetup.outputDeviceName;
- }
-
- if (newSetup.inputDeviceName.isNotEmpty()
- && ! type->getDeviceNames (true).contains (newSetup.inputDeviceName))
- {
- return "No such device: " + newSetup.outputDeviceName;
- }
-
- currentAudioDevice = type->createDevice (newSetup.outputDeviceName,
- newSetup.inputDeviceName);
-
- if (currentAudioDevice == 0)
- error = "Can't open device";
- else
- error = currentAudioDevice->getLastError();
-
- if (error.isNotEmpty())
- {
- deleteCurrentDevice();
- return error;
- }
-
- if (newSetup.useDefaultInputChannels)
- {
- inputChannels.clear();
- inputChannels.setRange (0, numInputChansNeeded, true);
- }
-
- if (newSetup.useDefaultOutputChannels)
- {
- outputChannels.clear();
- outputChannels.setRange (0, numOutputChansNeeded, true);
- }
- }
-
- if (! newSetup.useDefaultInputChannels)
- inputChannels = newSetup.inputChannels;
-
- if (! newSetup.useDefaultOutputChannels)
- outputChannels = newSetup.outputChannels;
-
- currentSetup = newSetup;
-
- currentSetup.sampleRate = chooseBestSampleRate (newSetup.sampleRate);
-
- error = currentAudioDevice->open (inputChannels,
- outputChannels,
- currentSetup.sampleRate,
- currentSetup.bufferSize);
-
- if (error.isEmpty())
- {
- currentDeviceType = currentAudioDevice->getTypeName();
-
- currentAudioDevice->start (&callbackHandler);
-
- currentSetup.sampleRate = currentAudioDevice->getCurrentSampleRate();
- currentSetup.bufferSize = currentAudioDevice->getCurrentBufferSizeSamples();
- currentSetup.inputChannels = currentAudioDevice->getActiveInputChannels();
- currentSetup.outputChannels = currentAudioDevice->getActiveOutputChannels();
-
- for (int i = 0; i < availableDeviceTypes.size(); ++i)
- if (availableDeviceTypes.getUnchecked (i)->getTypeName() == currentDeviceType)
- *(lastDeviceTypeConfigs.getUnchecked (i)) = currentSetup;
-
- if (treatAsChosenDevice)
- updateXml();
- }
- else
- {
- deleteCurrentDevice();
- }
-
- return error;
- }
-
- double AudioDeviceManager::chooseBestSampleRate (double rate) const
- {
- jassert (currentAudioDevice != 0);
-
- if (rate > 0)
- {
- bool ok = false;
-
- for (int i = currentAudioDevice->getNumSampleRates(); --i >= 0;)
- {
- const double sr = currentAudioDevice->getSampleRate (i);
-
- if (sr == rate)
- ok = true;
- }
-
- if (! ok)
- rate = 0;
- }
-
- if (rate == 0)
- {
- double lowestAbove44 = 0.0;
-
- for (int i = currentAudioDevice->getNumSampleRates(); --i >= 0;)
- {
- const double sr = currentAudioDevice->getSampleRate (i);
-
- if (sr >= 44100.0 && (lowestAbove44 == 0 || sr < lowestAbove44))
- lowestAbove44 = sr;
- }
-
- if (lowestAbove44 == 0.0)
- rate = currentAudioDevice->getSampleRate (0);
- else
- rate = lowestAbove44;
- }
-
- return rate;
- }
-
- void AudioDeviceManager::stopDevice()
- {
- if (currentAudioDevice != 0)
- currentAudioDevice->stop();
- }
-
- void AudioDeviceManager::closeAudioDevice()
- {
- stopDevice();
- deleteAndZero (currentAudioDevice);
- }
-
- void AudioDeviceManager::restartLastAudioDevice()
- {
- if (currentAudioDevice == 0)
- {
- if (currentSetup.inputDeviceName.isEmpty()
- && currentSetup.outputDeviceName.isEmpty())
- {
- // This method will only reload the last device that was running
- // before closeAudioDevice() was called - you need to actually open
- // one first, with setAudioDevice().
- jassertfalse
- return;
- }
-
- AudioDeviceSetup s (currentSetup);
- setAudioDeviceSetup (s, false);
- }
- }
-
- void AudioDeviceManager::updateXml()
- {
- delete lastExplicitSettings;
- lastExplicitSettings = new XmlElement (T("DEVICESETUP"));
-
- lastExplicitSettings->setAttribute (T("deviceType"), currentDeviceType);
- lastExplicitSettings->setAttribute (T("audioOutputDeviceName"), currentSetup.outputDeviceName);
- lastExplicitSettings->setAttribute (T("audioInputDeviceName"), currentSetup.inputDeviceName);
-
- if (currentAudioDevice != 0)
- {
- lastExplicitSettings->setAttribute (T("audioDeviceRate"), currentAudioDevice->getCurrentSampleRate());
-
- if (currentAudioDevice->getDefaultBufferSize() != currentAudioDevice->getCurrentBufferSizeSamples())
- lastExplicitSettings->setAttribute (T("audioDeviceBufferSize"), currentAudioDevice->getCurrentBufferSizeSamples());
-
- if (! currentSetup.useDefaultInputChannels)
- lastExplicitSettings->setAttribute (T("audioDeviceInChans"), currentSetup.inputChannels.toString (2));
-
- if (! currentSetup.useDefaultOutputChannels)
- lastExplicitSettings->setAttribute (T("audioDeviceOutChans"), currentSetup.outputChannels.toString (2));
- }
-
- for (int i = 0; i < enabledMidiInputs.size(); ++i)
- {
- XmlElement* const m = new XmlElement (T("MIDIINPUT"));
- m->setAttribute (T("name"), enabledMidiInputs[i]->getName());
-
- lastExplicitSettings->addChildElement (m);
- }
-
- if (midiInsFromXml.size() > 0)
- {
- // Add any midi devices that have been enabled before, but which aren't currently
- // open because the device has been disconnected.
- const StringArray availableMidiDevices (MidiInput::getDevices());
-
- for (int i = 0; i < midiInsFromXml.size(); ++i)
- {
- if (! availableMidiDevices.contains (midiInsFromXml[i], true))
- {
- XmlElement* const m = new XmlElement (T("MIDIINPUT"));
- m->setAttribute (T("name"), midiInsFromXml[i]);
-
- lastExplicitSettings->addChildElement (m);
- }
- }
- }
-
- if (defaultMidiOutputName.isNotEmpty())
- lastExplicitSettings->setAttribute (T("defaultMidiOutput"), defaultMidiOutputName);
- }
-
- void AudioDeviceManager::setAudioCallback (AudioIODeviceCallback* newCallback)
- {
- if (newCallback != currentCallback)
- {
- AudioIODeviceCallback* lastCallback = currentCallback;
-
- audioCallbackLock.enter();
- currentCallback = 0;
- audioCallbackLock.exit();
-
- if (currentAudioDevice != 0)
- {
- if (lastCallback != 0)
- lastCallback->audioDeviceStopped();
-
- if (newCallback != 0)
- newCallback->audioDeviceAboutToStart (currentAudioDevice);
- }
-
- currentCallback = newCallback;
- }
- }
-
- void AudioDeviceManager::audioDeviceIOCallbackInt (const float** inputChannelData,
- int numInputChannels,
- float** outputChannelData,
- int numOutputChannels,
- int numSamples)
- {
- const ScopedLock sl (audioCallbackLock);
-
- if (inputLevelMeasurementEnabled)
- {
- for (int j = 0; j < numSamples; ++j)
- {
- float s = 0;
-
- for (int i = 0; i < numInputChannels; ++i)
- s += fabsf (inputChannelData[i][j]);
-
- s /= numInputChannels;
-
- const double decayFactor = 0.99992;
-
- if (s > inputLevel)
- inputLevel = s;
- else if (inputLevel > 0.001f)
- inputLevel *= decayFactor;
- else
- inputLevel = 0;
- }
- }
-
- if (currentCallback != 0)
- {
- const double callbackStartTime = Time::getMillisecondCounterHiRes();
-
- currentCallback->audioDeviceIOCallback (inputChannelData,
- numInputChannels,
- outputChannelData,
- numOutputChannels,
- numSamples);
-
- const double msTaken = Time::getMillisecondCounterHiRes() - callbackStartTime;
- const double filterAmount = 0.2;
- cpuUsageMs += filterAmount * (msTaken - cpuUsageMs);
- }
- else
- {
- for (int i = 0; i < numOutputChannels; ++i)
- zeromem (outputChannelData[i], sizeof (float) * numSamples);
- }
-
- if (testSound != 0)
- {
- const int numSamps = jmin (numSamples, testSound->getNumSamples() - testSoundPosition);
- const float* const src = testSound->getSampleData (0, testSoundPosition);
-
- for (int i = 0; i < numOutputChannels; ++i)
- for (int j = 0; j < numSamps; ++j)
- outputChannelData [i][j] += src[j];
-
- testSoundPosition += numSamps;
- if (testSoundPosition >= testSound->getNumSamples())
- {
- delete testSound;
- testSound = 0;
- }
- }
- }
-
- void AudioDeviceManager::audioDeviceAboutToStartInt (AudioIODevice* const device)
- {
- cpuUsageMs = 0;
-
- const double sampleRate = device->getCurrentSampleRate();
- const int blockSize = device->getCurrentBufferSizeSamples();
-
- if (sampleRate > 0.0 && blockSize > 0)
- {
- const double msPerBlock = 1000.0 * blockSize / sampleRate;
- timeToCpuScale = (msPerBlock > 0.0) ? (1.0 / msPerBlock) : 0.0;
- }
-
- if (currentCallback != 0)
- currentCallback->audioDeviceAboutToStart (device);
-
- sendChangeMessage (this);
- }
-
- void AudioDeviceManager::audioDeviceStoppedInt()
- {
- cpuUsageMs = 0;
- timeToCpuScale = 0;
- sendChangeMessage (this);
-
- if (currentCallback != 0)
- currentCallback->audioDeviceStopped();
- }
-
- double AudioDeviceManager::getCpuUsage() const
- {
- return jlimit (0.0, 1.0, timeToCpuScale * cpuUsageMs);
- }
-
- void AudioDeviceManager::setMidiInputEnabled (const String& name,
- const bool enabled)
- {
- if (enabled != isMidiInputEnabled (name))
- {
- if (enabled)
- {
- const int index = MidiInput::getDevices().indexOf (name);
-
- if (index >= 0)
- {
- MidiInput* const min = MidiInput::openDevice (index, &callbackHandler);
-
- if (min != 0)
- {
- enabledMidiInputs.add (min);
- min->start();
- }
- }
- }
- else
- {
- for (int i = enabledMidiInputs.size(); --i >= 0;)
- if (enabledMidiInputs[i]->getName() == name)
- enabledMidiInputs.remove (i);
- }
-
- updateXml();
- sendChangeMessage (this);
- }
- }
-
- bool AudioDeviceManager::isMidiInputEnabled (const String& name) const
- {
- for (int i = enabledMidiInputs.size(); --i >= 0;)
- if (enabledMidiInputs[i]->getName() == name)
- return true;
-
- return false;
- }
-
- void AudioDeviceManager::addMidiInputCallback (const String& name,
- MidiInputCallback* callback)
- {
- removeMidiInputCallback (name, callback);
-
- if (name.isEmpty())
- {
- midiCallbacks.add (callback);
- midiCallbackDevices.add (0);
- }
- else
- {
- for (int i = enabledMidiInputs.size(); --i >= 0;)
- {
- if (enabledMidiInputs[i]->getName() == name)
- {
- const ScopedLock sl (midiCallbackLock);
- midiCallbacks.add (callback);
- midiCallbackDevices.add (enabledMidiInputs[i]);
- break;
- }
- }
- }
- }
-
- void AudioDeviceManager::removeMidiInputCallback (const String& name,
- MidiInputCallback* /*callback*/)
- {
- const ScopedLock sl (midiCallbackLock);
-
- for (int i = midiCallbacks.size(); --i >= 0;)
- {
- String devName;
-
- if (midiCallbackDevices.getUnchecked(i) != 0)
- devName = midiCallbackDevices.getUnchecked(i)->getName();
-
- if (devName == name)
- {
- midiCallbacks.remove (i);
- midiCallbackDevices.remove (i);
- }
- }
- }
-
- void AudioDeviceManager::handleIncomingMidiMessageInt (MidiInput* source,
- const MidiMessage& message)
- {
- if (! message.isActiveSense())
- {
- const bool isDefaultSource = (source == 0 || source == enabledMidiInputs.getFirst());
-
- const ScopedLock sl (midiCallbackLock);
-
- for (int i = midiCallbackDevices.size(); --i >= 0;)
- {
- MidiInput* const md = midiCallbackDevices.getUnchecked(i);
-
- if (md == source || (md == 0 && isDefaultSource))
- midiCallbacks.getUnchecked(i)->handleIncomingMidiMessage (source, message);
- }
- }
- }
-
- void AudioDeviceManager::setDefaultMidiOutput (const String& deviceName)
- {
- if (defaultMidiOutputName != deviceName)
- {
- deleteAndZero (defaultMidiOutput);
- defaultMidiOutputName = deviceName;
-
- if (deviceName.isNotEmpty())
- defaultMidiOutput = MidiOutput::openDevice (MidiOutput::getDevices().indexOf (deviceName));
-
- updateXml();
- sendChangeMessage (this);
- }
- }
-
- void AudioDeviceManager::CallbackHandler::audioDeviceIOCallback (const float** inputChannelData,
- int numInputChannels,
- float** outputChannelData,
- int numOutputChannels,
- int numSamples)
- {
- owner->audioDeviceIOCallbackInt (inputChannelData, numInputChannels, outputChannelData, numOutputChannels, numSamples);
- }
-
- void AudioDeviceManager::CallbackHandler::audioDeviceAboutToStart (AudioIODevice* device)
- {
- owner->audioDeviceAboutToStartInt (device);
- }
-
- void AudioDeviceManager::CallbackHandler::audioDeviceStopped()
- {
- owner->audioDeviceStoppedInt();
- }
-
- void AudioDeviceManager::CallbackHandler::handleIncomingMidiMessage (MidiInput* source, const MidiMessage& message)
- {
- owner->handleIncomingMidiMessageInt (source, message);
- }
-
- void AudioDeviceManager::playTestSound()
- {
- audioCallbackLock.enter();
- AudioSampleBuffer* oldSound = testSound;
- testSound = 0;
- audioCallbackLock.exit();
- delete oldSound;
-
- testSoundPosition = 0;
-
- if (currentAudioDevice != 0)
- {
- const double sampleRate = currentAudioDevice->getCurrentSampleRate();
- const int soundLength = (int) sampleRate;
-
- AudioSampleBuffer* const newSound = new AudioSampleBuffer (1, soundLength);
- float* samples = newSound->getSampleData (0);
-
- const double frequency = MidiMessage::getMidiNoteInHertz (80);
- const float amplitude = 0.5f;
-
- const double phasePerSample = double_Pi * 2.0 / (sampleRate / frequency);
-
- for (int i = 0; i < soundLength; ++i)
- samples[i] = amplitude * (float) sin (i * phasePerSample);
-
- newSound->applyGainRamp (0, 0, soundLength / 10, 0.0f, 1.0f);
- newSound->applyGainRamp (0, soundLength - soundLength / 4, soundLength / 4, 1.0f, 0.0f);
-
- const ScopedLock sl (audioCallbackLock);
- testSound = newSound;
- }
- }
-
- void AudioDeviceManager::enableInputLevelMeasurement (const bool enableMeasurement)
- {
- if (inputLevelMeasurementEnabled != enableMeasurement)
- {
- const ScopedLock sl (audioCallbackLock);
- inputLevelMeasurementEnabled = enableMeasurement;
- inputLevel = 0;
- }
- }
-
- double AudioDeviceManager::getCurrentInputLevel() const
- {
- jassert (inputLevelMeasurementEnabled); // you need to call enableInputLevelMeasurement() before using this!
- return inputLevel;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_AudioDeviceManager.cpp *********/
-
- /********* Start of inlined file: juce_AudioIODevice.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- AudioIODevice::AudioIODevice (const String& deviceName, const String& typeName_)
- : name (deviceName),
- typeName (typeName_)
- {
- }
-
- AudioIODevice::~AudioIODevice()
- {
- }
-
- bool AudioIODevice::hasControlPanel() const
- {
- return false;
- }
-
- bool AudioIODevice::showControlPanel()
- {
- jassertfalse // this should only be called for devices which return true from
- // their hasControlPanel() method.
- return false;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_AudioIODevice.cpp *********/
-
- /********* Start of inlined file: juce_AudioIODeviceType.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- AudioIODeviceType::AudioIODeviceType (const tchar* const name)
- : typeName (name)
- {
- }
-
- AudioIODeviceType::~AudioIODeviceType()
- {
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_AudioIODeviceType.cpp *********/
-
- /********* Start of inlined file: juce_MidiOutput.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- MidiOutput::MidiOutput() throw()
- : Thread ("midi out"),
- internal (0),
- firstMessage (0)
- {
- }
-
- MidiOutput::PendingMessage::PendingMessage (const uint8* const data,
- const int len,
- const double sampleNumber) throw()
- : message (data, len, sampleNumber)
- {
- }
-
- void MidiOutput::sendBlockOfMessages (const MidiBuffer& buffer,
- const double millisecondCounterToStartAt,
- double samplesPerSecondForBuffer) throw()
- {
- // You've got to call startBackgroundThread() for this to actually work..
- jassert (isThreadRunning());
-
- // this needs to be a value in the future - RTFM for this method!
- jassert (millisecondCounterToStartAt > 0);
-
- samplesPerSecondForBuffer *= 0.001;
-
- MidiBuffer::Iterator i (buffer);
-
- const uint8* data;
- int len, time;
-
- while (i.getNextEvent (data, len, time))
- {
- const double eventTime = millisecondCounterToStartAt + samplesPerSecondForBuffer * time;
-
- PendingMessage* const m
- = new PendingMessage (data, len, eventTime);
-
- const ScopedLock sl (lock);
-
- if (firstMessage == 0 || firstMessage->message.getTimeStamp() > eventTime)
- {
- m->next = firstMessage;
- firstMessage = m;
- }
- else
- {
- PendingMessage* mm = firstMessage;
-
- while (mm->next != 0 && mm->next->message.getTimeStamp() <= eventTime)
- mm = mm->next;
-
- m->next = mm->next;
- mm->next = m;
- }
- }
-
- notify();
- }
-
- void MidiOutput::clearAllPendingMessages() throw()
- {
- const ScopedLock sl (lock);
-
- while (firstMessage != 0)
- {
- PendingMessage* const m = firstMessage;
- firstMessage = firstMessage->next;
- delete m;
- }
- }
-
- void MidiOutput::startBackgroundThread() throw()
- {
- startThread (9);
- }
-
- void MidiOutput::stopBackgroundThread() throw()
- {
- stopThread (5000);
- }
-
- void MidiOutput::run()
- {
- while (! threadShouldExit())
- {
- uint32 now = Time::getMillisecondCounter();
- uint32 eventTime = 0;
- uint32 timeToWait = 500;
-
- lock.enter();
- PendingMessage* message = firstMessage;
-
- if (message != 0)
- {
- eventTime = roundDoubleToInt (message->message.getTimeStamp());
-
- if (eventTime > now + 20)
- {
- timeToWait = jmax (10, eventTime - now - 100);
- message = 0;
- }
- else
- {
- firstMessage = message->next;
- }
- }
-
- lock.exit();
-
- if (message != 0)
- {
- if (eventTime > now)
- {
- Time::waitForMillisecondCounter (eventTime);
-
- if (threadShouldExit())
- break;
- }
-
- if (eventTime > now - 200)
- sendMessageNow (message->message);
-
- delete message;
- }
- else
- {
- jassert (timeToWait < 1000 * 30);
- wait (timeToWait);
- }
- }
-
- clearAllPendingMessages();
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_MidiOutput.cpp *********/
-
- /********* Start of inlined file: juce_AudioDataConverters.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- void AudioDataConverters::convertFloatToInt16LE (const float* source, void* dest, int numSamples, const int destBytesPerSample)
- {
- const double maxVal = (double) 0x7fff;
- char* intData = (char*) dest;
-
- for (int i = 0; i < numSamples; ++i)
- {
- *(uint16*)intData = swapIfBigEndian ((uint16) (short) roundDoubleToInt (jlimit (-maxVal, maxVal, maxVal * source[i])));
- intData += destBytesPerSample;
- }
- }
-
- void AudioDataConverters::convertFloatToInt16BE (const float* source, void* dest, int numSamples, const int destBytesPerSample)
- {
- const double maxVal = (double) 0x7fff;
- char* intData = (char*) dest;
-
- for (int i = 0; i < numSamples; ++i)
- {
- *(uint16*)intData = swapIfLittleEndian ((uint16) (short) roundDoubleToInt (jlimit (-maxVal, maxVal, maxVal * source[i])));
- intData += destBytesPerSample;
- }
- }
-
- void AudioDataConverters::convertFloatToInt24LE (const float* source, void* dest, int numSamples, const int destBytesPerSample)
- {
- const double maxVal = (double) 0x7fffff;
- char* intData = (char*) dest;
-
- for (int i = 0; i < numSamples; ++i)
- {
- littleEndian24BitToChars ((uint32) roundDoubleToInt (jlimit (-maxVal, maxVal, maxVal * source[i])), intData);
- intData += destBytesPerSample;
- }
- }
-
- void AudioDataConverters::convertFloatToInt24BE (const float* source, void* dest, int numSamples, const int destBytesPerSample)
- {
- const double maxVal = (double) 0x7fffff;
- char* intData = (char*) dest;
-
- for (int i = 0; i < numSamples; ++i)
- {
- bigEndian24BitToChars ((uint32) roundDoubleToInt (jlimit (-maxVal, maxVal, maxVal * source[i])), intData);
- intData += destBytesPerSample;
- }
- }
-
- void AudioDataConverters::convertFloatToInt32LE (const float* source, void* dest, int numSamples, const int destBytesPerSample)
- {
- const double maxVal = (double) 0x7fffffff;
- char* intData = (char*) dest;
-
- for (int i = 0; i < numSamples; ++i)
- {
- *(uint32*)intData = swapIfBigEndian ((uint32) roundDoubleToInt (jlimit (-maxVal, maxVal, maxVal * source[i])));
- intData += destBytesPerSample;
- }
- }
-
- void AudioDataConverters::convertFloatToInt32BE (const float* source, void* dest, int numSamples, const int destBytesPerSample)
- {
- const double maxVal = (double) 0x7fffffff;
- char* intData = (char*) dest;
-
- for (int i = 0; i < numSamples; ++i)
- {
- *(uint32*)intData = swapIfLittleEndian ((uint32) roundDoubleToInt (jlimit (-maxVal, maxVal, maxVal * source[i])));
- intData += destBytesPerSample;
- }
- }
-
- void AudioDataConverters::convertFloatToFloat32LE (const float* source, void* dest, int numSamples, const int destBytesPerSample)
- {
- char* d = (char*) dest;
-
- for (int i = 0; i < numSamples; ++i)
- {
- *(float*)d = source[i];
-
- #if JUCE_BIG_ENDIAN
- *(uint32*)d = swapByteOrder (*(uint32*)d);
- #endif
-
- d += destBytesPerSample;
- }
- }
-
- void AudioDataConverters::convertFloatToFloat32BE (const float* source, void* dest, int numSamples, const int destBytesPerSample)
- {
- char* d = (char*) dest;
-
- for (int i = 0; i < numSamples; ++i)
- {
- *(float*)d = source[i];
-
- #if JUCE_LITTLE_ENDIAN
- *(uint32*)d = swapByteOrder (*(uint32*)d);
- #endif
-
- d += destBytesPerSample;
- }
- }
-
- void AudioDataConverters::convertInt16LEToFloat (const void* const source, float* const dest, int numSamples, const int srcBytesPerSample)
- {
- const float scale = 1.0f / 0x7fff;
- const char* intData = (const char*) source;
-
- for (int i = 0; i < numSamples; ++i)
- {
- dest[i] = scale * (short) swapIfBigEndian (*(uint16*)intData);
- intData += srcBytesPerSample;
- }
- }
-
- void AudioDataConverters::convertInt16BEToFloat (const void* const source, float* const dest, int numSamples, const int srcBytesPerSample)
- {
- const float scale = 1.0f / 0x7fff;
- const char* intData = (const char*) source;
-
- for (int i = 0; i < numSamples; ++i)
- {
- dest[i] = scale * (short) swapIfLittleEndian (*(uint16*)intData);
- intData += srcBytesPerSample;
- }
- }
-
- void AudioDataConverters::convertInt24LEToFloat (const void* const source, float* const dest, int numSamples, const int srcBytesPerSample)
- {
- const float scale = 1.0f / 0x7fffff;
- const char* intData = (const char*) source;
-
- for (int i = 0; i < numSamples; ++i)
- {
- dest[i] = scale * (short) littleEndian24Bit (intData);
- intData += srcBytesPerSample;
- }
- }
-
- void AudioDataConverters::convertInt24BEToFloat (const void* const source, float* const dest, int numSamples, const int srcBytesPerSample)
- {
- const float scale = 1.0f / 0x7fffff;
- const char* intData = (const char*) source;
-
- for (int i = 0; i < numSamples; ++i)
- {
- dest[i] = scale * (short) bigEndian24Bit (intData);
- intData += srcBytesPerSample;
- }
- }
-
- void AudioDataConverters::convertInt32LEToFloat (const void* const source, float* const dest, int numSamples, const int srcBytesPerSample)
- {
- const float scale = 1.0f / 0x7fffffff;
- const char* intData = (const char*) source;
-
- for (int i = 0; i < numSamples; ++i)
- {
- dest[i] = scale * (int) swapIfBigEndian (*(uint32*) intData);
- intData += srcBytesPerSample;
- }
- }
-
- void AudioDataConverters::convertInt32BEToFloat (const void* const source, float* const dest, int numSamples, const int srcBytesPerSample)
- {
- const float scale = 1.0f / 0x7fffffff;
- const char* intData = (const char*) source;
-
- for (int i = 0; i < numSamples; ++i)
- {
- dest[i] = scale * (int) (swapIfLittleEndian (*(uint32*) intData));
- intData += srcBytesPerSample;
- }
- }
-
- void AudioDataConverters::convertFloat32LEToFloat (const void* const source, float* const dest, int numSamples, const int srcBytesPerSample)
- {
- const char* s = (const char*) source;
-
- for (int i = 0; i < numSamples; ++i)
- {
- dest[i] = *(float*)s;
-
- #if JUCE_BIG_ENDIAN
- uint32* const d = (uint32*) (dest + i);
- *d = swapByteOrder (*d);
- #endif
-
- s += srcBytesPerSample;
- }
- }
-
- void AudioDataConverters::convertFloat32BEToFloat (const void* const source, float* const dest, int numSamples, const int srcBytesPerSample)
- {
- const char* s = (const char*) source;
-
- for (int i = 0; i < numSamples; ++i)
- {
- dest[i] = *(float*)s;
-
- #if JUCE_LITTLE_ENDIAN
- uint32* const d = (uint32*) (dest + i);
- *d = swapByteOrder (*d);
- #endif
-
- s += srcBytesPerSample;
- }
- }
-
- void AudioDataConverters::convertFloatToFormat (const DataFormat destFormat,
- const float* const source,
- void* const dest,
- const int numSamples)
- {
- switch (destFormat)
- {
- case int16LE:
- convertFloatToInt16LE (source, dest, numSamples);
- break;
-
- case int16BE:
- convertFloatToInt16BE (source, dest, numSamples);
- break;
-
- case int24LE:
- convertFloatToInt24LE (source, dest, numSamples);
- break;
-
- case int24BE:
- convertFloatToInt24BE (source, dest, numSamples);
- break;
-
- case int32LE:
- convertFloatToInt32LE (source, dest, numSamples);
- break;
-
- case int32BE:
- convertFloatToInt32BE (source, dest, numSamples);
- break;
-
- case float32LE:
- convertFloatToFloat32LE (source, dest, numSamples);
- break;
-
- case float32BE:
- convertFloatToFloat32BE (source, dest, numSamples);
- break;
-
- default:
- jassertfalse
- break;
- }
- }
-
- void AudioDataConverters::convertFormatToFloat (const DataFormat sourceFormat,
- const void* const source,
- float* const dest,
- const int numSamples)
- {
- switch (sourceFormat)
- {
- case int16LE:
- convertInt16LEToFloat (source, dest, numSamples);
- break;
-
- case int16BE:
- convertInt16BEToFloat (source, dest, numSamples);
- break;
-
- case int24LE:
- convertInt24LEToFloat (source, dest, numSamples);
- break;
-
- case int24BE:
- convertInt24BEToFloat (source, dest, numSamples);
- break;
-
- case int32LE:
- convertInt32LEToFloat (source, dest, numSamples);
- break;
-
- case int32BE:
- convertInt32BEToFloat (source, dest, numSamples);
- break;
-
- case float32LE:
- convertFloat32LEToFloat (source, dest, numSamples);
- break;
-
- case float32BE:
- convertFloat32BEToFloat (source, dest, numSamples);
- break;
-
- default:
- jassertfalse
- break;
- }
- }
-
- void AudioDataConverters::interleaveSamples (const float** const source,
- float* const dest,
- const int numSamples,
- const int numChannels)
- {
- for (int chan = 0; chan < numChannels; ++chan)
- {
- int i = chan;
- const float* src = source [chan];
-
- for (int j = 0; j < numSamples; ++j)
- {
- dest [i] = src [j];
- i += numChannels;
- }
- }
- }
-
- void AudioDataConverters::deinterleaveSamples (const float* const source,
- float** const dest,
- const int numSamples,
- const int numChannels)
- {
- for (int chan = 0; chan < numChannels; ++chan)
- {
- int i = chan;
- float* dst = dest [chan];
-
- for (int j = 0; j < numSamples; ++j)
- {
- dst [j] = source [i];
- i += numChannels;
- }
- }
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_AudioDataConverters.cpp *********/
-
- /********* Start of inlined file: juce_AudioSampleBuffer.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- AudioSampleBuffer::AudioSampleBuffer (const int numChannels_,
- const int numSamples) throw()
- : numChannels (numChannels_),
- size (numSamples)
- {
- jassert (numSamples >= 0);
- jassert (numChannels_ > 0 && numChannels_ <= maxNumAudioSampleBufferChannels);
-
- allocatedBytes = numChannels * numSamples * sizeof (float) + 32;
- allocatedData = (float*) juce_malloc (allocatedBytes);
-
- float* chan = allocatedData;
- for (int i = 0; i < numChannels_; ++i)
- {
- channels[i] = chan;
- chan += numSamples;
- }
-
- channels [numChannels_] = 0;
- }
-
- AudioSampleBuffer::AudioSampleBuffer (float** dataToReferTo,
- const int numChannels_,
- const int numSamples) throw()
- : numChannels (numChannels_),
- size (numSamples),
- allocatedBytes (0),
- allocatedData (0)
- {
- jassert (((unsigned int) numChannels_) <= (unsigned int) maxNumAudioSampleBufferChannels);
-
- for (int i = 0; i < numChannels_; ++i)
- {
- // you have to pass in the same number of valid pointers as numChannels
- jassert (dataToReferTo[i] != 0);
-
- channels[i] = dataToReferTo[i];
- }
-
- channels [numChannels_] = 0;
- }
-
- void AudioSampleBuffer::setDataToReferTo (float** dataToReferTo,
- const int numChannels_,
- const int numSamples) throw()
- {
- jassert (((unsigned int) numChannels_) <= (unsigned int) maxNumAudioSampleBufferChannels);
-
- juce_free (allocatedData);
- allocatedData = 0;
- allocatedBytes = 0;
-
- numChannels = numChannels_;
- size = numSamples;
-
- for (int i = 0; i < numChannels_; ++i)
- {
- // you have to pass in the same number of valid pointers as numChannels
- jassert (dataToReferTo[i] != 0);
-
- channels[i] = dataToReferTo[i];
- }
-
- channels [numChannels_] = 0;
- }
-
- AudioSampleBuffer::AudioSampleBuffer (const AudioSampleBuffer& other) throw()
- : numChannels (other.numChannels),
- size (other.size)
- {
- if (other.allocatedData != 0)
- {
- allocatedBytes = numChannels * size * sizeof (float) + 32;
- allocatedData = (float*) juce_malloc (allocatedBytes);
-
- memcpy (allocatedData, other.allocatedData, allocatedBytes);
-
- float* chan = allocatedData;
- for (int i = 0; i < numChannels; ++i)
- {
- channels[i] = chan;
- chan += size;
- }
-
- channels [numChannels] = 0;
- }
- else
- {
- allocatedData = 0;
- allocatedBytes = 0;
-
- memcpy (channels, other.channels, sizeof (channels));
- }
- }
-
- const AudioSampleBuffer& AudioSampleBuffer::operator= (const AudioSampleBuffer& other) throw()
- {
- if (this != &other)
- {
- setSize (other.getNumChannels(), other.getNumSamples(), false, false, false);
-
- const int numBytes = size * sizeof (float);
-
- for (int i = 0; i < numChannels; ++i)
- memcpy (channels[i], other.channels[i], numBytes);
- }
-
- return *this;
- }
-
- AudioSampleBuffer::~AudioSampleBuffer() throw()
- {
- juce_free (allocatedData);
- }
-
- float* AudioSampleBuffer::getSampleData (const int channelNumber,
- const int sampleOffset) const throw()
- {
- jassert (((unsigned int) channelNumber) < (unsigned int) numChannels);
- jassert (((unsigned int) sampleOffset) < (unsigned int) size);
-
- return channels [channelNumber] + sampleOffset;
- }
-
- void AudioSampleBuffer::setSize (const int newNumChannels,
- const int newNumSamples,
- const bool keepExistingContent,
- const bool clearExtraSpace,
- const bool avoidReallocating) throw()
- {
- jassert (newNumChannels > 0 && newNumChannels <= maxNumAudioSampleBufferChannels);
-
- if (newNumSamples != size || newNumChannels != numChannels)
- {
- const int newTotalBytes = newNumChannels * newNumSamples * sizeof (float) + 32;
-
- if (keepExistingContent)
- {
- float* const newData = (clearExtraSpace) ? (float*) juce_calloc (newTotalBytes)
- : (float*) juce_malloc (newTotalBytes);
-
- const int sizeToCopy = sizeof (float) * jmin (newNumSamples, size);
-
- for (int i = jmin (newNumChannels, numChannels); --i >= 0;)
- {
- memcpy (newData + i * newNumSamples,
- channels[i],
- sizeToCopy);
- }
-
- juce_free (allocatedData);
-
- allocatedData = newData;
- allocatedBytes = newTotalBytes;
- }
- else
- {
- if (avoidReallocating && allocatedBytes >= newTotalBytes)
- {
- if (clearExtraSpace)
- zeromem (allocatedData, newTotalBytes);
- }
- else
- {
- juce_free (allocatedData);
-
- allocatedData = (clearExtraSpace) ? (float*) juce_calloc (newTotalBytes)
- : (float*) juce_malloc (newTotalBytes);
- allocatedBytes = newTotalBytes;
- }
- }
-
- size = newNumSamples;
- numChannels = newNumChannels;
-
- float* chan = allocatedData;
- for (int i = 0; i < newNumChannels; ++i)
- {
- channels[i] = chan;
- chan += size;
- }
-
- channels [newNumChannels] = 0;
- }
- }
-
- void AudioSampleBuffer::clear() throw()
- {
- for (int i = 0; i < numChannels; ++i)
- zeromem (channels[i], size * sizeof (float));
- }
-
- void AudioSampleBuffer::clear (const int startSample,
- const int numSamples) throw()
- {
- jassert (startSample >= 0 && startSample + numSamples <= size);
-
- for (int i = 0; i < numChannels; ++i)
- zeromem (channels [i] + startSample, numSamples * sizeof (float));
- }
-
- void AudioSampleBuffer::clear (const int channel,
- const int startSample,
- const int numSamples) throw()
- {
- jassert (((unsigned int) channel) < (unsigned int) numChannels);
- jassert (startSample >= 0 && startSample + numSamples <= size);
-
- zeromem (channels [channel] + startSample, numSamples * sizeof (float));
- }
-
- void AudioSampleBuffer::applyGain (const int channel,
- const int startSample,
- int numSamples,
- const float gain) throw()
- {
- jassert (((unsigned int) channel) < (unsigned int) numChannels);
- jassert (startSample >= 0 && startSample + numSamples <= size);
-
- if (gain != 1.0f)
- {
- float* d = channels [channel] + startSample;
-
- if (gain == 0.0f)
- {
- zeromem (d, sizeof (float) * numSamples);
- }
- else
- {
- while (--numSamples >= 0)
- *d++ *= gain;
- }
- }
- }
-
- void AudioSampleBuffer::applyGainRamp (const int channel,
- const int startSample,
- int numSamples,
- float startGain,
- float endGain) throw()
- {
- if (startGain == endGain)
- {
- applyGain (channel, startSample, numSamples, startGain);
- }
- else
- {
- jassert (((unsigned int) channel) < (unsigned int) numChannels);
- jassert (startSample >= 0 && startSample + numSamples <= size);
-
- const float increment = (endGain - startGain) / numSamples;
- float* d = channels [channel] + startSample;
-
- while (--numSamples >= 0)
- {
- *d++ *= startGain;
- startGain += increment;
- }
- }
- }
-
- void AudioSampleBuffer::applyGain (const int startSample,
- const int numSamples,
- const float gain) throw()
- {
- for (int i = 0; i < numChannels; ++i)
- applyGain (i, startSample, numSamples, gain);
- }
-
- void AudioSampleBuffer::addFrom (const int destChannel,
- const int destStartSample,
- const AudioSampleBuffer& source,
- const int sourceChannel,
- const int sourceStartSample,
- int numSamples,
- const float gain) throw()
- {
- jassert (&source != this || sourceChannel != destChannel);
- jassert (((unsigned int) destChannel) < (unsigned int) numChannels);
- jassert (destStartSample >= 0 && destStartSample + numSamples <= size);
- jassert (((unsigned int) sourceChannel) < (unsigned int) source.numChannels);
- jassert (sourceStartSample >= 0 && sourceStartSample + numSamples <= source.size);
-
- if (gain != 0.0f && numSamples > 0)
- {
- float* d = channels [destChannel] + destStartSample;
- const float* s = source.channels [sourceChannel] + sourceStartSample;
-
- if (gain != 1.0f)
- {
- while (--numSamples >= 0)
- *d++ += gain * *s++;
- }
- else
- {
- while (--numSamples >= 0)
- *d++ += *s++;
- }
- }
- }
-
- void AudioSampleBuffer::addFrom (const int destChannel,
- const int destStartSample,
- const float* source,
- int numSamples,
- const float gain) throw()
- {
- jassert (((unsigned int) destChannel) < (unsigned int) numChannels);
- jassert (destStartSample >= 0 && destStartSample + numSamples <= size);
- jassert (source != 0);
-
- if (gain != 0.0f && numSamples > 0)
- {
- float* d = channels [destChannel] + destStartSample;
-
- if (gain != 1.0f)
- {
- while (--numSamples >= 0)
- *d++ += gain * *source++;
- }
- else
- {
- while (--numSamples >= 0)
- *d++ += *source++;
- }
- }
- }
-
- void AudioSampleBuffer::addFromWithRamp (const int destChannel,
- const int destStartSample,
- const float* source,
- int numSamples,
- float startGain,
- const float endGain) throw()
- {
- jassert (((unsigned int) destChannel) < (unsigned int) numChannels);
- jassert (destStartSample >= 0 && destStartSample + numSamples <= size);
- jassert (source != 0);
-
- if (startGain == endGain)
- {
- addFrom (destChannel,
- destStartSample,
- source,
- numSamples,
- startGain);
- }
- else
- {
- if (numSamples > 0 && (startGain != 0.0f || endGain != 0.0f))
- {
- const float increment = (endGain - startGain) / numSamples;
- float* d = channels [destChannel] + destStartSample;
-
- while (--numSamples >= 0)
- {
- *d++ += startGain * *source++;
- startGain += increment;
- }
- }
- }
- }
-
- void AudioSampleBuffer::copyFrom (const int destChannel,
- const int destStartSample,
- const AudioSampleBuffer& source,
- const int sourceChannel,
- const int sourceStartSample,
- int numSamples) throw()
- {
- jassert (&source != this || sourceChannel != destChannel);
- jassert (((unsigned int) destChannel) < (unsigned int) numChannels);
- jassert (destStartSample >= 0 && destStartSample + numSamples <= size);
- jassert (((unsigned int) sourceChannel) < (unsigned int) source.numChannels);
- jassert (sourceStartSample >= 0 && sourceStartSample + numSamples <= source.size);
-
- if (numSamples > 0)
- {
- memcpy (channels [destChannel] + destStartSample,
- source.channels [sourceChannel] + sourceStartSample,
- sizeof (float) * numSamples);
- }
- }
-
- void AudioSampleBuffer::copyFrom (const int destChannel,
- const int destStartSample,
- const float* source,
- int numSamples) throw()
- {
- jassert (((unsigned int) destChannel) < (unsigned int) numChannels);
- jassert (destStartSample >= 0 && destStartSample + numSamples <= size);
- jassert (source != 0);
-
- if (numSamples > 0)
- {
- memcpy (channels [destChannel] + destStartSample,
- source,
- sizeof (float) * numSamples);
- }
- }
-
- void AudioSampleBuffer::findMinMax (const int channel,
- const int startSample,
- int numSamples,
- float& minVal,
- float& maxVal) const throw()
- {
- jassert (((unsigned int) channel) < (unsigned int) numChannels);
- jassert (startSample >= 0 && startSample + numSamples <= size);
-
- if (numSamples <= 0)
- {
- minVal = 0.0f;
- maxVal = 0.0f;
- }
- else
- {
- const float* d = channels [channel] + startSample;
-
- float mn = *d++;
- float mx = mn;
-
- while (--numSamples > 0) // (> 0 rather than >= 0 because we've already taken the first sample)
- {
- const float samp = *d++;
-
- if (samp > mx)
- mx = samp;
-
- if (samp < mn)
- mn = samp;
- }
-
- maxVal = mx;
- minVal = mn;
- }
- }
-
- float AudioSampleBuffer::getMagnitude (const int channel,
- const int startSample,
- const int numSamples) const throw()
- {
- jassert (((unsigned int) channel) < (unsigned int) numChannels);
- jassert (startSample >= 0 && startSample + numSamples <= size);
-
- float mn, mx;
- findMinMax (channel, startSample, numSamples, mn, mx);
-
- return jmax (mn, -mn, mx, -mx);
- }
-
- float AudioSampleBuffer::getMagnitude (const int startSample,
- const int numSamples) const throw()
- {
- float mag = 0.0f;
-
- for (int i = 0; i < numChannels; ++i)
- mag = jmax (mag, getMagnitude (i, startSample, numSamples));
-
- return mag;
- }
-
- float AudioSampleBuffer::getRMSLevel (const int channel,
- const int startSample,
- const int numSamples) const throw()
- {
- jassert (((unsigned int) channel) < (unsigned int) numChannels);
- jassert (startSample >= 0 && startSample + numSamples <= size);
-
- if (numSamples <= 0 || channel < 0 || channel >= numChannels)
- return 0.0f;
-
- const float* const data = channels [channel] + startSample;
- double sum = 0.0;
-
- for (int i = 0; i < numSamples; ++i)
- {
- const float sample = data [i];
- sum += sample * sample;
- }
-
- return (float) sqrt (sum / numSamples);
- }
-
- void AudioSampleBuffer::readFromAudioReader (AudioFormatReader* reader,
- const int startSample,
- const int numSamples,
- const int readerStartSample,
- const bool useLeftChan,
- const bool useRightChan) throw()
- {
- jassert (reader != 0);
- jassert (startSample >= 0 && startSample + numSamples <= size);
-
- if (numSamples > 0)
- {
- int* chans[3];
-
- if (useLeftChan == useRightChan)
- {
- chans[0] = (int*) getSampleData (0, startSample);
- chans[1] = (reader->numChannels > 1 && getNumChannels() > 1) ? (int*) getSampleData (1, startSample) : 0;
- }
- else if (useLeftChan || (reader->numChannels == 1))
- {
- chans[0] = (int*) getSampleData (0, startSample);
- chans[1] = 0;
- }
- else if (useRightChan)
- {
- chans[0] = 0;
- chans[1] = (int*) getSampleData (0, startSample);
- }
-
- chans[2] = 0;
-
- reader->read (chans, readerStartSample, numSamples);
-
- if (! reader->usesFloatingPointData)
- {
- for (int j = 0; j < 2; ++j)
- {
- float* const d = (float*) (chans[j]);
-
- if (d != 0)
- {
- const float multiplier = 1.0f / 0x7fffffff;
-
- for (int i = 0; i < numSamples; ++i)
- d[i] = *(int*)(d + i) * multiplier;
- }
- }
- }
-
- if (numChannels > 1 && (chans[0] == 0 || chans[1] == 0))
- {
- // if this is a stereo buffer and the source was mono, dupe the first channel..
- memcpy (getSampleData (1, startSample),
- getSampleData (0, startSample),
- sizeof (float) * numSamples);
- }
- }
- }
-
- void AudioSampleBuffer::writeToAudioWriter (AudioFormatWriter* writer,
- const int startSample,
- const int numSamples) const throw()
- {
- jassert (startSample >= 0 && startSample + numSamples <= size);
-
- if (numSamples > 0)
- {
- int* chans [3];
-
- if (writer->isFloatingPoint())
- {
- chans[0] = (int*) getSampleData (0, startSample);
-
- if (numChannels > 1)
- chans[1] = (int*) getSampleData (1, startSample);
- else
- chans[1] = 0;
-
- chans[2] = 0;
- writer->write ((const int**) chans, numSamples);
- }
- else
- {
- chans[0] = (int*) juce_malloc (sizeof (int) * numSamples * 2);
-
- if (numChannels > 1)
- chans[1] = chans[0] + numSamples;
- else
- chans[1] = 0;
-
- chans[2] = 0;
-
- for (int j = 0; j < 2; ++j)
- {
- int* const dest = chans[j];
-
- if (dest != 0)
- {
- const float* const src = channels [j] + startSample;
-
- for (int i = 0; i < numSamples; ++i)
- {
- const double samp = src[i];
-
- if (samp <= -1.0)
- dest[i] = INT_MIN;
- else if (samp >= 1.0)
- dest[i] = INT_MAX;
- else
- dest[i] = roundDoubleToInt (INT_MAX * samp);
- }
- }
- }
-
- writer->write ((const int**) chans, numSamples);
-
- juce_free (chans[0]);
- }
- }
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_AudioSampleBuffer.cpp *********/
-
- /********* Start of inlined file: juce_IIRFilter.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- IIRFilter::IIRFilter() throw()
- : active (false)
- {
- reset();
- }
-
- IIRFilter::IIRFilter (const IIRFilter& other) throw()
- : active (other.active)
- {
- const ScopedLock sl (other.processLock);
- memcpy (coefficients, other.coefficients, sizeof (coefficients));
- reset();
- }
-
- IIRFilter::~IIRFilter() throw()
- {
- }
-
- void IIRFilter::reset() throw()
- {
- const ScopedLock sl (processLock);
-
- x1 = 0;
- x2 = 0;
- y1 = 0;
- y2 = 0;
- }
-
- void IIRFilter::processSamples (float* const samples,
- const int numSamples) throw()
- {
- const ScopedLock sl (processLock);
-
- if (active)
- {
- for (int i = 0; i < numSamples; ++i)
- {
- const float in = samples[i];
-
- float out = coefficients[0] * in
- + coefficients[1] * x1
- + coefficients[2] * x2
- - coefficients[4] * y1
- - coefficients[5] * y2;
-
- #if JUCE_INTEL
- if (! (out < -1.0e-8 || out > 1.0e-8))
- out = 0;
- #endif
-
- x2 = x1;
- x1 = in;
- y2 = y1;
- y1 = out;
-
- samples[i] = out;
- }
- }
- }
-
- void IIRFilter::makeLowPass (const double sampleRate,
- const double frequency) throw()
- {
- jassert (sampleRate > 0);
-
- const double n = 1.0 / tan (double_Pi * frequency / sampleRate);
- const double nSquared = n * n;
- const double c1 = 1.0 / (1.0 + sqrt (2.0) * n + nSquared);
-
- setCoefficients (c1,
- c1 * 2.0f,
- c1,
- 1.0,
- c1 * 2.0 * (1.0 - nSquared),
- c1 * (1.0 - sqrt (2.0) * n + nSquared));
- }
-
- void IIRFilter::makeHighPass (const double sampleRate,
- const double frequency) throw()
- {
- const double n = tan (double_Pi * frequency / sampleRate);
- const double nSquared = n * n;
- const double c1 = 1.0 / (1.0 + sqrt (2.0) * n + nSquared);
-
- setCoefficients (c1,
- c1 * -2.0f,
- c1,
- 1.0,
- c1 * 2.0 * (nSquared - 1.0),
- c1 * (1.0 - sqrt (2.0) * n + nSquared));
- }
-
- void IIRFilter::makeLowShelf (const double sampleRate,
- const double cutOffFrequency,
- const double Q,
- const float gainFactor) throw()
- {
- jassert (sampleRate > 0);
- jassert (Q > 0);
-
- const double A = jmax (0.0f, gainFactor);
- const double aminus1 = A - 1.0;
- const double aplus1 = A + 1.0;
- const double omega = (double_Pi * 2.0 * jmax (cutOffFrequency, 2.0)) / sampleRate;
- const double coso = cos (omega);
- const double beta = sin (omega) * sqrt (A) / Q;
- const double aminus1TimesCoso = aminus1 * coso;
-
- setCoefficients (A * (aplus1 - aminus1TimesCoso + beta),
- A * 2.0 * (aminus1 - aplus1 * coso),
- A * (aplus1 - aminus1TimesCoso - beta),
- aplus1 + aminus1TimesCoso + beta,
- -2.0 * (aminus1 + aplus1 * coso),
- aplus1 + aminus1TimesCoso - beta);
- }
-
- void IIRFilter::makeHighShelf (const double sampleRate,
- const double cutOffFrequency,
- const double Q,
- const float gainFactor) throw()
- {
- jassert (sampleRate > 0);
- jassert (Q > 0);
-
- const double A = jmax (0.0f, gainFactor);
- const double aminus1 = A - 1.0;
- const double aplus1 = A + 1.0;
- const double omega = (double_Pi * 2.0 * jmax (cutOffFrequency, 2.0)) / sampleRate;
- const double coso = cos (omega);
- const double beta = sin (omega) * sqrt (A) / Q;
- const double aminus1TimesCoso = aminus1 * coso;
-
- setCoefficients (A * (aplus1 + aminus1TimesCoso + beta),
- A * -2.0 * (aminus1 + aplus1 * coso),
- A * (aplus1 + aminus1TimesCoso - beta),
- aplus1 - aminus1TimesCoso + beta,
- 2.0 * (aminus1 - aplus1 * coso),
- aplus1 - aminus1TimesCoso - beta);
- }
-
- void IIRFilter::makeBandPass (const double sampleRate,
- const double centreFrequency,
- const double Q,
- const float gainFactor) throw()
- {
- jassert (sampleRate > 0);
- jassert (Q > 0);
-
- const double A = jmax (0.0f, gainFactor);
- const double omega = (double_Pi * 2.0 * jmax (centreFrequency, 2.0)) / sampleRate;
- const double alpha = 0.5 * sin (omega) / Q;
- const double c2 = -2.0 * cos (omega);
- const double alphaTimesA = alpha * A;
- const double alphaOverA = alpha / A;
-
- setCoefficients (1.0 + alphaTimesA,
- c2,
- 1.0 - alphaTimesA,
- 1.0 + alphaOverA,
- c2,
- 1.0 - alphaOverA);
- }
-
- void IIRFilter::makeInactive() throw()
- {
- const ScopedLock sl (processLock);
- active = false;
- }
-
- void IIRFilter::copyCoefficientsFrom (const IIRFilter& other) throw()
- {
- const ScopedLock sl (processLock);
-
- memcpy (coefficients, other.coefficients, sizeof (coefficients));
- active = other.active;
- }
-
- void IIRFilter::setCoefficients (double c1,
- double c2,
- double c3,
- double c4,
- double c5,
- double c6) throw()
- {
- const double a = 1.0 / c4;
-
- c1 *= a;
- c2 *= a;
- c3 *= a;
- c5 *= a;
- c6 *= a;
-
- const ScopedLock sl (processLock);
-
- coefficients[0] = (float) c1;
- coefficients[1] = (float) c2;
- coefficients[2] = (float) c3;
- coefficients[3] = (float) c4;
- coefficients[4] = (float) c5;
- coefficients[5] = (float) c6;
-
- active = true;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_IIRFilter.cpp *********/
-
- /********* Start of inlined file: juce_MidiBuffer.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- MidiBuffer::MidiBuffer() throw()
- : ArrayAllocationBase <uint8> (32),
- bytesUsed (0)
- {
- }
-
- MidiBuffer::MidiBuffer (const MidiBuffer& other) throw()
- : ArrayAllocationBase <uint8> (32),
- bytesUsed (other.bytesUsed)
- {
- ensureAllocatedSize (bytesUsed);
- memcpy (elements, other.elements, bytesUsed);
- }
-
- const MidiBuffer& MidiBuffer::operator= (const MidiBuffer& other) throw()
- {
- if (this != &other)
- {
- bytesUsed = other.bytesUsed;
- ensureAllocatedSize (bytesUsed);
-
- if (bytesUsed > 0)
- memcpy (elements, other.elements, bytesUsed);
- }
-
- return *this;
- }
-
- MidiBuffer::~MidiBuffer() throw()
- {
- }
-
- void MidiBuffer::clear() throw()
- {
- bytesUsed = 0;
- }
-
- void MidiBuffer::clear (const int startSample,
- const int numSamples) throw()
- {
- uint8* const start = findEventAfter (elements, startSample - 1);
- uint8* const end = findEventAfter (start, startSample + numSamples - 1);
-
- if (end > start)
- {
- const size_t bytesToMove = (size_t) (bytesUsed - (end - elements));
-
- if (bytesToMove > 0)
- memmove (start, end, bytesToMove);
-
- bytesUsed -= (int) (end - start);
- }
- }
-
- void MidiBuffer::addEvent (const MidiMessage& m,
- const int sampleNumber) throw()
- {
- addEvent (m.getRawData(), m.getRawDataSize(), sampleNumber);
- }
-
- static int findActualEventLength (const uint8* const data,
- const int maxBytes) throw()
- {
- unsigned int byte = (unsigned int) *data;
-
- int size = 0;
-
- if (byte == 0xf0 || byte == 0xf7)
- {
- const uint8* d = data + 1;
-
- while (d < data + maxBytes)
- if (*d++ == 0xf7)
- break;
-
- size = (int) (d - data);
- }
- else if (byte == 0xff)
- {
- int n;
- const int bytesLeft = MidiMessage::readVariableLengthVal (data + 1, n);
- size = jmin (maxBytes, n + 2 + bytesLeft);
- }
- else if (byte >= 0x80)
- {
- size = jmin (maxBytes, MidiMessage::getMessageLengthFromFirstByte ((uint8) byte));
- }
-
- return size;
- }
-
- void MidiBuffer::addEvent (const uint8* const newData,
- const int maxBytes,
- const int sampleNumber) throw()
- {
- const int numBytes = findActualEventLength (newData, maxBytes);
-
- if (numBytes > 0)
- {
- ensureAllocatedSize (bytesUsed + numBytes + 6);
-
- uint8* d = findEventAfter (elements, sampleNumber);
- const size_t bytesToMove = (size_t) (bytesUsed - (d - elements));
-
- if (bytesToMove > 0)
- memmove (d + numBytes + 6,
- d,
- bytesToMove);
-
- *(int*) d = sampleNumber;
- d += 4;
- *(uint16*) d = (uint16) numBytes;
- d += 2;
-
- memcpy (d, newData, numBytes);
-
- bytesUsed += numBytes + 6;
- }
- }
-
- void MidiBuffer::addEvents (const MidiBuffer& otherBuffer,
- const int startSample,
- const int numSamples,
- const int sampleDeltaToAdd) throw()
- {
- Iterator i (otherBuffer);
- i.setNextSamplePosition (startSample);
-
- const uint8* data;
- int size, position;
-
- while (i.getNextEvent (data, size, position)
- && (position < startSample + numSamples || numSamples < 0))
- {
- addEvent (data, size, position + sampleDeltaToAdd);
- }
- }
-
- bool MidiBuffer::isEmpty() const throw()
- {
- return bytesUsed == 0;
- }
-
- int MidiBuffer::getNumEvents() const throw()
- {
- int n = 0;
- const uint8* d = elements;
- const uint8* const end = elements + bytesUsed;
-
- while (d < end)
- {
- d += 4;
- d += 2 + *(const uint16*) d;
- ++n;
- }
-
- return n;
- }
-
- int MidiBuffer::getFirstEventTime() const throw()
- {
- return (bytesUsed > 0) ? *(const int*) elements : 0;
- }
-
- int MidiBuffer::getLastEventTime() const throw()
- {
- if (bytesUsed == 0)
- return 0;
-
- const uint8* d = elements;
- const uint8* const endData = d + bytesUsed;
-
- for (;;)
- {
- const uint8* nextOne = d + 6 + * (const uint16*) (d + 4);
-
- if (nextOne >= endData)
- return *(const int*) d;
-
- d = nextOne;
- }
- }
-
- uint8* MidiBuffer::findEventAfter (uint8* d, const int samplePosition) const throw()
- {
- const uint8* const endData = elements + bytesUsed;
-
- while (d < endData && *(int*) d <= samplePosition)
- {
- d += 4;
- d += 2 + *(uint16*) d;
- }
-
- return d;
- }
-
- MidiBuffer::Iterator::Iterator (const MidiBuffer& buffer) throw()
- : buffer (buffer),
- data (buffer.elements)
- {
- }
-
- MidiBuffer::Iterator::~Iterator() throw()
- {
- }
-
- void MidiBuffer::Iterator::setNextSamplePosition (const int samplePosition) throw()
- {
- data = buffer.elements;
- const uint8* dataEnd = buffer.elements + buffer.bytesUsed;
-
- while (data < dataEnd && *(int*) data < samplePosition)
- {
- data += 4;
- data += 2 + *(uint16*) data;
- }
- }
-
- bool MidiBuffer::Iterator::getNextEvent (const uint8* &midiData,
- int& numBytes,
- int& samplePosition) throw()
- {
- if (data >= buffer.elements + buffer.bytesUsed)
- return false;
-
- samplePosition = *(int*) data;
- data += 4;
- numBytes = *(uint16*) data;
- data += 2;
- midiData = data;
- data += numBytes;
-
- return true;
- }
-
- bool MidiBuffer::Iterator::getNextEvent (MidiMessage& result,
- int& samplePosition) throw()
- {
- if (data >= buffer.elements + buffer.bytesUsed)
- return false;
-
- samplePosition = *(int*) data;
- data += 4;
- const int numBytes = *(uint16*) data;
- data += 2;
- result = MidiMessage (data, numBytes, samplePosition);
- data += numBytes;
-
- return true;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_MidiBuffer.cpp *********/
-
- /********* Start of inlined file: juce_MidiFile.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- struct TempoInfo
- {
- double bpm, timestamp;
- };
-
- struct TimeSigInfo
- {
- int numerator, denominator;
- double timestamp;
- };
-
- MidiFile::MidiFile() throw()
- : numTracks (0),
- timeFormat ((short)(unsigned short)0xe728)
- {
- }
-
- MidiFile::~MidiFile() throw()
- {
- clear();
- }
-
- void MidiFile::clear() throw()
- {
- while (numTracks > 0)
- delete tracks [--numTracks];
- }
-
- int MidiFile::getNumTracks() const throw()
- {
- return numTracks;
- }
-
- const MidiMessageSequence* MidiFile::getTrack (const int index) const throw()
- {
- return (((unsigned int) index) < (unsigned int) numTracks) ? tracks[index] : 0;
- }
-
- void MidiFile::addTrack (const MidiMessageSequence& trackSequence) throw()
- {
- jassert (numTracks < numElementsInArray (tracks));
-
- if (numTracks < numElementsInArray (tracks))
- tracks [numTracks++] = new MidiMessageSequence (trackSequence);
- }
-
- short MidiFile::getTimeFormat() const throw()
- {
- return timeFormat;
- }
-
- void MidiFile::setTicksPerQuarterNote (const int ticks) throw()
- {
- timeFormat = (short)ticks;
- }
-
- void MidiFile::setSmpteTimeFormat (const int framesPerSecond,
- const int subframeResolution) throw()
- {
- timeFormat = (short) (((-framesPerSecond) << 8) | subframeResolution);
- }
-
- void MidiFile::findAllTempoEvents (MidiMessageSequence& tempoChangeEvents) const
- {
- for (int i = numTracks; --i >= 0;)
- {
- const int numEvents = tracks[i]->getNumEvents();
-
- for (int j = 0; j < numEvents; ++j)
- {
- const MidiMessage& m = tracks[i]->getEventPointer (j)->message;
-
- if (m.isTempoMetaEvent())
- tempoChangeEvents.addEvent (m);
- }
- }
- }
-
- void MidiFile::findAllTimeSigEvents (MidiMessageSequence& timeSigEvents) const
- {
- for (int i = numTracks; --i >= 0;)
- {
- const int numEvents = tracks[i]->getNumEvents();
-
- for (int j = 0; j < numEvents; ++j)
- {
- const MidiMessage& m = tracks[i]->getEventPointer (j)->message;
-
- if (m.isTimeSignatureMetaEvent())
- timeSigEvents.addEvent (m);
- }
- }
- }
-
- double MidiFile::getLastTimestamp() const
- {
- double t = 0.0;
-
- for (int i = numTracks; --i >= 0;)
- t = jmax (t, tracks[i]->getEndTime());
-
- return t;
- }
-
- static bool parseMidiHeader (const char* &data,
- short& timeFormat,
- short& fileType,
- short& numberOfTracks)
- {
- unsigned int ch = (int) bigEndianInt (data);
- data += 4;
-
- if (ch != bigEndianInt ("MThd"))
- {
- bool ok = false;
-
- if (ch == bigEndianInt ("RIFF"))
- {
- for (int i = 0; i < 8; ++i)
- {
- ch = bigEndianInt (data);
- data += 4;
-
- if (ch == bigEndianInt ("MThd"))
- {
- ok = true;
- break;
- }
- }
- }
-
- if (! ok)
- return false;
- }
-
- unsigned int bytesRemaining = bigEndianInt (data);
- data += 4;
- fileType = (short)bigEndianShort (data);
- data += 2;
- numberOfTracks = (short)bigEndianShort (data);
- data += 2;
- timeFormat = (short)bigEndianShort (data);
- data += 2;
- bytesRemaining -= 6;
- data += bytesRemaining;
-
- return true;
- }
-
- bool MidiFile::readFrom (InputStream& sourceStream)
- {
- clear();
- MemoryBlock data;
-
- const int maxSensibleMidiFileSize = 2 * 1024 * 1024;
-
- // (put a sanity-check on the file size, as midi files are generally small)
- if (sourceStream.readIntoMemoryBlock (data, maxSensibleMidiFileSize))
- {
- int size = data.getSize();
- const char* d = (char*) data.getData();
- short fileType, expectedTracks;
-
- if (size > 16 && parseMidiHeader (d, timeFormat, fileType, expectedTracks))
- {
- size -= (int) (d - (char*) data.getData());
-
- int track = 0;
-
- while (size > 0 && track < expectedTracks)
- {
- const int chunkType = (int)bigEndianInt (d);
- d += 4;
- const int chunkSize = (int)bigEndianInt (d);
- d += 4;
-
- if (chunkSize <= 0)
- break;
-
- if (size < 0)
- return false;
-
- if (chunkType == (int)bigEndianInt ("MTrk"))
- {
- readNextTrack (d, chunkSize);
- }
-
- size -= chunkSize + 8;
- d += chunkSize;
- ++track;
- }
-
- return true;
- }
- }
-
- return false;
- }
-
- // a comparator that puts all the note-offs before note-ons that have the same time
- int MidiFile::compareElements (const MidiMessageSequence::MidiEventHolder* const first,
- const MidiMessageSequence::MidiEventHolder* const second) throw()
- {
- const double diff = (first->message.getTimeStamp() - second->message.getTimeStamp());
-
- if (diff == 0)
- {
- if (first->message.isNoteOff() && second->message.isNoteOn())
- return -1;
- else if (first->message.isNoteOn() && second->message.isNoteOff())
- return 1;
- else
- return 0;
- }
- else
- {
- return (diff > 0) ? 1 : -1;
- }
- }
-
- void MidiFile::readNextTrack (const char* data, int size)
- {
- double time = 0;
- char lastStatusByte = 0;
-
- MidiMessageSequence result;
-
- while (size > 0)
- {
- int bytesUsed;
- const int delay = MidiMessage::readVariableLengthVal ((const uint8*) data, bytesUsed);
- data += bytesUsed;
- size -= bytesUsed;
- time += delay;
-
- int messSize = 0;
- const MidiMessage mm ((const uint8*) data, size, messSize, lastStatusByte, time);
-
- if (messSize <= 0)
- break;
-
- size -= messSize;
- data += messSize;
-
- result.addEvent (mm);
-
- const char firstByte = *(mm.getRawData());
- if ((firstByte & 0xf0) != 0xf0)
- lastStatusByte = firstByte;
- }
-
- // use a sort that puts all the note-offs before note-ons that have the same time
- result.list.sort (*this, true);
-
- result.updateMatchedPairs();
-
- addTrack (result);
- }
-
- static double convertTicksToSeconds (const double time,
- const MidiMessageSequence& tempoEvents,
- const int timeFormat)
- {
- if (timeFormat > 0)
- {
- int numer = 4, denom = 4;
- double tempoTime = 0.0, correctedTempoTime = 0.0;
- const double tickLen = 1.0 / (timeFormat & 0x7fff);
- double secsPerTick = 0.5 * tickLen;
- const int numEvents = tempoEvents.getNumEvents();
-
- for (int i = 0; i < numEvents; ++i)
- {
- const MidiMessage& m = tempoEvents.getEventPointer(i)->message;
-
- if (time <= m.getTimeStamp())
- break;
-
- if (timeFormat > 0)
- {
- correctedTempoTime = correctedTempoTime
- + (m.getTimeStamp() - tempoTime) * secsPerTick;
- }
- else
- {
- correctedTempoTime = tickLen * m.getTimeStamp() / (((timeFormat & 0x7fff) >> 8) * (timeFormat & 0xff));
- }
-
- tempoTime = m.getTimeStamp();
-
- if (m.isTempoMetaEvent())
- secsPerTick = tickLen * m.getTempoSecondsPerQuarterNote();
- else if (m.isTimeSignatureMetaEvent())
- m.getTimeSignatureInfo (numer, denom);
-
- while (i + 1 < numEvents)
- {
- const MidiMessage& m2 = tempoEvents.getEventPointer(i + 1)->message;
- if (m2.getTimeStamp() == tempoTime)
- {
- ++i;
-
- if (m2.isTempoMetaEvent())
- secsPerTick = tickLen * m2.getTempoSecondsPerQuarterNote();
- else if (m2.isTimeSignatureMetaEvent())
- m2.getTimeSignatureInfo (numer, denom);
- }
- else
- {
- break;
- }
- }
-
- }
-
- return correctedTempoTime + (time - tempoTime) * secsPerTick;
- }
- else
- {
- return time / (((timeFormat & 0x7fff) >> 8) * (timeFormat & 0xff));
- }
- }
-
- void MidiFile::convertTimestampTicksToSeconds()
- {
- MidiMessageSequence tempoEvents;
- findAllTempoEvents (tempoEvents);
- findAllTimeSigEvents (tempoEvents);
-
- for (int i = 0; i < numTracks; ++i)
- {
- MidiMessageSequence& ms = *tracks[i];
-
- for (int j = ms.getNumEvents(); --j >= 0;)
- {
- MidiMessage& m = ms.getEventPointer(j)->message;
-
- m.setTimeStamp (convertTicksToSeconds (m.getTimeStamp(),
- tempoEvents,
- timeFormat));
- }
- }
- }
-
- static void writeVariableLengthInt (OutputStream& out, unsigned int v)
- {
- unsigned int buffer = v & 0x7F;
-
- while ((v >>= 7) != 0)
- {
- buffer <<= 8;
- buffer |= ((v & 0x7F) | 0x80);
- }
-
- for (;;)
- {
- out.writeByte ((char) buffer);
-
- if (buffer & 0x80)
- buffer >>= 8;
- else
- break;
- }
- }
-
- bool MidiFile::writeTo (OutputStream& out)
- {
- out.writeIntBigEndian ((int) bigEndianInt ("MThd"));
- out.writeIntBigEndian (6);
- out.writeShortBigEndian (1); // type
- out.writeShortBigEndian (numTracks);
- out.writeShortBigEndian (timeFormat);
-
- for (int i = 0; i < numTracks; ++i)
- writeTrack (out, i);
-
- out.flush();
-
- return true;
- }
-
- void MidiFile::writeTrack (OutputStream& mainOut,
- const int trackNum)
- {
- MemoryOutputStream out;
-
- const MidiMessageSequence& ms = *tracks[trackNum];
-
- int lastTick = 0;
- char lastStatusByte = 0;
-
- for (int i = 0; i < ms.getNumEvents(); ++i)
- {
- const MidiMessage& mm = ms.getEventPointer(i)->message;
-
- const int tick = roundDoubleToInt (mm.getTimeStamp());
- const int delta = jmax (0, tick - lastTick);
- writeVariableLengthInt (out, delta);
- lastTick = tick;
-
- const char statusByte = *(mm.getRawData());
-
- if ((statusByte == lastStatusByte)
- && ((statusByte & 0xf0) != 0xf0)
- && i > 0
- && mm.getRawDataSize() > 1)
- {
- out.write (mm.getRawData() + 1, mm.getRawDataSize() - 1);
- }
- else
- {
- out.write (mm.getRawData(), mm.getRawDataSize());
- }
-
- lastStatusByte = statusByte;
- }
-
- out.writeByte (0);
- const MidiMessage m (MidiMessage::endOfTrack());
- out.write (m.getRawData(),
- m.getRawDataSize());
-
- mainOut.writeIntBigEndian ((int)bigEndianInt ("MTrk"));
- mainOut.writeIntBigEndian (out.getDataSize());
- mainOut.write (out.getData(), out.getDataSize());
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_MidiFile.cpp *********/
-
- /********* Start of inlined file: juce_MidiKeyboardState.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- MidiKeyboardState::MidiKeyboardState()
- : listeners (2)
- {
- zeromem (noteStates, sizeof (noteStates));
- }
-
- MidiKeyboardState::~MidiKeyboardState()
- {
- }
-
- void MidiKeyboardState::reset()
- {
- const ScopedLock sl (lock);
- zeromem (noteStates, sizeof (noteStates));
- eventsToAdd.clear();
- }
-
- bool MidiKeyboardState::isNoteOn (const int midiChannel, const int n) const throw()
- {
- jassert (midiChannel >= 0 && midiChannel <= 16);
-
- return ((unsigned int) n) < 128
- && (noteStates[n] & (1 << (midiChannel - 1))) != 0;
- }
-
- bool MidiKeyboardState::isNoteOnForChannels (const int midiChannelMask, const int n) const throw()
- {
- return ((unsigned int) n) < 128
- && (noteStates[n] & midiChannelMask) != 0;
- }
-
- void MidiKeyboardState::noteOn (const int midiChannel, const int midiNoteNumber, const float velocity)
- {
- jassert (midiChannel >= 0 && midiChannel <= 16);
- jassert (((unsigned int) midiNoteNumber) < 128);
-
- const ScopedLock sl (lock);
-
- if (((unsigned int) midiNoteNumber) < 128)
- {
- const int timeNow = (int) Time::getMillisecondCounter();
- eventsToAdd.addEvent (MidiMessage::noteOn (midiChannel, midiNoteNumber, velocity), timeNow);
- eventsToAdd.clear (0, timeNow - 500);
-
- noteOnInternal (midiChannel, midiNoteNumber, velocity);
- }
- }
-
- void MidiKeyboardState::noteOnInternal (const int midiChannel, const int midiNoteNumber, const float velocity)
- {
- if (((unsigned int) midiNoteNumber) < 128)
- {
- noteStates [midiNoteNumber] |= (1 << (midiChannel - 1));
-
- for (int i = listeners.size(); --i >= 0;)
- ((MidiKeyboardStateListener*) listeners.getUnchecked(i))
- ->handleNoteOn (this, midiChannel, midiNoteNumber, velocity);
- }
- }
-
- void MidiKeyboardState::noteOff (const int midiChannel, const int midiNoteNumber)
- {
- const ScopedLock sl (lock);
-
- if (isNoteOn (midiChannel, midiNoteNumber))
- {
- const int timeNow = (int) Time::getMillisecondCounter();
- eventsToAdd.addEvent (MidiMessage::noteOff (midiChannel, midiNoteNumber), timeNow);
- eventsToAdd.clear (0, timeNow - 500);
-
- noteOffInternal (midiChannel, midiNoteNumber);
- }
- }
-
- void MidiKeyboardState::noteOffInternal (const int midiChannel, const int midiNoteNumber)
- {
- if (isNoteOn (midiChannel, midiNoteNumber))
- {
- noteStates [midiNoteNumber] &= ~(1 << (midiChannel - 1));
-
- for (int i = listeners.size(); --i >= 0;)
- ((MidiKeyboardStateListener*) listeners.getUnchecked(i))
- ->handleNoteOff (this, midiChannel, midiNoteNumber);
- }
- }
-
- void MidiKeyboardState::allNotesOff (const int midiChannel)
- {
- const ScopedLock sl (lock);
-
- if (midiChannel <= 0)
- {
- for (int i = 1; i <= 16; ++i)
- allNotesOff (i);
- }
- else
- {
- for (int i = 0; i < 128; ++i)
- noteOff (midiChannel, i);
- }
- }
-
- void MidiKeyboardState::processNextMidiEvent (const MidiMessage& message)
- {
- if (message.isNoteOn())
- {
- noteOnInternal (message.getChannel(), message.getNoteNumber(), message.getFloatVelocity());
- }
- else if (message.isNoteOff())
- {
- noteOffInternal (message.getChannel(), message.getNoteNumber());
- }
- else if (message.isAllNotesOff())
- {
- for (int i = 0; i < 128; ++i)
- noteOffInternal (message.getChannel(), i);
- }
- }
-
- void MidiKeyboardState::processNextMidiBuffer (MidiBuffer& buffer,
- const int startSample,
- const int numSamples,
- const bool injectIndirectEvents)
- {
- MidiBuffer::Iterator i (buffer);
- MidiMessage message (0xf4, 0.0);
- int time;
-
- const ScopedLock sl (lock);
-
- while (i.getNextEvent (message, time))
- processNextMidiEvent (message);
-
- if (injectIndirectEvents)
- {
- MidiBuffer::Iterator i2 (eventsToAdd);
- const int firstEventToAdd = eventsToAdd.getFirstEventTime();
- const double scaleFactor = numSamples / (double) (eventsToAdd.getLastEventTime() + 1 - firstEventToAdd);
-
- while (i2.getNextEvent (message, time))
- {
- const int pos = jlimit (0, numSamples - 1, roundDoubleToInt ((time - firstEventToAdd) * scaleFactor));
- buffer.addEvent (message, startSample + pos);
- }
- }
-
- eventsToAdd.clear();
- }
-
- void MidiKeyboardState::addListener (MidiKeyboardStateListener* const listener) throw()
- {
- const ScopedLock sl (lock);
- listeners.addIfNotAlreadyThere (listener);
- }
-
- void MidiKeyboardState::removeListener (MidiKeyboardStateListener* const listener) throw()
- {
- const ScopedLock sl (lock);
- listeners.removeValue (listener);
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_MidiKeyboardState.cpp *********/
-
- /********* Start of inlined file: juce_MidiMessage.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- int MidiMessage::readVariableLengthVal (const uint8* data,
- int& numBytesUsed) throw()
- {
- numBytesUsed = 0;
- int v = 0;
- int i;
-
- do
- {
- i = (int) *data++;
-
- if (++numBytesUsed > 6)
- break;
-
- v = (v << 7) + (i & 0x7f);
-
- } while (i & 0x80);
-
- return v;
- }
-
- int MidiMessage::getMessageLengthFromFirstByte (const uint8 firstByte) throw()
- {
- // this method only works for valid starting bytes of a short midi message
- jassert (firstByte >= 0x80
- && firstByte != 0xff
- && firstByte != 0xf0
- && firstByte != 0xf7);
-
- static const char messageLengths[] =
- {
- 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,
- 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,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 1, 2, 3, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
- };
-
- return messageLengths [firstByte & 0x7f];
- }
-
- MidiMessage::MidiMessage (const uint8* const d,
- const int dataSize,
- const double t) throw()
- : timeStamp (t),
- message (0),
- size (dataSize)
- {
- jassert (dataSize > 0);
-
- if (dataSize <= 4)
- data = (uint8*) &message;
- else
- data = (uint8*) juce_malloc (dataSize);
-
- memcpy (data, d, dataSize);
-
- // check that the length matches the data..
- jassert (size > 3 || *d >= 0xf0 || getMessageLengthFromFirstByte (*d) == size);
- }
-
- MidiMessage::MidiMessage (const int byte1,
- const double t) throw()
- : timeStamp (t),
- data ((uint8*) &message),
- size (1)
- {
- data[0] = (uint8) byte1;
-
- // check that the length matches the data..
- jassert (byte1 >= 0xf0 || getMessageLengthFromFirstByte ((uint8) byte1) == 1);
- }
-
- MidiMessage::MidiMessage (const int byte1,
- const int byte2,
- const double t) throw()
- : timeStamp (t),
- data ((uint8*) &message),
- size (2)
- {
- data[0] = (uint8) byte1;
- data[1] = (uint8) byte2;
-
- // check that the length matches the data..
- jassert (byte1 >= 0xf0 || getMessageLengthFromFirstByte ((uint8) byte1) == 2);
- }
-
- MidiMessage::MidiMessage (const int byte1,
- const int byte2,
- const int byte3,
- const double t) throw()
- : timeStamp (t),
- data ((uint8*) &message),
- size (3)
- {
- data[0] = (uint8) byte1;
- data[1] = (uint8) byte2;
- data[2] = (uint8) byte3;
-
- // check that the length matches the data..
- jassert (byte1 >= 0xf0 || getMessageLengthFromFirstByte ((uint8) byte1) == 3);
- }
-
- MidiMessage::MidiMessage (const MidiMessage& other) throw()
- : timeStamp (other.timeStamp),
- message (other.message),
- size (other.size)
- {
- if (other.data != (uint8*) &other.message)
- {
- data = (uint8*) juce_malloc (size);
- memcpy (data, other.data, size);
- }
- else
- {
- data = (uint8*) &message;
- }
- }
-
- MidiMessage::MidiMessage (const MidiMessage& other,
- const double newTimeStamp) throw()
- : timeStamp (newTimeStamp),
- message (other.message),
- size (other.size)
- {
- if (other.data != (uint8*) &other.message)
- {
- data = (uint8*) juce_malloc (size);
- memcpy (data, other.data, size);
- }
- else
- {
- data = (uint8*) &message;
- }
- }
-
- MidiMessage::MidiMessage (const uint8* src,
- int sz,
- int& numBytesUsed,
- const uint8 lastStatusByte,
- double t) throw()
- : timeStamp (t),
- data ((uint8*) &message),
- message (0)
- {
- unsigned int byte = (unsigned int) *src;
-
- if (byte < 0x80)
- {
- byte = (unsigned int) (uint8) lastStatusByte;
- numBytesUsed = -1;
- }
- else
- {
- numBytesUsed = 0;
- --sz;
- ++src;
- }
-
- if (byte >= 0x80)
- {
- if (byte == 0xf0)
- {
- const uint8* d = (const uint8*) src;
-
- while (d < src + sz)
- {
- if (*d >= 0x80) // stop if we hit a status byte, and don't include it in this message
- {
- if (*d == 0xf7) // include an 0xf7 if we hit one
- ++d;
-
- break;
- }
-
- ++d;
- }
-
- size = 1 + (int) (d - src);
-
- data = (uint8*) juce_malloc (size);
- *data = (uint8) byte;
- memcpy (data + 1, src, size - 1);
- }
- else if (byte == 0xff)
- {
- int n;
- const int bytesLeft = readVariableLengthVal (src + 1, n);
- size = jmin (sz + 1, n + 2 + bytesLeft);
-
- data = (uint8*) juce_malloc (size);
- *data = (uint8) byte;
- memcpy (data + 1, src, size - 1);
- }
- else
- {
- size = getMessageLengthFromFirstByte ((uint8) byte);
- *data = (uint8) byte;
-
- if (size > 1)
- {
- data[1] = src[0];
-
- if (size > 2)
- data[2] = src[1];
- }
- }
-
- numBytesUsed += size;
- }
- else
- {
- message = 0;
- size = 0;
- }
- }
-
- const MidiMessage& MidiMessage::operator= (const MidiMessage& other) throw()
- {
- if (this == &other)
- return *this;
-
- timeStamp = other.timeStamp;
- size = other.size;
- message = other.message;
-
- if (data != (uint8*) &message)
- juce_free (data);
-
- if (other.data != (uint8*) &other.message)
- {
- data = (uint8*) juce_malloc (size);
- memcpy (data, other.data, size);
- }
- else
- {
- data = (uint8*) &message;
- }
-
- return *this;
- }
-
- MidiMessage::~MidiMessage() throw()
- {
- if (data != (uint8*) &message)
- juce_free (data);
- }
-
- int MidiMessage::getChannel() const throw()
- {
- if ((data[0] & 0xf0) != 0xf0)
- return (data[0] & 0xf) + 1;
- else
- return 0;
- }
-
- bool MidiMessage::isForChannel (const int channel) const throw()
- {
- return ((data[0] & 0xf) == channel - 1)
- && ((data[0] & 0xf0) != 0xf0);
- }
-
- void MidiMessage::setChannel (const int channel) throw()
- {
- if ((data[0] & 0xf0) != (uint8) 0xf0)
- data[0] = (uint8) ((data[0] & (uint8)0xf0)
- | (uint8)(channel - 1));
- }
-
- bool MidiMessage::isNoteOn() const throw()
- {
- return ((data[0] & 0xf0) == 0x90)
- && (data[2] != 0);
- }
-
- bool MidiMessage::isNoteOff() const throw()
- {
- return ((data[0] & 0xf0) == 0x80)
- || ((data[2] == 0) && ((data[0] & 0xf0) == 0x90));
- }
-
- bool MidiMessage::isNoteOnOrOff() const throw()
- {
- const int d = data[0] & 0xf0;
- return (d == 0x90) || (d == 0x80);
- }
-
- int MidiMessage::getNoteNumber() const throw()
- {
- return data[1];
- }
-
- void MidiMessage::setNoteNumber (const int newNoteNumber) throw()
- {
- if (isNoteOnOrOff())
- data[1] = (uint8) jlimit (0, 127, newNoteNumber);
- }
-
- uint8 MidiMessage::getVelocity() const throw()
- {
- if (isNoteOnOrOff())
- return data[2];
- else
- return 0;
- }
-
- float MidiMessage::getFloatVelocity() const throw()
- {
- return getVelocity() * (1.0f / 127.0f);
- }
-
- void MidiMessage::setVelocity (const float newVelocity) throw()
- {
- if (isNoteOnOrOff())
- data[2] = (uint8) jlimit (0, 0x7f, roundFloatToInt (newVelocity * 127.0f));
- }
-
- void MidiMessage::multiplyVelocity (const float scaleFactor) throw()
- {
- if (isNoteOnOrOff())
- data[2] = (uint8) jlimit (0, 0x7f, roundFloatToInt (scaleFactor * data[2]));
- }
-
- bool MidiMessage::isAftertouch() const throw()
- {
- return (data[0] & 0xf0) == 0xa0;
- }
-
- int MidiMessage::getAfterTouchValue() const throw()
- {
- return data[2];
- }
-
- const MidiMessage MidiMessage::aftertouchChange (const int channel,
- const int noteNum,
- const int aftertouchValue) throw()
- {
- jassert (channel > 0 && channel <= 16);
- jassert (((unsigned int) noteNum) <= 127);
- jassert (((unsigned int) aftertouchValue) <= 127);
-
- return MidiMessage (0xa0 | jlimit (0, 15, channel - 1),
- noteNum & 0x7f,
- aftertouchValue & 0x7f);
- }
-
- bool MidiMessage::isChannelPressure() const throw()
- {
- return (data[0] & 0xf0) == 0xd0;
- }
-
- int MidiMessage::getChannelPressureValue() const throw()
- {
- jassert (isChannelPressure());
-
- return data[1];
- }
-
- const MidiMessage MidiMessage::channelPressureChange (const int channel,
- const int pressure) throw()
- {
- jassert (channel > 0 && channel <= 16);
- jassert (((unsigned int) pressure) <= 127);
-
- return MidiMessage (0xd0 | jlimit (0, 15, channel - 1),
- pressure & 0x7f);
- }
-
- bool MidiMessage::isProgramChange() const throw()
- {
- return (data[0] & 0xf0) == 0xc0;
- }
-
- int MidiMessage::getProgramChangeNumber() const throw()
- {
- return data[1];
- }
-
- const MidiMessage MidiMessage::programChange (const int channel,
- const int programNumber) throw()
- {
- jassert (channel > 0 && channel <= 16);
-
- return MidiMessage (0xc0 | jlimit (0, 15, channel - 1),
- programNumber & 0x7f);
- }
-
- bool MidiMessage::isPitchWheel() const throw()
- {
- return (data[0] & 0xf0) == 0xe0;
- }
-
- int MidiMessage::getPitchWheelValue() const throw()
- {
- return data[1] | (data[2] << 7);
- }
-
- const MidiMessage MidiMessage::pitchWheel (const int channel,
- const int position) throw()
- {
- jassert (channel > 0 && channel <= 16);
- jassert (((unsigned int) position) <= 0x3fff);
-
- return MidiMessage (0xe0 | jlimit (0, 15, channel - 1),
- position & 127,
- (position >> 7) & 127);
- }
-
- bool MidiMessage::isController() const throw()
- {
- return (data[0] & 0xf0) == 0xb0;
- }
-
- int MidiMessage::getControllerNumber() const throw()
- {
- jassert (isController());
-
- return data[1];
- }
-
- int MidiMessage::getControllerValue() const throw()
- {
- jassert (isController());
-
- return data[2];
- }
-
- const MidiMessage MidiMessage::controllerEvent (const int channel,
- const int controllerType,
- const int value) throw()
- {
- // the channel must be between 1 and 16 inclusive
- jassert (channel > 0 && channel <= 16);
-
- return MidiMessage (0xb0 | jlimit (0, 15, channel - 1),
- controllerType & 127,
- value & 127);
- }
-
- const MidiMessage MidiMessage::noteOn (const int channel,
- const int noteNumber,
- const float velocity) throw()
- {
- return noteOn (channel, noteNumber, (uint8)(velocity * 127.0f));
- }
-
- const MidiMessage MidiMessage::noteOn (const int channel,
- const int noteNumber,
- const uint8 velocity) throw()
- {
- jassert (channel > 0 && channel <= 16);
- jassert (((unsigned int) noteNumber) <= 127);
-
- return MidiMessage (0x90 | jlimit (0, 15, channel - 1),
- noteNumber & 127,
- jlimit (0, 127, roundFloatToInt (velocity)));
- }
-
- const MidiMessage MidiMessage::noteOff (const int channel,
- const int noteNumber) throw()
- {
- jassert (channel > 0 && channel <= 16);
- jassert (((unsigned int) noteNumber) <= 127);
-
- return MidiMessage (0x80 | jlimit (0, 15, channel - 1), noteNumber & 127, 0);
- }
-
- const MidiMessage MidiMessage::allNotesOff (const int channel) throw()
- {
- jassert (channel > 0 && channel <= 16);
-
- return controllerEvent (channel, 123, 0);
- }
-
- bool MidiMessage::isAllNotesOff() const throw()
- {
- return (data[0] & 0xf0) == 0xb0
- && data[1] == 123;
- }
-
- const MidiMessage MidiMessage::allSoundOff (const int channel) throw()
- {
- return controllerEvent (channel, 120, 0);
- }
-
- bool MidiMessage::isAllSoundOff() const throw()
- {
- return (data[0] & 0xf0) == 0xb0
- && data[1] == 120;
- }
-
- const MidiMessage MidiMessage::allControllersOff (const int channel) throw()
- {
- return controllerEvent (channel, 121, 0);
- }
-
- const MidiMessage MidiMessage::masterVolume (const float volume) throw()
- {
- const int vol = jlimit (0, 0x3fff, roundFloatToInt (volume * 0x4000));
-
- uint8 buf[8];
- buf[0] = 0xf0;
- buf[1] = 0x7f;
- buf[2] = 0x7f;
- buf[3] = 0x04;
- buf[4] = 0x01;
- buf[5] = (uint8) (vol & 0x7f);
- buf[6] = (uint8) (vol >> 7);
- buf[7] = 0xf7;
-
- return MidiMessage (buf, 8);
- }
-
- bool MidiMessage::isSysEx() const throw()
- {
- return *data == 0xf0;
- }
-
- const MidiMessage MidiMessage::createSysExMessage (const uint8* sysexData,
- const int dataSize) throw()
- {
- MemoryBlock mm (dataSize + 2);
- uint8* const m = (uint8*) mm.getData();
-
- m[0] = 0xf0;
- memcpy (m + 1, sysexData, dataSize);
- m[dataSize + 1] = 0xf7;
-
- return MidiMessage (m, dataSize + 2);
- }
-
- const uint8* MidiMessage::getSysExData() const throw()
- {
- return (isSysEx()) ? getRawData() + 1
- : 0;
- }
-
- int MidiMessage::getSysExDataSize() const throw()
- {
- return (isSysEx()) ? size - 2
- : 0;
- }
-
- bool MidiMessage::isMetaEvent() const throw()
- {
- return *data == 0xff;
- }
-
- bool MidiMessage::isActiveSense() const throw()
- {
- return *data == 0xfe;
- }
-
- int MidiMessage::getMetaEventType() const throw()
- {
- if (*data != 0xff)
- return -1;
- else
- return data[1];
- }
-
- int MidiMessage::getMetaEventLength() const throw()
- {
- if (*data == 0xff)
- {
- int n;
- return jmin (size - 2, readVariableLengthVal (data + 2, n));
- }
-
- return 0;
- }
-
- const uint8* MidiMessage::getMetaEventData() const throw()
- {
- int n;
- const uint8* d = data + 2;
- readVariableLengthVal (d, n);
- return d + n;
- }
-
- bool MidiMessage::isTrackMetaEvent() const throw()
- {
- return getMetaEventType() == 0;
- }
-
- bool MidiMessage::isEndOfTrackMetaEvent() const throw()
- {
- return getMetaEventType() == 47;
- }
-
- bool MidiMessage::isTextMetaEvent() const throw()
- {
- const int t = getMetaEventType();
-
- return t > 0 && t < 16;
- }
-
- const String MidiMessage::getTextFromTextMetaEvent() const throw()
- {
- return String ((const char*) getMetaEventData(),
- getMetaEventLength());
- }
-
- bool MidiMessage::isTrackNameEvent() const throw()
- {
- return (data[1] == 3)
- && (*data == 0xff);
- }
-
- bool MidiMessage::isTempoMetaEvent() const throw()
- {
- return (data[1] == 81)
- && (*data == 0xff);
- }
-
- bool MidiMessage::isMidiChannelMetaEvent() const throw()
- {
- return (data[1] == 0x20)
- && (*data == 0xff)
- && (data[2] == 1);
- }
-
- int MidiMessage::getMidiChannelMetaEventChannel() const throw()
- {
- return data[3] + 1;
- }
-
- double MidiMessage::getTempoSecondsPerQuarterNote() const throw()
- {
- if (! isTempoMetaEvent())
- return 0.0;
-
- const uint8* const d = getMetaEventData();
-
- return (((unsigned int) d[0] << 16)
- | ((unsigned int) d[1] << 8)
- | d[2])
- / 1000000.0;
- }
-
- double MidiMessage::getTempoMetaEventTickLength (const short timeFormat) const throw()
- {
- if (timeFormat > 0)
- {
- if (! isTempoMetaEvent())
- return 0.5 / timeFormat;
-
- return getTempoSecondsPerQuarterNote() / timeFormat;
- }
- else
- {
- const int frameCode = (-timeFormat) >> 8;
- double framesPerSecond;
-
- switch (frameCode)
- {
- case 24: framesPerSecond = 24.0; break;
- case 25: framesPerSecond = 25.0; break;
- case 29: framesPerSecond = 29.97; break;
- case 30: framesPerSecond = 30.0; break;
- default: framesPerSecond = 30.0; break;
- }
-
- return (1.0 / framesPerSecond) / (timeFormat & 0xff);
- }
- }
-
- const MidiMessage MidiMessage::tempoMetaEvent (int microsecondsPerQuarterNote) throw()
- {
- uint8 d[8];
- d[0] = 0xff;
- d[1] = 81;
- d[2] = 3;
- d[3] = (uint8) (microsecondsPerQuarterNote >> 16);
- d[4] = (uint8) ((microsecondsPerQuarterNote >> 8) & 0xff);
- d[5] = (uint8) (microsecondsPerQuarterNote & 0xff);
-
- return MidiMessage (d, 6, 0.0);
- }
-
- bool MidiMessage::isTimeSignatureMetaEvent() const throw()
- {
- return (data[1] == 0x58)
- && (*data == (uint8) 0xff);
- }
-
- void MidiMessage::getTimeSignatureInfo (int& numerator,
- int& denominator) const throw()
- {
- if (isTimeSignatureMetaEvent())
- {
- const uint8* const d = getMetaEventData();
- numerator = d[0];
- denominator = 1 << d[1];
- }
- else
- {
- numerator = 4;
- denominator = 4;
- }
- }
-
- const MidiMessage MidiMessage::timeSignatureMetaEvent (const int numerator,
- const int denominator) throw()
- {
- uint8 d[8];
- d[0] = 0xff;
- d[1] = 0x58;
- d[2] = 0x04;
- d[3] = (uint8) numerator;
-
- int n = 1;
- int powerOfTwo = 0;
-
- while (n < denominator)
- {
- n <<= 1;
- ++powerOfTwo;
- }
-
- d[4] = (uint8) powerOfTwo;
- d[5] = 0x01;
- d[6] = 96;
-
- return MidiMessage (d, 7, 0.0);
- }
-
- const MidiMessage MidiMessage::midiChannelMetaEvent (const int channel) throw()
- {
- uint8 d[8];
- d[0] = 0xff;
- d[1] = 0x20;
- d[2] = 0x01;
- d[3] = (uint8) jlimit (0, 0xff, channel - 1);
-
- return MidiMessage (d, 4, 0.0);
- }
-
- bool MidiMessage::isKeySignatureMetaEvent() const throw()
- {
- return getMetaEventType() == 89;
- }
-
- int MidiMessage::getKeySignatureNumberOfSharpsOrFlats() const throw()
- {
- return (int) *getMetaEventData();
- }
-
- const MidiMessage MidiMessage::endOfTrack() throw()
- {
- return MidiMessage (0xff, 0x2f, 0, 0.0);
- }
-
- bool MidiMessage::isSongPositionPointer() const throw()
- {
- return *data == 0xf2;
- }
-
- int MidiMessage::getSongPositionPointerMidiBeat() const throw()
- {
- return data[1] | (data[2] << 7);
- }
-
- const MidiMessage MidiMessage::songPositionPointer (const int positionInMidiBeats) throw()
- {
- return MidiMessage (0xf2,
- positionInMidiBeats & 127,
- (positionInMidiBeats >> 7) & 127);
- }
-
- bool MidiMessage::isMidiStart() const throw()
- {
- return *data == 0xfa;
- }
-
- const MidiMessage MidiMessage::midiStart() throw()
- {
- return MidiMessage (0xfa);
- }
-
- bool MidiMessage::isMidiContinue() const throw()
- {
- return *data == 0xfb;
- }
-
- const MidiMessage MidiMessage::midiContinue() throw()
- {
- return MidiMessage (0xfb);
- }
-
- bool MidiMessage::isMidiStop() const throw()
- {
- return *data == 0xfc;
- }
-
- const MidiMessage MidiMessage::midiStop() throw()
- {
- return MidiMessage (0xfc);
- }
-
- bool MidiMessage::isMidiClock() const throw()
- {
- return *data == 0xf8;
- }
-
- const MidiMessage MidiMessage::midiClock() throw()
- {
- return MidiMessage (0xf8);
- }
-
- bool MidiMessage::isQuarterFrame() const throw()
- {
- return *data == 0xf1;
- }
-
- int MidiMessage::getQuarterFrameSequenceNumber() const throw()
- {
- return ((int) data[1]) >> 4;
- }
-
- int MidiMessage::getQuarterFrameValue() const throw()
- {
- return ((int) data[1]) & 0x0f;
- }
-
- const MidiMessage MidiMessage::quarterFrame (const int sequenceNumber,
- const int value) throw()
- {
- return MidiMessage (0xf1, (sequenceNumber << 4) | value);
- }
-
- bool MidiMessage::isFullFrame() const throw()
- {
- return data[0] == 0xf0
- && data[1] == 0x7f
- && size >= 10
- && data[3] == 0x01
- && data[4] == 0x01;
- }
-
- void MidiMessage::getFullFrameParameters (int& hours,
- int& minutes,
- int& seconds,
- int& frames,
- MidiMessage::SmpteTimecodeType& timecodeType) const throw()
- {
- jassert (isFullFrame());
-
- timecodeType = (SmpteTimecodeType) (data[5] >> 5);
- hours = data[5] & 0x1f;
- minutes = data[6];
- seconds = data[7];
- frames = data[8];
- }
-
- const MidiMessage MidiMessage::fullFrame (const int hours,
- const int minutes,
- const int seconds,
- const int frames,
- MidiMessage::SmpteTimecodeType timecodeType)
- {
- uint8 d[10];
- d[0] = 0xf0;
- d[1] = 0x7f;
- d[2] = 0x7f;
- d[3] = 0x01;
- d[4] = 0x01;
- d[5] = (uint8) ((hours & 0x01f) | (timecodeType << 5));
- d[6] = (uint8) minutes;
- d[7] = (uint8) seconds;
- d[8] = (uint8) frames;
- d[9] = 0xf7;
-
- return MidiMessage (d, 10, 0.0);
- }
-
- bool MidiMessage::isMidiMachineControlMessage() const throw()
- {
- return data[0] == 0xf0
- && data[1] == 0x7f
- && data[3] == 0x06
- && size > 5;
- }
-
- MidiMessage::MidiMachineControlCommand MidiMessage::getMidiMachineControlCommand() const throw()
- {
- jassert (isMidiMachineControlMessage());
-
- return (MidiMachineControlCommand) data[4];
- }
-
- const MidiMessage MidiMessage::midiMachineControlCommand (MidiMessage::MidiMachineControlCommand command)
- {
- uint8 d[6];
- d[0] = 0xf0;
- d[1] = 0x7f;
- d[2] = 0x00;
- d[3] = 0x06;
- d[4] = (uint8) command;
- d[5] = 0xf7;
-
- return MidiMessage (d, 6, 0.0);
- }
-
- bool MidiMessage::isMidiMachineControlGoto (int& hours,
- int& minutes,
- int& seconds,
- int& frames) const throw()
- {
- if (size >= 12
- && data[0] == 0xf0
- && data[1] == 0x7f
- && data[3] == 0x06
- && data[4] == 0x44
- && data[5] == 0x06
- && data[6] == 0x01)
- {
- hours = data[7] % 24; // (that some machines send out hours > 24)
- minutes = data[8];
- seconds = data[9];
- frames = data[10];
-
- return true;
- }
-
- return false;
- }
-
- const MidiMessage MidiMessage::midiMachineControlGoto (int hours,
- int minutes,
- int seconds,
- int frames)
- {
- uint8 d[12];
- d[0] = 0xf0;
- d[1] = 0x7f;
- d[2] = 0x00;
- d[3] = 0x06;
- d[4] = 0x44;
- d[5] = 0x06;
- d[6] = 0x01;
- d[7] = (uint8) hours;
- d[8] = (uint8) minutes;
- d[9] = (uint8) seconds;
- d[10] = (uint8) frames;
- d[11] = 0xf7;
-
- return MidiMessage (d, 12, 0.0);
- }
-
- const String MidiMessage::getMidiNoteName (int note,
- bool useSharps,
- bool includeOctaveNumber,
- int octaveNumForMiddleC) throw()
- {
- static const char* const sharpNoteNames[] = { "C", "C#", "D", "D#", "E",
- "F", "F#", "G", "G#", "A",
- "A#", "B" };
-
- static const char* const flatNoteNames[] = { "C", "Db", "D", "Eb", "E",
- "F", "Gb", "G", "Ab", "A",
- "Bb", "B" };
-
- if (((unsigned int) note) < 128)
- {
- const String s ((useSharps) ? sharpNoteNames [note % 12]
- : flatNoteNames [note % 12]);
-
- if (includeOctaveNumber)
- return s + String (note / 12 + (octaveNumForMiddleC - 5));
- else
- return s;
- }
-
- return String::empty;
- }
-
- const double MidiMessage::getMidiNoteInHertz (int noteNumber) throw()
- {
- noteNumber -= 12 * 6 + 9; // now 0 = A440
- return 440.0 * pow (2.0, noteNumber / 12.0);
- }
-
- const String MidiMessage::getGMInstrumentName (int n) throw()
- {
- const char *names[] =
- {
- "Acoustic Grand Piano", "Bright Acoustic Piano", "Electric Grand Piano", "Honky-tonk Piano",
- "Electric Piano 1", "Electric Piano 2", "Harpsichord", "Clavinet", "Celesta", "Glockenspiel",
- "Music Box", "Vibraphone", "Marimba", "Xylophone", "Tubular Bells", "Dulcimer", "Drawbar Organ",
- "Percussive Organ", "Rock Organ", "Church Organ", "Reed Organ", "Accordion", "Harmonica",
- "Tango Accordion", "Acoustic Guitar (nylon)", "Acoustic Guitar (steel)", "Electric Guitar (jazz)",
- "Electric Guitar (clean)", "Electric Guitar (mute)", "Overdriven Guitar", "Distortion Guitar",
- "Guitar Harmonics", "Acoustic Bass", "Electric Bass (finger)", "Electric Bass (pick)",
- "Fretless Bass", "Slap Bass 1", "Slap Bass 2", "Synth Bass 1", "Synth Bass 2", "Violin",
- "Viola", "Cello", "Contrabass", "Tremolo Strings", "Pizzicato Strings", "Orchestral Harp",
- "Timpani", "String Ensemble 1", "String Ensemble 2", "SynthStrings 1", "SynthStrings 2",
- "Choir Aahs", "Voice Oohs", "Synth Voice", "Orchestra Hit", "Trumpet", "Trombone", "Tuba",
- "Muted Trumpet", "French Horn", "Brass Section", "SynthBrass 1", "SynthBrass 2", "Soprano Sax",
- "Alto Sax", "Tenor Sax", "Baritone Sax", "Oboe", "English Horn", "Bassoon", "Clarinet",
- "Piccolo", "Flute", "Recorder", "Pan Flute", "Blown Bottle", "Shakuhachi", "Whistle",
- "Ocarina", "Lead 1 (square)", "Lead 2 (sawtooth)", "Lead 3 (calliope)", "Lead 4 (chiff)",
- "Lead 5 (charang)", "Lead 6 (voice)", "Lead 7 (fifths)", "Lead 8 (bass+lead)", "Pad 1 (new age)",
- "Pad 2 (warm)", "Pad 3 (polysynth)", "Pad 4 (choir)", "Pad 5 (bowed)", "Pad 6 (metallic)",
- "Pad 7 (halo)", "Pad 8 (sweep)", "FX 1 (rain)", "FX 2 (soundtrack)", "FX 3 (crystal)",
- "FX 4 (atmosphere)", "FX 5 (brightness)", "FX 6 (goblins)", "FX 7 (echoes)", "FX 8 (sci-fi)",
- "Sitar", "Banjo", "Shamisen", "Koto", "Kalimba", "Bag pipe", "Fiddle", "Shanai", "Tinkle Bell",
- "Agogo", "Steel Drums", "Woodblock", "Taiko Drum", "Melodic Tom", "Synth Drum", "Reverse Cymbal",
- "Guitar Fret Noise", "Breath Noise", "Seashore", "Bird Tweet", "Telephone Ring", "Helicopter",
- "Applause", "Gunshot"
- };
-
- return (((unsigned int) n) < 128) ? names[n]
- : (const char*)0;
- }
-
- const String MidiMessage::getGMInstrumentBankName (int n) throw()
- {
- const char* names[] =
- {
- "Piano", "Chromatic Percussion", "Organ", "Guitar",
- "Bass", "Strings", "Ensemble", "Brass",
- "Reed", "Pipe", "Synth Lead", "Synth Pad",
- "Synth Effects", "Ethnic", "Percussive", "Sound Effects"
- };
-
- return (((unsigned int) n) <= 15) ? names[n]
- : (const char*)0;
- }
-
- const String MidiMessage::getRhythmInstrumentName (int n) throw()
- {
- const char* names[] =
- {
- "Acoustic Bass Drum", "Bass Drum 1", "Side Stick", "Acoustic Snare",
- "Hand Clap", "Electric Snare", "Low Floor Tom", "Closed Hi-Hat", "High Floor Tom",
- "Pedal Hi-Hat", "Low Tom", "Open Hi-Hat", "Low-Mid Tom", "Hi-Mid Tom", "Crash Cymbal 1",
- "High Tom", "Ride Cymbal 1", "Chinese Cymbal", "Ride Bell", "Tambourine", "Splash Cymbal",
- "Cowbell", "Crash Cymbal 2", "Vibraslap", "Ride Cymbal 2", "Hi Bongo", "Low Bongo",
- "Mute Hi Conga", "Open Hi Conga", "Low Conga", "High Timbale", "Low Timbale", "High Agogo",
- "Low Agogo", "Cabasa", "Maracas", "Short Whistle", "Long Whistle", "Short Guiro",
- "Long Guiro", "Claves", "Hi Wood Block", "Low Wood Block", "Mute Cuica", "Open Cuica",
- "Mute Triangle", "Open Triangle"
- };
-
- return (n >= 35 && n <= 81) ? names [n - 35]
- : (const char*)0;
- }
-
- const String MidiMessage::getControllerName (int n) throw()
- {
- const char* names[] =
- {
- "Bank Select", "Modulation Wheel (coarse)", "Breath controller (coarse)",
- 0, "Foot Pedal (coarse)", "Portamento Time (coarse)",
- "Data Entry (coarse)", "Volume (coarse)", "Balance (coarse)",
- 0, "Pan position (coarse)", "Expression (coarse)", "Effect Control 1 (coarse)",
- "Effect Control 2 (coarse)", 0, 0, "General Purpose Slider 1", "General Purpose Slider 2",
- "General Purpose Slider 3", "General Purpose Slider 4", 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, "Bank Select (fine)", "Modulation Wheel (fine)", "Breath controller (fine)",
- 0, "Foot Pedal (fine)", "Portamento Time (fine)", "Data Entry (fine)", "Volume (fine)",
- "Balance (fine)", 0, "Pan position (fine)", "Expression (fine)", "Effect Control 1 (fine)",
- "Effect Control 2 (fine)", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- "Hold Pedal (on/off)", "Portamento (on/off)", "Sustenuto Pedal (on/off)", "Soft Pedal (on/off)",
- "Legato Pedal (on/off)", "Hold 2 Pedal (on/off)", "Sound Variation", "Sound Timbre",
- "Sound Release Time", "Sound Attack Time", "Sound Brightness", "Sound Control 6",
- "Sound Control 7", "Sound Control 8", "Sound Control 9", "Sound Control 10",
- "General Purpose Button 1 (on/off)", "General Purpose Button 2 (on/off)",
- "General Purpose Button 3 (on/off)", "General Purpose Button 4 (on/off)",
- 0, 0, 0, 0, 0, 0, 0, "Reverb Level", "Tremolo Level", "Chorus Level", "Celeste Level",
- "Phaser Level", "Data Button increment", "Data Button decrement", "Non-registered Parameter (fine)",
- "Non-registered Parameter (coarse)", "Registered Parameter (fine)", "Registered Parameter (coarse)",
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "All Sound Off", "All Controllers Off",
- "Local Keyboard (on/off)", "All Notes Off", "Omni Mode Off", "Omni Mode On", "Mono Operation",
- "Poly Operation"
- };
-
- return (((unsigned int) n) < 128) ? names[n]
- : (const char*)0;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_MidiMessage.cpp *********/
-
- /********* Start of inlined file: juce_MidiMessageCollector.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- MidiMessageCollector::MidiMessageCollector()
- : lastCallbackTime (0),
- sampleRate (44100.0001)
- {
- }
-
- MidiMessageCollector::~MidiMessageCollector()
- {
- }
-
- void MidiMessageCollector::reset (const double sampleRate_)
- {
- jassert (sampleRate_ > 0);
-
- const ScopedLock sl (midiCallbackLock);
- sampleRate = sampleRate_;
- incomingMessages.clear();
- lastCallbackTime = Time::getMillisecondCounterHiRes();
- }
-
- void MidiMessageCollector::addMessageToQueue (const MidiMessage& message)
- {
- // you need to call reset() to set the correct sample rate before using this object
- jassert (sampleRate != 44100.0001);
-
- // the messages that come in here need to be time-stamped correctly - see MidiInput
- // for details of what the number should be.
- jassert (message.getTimeStamp() != 0);
-
- const ScopedLock sl (midiCallbackLock);
-
- const int sampleNumber
- = (int) ((message.getTimeStamp() - 0.001 * lastCallbackTime) * sampleRate);
-
- incomingMessages.addEvent (message, sampleNumber);
-
- // if the messages don't get used for over a second, we'd better
- // get rid of any old ones to avoid the queue getting too big
- if (sampleNumber > sampleRate)
- incomingMessages.clear (0, sampleNumber - (int) sampleRate);
- }
-
- void MidiMessageCollector::removeNextBlockOfMessages (MidiBuffer& destBuffer,
- const int numSamples)
- {
- // you need to call reset() to set the correct sample rate before using this object
- jassert (sampleRate != 44100.0001);
-
- const double timeNow = Time::getMillisecondCounterHiRes();
- const double msElapsed = timeNow - lastCallbackTime;
-
- const ScopedLock sl (midiCallbackLock);
- lastCallbackTime = timeNow;
-
- if (! incomingMessages.isEmpty())
- {
- int numSourceSamples = jmax (1, roundDoubleToInt (msElapsed * 0.001 * sampleRate));
-
- int startSample = 0;
- int scale = 1 << 16;
-
- const uint8* midiData;
- int numBytes, samplePosition;
-
- MidiBuffer::Iterator iter (incomingMessages);
-
- if (numSourceSamples > numSamples)
- {
- // if our list of events is longer than the buffer we're being
- // asked for, scale them down to squeeze them all in..
- const int maxBlockLengthToUse = numSamples << 3;
-
- if (numSourceSamples > maxBlockLengthToUse)
- {
- startSample = numSourceSamples - maxBlockLengthToUse;
- numSourceSamples = maxBlockLengthToUse;
- iter.setNextSamplePosition (startSample);
- }
-
- scale = (numSamples << 10) / numSourceSamples;
-
- while (iter.getNextEvent (midiData, numBytes, samplePosition))
- {
- samplePosition = ((samplePosition - startSample) * scale) >> 10;
-
- destBuffer.addEvent (midiData, numBytes,
- jlimit (0, numSamples - 1, samplePosition));
- }
- }
- else
- {
- // if our event list is shorter than the number we need, put them
- // towards the end of the buffer
- startSample = numSamples - numSourceSamples;
-
- while (iter.getNextEvent (midiData, numBytes, samplePosition))
- {
- destBuffer.addEvent (midiData, numBytes,
- jlimit (0, numSamples - 1, samplePosition + startSample));
- }
- }
-
- incomingMessages.clear();
- }
- }
-
- void MidiMessageCollector::handleNoteOn (MidiKeyboardState*, int midiChannel, int midiNoteNumber, float velocity)
- {
- MidiMessage m (MidiMessage::noteOn (midiChannel, midiNoteNumber, velocity));
- m.setTimeStamp (Time::getMillisecondCounter() * 0.001);
-
- addMessageToQueue (m);
- }
-
- void MidiMessageCollector::handleNoteOff (MidiKeyboardState*, int midiChannel, int midiNoteNumber)
- {
- MidiMessage m (MidiMessage::noteOff (midiChannel, midiNoteNumber));
- m.setTimeStamp (Time::getMillisecondCounter() * 0.001);
-
- addMessageToQueue (m);
- }
-
- void MidiMessageCollector::handleIncomingMidiMessage (MidiInput*, const MidiMessage& message)
- {
- addMessageToQueue (message);
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_MidiMessageCollector.cpp *********/
-
- /********* Start of inlined file: juce_MidiMessageSequence.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- MidiMessageSequence::MidiMessageSequence()
- {
- }
-
- MidiMessageSequence::MidiMessageSequence (const MidiMessageSequence& other)
- {
- list.ensureStorageAllocated (other.list.size());
-
- for (int i = 0; i < other.list.size(); ++i)
- list.add (new MidiEventHolder (other.list.getUnchecked(i)->message));
- }
-
- const MidiMessageSequence& MidiMessageSequence::operator= (const MidiMessageSequence& other)
- {
- if (this != &other)
- {
- clear();
-
- for (int i = 0; i < other.list.size(); ++i)
- list.add (new MidiEventHolder (other.list.getUnchecked(i)->message));
- }
-
- return *this;
- }
-
- MidiMessageSequence::~MidiMessageSequence()
- {
- }
-
- void MidiMessageSequence::clear()
- {
- list.clear();
- }
-
- int MidiMessageSequence::getNumEvents() const
- {
- return list.size();
- }
-
- MidiMessageSequence::MidiEventHolder* MidiMessageSequence::getEventPointer (const int index) const
- {
- return list [index];
- }
-
- double MidiMessageSequence::getTimeOfMatchingKeyUp (const int index) const
- {
- const MidiEventHolder* const meh = list [index];
-
- if (meh != 0 && meh->noteOffObject != 0)
- return meh->noteOffObject->message.getTimeStamp();
- else
- return 0.0;
- }
-
- int MidiMessageSequence::getIndexOfMatchingKeyUp (const int index) const
- {
- const MidiEventHolder* const meh = list [index];
-
- return (meh != 0) ? list.indexOf (meh->noteOffObject) : -1;
- }
-
- int MidiMessageSequence::getIndexOf (MidiEventHolder* const event) const
- {
- return list.indexOf (event);
- }
-
- int MidiMessageSequence::getNextIndexAtTime (const double timeStamp) const
- {
- const int numEvents = list.size();
-
- int i;
- for (i = 0; i < numEvents; ++i)
- if (list.getUnchecked(i)->message.getTimeStamp() >= timeStamp)
- break;
-
- return i;
- }
-
- double MidiMessageSequence::getStartTime() const
- {
- if (list.size() > 0)
- return list.getUnchecked(0)->message.getTimeStamp();
- else
- return 0;
- }
-
- double MidiMessageSequence::getEndTime() const
- {
- if (list.size() > 0)
- return list.getLast()->message.getTimeStamp();
- else
- return 0;
- }
-
- double MidiMessageSequence::getEventTime (const int index) const
- {
- if (((unsigned int) index) < (unsigned int) list.size())
- return list.getUnchecked (index)->message.getTimeStamp();
-
- return 0.0;
- }
-
- void MidiMessageSequence::addEvent (const MidiMessage& newMessage,
- double timeAdjustment)
- {
- MidiEventHolder* const newOne = new MidiEventHolder (newMessage);
-
- timeAdjustment += newMessage.getTimeStamp();
- newOne->message.setTimeStamp (timeAdjustment);
-
- int i;
- for (i = list.size(); --i >= 0;)
- if (list.getUnchecked(i)->message.getTimeStamp() <= timeAdjustment)
- break;
-
- list.insert (i + 1, newOne);
- }
-
- void MidiMessageSequence::deleteEvent (const int index,
- const bool deleteMatchingNoteUp)
- {
- if (((unsigned int) index) < (unsigned int) list.size())
- {
- if (deleteMatchingNoteUp)
- deleteEvent (getIndexOfMatchingKeyUp (index), false);
-
- list.remove (index);
- }
- }
-
- void MidiMessageSequence::addSequence (const MidiMessageSequence& other,
- double timeAdjustment,
- double firstAllowableTime,
- double endOfAllowableDestTimes)
- {
- firstAllowableTime -= timeAdjustment;
- endOfAllowableDestTimes -= timeAdjustment;
-
- for (int i = 0; i < other.list.size(); ++i)
- {
- const MidiMessage& m = other.list.getUnchecked(i)->message;
- const double t = m.getTimeStamp();
-
- if (t >= firstAllowableTime && t < endOfAllowableDestTimes)
- {
- MidiEventHolder* const newOne = new MidiEventHolder (m);
- newOne->message.setTimeStamp (timeAdjustment + t);
-
- list.add (newOne);
- }
- }
-
- sort();
- }
-
- int MidiMessageSequence::compareElements (const MidiMessageSequence::MidiEventHolder* const first,
- const MidiMessageSequence::MidiEventHolder* const second) throw()
- {
- const double diff = first->message.getTimeStamp()
- - second->message.getTimeStamp();
-
- return (diff == 0) ? 0
- : ((diff > 0) ? 1
- : -1);
- }
-
- void MidiMessageSequence::sort()
- {
- list.sort (*this, true);
- }
-
- void MidiMessageSequence::updateMatchedPairs()
- {
- for (int i = 0; i < list.size(); ++i)
- {
- const MidiMessage& m1 = list.getUnchecked(i)->message;
-
- if (m1.isNoteOn())
- {
- list.getUnchecked(i)->noteOffObject = 0;
- const int note = m1.getNoteNumber();
- const int chan = m1.getChannel();
- const int len = list.size();
-
- for (int j = i + 1; j < len; ++j)
- {
- const MidiMessage& m = list.getUnchecked(j)->message;
-
- if (m.getNoteNumber() == note && m.getChannel() == chan)
- {
- if (m.isNoteOff())
- {
- list.getUnchecked(i)->noteOffObject = list[j];
- break;
- }
- else if (m.isNoteOn())
- {
- list.insert (j, new MidiEventHolder (MidiMessage::noteOff (chan, note)));
- list.getUnchecked(j)->message.setTimeStamp (m.getTimeStamp());
- list.getUnchecked(i)->noteOffObject = list[j];
- break;
- }
- }
- }
- }
- }
- }
-
- void MidiMessageSequence::addTimeToMessages (const double delta)
- {
- for (int i = list.size(); --i >= 0;)
- list.getUnchecked (i)->message.setTimeStamp (list.getUnchecked (i)->message.getTimeStamp()
- + delta);
- }
-
- void MidiMessageSequence::extractMidiChannelMessages (const int channelNumberToExtract,
- MidiMessageSequence& destSequence,
- const bool alsoIncludeMetaEvents) const
- {
- for (int i = 0; i < list.size(); ++i)
- {
- const MidiMessage& mm = list.getUnchecked(i)->message;
-
- if (mm.isForChannel (channelNumberToExtract)
- || (alsoIncludeMetaEvents && mm.isMetaEvent()))
- {
- destSequence.addEvent (mm);
- }
- }
- }
-
- void MidiMessageSequence::extractSysExMessages (MidiMessageSequence& destSequence) const
- {
- for (int i = 0; i < list.size(); ++i)
- {
- const MidiMessage& mm = list.getUnchecked(i)->message;
-
- if (mm.isSysEx())
- destSequence.addEvent (mm);
- }
- }
-
- void MidiMessageSequence::deleteMidiChannelMessages (const int channelNumberToRemove)
- {
- for (int i = list.size(); --i >= 0;)
- if (list.getUnchecked(i)->message.isForChannel (channelNumberToRemove))
- list.remove(i);
- }
-
- void MidiMessageSequence::deleteSysExMessages()
- {
- for (int i = list.size(); --i >= 0;)
- if (list.getUnchecked(i)->message.isSysEx())
- list.remove(i);
- }
-
- void MidiMessageSequence::createControllerUpdatesForTime (const int channelNumber,
- const double time,
- OwnedArray<MidiMessage>& dest)
- {
- bool doneProg = false;
- bool donePitchWheel = false;
- Array <int> doneControllers (32);
-
- for (int i = list.size(); --i >= 0;)
- {
- const MidiMessage& mm = list.getUnchecked(i)->message;
-
- if (mm.isForChannel (channelNumber)
- && mm.getTimeStamp() <= time)
- {
- if (mm.isProgramChange())
- {
- if (! doneProg)
- {
- dest.add (new MidiMessage (mm, 0.0));
- doneProg = true;
- }
- }
- else if (mm.isController())
- {
- if (! doneControllers.contains (mm.getControllerNumber()))
- {
- dest.add (new MidiMessage (mm, 0.0));
- doneControllers.add (mm.getControllerNumber());
- }
- }
- else if (mm.isPitchWheel())
- {
- if (! donePitchWheel)
- {
- dest.add (new MidiMessage (mm, 0.0));
- donePitchWheel = true;
- }
- }
- }
- }
- }
-
- MidiMessageSequence::MidiEventHolder::MidiEventHolder (const MidiMessage& message_)
- : message (message_),
- noteOffObject (0)
- {
- }
-
- MidiMessageSequence::MidiEventHolder::~MidiEventHolder()
- {
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_MidiMessageSequence.cpp *********/
-
- /********* Start of inlined file: juce_AudioPluginFormat.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- AudioPluginFormat::AudioPluginFormat() throw()
- {
- }
-
- AudioPluginFormat::~AudioPluginFormat()
- {
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_AudioPluginFormat.cpp *********/
-
- /********* Start of inlined file: juce_AudioPluginFormatManager.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- AudioPluginFormatManager::AudioPluginFormatManager() throw()
- {
- }
-
- AudioPluginFormatManager::~AudioPluginFormatManager() throw()
- {
- }
-
- juce_ImplementSingleton_SingleThreaded (AudioPluginFormatManager);
-
- void AudioPluginFormatManager::addDefaultFormats()
- {
- #ifdef JUCE_DEBUG
- // you should only call this method once!
- for (int i = formats.size(); --i >= 0;)
- {
- #if JUCE_PLUGINHOST_VST
- jassert (dynamic_cast <VSTPluginFormat*> (formats[i]) == 0);
- #endif
-
- #if JUCE_PLUGINHOST_AU && JUCE_MAC
- jassert (dynamic_cast <AudioUnitPluginFormat*> (formats[i]) == 0);
- #endif
-
- #if JUCE_PLUGINHOST_DX && JUCE_WIN32
- jassert (dynamic_cast <DirectXPluginFormat*> (formats[i]) == 0);
- #endif
-
- #if JUCE_PLUGINHOST_LADSPA && JUCE_LINUX
- jassert (dynamic_cast <LADSPAPluginFormat*> (formats[i]) == 0);
- #endif
- }
- #endif
-
- #if JUCE_PLUGINHOST_VST
- formats.add (new VSTPluginFormat());
- #endif
-
- #if JUCE_PLUGINHOST_AU && JUCE_MAC
- formats.add (new AudioUnitPluginFormat());
- #endif
-
- #if JUCE_PLUGINHOST_DX && JUCE_WIN32
- formats.add (new DirectXPluginFormat());
- #endif
-
- #if JUCE_PLUGINHOST_LADSPA && JUCE_LINUX
- formats.add (new LADSPAPluginFormat());
- #endif
- }
-
- int AudioPluginFormatManager::getNumFormats() throw()
- {
- return formats.size();
- }
-
- AudioPluginFormat* AudioPluginFormatManager::getFormat (const int index) throw()
- {
- return formats [index];
- }
-
- void AudioPluginFormatManager::addFormat (AudioPluginFormat* const format) throw()
- {
- formats.add (format);
- }
-
- AudioPluginInstance* AudioPluginFormatManager::createPluginInstance (const PluginDescription& description,
- String& errorMessage) const
- {
- AudioPluginInstance* result = 0;
-
- for (int i = 0; i < formats.size(); ++i)
- {
- result = formats.getUnchecked(i)->createInstanceFromDescription (description);
-
- if (result != 0)
- break;
- }
-
- if (result == 0)
- {
- if (description.file != File::nonexistent && ! description.file.exists())
- errorMessage = TRANS ("This plug-in file no longer exists");
- else
- errorMessage = TRANS ("This plug-in failed to load correctly");
- }
-
- return result;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_AudioPluginFormatManager.cpp *********/
-
- /********* Start of inlined file: juce_AudioPluginInstance.cpp *********/
- #define JUCE_PLUGIN_HOST 1
-
- BEGIN_JUCE_NAMESPACE
-
- AudioPluginInstance::AudioPluginInstance()
- {
- }
-
- AudioPluginInstance::~AudioPluginInstance()
- {
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_AudioPluginInstance.cpp *********/
-
- /********* Start of inlined file: juce_KnownPluginList.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- KnownPluginList::KnownPluginList()
- {
- }
-
- KnownPluginList::~KnownPluginList()
- {
- }
-
- void KnownPluginList::clear()
- {
- if (types.size() > 0)
- {
- types.clear();
- sendChangeMessage (this);
- }
- }
-
- PluginDescription* KnownPluginList::getTypeForFile (const File& file) const throw()
- {
- for (int i = 0; i < types.size(); ++i)
- if (types.getUnchecked(i)->file == file)
- return types.getUnchecked(i);
-
- return 0;
- }
-
- PluginDescription* KnownPluginList::getTypeForIdentifierString (const String& identifierString) const throw()
- {
- for (int i = 0; i < types.size(); ++i)
- if (types.getUnchecked(i)->createIdentifierString() == identifierString)
- return types.getUnchecked(i);
-
- return 0;
- }
-
- bool KnownPluginList::addType (const PluginDescription& type)
- {
- for (int i = types.size(); --i >= 0;)
- {
- if (types.getUnchecked(i)->isDuplicateOf (type))
- {
- // strange - found a duplicate plugin with different info..
- jassert (types.getUnchecked(i)->name == type.name);
- jassert (types.getUnchecked(i)->isInstrument == type.isInstrument);
-
- *types.getUnchecked(i) = type;
- return false;
- }
- }
-
- types.add (new PluginDescription (type));
- sendChangeMessage (this);
- return true;
- }
-
- void KnownPluginList::removeType (const int index) throw()
- {
- types.remove (index);
- sendChangeMessage (this);
- }
-
- bool KnownPluginList::isListingUpToDate (const File& possiblePluginFile) const throw()
- {
- if (getTypeForFile (possiblePluginFile) == 0)
- return false;
-
- for (int i = types.size(); --i >= 0;)
- {
- const PluginDescription* const d = types.getUnchecked(i);
-
- if (d->file == possiblePluginFile
- && d->lastFileModTime != possiblePluginFile.getLastModificationTime())
- {
- return false;
- }
- }
-
- return true;
- }
-
- bool KnownPluginList::scanAndAddFile (const File& possiblePluginFile,
- const bool dontRescanIfAlreadyInList,
- OwnedArray <PluginDescription>& typesFound)
- {
- bool addedOne = false;
-
- if (dontRescanIfAlreadyInList
- && getTypeForFile (possiblePluginFile) != 0)
- {
- bool needsRescanning = false;
-
- for (int i = types.size(); --i >= 0;)
- {
- const PluginDescription* const d = types.getUnchecked(i);
-
- if (d->file == possiblePluginFile)
- {
- if (d->lastFileModTime != possiblePluginFile.getLastModificationTime())
- needsRescanning = true;
- else
- typesFound.add (new PluginDescription (*d));
- }
- }
-
- if (! needsRescanning)
- return false;
- }
-
- for (int i = 0; i < AudioPluginFormatManager::getInstance()->getNumFormats(); ++i)
- {
- AudioPluginFormat* const format = AudioPluginFormatManager::getInstance()->getFormat (i);
-
- OwnedArray <PluginDescription> found;
- format->findAllTypesForFile (found, possiblePluginFile);
-
- for (int i = 0; i < found.size(); ++i)
- {
- PluginDescription* const desc = found.getUnchecked(i);
- jassert (desc != 0);
-
- if (addType (*desc))
- addedOne = true;
-
- typesFound.add (new PluginDescription (*desc));
- }
- }
-
- return addedOne;
- }
-
- void KnownPluginList::scanAndAddDragAndDroppedFiles (const StringArray& files,
- OwnedArray <PluginDescription>& typesFound)
- {
- for (int i = 0; i < files.size(); ++i)
- {
- const File f (files [i]);
-
- if (! scanAndAddFile (f, true, typesFound))
- {
- if (f.isDirectory())
- {
- StringArray s;
-
- {
- OwnedArray <File> subFiles;
- f.findChildFiles (subFiles, File::findFilesAndDirectories, false);
-
- for (int j = 0; j < subFiles.size(); ++j)
- s.add (subFiles.getUnchecked (j)->getFullPathName());
- }
-
- scanAndAddDragAndDroppedFiles (s, typesFound);
- }
- }
- }
- }
-
- class PluginSorter
- {
- public:
- KnownPluginList::SortMethod method;
-
- PluginSorter() throw() {}
-
- int compareElements (const PluginDescription* const first,
- const PluginDescription* const second) const throw()
- {
- int diff = 0;
-
- if (method == KnownPluginList::sortByCategory)
- diff = first->category.compareLexicographically (second->category);
- else if (method == KnownPluginList::sortByManufacturer)
- diff = first->manufacturerName.compareLexicographically (second->manufacturerName);
- else if (method == KnownPluginList::sortByFileSystemLocation)
- diff = first->file.getParentDirectory().getFullPathName().compare (second->file.getParentDirectory().getFullPathName());
-
- if (diff == 0)
- diff = first->name.compareLexicographically (second->name);
-
- return diff;
- }
- };
-
- void KnownPluginList::sort (const SortMethod method)
- {
- if (method != defaultOrder)
- {
- PluginSorter sorter;
- sorter.method = method;
- types.sort (sorter, true);
-
- sendChangeMessage (this);
- }
- }
-
- XmlElement* KnownPluginList::createXml() const
- {
- XmlElement* const e = new XmlElement (T("KNOWNPLUGINS"));
-
- for (int i = 0; i < types.size(); ++i)
- e->addChildElement (types.getUnchecked(i)->createXml());
-
- return e;
- }
-
- void KnownPluginList::recreateFromXml (const XmlElement& xml)
- {
- clear();
-
- if (xml.hasTagName (T("KNOWNPLUGINS")))
- {
- forEachXmlChildElement (xml, e)
- {
- PluginDescription info;
-
- if (info.loadFromXml (*e))
- addType (info);
- }
- }
- }
-
- const int menuIdBase = 0x324503f4;
-
- // This is used to turn a bunch of paths into a nested menu structure.
- struct PluginFilesystemTree
- {
- private:
- String folder;
- OwnedArray <PluginFilesystemTree> subFolders;
- Array <PluginDescription*> plugins;
-
- void addPlugin (PluginDescription* const pd, const String& path)
- {
- if (path.isEmpty())
- {
- plugins.add (pd);
- }
- else
- {
- const String firstSubFolder (path.upToFirstOccurrenceOf (T("/"), false, false));
- const String remainingPath (path.fromFirstOccurrenceOf (T("/"), false, false));
-
- for (int i = subFolders.size(); --i >= 0;)
- {
- if (subFolders.getUnchecked(i)->folder.equalsIgnoreCase (firstSubFolder))
- {
- subFolders.getUnchecked(i)->addPlugin (pd, remainingPath);
- return;
- }
- }
-
- PluginFilesystemTree* const newFolder = new PluginFilesystemTree();
- newFolder->folder = firstSubFolder;
- subFolders.add (newFolder);
-
- newFolder->addPlugin (pd, remainingPath);
- }
- }
-
- // removes any deeply nested folders that don't contain any actual plugins
- void optimise()
- {
- for (int i = subFolders.size(); --i >= 0;)
- {
- PluginFilesystemTree* const sub = subFolders.getUnchecked(i);
-
- sub->optimise();
-
- if (sub->plugins.size() == 0)
- {
- for (int j = 0; j < sub->subFolders.size(); ++j)
- subFolders.add (sub->subFolders.getUnchecked(j));
-
- sub->subFolders.clear (false);
- subFolders.remove (i);
- }
- }
- }
-
- public:
- void buildTree (const Array <PluginDescription*>& allPlugins)
- {
- for (int i = 0; i < allPlugins.size(); ++i)
- {
- String path (allPlugins.getUnchecked(i)->file.getParentDirectory().getFullPathName());
-
- if (path.substring (1, 2) == T(":"))
- path = path.substring (2);
-
- path = path.replaceCharacter (T('\\'), T('/'));
-
- addPlugin (allPlugins.getUnchecked(i), path);
- }
-
- optimise();
- }
-
- void addToMenu (PopupMenu& m, const OwnedArray <PluginDescription>& allPlugins) const
- {
- int i;
- for (i = 0; i < subFolders.size(); ++i)
- {
- const PluginFilesystemTree* const sub = subFolders.getUnchecked(i);
-
- PopupMenu subMenu;
- sub->addToMenu (subMenu, allPlugins);
- m.addSubMenu (sub->folder, subMenu);
- }
-
- for (i = 0; i < plugins.size(); ++i)
- {
- PluginDescription* const plugin = plugins.getUnchecked(i);
-
- m.addItem (allPlugins.indexOf (plugin) + menuIdBase,
- plugin->name, true, false);
- }
- }
- };
-
- void KnownPluginList::addToMenu (PopupMenu& menu, const SortMethod sortMethod) const
- {
- Array <PluginDescription*> sorted;
-
- {
- PluginSorter sorter;
- sorter.method = sortMethod;
-
- for (int i = 0; i < types.size(); ++i)
- sorted.addSorted (sorter, types.getUnchecked(i));
- }
-
- if (sortMethod == sortByCategory
- || sortMethod == sortByManufacturer)
- {
- String lastSubMenuName;
- PopupMenu sub;
-
- for (int i = 0; i < sorted.size(); ++i)
- {
- const PluginDescription* const pd = sorted.getUnchecked(i);
- String thisSubMenuName (sortMethod == sortByCategory ? pd->category
- : pd->manufacturerName);
-
- if (thisSubMenuName.trim().isEmpty())
- thisSubMenuName = T("Other");
-
- if (thisSubMenuName != lastSubMenuName)
- {
- if (sub.getNumItems() > 0)
- {
- menu.addSubMenu (lastSubMenuName, sub);
- sub.clear();
- }
-
- lastSubMenuName = thisSubMenuName;
- }
-
- sub.addItem (types.indexOf (pd) + menuIdBase, pd->name, true, false);
- }
-
- if (sub.getNumItems() > 0)
- menu.addSubMenu (lastSubMenuName, sub);
- }
- else if (sortMethod == sortByFileSystemLocation)
- {
- PluginFilesystemTree root;
- root.buildTree (sorted);
- root.addToMenu (menu, types);
- }
- else
- {
- for (int i = 0; i < sorted.size(); ++i)
- {
- const PluginDescription* const pd = sorted.getUnchecked(i);
- menu.addItem (types.indexOf (pd) + menuIdBase, pd->name, true, false);
- }
- }
- }
-
- int KnownPluginList::getIndexChosenByMenu (const int menuResultCode) const
- {
- const int i = menuResultCode - menuIdBase;
-
- return (((unsigned int) i) < (unsigned int) types.size()) ? i : -1;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_KnownPluginList.cpp *********/
-
- /********* Start of inlined file: juce_PluginDescription.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- PluginDescription::PluginDescription() throw()
- : uid (0),
- isInstrument (false),
- numInputChannels (0),
- numOutputChannels (0)
- {
- }
-
- PluginDescription::~PluginDescription() throw()
- {
- }
-
- PluginDescription::PluginDescription (const PluginDescription& other) throw()
- : name (other.name),
- pluginFormatName (other.pluginFormatName),
- category (other.category),
- manufacturerName (other.manufacturerName),
- version (other.version),
- file (other.file),
- lastFileModTime (other.lastFileModTime),
- uid (other.uid),
- isInstrument (other.isInstrument),
- numInputChannels (other.numInputChannels),
- numOutputChannels (other.numOutputChannels)
- {
- }
-
- const PluginDescription& PluginDescription::operator= (const PluginDescription& other) throw()
- {
- name = other.name;
- pluginFormatName = other.pluginFormatName;
- category = other.category;
- manufacturerName = other.manufacturerName;
- version = other.version;
- file = other.file;
- uid = other.uid;
- isInstrument = other.isInstrument;
- lastFileModTime = other.lastFileModTime;
- numInputChannels = other.numInputChannels;
- numOutputChannels = other.numOutputChannels;
-
- return *this;
- }
-
- bool PluginDescription::isDuplicateOf (const PluginDescription& other) const
- {
- return file == other.file
- && uid == other.uid;
- }
-
- const String PluginDescription::createIdentifierString() const throw()
- {
- return pluginFormatName
- + T("-") + name
- + T("-") + String::toHexString (file.getFileName().hashCode())
- + T("-") + String::toHexString (uid);
- }
-
- XmlElement* PluginDescription::createXml() const
- {
- XmlElement* const e = new XmlElement (T("PLUGIN"));
- e->setAttribute (T("name"), name);
- e->setAttribute (T("format"), pluginFormatName);
- e->setAttribute (T("category"), category);
- e->setAttribute (T("manufacturer"), manufacturerName);
- e->setAttribute (T("version"), version);
- e->setAttribute (T("file"), file.getFullPathName());
- e->setAttribute (T("uid"), String::toHexString (uid));
- e->setAttribute (T("isInstrument"), isInstrument);
- e->setAttribute (T("fileTime"), String::toHexString (lastFileModTime.toMilliseconds()));
- e->setAttribute (T("numInputs"), numInputChannels);
- e->setAttribute (T("numOutputs"), numOutputChannels);
-
- return e;
- }
-
- bool PluginDescription::loadFromXml (const XmlElement& xml)
- {
- if (xml.hasTagName (T("PLUGIN")))
- {
- name = xml.getStringAttribute (T("name"));
- pluginFormatName = xml.getStringAttribute (T("format"));
- category = xml.getStringAttribute (T("category"));
- manufacturerName = xml.getStringAttribute (T("manufacturer"));
- version = xml.getStringAttribute (T("version"));
- file = File (xml.getStringAttribute (T("file")));
- uid = xml.getStringAttribute (T("uid")).getHexValue32();
- isInstrument = xml.getBoolAttribute (T("isInstrument"), false);
- lastFileModTime = Time (xml.getStringAttribute (T("fileTime")).getHexValue64());
- numInputChannels = xml.getIntAttribute (T("numInputs"));
- numOutputChannels = xml.getIntAttribute (T("numOutputs"));
-
- return true;
- }
-
- return false;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_PluginDescription.cpp *********/
-
- /********* Start of inlined file: juce_PluginDirectoryScanner.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- PluginDirectoryScanner::PluginDirectoryScanner (KnownPluginList& listToAddTo,
- AudioPluginFormat& formatToLookFor,
- FileSearchPath directoriesToSearch,
- const bool recursive,
- const File& deadMansPedalFile_)
- : list (listToAddTo),
- format (formatToLookFor),
- deadMansPedalFile (deadMansPedalFile_),
- nextIndex (0),
- progress (0)
- {
- directoriesToSearch.removeRedundantPaths();
-
- for (int j = 0; j < directoriesToSearch.getNumPaths(); ++j)
- recursiveFileSearch (directoriesToSearch [j], recursive);
-
- // If any plugins have crashed recently when being loaded, move them to the
- // end of the list to give the others a chance to load correctly..
- const StringArray crashedPlugins (getDeadMansPedalFile());
-
- for (int i = 0; i < crashedPlugins.size(); ++i)
- {
- const File f (crashedPlugins[i]);
-
- for (int j = filesToScan.size(); --j >= 0;)
- if (f == *filesToScan.getUnchecked (j))
- filesToScan.move (j, -1);
- }
- }
-
- void PluginDirectoryScanner::recursiveFileSearch (const File& dir, const bool recursive)
- {
- // avoid allowing the dir iterator to be recursive, because we want to avoid letting it delve inside
- // .component or .vst directories.
- DirectoryIterator iter (dir, false, "*", File::findFilesAndDirectories);
-
- while (iter.next())
- {
- const File f (iter.getFile());
- bool isPlugin = false;
-
- if (format.fileMightContainThisPluginType (f))
- {
- isPlugin = true;
- filesToScan.add (new File (f));
- }
-
- if (recursive && (! isPlugin) && f.isDirectory())
- recursiveFileSearch (f, true);
- }
- }
-
- PluginDirectoryScanner::~PluginDirectoryScanner()
- {
- }
-
- const File PluginDirectoryScanner::getNextPluginFileThatWillBeScanned() const throw()
- {
- File* const file = filesToScan [nextIndex];
-
- if (file != 0)
- return *file;
-
- return File::nonexistent;
- }
-
- bool PluginDirectoryScanner::scanNextFile (const bool dontRescanIfAlreadyInList)
- {
- File* const file = filesToScan [nextIndex];
-
- if (file != 0)
- {
- if (! list.isListingUpToDate (*file))
- {
- OwnedArray <PluginDescription> typesFound;
-
- // Add this plugin to the end of the dead-man's pedal list in case it crashes...
- StringArray crashedPlugins (getDeadMansPedalFile());
- crashedPlugins.removeString (file->getFullPathName());
- crashedPlugins.add (file->getFullPathName());
- setDeadMansPedalFile (crashedPlugins);
-
- list.scanAndAddFile (*file,
- dontRescanIfAlreadyInList,
- typesFound);
-
- // Managed to load without crashing, so remove it from the dead-man's-pedal..
- crashedPlugins.removeString (file->getFullPathName());
- setDeadMansPedalFile (crashedPlugins);
-
- if (typesFound.size() == 0)
- failedFiles.add (file->getFullPathName());
- }
-
- ++nextIndex;
- progress = nextIndex / (float) filesToScan.size();
- }
-
- return nextIndex < filesToScan.size();
- }
-
- const StringArray PluginDirectoryScanner::getDeadMansPedalFile() throw()
- {
- StringArray lines;
-
- if (deadMansPedalFile != File::nonexistent)
- {
- lines.addLines (deadMansPedalFile.loadFileAsString());
- lines.removeEmptyStrings();
- }
-
- return lines;
- }
-
- void PluginDirectoryScanner::setDeadMansPedalFile (const StringArray& newContents) throw()
- {
- if (deadMansPedalFile != File::nonexistent)
- deadMansPedalFile.replaceWithText (newContents.joinIntoString ("\n"), true, true);
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_PluginDirectoryScanner.cpp *********/
-
- /********* Start of inlined file: juce_PluginListComponent.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- PluginListComponent::PluginListComponent (KnownPluginList& listToEdit,
- const File& deadMansPedalFile_,
- PropertiesFile* const propertiesToUse_)
- : list (listToEdit),
- deadMansPedalFile (deadMansPedalFile_),
- propertiesToUse (propertiesToUse_)
- {
- addAndMakeVisible (listBox = new ListBox (String::empty, this));
-
- addAndMakeVisible (optionsButton = new TextButton ("Options..."));
- optionsButton->addButtonListener (this);
- optionsButton->setTriggeredOnMouseDown (true);
-
- setSize (400, 600);
- list.addChangeListener (this);
- }
-
- PluginListComponent::~PluginListComponent()
- {
- list.removeChangeListener (this);
- deleteAllChildren();
- }
-
- void PluginListComponent::resized()
- {
- listBox->setBounds (0, 0, getWidth(), getHeight() - 30);
- optionsButton->changeWidthToFitText (24);
- optionsButton->setTopLeftPosition (8, getHeight() - 28);
- }
-
- void PluginListComponent::changeListenerCallback (void*)
- {
- listBox->updateContent();
- listBox->repaint();
- }
-
- int PluginListComponent::getNumRows()
- {
- return list.getNumTypes();
- }
-
- void PluginListComponent::paintListBoxItem (int row,
- Graphics& g,
- int width, int height,
- bool rowIsSelected)
- {
- if (rowIsSelected)
- g.fillAll (findColour (TextEditor::highlightColourId));
-
- const PluginDescription* const pd = list.getType (row);
-
- if (pd != 0)
- {
- GlyphArrangement ga;
- ga.addCurtailedLineOfText (Font (height * 0.7f, Font::bold), pd->name, 8.0f, height * 0.8f, width - 10.0f, true);
-
- g.setColour (Colours::black);
- ga.draw (g);
-
- float x, y, r, b;
- ga.getBoundingBox (0, -1, x, y, r, b, false);
-
- String desc;
- desc << pd->pluginFormatName
- << (pd->isInstrument ? " instrument" : " effect")
- << " - "
- << pd->numInputChannels << (pd->numInputChannels == 1 ? " in" : " ins")
- << " / "
- << pd->numOutputChannels << (pd->numOutputChannels == 1 ? " out" : " outs");
-
- if (pd->manufacturerName.isNotEmpty())
- desc << " - " << pd->manufacturerName;
-
- if (pd->version.isNotEmpty())
- desc << " - " << pd->version;
-
- if (pd->category.isNotEmpty())
- desc << " - category: '" << pd->category << '\'';
-
- g.setColour (Colours::grey);
-
- ga.clear();
- ga.addCurtailedLineOfText (Font (height * 0.6f), desc, r + 10.0f, height * 0.8f, width - r - 12.0f, true);
- ga.draw (g);
- }
- }
-
- void PluginListComponent::deleteKeyPressed (int lastRowSelected)
- {
- list.removeType (lastRowSelected);
- }
-
- void PluginListComponent::buttonClicked (Button* b)
- {
- if (optionsButton == b)
- {
- PopupMenu menu;
- menu.addItem (1, TRANS("Clear list"));
- menu.addItem (5, TRANS("Remove selected plugin from list"), listBox->getNumSelectedRows() > 0);
- menu.addItem (6, TRANS("Show folder containing selected plugin"), listBox->getNumSelectedRows() > 0);
- menu.addItem (7, TRANS("Remove any plugins whose files no longer exist"));
- menu.addSeparator();
- menu.addItem (2, TRANS("Sort alphabetically"));
- menu.addItem (3, TRANS("Sort by category"));
- menu.addItem (4, TRANS("Sort by manufacturer"));
- menu.addSeparator();
-
- for (int i = 0; i < AudioPluginFormatManager::getInstance()->getNumFormats(); ++i)
- {
- AudioPluginFormat* const format = AudioPluginFormatManager::getInstance()->getFormat (i);
-
- if (format->getDefaultLocationsToSearch().getNumPaths() > 0)
- menu.addItem (10 + i, "Scan for new or updated " + format->getName() + " plugins...");
- }
-
- const int r = menu.showAt (optionsButton);
-
- if (r == 1)
- {
- list.clear();
- }
- else if (r == 2)
- {
- list.sort (KnownPluginList::sortAlphabetically);
- }
- else if (r == 3)
- {
- list.sort (KnownPluginList::sortByCategory);
- }
- else if (r == 4)
- {
- list.sort (KnownPluginList::sortByManufacturer);
- }
- else if (r == 5)
- {
- const SparseSet <int> selected (listBox->getSelectedRows());
-
- for (int i = list.getNumTypes(); --i >= 0;)
- if (selected.contains (i))
- list.removeType (i);
- }
- else if (r == 6)
- {
- const PluginDescription* const desc = list.getType (listBox->getSelectedRow());
-
- if (desc != 0)
- desc->file.getParentDirectory().startAsProcess();
- }
- else if (r == 7)
- {
- for (int i = list.getNumTypes(); --i >= 0;)
- {
- if (list.getType (i)->file != File::nonexistent
- && ! list.getType (i)->file.exists())
- {
- list.removeType (i);
- }
- }
- }
- else if (r != 0)
- {
- typeToScan = r - 10;
- startTimer (1);
- }
- }
- }
-
- void PluginListComponent::timerCallback()
- {
- stopTimer();
- scanFor (AudioPluginFormatManager::getInstance()->getFormat (typeToScan));
- }
-
- bool PluginListComponent::isInterestedInFileDrag (const StringArray& /*files*/)
- {
- return true;
- }
-
- void PluginListComponent::filesDropped (const StringArray& files, int, int)
- {
- OwnedArray <PluginDescription> typesFound;
- list.scanAndAddDragAndDroppedFiles (files, typesFound);
- }
-
- void PluginListComponent::scanFor (AudioPluginFormat* format)
- {
- if (format == 0)
- return;
-
- FileSearchPath path (format->getDefaultLocationsToSearch());
-
- if (propertiesToUse != 0)
- path = propertiesToUse->getValue ("lastPluginScanPath_" + format->getName(), path.toString());
-
- {
- AlertWindow aw (TRANS("Select folders to scan..."), String::empty, AlertWindow::NoIcon);
- FileSearchPathListComponent pathList;
- pathList.setSize (500, 300);
- pathList.setPath (path);
-
- aw.addCustomComponent (&pathList);
- aw.addButton (TRANS("Scan"), 1, KeyPress::returnKey);
- aw.addButton (TRANS("Cancel"), 0, KeyPress (KeyPress::escapeKey));
-
- if (aw.runModalLoop() == 0)
- return;
-
- path = pathList.getPath();
- }
-
- if (propertiesToUse != 0)
- {
- propertiesToUse->setValue ("lastPluginScanPath_" + format->getName(), path.toString());
- propertiesToUse->saveIfNeeded();
- }
-
- double progress = 0.0;
-
- AlertWindow aw (TRANS("Scanning for plugins..."),
- TRANS("Searching for all possible plugin files..."), AlertWindow::NoIcon);
-
- aw.addButton (TRANS("Cancel"), 0, KeyPress (KeyPress::escapeKey));
- aw.addProgressBarComponent (progress);
-
- aw.enterModalState();
-
- MessageManager::getInstance()->dispatchPendingMessages();
-
- PluginDirectoryScanner scanner (list, *format, path, true, deadMansPedalFile);
-
- for (;;)
- {
- aw.setMessage (TRANS("Testing:\n\n")
- + scanner.getNextPluginFileThatWillBeScanned().getFileName());
-
- MessageManager::getInstance()->dispatchPendingMessages (500);
-
- if (! scanner.scanNextFile (true))
- break;
-
- if (! aw.isCurrentlyModal())
- break;
-
- progress = scanner.getProgress();
- }
-
- if (scanner.getFailedFiles().size() > 0)
- {
- StringArray shortNames;
-
- for (int i = 0; i < scanner.getFailedFiles().size(); ++i)
- shortNames.add (File (scanner.getFailedFiles()[i]).getFileName());
-
- AlertWindow::showMessageBox (AlertWindow::InfoIcon,
- TRANS("Scan complete"),
- TRANS("Note that the following files appeared to be plugin files, but failed to load correctly:\n\n")
- + shortNames.joinIntoString (", "));
- }
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_PluginListComponent.cpp *********/
-
- /********* Start of inlined file: juce_AudioUnitPluginFormat.cpp *********/
-
- #if JUCE_PLUGINHOST_AU && (! (defined (LINUX) || defined (_WIN32)))
-
- #include <Carbon/Carbon.h>
- #include <AudioToolbox/AudioToolbox.h>
- #include <AudioUnit/AudioUnitCarbonView.h>
-
- BEGIN_JUCE_NAMESPACE
-
- #if JUCE_MAC
-
- extern void juce_callAnyTimersSynchronously();
- extern bool juce_isHIViewCreatedByJuce (HIViewRef view);
- extern bool juce_isWindowCreatedByJuce (WindowRef window);
-
- #if MACOS_10_3_OR_EARLIER
- #define kAudioUnitType_Generator 'augn'
- #endif
-
- // Change this to disable logging of various activities
- #ifndef AU_LOGGING
- #define AU_LOGGING 1
- #endif
-
- #if AU_LOGGING
- #define log(a) Logger::writeToLog(a);
- #else
- #define log(a)
- #endif
-
- static int insideCallback = 0;
-
- class AudioUnitPluginWindow;
-
- class AudioUnitPluginInstance : public AudioPluginInstance
- {
- public:
-
- ~AudioUnitPluginInstance();
-
- // AudioPluginInstance methods:
-
- void fillInPluginDescription (PluginDescription& desc) const
- {
- desc.name = pluginName;
- desc.file = file;
- desc.uid = ((int) componentDesc.componentType)
- ^ ((int) componentDesc.componentSubType)
- ^ ((int) componentDesc.componentManufacturer);
- desc.lastFileModTime = file.getLastModificationTime();
- desc.pluginFormatName = "AudioUnit";
- desc.category = getCategory();
- desc.manufacturerName = manufacturer;
- desc.version = version;
- desc.numInputChannels = getNumInputChannels();
- desc.numOutputChannels = getNumOutputChannels();
- desc.isInstrument = (componentDesc.componentType == kAudioUnitType_MusicDevice);
- }
-
- const String getName() const { return pluginName; }
- bool acceptsMidi() const { return wantsMidiMessages; }
- bool producesMidi() const { return false; }
-
- // AudioProcessor methods:
-
- void prepareToPlay (double sampleRate, int estimatedSamplesPerBlock);
- void releaseResources();
- void processBlock (AudioSampleBuffer& buffer,
- MidiBuffer& midiMessages);
-
- AudioProcessorEditor* createEditor();
-
- const String getInputChannelName (const int index) const;
- bool isInputChannelStereoPair (int index) const;
-
- const String getOutputChannelName (const int index) const;
- bool isOutputChannelStereoPair (int index) const;
-
- int getNumParameters();
- float getParameter (int index);
- void setParameter (int index, float newValue);
- const String getParameterName (int index);
- const String getParameterText (int index);
- bool isParameterAutomatable (int index) const;
-
- int getNumPrograms();
- int getCurrentProgram();
- void setCurrentProgram (int index);
- const String getProgramName (int index);
- void changeProgramName (int index, const String& newName);
-
- void getStateInformation (MemoryBlock& destData);
- void getCurrentProgramStateInformation (MemoryBlock& destData);
- void setStateInformation (const void* data, int sizeInBytes);
- void setCurrentProgramStateInformation (const void* data, int sizeInBytes);
-
- juce_UseDebuggingNewOperator
-
- private:
- friend class AudioUnitPluginWindow;
- friend class AudioUnitPluginFormat;
-
- ComponentDescription componentDesc;
- String pluginName, manufacturer, version;
- File file;
- CriticalSection lock;
- bool initialised, wantsMidiMessages, wasPlaying;
-
- AudioBufferList* outputBufferList;
- AudioTimeStamp timeStamp;
- AudioSampleBuffer* currentBuffer;
-
- AudioUnit audioUnit;
- Array <int> parameterIds;
-
- bool getComponentDescFromFile (const File& file);
- void initialise();
-
- OSStatus renderGetInput (AudioUnitRenderActionFlags* ioActionFlags,
- const AudioTimeStamp* inTimeStamp,
- UInt32 inBusNumber,
- UInt32 inNumberFrames,
- AudioBufferList* ioData) const;
-
- static OSStatus renderGetInputCallback (void* inRefCon,
- AudioUnitRenderActionFlags* ioActionFlags,
- const AudioTimeStamp* inTimeStamp,
- UInt32 inBusNumber,
- UInt32 inNumberFrames,
- AudioBufferList* ioData)
- {
- return ((AudioUnitPluginInstance*) inRefCon)
- ->renderGetInput (ioActionFlags, inTimeStamp, inBusNumber, inNumberFrames, ioData);
- }
-
- OSStatus getBeatAndTempo (Float64* outCurrentBeat, Float64* outCurrentTempo) const;
- OSStatus getMusicalTimeLocation (UInt32* outDeltaSampleOffsetToNextBeat, Float32* outTimeSig_Numerator,
- UInt32* outTimeSig_Denominator, Float64* outCurrentMeasureDownBeat) const;
- OSStatus getTransportState (Boolean* outIsPlaying, Boolean* outTransportStateChanged,
- Float64* outCurrentSampleInTimeLine, Boolean* outIsCycling,
- Float64* outCycleStartBeat, Float64* outCycleEndBeat);
-
- static OSStatus getBeatAndTempoCallback (void* inHostUserData, Float64* outCurrentBeat, Float64* outCurrentTempo)
- {
- return ((AudioUnitPluginInstance*) inHostUserData)->getBeatAndTempo (outCurrentBeat, outCurrentTempo);
- }
-
- static OSStatus getMusicalTimeLocationCallback (void* inHostUserData, UInt32* outDeltaSampleOffsetToNextBeat,
- Float32* outTimeSig_Numerator, UInt32* outTimeSig_Denominator,
- Float64* outCurrentMeasureDownBeat)
- {
- return ((AudioUnitPluginInstance*) inHostUserData)
- ->getMusicalTimeLocation (outDeltaSampleOffsetToNextBeat, outTimeSig_Numerator,
- outTimeSig_Denominator, outCurrentMeasureDownBeat);
- }
-
- static OSStatus getTransportStateCallback (void* inHostUserData, Boolean* outIsPlaying, Boolean* outTransportStateChanged,
- Float64* outCurrentSampleInTimeLine, Boolean* outIsCycling,
- Float64* outCycleStartBeat, Float64* outCycleEndBeat)
- {
- return ((AudioUnitPluginInstance*) inHostUserData)
- ->getTransportState (outIsPlaying, outTransportStateChanged,
- outCurrentSampleInTimeLine, outIsCycling,
- outCycleStartBeat, outCycleEndBeat);
- }
-
- void getNumChannels (int& numIns, int& numOuts)
- {
- numIns = 0;
- numOuts = 0;
-
- AUChannelInfo supportedChannels [128];
- UInt32 supportedChannelsSize = sizeof (supportedChannels);
-
- if (AudioUnitGetProperty (audioUnit, kAudioUnitProperty_SupportedNumChannels, kAudioUnitScope_Global,
- 0, supportedChannels, &supportedChannelsSize) == noErr
- && supportedChannelsSize > 0)
- {
- for (int i = 0; i < supportedChannelsSize / sizeof (AUChannelInfo); ++i)
- {
- numIns = jmax (numIns, supportedChannels[i].inChannels);
- numOuts = jmax (numOuts, supportedChannels[i].outChannels);
- }
- }
- else
- {
- // (this really means the plugin will take any number of ins/outs as long
- // as they are the same)
- numIns = numOuts = 2;
- }
- }
-
- const String getCategory() const;
-
- AudioUnitPluginInstance (const File& file);
- };
-
- AudioUnitPluginInstance::AudioUnitPluginInstance (const File& file_)
- : file (file_),
- initialised (false),
- wantsMidiMessages (false),
- audioUnit (0),
- outputBufferList (0),
- currentBuffer (0)
- {
- try
- {
- ++insideCallback;
-
- log (T("Opening AU: ") + file.getFullPathName());
-
- if (getComponentDescFromFile (file))
- {
- ComponentRecord* const comp = FindNextComponent (0, &componentDesc);
-
- if (comp != 0)
- {
- audioUnit = (AudioUnit) OpenComponent (comp);
-
- wantsMidiMessages = componentDesc.componentType == kAudioUnitType_MusicDevice
- || componentDesc.componentType == kAudioUnitType_MusicEffect;
- }
- }
-
- --insideCallback;
- }
- catch (...)
- {
- --insideCallback;
- }
- }
-
- AudioUnitPluginInstance::~AudioUnitPluginInstance()
- {
- {
- const ScopedLock sl (lock);
-
- jassert (insideCallback == 0);
-
- if (audioUnit != 0)
- {
- AudioUnitUninitialize (audioUnit);
- CloseComponent (audioUnit);
- audioUnit = 0;
- }
- }
-
- juce_free (outputBufferList);
- }
-
- bool AudioUnitPluginInstance::getComponentDescFromFile (const File& file)
- {
- zerostruct (componentDesc);
-
- if (! file.hasFileExtension (T(".component")))
- return false;
-
- const String filename (file.getFullPathName());
- const char* const utf8 = filename.toUTF8();
- CFURLRef url = CFURLCreateFromFileSystemRepresentation (0, (const UInt8*) utf8,
- strlen (utf8), file.isDirectory());
- if (url != 0)
- {
- CFBundleRef bundleRef = CFBundleCreate (kCFAllocatorDefault, url);
- CFRelease (url);
-
- if (bundleRef != 0)
- {
- CFTypeRef name = CFBundleGetValueForInfoDictionaryKey (bundleRef, CFSTR("CFBundleName"));
-
- if (name != 0 && CFGetTypeID (name) == CFStringGetTypeID())
- pluginName = PlatformUtilities::cfStringToJuceString ((CFStringRef) name);
-
- if (pluginName.isEmpty())
- pluginName = file.getFileNameWithoutExtension();
-
- CFTypeRef versionString = CFBundleGetValueForInfoDictionaryKey (bundleRef, CFSTR("CFBundleVersion"));
-
- if (versionString != 0 && CFGetTypeID (versionString) == CFStringGetTypeID())
- version = PlatformUtilities::cfStringToJuceString ((CFStringRef) versionString);
-
- CFTypeRef manuString = CFBundleGetValueForInfoDictionaryKey (bundleRef, CFSTR("CFBundleGetInfoString"));
-
- if (manuString != 0 && CFGetTypeID (manuString) == CFStringGetTypeID())
- manufacturer = PlatformUtilities::cfStringToJuceString ((CFStringRef) manuString);
-
- short resFileId = CFBundleOpenBundleResourceMap (bundleRef);
- UseResFile (resFileId);
-
- for (int i = 1; i <= Count1Resources ('thng'); ++i)
- {
- Handle h = Get1IndResource ('thng', i);
-
- if (h != 0)
- {
- HLock (h);
- const uint32* const types = (const uint32*) *h;
-
- if (types[0] == kAudioUnitType_MusicDevice
- || types[0] == kAudioUnitType_MusicEffect
- || types[0] == kAudioUnitType_Effect
- || types[0] == kAudioUnitType_Generator
- || types[0] == kAudioUnitType_Panner)
- {
- componentDesc.componentType = types[0];
- componentDesc.componentSubType = types[1];
- componentDesc.componentManufacturer = types[2];
- break;
- }
-
- HUnlock (h);
- ReleaseResource (h);
- }
- }
-
- CFBundleCloseBundleResourceMap (bundleRef, resFileId);
- CFRelease (bundleRef);
- }
- }
-
- return componentDesc.componentType != 0 && componentDesc.componentSubType != 0;
- }
-
- void AudioUnitPluginInstance::initialise()
- {
- if (initialised || audioUnit == 0)
- return;
-
- log (T("Initialising AU: ") + pluginName);
-
- parameterIds.clear();
-
- {
- UInt32 paramListSize = 0;
- AudioUnitGetProperty (audioUnit, kAudioUnitProperty_ParameterList, kAudioUnitScope_Global,
- 0, 0, ¶mListSize);
-
- if (paramListSize > 0)
- {
- parameterIds.insertMultiple (0, 0, paramListSize / sizeof (int));
-
- AudioUnitGetProperty (audioUnit, kAudioUnitProperty_ParameterList, kAudioUnitScope_Global,
- 0, ¶meterIds.getReference(0), ¶mListSize);
- }
- }
-
- {
- AURenderCallbackStruct info;
- zerostruct (info);
- info.inputProcRefCon = this;
- info.inputProc = renderGetInputCallback;
-
- AudioUnitSetProperty (audioUnit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input,
- 0, &info, sizeof (info));
- }
-
- {
- HostCallbackInfo info;
- zerostruct (info);
- info.hostUserData = this;
- info.beatAndTempoProc = getBeatAndTempoCallback;
- info.musicalTimeLocationProc = getMusicalTimeLocationCallback;
- info.transportStateProc = getTransportStateCallback;
-
- AudioUnitSetProperty (audioUnit, kAudioUnitProperty_HostCallbacks, kAudioUnitScope_Global,
- 0, &info, sizeof (info));
- }
-
- int numIns, numOuts;
- getNumChannels (numIns, numOuts);
- setPlayConfigDetails (numIns, numOuts, 0, 0);
-
- initialised = AudioUnitInitialize (audioUnit) == noErr;
-
- setLatencySamples (0);
- }
-
- void AudioUnitPluginInstance::prepareToPlay (double sampleRate_,
- int samplesPerBlockExpected)
- {
- initialise();
-
- if (initialised)
- {
- int numIns, numOuts;
- getNumChannels (numIns, numOuts);
-
- setPlayConfigDetails (numIns, numOuts, sampleRate_, samplesPerBlockExpected);
-
- Float64 latencySecs = 0.0;
- UInt32 latencySize = sizeof (latencySecs);
- AudioUnitGetProperty (audioUnit, kAudioUnitProperty_Latency, kAudioUnitScope_Global,
- 0, &latencySecs, &latencySize);
-
- setLatencySamples (roundDoubleToInt (latencySecs * sampleRate_));
-
- AudioUnitReset (audioUnit, kAudioUnitScope_Input, 0);
- AudioUnitReset (audioUnit, kAudioUnitScope_Output, 0);
- AudioUnitReset (audioUnit, kAudioUnitScope_Global, 0);
-
- AudioStreamBasicDescription stream;
- zerostruct (stream);
- stream.mSampleRate = sampleRate_;
- stream.mFormatID = kAudioFormatLinearPCM;
- stream.mFormatFlags = kAudioFormatFlagsNativeFloatPacked | kAudioFormatFlagIsNonInterleaved;
- stream.mFramesPerPacket = 1;
- stream.mBytesPerPacket = 4;
- stream.mBytesPerFrame = 4;
- stream.mBitsPerChannel = 32;
- stream.mChannelsPerFrame = numIns;
-
- OSStatus err = AudioUnitSetProperty (audioUnit,
- kAudioUnitProperty_StreamFormat,
- kAudioUnitScope_Input,
- 0, &stream, sizeof (stream));
-
- stream.mChannelsPerFrame = numOuts;
-
- err = AudioUnitSetProperty (audioUnit,
- kAudioUnitProperty_StreamFormat,
- kAudioUnitScope_Output,
- 0, &stream, sizeof (stream));
-
- juce_free (outputBufferList);
- outputBufferList = (AudioBufferList*) juce_calloc (sizeof (AudioBufferList) + sizeof (AudioBuffer) * (numOuts + 1));
- outputBufferList->mNumberBuffers = numOuts;
-
- for (int i = numOuts; --i >= 0;)
- outputBufferList->mBuffers[i].mNumberChannels = 1;
-
- zerostruct (timeStamp);
- timeStamp.mSampleTime = 0;
- timeStamp.mHostTime = AudioGetCurrentHostTime();
- timeStamp.mFlags = kAudioTimeStampSampleTimeValid | kAudioTimeStampHostTimeValid;
-
- currentBuffer = 0;
- wasPlaying = false;
- }
- }
-
- void AudioUnitPluginInstance::releaseResources()
- {
- if (initialised)
- {
- AudioUnitReset (audioUnit, kAudioUnitScope_Input, 0);
- AudioUnitReset (audioUnit, kAudioUnitScope_Output, 0);
- AudioUnitReset (audioUnit, kAudioUnitScope_Global, 0);
-
- juce_free (outputBufferList);
- outputBufferList = 0;
- currentBuffer = 0;
- }
- }
-
- OSStatus AudioUnitPluginInstance::renderGetInput (AudioUnitRenderActionFlags* ioActionFlags,
- const AudioTimeStamp* inTimeStamp,
- UInt32 inBusNumber,
- UInt32 inNumberFrames,
- AudioBufferList* ioData) const
- {
- if (inBusNumber == 0
- && currentBuffer != 0)
- {
- jassert (inNumberFrames == currentBuffer->getNumSamples()); // if this ever happens, might need to add extra handling
-
- for (int i = 0; i < ioData->mNumberBuffers; ++i)
- {
- if (i < currentBuffer->getNumChannels())
- {
- memcpy (ioData->mBuffers[i].mData,
- currentBuffer->getSampleData (i, 0),
- sizeof (float) * inNumberFrames);
- }
- else
- {
- zeromem (ioData->mBuffers[i].mData, sizeof (float) * inNumberFrames);
- }
- }
- }
-
- return noErr;
- }
-
- void AudioUnitPluginInstance::processBlock (AudioSampleBuffer& buffer,
- MidiBuffer& midiMessages)
- {
- const int numSamples = buffer.getNumSamples();
-
- if (initialised)
- {
- AudioUnitRenderActionFlags flags = 0;
-
- timeStamp.mHostTime = AudioGetCurrentHostTime();
-
- for (int i = getNumOutputChannels(); --i >= 0;)
- {
- outputBufferList->mBuffers[i].mDataByteSize = sizeof (float) * numSamples;
- outputBufferList->mBuffers[i].mData = buffer.getSampleData (i, 0);
- }
-
- currentBuffer = &buffer;
-
- if (wantsMidiMessages)
- {
- const uint8* midiEventData;
- int midiEventSize, midiEventPosition;
- MidiBuffer::Iterator i (midiMessages);
-
- while (i.getNextEvent (midiEventData, midiEventSize, midiEventPosition))
- {
- if (midiEventSize <= 3)
- MusicDeviceMIDIEvent (audioUnit,
- midiEventData[0], midiEventData[1], midiEventData[2],
- midiEventPosition);
- else
- MusicDeviceSysEx (audioUnit, midiEventData, midiEventSize);
- }
-
- midiMessages.clear();
- }
-
- AudioUnitRender (audioUnit, &flags, &timeStamp,
- 0, numSamples, outputBufferList);
-
- timeStamp.mSampleTime += numSamples;
- }
- else
- {
- // Not initialised, so just bypass..
- for (int i = getNumInputChannels(); i < getNumOutputChannels(); ++i)
- buffer.clear (i, 0, buffer.getNumSamples());
- }
- }
-
- OSStatus AudioUnitPluginInstance::getBeatAndTempo (Float64* outCurrentBeat, Float64* outCurrentTempo) const
- {
- AudioPlayHead* const ph = getPlayHead();
- AudioPlayHead::CurrentPositionInfo result;
-
- if (ph != 0 && ph->getCurrentPosition (result))
- {
- *outCurrentBeat = result.ppqPosition;
- *outCurrentTempo = result.bpm;
- }
- else
- {
- *outCurrentBeat = 0;
- *outCurrentTempo = 120.0;
- }
-
- return noErr;
- }
-
- OSStatus AudioUnitPluginInstance::getMusicalTimeLocation (UInt32* outDeltaSampleOffsetToNextBeat,
- Float32* outTimeSig_Numerator,
- UInt32* outTimeSig_Denominator,
- Float64* outCurrentMeasureDownBeat) const
- {
- AudioPlayHead* const ph = getPlayHead();
- AudioPlayHead::CurrentPositionInfo result;
-
- if (ph != 0 && ph->getCurrentPosition (result))
- {
- *outTimeSig_Numerator = result.timeSigNumerator;
- *outTimeSig_Denominator = result.timeSigDenominator;
-
- *outDeltaSampleOffsetToNextBeat = 0; //xxx
- *outCurrentMeasureDownBeat = result.ppqPositionOfLastBarStart; //xxx wrong
- }
- else
- {
- *outDeltaSampleOffsetToNextBeat = 0;
- *outTimeSig_Numerator = 4;
- *outTimeSig_Denominator = 4;
- *outCurrentMeasureDownBeat = 0;
- }
-
- return noErr;
- }
-
- OSStatus AudioUnitPluginInstance::getTransportState (Boolean* outIsPlaying,
- Boolean* outTransportStateChanged,
- Float64* outCurrentSampleInTimeLine,
- Boolean* outIsCycling,
- Float64* outCycleStartBeat,
- Float64* outCycleEndBeat)
- {
- AudioPlayHead* const ph = getPlayHead();
- AudioPlayHead::CurrentPositionInfo result;
-
- if (ph != 0 && ph->getCurrentPosition (result))
- {
- *outIsPlaying = result.isPlaying;
- *outTransportStateChanged = result.isPlaying != wasPlaying;
- wasPlaying = result.isPlaying;
- *outCurrentSampleInTimeLine = roundDoubleToInt (result.timeInSeconds * getSampleRate());
- *outIsCycling = false;
- *outCycleStartBeat = 0;
- *outCycleEndBeat = 0;
- }
- else
- {
- *outIsPlaying = false;
- *outTransportStateChanged = false;
- *outCurrentSampleInTimeLine = 0;
- *outIsCycling = false;
- *outCycleStartBeat = 0;
- *outCycleEndBeat = 0;
- }
-
- return noErr;
- }
-
- static VoidArray activeWindows;
-
- class AudioUnitPluginWindow : public AudioProcessorEditor,
- public Timer
- {
- public:
-
- AudioUnitPluginWindow (AudioUnitPluginInstance& plugin_)
- : AudioProcessorEditor (&plugin_),
- plugin (plugin_),
- isOpen (false),
- pluginWantsKeys (false),
- wasShowing (false),
- recursiveResize (false),
- viewComponent (0),
- pluginViewRef (0)
- {
- movementWatcher = new CompMovementWatcher (this);
-
- activeWindows.add (this);
-
- setOpaque (true);
- setVisible (true);
- setSize (1, 1);
-
- ComponentDescription viewList [16];
- UInt32 viewListSize = sizeof (viewList);
- AudioUnitGetProperty (plugin.audioUnit, kAudioUnitProperty_GetUIComponentList, kAudioUnitScope_Global,
- 0, &viewList, &viewListSize);
-
- componentRecord = FindNextComponent (0, &viewList[0]);
- }
-
- ~AudioUnitPluginWindow()
- {
- deleteAndZero (movementWatcher);
-
- closePluginWindow();
-
- activeWindows.removeValue (this);
- plugin.editorBeingDeleted (this);
- }
-
- bool isValid() const throw() { return componentRecord != 0; }
-
- void componentMovedOrResized()
- {
- if (recursiveResize)
- return;
-
- Component* const topComp = getTopLevelComponent();
-
- if (topComp->getPeer() != 0)
- {
- int x = 0, y = 0;
- relativePositionToOtherComponent (topComp, x, y);
-
- recursiveResize = true;
-
- if (pluginViewRef != 0)
- {
- HIRect r;
- r.origin.x = (float) x;
- r.origin.y = (float) y;
- r.size.width = (float) getWidth();
- r.size.height = (float) getHeight();
- HIViewSetFrame (pluginViewRef, &r);
- }
-
- recursiveResize = false;
- }
- }
-
- void componentVisibilityChanged()
- {
- const bool isShowingNow = isShowing();
-
- if (wasShowing != isShowingNow)
- {
- wasShowing = isShowingNow;
-
- if (isShowingNow)
- openPluginWindow();
- else
- closePluginWindow();
- }
-
- componentMovedOrResized();
- }
-
- void componentPeerChanged()
- {
- closePluginWindow();
- openPluginWindow();
- }
-
- void timerCallback()
- {
- if (pluginViewRef != 0)
- {
- HIRect bounds;
- HIViewGetBounds (pluginViewRef, &bounds);
- const int w = jmax (32, (int) bounds.size.width);
- const int h = jmax (32, (int) bounds.size.height);
-
- if (w != getWidth() || h != getHeight())
- {
- setSize (w, h);
- startTimer (50);
- }
- else
- {
- startTimer (jlimit (50, 500, getTimerInterval() + 20));
- }
- }
- }
-
- bool keyStateChanged()
- {
- return pluginWantsKeys;
- }
-
- bool keyPressed (const KeyPress&)
- {
- return pluginWantsKeys;
- }
-
- void paint (Graphics& g)
- {
- if (isOpen)
- {
- ComponentPeer* const peer = getPeer();
-
- if (peer != 0)
- {
- peer->addMaskedRegion (getScreenX() - peer->getScreenX(),
- getScreenY() - peer->getScreenY(),
- getWidth(), getHeight());
- }
- }
- else
- {
- g.fillAll (Colours::black);
- }
- }
-
- void broughtToFront()
- {
- activeWindows.removeValue (this);
- activeWindows.add (this);
- }
-
- juce_UseDebuggingNewOperator
-
- private:
- AudioUnitPluginInstance& plugin;
- bool isOpen, wasShowing, recursiveResize;
- bool pluginWantsKeys;
-
- ComponentRecord* componentRecord;
- AudioUnitCarbonView viewComponent;
- HIViewRef pluginViewRef;
-
- void openPluginWindow()
- {
- if (isOpen || getWindowHandle() == 0 || componentRecord == 0)
- return;
-
- log (T("Opening AU GUI: ") + plugin.getName());
- isOpen = true;
-
- pluginWantsKeys = true; //xxx any way to find this out? Does it matter?
-
- viewComponent = (AudioUnitCarbonView) OpenComponent (componentRecord);
-
- if (viewComponent != 0)
- {
- Float32Point pos = { getScreenX() - getTopLevelComponent()->getScreenX(),
- getScreenY() - getTopLevelComponent()->getScreenY() };
- Float32Point size = { 250, 200 };
-
- AudioUnitCarbonViewCreate (viewComponent,
- plugin.audioUnit,
- (WindowRef) getWindowHandle(),
- HIViewGetRoot ((WindowRef) getWindowHandle()),
- &pos, &size,
- (ControlRef*) &pluginViewRef);
- }
-
- timerCallback(); // to set our comp to the right size
- repaint();
- }
-
- void closePluginWindow()
- {
- stopTimer();
-
- if (isOpen)
- {
- log (T("Closing AU GUI: ") + plugin.getName());
- isOpen = false;
-
- if (viewComponent != 0)
- CloseComponent (viewComponent);
-
- pluginViewRef = 0;
- }
- }
-
- class CompMovementWatcher : public ComponentMovementWatcher
- {
- public:
- CompMovementWatcher (AudioUnitPluginWindow* const owner_)
- : ComponentMovementWatcher (owner_),
- owner (owner_)
- {
- }
-
- void componentMovedOrResized (bool /*wasMoved*/, bool /*wasResized*/)
- {
- owner->componentMovedOrResized();
- }
-
- void componentPeerChanged()
- {
- owner->componentPeerChanged();
- }
-
- void componentVisibilityChanged (Component&)
- {
- owner->componentVisibilityChanged();
- }
-
- private:
- AudioUnitPluginWindow* const owner;
- };
-
- CompMovementWatcher* movementWatcher;
- };
-
- AudioProcessorEditor* AudioUnitPluginInstance::createEditor()
- {
- AudioUnitPluginWindow* w = new AudioUnitPluginWindow (*this);
-
- if (! w->isValid())
- deleteAndZero (w);
-
- return w;
- }
-
- const String AudioUnitPluginInstance::getCategory() const
- {
- const char* result = 0;
-
- switch (componentDesc.componentType)
- {
- case kAudioUnitType_Effect:
- case kAudioUnitType_MusicEffect:
- result = "Effect";
- break;
- case kAudioUnitType_MusicDevice:
- result = "Synth";
- break;
- case kAudioUnitType_Generator:
- result = "Generator";
- break;
- case kAudioUnitType_Panner:
- result = "Panner";
- break;
- default:
- break;
- }
-
- return result;
- }
-
- int AudioUnitPluginInstance::getNumParameters()
- {
- return parameterIds.size();
- }
-
- float AudioUnitPluginInstance::getParameter (int index)
- {
- const ScopedLock sl (lock);
-
- Float32 value = 0.0f;
-
- if (audioUnit != 0 && ((unsigned int) index) < (unsigned int) parameterIds.size())
- {
- AudioUnitGetParameter (audioUnit,
- (UInt32) parameterIds.getUnchecked (index),
- kAudioUnitScope_Global, 0,
- &value);
- }
-
- return value;
- }
-
- void AudioUnitPluginInstance::setParameter (int index, float newValue)
- {
- const ScopedLock sl (lock);
-
- if (audioUnit != 0 && ((unsigned int) index) < (unsigned int) parameterIds.size())
- {
- AudioUnitSetParameter (audioUnit,
- (UInt32) parameterIds.getUnchecked (index),
- kAudioUnitScope_Global, 0,
- newValue, 0);
- }
- }
-
- const String AudioUnitPluginInstance::getParameterName (int index)
- {
- AudioUnitParameterInfo info;
- zerostruct (info);
- UInt32 sz = sizeof (info);
-
- String name;
-
- if (AudioUnitGetProperty (audioUnit,
- kAudioUnitProperty_ParameterInfo,
- kAudioUnitScope_Global,
- parameterIds [index], &info, &sz) == noErr)
- {
- if ((info.flags & kAudioUnitParameterFlag_HasCFNameString) != 0)
- name = PlatformUtilities::cfStringToJuceString (info.cfNameString);
- else
- name = String (info.name, sizeof (info.name));
- }
-
- return name;
- }
-
- const String AudioUnitPluginInstance::getParameterText (int index)
- {
- return String (getParameter (index));
- }
-
- bool AudioUnitPluginInstance::isParameterAutomatable (int index) const
- {
- AudioUnitParameterInfo info;
- UInt32 sz = sizeof (info);
-
- if (AudioUnitGetProperty (audioUnit,
- kAudioUnitProperty_ParameterInfo,
- kAudioUnitScope_Global,
- parameterIds [index], &info, &sz) == noErr)
- {
- return (info.flags & kAudioUnitParameterFlag_NonRealTime) == 0;
- }
-
- return true;
- }
-
- int AudioUnitPluginInstance::getNumPrograms()
- {
- CFArrayRef presets;
- UInt32 sz = sizeof (CFArrayRef);
- int num = 0;
-
- if (AudioUnitGetProperty (audioUnit,
- kAudioUnitProperty_FactoryPresets,
- kAudioUnitScope_Global,
- 0, &presets, &sz) == noErr)
- {
- num = (int) CFArrayGetCount (presets);
- CFRelease (presets);
- }
-
- return num;
- }
-
- int AudioUnitPluginInstance::getCurrentProgram()
- {
- AUPreset current;
- current.presetNumber = 0;
- UInt32 sz = sizeof (AUPreset);
-
- AudioUnitGetProperty (audioUnit,
- kAudioUnitProperty_FactoryPresets,
- kAudioUnitScope_Global,
- 0, ¤t, &sz);
-
- return current.presetNumber;
- }
-
- void AudioUnitPluginInstance::setCurrentProgram (int newIndex)
- {
- AUPreset current;
- current.presetNumber = newIndex;
- current.presetName = 0;
-
- AudioUnitSetProperty (audioUnit,
- kAudioUnitProperty_FactoryPresets,
- kAudioUnitScope_Global,
- 0, ¤t, sizeof (AUPreset));
- }
-
- const String AudioUnitPluginInstance::getProgramName (int index)
- {
- String s;
- CFArrayRef presets;
- UInt32 sz = sizeof (CFArrayRef);
-
- if (AudioUnitGetProperty (audioUnit,
- kAudioUnitProperty_FactoryPresets,
- kAudioUnitScope_Global,
- 0, &presets, &sz) == noErr)
- {
- for (CFIndex i = 0; i < CFArrayGetCount (presets); ++i)
- {
- const AUPreset* p = (const AUPreset*) CFArrayGetValueAtIndex (presets, i);
-
- if (p != 0 && p->presetNumber == index)
- {
- s = PlatformUtilities::cfStringToJuceString (p->presetName);
- break;
- }
- }
-
- CFRelease (presets);
- }
-
- return s;
- }
-
- void AudioUnitPluginInstance::changeProgramName (int index, const String& newName)
- {
- jassertfalse // xxx not implemented!
- }
-
- const String AudioUnitPluginInstance::getInputChannelName (const int index) const
- {
- if (((unsigned int) index) < (unsigned int) getNumInputChannels())
- return T("Input ") + String (index + 1);
-
- return String::empty;
- }
-
- bool AudioUnitPluginInstance::isInputChannelStereoPair (int index) const
- {
- if (((unsigned int) index) >= (unsigned int) getNumInputChannels())
- return false;
-
- return true;
- }
-
- const String AudioUnitPluginInstance::getOutputChannelName (const int index) const
- {
- if (((unsigned int) index) < (unsigned int) getNumOutputChannels())
- return T("Output ") + String (index + 1);
-
- return String::empty;
- }
-
- bool AudioUnitPluginInstance::isOutputChannelStereoPair (int index) const
- {
- if (((unsigned int) index) >= (unsigned int) getNumOutputChannels())
- return false;
-
- return true;
- }
-
- void AudioUnitPluginInstance::getStateInformation (MemoryBlock& destData)
- {
- getCurrentProgramStateInformation (destData);
- }
-
- void AudioUnitPluginInstance::getCurrentProgramStateInformation (MemoryBlock& destData)
- {
- CFPropertyListRef propertyList = 0;
- UInt32 sz = sizeof (CFPropertyListRef);
-
- if (AudioUnitGetProperty (audioUnit,
- kAudioUnitProperty_ClassInfo,
- kAudioUnitScope_Global,
- 0, &propertyList, &sz) == noErr)
- {
- CFWriteStreamRef stream = CFWriteStreamCreateWithAllocatedBuffers (kCFAllocatorDefault, kCFAllocatorDefault);
- CFWriteStreamOpen (stream);
-
- CFIndex bytesWritten = CFPropertyListWriteToStream (propertyList, stream, kCFPropertyListBinaryFormat_v1_0, 0);
- CFWriteStreamClose (stream);
-
- CFDataRef data = (CFDataRef) CFWriteStreamCopyProperty (stream, kCFStreamPropertyDataWritten);
-
- destData.setSize (bytesWritten);
- destData.copyFrom (CFDataGetBytePtr (data), 0, destData.getSize());
- CFRelease (data);
-
- CFRelease (stream);
- CFRelease (propertyList);
- }
- }
-
- void AudioUnitPluginInstance::setStateInformation (const void* data, int sizeInBytes)
- {
- setCurrentProgramStateInformation (data, sizeInBytes);
- }
-
- void AudioUnitPluginInstance::setCurrentProgramStateInformation (const void* data, int sizeInBytes)
- {
- CFReadStreamRef stream = CFReadStreamCreateWithBytesNoCopy (kCFAllocatorDefault,
- (const UInt8*) data,
- sizeInBytes,
- kCFAllocatorNull);
- CFReadStreamOpen (stream);
-
- CFPropertyListFormat format = kCFPropertyListBinaryFormat_v1_0;
- CFPropertyListRef propertyList = CFPropertyListCreateFromStream (kCFAllocatorDefault,
- stream,
- 0,
- kCFPropertyListImmutable,
- &format,
- 0);
- CFRelease (stream);
-
- if (propertyList != 0)
- AudioUnitSetProperty (audioUnit,
- kAudioUnitProperty_ClassInfo,
- kAudioUnitScope_Global,
- 0, &propertyList, sizeof (propertyList));
- }
-
- AudioUnitPluginFormat::AudioUnitPluginFormat()
- {
- }
-
- AudioUnitPluginFormat::~AudioUnitPluginFormat()
- {
- }
-
- void AudioUnitPluginFormat::findAllTypesForFile (OwnedArray <PluginDescription>& results,
- const File& file)
- {
- if (! fileMightContainThisPluginType (file))
- return;
-
- PluginDescription desc;
- desc.file = file;
- desc.uid = 0;
-
- AudioUnitPluginInstance* instance = dynamic_cast <AudioUnitPluginInstance*> (createInstanceFromDescription (desc));
-
- if (instance == 0)
- return;
-
- try
- {
- instance->fillInPluginDescription (desc);
- results.add (new PluginDescription (desc));
- }
- catch (...)
- {
- // crashed while loading...
- }
-
- deleteAndZero (instance);
- }
-
- AudioPluginInstance* AudioUnitPluginFormat::createInstanceFromDescription (const PluginDescription& desc)
- {
- AudioUnitPluginInstance* result = 0;
-
- if (fileMightContainThisPluginType (desc.file))
- {
- result = new AudioUnitPluginInstance (desc.file);
-
- if (result->audioUnit != 0)
- {
- result->initialise();
- }
- else
- {
- deleteAndZero (result);
- }
- }
-
- return result;
- }
-
- bool AudioUnitPluginFormat::fileMightContainThisPluginType (const File& f)
- {
- return f.hasFileExtension (T(".component"))
- && f.isDirectory();
- }
-
- const FileSearchPath AudioUnitPluginFormat::getDefaultLocationsToSearch()
- {
- return FileSearchPath ("~/Library/Audio/Plug-Ins/Components;/Library/Audio/Plug-Ins/Components");
- }
-
- #endif
-
- END_JUCE_NAMESPACE
-
- #undef log
-
- #endif
- /********* End of inlined file: juce_AudioUnitPluginFormat.cpp *********/
-
- /********* Start of inlined file: juce_VSTPluginFormat.cpp *********/
-
- #if JUCE_PLUGINHOST_VST
-
- #ifdef _WIN32
- #undef _WIN32_WINNT
- #define _WIN32_WINNT 0x500
- #undef STRICT
- #define STRICT
- #include <windows.h>
- #include <float.h>
- #pragma warning (disable : 4312)
- #elif defined (LINUX)
- #include <float.h>
- #include <sys/time.h>
- #include <X11/Xlib.h>
- #include <X11/Xutil.h>
- #include <X11/Xatom.h>
- #undef Font
- #undef KeyPress
- #undef Drawable
- #undef Time
- #else
- #include <Carbon/Carbon.h>
- #endif
-
- BEGIN_JUCE_NAMESPACE
-
- #undef PRAGMA_ALIGN_SUPPORTED
- #define VST_FORCE_DEPRECATED 0
-
- #ifdef _MSC_VER
- #pragma warning (push)
- #pragma warning (disable: 4996)
- #endif
-
- /* Obviously you're going to need the Steinberg vstsdk2.4 folder in
- your include path if you want to add VST support.
-
- If you're not interested in VSTs, you can disable them by changing the
- JUCE_PLUGINHOST_VST flag in juce_Config.h
- */
- #include "pluginterfaces/vst2.x/aeffectx.h"
-
- #ifdef _MSC_VER
- #pragma warning (pop)
- #endif
-
- #if JUCE_LINUX
- #define Font JUCE_NAMESPACE::Font
- #define KeyPress JUCE_NAMESPACE::KeyPress
- #define Drawable JUCE_NAMESPACE::Drawable
- #define Time JUCE_NAMESPACE::Time
- #endif
-
- #if ! JUCE_WIN32
- #define _fpreset()
- #define _clearfp()
- #endif
-
- extern void juce_callAnyTimersSynchronously();
-
- const int fxbVersionNum = 1;
-
- struct fxProgram
- {
- long chunkMagic; // 'CcnK'
- long byteSize; // of this chunk, excl. magic + byteSize
- long fxMagic; // 'FxCk'
- long version;
- long fxID; // fx unique id
- long fxVersion;
- long numParams;
- char prgName[28];
- float params[1]; // variable no. of parameters
- };
-
- struct fxSet
- {
- long chunkMagic; // 'CcnK'
- long byteSize; // of this chunk, excl. magic + byteSize
- long fxMagic; // 'FxBk'
- long version;
- long fxID; // fx unique id
- long fxVersion;
- long numPrograms;
- char future[128];
- fxProgram programs[1]; // variable no. of programs
- };
-
- struct fxChunkSet
- {
- long chunkMagic; // 'CcnK'
- long byteSize; // of this chunk, excl. magic + byteSize
- long fxMagic; // 'FxCh', 'FPCh', or 'FBCh'
- long version;
- long fxID; // fx unique id
- long fxVersion;
- long numPrograms;
- char future[128];
- long chunkSize;
- char chunk[8]; // variable
- };
-
- struct fxProgramSet
- {
- long chunkMagic; // 'CcnK'
- long byteSize; // of this chunk, excl. magic + byteSize
- long fxMagic; // 'FxCh', 'FPCh', or 'FBCh'
- long version;
- long fxID; // fx unique id
- long fxVersion;
- long numPrograms;
- char name[28];
- long chunkSize;
- char chunk[8]; // variable
- };
-
- #ifdef JUCE_LITTLE_ENDIAN
- static long vst_swap (const long x) throw() { return (long) swapByteOrder ((uint32) x); }
-
- static float vst_swapFloat (const float x) throw()
- {
- union { uint32 asInt; float asFloat; } n;
- n.asFloat = x;
- n.asInt = swapByteOrder (n.asInt);
- return n.asFloat;
- }
- #else
- #define vst_swap(x) (x)
- #define vst_swapFloat(x) (x)
- #endif
-
- typedef AEffect* (*MainCall) (audioMasterCallback);
-
- static VstIntPtr VSTCALLBACK audioMaster (AEffect* effect, VstInt32 opcode, VstInt32 index, VstIntPtr value, void* ptr, float opt);
-
- static int shellUIDToCreate = 0;
- static int insideVSTCallback = 0;
-
- class VSTPluginWindow;
-
- // Change this to disable logging of various VST activities
- #ifndef VST_LOGGING
- #define VST_LOGGING 1
- #endif
-
- #if VST_LOGGING
- #define log(a) Logger::writeToLog(a);
- #else
- #define log(a)
- #endif
-
- #if JUCE_MAC
- extern bool juce_isHIViewCreatedByJuce (HIViewRef view);
- extern bool juce_isWindowCreatedByJuce (WindowRef window);
-
- #if JUCE_PPC
- static void* NewCFMFromMachO (void* const machofp) throw()
- {
- void* result = juce_malloc (8);
-
- ((void**) result)[0] = machofp;
- ((void**) result)[1] = result;
-
- return result;
- }
- #endif
- #endif
-
- #if JUCE_LINUX
-
- extern Display* display;
- extern XContext improbableNumber;
-
- typedef void (*EventProcPtr) (XEvent* ev);
-
- static bool xErrorTriggered;
-
- static int temporaryErrorHandler (Display*, XErrorEvent*)
- {
- xErrorTriggered = true;
- return 0;
- }
-
- static int getPropertyFromXWindow (Window handle, Atom atom)
- {
- XErrorHandler oldErrorHandler = XSetErrorHandler (temporaryErrorHandler);
- xErrorTriggered = false;
-
- int userSize;
- unsigned long bytes, userCount;
- unsigned char* data;
- Atom userType;
-
- XGetWindowProperty (display, handle, atom, 0, 1, false, AnyPropertyType,
- &userType, &userSize, &userCount, &bytes, &data);
-
- XSetErrorHandler (oldErrorHandler);
-
- return (userCount == 1 && ! xErrorTriggered) ? *(int*) data
- : 0;
- }
-
- static Window getChildWindow (Window windowToCheck)
- {
- Window rootWindow, parentWindow;
- Window* childWindows;
- unsigned int numChildren;
-
- XQueryTree (display,
- windowToCheck,
- &rootWindow,
- &parentWindow,
- &childWindows,
- &numChildren);
-
- if (numChildren > 0)
- return childWindows [0];
-
- return 0;
- }
-
- static void translateJuceToXButtonModifiers (const MouseEvent& e, XEvent& ev) throw()
- {
- if (e.mods.isLeftButtonDown())
- {
- ev.xbutton.button = Button1;
- ev.xbutton.state |= Button1Mask;
- }
- else if (e.mods.isRightButtonDown())
- {
- ev.xbutton.button = Button3;
- ev.xbutton.state |= Button3Mask;
- }
- else if (e.mods.isMiddleButtonDown())
- {
- ev.xbutton.button = Button2;
- ev.xbutton.state |= Button2Mask;
- }
- }
-
- static void translateJuceToXMotionModifiers (const MouseEvent& e, XEvent& ev) throw()
- {
- if (e.mods.isLeftButtonDown())
- ev.xmotion.state |= Button1Mask;
- else if (e.mods.isRightButtonDown())
- ev.xmotion.state |= Button3Mask;
- else if (e.mods.isMiddleButtonDown())
- ev.xmotion.state |= Button2Mask;
- }
-
- static void translateJuceToXCrossingModifiers (const MouseEvent& e, XEvent& ev) throw()
- {
- if (e.mods.isLeftButtonDown())
- ev.xcrossing.state |= Button1Mask;
- else if (e.mods.isRightButtonDown())
- ev.xcrossing.state |= Button3Mask;
- else if (e.mods.isMiddleButtonDown())
- ev.xcrossing.state |= Button2Mask;
- }
-
- static void translateJuceToXMouseWheelModifiers (const MouseEvent& e, const float increment, XEvent& ev) throw()
- {
- if (increment < 0)
- {
- ev.xbutton.button = Button5;
- ev.xbutton.state |= Button5Mask;
- }
- else if (increment > 0)
- {
- ev.xbutton.button = Button4;
- ev.xbutton.state |= Button4Mask;
- }
- }
-
- #endif
-
- static VoidArray activeModules;
-
- class ModuleHandle : public ReferenceCountedObject
- {
- public:
-
- File file;
- MainCall moduleMain;
- String pluginName;
-
- static ModuleHandle* findOrCreateModule (const File& file)
- {
- for (int i = activeModules.size(); --i >= 0;)
- {
- ModuleHandle* const module = (ModuleHandle*) activeModules.getUnchecked(i);
-
- if (module->file == file)
- return module;
- }
-
- _fpreset(); // (doesn't do any harm)
- ++insideVSTCallback;
- shellUIDToCreate = 0;
-
- log ("Attempting to load VST: " + file.getFullPathName());
-
- ModuleHandle* m = new ModuleHandle (file);
-
- if (! m->open())
- deleteAndZero (m);
-
- --insideVSTCallback;
- _fpreset(); // (doesn't do any harm)
-
- return m;
- }
-
- ModuleHandle (const File& file_)
- : file (file_),
- moduleMain (0),
- #if JUCE_WIN32 || JUCE_LINUX
- hModule (0)
- #elif JUCE_MAC
- fragId (0),
- resHandle (0),
- bundleRef (0),
- resFileId (0)
- #endif
- {
- activeModules.add (this);
-
- #if JUCE_WIN32 || JUCE_LINUX
- fullParentDirectoryPathName = file_.getParentDirectory().getFullPathName();
- #elif JUCE_MAC
- PlatformUtilities::makeFSSpecFromPath (&parentDirFSSpec, file_.getParentDirectory().getFullPathName());
- #endif
- }
-
- ~ModuleHandle()
- {
- activeModules.removeValue (this);
-
- close();
- }
-
- juce_UseDebuggingNewOperator
-
- #if JUCE_WIN32 || JUCE_LINUX
- void* hModule;
- String fullParentDirectoryPathName;
-
- bool open()
- {
- #if JUCE_WIN32
- static bool timePeriodSet = false;
-
- if (! timePeriodSet)
- {
- timePeriodSet = true;
- timeBeginPeriod (2);
- }
- #endif
-
- pluginName = file.getFileNameWithoutExtension();
-
- hModule = Process::loadDynamicLibrary (file.getFullPathName());
-
- moduleMain = (MainCall) Process::getProcedureEntryPoint (hModule, "VSTPluginMain");
-
- if (moduleMain == 0)
- moduleMain = (MainCall) Process::getProcedureEntryPoint (hModule, "main");
-
- return moduleMain != 0;
- }
-
- void close()
- {
- _fpreset(); // (doesn't do any harm)
-
- Process::freeDynamicLibrary (hModule);
- }
-
- void closeEffect (AEffect* eff)
- {
- eff->dispatcher (eff, effClose, 0, 0, 0, 0);
- }
-
- #else
- CFragConnectionID fragId;
- Handle resHandle;
- CFBundleRef bundleRef;
- FSSpec parentDirFSSpec;
- short resFileId;
-
- bool open()
- {
- bool ok = false;
- const String filename (file.getFullPathName());
-
- if (file.hasFileExtension (T(".vst")))
- {
- const char* const utf8 = filename.toUTF8();
- CFURLRef url = CFURLCreateFromFileSystemRepresentation (0, (const UInt8*) utf8,
- strlen (utf8), file.isDirectory());
-
- if (url != 0)
- {
- bundleRef = CFBundleCreate (kCFAllocatorDefault, url);
- CFRelease (url);
-
- if (bundleRef != 0)
- {
- if (CFBundleLoadExecutable (bundleRef))
- {
- moduleMain = (MainCall) CFBundleGetFunctionPointerForName (bundleRef, CFSTR("main_macho"));
-
- if (moduleMain == 0)
- moduleMain = (MainCall) CFBundleGetFunctionPointerForName (bundleRef, CFSTR("VSTPluginMain"));
-
- if (moduleMain != 0)
- {
- CFTypeRef name = CFBundleGetValueForInfoDictionaryKey (bundleRef, CFSTR("CFBundleName"));
-
- if (name != 0)
- {
- if (CFGetTypeID (name) == CFStringGetTypeID())
- {
- char buffer[1024];
-
- if (CFStringGetCString ((CFStringRef) name, buffer, sizeof (buffer), CFStringGetSystemEncoding()))
- pluginName = buffer;
- }
- }
-
- if (pluginName.isEmpty())
- pluginName = file.getFileNameWithoutExtension();
-
- resFileId = CFBundleOpenBundleResourceMap (bundleRef);
-
- ok = true;
- }
- }
-
- if (! ok)
- {
- CFBundleUnloadExecutable (bundleRef);
- CFRelease (bundleRef);
- bundleRef = 0;
- }
- }
- }
- }
- #if JUCE_PPC
- else
- {
- FSRef fn;
-
- if (FSPathMakeRef ((UInt8*) (const char*) filename, &fn, 0) == noErr)
- {
- resFileId = FSOpenResFile (&fn, fsRdPerm);
-
- if (resFileId != -1)
- {
- const int numEffs = Count1Resources ('aEff');
-
- for (int i = 0; i < numEffs; ++i)
- {
- resHandle = Get1IndResource ('aEff', i + 1);
-
- if (resHandle != 0)
- {
- OSType type;
- Str255 name;
- SInt16 id;
- GetResInfo (resHandle, &id, &type, name);
- pluginName = String ((const char*) name + 1, name[0]);
- DetachResource (resHandle);
- HLock (resHandle);
-
- Ptr ptr;
- Str255 errorText;
-
- OSErr err = GetMemFragment (*resHandle, GetHandleSize (resHandle),
- name, kPrivateCFragCopy,
- &fragId, &ptr, errorText);
-
- if (err == noErr)
- {
- moduleMain = (MainCall) newMachOFromCFM (ptr);
- ok = true;
- }
- else
- {
- HUnlock (resHandle);
- }
-
- break;
- }
- }
-
- if (! ok)
- CloseResFile (resFileId);
- }
- }
- }
- #endif
-
- return ok;
- }
-
- void close()
- {
- #if JUCE_PPC
- if (fragId != 0)
- {
- if (moduleMain != 0)
- disposeMachOFromCFM ((void*) moduleMain);
-
- CloseConnection (&fragId);
- HUnlock (resHandle);
-
- if (resFileId != 0)
- CloseResFile (resFileId);
- }
- else
- #endif
- if (bundleRef != 0)
- {
- CFBundleCloseBundleResourceMap (bundleRef, resFileId);
-
- if (CFGetRetainCount (bundleRef) == 1)
- CFBundleUnloadExecutable (bundleRef);
-
- if (CFGetRetainCount (bundleRef) > 0)
- CFRelease (bundleRef);
- }
- }
-
- void closeEffect (AEffect* eff)
- {
- #if JUCE_PPC
- if (fragId != 0)
- {
- VoidArray thingsToDelete;
- thingsToDelete.add ((void*) eff->dispatcher);
- thingsToDelete.add ((void*) eff->process);
- thingsToDelete.add ((void*) eff->setParameter);
- thingsToDelete.add ((void*) eff->getParameter);
- thingsToDelete.add ((void*) eff->processReplacing);
-
- eff->dispatcher (eff, effClose, 0, 0, 0, 0);
-
- for (int i = thingsToDelete.size(); --i >= 0;)
- disposeMachOFromCFM (thingsToDelete[i]);
- }
- else
- #endif
- {
- eff->dispatcher (eff, effClose, 0, 0, 0, 0);
- }
- }
-
- #if JUCE_PPC
- static void* newMachOFromCFM (void* cfmfp)
- {
- if (cfmfp == 0)
- return 0;
-
- UInt32* const mfp = (UInt32*) juce_malloc (sizeof (UInt32) * 6);
-
- mfp[0] = 0x3d800000 | ((UInt32) cfmfp >> 16);
- mfp[1] = 0x618c0000 | ((UInt32) cfmfp & 0xffff);
- mfp[2] = 0x800c0000;
- mfp[3] = 0x804c0004;
- mfp[4] = 0x7c0903a6;
- mfp[5] = 0x4e800420;
-
- MakeDataExecutable (mfp, sizeof (UInt32) * 6);
- return mfp;
- }
-
- static void disposeMachOFromCFM (void* ptr)
- {
- juce_free (ptr);
- }
-
- void coerceAEffectFunctionCalls (AEffect* eff)
- {
- if (fragId != 0)
- {
- eff->dispatcher = (AEffectDispatcherProc) newMachOFromCFM ((void*) eff->dispatcher);
- eff->process = (AEffectProcessProc) newMachOFromCFM ((void*) eff->process);
- eff->setParameter = (AEffectSetParameterProc) newMachOFromCFM ((void*) eff->setParameter);
- eff->getParameter = (AEffectGetParameterProc) newMachOFromCFM ((void*) eff->getParameter);
- eff->processReplacing = (AEffectProcessProc) newMachOFromCFM ((void*) eff->processReplacing);
- }
- }
- #endif
-
- #endif
- };
-
- /**
- An instance of a plugin, created by a VSTPluginFormat.
-
- */
- class VSTPluginInstance : public AudioPluginInstance,
- private Timer,
- private AsyncUpdater
- {
- public:
-
- ~VSTPluginInstance();
-
- // AudioPluginInstance methods:
-
- void fillInPluginDescription (PluginDescription& desc) const
- {
- desc.name = name;
- desc.file = module->file;
- desc.uid = getUID();
- desc.lastFileModTime = desc.file.getLastModificationTime();
- desc.pluginFormatName = "VST";
- desc.category = getCategory();
-
- {
- char buffer [kVstMaxVendorStrLen + 8];
- zerostruct (buffer);
- dispatch (effGetVendorString, 0, 0, buffer, 0);
- desc.manufacturerName = buffer;
- }
-
- desc.version = getVersion();
- desc.numInputChannels = getNumInputChannels();
- desc.numOutputChannels = getNumOutputChannels();
- desc.isInstrument = (effect != 0 && (effect->flags & effFlagsIsSynth) != 0);
- }
-
- const String getName() const { return name; }
- int getUID() const throw();
- bool acceptsMidi() const { return wantsMidiMessages; }
- bool producesMidi() const { return dispatch (effCanDo, 0, 0, (void*) "sendVstMidiEvent", 0) > 0; }
-
- // AudioProcessor methods:
-
- void prepareToPlay (double sampleRate, int estimatedSamplesPerBlock);
- void releaseResources();
- void processBlock (AudioSampleBuffer& buffer,
- MidiBuffer& midiMessages);
-
- AudioProcessorEditor* createEditor();
-
- const String getInputChannelName (const int index) const;
- bool isInputChannelStereoPair (int index) const;
-
- const String getOutputChannelName (const int index) const;
- bool isOutputChannelStereoPair (int index) const;
-
- int getNumParameters() { return effect != 0 ? effect->numParams : 0; }
- float getParameter (int index);
- void setParameter (int index, float newValue);
- const String getParameterName (int index);
- const String getParameterText (int index);
- bool isParameterAutomatable (int index) const;
-
- int getNumPrograms() { return effect != 0 ? effect->numPrograms : 0; }
- int getCurrentProgram() { return dispatch (effGetProgram, 0, 0, 0, 0); }
- void setCurrentProgram (int index);
- const String getProgramName (int index);
- void changeProgramName (int index, const String& newName);
-
- void getStateInformation (MemoryBlock& destData);
- void getCurrentProgramStateInformation (MemoryBlock& destData);
- void setStateInformation (const void* data, int sizeInBytes);
- void setCurrentProgramStateInformation (const void* data, int sizeInBytes);
-
- void timerCallback();
- void handleAsyncUpdate();
- VstIntPtr handleCallback (VstInt32 opcode, VstInt32 index, VstInt32 value, void *ptr, float opt);
-
- juce_UseDebuggingNewOperator
-
- private:
- friend class VSTPluginWindow;
- friend class VSTPluginFormat;
-
- AEffect* effect;
- String name;
- CriticalSection lock;
- bool wantsMidiMessages, initialised, isPowerOn;
- mutable StringArray programNames;
- AudioSampleBuffer tempBuffer;
- CriticalSection midiInLock;
- MidiBuffer incomingMidi;
- void* midiEventsToSend;
- int numAllocatedMidiEvents;
- VstTimeInfo vstHostTime;
- float** channels;
-
- ReferenceCountedObjectPtr <ModuleHandle> module;
-
- int dispatch (const int opcode, const int index, const int value, void* const ptr, float opt) const;
- bool restoreProgramSettings (const fxProgram* const prog);
- const String getCurrentProgramName();
- void setParamsInProgramBlock (fxProgram* const prog) throw();
- void updateStoredProgramNames();
- void initialise();
- void ensureMidiEventSize (int numEventsNeeded);
- void freeMidiEvents();
- void handleMidiFromPlugin (const VstEvents* const events);
- void createTempParameterStore (MemoryBlock& dest);
- void restoreFromTempParameterStore (const MemoryBlock& mb);
- const String getParameterLabel (int index) const;
-
- bool usesChunks() const throw() { return effect != 0 && (effect->flags & effFlagsProgramChunks) != 0; }
- void getChunkData (MemoryBlock& mb, bool isPreset, int maxSizeMB) const;
- void setChunkData (const char* data, int size, bool isPreset);
- bool loadFromFXBFile (const void* data, int numBytes);
- bool saveToFXBFile (MemoryBlock& dest, bool isFXB, int maxSizeMB);
-
- int getVersionNumber() const throw() { return effect != 0 ? effect->version : 0; }
- const String getVersion() const throw();
- const String getCategory() const throw();
-
- bool hasEditor() const throw() { return effect != 0 && (effect->flags & effFlagsHasEditor) != 0; }
- void setPower (const bool on);
-
- VSTPluginInstance (const ReferenceCountedObjectPtr <ModuleHandle>& module);
- };
-
- VSTPluginInstance::VSTPluginInstance (const ReferenceCountedObjectPtr <ModuleHandle>& module_)
- : effect (0),
- wantsMidiMessages (false),
- initialised (false),
- isPowerOn (false),
- numAllocatedMidiEvents (0),
- midiEventsToSend (0),
- tempBuffer (1, 1),
- channels (0),
- module (module_)
- {
- try
- {
- _fpreset();
-
- ++insideVSTCallback;
-
- name = module->pluginName;
- log (T("Creating VST instance: ") + name);
-
- #if JUCE_MAC
- if (module->resFileId != 0)
- UseResFile (module->resFileId);
-
- #if JUCE_PPC
- if (module->fragId != 0)
- {
- static void* audioMasterCoerced = 0;
- if (audioMasterCoerced == 0)
- audioMasterCoerced = NewCFMFromMachO ((void*) &audioMaster);
-
- effect = module->moduleMain ((audioMasterCallback) audioMasterCoerced);
- }
- else
- #endif
- #endif
- {
- effect = module->moduleMain (&audioMaster);
- }
-
- --insideVSTCallback;
-
- if (effect != 0 && effect->magic == kEffectMagic)
- {
- #if JUCE_PPC
- module->coerceAEffectFunctionCalls (effect);
- #endif
-
- jassert (effect->resvd2 == 0);
- jassert (effect->object != 0);
-
- _fpreset(); // some dodgy plugs fuck around with this
- }
- else
- {
- effect = 0;
- }
- }
- catch (...)
- {
- --insideVSTCallback;
- }
- }
-
- VSTPluginInstance::~VSTPluginInstance()
- {
- {
- const ScopedLock sl (lock);
-
- jassert (insideVSTCallback == 0);
-
- if (effect != 0 && effect->magic == kEffectMagic)
- {
- try
- {
- #if JUCE_MAC
- if (module->resFileId != 0)
- UseResFile (module->resFileId);
- #endif
-
- // Must delete any editors before deleting the plugin instance!
- jassert (getActiveEditor() == 0);
-
- _fpreset(); // some dodgy plugs fuck around with this
-
- module->closeEffect (effect);
- }
- catch (...)
- {}
- }
-
- module = 0;
- effect = 0;
- }
-
- freeMidiEvents();
-
- juce_free (channels);
- channels = 0;
- }
-
- void VSTPluginInstance::initialise()
- {
- if (initialised || effect == 0)
- return;
-
- log (T("Initialising VST: ") + module->pluginName);
- initialised = true;
-
- dispatch (effIdentify, 0, 0, 0, 0);
-
- // this code would ask the plugin for its name, but so few plugins
- // actually bother implementing this correctly, that it's better to
- // just ignore it and use the file name instead.
- /* {
- char buffer [256];
- zerostruct (buffer);
- dispatch (effGetEffectName, 0, 0, buffer, 0);
-
- name = String (buffer).trim();
- if (name.isEmpty())
- name = module->pluginName;
- }
- */
-
- if (getSampleRate() > 0)
- dispatch (effSetSampleRate, 0, 0, 0, (float) getSampleRate());
-
- if (getBlockSize() > 0)
- dispatch (effSetBlockSize, 0, jmax (32, getBlockSize()), 0, 0);
-
- dispatch (effOpen, 0, 0, 0, 0);
-
- setPlayConfigDetails (effect->numInputs, effect->numOutputs,
- getSampleRate(), getBlockSize());
-
- if (getNumPrograms() > 1)
- setCurrentProgram (0);
- else
- dispatch (effSetProgram, 0, 0, 0, 0);
-
- int i;
- for (i = effect->numInputs; --i >= 0;)
- dispatch (effConnectInput, i, 1, 0, 0);
-
- for (i = effect->numOutputs; --i >= 0;)
- dispatch (effConnectOutput, i, 1, 0, 0);
-
- updateStoredProgramNames();
-
- wantsMidiMessages = dispatch (effCanDo, 0, 0, (void*) "receiveVstMidiEvent", 0) > 0;
-
- setLatencySamples (effect->initialDelay);
- }
-
- void VSTPluginInstance::prepareToPlay (double sampleRate_,
- int samplesPerBlockExpected)
- {
- setPlayConfigDetails (effect->numInputs, effect->numOutputs,
- sampleRate_, samplesPerBlockExpected);
-
- setLatencySamples (effect->initialDelay);
-
- juce_free (channels);
- channels = (float**) juce_calloc (sizeof (float*) * jmax (16, getNumOutputChannels() + 2, getNumInputChannels() + 2));
-
- vstHostTime.tempo = 120.0;
- vstHostTime.timeSigNumerator = 4;
- vstHostTime.timeSigDenominator = 4;
- vstHostTime.sampleRate = sampleRate_;
- vstHostTime.samplePos = 0;
- vstHostTime.flags = kVstNanosValid; /*| kVstTransportPlaying | kVstTempoValid | kVstTimeSigValid*/;
-
- initialise();
-
- if (initialised)
- {
- wantsMidiMessages = wantsMidiMessages
- || (dispatch (effCanDo, 0, 0, (void*) "receiveVstMidiEvent", 0) > 0);
-
- if (wantsMidiMessages)
- ensureMidiEventSize (256);
- else
- freeMidiEvents();
-
- incomingMidi.clear();
-
- dispatch (effSetSampleRate, 0, 0, 0, (float) sampleRate_);
- dispatch (effSetBlockSize, 0, jmax (16, samplesPerBlockExpected), 0, 0);
-
- tempBuffer.setSize (jmax (1, effect->numOutputs), samplesPerBlockExpected);
-
- if (! isPowerOn)
- setPower (true);
-
- // dodgy hack to force some plugins to initialise the sample rate..
- if ((! hasEditor()) && getNumParameters() > 0)
- {
- const float old = getParameter (0);
- setParameter (0, (old < 0.5f) ? 1.0f : 0.0f);
- setParameter (0, old);
- }
-
- dispatch (effStartProcess, 0, 0, 0, 0);
- }
- }
-
- void VSTPluginInstance::releaseResources()
- {
- if (initialised)
- {
- dispatch (effStopProcess, 0, 0, 0, 0);
- setPower (false);
- }
-
- tempBuffer.setSize (1, 1);
- incomingMidi.clear();
-
- freeMidiEvents();
- juce_free (channels);
- channels = 0;
- }
-
- void VSTPluginInstance::processBlock (AudioSampleBuffer& buffer,
- MidiBuffer& midiMessages)
- {
- const int numSamples = buffer.getNumSamples();
-
- if (initialised)
- {
- #if JUCE_WIN32
- vstHostTime.nanoSeconds = timeGetTime() * 1000000.0;
- #elif JUCE_LINUX
- timeval micro;
- gettimeofday (µ, 0);
- vstHostTime.nanoSeconds = micro.tv_usec * 1000.0;
- #elif JUCE_MAC
- UnsignedWide micro;
- Microseconds (µ);
- vstHostTime.nanoSeconds = micro.lo * 1000.0;
- #endif
-
- if (wantsMidiMessages)
- {
- MidiBuffer::Iterator iter (midiMessages);
-
- int eventIndex = 0;
- const uint8* midiData;
- int numBytesOfMidiData, samplePosition;
-
- while (iter.getNextEvent (midiData, numBytesOfMidiData, samplePosition))
- {
- if (numBytesOfMidiData < 4)
- {
- ensureMidiEventSize (eventIndex);
- VstMidiEvent* const e
- = (VstMidiEvent*) ((VstEvents*) midiEventsToSend)->events [eventIndex++];
-
- // check that some plugin hasn't messed up our objects
- jassert (e->type == kVstMidiType);
- jassert (e->byteSize == 24);
-
- e->deltaFrames = jlimit (0, numSamples - 1, samplePosition);
- e->noteLength = 0;
- e->noteOffset = 0;
- e->midiData[0] = midiData[0];
- e->midiData[1] = midiData[1];
- e->midiData[2] = midiData[2];
- e->detune = 0;
- e->noteOffVelocity = 0;
- }
- }
-
- if (midiEventsToSend == 0)
- ensureMidiEventSize (1);
-
- ((VstEvents*) midiEventsToSend)->numEvents = eventIndex;
-
- try
- {
- effect->dispatcher (effect, effProcessEvents, 0, 0, midiEventsToSend, 0);
- }
- catch (...)
- {}
- }
-
- int i;
- const int maxChans = jmax (effect->numInputs, effect->numOutputs);
-
- for (i = 0; i < maxChans; ++i)
- channels[i] = buffer.getSampleData (i);
-
- channels [maxChans] = 0;
-
- _clearfp();
-
- if ((effect->flags & effFlagsCanReplacing) != 0)
- {
- try
- {
- effect->processReplacing (effect, channels, channels, numSamples);
- }
- catch (...)
- {}
- }
- else
- {
- tempBuffer.setSize (effect->numOutputs, numSamples);
- tempBuffer.clear();
-
- float* outs [64];
-
- for (i = effect->numOutputs; --i >= 0;)
- outs[i] = tempBuffer.getSampleData (i);
-
- outs [effect->numOutputs] = 0;
-
- try
- {
- effect->process (effect, channels, outs, numSamples);
- }
- catch (...)
- {}
-
- for (i = effect->numOutputs; --i >= 0;)
- buffer.copyFrom (i, 0, outs[i], numSamples);
- }
- }
- else
- {
- // Not initialised, so just bypass..
- for (int i = getNumInputChannels(); i < getNumOutputChannels(); ++i)
- buffer.clear (i, 0, buffer.getNumSamples());
- }
-
- {
- // copy any incoming midi..
- const ScopedLock sl (midiInLock);
-
- midiMessages = incomingMidi;
- incomingMidi.clear();
- }
- }
-
- void VSTPluginInstance::ensureMidiEventSize (int numEventsNeeded)
- {
- if (numEventsNeeded > numAllocatedMidiEvents)
- {
- numEventsNeeded = (numEventsNeeded + 32) & ~31;
-
- const int size = 20 + sizeof (VstEvent*) * numEventsNeeded;
-
- if (midiEventsToSend == 0)
- midiEventsToSend = juce_calloc (size);
- else
- midiEventsToSend = juce_realloc (midiEventsToSend, size);
-
- for (int i = numAllocatedMidiEvents; i < numEventsNeeded; ++i)
- {
- VstMidiEvent* const e = (VstMidiEvent*) juce_calloc (sizeof (VstMidiEvent));
- e->type = kVstMidiType;
- e->byteSize = 24;
-
- ((VstEvents*) midiEventsToSend)->events[i] = (VstEvent*) e;
- }
-
- numAllocatedMidiEvents = numEventsNeeded;
- }
- }
-
- void VSTPluginInstance::freeMidiEvents()
- {
- if (midiEventsToSend != 0)
- {
- for (int i = numAllocatedMidiEvents; --i >= 0;)
- juce_free (((VstEvents*) midiEventsToSend)->events[i]);
-
- juce_free (midiEventsToSend);
- midiEventsToSend = 0;
- numAllocatedMidiEvents = 0;
- }
- }
-
- void VSTPluginInstance::handleMidiFromPlugin (const VstEvents* const events)
- {
- if (events != 0)
- {
- const ScopedLock sl (midiInLock);
-
- for (int i = 0; i < events->numEvents; ++i)
- {
- const VstEvent* const e = events->events[i];
-
- if (e->type == kVstMidiType)
- {
- incomingMidi.addEvent ((const uint8*) ((const VstMidiEvent*) e)->midiData,
- 3, e->deltaFrames);
- }
- }
- }
- }
-
- static Array <VSTPluginWindow*> activeVSTWindows;
-
- class VSTPluginWindow : public AudioProcessorEditor,
- public Timer
- {
- public:
-
- VSTPluginWindow (VSTPluginInstance& plugin_)
- : AudioProcessorEditor (&plugin_),
- plugin (plugin_),
- isOpen (false),
- wasShowing (false),
- pluginRefusesToResize (false),
- pluginWantsKeys (false),
- alreadyInside (false),
- recursiveResize (false)
- {
- #if JUCE_WIN32
- sizeCheckCount = 0;
- pluginHWND = 0;
- #elif JUCE_LINUX
- pluginWindow = None;
- pluginProc = None;
- #else
- pluginViewRef = 0;
- #endif
-
- movementWatcher = new CompMovementWatcher (this);
-
- activeVSTWindows.add (this);
-
- setSize (1, 1);
- setOpaque (true);
- setVisible (true);
- }
-
- ~VSTPluginWindow()
- {
- deleteAndZero (movementWatcher);
-
- closePluginWindow();
-
- activeVSTWindows.removeValue (this);
- plugin.editorBeingDeleted (this);
- }
-
- void componentMovedOrResized()
- {
- if (recursiveResize)
- return;
-
- Component* const topComp = getTopLevelComponent();
-
- if (topComp->getPeer() != 0)
- {
- int x = 0, y = 0;
- relativePositionToOtherComponent (topComp, x, y);
-
- recursiveResize = true;
-
- #if JUCE_MAC
- if (pluginViewRef != 0)
- {
- HIRect r;
- r.origin.x = (float) x;
- r.origin.y = (float) y;
- r.size.width = (float) getWidth();
- r.size.height = (float) getHeight();
- HIViewSetFrame (pluginViewRef, &r);
- }
- else if (pluginWindowRef != 0)
- {
- Rect r;
- r.left = getScreenX();
- r.top = getScreenY();
- r.right = r.left + getWidth();
- r.bottom = r.top + getHeight();
-
- WindowGroupRef group = GetWindowGroup (pluginWindowRef);
- WindowGroupAttributes atts;
- GetWindowGroupAttributes (group, &atts);
- ChangeWindowGroupAttributes (group, 0, kWindowGroupAttrMoveTogether);
-
- SetWindowBounds (pluginWindowRef, kWindowContentRgn, &r);
-
- if ((atts & kWindowGroupAttrMoveTogether) != 0)
- ChangeWindowGroupAttributes (group, kWindowGroupAttrMoveTogether, 0);
- }
- else
- {
- repaint();
- }
- #elif JUCE_WIN32
- if (pluginHWND != 0)
- MoveWindow (pluginHWND, x, y, getWidth(), getHeight(), TRUE);
- #elif JUCE_LINUX
- if (pluginWindow != 0)
- {
- XResizeWindow (display, pluginWindow, getWidth(), getHeight());
- XMoveWindow (display, pluginWindow, x, y);
- XMapRaised (display, pluginWindow);
- }
- #endif
-
- recursiveResize = false;
- }
- }
-
- void componentVisibilityChanged()
- {
- const bool isShowingNow = isShowing();
-
- if (wasShowing != isShowingNow)
- {
- wasShowing = isShowingNow;
-
- if (isShowingNow)
- openPluginWindow();
- else
- closePluginWindow();
- }
-
- componentMovedOrResized();
- }
-
- void componentPeerChanged()
- {
- closePluginWindow();
- openPluginWindow();
- }
-
- bool keyStateChanged()
- {
- return pluginWantsKeys;
- }
-
- bool keyPressed (const KeyPress&)
- {
- return pluginWantsKeys;
- }
-
- void paint (Graphics& g)
- {
- if (isOpen)
- {
- ComponentPeer* const peer = getPeer();
-
- if (peer != 0)
- {
- peer->addMaskedRegion (getScreenX() - peer->getScreenX(),
- getScreenY() - peer->getScreenY(),
- getWidth(), getHeight());
-
- #if JUCE_MAC
- if (pluginViewRef == 0)
- {
- ERect r;
- r.left = getScreenX() - peer->getScreenX();
- r.right = r.left + getWidth();
- r.top = getScreenY() - peer->getScreenY();
- r.bottom = r.top + getHeight();
-
- dispatch (effEditDraw, 0, 0, &r, 0);
- }
- #elif JUCE_LINUX
- if (pluginWindow != 0)
- {
- const Rectangle clip (g.getClipBounds());
-
- XEvent ev;
- zerostruct (ev);
- ev.xexpose.type = Expose;
- ev.xexpose.display = display;
- ev.xexpose.window = pluginWindow;
- ev.xexpose.x = clip.getX();
- ev.xexpose.y = clip.getY();
- ev.xexpose.width = clip.getWidth();
- ev.xexpose.height = clip.getHeight();
-
- sendEventToChild (&ev);
- }
- #endif
- }
- }
- else
- {
- g.fillAll (Colours::black);
- }
- }
-
- void timerCallback()
- {
- #if JUCE_WIN32
- if (--sizeCheckCount <= 0)
- {
- sizeCheckCount = 10;
-
- checkPluginWindowSize();
- }
- #endif
-
- try
- {
- static bool reentrant = false;
-
- if (! reentrant)
- {
- reentrant = true;
- plugin.dispatch (effEditIdle, 0, 0, 0, 0);
- reentrant = false;
- }
- }
- catch (...)
- {}
- }
-
- void mouseDown (const MouseEvent& e)
- {
- #if JUCE_MAC
- if (! alreadyInside)
- {
- alreadyInside = true;
- toFront (true);
- dispatch (effEditMouse, e.x, e.y, 0, 0);
- alreadyInside = false;
- }
- else
- {
- PostEvent (::mouseDown, 0);
- }
- #elif JUCE_LINUX
-
- if (pluginWindow == 0)
- return;
-
- toFront (true);
-
- XEvent ev;
- zerostruct (ev);
- ev.xbutton.display = display;
- ev.xbutton.type = ButtonPress;
- ev.xbutton.window = pluginWindow;
- ev.xbutton.root = RootWindow (display, DefaultScreen (display));
- ev.xbutton.time = CurrentTime;
- ev.xbutton.x = e.x;
- ev.xbutton.y = e.y;
- ev.xbutton.x_root = e.getScreenX();
- ev.xbutton.y_root = e.getScreenY();
-
- translateJuceToXButtonModifiers (e, ev);
-
- sendEventToChild (&ev);
-
- #else
- (void) e;
-
- toFront (true);
- #endif
- }
-
- void broughtToFront()
- {
- activeVSTWindows.removeValue (this);
- activeVSTWindows.add (this);
-
- #if JUCE_MAC
- dispatch (effEditTop, 0, 0, 0, 0);
- #endif
- }
-
- juce_UseDebuggingNewOperator
-
- private:
- VSTPluginInstance& plugin;
- bool isOpen, wasShowing, recursiveResize;
- bool pluginWantsKeys, pluginRefusesToResize, alreadyInside;
-
- #if JUCE_WIN32
- HWND pluginHWND;
- void* originalWndProc;
- int sizeCheckCount;
- #elif JUCE_MAC
- HIViewRef pluginViewRef;
- WindowRef pluginWindowRef;
- #elif JUCE_LINUX
- Window pluginWindow;
- EventProcPtr pluginProc;
- #endif
-
- void openPluginWindow()
- {
- if (isOpen || getWindowHandle() == 0)
- return;
-
- log (T("Opening VST UI: ") + plugin.name);
- isOpen = true;
-
- ERect* rect = 0;
- dispatch (effEditGetRect, 0, 0, &rect, 0);
- dispatch (effEditOpen, 0, 0, getWindowHandle(), 0);
-
- // do this before and after like in the steinberg example
- dispatch (effEditGetRect, 0, 0, &rect, 0);
- dispatch (effGetProgram, 0, 0, 0, 0); // also in steinberg code
-
- // Install keyboard hooks
- pluginWantsKeys = (dispatch (effKeysRequired, 0, 0, 0, 0) == 0);
-
- #if JUCE_WIN32
- originalWndProc = 0;
- pluginHWND = GetWindow ((HWND) getWindowHandle(), GW_CHILD);
-
- if (pluginHWND == 0)
- {
- isOpen = false;
- setSize (300, 150);
- return;
- }
-
- #pragma warning (push)
- #pragma warning (disable: 4244)
-
- originalWndProc = (void*) GetWindowLongPtr (pluginHWND, GWL_WNDPROC);
-
- if (! pluginWantsKeys)
- SetWindowLongPtr (pluginHWND, GWL_WNDPROC, (LONG_PTR) vstHookWndProc);
-
- #pragma warning (pop)
-
- int w, h;
- RECT r;
- GetWindowRect (pluginHWND, &r);
- w = r.right - r.left;
- h = r.bottom - r.top;
-
- if (rect != 0)
- {
- const int rw = rect->right - rect->left;
- const int rh = rect->bottom - rect->top;
-
- if ((rw > 50 && rh > 50 && rw < 2000 && rh < 2000 && rw != w && rh != h)
- || ((w == 0 && rw > 0) || (h == 0 && rh > 0)))
- {
- // very dodgy logic to decide which size is right.
- if (abs (rw - w) > 350 || abs (rh - h) > 350)
- {
- SetWindowPos (pluginHWND, 0,
- 0, 0, rw, rh,
- SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER);
-
- GetWindowRect (pluginHWND, &r);
-
- w = r.right - r.left;
- h = r.bottom - r.top;
-
- pluginRefusesToResize = (w != rw) || (h != rh);
-
- w = rw;
- h = rh;
- }
- }
- }
- #elif JUCE_MAC
- HIViewRef root = HIViewGetRoot ((WindowRef) getWindowHandle());
- HIViewFindByID (root, kHIViewWindowContentID, &root);
- pluginViewRef = HIViewGetFirstSubview (root);
-
- while (pluginViewRef != 0 && juce_isHIViewCreatedByJuce (pluginViewRef))
- pluginViewRef = HIViewGetNextView (pluginViewRef);
-
- pluginWindowRef = 0;
-
- if (pluginViewRef == 0)
- {
- WindowGroupRef ourGroup = GetWindowGroup ((WindowRef) getWindowHandle());
- //DebugPrintWindowGroup (ourGroup);
- //DebugPrintAllWindowGroups();
-
- GetIndexedWindow (ourGroup, 1,
- kWindowGroupContentsVisible,
- &pluginWindowRef);
-
- if (pluginWindowRef == (WindowRef) getWindowHandle()
- || juce_isWindowCreatedByJuce (pluginWindowRef))
- pluginWindowRef = 0;
- }
-
- int w = 250, h = 150;
-
- if (rect != 0)
- {
- w = rect->right - rect->left;
- h = rect->bottom - rect->top;
-
- if (w == 0 || h == 0)
- {
- w = 250;
- h = 150;
- }
- }
-
- #elif JUCE_LINUX
- pluginWindow = getChildWindow ((Window) getWindowHandle());
-
- if (pluginWindow != 0)
- pluginProc = (EventProcPtr) getPropertyFromXWindow (pluginWindow,
- XInternAtom (display, "_XEventProc", False));
-
- int w = 250, h = 150;
-
- if (rect != 0)
- {
- w = rect->right - rect->left;
- h = rect->bottom - rect->top;
-
- if (w == 0 || h == 0)
- {
- w = 250;
- h = 150;
- }
- }
-
- if (pluginWindow != 0)
- XMapRaised (display, pluginWindow);
- #endif
-
- // double-check it's not too tiny
- w = jmax (w, 32);
- h = jmax (h, 32);
-
- setSize (w, h);
-
- #if JUCE_WIN32
- checkPluginWindowSize();
- #endif
-
- startTimer (18 + JUCE_NAMESPACE::Random::getSystemRandom().nextInt (5));
- repaint();
- }
-
- void closePluginWindow()
- {
- if (isOpen)
- {
- log (T("Closing VST UI: ") + plugin.getName());
- isOpen = false;
-
- dispatch (effEditClose, 0, 0, 0, 0);
-
- #if JUCE_WIN32
- #pragma warning (push)
- #pragma warning (disable: 4244)
-
- if (pluginHWND != 0 && IsWindow (pluginHWND))
- SetWindowLongPtr (pluginHWND, GWL_WNDPROC, (LONG_PTR) originalWndProc);
-
- #pragma warning (pop)
-
- stopTimer();
-
- if (pluginHWND != 0 && IsWindow (pluginHWND))
- DestroyWindow (pluginHWND);
-
- pluginHWND = 0;
- #elif JUCE_MAC
- dispatch (effEditSleep, 0, 0, 0, 0);
- pluginViewRef = 0;
- stopTimer();
- #elif JUCE_LINUX
- stopTimer();
- pluginWindow = 0;
- pluginProc = 0;
- #endif
- }
- }
-
- #if JUCE_WIN32
- void checkPluginWindowSize() throw()
- {
- RECT r;
- GetWindowRect (pluginHWND, &r);
- const int w = r.right - r.left;
- const int h = r.bottom - r.top;
-
- if (isShowing() && w > 0 && h > 0
- && (w != getWidth() || h != getHeight())
- && ! pluginRefusesToResize)
- {
- setSize (w, h);
- sizeCheckCount = 0;
- }
- }
- #endif
-
- class CompMovementWatcher : public ComponentMovementWatcher
- {
- public:
- CompMovementWatcher (VSTPluginWindow* const owner_)
- : ComponentMovementWatcher (owner_),
- owner (owner_)
- {
- }
-
- void componentMovedOrResized (bool /*wasMoved*/, bool /*wasResized*/)
- {
- owner->componentMovedOrResized();
- }
-
- void componentPeerChanged()
- {
- owner->componentPeerChanged();
- }
-
- void componentVisibilityChanged (Component&)
- {
- owner->componentVisibilityChanged();
- }
-
- private:
- VSTPluginWindow* const owner;
- };
-
- CompMovementWatcher* movementWatcher;
-
- int dispatch (const int opcode, const int index, const int value, void* const ptr, float opt)
- {
- return plugin.dispatch (opcode, index, value, ptr, opt);
- }
-
- // hooks to get keyboard events from VST windows..
- #if JUCE_WIN32
- static LRESULT CALLBACK vstHookWndProc (HWND hW, UINT message, WPARAM wParam, LPARAM lParam)
- {
- for (int i = activeVSTWindows.size(); --i >= 0;)
- {
- const VSTPluginWindow* const w = (const VSTPluginWindow*) activeVSTWindows.getUnchecked (i);
-
- if (w->pluginHWND == hW)
- {
- if (message == WM_CHAR
- || message == WM_KEYDOWN
- || message == WM_SYSKEYDOWN
- || message == WM_KEYUP
- || message == WM_SYSKEYUP
- || message == WM_APPCOMMAND)
- {
- SendMessage ((HWND) w->getTopLevelComponent()->getWindowHandle(),
- message, wParam, lParam);
- }
-
- return CallWindowProc ((WNDPROC) (w->originalWndProc),
- (HWND) w->pluginHWND,
- message,
- wParam,
- lParam);
- }
- }
-
- return DefWindowProc (hW, message, wParam, lParam);
- }
- #endif
-
- #if JUCE_LINUX
-
- // overload mouse/keyboard events to forward them to the plugin's inner window..
- void sendEventToChild (XEvent* event)
- {
- if (pluginProc != 0)
- {
- // if the plugin publishes an event procedure, pass the event directly..
- pluginProc (event);
- }
- else if (pluginWindow != 0)
- {
- // if the plugin has a window, then send the event to the window so that
- // its message thread will pick it up..
- XSendEvent (display, pluginWindow, False, 0L, event);
- XFlush (display);
- }
- }
-
- void mouseEnter (const MouseEvent& e)
- {
- if (pluginWindow != 0)
- {
- XEvent ev;
- zerostruct (ev);
- ev.xcrossing.display = display;
- ev.xcrossing.type = EnterNotify;
- ev.xcrossing.window = pluginWindow;
- ev.xcrossing.root = RootWindow (display, DefaultScreen (display));
- ev.xcrossing.time = CurrentTime;
- ev.xcrossing.x = e.x;
- ev.xcrossing.y = e.y;
- ev.xcrossing.x_root = e.getScreenX();
- ev.xcrossing.y_root = e.getScreenY();
- ev.xcrossing.mode = NotifyNormal; // NotifyGrab, NotifyUngrab
- ev.xcrossing.detail = NotifyAncestor; // NotifyVirtual, NotifyInferior, NotifyNonlinear,NotifyNonlinearVirtual
-
- translateJuceToXCrossingModifiers (e, ev);
-
- sendEventToChild (&ev);
- }
- }
-
- void mouseExit (const MouseEvent& e)
- {
- if (pluginWindow != 0)
- {
- XEvent ev;
- zerostruct (ev);
- ev.xcrossing.display = display;
- ev.xcrossing.type = LeaveNotify;
- ev.xcrossing.window = pluginWindow;
- ev.xcrossing.root = RootWindow (display, DefaultScreen (display));
- ev.xcrossing.time = CurrentTime;
- ev.xcrossing.x = e.x;
- ev.xcrossing.y = e.y;
- ev.xcrossing.x_root = e.getScreenX();
- ev.xcrossing.y_root = e.getScreenY();
- ev.xcrossing.mode = NotifyNormal; // NotifyGrab, NotifyUngrab
- ev.xcrossing.detail = NotifyAncestor; // NotifyVirtual, NotifyInferior, NotifyNonlinear,NotifyNonlinearVirtual
- ev.xcrossing.focus = hasKeyboardFocus (true); // TODO - yes ?
-
- translateJuceToXCrossingModifiers (e, ev);
-
- sendEventToChild (&ev);
- }
- }
-
- void mouseMove (const MouseEvent& e)
- {
- if (pluginWindow != 0)
- {
- XEvent ev;
- zerostruct (ev);
- ev.xmotion.display = display;
- ev.xmotion.type = MotionNotify;
- ev.xmotion.window = pluginWindow;
- ev.xmotion.root = RootWindow (display, DefaultScreen (display));
- ev.xmotion.time = CurrentTime;
- ev.xmotion.is_hint = NotifyNormal;
- ev.xmotion.x = e.x;
- ev.xmotion.y = e.y;
- ev.xmotion.x_root = e.getScreenX();
- ev.xmotion.y_root = e.getScreenY();
-
- sendEventToChild (&ev);
- }
- }
-
- void mouseDrag (const MouseEvent& e)
- {
- if (pluginWindow != 0)
- {
- XEvent ev;
- zerostruct (ev);
- ev.xmotion.display = display;
- ev.xmotion.type = MotionNotify;
- ev.xmotion.window = pluginWindow;
- ev.xmotion.root = RootWindow (display, DefaultScreen (display));
- ev.xmotion.time = CurrentTime;
- ev.xmotion.x = e.x ;
- ev.xmotion.y = e.y;
- ev.xmotion.x_root = e.getScreenX();
- ev.xmotion.y_root = e.getScreenY();
- ev.xmotion.is_hint = NotifyNormal;
-
- translateJuceToXMotionModifiers (e, ev);
- sendEventToChild (&ev);
- }
- }
-
- void mouseUp (const MouseEvent& e)
- {
- if (pluginWindow != 0)
- {
- XEvent ev;
- zerostruct (ev);
- ev.xbutton.display = display;
- ev.xbutton.type = ButtonRelease;
- ev.xbutton.window = pluginWindow;
- ev.xbutton.root = RootWindow (display, DefaultScreen (display));
- ev.xbutton.time = CurrentTime;
- ev.xbutton.x = e.x;
- ev.xbutton.y = e.y;
- ev.xbutton.x_root = e.getScreenX();
- ev.xbutton.y_root = e.getScreenY();
-
- translateJuceToXButtonModifiers (e, ev);
- sendEventToChild (&ev);
- }
- }
-
- void mouseWheelMove (const MouseEvent& e,
- float incrementX,
- float incrementY)
- {
- if (pluginWindow != 0)
- {
- XEvent ev;
- zerostruct (ev);
- ev.xbutton.display = display;
- ev.xbutton.type = ButtonPress;
- ev.xbutton.window = pluginWindow;
- ev.xbutton.root = RootWindow (display, DefaultScreen (display));
- ev.xbutton.time = CurrentTime;
- ev.xbutton.x = e.x;
- ev.xbutton.y = e.y;
- ev.xbutton.x_root = e.getScreenX();
- ev.xbutton.y_root = e.getScreenY();
-
- translateJuceToXMouseWheelModifiers (e, incrementY, ev);
- sendEventToChild (&ev);
-
- // TODO - put a usleep here ?
-
- ev.xbutton.type = ButtonRelease;
- sendEventToChild (&ev);
- }
- }
- #endif
-
- };
-
- AudioProcessorEditor* VSTPluginInstance::createEditor()
- {
- if (hasEditor())
- return new VSTPluginWindow (*this);
-
- return 0;
- }
-
- void VSTPluginInstance::handleAsyncUpdate()
- {
- // indicates that something about the plugin has changed..
- updateHostDisplay();
- }
-
- bool VSTPluginInstance::restoreProgramSettings (const fxProgram* const prog)
- {
- if (vst_swap (prog->chunkMagic) == 'CcnK' && vst_swap (prog->fxMagic) == 'FxCk')
- {
- changeProgramName (getCurrentProgram(), prog->prgName);
-
- for (int i = 0; i < vst_swap (prog->numParams); ++i)
- setParameter (i, vst_swapFloat (prog->params[i]));
-
- return true;
- }
-
- return false;
- }
-
- bool VSTPluginInstance::loadFromFXBFile (const void* const data,
- const int dataSize)
- {
- if (dataSize < 28)
- return false;
-
- const fxSet* const set = (const fxSet*) data;
-
- if ((vst_swap (set->chunkMagic) != 'CcnK' && vst_swap (set->chunkMagic) != 'KncC')
- || vst_swap (set->version) > fxbVersionNum)
- return false;
-
- if (vst_swap (set->fxMagic) == 'FxBk')
- {
- // bank of programs
- if (vst_swap (set->numPrograms) >= 0)
- {
- const int oldProg = getCurrentProgram();
- const int numParams = vst_swap (((const fxProgram*) (set->programs))->numParams);
- const int progLen = sizeof (fxProgram) + (numParams - 1) * sizeof (float);
-
- for (int i = 0; i < vst_swap (set->numPrograms); ++i)
- {
- if (i != oldProg)
- {
- const fxProgram* const prog = (const fxProgram*) (((const char*) (set->programs)) + i * progLen);
- if (((const char*) prog) - ((const char*) set) >= dataSize)
- return false;
-
- if (vst_swap (set->numPrograms) > 0)
- setCurrentProgram (i);
-
- if (! restoreProgramSettings (prog))
- return false;
- }
- }
-
- if (vst_swap (set->numPrograms) > 0)
- setCurrentProgram (oldProg);
-
- const fxProgram* const prog = (const fxProgram*) (((const char*) (set->programs)) + oldProg * progLen);
- if (((const char*) prog) - ((const char*) set) >= dataSize)
- return false;
-
- if (! restoreProgramSettings (prog))
- return false;
- }
- }
- else if (vst_swap (set->fxMagic) == 'FxCk')
- {
- // single program
- const fxProgram* const prog = (const fxProgram*) data;
-
- if (vst_swap (prog->chunkMagic) != 'CcnK')
- return false;
-
- changeProgramName (getCurrentProgram(), prog->prgName);
-
- for (int i = 0; i < vst_swap (prog->numParams); ++i)
- setParameter (i, vst_swapFloat (prog->params[i]));
- }
- else if (vst_swap (set->fxMagic) == 'FBCh' || vst_swap (set->fxMagic) == 'hCBF')
- {
- // non-preset chunk
- const fxChunkSet* const cset = (const fxChunkSet*) data;
-
- if (vst_swap (cset->chunkSize) + sizeof (fxChunkSet) - 8 > (unsigned int) dataSize)
- return false;
-
- setChunkData (cset->chunk, vst_swap (cset->chunkSize), false);
- }
- else if (vst_swap (set->fxMagic) == 'FPCh' || vst_swap (set->fxMagic) == 'hCPF')
- {
- // preset chunk
- const fxProgramSet* const cset = (const fxProgramSet*) data;
-
- if (vst_swap (cset->chunkSize) + sizeof (fxProgramSet) - 8 > (unsigned int) dataSize)
- return false;
-
- setChunkData (cset->chunk, vst_swap (cset->chunkSize), true);
-
- changeProgramName (getCurrentProgram(), cset->name);
- }
- else
- {
- return false;
- }
-
- return true;
- }
-
- void VSTPluginInstance::setParamsInProgramBlock (fxProgram* const prog) throw()
- {
- const int numParams = getNumParameters();
-
- prog->chunkMagic = vst_swap ('CcnK');
- prog->byteSize = 0;
- prog->fxMagic = vst_swap ('FxCk');
- prog->version = vst_swap (fxbVersionNum);
- prog->fxID = vst_swap (getUID());
- prog->fxVersion = vst_swap (getVersionNumber());
- prog->numParams = vst_swap (numParams);
-
- getCurrentProgramName().copyToBuffer (prog->prgName, sizeof (prog->prgName) - 1);
-
- for (int i = 0; i < numParams; ++i)
- prog->params[i] = vst_swapFloat (getParameter (i));
- }
-
- bool VSTPluginInstance::saveToFXBFile (MemoryBlock& dest, bool isFXB, int maxSizeMB)
- {
- const int numPrograms = getNumPrograms();
- const int numParams = getNumParameters();
-
- if (usesChunks())
- {
- if (isFXB)
- {
- MemoryBlock chunk;
- getChunkData (chunk, false, maxSizeMB);
-
- const int totalLen = sizeof (fxChunkSet) + chunk.getSize() - 8;
- dest.setSize (totalLen, true);
-
- fxChunkSet* const set = (fxChunkSet*) dest.getData();
- set->chunkMagic = vst_swap ('CcnK');
- set->byteSize = 0;
- set->fxMagic = vst_swap ('FBCh');
- set->version = vst_swap (fxbVersionNum);
- set->fxID = vst_swap (getUID());
- set->fxVersion = vst_swap (getVersionNumber());
- set->numPrograms = vst_swap (numPrograms);
- set->chunkSize = vst_swap (chunk.getSize());
-
- chunk.copyTo (set->chunk, 0, chunk.getSize());
- }
- else
- {
- MemoryBlock chunk;
- getChunkData (chunk, true, maxSizeMB);
-
- const int totalLen = sizeof (fxProgramSet) + chunk.getSize() - 8;
- dest.setSize (totalLen, true);
-
- fxProgramSet* const set = (fxProgramSet*) dest.getData();
- set->chunkMagic = vst_swap ('CcnK');
- set->byteSize = 0;
- set->fxMagic = vst_swap ('FPCh');
- set->version = vst_swap (fxbVersionNum);
- set->fxID = vst_swap (getUID());
- set->fxVersion = vst_swap (getVersionNumber());
- set->numPrograms = vst_swap (numPrograms);
- set->chunkSize = vst_swap (chunk.getSize());
-
- getCurrentProgramName().copyToBuffer (set->name, sizeof (set->name) - 1);
- chunk.copyTo (set->chunk, 0, chunk.getSize());
- }
- }
- else
- {
- if (isFXB)
- {
- const int progLen = sizeof (fxProgram) + (numParams - 1) * sizeof (float);
- const int len = (sizeof (fxSet) - sizeof (fxProgram)) + progLen * jmax (1, numPrograms);
- dest.setSize (len, true);
-
- fxSet* const set = (fxSet*) dest.getData();
- set->chunkMagic = vst_swap ('CcnK');
- set->byteSize = 0;
- set->fxMagic = vst_swap ('FxBk');
- set->version = vst_swap (fxbVersionNum);
- set->fxID = vst_swap (getUID());
- set->fxVersion = vst_swap (getVersionNumber());
- set->numPrograms = vst_swap (numPrograms);
-
- const int oldProgram = getCurrentProgram();
- MemoryBlock oldSettings;
- createTempParameterStore (oldSettings);
-
- setParamsInProgramBlock ((fxProgram*) (((char*) (set->programs)) + oldProgram * progLen));
-
- for (int i = 0; i < numPrograms; ++i)
- {
- if (i != oldProgram)
- {
- setCurrentProgram (i);
- setParamsInProgramBlock ((fxProgram*) (((char*) (set->programs)) + i * progLen));
- }
- }
-
- setCurrentProgram (oldProgram);
- restoreFromTempParameterStore (oldSettings);
- }
- else
- {
- const int totalLen = sizeof (fxProgram) + (numParams - 1) * sizeof (float);
- dest.setSize (totalLen, true);
-
- setParamsInProgramBlock ((fxProgram*) dest.getData());
- }
- }
-
- return true;
- }
-
- void VSTPluginInstance::getChunkData (MemoryBlock& mb, bool isPreset, int maxSizeMB) const
- {
- if (usesChunks())
- {
- void* data = 0;
- const int bytes = dispatch (effGetChunk, isPreset ? 1 : 0, 0, &data, 0.0f);
-
- if (data != 0 && bytes <= maxSizeMB * 1024 * 1024)
- {
- mb.setSize (bytes);
- mb.copyFrom (data, 0, bytes);
- }
- }
- }
-
- void VSTPluginInstance::setChunkData (const char* data, int size, bool isPreset)
- {
- if (size > 0 && usesChunks())
- {
- dispatch (effSetChunk, isPreset ? 1 : 0, size, (void*) data, 0.0f);
-
- if (! isPreset)
- updateStoredProgramNames();
- }
- }
-
- void VSTPluginInstance::timerCallback()
- {
- if (dispatch (effIdle, 0, 0, 0, 0) == 0)
- stopTimer();
- }
-
- int VSTPluginInstance::dispatch (const int opcode, const int index, const int value, void* const ptr, float opt) const
- {
- const ScopedLock sl (lock);
-
- ++insideVSTCallback;
- int result = 0;
-
- try
- {
- if (effect != 0)
- {
- #if JUCE_MAC
- if (module->resFileId != 0)
- UseResFile (module->resFileId);
-
- CGrafPtr oldPort;
-
- if (getActiveEditor() != 0)
- {
- int x = 0, y = 0;
- getActiveEditor()->relativePositionToOtherComponent (getActiveEditor()->getTopLevelComponent(), x, y);
-
- GetPort (&oldPort);
- SetPortWindowPort ((WindowRef) getActiveEditor()->getWindowHandle());
- SetOrigin (-x, -y);
- }
- #endif
-
- result = effect->dispatcher (effect, opcode, index, value, ptr, opt);
-
- #if JUCE_MAC
- if (getActiveEditor() != 0)
- SetPort (oldPort);
-
- module->resFileId = CurResFile();
- #endif
-
- --insideVSTCallback;
- return result;
- }
- }
- catch (...)
- {
- //char s[512];
- //sprintf (s, "dispatcher (%d, %d, %d, %x, %f)", opcode, index, value, (int)ptr, opt);
- }
-
- --insideVSTCallback;
- return result;
- }
-
- // handles non plugin-specific callbacks..
- static VstIntPtr handleGeneralCallback (VstInt32 opcode, VstInt32 index, VstInt32 value, void *ptr, float opt)
- {
- (void) index;
- (void) value;
- (void) opt;
-
- switch (opcode)
- {
- case audioMasterCanDo:
- {
- static const char* canDos[] = { "supplyIdle",
- "sendVstEvents",
- "sendVstMidiEvent",
- "sendVstTimeInfo",
- "receiveVstEvents",
- "receiveVstMidiEvent",
- "supportShell",
- "shellCategory" };
-
- for (int i = 0; i < numElementsInArray (canDos); ++i)
- if (strcmp (canDos[i], (const char*) ptr) == 0)
- return 1;
-
- return 0;
- }
-
- case audioMasterVersion:
- return 0x2400;
- case audioMasterCurrentId:
- return shellUIDToCreate;
- case audioMasterGetNumAutomatableParameters:
- return 0;
- case audioMasterGetAutomationState:
- return 1;
-
- case audioMasterGetVendorVersion:
- return 0x0101;
- case audioMasterGetVendorString:
- case audioMasterGetProductString:
- {
- String hostName ("Juce VST Host");
-
- if (JUCEApplication::getInstance() != 0)
- hostName = JUCEApplication::getInstance()->getApplicationName();
-
- hostName.copyToBuffer ((char*) ptr, jmin (kVstMaxVendorStrLen, kVstMaxProductStrLen) - 1);
- }
- break;
-
- case audioMasterGetSampleRate:
- return 44100;
-
- case audioMasterGetBlockSize:
- return 512;
-
- case audioMasterSetOutputSampleRate:
- return 0;
-
- default:
- DBG ("*** Unhandled VST Callback: " + String ((int) opcode));
- break;
- }
-
- return 0;
- }
-
- // handles callbacks for a specific plugin
- VstIntPtr VSTPluginInstance::handleCallback (VstInt32 opcode, VstInt32 index, VstInt32 value, void *ptr, float opt)
- {
- switch (opcode)
- {
- case audioMasterAutomate:
- sendParamChangeMessageToListeners (index, opt);
- break;
-
- case audioMasterProcessEvents:
- handleMidiFromPlugin ((const VstEvents*) ptr);
- break;
-
- case audioMasterGetTime:
- #ifdef _MSC_VER
- #pragma warning (push)
- #pragma warning (disable: 4311)
- #endif
-
- return (VstIntPtr) &vstHostTime;
-
- #ifdef _MSC_VER
- #pragma warning (pop)
- #endif
- break;
-
- case audioMasterIdle:
- if (insideVSTCallback == 0 && MessageManager::getInstance()->isThisTheMessageThread())
- {
- ++insideVSTCallback;
- #if JUCE_MAC
- if (getActiveEditor() != 0)
- dispatch (effEditIdle, 0, 0, 0, 0);
- #endif
- const MessageManagerLock mml;
-
- juce_callAnyTimersSynchronously();
-
- handleUpdateNowIfNeeded();
-
- for (int i = ComponentPeer::getNumPeers(); --i >= 0;)
- ComponentPeer::getPeer (i)->performAnyPendingRepaintsNow();
-
- --insideVSTCallback;
- }
- break;
-
- case audioMasterUpdateDisplay:
- triggerAsyncUpdate();
- break;
-
- case audioMasterTempoAt:
- // returns (10000 * bpm)
- break;
-
- case audioMasterNeedIdle:
- startTimer (50);
- break;
-
- case audioMasterSizeWindow:
- if (getActiveEditor() != 0)
- getActiveEditor()->setSize (index, value);
-
- return 1;
-
- case audioMasterGetSampleRate:
- return (VstIntPtr) getSampleRate();
-
- case audioMasterGetBlockSize:
- return (VstIntPtr) getBlockSize();
-
- case audioMasterWantMidi:
- wantsMidiMessages = true;
- break;
-
- case audioMasterGetDirectory:
- #if JUCE_MAC
- return (VstIntPtr) (void*) &module->parentDirFSSpec;
- #else
- return (VstIntPtr) (pointer_sized_uint) (const char*) module->fullParentDirectoryPathName;
- #endif
-
- case audioMasterGetAutomationState:
- // returns 0: not supported, 1: off, 2:read, 3:write, 4:read/write
- break;
-
- // none of these are handled (yet)..
- case audioMasterBeginEdit:
- case audioMasterEndEdit:
- case audioMasterSetTime:
- case audioMasterPinConnected:
- case audioMasterGetParameterQuantization:
- case audioMasterIOChanged:
- case audioMasterGetInputLatency:
- case audioMasterGetOutputLatency:
- case audioMasterGetPreviousPlug:
- case audioMasterGetNextPlug:
- case audioMasterWillReplaceOrAccumulate:
- case audioMasterGetCurrentProcessLevel:
- case audioMasterOfflineStart:
- case audioMasterOfflineRead:
- case audioMasterOfflineWrite:
- case audioMasterOfflineGetCurrentPass:
- case audioMasterOfflineGetCurrentMetaPass:
- case audioMasterVendorSpecific:
- case audioMasterSetIcon:
- case audioMasterGetLanguage:
- case audioMasterOpenWindow:
- case audioMasterCloseWindow:
- break;
-
- default:
- return handleGeneralCallback (opcode, index, value, ptr, opt);
- }
-
- return 0;
- }
-
- // entry point for all callbacks from the plugin
- static VstIntPtr VSTCALLBACK audioMaster (AEffect* effect, VstInt32 opcode, VstInt32 index, VstIntPtr value, void* ptr, float opt)
- {
- try
- {
- if (effect != 0 && effect->resvd2 != 0)
- {
- return ((VSTPluginInstance*)(effect->resvd2))
- ->handleCallback (opcode, index, value, ptr, opt);
- }
-
- return handleGeneralCallback (opcode, index, value, ptr, opt);
- }
- catch (...)
- {
- return 0;
- }
- }
-
- const String VSTPluginInstance::getVersion() const throw()
- {
- int v = dispatch (effGetVendorVersion, 0, 0, 0, 0);
-
- String s;
-
- if (v != 0)
- {
- int versionBits[4];
- int n = 0;
-
- while (v != 0)
- {
- versionBits [n++] = (v & 0xff);
- v >>= 8;
- }
-
- s << 'V';
-
- while (n > 0)
- {
- s << versionBits [--n];
-
- if (n > 0)
- s << '.';
- }
- }
-
- return s;
- }
-
- int VSTPluginInstance::getUID() const throw()
- {
- int uid = effect != 0 ? effect->uniqueID : 0;
-
- if (uid == 0)
- uid = module->file.hashCode();
-
- return uid;
- }
-
- const String VSTPluginInstance::getCategory() const throw()
- {
- const char* result = 0;
-
- switch (dispatch (effGetPlugCategory, 0, 0, 0, 0))
- {
- case kPlugCategEffect:
- result = "Effect";
- break;
-
- case kPlugCategSynth:
- result = "Synth";
- break;
-
- case kPlugCategAnalysis:
- result = "Anaylsis";
- break;
-
- case kPlugCategMastering:
- result = "Mastering";
- break;
-
- case kPlugCategSpacializer:
- result = "Spacial";
- break;
-
- case kPlugCategRoomFx:
- result = "Reverb";
- break;
-
- case kPlugSurroundFx:
- result = "Surround";
- break;
-
- case kPlugCategRestoration:
- result = "Restoration";
- break;
-
- case kPlugCategGenerator:
- result = "Tone generation";
- break;
-
- default:
- break;
- }
-
- return result;
- }
-
- float VSTPluginInstance::getParameter (int index)
- {
- if (effect != 0 && ((unsigned int) index) < (unsigned int) effect->numParams)
- {
- try
- {
- const ScopedLock sl (lock);
- return effect->getParameter (effect, index);
- }
- catch (...)
- {
- }
- }
-
- return 0.0f;
- }
-
- void VSTPluginInstance::setParameter (int index, float newValue)
- {
- if (effect != 0 && ((unsigned int) index) < (unsigned int) effect->numParams)
- {
- try
- {
- const ScopedLock sl (lock);
-
- if (effect->getParameter (effect, index) != newValue)
- effect->setParameter (effect, index, newValue);
- }
- catch (...)
- {
- }
- }
- }
-
- const String VSTPluginInstance::getParameterName (int index)
- {
- if (effect != 0)
- {
- jassert (index >= 0 && index < effect->numParams);
-
- char nm [256];
- zerostruct (nm);
- dispatch (effGetParamName, index, 0, nm, 0);
- return String (nm).trim();
- }
-
- return String::empty;
- }
-
- const String VSTPluginInstance::getParameterLabel (int index) const
- {
- if (effect != 0)
- {
- jassert (index >= 0 && index < effect->numParams);
-
- char nm [256];
- zerostruct (nm);
- dispatch (effGetParamLabel, index, 0, nm, 0);
- return String (nm).trim();
- }
-
- return String::empty;
- }
-
- const String VSTPluginInstance::getParameterText (int index)
- {
- if (effect != 0)
- {
- jassert (index >= 0 && index < effect->numParams);
-
- char nm [256];
- zerostruct (nm);
- dispatch (effGetParamDisplay, index, 0, nm, 0);
- return String (nm).trim();
- }
-
- return String::empty;
- }
-
- bool VSTPluginInstance::isParameterAutomatable (int index) const
- {
- if (effect != 0)
- {
- jassert (index >= 0 && index < effect->numParams);
- return dispatch (effCanBeAutomated, index, 0, 0, 0) != 0;
- }
-
- return false;
- }
-
- void VSTPluginInstance::createTempParameterStore (MemoryBlock& dest)
- {
- dest.setSize (64 + 4 * getNumParameters());
- dest.fillWith (0);
-
- getCurrentProgramName().copyToBuffer ((char*) dest.getData(), 63);
-
- float* const p = (float*) (((char*) dest.getData()) + 64);
- for (int i = 0; i < getNumParameters(); ++i)
- p[i] = getParameter(i);
- }
-
- void VSTPluginInstance::restoreFromTempParameterStore (const MemoryBlock& m)
- {
- changeProgramName (getCurrentProgram(), (const char*) m.getData());
-
- float* p = (float*) (((char*) m.getData()) + 64);
- for (int i = 0; i < getNumParameters(); ++i)
- setParameter (i, p[i]);
- }
-
- void VSTPluginInstance::setCurrentProgram (int newIndex)
- {
- if (getNumPrograms() > 0 && newIndex != getCurrentProgram())
- dispatch (effSetProgram, 0, jlimit (0, getNumPrograms() - 1, newIndex), 0, 0);
- }
-
- const String VSTPluginInstance::getProgramName (int index)
- {
- if (index == getCurrentProgram())
- {
- return getCurrentProgramName();
- }
- else if (effect != 0)
- {
- char nm [256];
- zerostruct (nm);
-
- if (dispatch (effGetProgramNameIndexed,
- jlimit (0, getNumPrograms(), index),
- -1, nm, 0) != 0)
- {
- return String (nm).trim();
- }
- }
-
- return programNames [index];
- }
-
- void VSTPluginInstance::changeProgramName (int index, const String& newName)
- {
- if (index == getCurrentProgram())
- {
- if (getNumPrograms() > 0 && newName != getCurrentProgramName())
- dispatch (effSetProgramName, 0, 0, (void*) (const char*) newName.substring (0, 24), 0.0f);
- }
- else
- {
- jassertfalse // xxx not implemented!
- }
- }
-
- void VSTPluginInstance::updateStoredProgramNames()
- {
- if (effect != 0 && getNumPrograms() > 0)
- {
- char nm [256];
- zerostruct (nm);
-
- // only do this if the plugin can't use indexed names..
- if (dispatch (effGetProgramNameIndexed, 0, -1, nm, 0) == 0)
- {
- const int oldProgram = getCurrentProgram();
- MemoryBlock oldSettings;
- createTempParameterStore (oldSettings);
-
- for (int i = 0; i < getNumPrograms(); ++i)
- {
- setCurrentProgram (i);
- getCurrentProgramName(); // (this updates the list)
- }
-
- setCurrentProgram (oldProgram);
- restoreFromTempParameterStore (oldSettings);
- }
- }
- }
-
- const String VSTPluginInstance::getCurrentProgramName()
- {
- if (effect != 0)
- {
- char nm [256];
- zerostruct (nm);
- dispatch (effGetProgramName, 0, 0, nm, 0);
-
- const int index = getCurrentProgram();
- if (programNames[index].isEmpty())
- {
- while (programNames.size() < index)
- programNames.add (String::empty);
-
- programNames.set (index, String (nm).trim());
- }
-
- return String (nm).trim();
- }
-
- return String::empty;
- }
-
- const String VSTPluginInstance::getInputChannelName (const int index) const
- {
- if (index >= 0 && index < getNumInputChannels())
- {
- VstPinProperties pinProps;
- if (dispatch (effGetInputProperties, index, 0, &pinProps, 0.0f) != 0)
- return String (pinProps.label, sizeof (pinProps.label));
- }
-
- return String::empty;
- }
-
- bool VSTPluginInstance::isInputChannelStereoPair (int index) const
- {
- if (index < 0 || index >= getNumInputChannels())
- return false;
-
- VstPinProperties pinProps;
- if (dispatch (effGetInputProperties, index, 0, &pinProps, 0.0f) != 0)
- return (pinProps.flags & kVstPinIsStereo) != 0;
-
- return true;
- }
-
- const String VSTPluginInstance::getOutputChannelName (const int index) const
- {
- if (index >= 0 && index < getNumOutputChannels())
- {
- VstPinProperties pinProps;
- if (dispatch (effGetOutputProperties, index, 0, &pinProps, 0.0f) != 0)
- return String (pinProps.label, sizeof (pinProps.label));
- }
-
- return String::empty;
- }
-
- bool VSTPluginInstance::isOutputChannelStereoPair (int index) const
- {
- if (index < 0 || index >= getNumOutputChannels())
- return false;
-
- VstPinProperties pinProps;
- if (dispatch (effGetOutputProperties, index, 0, &pinProps, 0.0f) != 0)
- return (pinProps.flags & kVstPinIsStereo) != 0;
-
- return true;
- }
-
- void VSTPluginInstance::setPower (const bool on)
- {
- dispatch (effMainsChanged, 0, on ? 1 : 0, 0, 0);
- isPowerOn = on;
- }
-
- const int defaultMaxSizeMB = 64;
-
- void VSTPluginInstance::getStateInformation (MemoryBlock& destData)
- {
- saveToFXBFile (destData, true, defaultMaxSizeMB);
- }
-
- void VSTPluginInstance::getCurrentProgramStateInformation (MemoryBlock& destData)
- {
- saveToFXBFile (destData, false, defaultMaxSizeMB);
- }
-
- void VSTPluginInstance::setStateInformation (const void* data, int sizeInBytes)
- {
- loadFromFXBFile (data, sizeInBytes);
- }
-
- void VSTPluginInstance::setCurrentProgramStateInformation (const void* data, int sizeInBytes)
- {
- loadFromFXBFile (data, sizeInBytes);
- }
-
- VSTPluginFormat::VSTPluginFormat()
- {
- }
-
- VSTPluginFormat::~VSTPluginFormat()
- {
- }
-
- void VSTPluginFormat::findAllTypesForFile (OwnedArray <PluginDescription>& results,
- const File& file)
- {
- if (! fileMightContainThisPluginType (file))
- return;
-
- PluginDescription desc;
- desc.file = file;
- desc.uid = 0;
-
- VSTPluginInstance* instance = dynamic_cast <VSTPluginInstance*> (createInstanceFromDescription (desc));
-
- if (instance == 0)
- return;
-
- try
- {
- #if JUCE_MAC
- if (instance->module->resFileId != 0)
- UseResFile (instance->module->resFileId);
- #endif
-
- instance->fillInPluginDescription (desc);
-
- VstPlugCategory category = (VstPlugCategory) instance->dispatch (effGetPlugCategory, 0, 0, 0, 0);
-
- if (category != kPlugCategShell)
- {
- // Normal plugin...
- results.add (new PluginDescription (desc));
-
- ++insideVSTCallback;
- instance->dispatch (effOpen, 0, 0, 0, 0);
- --insideVSTCallback;
- }
- else
- {
- // It's a shell plugin, so iterate all the subtypes...
- char shellEffectName [64];
-
- for (;;)
- {
- zerostruct (shellEffectName);
- const int uid = instance->dispatch (effShellGetNextPlugin, 0, 0, shellEffectName, 0);
-
- if (uid == 0)
- {
- break;
- }
- else
- {
- desc.uid = uid;
- desc.name = shellEffectName;
-
- bool alreadyThere = false;
-
- for (int i = results.size(); --i >= 0;)
- {
- PluginDescription* const d = results.getUnchecked(i);
-
- if (d->isDuplicateOf (desc))
- {
- alreadyThere = true;
- break;
- }
- }
-
- if (! alreadyThere)
- results.add (new PluginDescription (desc));
- }
- }
- }
- }
- catch (...)
- {
- // crashed while loading...
- }
-
- deleteAndZero (instance);
- }
-
- AudioPluginInstance* VSTPluginFormat::createInstanceFromDescription (const PluginDescription& desc)
- {
- VSTPluginInstance* result = 0;
-
- if (fileMightContainThisPluginType (desc.file))
- {
- const File previousWorkingDirectory (File::getCurrentWorkingDirectory());
- desc.file.getParentDirectory().setAsCurrentWorkingDirectory();
-
- const ReferenceCountedObjectPtr <ModuleHandle> module (ModuleHandle::findOrCreateModule (desc.file));
-
- if (module != 0)
- {
- shellUIDToCreate = desc.uid;
-
- result = new VSTPluginInstance (module);
-
- if (result->effect != 0)
- {
- result->effect->resvd2 = (VstIntPtr) (pointer_sized_int) result;
- result->initialise();
- }
- else
- {
- deleteAndZero (result);
- }
- }
-
- previousWorkingDirectory.setAsCurrentWorkingDirectory();
- }
-
- return result;
- }
-
- bool VSTPluginFormat::fileMightContainThisPluginType (const File& f)
- {
- #if JUCE_MAC
- if (f.isDirectory() && f.hasFileExtension (T(".vst")))
- return true;
-
- #if JUCE_PPC
- FSRef fileRef;
- if (PlatformUtilities::makeFSRefFromPath (&fileRef, f.getFullPathName()))
- {
- const short resFileId = FSOpenResFile (&fileRef, fsRdPerm);
-
- if (resFileId != -1)
- {
- const int numEffects = Count1Resources ('aEff');
- CloseResFile (resFileId);
-
- if (numEffects > 0)
- return true;
- }
- }
- #endif
-
- return false;
- #elif JUCE_WIN32
- return f.existsAsFile()
- && f.hasFileExtension (T(".dll"));
- #elif JUCE_LINUX
- return f.existsAsFile()
- && f.hasFileExtension (T(".so"));
- #endif
- }
-
- const FileSearchPath VSTPluginFormat::getDefaultLocationsToSearch()
- {
- #if JUCE_MAC
- return FileSearchPath ("~/Library/Audio/Plug-Ins/VST;/Library/Audio/Plug-Ins/VST");
- #elif JUCE_WIN32
- const String programFiles (File::getSpecialLocation (File::globalApplicationsDirectory).getFullPathName());
-
- return FileSearchPath (programFiles + "\\Steinberg\\VstPlugins");
- #elif JUCE_LINUX
- return FileSearchPath ("/usr/lib/vst");
- #endif
- }
-
- END_JUCE_NAMESPACE
-
- #undef log
-
- #endif
- /********* End of inlined file: juce_VSTPluginFormat.cpp *********/
-
- /********* Start of inlined file: juce_AudioProcessor.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- AudioProcessor::AudioProcessor()
- : playHead (0),
- activeEditor (0),
- sampleRate (0),
- blockSize (0),
- numInputChannels (0),
- numOutputChannels (0),
- latencySamples (0),
- suspended (false),
- nonRealtime (false)
- {
- }
-
- AudioProcessor::~AudioProcessor()
- {
- // ooh, nasty - the editor should have been deleted before the filter
- // that it refers to is deleted..
- jassert (activeEditor == 0);
-
- #ifdef JUCE_DEBUG
- // This will fail if you've called beginParameterChangeGesture() for one
- // or more parameters without having made a corresponding call to endParameterChangeGesture...
- jassert (changingParams.countNumberOfSetBits() == 0);
- #endif
- }
-
- void AudioProcessor::setPlayHead (AudioPlayHead* const newPlayHead) throw()
- {
- playHead = newPlayHead;
- }
-
- void AudioProcessor::addListener (AudioProcessorListener* const newListener) throw()
- {
- const ScopedLock sl (listenerLock);
- listeners.addIfNotAlreadyThere (newListener);
- }
-
- void AudioProcessor::removeListener (AudioProcessorListener* const listenerToRemove) throw()
- {
- const ScopedLock sl (listenerLock);
- listeners.removeValue (listenerToRemove);
- }
-
- void AudioProcessor::setPlayConfigDetails (const int numIns,
- const int numOuts,
- const double sampleRate_,
- const int blockSize_) throw()
- {
- numInputChannels = numIns;
- numOutputChannels = numOuts;
- sampleRate = sampleRate_;
- blockSize = blockSize_;
- }
-
- void AudioProcessor::setNonRealtime (const bool nonRealtime_) throw()
- {
- nonRealtime = nonRealtime_;
- }
-
- void AudioProcessor::setLatencySamples (const int newLatency)
- {
- if (latencySamples != newLatency)
- {
- latencySamples = newLatency;
- updateHostDisplay();
- }
- }
-
- void AudioProcessor::setParameterNotifyingHost (const int parameterIndex,
- const float newValue)
- {
- setParameter (parameterIndex, newValue);
- sendParamChangeMessageToListeners (parameterIndex, newValue);
- }
-
- void AudioProcessor::sendParamChangeMessageToListeners (const int parameterIndex, const float newValue)
- {
- jassert (((unsigned int) parameterIndex) < (unsigned int) getNumParameters());
-
- for (int i = listeners.size(); --i >= 0;)
- {
- listenerLock.enter();
- AudioProcessorListener* const l = (AudioProcessorListener*) listeners [i];
- listenerLock.exit();
-
- if (l != 0)
- l->audioProcessorParameterChanged (this, parameterIndex, newValue);
- }
- }
-
- void AudioProcessor::beginParameterChangeGesture (int parameterIndex)
- {
- jassert (((unsigned int) parameterIndex) < (unsigned int) getNumParameters());
-
- #ifdef JUCE_DEBUG
- // This means you've called beginParameterChangeGesture twice in succession without a matching
- // call to endParameterChangeGesture. That might be fine in most hosts, but better to avoid doing it.
- jassert (! changingParams [parameterIndex]);
- changingParams.setBit (parameterIndex);
- #endif
-
- for (int i = listeners.size(); --i >= 0;)
- {
- listenerLock.enter();
- AudioProcessorListener* const l = (AudioProcessorListener*) listeners [i];
- listenerLock.exit();
-
- if (l != 0)
- l->audioProcessorParameterChangeGestureBegin (this, parameterIndex);
- }
- }
-
- void AudioProcessor::endParameterChangeGesture (int parameterIndex)
- {
- jassert (((unsigned int) parameterIndex) < (unsigned int) getNumParameters());
-
- #ifdef JUCE_DEBUG
- // This means you've called endParameterChangeGesture without having previously called
- // endParameterChangeGesture. That might be fine in most hosts, but better to keep the
- // calls matched correctly.
- jassert (changingParams [parameterIndex]);
- changingParams.clearBit (parameterIndex);
- #endif
-
- for (int i = listeners.size(); --i >= 0;)
- {
- listenerLock.enter();
- AudioProcessorListener* const l = (AudioProcessorListener*) listeners [i];
- listenerLock.exit();
-
- if (l != 0)
- l->audioProcessorParameterChangeGestureEnd (this, parameterIndex);
- }
- }
-
- void AudioProcessor::updateHostDisplay()
- {
- for (int i = listeners.size(); --i >= 0;)
- {
- listenerLock.enter();
- AudioProcessorListener* const l = (AudioProcessorListener*) listeners [i];
- listenerLock.exit();
-
- if (l != 0)
- l->audioProcessorChanged (this);
- }
- }
-
- bool AudioProcessor::isParameterAutomatable (int /*index*/) const
- {
- return true;
- }
-
- void AudioProcessor::suspendProcessing (const bool shouldBeSuspended)
- {
- const ScopedLock sl (callbackLock);
- suspended = shouldBeSuspended;
- }
-
- void AudioProcessor::editorBeingDeleted (AudioProcessorEditor* const editor) throw()
- {
- const ScopedLock sl (callbackLock);
-
- jassert (activeEditor == editor);
-
- if (activeEditor == editor)
- activeEditor = 0;
- }
-
- AudioProcessorEditor* AudioProcessor::createEditorIfNeeded()
- {
- if (activeEditor != 0)
- return activeEditor;
-
- AudioProcessorEditor* const ed = createEditor();
-
- if (ed != 0)
- {
- // you must give your editor comp a size before returning it..
- jassert (ed->getWidth() > 0 && ed->getHeight() > 0);
-
- const ScopedLock sl (callbackLock);
- activeEditor = ed;
- }
-
- return ed;
- }
-
- void AudioProcessor::getCurrentProgramStateInformation (JUCE_NAMESPACE::MemoryBlock& destData)
- {
- getStateInformation (destData);
- }
-
- void AudioProcessor::setCurrentProgramStateInformation (const void* data, int sizeInBytes)
- {
- setStateInformation (data, sizeInBytes);
- }
-
- // magic number to identify memory blocks that we've stored as XML
- const uint32 magicXmlNumber = 0x21324356;
-
- void AudioProcessor::copyXmlToBinary (const XmlElement& xml,
- JUCE_NAMESPACE::MemoryBlock& destData)
- {
- const String xmlString (xml.createDocument (String::empty, true, false));
- const int stringLength = xmlString.length();
-
- destData.setSize (stringLength + 10);
-
- char* const d = (char*) destData.getData();
- *(uint32*) d = swapIfBigEndian ((const uint32) magicXmlNumber);
- *(uint32*) (d + 4) = swapIfBigEndian ((const uint32) stringLength);
-
- xmlString.copyToBuffer (d + 8, stringLength);
- }
-
- XmlElement* AudioProcessor::getXmlFromBinary (const void* data,
- const int sizeInBytes)
- {
- if (sizeInBytes > 8
- && littleEndianInt ((const char*) data) == magicXmlNumber)
- {
- const uint32 stringLength = littleEndianInt (((const char*) data) + 4);
-
- if (stringLength > 0)
- {
- XmlDocument doc (String (((const char*) data) + 8,
- jmin ((sizeInBytes - 8), stringLength)));
-
- return doc.getDocumentElement();
- }
- }
-
- return 0;
- }
-
- void AudioProcessorListener::audioProcessorParameterChangeGestureBegin (AudioProcessor*, int)
- {
- }
-
- void AudioProcessorListener::audioProcessorParameterChangeGestureEnd (AudioProcessor*, int)
- {
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_AudioProcessor.cpp *********/
-
- /********* Start of inlined file: juce_AudioProcessorEditor.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- AudioProcessorEditor::AudioProcessorEditor (AudioProcessor* const owner_)
- : owner (owner_)
- {
- // the filter must be valid..
- jassert (owner != 0);
- }
-
- AudioProcessorEditor::~AudioProcessorEditor()
- {
- // if this fails, then the wrapper hasn't called editorBeingDeleted() on the
- // filter for some reason..
- jassert (owner->getActiveEditor() != this);
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_AudioProcessorEditor.cpp *********/
-
- /********* Start of inlined file: juce_AudioProcessorGraph.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- const int AudioProcessorGraph::midiChannelIndex = 0x1000;
-
- AudioProcessorGraph::Node::Node (const uint32 id_,
- AudioProcessor* const processor_) throw()
- : id (id_),
- processor (processor_),
- isPrepared (false)
- {
- jassert (processor_ != 0);
- }
-
- AudioProcessorGraph::Node::~Node()
- {
- delete processor;
- }
-
- void AudioProcessorGraph::Node::prepare (const double sampleRate, const int blockSize,
- AudioProcessorGraph* const graph)
- {
- if (! isPrepared)
- {
- isPrepared = true;
-
- AudioProcessorGraph::AudioGraphIOProcessor* const ioProc
- = dynamic_cast <AudioProcessorGraph::AudioGraphIOProcessor*> (processor);
-
- if (ioProc != 0)
- ioProc->setParentGraph (graph);
-
- processor->setPlayConfigDetails (processor->getNumInputChannels(),
- processor->getNumOutputChannels(),
- sampleRate, blockSize);
-
- processor->prepareToPlay (sampleRate, blockSize);
- }
- }
-
- void AudioProcessorGraph::Node::unprepare()
- {
- if (isPrepared)
- {
- isPrepared = false;
- processor->releaseResources();
- }
- }
-
- AudioProcessorGraph::AudioProcessorGraph()
- : lastNodeId (0),
- renderingBuffers (1, 1),
- currentAudioOutputBuffer (1, 1)
- {
- }
-
- AudioProcessorGraph::~AudioProcessorGraph()
- {
- clearRenderingSequence();
- clear();
- }
-
- const String AudioProcessorGraph::getName() const
- {
- return "Audio Graph";
- }
-
- void AudioProcessorGraph::clear()
- {
- nodes.clear();
- connections.clear();
- triggerAsyncUpdate();
- }
-
- AudioProcessorGraph::Node* AudioProcessorGraph::getNodeForId (const uint32 nodeId) const throw()
- {
- for (int i = nodes.size(); --i >= 0;)
- if (nodes.getUnchecked(i)->id == nodeId)
- return nodes.getUnchecked(i);
-
- return 0;
- }
-
- AudioProcessorGraph::Node* AudioProcessorGraph::addNode (AudioProcessor* const newProcessor,
- uint32 nodeId)
- {
- if (newProcessor == 0)
- {
- jassertfalse
- return 0;
- }
-
- if (nodeId == 0)
- {
- nodeId = ++lastNodeId;
- }
- else
- {
- // you can't add a node with an id that already exists in the graph..
- jassert (getNodeForId (nodeId) == 0);
- removeNode (nodeId);
- }
-
- lastNodeId = nodeId;
-
- Node* const n = new Node (nodeId, newProcessor);
- nodes.add (n);
- triggerAsyncUpdate();
-
- AudioProcessorGraph::AudioGraphIOProcessor* const ioProc
- = dynamic_cast <AudioProcessorGraph::AudioGraphIOProcessor*> (n->processor);
-
- if (ioProc != 0)
- ioProc->setParentGraph (this);
-
- return n;
- }
-
- bool AudioProcessorGraph::removeNode (const uint32 nodeId)
- {
- disconnectNode (nodeId);
-
- for (int i = nodes.size(); --i >= 0;)
- {
- if (nodes.getUnchecked(i)->id == nodeId)
- {
- AudioProcessorGraph::AudioGraphIOProcessor* const ioProc
- = dynamic_cast <AudioProcessorGraph::AudioGraphIOProcessor*> (nodes.getUnchecked(i)->processor);
-
- if (ioProc != 0)
- ioProc->setParentGraph (0);
-
- nodes.remove (i);
- triggerAsyncUpdate();
-
- return true;
- }
- }
-
- return false;
- }
-
- const AudioProcessorGraph::Connection* AudioProcessorGraph::getConnectionBetween (const uint32 sourceNodeId,
- const int sourceChannelIndex,
- const uint32 destNodeId,
- const int destChannelIndex) const throw()
- {
- for (int i = connections.size(); --i >= 0;)
- {
- const Connection* const c = connections.getUnchecked(i);
-
- if (c->sourceNodeId == sourceNodeId
- && c->destNodeId == destNodeId
- && c->sourceChannelIndex == sourceChannelIndex
- && c->destChannelIndex == destChannelIndex)
- {
- return c;
- }
- }
-
- return 0;
- }
-
- bool AudioProcessorGraph::isConnected (const uint32 possibleSourceNodeId,
- const uint32 possibleDestNodeId) const throw()
- {
- for (int i = connections.size(); --i >= 0;)
- {
- const Connection* const c = connections.getUnchecked(i);
-
- if (c->sourceNodeId == possibleSourceNodeId
- && c->destNodeId == possibleDestNodeId)
- {
- return true;
- }
- }
-
- return false;
- }
-
- bool AudioProcessorGraph::canConnect (const uint32 sourceNodeId,
- const int sourceChannelIndex,
- const uint32 destNodeId,
- const int destChannelIndex) const throw()
- {
- if (sourceChannelIndex < 0
- || destChannelIndex < 0
- || sourceNodeId == destNodeId
- || (destChannelIndex == midiChannelIndex) != (sourceChannelIndex == midiChannelIndex))
- return false;
-
- const Node* const source = getNodeForId (sourceNodeId);
-
- if (source == 0
- || (sourceChannelIndex != midiChannelIndex && sourceChannelIndex >= source->processor->getNumOutputChannels())
- || (sourceChannelIndex == midiChannelIndex && ! source->processor->producesMidi()))
- return false;
-
- const Node* const dest = getNodeForId (destNodeId);
-
- if (dest == 0
- || (destChannelIndex != midiChannelIndex && destChannelIndex >= dest->processor->getNumInputChannels())
- || (destChannelIndex == midiChannelIndex && ! dest->processor->acceptsMidi()))
- return false;
-
- return getConnectionBetween (sourceNodeId, sourceChannelIndex,
- destNodeId, destChannelIndex) == 0;
- }
-
- bool AudioProcessorGraph::addConnection (const uint32 sourceNodeId,
- const int sourceChannelIndex,
- const uint32 destNodeId,
- const int destChannelIndex)
- {
- if (! canConnect (sourceNodeId, sourceChannelIndex, destNodeId, destChannelIndex))
- return false;
-
- Connection* const c = new Connection();
- c->sourceNodeId = sourceNodeId;
- c->sourceChannelIndex = sourceChannelIndex;
- c->destNodeId = destNodeId;
- c->destChannelIndex = destChannelIndex;
-
- connections.add (c);
- triggerAsyncUpdate();
-
- return true;
- }
-
- void AudioProcessorGraph::removeConnection (const int index)
- {
- connections.remove (index);
- triggerAsyncUpdate();
- }
-
- bool AudioProcessorGraph::removeConnection (const uint32 sourceNodeId, const int sourceChannelIndex,
- const uint32 destNodeId, const int destChannelIndex)
- {
- bool doneAnything = false;
-
- for (int i = connections.size(); --i >= 0;)
- {
- const Connection* const c = connections.getUnchecked(i);
-
- if (c->sourceNodeId == sourceNodeId
- && c->destNodeId == destNodeId
- && c->sourceChannelIndex == sourceChannelIndex
- && c->destChannelIndex == destChannelIndex)
- {
- removeConnection (i);
- doneAnything = true;
- triggerAsyncUpdate();
- }
- }
-
- return doneAnything;
- }
-
- bool AudioProcessorGraph::disconnectNode (const uint32 nodeId)
- {
- bool doneAnything = false;
-
- for (int i = connections.size(); --i >= 0;)
- {
- const Connection* const c = connections.getUnchecked(i);
-
- if (c->sourceNodeId == nodeId || c->destNodeId == nodeId)
- {
- removeConnection (i);
- doneAnything = true;
- triggerAsyncUpdate();
- }
- }
-
- return doneAnything;
- }
-
- bool AudioProcessorGraph::removeIllegalConnections()
- {
- bool doneAnything = false;
-
- for (int i = connections.size(); --i >= 0;)
- {
- const Connection* const c = connections.getUnchecked(i);
-
- const Node* const source = getNodeForId (c->sourceNodeId);
- const Node* const dest = getNodeForId (c->destNodeId);
-
- if (source == 0 || dest == 0
- || (c->sourceChannelIndex != midiChannelIndex
- && (((unsigned int) c->sourceChannelIndex) >= (unsigned int) source->processor->getNumOutputChannels()))
- || (c->sourceChannelIndex == midiChannelIndex
- && ! source->processor->producesMidi())
- || (c->destChannelIndex != midiChannelIndex
- && (((unsigned int) c->destChannelIndex) >= (unsigned int) dest->processor->getNumInputChannels()))
- || (c->destChannelIndex == midiChannelIndex
- && ! dest->processor->acceptsMidi()))
- {
- removeConnection (i);
- doneAnything = true;
- triggerAsyncUpdate();
- }
- }
-
- return doneAnything;
- }
-
- namespace GraphRenderingOps
- {
-
- class AudioGraphRenderingOp
- {
- public:
- AudioGraphRenderingOp() throw() {}
- virtual ~AudioGraphRenderingOp() throw() {}
-
- virtual void perform (AudioSampleBuffer& sharedBufferChans,
- const OwnedArray <MidiBuffer>& sharedMidiBuffers,
- const int numSamples) throw() = 0;
-
- juce_UseDebuggingNewOperator
- };
-
- class ClearChannelOp : public AudioGraphRenderingOp
- {
- public:
- ClearChannelOp (const int channelNum_) throw()
- : channelNum (channelNum_)
- {}
-
- ~ClearChannelOp() throw() {}
-
- void perform (AudioSampleBuffer& sharedBufferChans, const OwnedArray <MidiBuffer>&, const int numSamples) throw()
- {
- sharedBufferChans.clear (channelNum, 0, numSamples);
- }
-
- private:
- const int channelNum;
-
- ClearChannelOp (const ClearChannelOp&);
- const ClearChannelOp& operator= (const ClearChannelOp&);
- };
-
- class CopyChannelOp : public AudioGraphRenderingOp
- {
- public:
- CopyChannelOp (const int srcChannelNum_, const int dstChannelNum_) throw()
- : srcChannelNum (srcChannelNum_),
- dstChannelNum (dstChannelNum_)
- {}
-
- ~CopyChannelOp() throw() {}
-
- void perform (AudioSampleBuffer& sharedBufferChans, const OwnedArray <MidiBuffer>&, const int numSamples) throw()
- {
- sharedBufferChans.copyFrom (dstChannelNum, 0, sharedBufferChans, srcChannelNum, 0, numSamples);
- }
-
- private:
- const int srcChannelNum, dstChannelNum;
-
- CopyChannelOp (const CopyChannelOp&);
- const CopyChannelOp& operator= (const CopyChannelOp&);
- };
-
- class AddChannelOp : public AudioGraphRenderingOp
- {
- public:
- AddChannelOp (const int srcChannelNum_, const int dstChannelNum_) throw()
- : srcChannelNum (srcChannelNum_),
- dstChannelNum (dstChannelNum_)
- {}
-
- ~AddChannelOp() throw() {}
-
- void perform (AudioSampleBuffer& sharedBufferChans, const OwnedArray <MidiBuffer>&, const int numSamples) throw()
- {
- sharedBufferChans.addFrom (dstChannelNum, 0, sharedBufferChans, srcChannelNum, 0, numSamples);
- }
-
- private:
- const int srcChannelNum, dstChannelNum;
-
- AddChannelOp (const AddChannelOp&);
- const AddChannelOp& operator= (const AddChannelOp&);
- };
-
- class ClearMidiBufferOp : public AudioGraphRenderingOp
- {
- public:
- ClearMidiBufferOp (const int bufferNum_) throw()
- : bufferNum (bufferNum_)
- {}
-
- ~ClearMidiBufferOp() throw() {}
-
- void perform (AudioSampleBuffer&, const OwnedArray <MidiBuffer>& sharedMidiBuffers, const int) throw()
- {
- sharedMidiBuffers.getUnchecked (bufferNum)->clear();
- }
-
- private:
- const int bufferNum;
-
- ClearMidiBufferOp (const ClearMidiBufferOp&);
- const ClearMidiBufferOp& operator= (const ClearMidiBufferOp&);
- };
-
- class CopyMidiBufferOp : public AudioGraphRenderingOp
- {
- public:
- CopyMidiBufferOp (const int srcBufferNum_, const int dstBufferNum_) throw()
- : srcBufferNum (srcBufferNum_),
- dstBufferNum (dstBufferNum_)
- {}
-
- ~CopyMidiBufferOp() throw() {}
-
- void perform (AudioSampleBuffer&, const OwnedArray <MidiBuffer>& sharedMidiBuffers, const int) throw()
- {
- *sharedMidiBuffers.getUnchecked (dstBufferNum) = *sharedMidiBuffers.getUnchecked (srcBufferNum);
- }
-
- private:
- const int srcBufferNum, dstBufferNum;
-
- CopyMidiBufferOp (const CopyMidiBufferOp&);
- const CopyMidiBufferOp& operator= (const CopyMidiBufferOp&);
- };
-
- class AddMidiBufferOp : public AudioGraphRenderingOp
- {
- public:
- AddMidiBufferOp (const int srcBufferNum_, const int dstBufferNum_) throw()
- : srcBufferNum (srcBufferNum_),
- dstBufferNum (dstBufferNum_)
- {}
-
- ~AddMidiBufferOp() throw() {}
-
- void perform (AudioSampleBuffer&, const OwnedArray <MidiBuffer>& sharedMidiBuffers, const int numSamples) throw()
- {
- sharedMidiBuffers.getUnchecked (dstBufferNum)
- ->addEvents (*sharedMidiBuffers.getUnchecked (srcBufferNum), 0, numSamples, 0);
- }
-
- private:
- const int srcBufferNum, dstBufferNum;
-
- AddMidiBufferOp (const AddMidiBufferOp&);
- const AddMidiBufferOp& operator= (const AddMidiBufferOp&);
- };
-
- class ProcessBufferOp : public AudioGraphRenderingOp
- {
- public:
- ProcessBufferOp (const AudioProcessorGraph::Node::Ptr& node_,
- const Array <int>& audioChannelsToUse_,
- const int totalChans_,
- const int midiBufferToUse_) throw()
- : node (node_),
- processor (node_->processor),
- audioChannelsToUse (audioChannelsToUse_),
- totalChans (totalChans_),
- midiBufferToUse (midiBufferToUse_)
- {
- channels = (float**) juce_calloc (sizeof (float*) * totalChans_);
- }
-
- ~ProcessBufferOp() throw()
- {
- juce_free (channels);
- }
-
- void perform (AudioSampleBuffer& sharedBufferChans, const OwnedArray <MidiBuffer>& sharedMidiBuffers, const int numSamples) throw()
- {
- for (int i = totalChans; --i >= 0;)
- channels[i] = sharedBufferChans.getSampleData (audioChannelsToUse.getUnchecked (i), 0);
-
- AudioSampleBuffer buffer (channels, totalChans, numSamples);
-
- processor->processBlock (buffer, *sharedMidiBuffers.getUnchecked (midiBufferToUse));
- }
-
- const AudioProcessorGraph::Node::Ptr node;
- AudioProcessor* const processor;
-
- private:
- Array <int> audioChannelsToUse;
- float** channels;
- int totalChans;
- int midiBufferToUse;
-
- ProcessBufferOp (const ProcessBufferOp&);
- const ProcessBufferOp& operator= (const ProcessBufferOp&);
- };
-
- /** Used to calculate the correct sequence of rendering ops needed, based on
- the best re-use of shared buffers at each stage.
- */
- class RenderingOpSequenceCalculator
- {
- public:
-
- RenderingOpSequenceCalculator (AudioProcessorGraph& graph_,
- const VoidArray& orderedNodes_,
- VoidArray& renderingOps)
- : graph (graph_),
- orderedNodes (orderedNodes_)
- {
- nodeIds.add (-2); // first buffer is read-only zeros
- channels.add (0);
-
- midiNodeIds.add (-2);
-
- for (int i = 0; i < orderedNodes.size(); ++i)
- {
- createRenderingOpsForNode ((AudioProcessorGraph::Node*) orderedNodes.getUnchecked(i),
- renderingOps, i);
-
- markAnyUnusedBuffersAsFree (i);
- }
- }
-
- int getNumBuffersNeeded() const throw() { return nodeIds.size(); }
-
- int getNumMidiBuffersNeeded() const throw() { return midiNodeIds.size(); }
-
- juce_UseDebuggingNewOperator
-
- private:
- AudioProcessorGraph& graph;
- const VoidArray& orderedNodes;
- Array <int> nodeIds, channels, midiNodeIds;
-
- void createRenderingOpsForNode (AudioProcessorGraph::Node* const node,
- VoidArray& renderingOps,
- const int ourRenderingIndex)
- {
- const int numIns = node->processor->getNumInputChannels();
- const int numOuts = node->processor->getNumOutputChannels();
- const int totalChans = jmax (numIns, numOuts);
-
- Array <int> audioChannelsToUse;
- int midiBufferToUse = -1;
-
- for (int inputChan = 0; inputChan < numIns; ++inputChan)
- {
- // get a list of all the inputs to this node
- Array <int> sourceNodes, sourceOutputChans;
-
- for (int i = graph.getNumConnections(); --i >= 0;)
- {
- const AudioProcessorGraph::Connection* const c = graph.getConnection (i);
-
- if (c->destNodeId == node->id && c->destChannelIndex == inputChan)
- {
- sourceNodes.add (c->sourceNodeId);
- sourceOutputChans.add (c->sourceChannelIndex);
- }
- }
-
- int bufIndex = -1;
-
- if (sourceNodes.size() == 0)
- {
- // unconnected input channel
-
- if (inputChan >= numOuts)
- {
- bufIndex = getReadOnlyEmptyBuffer();
- jassert (bufIndex >= 0);
- }
- else
- {
- bufIndex = getFreeBuffer (false);
- renderingOps.add (new ClearChannelOp (bufIndex));
- }
- }
- else if (sourceNodes.size() == 1)
- {
- // channel with a straightforward single input..
- const int srcNode = sourceNodes.getUnchecked(0);
- const int srcChan = sourceOutputChans.getUnchecked(0);
-
- bufIndex = getBufferContaining (srcNode, srcChan);
-
- if (bufIndex < 0)
- {
- // if not found, this is probably a feedback loop
- bufIndex = getReadOnlyEmptyBuffer();
- jassert (bufIndex >= 0);
- }
-
- if (inputChan < numOuts
- && isBufferNeededLater (ourRenderingIndex,
- inputChan,
- srcNode, srcChan))
- {
- // can't mess up this channel because it's needed later by another node, so we
- // need to use a copy of it..
- const int newFreeBuffer = getFreeBuffer (false);
-
- renderingOps.add (new CopyChannelOp (bufIndex, newFreeBuffer));
-
- bufIndex = newFreeBuffer;
- }
- }
- else
- {
- // channel with a mix of several inputs..
-
- // try to find a re-usable channel from our inputs..
- int reusableInputIndex = -1;
-
- for (int i = 0; i < sourceNodes.size(); ++i)
- {
- const int sourceBufIndex = getBufferContaining (sourceNodes.getUnchecked(i),
- sourceOutputChans.getUnchecked(i));
-
- if (sourceBufIndex >= 0
- && ! isBufferNeededLater (ourRenderingIndex,
- inputChan,
- sourceNodes.getUnchecked(i),
- sourceOutputChans.getUnchecked(i)))
- {
- // we've found one of our input chans that can be re-used..
- reusableInputIndex = i;
- bufIndex = sourceBufIndex;
- break;
- }
- }
-
- if (reusableInputIndex < 0)
- {
- // can't re-use any of our input chans, so get a new one and copy everything into it..
- bufIndex = getFreeBuffer (false);
- jassert (bufIndex != 0);
-
- const int srcIndex = getBufferContaining (sourceNodes.getUnchecked (0),
- sourceOutputChans.getUnchecked (0));
- if (srcIndex < 0)
- {
- // if not found, this is probably a feedback loop
- renderingOps.add (new ClearChannelOp (bufIndex));
- }
- else
- {
- renderingOps.add (new CopyChannelOp (srcIndex, bufIndex));
- }
-
- reusableInputIndex = 0;
- }
-
- for (int j = 0; j < sourceNodes.size(); ++j)
- {
- if (j != reusableInputIndex)
- {
- const int srcIndex = getBufferContaining (sourceNodes.getUnchecked(j),
- sourceOutputChans.getUnchecked(j));
- if (srcIndex >= 0)
- renderingOps.add (new AddChannelOp (srcIndex, bufIndex));
- }
- }
- }
-
- jassert (bufIndex >= 0);
- audioChannelsToUse.add (bufIndex);
-
- if (inputChan < numOuts)
- markBufferAsContaining (bufIndex, node->id, inputChan);
- }
-
- for (int outputChan = numIns; outputChan < numOuts; ++outputChan)
- {
- const int bufIndex = getFreeBuffer (false);
- jassert (bufIndex != 0);
- audioChannelsToUse.add (bufIndex);
-
- markBufferAsContaining (bufIndex, node->id, outputChan);
- }
-
- // Now the same thing for midi..
- Array <int> midiSourceNodes;
-
- for (int i = graph.getNumConnections(); --i >= 0;)
- {
- const AudioProcessorGraph::Connection* const c = graph.getConnection (i);
-
- if (c->destNodeId == node->id && c->destChannelIndex == AudioProcessorGraph::midiChannelIndex)
- midiSourceNodes.add (c->sourceNodeId);
- }
-
- if (midiSourceNodes.size() == 0)
- {
- // No midi inputs..
- midiBufferToUse = getFreeBuffer (true); // need to pick a buffer even if the processor doesn't use midi
-
- if (node->processor->acceptsMidi() || node->processor->producesMidi())
- renderingOps.add (new ClearMidiBufferOp (midiBufferToUse));
- }
- else if (midiSourceNodes.size() == 1)
- {
- // One midi input..
- midiBufferToUse = getBufferContaining (midiSourceNodes.getUnchecked(0),
- AudioProcessorGraph::midiChannelIndex);
-
- if (midiBufferToUse >= 0)
- {
- if (isBufferNeededLater (ourRenderingIndex,
- AudioProcessorGraph::midiChannelIndex,
- midiSourceNodes.getUnchecked(0),
- AudioProcessorGraph::midiChannelIndex))
- {
- // can't mess up this channel because it's needed later by another node, so we
- // need to use a copy of it..
- const int newFreeBuffer = getFreeBuffer (true);
- renderingOps.add (new CopyMidiBufferOp (midiBufferToUse, newFreeBuffer));
- midiBufferToUse = newFreeBuffer;
- }
- }
- else
- {
- // probably a feedback loop, so just use an empty one..
- midiBufferToUse = getFreeBuffer (true); // need to pick a buffer even if the processor doesn't use midi
- }
- }
- else
- {
- // More than one midi input being mixed..
- int reusableInputIndex = -1;
-
- for (int i = 0; i < midiSourceNodes.size(); ++i)
- {
- const int sourceBufIndex = getBufferContaining (midiSourceNodes.getUnchecked(i),
- AudioProcessorGraph::midiChannelIndex);
-
- if (sourceBufIndex >= 0
- && ! isBufferNeededLater (ourRenderingIndex,
- AudioProcessorGraph::midiChannelIndex,
- midiSourceNodes.getUnchecked(i),
- AudioProcessorGraph::midiChannelIndex))
- {
- // we've found one of our input buffers that can be re-used..
- reusableInputIndex = i;
- midiBufferToUse = sourceBufIndex;
- break;
- }
- }
-
- if (reusableInputIndex < 0)
- {
- // can't re-use any of our input buffers, so get a new one and copy everything into it..
- midiBufferToUse = getFreeBuffer (true);
- jassert (midiBufferToUse >= 0);
-
- const int srcIndex = getBufferContaining (midiSourceNodes.getUnchecked(0),
- AudioProcessorGraph::midiChannelIndex);
- if (srcIndex >= 0)
- renderingOps.add (new CopyMidiBufferOp (srcIndex, midiBufferToUse));
- else
- renderingOps.add (new ClearMidiBufferOp (midiBufferToUse));
-
- reusableInputIndex = 0;
- }
-
- for (int j = 0; j < midiSourceNodes.size(); ++j)
- {
- if (j != reusableInputIndex)
- {
- const int srcIndex = getBufferContaining (midiSourceNodes.getUnchecked(j),
- AudioProcessorGraph::midiChannelIndex);
- if (srcIndex >= 0)
- renderingOps.add (new AddMidiBufferOp (srcIndex, midiBufferToUse));
- }
- }
- }
-
- if (node->processor->producesMidi())
- markBufferAsContaining (midiBufferToUse, node->id,
- AudioProcessorGraph::midiChannelIndex);
-
- renderingOps.add (new ProcessBufferOp (node, audioChannelsToUse,
- totalChans, midiBufferToUse));
- }
-
- int getFreeBuffer (const bool forMidi)
- {
- if (forMidi)
- {
- for (int i = 1; i < midiNodeIds.size(); ++i)
- if (midiNodeIds.getUnchecked(i) < 0)
- return i;
-
- midiNodeIds.add (-1);
- return midiNodeIds.size() - 1;
- }
- else
- {
- for (int i = 1; i < nodeIds.size(); ++i)
- if (nodeIds.getUnchecked(i) < 0)
- return i;
-
- nodeIds.add (-1);
- channels.add (0);
- return nodeIds.size() - 1;
- }
- }
-
- int getReadOnlyEmptyBuffer() const throw()
- {
- return 0;
- }
-
- int getBufferContaining (const int nodeId, const int outputChannel) const throw()
- {
- if (outputChannel == AudioProcessorGraph::midiChannelIndex)
- {
- for (int i = midiNodeIds.size(); --i >= 0;)
- if (midiNodeIds.getUnchecked(i) == nodeId)
- return i;
- }
- else
- {
- for (int i = nodeIds.size(); --i >= 0;)
- if (nodeIds.getUnchecked(i) == nodeId
- && channels.getUnchecked(i) == outputChannel)
- return i;
- }
-
- return -1;
- }
-
- void markAnyUnusedBuffersAsFree (const int stepIndex)
- {
- int i;
- for (i = 0; i < nodeIds.size(); ++i)
- {
- if (nodeIds.getUnchecked(i) >= 0
- && ! isBufferNeededLater (stepIndex, -1,
- nodeIds.getUnchecked(i),
- channels.getUnchecked(i)))
- {
- nodeIds.set (i, -1);
- }
- }
-
- for (i = 0; i < midiNodeIds.size(); ++i)
- {
- if (midiNodeIds.getUnchecked(i) >= 0
- && ! isBufferNeededLater (stepIndex, -1,
- midiNodeIds.getUnchecked(i),
- AudioProcessorGraph::midiChannelIndex))
- {
- midiNodeIds.set (i, -1);
- }
- }
- }
-
- bool isBufferNeededLater (int stepIndexToSearchFrom,
- int inputChannelOfIndexToIgnore,
- const int nodeId,
- const int outputChanIndex) const throw()
- {
- while (stepIndexToSearchFrom < orderedNodes.size())
- {
- const AudioProcessorGraph::Node* const node = (const AudioProcessorGraph::Node*) orderedNodes.getUnchecked (stepIndexToSearchFrom);
-
- if (outputChanIndex == AudioProcessorGraph::midiChannelIndex)
- {
- if (inputChannelOfIndexToIgnore != AudioProcessorGraph::midiChannelIndex
- && graph.getConnectionBetween (nodeId, AudioProcessorGraph::midiChannelIndex,
- node->id, AudioProcessorGraph::midiChannelIndex) != 0)
- return true;
- }
- else
- {
- for (int i = 0; i < node->processor->getNumInputChannels(); ++i)
- if (i != inputChannelOfIndexToIgnore
- && graph.getConnectionBetween (nodeId, outputChanIndex,
- node->id, i) != 0)
- return true;
- }
-
- inputChannelOfIndexToIgnore = -1;
- ++stepIndexToSearchFrom;
- }
-
- return false;
- }
-
- void markBufferAsContaining (int bufferNum, int nodeId, int outputIndex)
- {
- if (outputIndex == AudioProcessorGraph::midiChannelIndex)
- {
- jassert (bufferNum > 0 && bufferNum < midiNodeIds.size());
-
- midiNodeIds.set (bufferNum, nodeId);
- }
- else
- {
- jassert (bufferNum >= 0 && bufferNum < nodeIds.size());
-
- nodeIds.set (bufferNum, nodeId);
- channels.set (bufferNum, outputIndex);
- }
- }
-
- RenderingOpSequenceCalculator (const RenderingOpSequenceCalculator&);
- const RenderingOpSequenceCalculator& operator= (const RenderingOpSequenceCalculator&);
- };
-
- }
-
- void AudioProcessorGraph::clearRenderingSequence()
- {
- const ScopedLock sl (renderLock);
-
- for (int i = renderingOps.size(); --i >= 0;)
- {
- GraphRenderingOps::AudioGraphRenderingOp* const r
- = (GraphRenderingOps::AudioGraphRenderingOp*) renderingOps.getUnchecked(i);
-
- renderingOps.remove (i);
- delete r;
- }
- }
-
- bool AudioProcessorGraph::isAnInputTo (const uint32 possibleInputId,
- const uint32 possibleDestinationId,
- const int recursionCheck) const throw()
- {
- if (recursionCheck > 0)
- {
- for (int i = connections.size(); --i >= 0;)
- {
- const AudioProcessorGraph::Connection* const c = connections.getUnchecked (i);
-
- if (c->destNodeId == possibleDestinationId
- && (c->sourceNodeId == possibleInputId
- || isAnInputTo (possibleInputId, c->sourceNodeId, recursionCheck - 1)))
- return true;
- }
- }
-
- return false;
- }
-
- void AudioProcessorGraph::buildRenderingSequence()
- {
- VoidArray newRenderingOps;
- int numRenderingBuffersNeeded = 2;
- int numMidiBuffersNeeded = 1;
-
- {
- MessageManagerLock mml;
-
- VoidArray orderedNodes;
-
- int i;
- for (i = 0; i < nodes.size(); ++i)
- {
- Node* const node = nodes.getUnchecked(i);
-
- node->prepare (getSampleRate(), getBlockSize(), this);
-
- int j = 0;
- for (; j < orderedNodes.size(); ++j)
- if (isAnInputTo (node->id,
- ((Node*) orderedNodes.getUnchecked (j))->id,
- nodes.size() + 1))
- break;
-
- orderedNodes.insert (j, node);
- }
-
- GraphRenderingOps::RenderingOpSequenceCalculator calculator (*this, orderedNodes, newRenderingOps);
-
- numRenderingBuffersNeeded = calculator.getNumBuffersNeeded();
- numMidiBuffersNeeded = calculator.getNumMidiBuffersNeeded();
- }
-
- VoidArray oldRenderingOps (renderingOps);
-
- {
- // swap over to the new rendering sequence..
- const ScopedLock sl (renderLock);
-
- renderingBuffers.setSize (numRenderingBuffersNeeded, getBlockSize());
- renderingBuffers.clear();
-
- for (int i = midiBuffers.size(); --i >= 0;)
- midiBuffers.getUnchecked(i)->clear();
-
- while (midiBuffers.size() < numMidiBuffersNeeded)
- midiBuffers.add (new MidiBuffer());
-
- renderingOps = newRenderingOps;
- }
-
- for (int i = oldRenderingOps.size(); --i >= 0;)
- delete (GraphRenderingOps::AudioGraphRenderingOp*) oldRenderingOps.getUnchecked(i);
- }
-
- void AudioProcessorGraph::handleAsyncUpdate()
- {
- buildRenderingSequence();
- }
-
- void AudioProcessorGraph::prepareToPlay (double /*sampleRate*/, int estimatedSamplesPerBlock)
- {
- currentAudioInputBuffer = 0;
- currentAudioOutputBuffer.setSize (jmax (1, getNumOutputChannels()), estimatedSamplesPerBlock);
- currentMidiInputBuffer = 0;
- currentMidiOutputBuffer.clear();
-
- clearRenderingSequence();
- buildRenderingSequence();
- }
-
- void AudioProcessorGraph::releaseResources()
- {
- for (int i = 0; i < nodes.size(); ++i)
- nodes.getUnchecked(i)->unprepare();
-
- renderingBuffers.setSize (1, 1);
- midiBuffers.clear();
-
- currentAudioInputBuffer = 0;
- currentAudioOutputBuffer.setSize (1, 1);
- currentMidiInputBuffer = 0;
- currentMidiOutputBuffer.clear();
- }
-
- void AudioProcessorGraph::processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages)
- {
- const int numSamples = buffer.getNumSamples();
-
- const ScopedLock sl (renderLock);
-
- currentAudioInputBuffer = &buffer;
- currentAudioOutputBuffer.setSize (jmax (1, buffer.getNumChannels()), numSamples);
- currentAudioOutputBuffer.clear();
- currentMidiInputBuffer = &midiMessages;
- currentMidiOutputBuffer.clear();
-
- int i;
- for (i = 0; i < renderingOps.size(); ++i)
- {
- GraphRenderingOps::AudioGraphRenderingOp* const op
- = (GraphRenderingOps::AudioGraphRenderingOp*) renderingOps.getUnchecked(i);
-
- op->perform (renderingBuffers, midiBuffers, numSamples);
- }
-
- for (i = 0; i < buffer.getNumChannels(); ++i)
- buffer.copyFrom (i, 0, currentAudioOutputBuffer, i, 0, numSamples);
- }
-
- const String AudioProcessorGraph::getInputChannelName (const int channelIndex) const
- {
- return "Input " + String (channelIndex + 1);
- }
-
- const String AudioProcessorGraph::getOutputChannelName (const int channelIndex) const
- {
- return "Output " + String (channelIndex + 1);
- }
-
- bool AudioProcessorGraph::isInputChannelStereoPair (int /*index*/) const
- {
- return true;
- }
-
- bool AudioProcessorGraph::isOutputChannelStereoPair (int /*index*/) const
- {
- return true;
- }
-
- bool AudioProcessorGraph::acceptsMidi() const
- {
- return true;
- }
-
- bool AudioProcessorGraph::producesMidi() const
- {
- return true;
- }
-
- void AudioProcessorGraph::getStateInformation (JUCE_NAMESPACE::MemoryBlock& /*destData*/)
- {
- }
-
- void AudioProcessorGraph::setStateInformation (const void* /*data*/, int /*sizeInBytes*/)
- {
- }
-
- AudioProcessorGraph::AudioGraphIOProcessor::AudioGraphIOProcessor (const IODeviceType type_)
- : type (type_),
- graph (0)
- {
- }
-
- AudioProcessorGraph::AudioGraphIOProcessor::~AudioGraphIOProcessor()
- {
- }
-
- const String AudioProcessorGraph::AudioGraphIOProcessor::getName() const
- {
- switch (type)
- {
- case audioOutputNode:
- return "Audio Output";
- case audioInputNode:
- return "Audio Input";
- case midiOutputNode:
- return "Midi Output";
- case midiInputNode:
- return "Midi Input";
- default:
- break;
- }
-
- return String::empty;
- }
-
- void AudioProcessorGraph::AudioGraphIOProcessor::fillInPluginDescription (PluginDescription& d) const
- {
- d.name = getName();
- d.uid = d.name.hashCode();
- d.category = "I/O devices";
- d.pluginFormatName = "Internal";
- d.manufacturerName = "Raw Material Software";
- d.version = "1.0";
- d.isInstrument = false;
-
- d.numInputChannels = getNumInputChannels();
- if (type == audioOutputNode && graph != 0)
- d.numInputChannels = graph->getNumInputChannels();
-
- d.numOutputChannels = getNumOutputChannels();
- if (type == audioInputNode && graph != 0)
- d.numOutputChannels = graph->getNumOutputChannels();
- }
-
- void AudioProcessorGraph::AudioGraphIOProcessor::prepareToPlay (double, int)
- {
- jassert (graph != 0);
- }
-
- void AudioProcessorGraph::AudioGraphIOProcessor::releaseResources()
- {
- }
-
- void AudioProcessorGraph::AudioGraphIOProcessor::processBlock (AudioSampleBuffer& buffer,
- MidiBuffer& midiMessages)
- {
- jassert (graph != 0);
-
- switch (type)
- {
- case audioOutputNode:
- {
- for (int i = jmin (graph->currentAudioOutputBuffer.getNumChannels(),
- buffer.getNumChannels()); --i >= 0;)
- {
- graph->currentAudioOutputBuffer.addFrom (i, 0, buffer, i, 0, buffer.getNumSamples());
- }
-
- break;
- }
-
- case audioInputNode:
- {
- for (int i = jmin (graph->currentAudioInputBuffer->getNumChannels(),
- buffer.getNumChannels()); --i >= 0;)
- {
- buffer.copyFrom (i, 0, *graph->currentAudioInputBuffer, i, 0, buffer.getNumSamples());
- }
-
- break;
- }
-
- case midiOutputNode:
- graph->currentMidiOutputBuffer.addEvents (midiMessages, 0, buffer.getNumSamples(), 0);
- break;
-
- case midiInputNode:
- midiMessages.addEvents (*graph->currentMidiInputBuffer, 0, buffer.getNumSamples(), 0);
- break;
-
- default:
- break;
- }
- }
-
- bool AudioProcessorGraph::AudioGraphIOProcessor::acceptsMidi() const
- {
- return type == midiOutputNode;
- }
-
- bool AudioProcessorGraph::AudioGraphIOProcessor::producesMidi() const
- {
- return type == midiInputNode;
- }
-
- const String AudioProcessorGraph::AudioGraphIOProcessor::getInputChannelName (const int channelIndex) const
- {
- switch (type)
- {
- case audioOutputNode:
- return "Output " + String (channelIndex + 1);
- case midiOutputNode:
- return "Midi Output";
- default:
- break;
- }
-
- return String::empty;
- }
-
- const String AudioProcessorGraph::AudioGraphIOProcessor::getOutputChannelName (const int channelIndex) const
- {
- switch (type)
- {
- case audioInputNode:
- return "Input " + String (channelIndex + 1);
- case midiInputNode:
- return "Midi Input";
- default:
- break;
- }
-
- return String::empty;
- }
-
- bool AudioProcessorGraph::AudioGraphIOProcessor::isInputChannelStereoPair (int /*index*/) const
- {
- return type == audioInputNode || type == audioOutputNode;
- }
-
- bool AudioProcessorGraph::AudioGraphIOProcessor::isOutputChannelStereoPair (int index) const
- {
- return isInputChannelStereoPair (index);
- }
-
- bool AudioProcessorGraph::AudioGraphIOProcessor::isInput() const throw()
- {
- return type == audioInputNode || type == midiInputNode;
- }
-
- bool AudioProcessorGraph::AudioGraphIOProcessor::isOutput() const throw()
- {
- return type == audioOutputNode || type == midiOutputNode;
- }
-
- AudioProcessorEditor* AudioProcessorGraph::AudioGraphIOProcessor::createEditor()
- {
- return 0;
- }
-
- int AudioProcessorGraph::AudioGraphIOProcessor::getNumParameters() { return 0; }
- const String AudioProcessorGraph::AudioGraphIOProcessor::getParameterName (int) { return String::empty; }
-
- float AudioProcessorGraph::AudioGraphIOProcessor::getParameter (int) { return 0.0f; }
- const String AudioProcessorGraph::AudioGraphIOProcessor::getParameterText (int) { return String::empty; }
- void AudioProcessorGraph::AudioGraphIOProcessor::setParameter (int, float) { }
-
- int AudioProcessorGraph::AudioGraphIOProcessor::getNumPrograms() { return 0; }
- int AudioProcessorGraph::AudioGraphIOProcessor::getCurrentProgram() { return 0; }
- void AudioProcessorGraph::AudioGraphIOProcessor::setCurrentProgram (int) { }
-
- const String AudioProcessorGraph::AudioGraphIOProcessor::getProgramName (int) { return String::empty; }
- void AudioProcessorGraph::AudioGraphIOProcessor::changeProgramName (int, const String&) { }
-
- void AudioProcessorGraph::AudioGraphIOProcessor::getStateInformation (JUCE_NAMESPACE::MemoryBlock&)
- {
- }
-
- void AudioProcessorGraph::AudioGraphIOProcessor::setStateInformation (const void*, int)
- {
- }
-
- void AudioProcessorGraph::AudioGraphIOProcessor::setParentGraph (AudioProcessorGraph* const newGraph) throw()
- {
- graph = newGraph;
-
- if (graph != 0)
- {
- setPlayConfigDetails (type == audioOutputNode ? graph->getNumOutputChannels() : 0,
- type == audioInputNode ? graph->getNumInputChannels() : 0,
- getSampleRate(),
- getBlockSize());
-
- updateHostDisplay();
- }
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_AudioProcessorGraph.cpp *********/
-
- /********* Start of inlined file: juce_AudioProcessorPlayer.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- AudioProcessorPlayer::AudioProcessorPlayer()
- : processor (0),
- sampleRate (0),
- blockSize (0),
- isPrepared (false),
- numInputChans (0),
- numOutputChans (0),
- tempBuffer (1, 1)
- {
- }
-
- AudioProcessorPlayer::~AudioProcessorPlayer()
- {
- setProcessor (0);
- }
-
- void AudioProcessorPlayer::setProcessor (AudioProcessor* const processorToPlay)
- {
- if (processor != processorToPlay)
- {
- if (processorToPlay != 0 && sampleRate > 0 && blockSize > 0)
- {
- processorToPlay->setPlayConfigDetails (numInputChans, numOutputChans,
- sampleRate, blockSize);
-
- processorToPlay->prepareToPlay (sampleRate, blockSize);
- }
-
- lock.enter();
- AudioProcessor* const oldOne = isPrepared ? processor : 0;
- processor = processorToPlay;
- isPrepared = true;
- lock.exit();
-
- if (oldOne != 0)
- oldOne->releaseResources();
- }
- }
-
- void AudioProcessorPlayer::audioDeviceIOCallback (const float** inputChannelData,
- int numInputChannels,
- float** outputChannelData,
- int numOutputChannels,
- int numSamples)
- {
- // these should have been prepared by audioDeviceAboutToStart()...
- jassert (sampleRate > 0 && blockSize > 0);
-
- incomingMidi.clear();
- messageCollector.removeNextBlockOfMessages (incomingMidi, numSamples);
- int i, totalNumChans = 0;
-
- if (numInputChannels > numOutputChannels)
- {
- // if there aren't enough output channels for the number of
- // inputs, we need to create some temporary extra ones (can't
- // use the input data in case it gets written to)
- tempBuffer.setSize (numInputChannels - numOutputChannels, numSamples,
- false, false, true);
-
- for (i = 0; i < numOutputChannels; ++i)
- {
- channels[totalNumChans] = outputChannelData[i];
- memcpy (channels[totalNumChans], inputChannelData[i], sizeof (float) * numSamples);
- ++totalNumChans;
- }
-
- for (i = numOutputChannels; i < numInputChannels; ++i)
- {
- channels[totalNumChans] = tempBuffer.getSampleData (i - numOutputChannels, 0);
- memcpy (channels[totalNumChans], inputChannelData[i], sizeof (float) * numSamples);
- ++totalNumChans;
- }
- }
- else
- {
- for (i = 0; i < numInputChannels; ++i)
- {
- channels[totalNumChans] = outputChannelData[i];
- memcpy (channels[totalNumChans], inputChannelData[i], sizeof (float) * numSamples);
- ++totalNumChans;
- }
-
- for (i = numInputChannels; i < numOutputChannels; ++i)
- {
- channels[totalNumChans] = outputChannelData[i];
- zeromem (channels[totalNumChans], sizeof (float) * numSamples);
- ++totalNumChans;
- }
- }
-
- AudioSampleBuffer buffer (channels, totalNumChans, numSamples);
-
- const ScopedLock sl (lock);
-
- if (processor != 0)
- processor->processBlock (buffer, incomingMidi);
- }
-
- void AudioProcessorPlayer::audioDeviceAboutToStart (AudioIODevice* device)
- {
- const ScopedLock sl (lock);
-
- sampleRate = device->getCurrentSampleRate();
- blockSize = device->getCurrentBufferSizeSamples();
- numInputChans = device->getActiveInputChannels().countNumberOfSetBits();
- numOutputChans = device->getActiveOutputChannels().countNumberOfSetBits();
-
- messageCollector.reset (sampleRate);
- zeromem (channels, sizeof (channels));
-
- if (processor != 0)
- {
- if (isPrepared)
- processor->releaseResources();
-
- AudioProcessor* const oldProcessor = processor;
- setProcessor (0);
- setProcessor (oldProcessor);
- }
- }
-
- void AudioProcessorPlayer::audioDeviceStopped()
- {
- const ScopedLock sl (lock);
-
- if (processor != 0 && isPrepared)
- processor->releaseResources();
-
- sampleRate = 0.0;
- blockSize = 0;
- isPrepared = false;
- tempBuffer.setSize (1, 1);
- }
-
- void AudioProcessorPlayer::handleIncomingMidiMessage (MidiInput*, const MidiMessage& message)
- {
- messageCollector.addMessageToQueue (message);
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_AudioProcessorPlayer.cpp *********/
-
- /********* Start of inlined file: juce_GenericAudioProcessorEditor.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- class ProcessorParameterPropertyComp : public PropertyComponent,
- public AudioProcessorListener,
- public AsyncUpdater
- {
- public:
- ProcessorParameterPropertyComp (const String& name,
- AudioProcessor* const owner_,
- const int index_)
- : PropertyComponent (name),
- owner (owner_),
- index (index_)
- {
- addAndMakeVisible (slider = new ParamSlider (owner_, index_));
- owner_->addListener (this);
- }
-
- ~ProcessorParameterPropertyComp()
- {
- owner->removeListener (this);
- deleteAllChildren();
- }
-
- void refresh()
- {
- slider->setValue (owner->getParameter (index), false);
- }
-
- void audioProcessorChanged (AudioProcessor*) {}
-
- void audioProcessorParameterChanged (AudioProcessor*, int parameterIndex, float)
- {
- if (parameterIndex == index)
- triggerAsyncUpdate();
- }
-
- void handleAsyncUpdate()
- {
- refresh();
- }
-
- juce_UseDebuggingNewOperator
-
- private:
- AudioProcessor* const owner;
- const int index;
- Slider* slider;
-
- class ParamSlider : public Slider
- {
- public:
- ParamSlider (AudioProcessor* const owner_, const int index_)
- : Slider (String::empty),
- owner (owner_),
- index (index_)
- {
- setRange (0.0, 1.0, 0.0);
- setSliderStyle (Slider::LinearBar);
- setTextBoxIsEditable (false);
- setScrollWheelEnabled (false);
- }
-
- ~ParamSlider()
- {
- }
-
- void valueChanged()
- {
- const float newVal = (float) getValue();
-
- if (owner->getParameter (index) != newVal)
- owner->setParameter (index, newVal);
- }
-
- const String getTextFromValue (double /*value*/)
- {
- return owner->getParameterText (index);
- }
-
- juce_UseDebuggingNewOperator
-
- private:
- AudioProcessor* const owner;
- const int index;
- };
- };
-
- GenericAudioProcessorEditor::GenericAudioProcessorEditor (AudioProcessor* const owner)
- : AudioProcessorEditor (owner)
- {
- setOpaque (true);
-
- addAndMakeVisible (panel = new PropertyPanel());
-
- Array <PropertyComponent*> params;
-
- const int numParams = owner->getNumParameters();
- int totalHeight = 0;
-
- for (int i = 0; i < numParams; ++i)
- {
- String name (owner->getParameterName (i));
- if (name.trim().isEmpty())
- name = "Unnamed";
-
- ProcessorParameterPropertyComp* const pc = new ProcessorParameterPropertyComp (name, owner, i);
- params.add (pc);
- totalHeight += pc->getPreferredHeight();
- }
-
- panel->addProperties (params);
-
- setSize (400, jlimit (25, 400, totalHeight));
- }
-
- GenericAudioProcessorEditor::~GenericAudioProcessorEditor()
- {
- deleteAllChildren();
- }
-
- void GenericAudioProcessorEditor::paint (Graphics& g)
- {
- g.fillAll (Colours::white);
- }
-
- void GenericAudioProcessorEditor::resized()
- {
- panel->setSize (getWidth(), getHeight());
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_GenericAudioProcessorEditor.cpp *********/
-
- /********* Start of inlined file: juce_Sampler.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- SamplerSound::SamplerSound (const String& name_,
- AudioFormatReader& source,
- const BitArray& midiNotes_,
- const int midiNoteForNormalPitch,
- const double attackTimeSecs,
- const double releaseTimeSecs,
- const double maxSampleLengthSeconds)
- : name (name_),
- midiNotes (midiNotes_),
- midiRootNote (midiNoteForNormalPitch)
- {
- sourceSampleRate = source.sampleRate;
-
- if (sourceSampleRate <= 0 || source.lengthInSamples <= 0)
- {
- data = 0;
- length = 0;
- attackSamples = 0;
- releaseSamples = 0;
- }
- else
- {
- length = jmin ((int) source.lengthInSamples,
- (int) (maxSampleLengthSeconds * sourceSampleRate));
-
- data = new AudioSampleBuffer (jmin (2, source.numChannels), length + 4);
-
- data->readFromAudioReader (&source, 0, length + 4, 0, true, true);
-
- attackSamples = roundDoubleToInt (attackTimeSecs * sourceSampleRate);
- releaseSamples = roundDoubleToInt (releaseTimeSecs * sourceSampleRate);
- }
- }
-
- SamplerSound::~SamplerSound()
- {
- delete data;
- data = 0;
- }
-
- bool SamplerSound::appliesToNote (const int midiNoteNumber)
- {
- return midiNotes [midiNoteNumber];
- }
-
- bool SamplerSound::appliesToChannel (const int /*midiChannel*/)
- {
- return true;
- }
-
- SamplerVoice::SamplerVoice()
- : pitchRatio (0.0),
- sourceSamplePosition (0.0),
- lgain (0.0f),
- rgain (0.0f),
- isInAttack (false),
- isInRelease (false)
- {
- }
-
- SamplerVoice::~SamplerVoice()
- {
- }
-
- bool SamplerVoice::canPlaySound (SynthesiserSound* sound)
- {
- return dynamic_cast <const SamplerSound*> (sound) != 0;
- }
-
- void SamplerVoice::startNote (const int midiNoteNumber,
- const float velocity,
- SynthesiserSound* s,
- const int /*currentPitchWheelPosition*/)
- {
- const SamplerSound* const sound = dynamic_cast <const SamplerSound*> (s);
- jassert (sound != 0); // this object can only play SamplerSounds!
-
- if (sound != 0)
- {
- const double targetFreq = MidiMessage::getMidiNoteInHertz (midiNoteNumber);
- const double naturalFreq = MidiMessage::getMidiNoteInHertz (sound->midiRootNote);
-
- pitchRatio = (targetFreq * sound->sourceSampleRate) / (naturalFreq * getSampleRate());
-
- sourceSamplePosition = 0.0;
- lgain = velocity;
- rgain = velocity;
-
- isInAttack = (sound->attackSamples > 0);
- isInRelease = false;
-
- if (isInAttack)
- {
- attackReleaseLevel = 0.0f;
- attackDelta = (float) (pitchRatio / sound->attackSamples);
- }
- else
- {
- attackReleaseLevel = 1.0f;
- attackDelta = 0.0f;
- }
-
- if (sound->releaseSamples > 0)
- {
- releaseDelta = (float) (-pitchRatio / sound->releaseSamples);
- }
- else
- {
- releaseDelta = 0.0f;
- }
- }
- }
-
- void SamplerVoice::stopNote (const bool allowTailOff)
- {
- if (allowTailOff)
- {
- isInAttack = false;
- isInRelease = true;
- }
- else
- {
- clearCurrentNote();
- }
- }
-
- void SamplerVoice::pitchWheelMoved (const int /*newValue*/)
- {
- }
-
- void SamplerVoice::controllerMoved (const int /*controllerNumber*/,
- const int /*newValue*/)
- {
- }
-
- void SamplerVoice::renderNextBlock (AudioSampleBuffer& outputBuffer, int startSample, int numSamples)
- {
- const SamplerSound* const playingSound = (SamplerSound*) (SynthesiserSound*) getCurrentlyPlayingSound();
-
- if (playingSound != 0)
- {
- const float* const inL = playingSound->data->getSampleData (0, 0);
- const float* const inR = playingSound->data->getNumChannels() > 1
- ? playingSound->data->getSampleData (1, 0) : 0;
-
- float* outL = outputBuffer.getSampleData (0, startSample);
- float* outR = outputBuffer.getNumChannels() > 1 ? outputBuffer.getSampleData (1, startSample) : 0;
-
- while (--numSamples >= 0)
- {
- const int pos = (int) sourceSamplePosition;
- const float alpha = (float) (sourceSamplePosition - pos);
- const float invAlpha = 1.0f - alpha;
-
- // just using a very simple linear interpolation here..
- float l = (inL [pos] * invAlpha + inL [pos + 1] * alpha);
- float r = (inR != 0) ? (inR [pos] * invAlpha + inR [pos + 1] * alpha)
- : l;
-
- l *= lgain;
- r *= rgain;
-
- if (isInAttack)
- {
- l *= attackReleaseLevel;
- r *= attackReleaseLevel;
-
- attackReleaseLevel += attackDelta;
-
- if (attackReleaseLevel >= 1.0f)
- {
- attackReleaseLevel = 1.0f;
- isInAttack = false;
- }
- }
- else if (isInRelease)
- {
- l *= attackReleaseLevel;
- r *= attackReleaseLevel;
-
- attackReleaseLevel += releaseDelta;
-
- if (attackReleaseLevel <= 0.0f)
- {
- stopNote (false);
- break;
- }
- }
-
- if (outR != 0)
- {
- *outL++ += l;
- *outR++ += r;
- }
- else
- {
- *outL++ += (l + r) * 0.5f;
- }
-
- sourceSamplePosition += pitchRatio;
-
- if (sourceSamplePosition > playingSound->length)
- {
- stopNote (false);
- break;
- }
- }
- }
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_Sampler.cpp *********/
-
- /********* Start of inlined file: juce_Synthesiser.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- SynthesiserSound::SynthesiserSound()
- {
- }
-
- SynthesiserSound::~SynthesiserSound()
- {
- }
-
- SynthesiserVoice::SynthesiserVoice()
- : currentSampleRate (44100.0),
- currentlyPlayingNote (-1),
- noteOnTime (0),
- currentlyPlayingSound (0)
- {
- }
-
- SynthesiserVoice::~SynthesiserVoice()
- {
- }
-
- bool SynthesiserVoice::isPlayingChannel (const int midiChannel) const
- {
- return currentlyPlayingSound != 0
- && currentlyPlayingSound->appliesToChannel (midiChannel);
- }
-
- void SynthesiserVoice::setCurrentPlaybackSampleRate (const double newRate)
- {
- currentSampleRate = newRate;
- }
-
- void SynthesiserVoice::clearCurrentNote()
- {
- currentlyPlayingNote = -1;
- currentlyPlayingSound = 0;
- }
-
- Synthesiser::Synthesiser()
- : voices (2),
- sounds (2),
- sampleRate (0),
- lastNoteOnCounter (0),
- shouldStealNotes (true)
- {
- zeromem (lastPitchWheelValues, sizeof (lastPitchWheelValues));
- }
-
- Synthesiser::~Synthesiser()
- {
- }
-
- SynthesiserVoice* Synthesiser::getVoice (const int index) const throw()
- {
- const ScopedLock sl (lock);
- return voices [index];
- }
-
- void Synthesiser::clearVoices()
- {
- const ScopedLock sl (lock);
- voices.clear();
- }
-
- void Synthesiser::addVoice (SynthesiserVoice* const newVoice)
- {
- const ScopedLock sl (lock);
- voices.add (newVoice);
- }
-
- void Synthesiser::removeVoice (const int index)
- {
- const ScopedLock sl (lock);
- voices.remove (index);
- }
-
- void Synthesiser::clearSounds()
- {
- const ScopedLock sl (lock);
- sounds.clear();
- }
-
- void Synthesiser::addSound (const SynthesiserSound::Ptr& newSound)
- {
- const ScopedLock sl (lock);
- sounds.add (newSound);
- }
-
- void Synthesiser::removeSound (const int index)
- {
- const ScopedLock sl (lock);
- sounds.remove (index);
- }
-
- void Synthesiser::setNoteStealingEnabled (const bool shouldStealNotes_)
- {
- shouldStealNotes = shouldStealNotes_;
- }
-
- void Synthesiser::setCurrentPlaybackSampleRate (const double newRate)
- {
- if (sampleRate != newRate)
- {
- const ScopedLock sl (lock);
-
- allNotesOff (0, false);
-
- sampleRate = newRate;
-
- for (int i = voices.size(); --i >= 0;)
- voices.getUnchecked (i)->setCurrentPlaybackSampleRate (newRate);
- }
- }
-
- void Synthesiser::renderNextBlock (AudioSampleBuffer& outputBuffer,
- const MidiBuffer& midiData,
- int startSample,
- int numSamples)
- {
- // must set the sample rate before using this!
- jassert (sampleRate != 0);
-
- const ScopedLock sl (lock);
-
- MidiBuffer::Iterator midiIterator (midiData);
- midiIterator.setNextSamplePosition (startSample);
- MidiMessage m (0xf4, 0.0);
-
- while (numSamples > 0)
- {
- int midiEventPos;
- const bool useEvent = midiIterator.getNextEvent (m, midiEventPos)
- && midiEventPos < startSample + numSamples;
-
- const int numThisTime = useEvent ? midiEventPos - startSample
- : numSamples;
-
- if (numThisTime > 0)
- {
- for (int i = voices.size(); --i >= 0;)
- voices.getUnchecked (i)->renderNextBlock (outputBuffer, startSample, numThisTime);
- }
-
- if (useEvent)
- {
- if (m.isNoteOn())
- {
- const int channel = m.getChannel();
-
- noteOn (channel,
- m.getNoteNumber(),
- m.getFloatVelocity());
- }
- else if (m.isNoteOff())
- {
- noteOff (m.getChannel(),
- m.getNoteNumber(),
- true);
- }
- else if (m.isAllNotesOff() || m.isAllSoundOff())
- {
- allNotesOff (m.getChannel(), true);
- }
- else if (m.isPitchWheel())
- {
- const int channel = m.getChannel();
- const int wheelPos = m.getPitchWheelValue();
- lastPitchWheelValues [channel - 1] = wheelPos;
-
- handlePitchWheel (channel, wheelPos);
- }
- else if (m.isController())
- {
- handleController (m.getChannel(),
- m.getControllerNumber(),
- m.getControllerValue());
- }
- }
-
- startSample += numThisTime;
- numSamples -= numThisTime;
- }
- }
-
- void Synthesiser::noteOn (const int midiChannel,
- const int midiNoteNumber,
- const float velocity)
- {
- const ScopedLock sl (lock);
-
- for (int i = sounds.size(); --i >= 0;)
- {
- SynthesiserSound* const sound = sounds.getUnchecked(i);
-
- if (sound->appliesToNote (midiNoteNumber)
- && sound->appliesToChannel (midiChannel))
- {
- startVoice (findFreeVoice (sound, shouldStealNotes),
- sound, midiChannel, midiNoteNumber, velocity);
- }
- }
- }
-
- void Synthesiser::startVoice (SynthesiserVoice* const voice,
- SynthesiserSound* const sound,
- const int midiChannel,
- const int midiNoteNumber,
- const float velocity)
- {
- if (voice != 0 && sound != 0)
- {
- if (voice->currentlyPlayingSound != 0)
- voice->stopNote (false);
-
- voice->startNote (midiNoteNumber,
- velocity,
- sound,
- lastPitchWheelValues [midiChannel - 1]);
-
- voice->currentlyPlayingNote = midiNoteNumber;
- voice->noteOnTime = ++lastNoteOnCounter;
- voice->currentlyPlayingSound = sound;
- }
- }
-
- void Synthesiser::noteOff (const int midiChannel,
- const int midiNoteNumber,
- const bool allowTailOff)
- {
- const ScopedLock sl (lock);
-
- for (int i = voices.size(); --i >= 0;)
- {
- SynthesiserVoice* const voice = voices.getUnchecked (i);
-
- if (voice->getCurrentlyPlayingNote() == midiNoteNumber)
- {
- SynthesiserSound* const sound = voice->getCurrentlyPlayingSound();
-
- if (sound != 0
- && sound->appliesToNote (midiNoteNumber)
- && sound->appliesToChannel (midiChannel))
- {
- voice->stopNote (allowTailOff);
-
- // the subclass MUST call clearCurrentNote() if it's not tailing off! RTFM for stopNote()!
- jassert (allowTailOff || (voice->getCurrentlyPlayingNote() < 0 && voice->getCurrentlyPlayingSound() == 0));
- }
- }
- }
- }
-
- void Synthesiser::allNotesOff (const int midiChannel,
- const bool allowTailOff)
- {
- const ScopedLock sl (lock);
-
- for (int i = voices.size(); --i >= 0;)
- {
- SynthesiserVoice* const voice = voices.getUnchecked (i);
-
- if (midiChannel <= 0 || voice->isPlayingChannel (midiChannel))
- voice->stopNote (allowTailOff);
- }
- }
-
- void Synthesiser::handlePitchWheel (const int midiChannel,
- const int wheelValue)
- {
- const ScopedLock sl (lock);
-
- for (int i = voices.size(); --i >= 0;)
- {
- SynthesiserVoice* const voice = voices.getUnchecked (i);
-
- if (midiChannel <= 0 || voice->isPlayingChannel (midiChannel))
- {
- voice->pitchWheelMoved (wheelValue);
- }
- }
- }
-
- void Synthesiser::handleController (const int midiChannel,
- const int controllerNumber,
- const int controllerValue)
- {
- const ScopedLock sl (lock);
-
- for (int i = voices.size(); --i >= 0;)
- {
- SynthesiserVoice* const voice = voices.getUnchecked (i);
-
- if (midiChannel <= 0 || voice->isPlayingChannel (midiChannel))
- voice->controllerMoved (controllerNumber, controllerValue);
- }
- }
-
- SynthesiserVoice* Synthesiser::findFreeVoice (SynthesiserSound* soundToPlay,
- const bool stealIfNoneAvailable) const
- {
- const ScopedLock sl (lock);
-
- for (int i = voices.size(); --i >= 0;)
- if (voices.getUnchecked (i)->getCurrentlyPlayingNote() < 0
- && voices.getUnchecked (i)->canPlaySound (soundToPlay))
- return voices.getUnchecked (i);
-
- if (stealIfNoneAvailable)
- {
- // currently this just steals the one that's been playing the longest, but could be made a bit smarter..
- SynthesiserVoice* oldest = 0;
-
- for (int i = voices.size(); --i >= 0;)
- {
- SynthesiserVoice* const voice = voices.getUnchecked (i);
-
- if (voice->canPlaySound (soundToPlay)
- && (oldest == 0 || oldest->noteOnTime > voice->noteOnTime))
- oldest = voice;
- }
-
- jassert (oldest != 0);
- return oldest;
- }
-
- return 0;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_Synthesiser.cpp *********/
-
- /********* Start of inlined file: juce_FileBasedDocument.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- FileBasedDocument::FileBasedDocument (const String& fileExtension_,
- const String& fileWildcard_,
- const String& openFileDialogTitle_,
- const String& saveFileDialogTitle_)
- : changedSinceSave (false),
- fileExtension (fileExtension_),
- fileWildcard (fileWildcard_),
- openFileDialogTitle (openFileDialogTitle_),
- saveFileDialogTitle (saveFileDialogTitle_)
- {
- }
-
- FileBasedDocument::~FileBasedDocument()
- {
- }
-
- void FileBasedDocument::setChangedFlag (const bool hasChanged)
- {
- changedSinceSave = hasChanged;
- }
-
- void FileBasedDocument::changed()
- {
- changedSinceSave = true;
- sendChangeMessage (this);
- }
-
- void FileBasedDocument::setFile (const File& newFile)
- {
- if (documentFile != newFile)
- {
- documentFile = newFile;
- changedSinceSave = true;
- }
- }
-
- bool FileBasedDocument::loadFrom (const File& newFile,
- const bool showMessageOnFailure)
- {
- MouseCursor::showWaitCursor();
-
- const File oldFile (documentFile);
- documentFile = newFile;
-
- String error;
-
- if (newFile.existsAsFile())
- {
- error = loadDocument (newFile);
-
- if (error.isEmpty())
- {
- setChangedFlag (false);
- MouseCursor::hideWaitCursor();
-
- setLastDocumentOpened (newFile);
- return true;
- }
- }
- else
- {
- error = "The file doesn't exist";
- }
-
- documentFile = oldFile;
- MouseCursor::hideWaitCursor();
-
- if (showMessageOnFailure)
- {
- AlertWindow::showMessageBox (AlertWindow::WarningIcon,
- TRANS("Failed to open file..."),
- TRANS("There was an error while trying to load the file:\n\n")
- + newFile.getFullPathName()
- + T("\n\n")
- + error);
- }
-
- return false;
- }
-
- bool FileBasedDocument::loadFromUserSpecifiedFile (const bool showMessageOnFailure)
- {
- FileChooser fc (openFileDialogTitle,
- getLastDocumentOpened(),
- fileWildcard);
-
- if (fc.browseForFileToOpen())
- return loadFrom (fc.getResult(), showMessageOnFailure);
-
- return false;
- }
-
- FileBasedDocument::SaveResult FileBasedDocument::save (const bool askUserForFileIfNotSpecified,
- const bool showMessageOnFailure)
- {
- return saveAs (documentFile,
- false,
- askUserForFileIfNotSpecified,
- showMessageOnFailure);
- }
-
- FileBasedDocument::SaveResult FileBasedDocument::saveAs (const File& newFile,
- const bool warnAboutOverwritingExistingFiles,
- const bool askUserForFileIfNotSpecified,
- const bool showMessageOnFailure)
- {
- if (newFile == File::nonexistent)
- {
- if (askUserForFileIfNotSpecified)
- {
- return saveAsInteractive (true);
- }
- else
- {
- // can't save to an unspecified file
- jassertfalse
- return failedToWriteToFile;
- }
- }
-
- if (warnAboutOverwritingExistingFiles && newFile.exists())
- {
- if (! AlertWindow::showOkCancelBox (AlertWindow::WarningIcon,
- TRANS("File already exists"),
- TRANS("There's already a file called:\n\n")
- + newFile.getFullPathName()
- + TRANS("\n\nAre you sure you want to overwrite it?"),
- TRANS("overwrite"),
- TRANS("cancel")))
- {
- return userCancelledSave;
- }
- }
-
- MouseCursor::showWaitCursor();
-
- const File oldFile (documentFile);
- documentFile = newFile;
-
- String error (saveDocument (newFile));
-
- if (error.isEmpty())
- {
- setChangedFlag (false);
- MouseCursor::hideWaitCursor();
-
- return savedOk;
- }
-
- documentFile = oldFile;
- MouseCursor::hideWaitCursor();
-
- if (showMessageOnFailure)
- {
- AlertWindow::showMessageBox (AlertWindow::WarningIcon,
- TRANS("Error writing to file..."),
- TRANS("An error occurred while trying to save \"")
- + getDocumentTitle()
- + TRANS("\" to the file:\n\n")
- + newFile.getFullPathName()
- + T("\n\n")
- + error);
- }
-
- return failedToWriteToFile;
- }
-
- FileBasedDocument::SaveResult FileBasedDocument::saveIfNeededAndUserAgrees()
- {
- if (! hasChangedSinceSaved())
- return savedOk;
-
- const int r = AlertWindow::showYesNoCancelBox (AlertWindow::QuestionIcon,
- TRANS("Closing document..."),
- TRANS("Do you want to save the changes to \"")
- + getDocumentTitle() + T("\"?"),
- TRANS("save"),
- TRANS("discard changes"),
- TRANS("cancel"));
-
- if (r == 1)
- {
- // save changes
- return save (true, true);
- }
- else if (r == 2)
- {
- // discard changes
- return savedOk;
- }
-
- return userCancelledSave;
- }
-
- FileBasedDocument::SaveResult FileBasedDocument::saveAsInteractive (const bool warnAboutOverwritingExistingFiles)
- {
- File f;
-
- if (documentFile.existsAsFile())
- f = documentFile;
- else
- f = getLastDocumentOpened();
-
- String legalFilename (File::createLegalFileName (getDocumentTitle()));
-
- if (legalFilename.isEmpty())
- legalFilename = "unnamed";
-
- if (f.existsAsFile() || f.getParentDirectory().isDirectory())
- f = f.getSiblingFile (legalFilename);
- else
- f = File::getSpecialLocation (File::userDocumentsDirectory).getChildFile (legalFilename);
-
- f = f.withFileExtension (fileExtension)
- .getNonexistentSibling (true);
-
- FileChooser fc (saveFileDialogTitle, f, fileWildcard);
-
- if (fc.browseForFileToSave (warnAboutOverwritingExistingFiles))
- {
- setLastDocumentOpened (fc.getResult());
-
- File chosen (fc.getResult());
- if (chosen.getFileExtension().isEmpty())
- chosen = chosen.withFileExtension (fileExtension);
-
- return saveAs (chosen, false, false, true);
- }
-
- return userCancelledSave;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_FileBasedDocument.cpp *********/
-
- /********* Start of inlined file: juce_RecentlyOpenedFilesList.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- RecentlyOpenedFilesList::RecentlyOpenedFilesList()
- : maxNumberOfItems (10)
- {
- }
-
- RecentlyOpenedFilesList::~RecentlyOpenedFilesList()
- {
- }
-
- void RecentlyOpenedFilesList::setMaxNumberOfItems (const int newMaxNumber)
- {
- maxNumberOfItems = jmax (1, newMaxNumber);
-
- while (getNumFiles() > maxNumberOfItems)
- files.remove (getNumFiles() - 1);
- }
-
- int RecentlyOpenedFilesList::getNumFiles() const
- {
- return files.size();
- }
-
- const File RecentlyOpenedFilesList::getFile (const int index) const
- {
- return File (files [index]);
- }
-
- void RecentlyOpenedFilesList::clear()
- {
- files.clear();
- }
-
- void RecentlyOpenedFilesList::addFile (const File& file)
- {
- const String path (file.getFullPathName());
-
- files.removeString (path, true);
- files.insert (0, path);
-
- setMaxNumberOfItems (maxNumberOfItems);
- }
-
- void RecentlyOpenedFilesList::removeNonExistentFiles()
- {
- for (int i = getNumFiles(); --i >= 0;)
- if (! getFile(i).exists())
- files.remove (i);
- }
-
- int RecentlyOpenedFilesList::createPopupMenuItems (PopupMenu& menuToAddTo,
- const int baseItemId,
- const bool showFullPaths,
- const bool dontAddNonExistentFiles,
- const File** filesToAvoid)
- {
- int num = 0;
-
- for (int i = 0; i < getNumFiles(); ++i)
- {
- const File f (getFile(i));
-
- if ((! dontAddNonExistentFiles) || f.exists())
- {
- bool needsAvoiding = false;
-
- if (filesToAvoid != 0)
- {
- const File** files = filesToAvoid;
-
- while (*files != 0)
- {
- if (f == **files)
- {
- needsAvoiding = true;
- break;
- }
-
- ++files;
- }
- }
-
- if (! needsAvoiding)
- {
- menuToAddTo.addItem (baseItemId + i,
- showFullPaths ? f.getFullPathName()
- : f.getFileName());
- ++num;
- }
- }
- }
-
- return num;
- }
-
- const String RecentlyOpenedFilesList::toString() const
- {
- return files.joinIntoString (T("\n"));
- }
-
- void RecentlyOpenedFilesList::restoreFromString (const String& stringifiedVersion)
- {
- clear();
- files.addLines (stringifiedVersion);
-
- setMaxNumberOfItems (maxNumberOfItems);
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_RecentlyOpenedFilesList.cpp *********/
-
- /********* Start of inlined file: juce_UndoManager.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- UndoManager::UndoManager (const int maxNumberOfUnitsToKeep,
- const int minimumTransactions)
- : totalUnitsStored (0),
- nextIndex (0),
- newTransaction (true),
- reentrancyCheck (false)
- {
- setMaxNumberOfStoredUnits (maxNumberOfUnitsToKeep,
- minimumTransactions);
- }
-
- UndoManager::~UndoManager()
- {
- clearUndoHistory();
- }
-
- void UndoManager::clearUndoHistory()
- {
- transactions.clear();
- transactionNames.clear();
- totalUnitsStored = 0;
- nextIndex = 0;
- sendChangeMessage (this);
- }
-
- int UndoManager::getNumberOfUnitsTakenUpByStoredCommands() const
- {
- return totalUnitsStored;
- }
-
- void UndoManager::setMaxNumberOfStoredUnits (const int maxNumberOfUnitsToKeep,
- const int minimumTransactions)
- {
- maxNumUnitsToKeep = jmax (1, maxNumberOfUnitsToKeep);
- minimumTransactionsToKeep = jmax (1, minimumTransactions);
- }
-
- bool UndoManager::perform (UndoableAction* const command, const String& actionName)
- {
- if (command != 0)
- {
- if (actionName.isNotEmpty())
- currentTransactionName = actionName;
-
- if (reentrancyCheck)
- {
- jassertfalse // don't call perform() recursively from the UndoableAction::perform() or
- // undo() methods, or else these actions won't actually get done.
-
- return false;
- }
- else
- {
- bool success = false;
-
- JUCE_TRY
- {
- success = command->perform();
- }
- JUCE_CATCH_EXCEPTION
-
- jassert (success);
- if (success)
- {
- if (nextIndex > 0 && ! newTransaction)
- {
- OwnedArray<UndoableAction>* commandSet = transactions [nextIndex - 1];
-
- jassert (commandSet != 0);
- if (commandSet == 0)
- return false;
-
- commandSet->add (command);
- }
- else
- {
- OwnedArray<UndoableAction>* commandSet = new OwnedArray<UndoableAction>();
- commandSet->add (command);
- transactions.insert (nextIndex, commandSet);
- transactionNames.insert (nextIndex, currentTransactionName);
- ++nextIndex;
- }
-
- totalUnitsStored += command->getSizeInUnits();
- newTransaction = false;
- }
-
- while (nextIndex < transactions.size())
- {
- const OwnedArray <UndoableAction>* const lastSet = transactions.getLast();
-
- for (int i = lastSet->size(); --i >= 0;)
- totalUnitsStored -= lastSet->getUnchecked (i)->getSizeInUnits();
-
- transactions.removeLast();
- transactionNames.remove (transactionNames.size() - 1);
- }
-
- while (nextIndex > 0
- && totalUnitsStored > maxNumUnitsToKeep
- && transactions.size() > minimumTransactionsToKeep)
- {
- const OwnedArray <UndoableAction>* const firstSet = transactions.getFirst();
-
- for (int i = firstSet->size(); --i >= 0;)
- totalUnitsStored -= firstSet->getUnchecked (i)->getSizeInUnits();
-
- jassert (totalUnitsStored >= 0); // something fishy going on if this fails!
-
- transactions.remove (0);
- transactionNames.remove (0);
- --nextIndex;
- }
-
- sendChangeMessage (this);
-
- return success;
- }
- }
-
- return false;
- }
-
- void UndoManager::beginNewTransaction (const String& actionName)
- {
- newTransaction = true;
- currentTransactionName = actionName;
- }
-
- void UndoManager::setCurrentTransactionName (const String& newName)
- {
- currentTransactionName = newName;
- }
-
- bool UndoManager::canUndo() const
- {
- return nextIndex > 0;
- }
-
- bool UndoManager::canRedo() const
- {
- return nextIndex < transactions.size();
- }
-
- const String UndoManager::getUndoDescription() const
- {
- return transactionNames [nextIndex - 1];
- }
-
- const String UndoManager::getRedoDescription() const
- {
- return transactionNames [nextIndex];
- }
-
- bool UndoManager::undo()
- {
- const OwnedArray<UndoableAction>* const commandSet = transactions [nextIndex - 1];
-
- if (commandSet == 0)
- return false;
-
- reentrancyCheck = true;
- bool failed = false;
-
- for (int i = commandSet->size(); --i >= 0;)
- {
- if (! commandSet->getUnchecked(i)->undo())
- {
- jassertfalse
- failed = true;
- break;
- }
- }
-
- reentrancyCheck = false;
-
- if (failed)
- {
- clearUndoHistory();
- }
- else
- {
- --nextIndex;
- }
-
- beginNewTransaction();
-
- sendChangeMessage (this);
- return true;
- }
-
- bool UndoManager::redo()
- {
- const OwnedArray<UndoableAction>* const commandSet = transactions [nextIndex];
-
- if (commandSet == 0)
- return false;
-
- reentrancyCheck = true;
- bool failed = false;
-
- for (int i = 0; i < commandSet->size(); ++i)
- {
- if (! commandSet->getUnchecked(i)->perform())
- {
- jassertfalse
- failed = true;
- break;
- }
- }
-
- reentrancyCheck = false;
-
- if (failed)
- {
- clearUndoHistory();
- }
- else
- {
- ++nextIndex;
- }
-
- beginNewTransaction();
-
- sendChangeMessage (this);
- return true;
- }
-
- bool UndoManager::undoCurrentTransactionOnly()
- {
- return newTransaction ? false
- : undo();
- }
-
- void UndoManager::getActionsInCurrentTransaction (Array <const UndoableAction*>& actionsFound) const
- {
- const OwnedArray <UndoableAction>* const commandSet = transactions [nextIndex - 1];
-
- if (commandSet != 0 && ! newTransaction)
- {
- for (int i = 0; i < commandSet->size(); ++i)
- actionsFound.add (commandSet->getUnchecked(i));
- }
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_UndoManager.cpp *********/
-
- /********* Start of inlined file: juce_ActionBroadcaster.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- ActionBroadcaster::ActionBroadcaster() throw()
- {
- // are you trying to create this object before or after juce has been intialised??
- jassert (MessageManager::instance != 0);
- }
-
- ActionBroadcaster::~ActionBroadcaster()
- {
- // all event-based objects must be deleted BEFORE juce is shut down!
- jassert (MessageManager::instance != 0);
- }
-
- void ActionBroadcaster::addActionListener (ActionListener* const listener)
- {
- actionListenerList.addActionListener (listener);
- }
-
- void ActionBroadcaster::removeActionListener (ActionListener* const listener)
- {
- jassert (actionListenerList.isValidMessageListener());
-
- if (actionListenerList.isValidMessageListener())
- actionListenerList.removeActionListener (listener);
- }
-
- void ActionBroadcaster::removeAllActionListeners()
- {
- actionListenerList.removeAllActionListeners();
- }
-
- void ActionBroadcaster::sendActionMessage (const String& message) const
- {
- actionListenerList.sendActionMessage (message);
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_ActionBroadcaster.cpp *********/
-
- /********* Start of inlined file: juce_ActionListenerList.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- // special message of our own with a string in it
- class ActionMessage : public Message
- {
- public:
- const String message;
-
- ActionMessage (const String& messageText,
- void* const listener_) throw()
- : message (messageText)
- {
- pointerParameter = listener_;
- }
-
- ~ActionMessage() throw()
- {
- }
-
- private:
- ActionMessage (const ActionMessage&);
- const ActionMessage& operator= (const ActionMessage&);
- };
-
- ActionListenerList::ActionListenerList() throw()
- {
- }
-
- ActionListenerList::~ActionListenerList() throw()
- {
- }
-
- void ActionListenerList::addActionListener (ActionListener* const listener) throw()
- {
- const ScopedLock sl (actionListenerLock_);
-
- jassert (listener != 0);
- jassert (! actionListeners_.contains (listener)); // trying to add a listener to the list twice!
-
- if (listener != 0)
- actionListeners_.add (listener);
- }
-
- void ActionListenerList::removeActionListener (ActionListener* const listener) throw()
- {
- const ScopedLock sl (actionListenerLock_);
-
- jassert (actionListeners_.contains (listener)); // trying to remove a listener that isn't on the list!
-
- actionListeners_.removeValue (listener);
- }
-
- void ActionListenerList::removeAllActionListeners() throw()
- {
- const ScopedLock sl (actionListenerLock_);
- actionListeners_.clear();
- }
-
- void ActionListenerList::sendActionMessage (const String& message) const
- {
- const ScopedLock sl (actionListenerLock_);
-
- for (int i = actionListeners_.size(); --i >= 0;)
- {
- postMessage (new ActionMessage (message,
- (ActionListener*) actionListeners_.getUnchecked(i)));
- }
- }
-
- void ActionListenerList::handleMessage (const Message& message)
- {
- const ActionMessage& am = (const ActionMessage&) message;
-
- if (actionListeners_.contains (am.pointerParameter))
- ((ActionListener*) am.pointerParameter)->actionListenerCallback (am.message);
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_ActionListenerList.cpp *********/
-
- /********* Start of inlined file: juce_AsyncUpdater.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- AsyncUpdater::AsyncUpdater() throw()
- : asyncMessagePending (false)
- {
- internalAsyncHandler.owner = this;
- }
-
- AsyncUpdater::~AsyncUpdater()
- {
- }
-
- void AsyncUpdater::triggerAsyncUpdate() throw()
- {
- if (! asyncMessagePending)
- {
- asyncMessagePending = true;
- internalAsyncHandler.postMessage (new Message());
- }
- }
-
- void AsyncUpdater::cancelPendingUpdate() throw()
- {
- asyncMessagePending = false;
- }
-
- void AsyncUpdater::handleUpdateNowIfNeeded()
- {
- if (asyncMessagePending)
- {
- asyncMessagePending = false;
- handleAsyncUpdate();
- }
- }
-
- void AsyncUpdater::AsyncUpdaterInternal::handleMessage (const Message&)
- {
- owner->handleUpdateNowIfNeeded();
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_AsyncUpdater.cpp *********/
-
- /********* Start of inlined file: juce_ChangeBroadcaster.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- ChangeBroadcaster::ChangeBroadcaster() throw()
- {
- // are you trying to create this object before or after juce has been intialised??
- jassert (MessageManager::instance != 0);
- }
-
- ChangeBroadcaster::~ChangeBroadcaster()
- {
- // all event-based objects must be deleted BEFORE juce is shut down!
- jassert (MessageManager::instance != 0);
- }
-
- void ChangeBroadcaster::addChangeListener (ChangeListener* const listener) throw()
- {
- changeListenerList.addChangeListener (listener);
- }
-
- void ChangeBroadcaster::removeChangeListener (ChangeListener* const listener) throw()
- {
- jassert (changeListenerList.isValidMessageListener());
-
- if (changeListenerList.isValidMessageListener())
- changeListenerList.removeChangeListener (listener);
- }
-
- void ChangeBroadcaster::removeAllChangeListeners() throw()
- {
- changeListenerList.removeAllChangeListeners();
- }
-
- void ChangeBroadcaster::sendChangeMessage (void* objectThatHasChanged) throw()
- {
- changeListenerList.sendChangeMessage (objectThatHasChanged);
- }
-
- void ChangeBroadcaster::sendSynchronousChangeMessage (void* objectThatHasChanged)
- {
- changeListenerList.sendSynchronousChangeMessage (objectThatHasChanged);
- }
-
- void ChangeBroadcaster::dispatchPendingMessages()
- {
- changeListenerList.dispatchPendingMessages();
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_ChangeBroadcaster.cpp *********/
-
- /********* Start of inlined file: juce_ChangeListenerList.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- ChangeListenerList::ChangeListenerList() throw()
- : lastChangedObject (0),
- messagePending (false)
- {
- }
-
- ChangeListenerList::~ChangeListenerList() throw()
- {
- }
-
- void ChangeListenerList::addChangeListener (ChangeListener* const listener) throw()
- {
- const ScopedLock sl (lock);
-
- jassert (listener != 0);
-
- if (listener != 0)
- listeners.add (listener);
- }
-
- void ChangeListenerList::removeChangeListener (ChangeListener* const listener) throw()
- {
- const ScopedLock sl (lock);
- listeners.removeValue (listener);
- }
-
- void ChangeListenerList::removeAllChangeListeners() throw()
- {
- const ScopedLock sl (lock);
- listeners.clear();
- }
-
- void ChangeListenerList::sendChangeMessage (void* const objectThatHasChanged) throw()
- {
- const ScopedLock sl (lock);
-
- if ((! messagePending) && (listeners.size() > 0))
- {
- lastChangedObject = objectThatHasChanged;
- postMessage (new Message (0, 0, 0, objectThatHasChanged));
- messagePending = true;
- }
- }
-
- void ChangeListenerList::handleMessage (const Message& message)
- {
- sendSynchronousChangeMessage (message.pointerParameter);
- }
-
- void ChangeListenerList::sendSynchronousChangeMessage (void* const objectThatHasChanged)
- {
- const ScopedLock sl (lock);
- messagePending = false;
-
- for (int i = listeners.size(); --i >= 0;)
- {
- ChangeListener* const l = (ChangeListener*) listeners.getUnchecked (i);
-
- {
- const ScopedUnlock tempUnlocker (lock);
- l->changeListenerCallback (objectThatHasChanged);
- }
-
- i = jmin (i, listeners.size());
- }
- }
-
- void ChangeListenerList::dispatchPendingMessages()
- {
- if (messagePending)
- sendSynchronousChangeMessage (lastChangedObject);
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_ChangeListenerList.cpp *********/
-
- /********* Start of inlined file: juce_InterprocessConnection.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- InterprocessConnection::InterprocessConnection (const bool callbacksOnMessageThread,
- const uint32 magicMessageHeaderNumber)
- : Thread ("Juce IPC connection"),
- socket (0),
- pipe (0),
- callbackConnectionState (false),
- useMessageThread (callbacksOnMessageThread),
- magicMessageHeader (magicMessageHeaderNumber),
- pipeReceiveMessageTimeout (-1)
- {
- }
-
- InterprocessConnection::~InterprocessConnection()
- {
- callbackConnectionState = false;
- disconnect();
- }
-
- bool InterprocessConnection::connectToSocket (const String& hostName,
- const int portNumber,
- const int timeOutMillisecs)
- {
- disconnect();
-
- const ScopedLock sl (pipeAndSocketLock);
- socket = new StreamingSocket();
-
- if (socket->connect (hostName, portNumber, timeOutMillisecs))
- {
- connectionMadeInt();
- startThread();
- return true;
- }
- else
- {
- deleteAndZero (socket);
- return false;
- }
- }
-
- bool InterprocessConnection::connectToPipe (const String& pipeName,
- const int pipeReceiveMessageTimeoutMs)
- {
- disconnect();
-
- NamedPipe* const newPipe = new NamedPipe();
-
- if (newPipe->openExisting (pipeName))
- {
- const ScopedLock sl (pipeAndSocketLock);
- pipeReceiveMessageTimeout = pipeReceiveMessageTimeoutMs;
- initialiseWithPipe (newPipe);
- return true;
- }
- else
- {
- delete newPipe;
- return false;
- }
- }
-
- bool InterprocessConnection::createPipe (const String& pipeName,
- const int pipeReceiveMessageTimeoutMs)
- {
- disconnect();
-
- NamedPipe* const newPipe = new NamedPipe();
-
- if (newPipe->createNewPipe (pipeName))
- {
- const ScopedLock sl (pipeAndSocketLock);
- pipeReceiveMessageTimeout = pipeReceiveMessageTimeoutMs;
- initialiseWithPipe (newPipe);
- return true;
- }
- else
- {
- delete newPipe;
- return false;
- }
- }
-
- void InterprocessConnection::disconnect()
- {
- if (socket != 0)
- socket->close();
-
- if (pipe != 0)
- {
- pipe->cancelPendingReads();
- pipe->close();
- }
-
- stopThread (4000);
-
- {
- const ScopedLock sl (pipeAndSocketLock);
- deleteAndZero (socket);
- deleteAndZero (pipe);
- }
-
- connectionLostInt();
- }
-
- bool InterprocessConnection::isConnected() const
- {
- const ScopedLock sl (pipeAndSocketLock);
-
- return ((socket != 0 && socket->isConnected())
- || (pipe != 0 && pipe->isOpen()))
- && isThreadRunning();
- }
-
- const String InterprocessConnection::getConnectedHostName() const
- {
- if (pipe != 0)
- {
- return "localhost";
- }
- else if (socket != 0)
- {
- if (! socket->isLocal())
- return socket->getHostName();
-
- return "localhost";
- }
-
- return String::empty;
- }
-
- bool InterprocessConnection::sendMessage (const MemoryBlock& message)
- {
- uint32 messageHeader[2];
- messageHeader [0] = swapIfBigEndian (magicMessageHeader);
- messageHeader [1] = swapIfBigEndian ((uint32) message.getSize());
-
- MemoryBlock messageData (sizeof (messageHeader) + message.getSize());
- messageData.copyFrom (messageHeader, 0, sizeof (messageHeader));
- messageData.copyFrom (message.getData(), sizeof (messageHeader), message.getSize());
-
- int bytesWritten = 0;
-
- const ScopedLock sl (pipeAndSocketLock);
-
- if (socket != 0)
- {
- bytesWritten = socket->write (messageData.getData(), messageData.getSize());
- }
- else if (pipe != 0)
- {
- bytesWritten = pipe->write (messageData.getData(), messageData.getSize());
- }
-
- if (bytesWritten < 0)
- {
- // error..
- return false;
- }
-
- return (bytesWritten == messageData.getSize());
- }
-
- void InterprocessConnection::initialiseWithSocket (StreamingSocket* const socket_)
- {
- jassert (socket == 0);
- socket = socket_;
- connectionMadeInt();
- startThread();
- }
-
- void InterprocessConnection::initialiseWithPipe (NamedPipe* const pipe_)
- {
- jassert (pipe == 0);
- pipe = pipe_;
- connectionMadeInt();
- startThread();
- }
-
- const int messageMagicNumber = 0xb734128b;
-
- void InterprocessConnection::handleMessage (const Message& message)
- {
- if (message.intParameter1 == messageMagicNumber)
- {
- switch (message.intParameter2)
- {
- case 0:
- {
- MemoryBlock* const data = (MemoryBlock*) message.pointerParameter;
- messageReceived (*data);
- delete data;
- break;
- }
-
- case 1:
- connectionMade();
- break;
-
- case 2:
- connectionLost();
- break;
- }
- }
- }
-
- void InterprocessConnection::connectionMadeInt()
- {
- if (! callbackConnectionState)
- {
- callbackConnectionState = true;
-
- if (useMessageThread)
- postMessage (new Message (messageMagicNumber, 1, 0, 0));
- else
- connectionMade();
- }
- }
-
- void InterprocessConnection::connectionLostInt()
- {
- if (callbackConnectionState)
- {
- callbackConnectionState = false;
-
- if (useMessageThread)
- postMessage (new Message (messageMagicNumber, 2, 0, 0));
- else
- connectionLost();
- }
- }
-
- void InterprocessConnection::deliverDataInt (const MemoryBlock& data)
- {
- jassert (callbackConnectionState);
-
- if (useMessageThread)
- postMessage (new Message (messageMagicNumber, 0, 0, new MemoryBlock (data)));
- else
- messageReceived (data);
- }
-
- bool InterprocessConnection::readNextMessageInt()
- {
- const int maximumMessageSize = 1024 * 1024 * 10; // sanity check
-
- uint32 messageHeader[2];
- const int bytes = (socket != 0) ? socket->read (messageHeader, sizeof (messageHeader))
- : pipe->read (messageHeader, sizeof (messageHeader), pipeReceiveMessageTimeout);
-
- if (bytes == sizeof (messageHeader)
- && swapIfBigEndian (messageHeader[0]) == magicMessageHeader)
- {
- const int bytesInMessage = (int) swapIfBigEndian (messageHeader[1]);
-
- if (bytesInMessage > 0 && bytesInMessage < maximumMessageSize)
- {
- MemoryBlock messageData (bytesInMessage, true);
- int bytesRead = 0;
-
- while (bytesRead < bytesInMessage)
- {
- if (threadShouldExit())
- return false;
-
- const int numThisTime = jmin (bytesInMessage, 65536);
- const int bytesIn = (socket != 0) ? socket->read (((char*) messageData.getData()) + bytesRead, numThisTime)
- : pipe->read (((char*) messageData.getData()) + bytesRead, numThisTime,
- pipeReceiveMessageTimeout);
-
- if (bytesIn <= 0)
- break;
-
- bytesRead += bytesIn;
- }
-
- if (bytesRead >= 0)
- deliverDataInt (messageData);
- }
- }
- else if (bytes < 0)
- {
- {
- const ScopedLock sl (pipeAndSocketLock);
- deleteAndZero (socket);
- }
-
- connectionLostInt();
- return false;
- }
-
- return true;
- }
-
- void InterprocessConnection::run()
- {
- while (! threadShouldExit())
- {
- if (socket != 0)
- {
- const int ready = socket->waitUntilReady (true, 0);
-
- if (ready < 0)
- {
- {
- const ScopedLock sl (pipeAndSocketLock);
- deleteAndZero (socket);
- }
-
- connectionLostInt();
- break;
- }
- else if (ready > 0)
- {
- if (! readNextMessageInt())
- break;
- }
- else
- {
- Thread::sleep (2);
- }
- }
- else if (pipe != 0)
- {
- if (! pipe->isOpen())
- {
- {
- const ScopedLock sl (pipeAndSocketLock);
- deleteAndZero (pipe);
- }
-
- connectionLostInt();
- break;
- }
- else
- {
- if (! readNextMessageInt())
- break;
- }
- }
- else
- {
- break;
- }
- }
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_InterprocessConnection.cpp *********/
-
- /********* Start of inlined file: juce_InterprocessConnectionServer.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- InterprocessConnectionServer::InterprocessConnectionServer()
- : Thread ("Juce IPC server"),
- socket (0)
- {
- }
-
- InterprocessConnectionServer::~InterprocessConnectionServer()
- {
- stop();
- }
-
- bool InterprocessConnectionServer::beginWaitingForSocket (const int portNumber)
- {
- stop();
-
- socket = new StreamingSocket();
-
- if (socket->createListener (portNumber))
- {
- startThread();
- return true;
- }
-
- deleteAndZero (socket);
- return false;
- }
-
- void InterprocessConnectionServer::stop()
- {
- signalThreadShouldExit();
-
- if (socket != 0)
- socket->close();
-
- stopThread (4000);
-
- deleteAndZero (socket);
- }
-
- void InterprocessConnectionServer::run()
- {
- while ((! threadShouldExit()) && socket != 0)
- {
- StreamingSocket* const clientSocket = socket->waitForNextConnection();
-
- if (clientSocket != 0)
- {
- InterprocessConnection* newConnection = createConnectionObject();
-
- if (newConnection != 0)
- {
- newConnection->initialiseWithSocket (clientSocket);
- }
- else
- {
- delete clientSocket;
- }
- }
- }
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_InterprocessConnectionServer.cpp *********/
-
- /********* Start of inlined file: juce_Message.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- Message::Message() throw()
- {
- }
-
- Message::~Message() throw()
- {
- }
-
- Message::Message (const int intParameter1_,
- const int intParameter2_,
- const int intParameter3_,
- void* const pointerParameter_) throw()
- : intParameter1 (intParameter1_),
- intParameter2 (intParameter2_),
- intParameter3 (intParameter3_),
- pointerParameter (pointerParameter_)
- {
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_Message.cpp *********/
-
- /********* Start of inlined file: juce_MessageListener.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- MessageListener::MessageListener() throw()
- {
- // are you trying to create a messagelistener before or after juce has been intialised??
- jassert (MessageManager::instance != 0);
-
- if (MessageManager::instance != 0)
- MessageManager::instance->messageListeners.add (this);
- }
-
- MessageListener::~MessageListener()
- {
- if (MessageManager::instance != 0)
- MessageManager::instance->messageListeners.removeValue (this);
- }
-
- void MessageListener::postMessage (Message* const message) const throw()
- {
- message->messageRecipient = const_cast <MessageListener*> (this);
-
- if (MessageManager::instance == 0)
- MessageManager::getInstance();
-
- MessageManager::instance->postMessageToQueue (message);
- }
-
- bool MessageListener::isValidMessageListener() const throw()
- {
- return (MessageManager::instance != 0)
- && MessageManager::instance->messageListeners.contains (this);
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_MessageListener.cpp *********/
-
- /********* Start of inlined file: juce_MessageManager.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- // platform-specific functions..
- bool juce_dispatchNextMessageOnSystemQueue (bool returnIfNoPendingMessages);
- bool juce_postMessageToSystemQueue (void* message);
-
- MessageManager* MessageManager::instance = 0;
-
- static const int quitMessageId = 0xfffff321;
-
- MessageManager::MessageManager() throw()
- : broadcastListeners (0),
- quitMessagePosted (false),
- quitMessageReceived (false),
- useMaximumForceWhenQuitting (true),
- messageCounter (0),
- lastMessageCounter (-1),
- isInMessageDispatcher (0),
- needToGetRidOfWaitCursor (false),
- timeBeforeWaitCursor (0),
- lastActivityCheckOkTime (0)
- {
- currentLockingThreadId = messageThreadId = Thread::getCurrentThreadId();
- }
-
- MessageManager::~MessageManager() throw()
- {
- jassert (instance == this);
- instance = 0;
- deleteAndZero (broadcastListeners);
-
- doPlatformSpecificShutdown();
- }
-
- MessageManager* MessageManager::getInstance() throw()
- {
- if (instance == 0)
- {
- instance = new MessageManager();
- doPlatformSpecificInitialisation();
-
- instance->setTimeBeforeShowingWaitCursor (500);
- }
-
- return instance;
- }
-
- void MessageManager::postMessageToQueue (Message* const message)
- {
- if (quitMessagePosted || ! juce_postMessageToSystemQueue (message))
- delete message;
- }
-
- // not for public use..
- void MessageManager::deliverMessage (void* message)
- {
- const MessageManagerLock lock;
-
- Message* const m = (Message*) message;
- MessageListener* const recipient = m->messageRecipient;
-
- if (messageListeners.contains (recipient))
- {
- JUCE_TRY
- {
- recipient->handleMessage (*m);
- }
- JUCE_CATCH_EXCEPTION
-
- if (needToGetRidOfWaitCursor)
- {
- needToGetRidOfWaitCursor = false;
- MouseCursor::hideWaitCursor();
- }
-
- ++messageCounter;
- }
- else if (recipient == 0 && m->intParameter1 == quitMessageId)
- {
- quitMessageReceived = true;
- useMaximumForceWhenQuitting = (m->intParameter2 != 0);
- }
-
- delete m;
- }
-
- bool MessageManager::dispatchNextMessage (const bool returnImmediatelyIfNoMessages,
- bool* const wasAMessageDispatched)
- {
- if (quitMessageReceived)
- {
- if (wasAMessageDispatched != 0)
- *wasAMessageDispatched = false;
-
- return false;
- }
-
- ++isInMessageDispatcher;
-
- bool result = false;
-
- JUCE_TRY
- {
- result = juce_dispatchNextMessageOnSystemQueue (returnImmediatelyIfNoMessages);
-
- if (wasAMessageDispatched != 0)
- *wasAMessageDispatched = result;
-
- if (instance == 0)
- return false;
- }
- JUCE_CATCH_EXCEPTION
-
- --isInMessageDispatcher;
- ++messageCounter;
-
- return result || ! returnImmediatelyIfNoMessages;
- }
-
- void MessageManager::dispatchPendingMessages (int maxNumberOfMessagesToDispatch)
- {
- jassert (isThisTheMessageThread()); // must only be called by the message thread
-
- while (--maxNumberOfMessagesToDispatch >= 0 && ! quitMessageReceived)
- {
- ++isInMessageDispatcher;
-
- bool carryOn = false;
-
- JUCE_TRY
- {
- carryOn = juce_dispatchNextMessageOnSystemQueue (true);
- }
- JUCE_CATCH_EXCEPTION
-
- --isInMessageDispatcher;
- ++messageCounter;
-
- if (! carryOn)
- break;
- }
- }
-
- bool MessageManager::runDispatchLoop()
- {
- jassert (isThisTheMessageThread()); // must only be called by the message thread
-
- while (dispatchNextMessage())
- {
- }
-
- return useMaximumForceWhenQuitting;
- }
-
- void MessageManager::postQuitMessage (const bool useMaximumForce)
- {
- Message* const m = new Message (quitMessageId, (useMaximumForce) ? 1 : 0, 0, 0);
- m->messageRecipient = 0;
- postMessageToQueue (m);
-
- quitMessagePosted = true;
- }
-
- bool MessageManager::hasQuitMessageBeenPosted() const throw()
- {
- return quitMessagePosted;
- }
-
- void MessageManager::deliverBroadcastMessage (const String& value)
- {
- if (broadcastListeners != 0)
- broadcastListeners->sendActionMessage (value);
- }
-
- void MessageManager::registerBroadcastListener (ActionListener* const listener) throw()
- {
- if (broadcastListeners == 0)
- broadcastListeners = new ActionListenerList();
-
- broadcastListeners->addActionListener (listener);
- }
-
- void MessageManager::deregisterBroadcastListener (ActionListener* const listener) throw()
- {
- if (broadcastListeners != 0)
- broadcastListeners->removeActionListener (listener);
- }
-
- // This gets called occasionally by the timer thread (to save using an extra thread
- // for it).
- void MessageManager::inactivityCheckCallback() throw()
- {
- if (instance != 0)
- instance->inactivityCheckCallbackInt();
- }
-
- void MessageManager::inactivityCheckCallbackInt() throw()
- {
- const unsigned int now = Time::getApproximateMillisecondCounter();
-
- if (isInMessageDispatcher > 0
- && lastMessageCounter == messageCounter
- && timeBeforeWaitCursor > 0
- && lastActivityCheckOkTime > 0
- && ! ModifierKeys::getCurrentModifiersRealtime().isAnyMouseButtonDown())
- {
- if (now >= lastActivityCheckOkTime + timeBeforeWaitCursor
- && ! needToGetRidOfWaitCursor)
- {
- // been in the same message call too long..
- MouseCursor::showWaitCursor();
- needToGetRidOfWaitCursor = true;
- }
- }
- else
- {
- lastActivityCheckOkTime = now;
- lastMessageCounter = messageCounter;
- }
- }
-
- void MessageManager::delayWaitCursor() throw()
- {
- if (instance != 0)
- {
- instance->messageCounter++;
-
- if (instance->needToGetRidOfWaitCursor)
- {
- instance->needToGetRidOfWaitCursor = false;
- MouseCursor::hideWaitCursor();
- }
- }
- }
-
- void MessageManager::setTimeBeforeShowingWaitCursor (const int millisecs) throw()
- {
- // if this is a bit too small you'll get a lot of unwanted hourglass cursors..
- jassert (millisecs <= 0 || millisecs > 200);
-
- timeBeforeWaitCursor = millisecs;
-
- if (millisecs > 0)
- startTimer (millisecs / 2); // (see timerCallback() for explanation of this)
- else
- stopTimer();
- }
-
- void MessageManager::timerCallback()
- {
- // dummy callback - the message manager is just a Timer to ensure that there are always
- // some events coming in - otherwise it'll show the egg-timer/beachball-of-death.
- ++messageCounter;
- }
-
- int MessageManager::getTimeBeforeShowingWaitCursor() const throw()
- {
- return timeBeforeWaitCursor;
- }
-
- bool MessageManager::isThisTheMessageThread() const throw()
- {
- return Thread::getCurrentThreadId() == messageThreadId;
- }
-
- void MessageManager::setCurrentMessageThread (const int threadId) throw()
- {
- messageThreadId = threadId;
- }
-
- bool MessageManager::currentThreadHasLockedMessageManager() const throw()
- {
- return Thread::getCurrentThreadId() == currentLockingThreadId;
- }
-
- MessageManagerLock::MessageManagerLock() throw()
- : locked (false)
- {
- if (MessageManager::instance != 0)
- {
- MessageManager::instance->messageDispatchLock.enter();
- lastLockingThreadId = MessageManager::instance->currentLockingThreadId;
- MessageManager::instance->currentLockingThreadId = Thread::getCurrentThreadId();
- locked = true;
- }
- }
-
- MessageManagerLock::MessageManagerLock (Thread* const thread) throw()
- : locked (false)
- {
- jassert (thread != 0); // This will only work if you give it a valid thread!
-
- if (MessageManager::instance != 0)
- {
- for (;;)
- {
- if (MessageManager::instance->messageDispatchLock.tryEnter())
- {
- locked = true;
- lastLockingThreadId = MessageManager::instance->currentLockingThreadId;
- MessageManager::instance->currentLockingThreadId = Thread::getCurrentThreadId();
- break;
- }
-
- if (thread != 0 && thread->threadShouldExit())
- break;
-
- Thread::sleep (1);
- }
- }
- }
-
- MessageManagerLock::~MessageManagerLock() throw()
- {
- if (locked && MessageManager::instance != 0)
- {
- MessageManager::instance->currentLockingThreadId = lastLockingThreadId;
- MessageManager::instance->messageDispatchLock.exit();
- }
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_MessageManager.cpp *********/
-
- /********* Start of inlined file: juce_MultiTimer.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- class InternalMultiTimerCallback : public Timer
- {
- public:
- InternalMultiTimerCallback (const int timerId_, MultiTimer& owner_)
- : timerId (timerId_),
- owner (owner_)
- {
- }
-
- ~InternalMultiTimerCallback()
- {
- }
-
- void timerCallback()
- {
- owner.timerCallback (timerId);
- }
-
- const int timerId;
-
- private:
- MultiTimer& owner;
- };
-
- MultiTimer::MultiTimer() throw()
- {
- }
-
- MultiTimer::MultiTimer (const MultiTimer&) throw()
- {
- }
-
- MultiTimer::~MultiTimer()
- {
- const ScopedLock sl (timerListLock);
-
- for (int i = timers.size(); --i >= 0;)
- delete (InternalMultiTimerCallback*) timers.getUnchecked(i);
-
- timers.clear();
- }
-
- void MultiTimer::startTimer (const int timerId, const int intervalInMilliseconds) throw()
- {
- const ScopedLock sl (timerListLock);
-
- for (int i = timers.size(); --i >= 0;)
- {
- InternalMultiTimerCallback* const t = (InternalMultiTimerCallback*) timers.getUnchecked(i);
-
- if (t->timerId == timerId)
- {
- t->startTimer (intervalInMilliseconds);
- return;
- }
- }
-
- InternalMultiTimerCallback* const newTimer = new InternalMultiTimerCallback (timerId, *this);
- timers.add (newTimer);
- newTimer->startTimer (intervalInMilliseconds);
- }
-
- void MultiTimer::stopTimer (const int timerId) throw()
- {
- const ScopedLock sl (timerListLock);
-
- for (int i = timers.size(); --i >= 0;)
- {
- InternalMultiTimerCallback* const t = (InternalMultiTimerCallback*) timers.getUnchecked(i);
-
- if (t->timerId == timerId)
- t->stopTimer();
- }
- }
-
- bool MultiTimer::isTimerRunning (const int timerId) const throw()
- {
- const ScopedLock sl (timerListLock);
-
- for (int i = timers.size(); --i >= 0;)
- {
- const InternalMultiTimerCallback* const t = (InternalMultiTimerCallback*) timers.getUnchecked(i);
- if (t->timerId == timerId)
- return t->isTimerRunning();
- }
-
- return false;
- }
-
- int MultiTimer::getTimerInterval (const int timerId) const throw()
- {
- const ScopedLock sl (timerListLock);
-
- for (int i = timers.size(); --i >= 0;)
- {
- const InternalMultiTimerCallback* const t = (InternalMultiTimerCallback*) timers.getUnchecked(i);
- if (t->timerId == timerId)
- return t->getTimerInterval();
- }
-
- return 0;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_MultiTimer.cpp *********/
-
- /********* Start of inlined file: juce_Timer.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- class InternalTimerThread : private Thread,
- private MessageListener,
- private DeletedAtShutdown,
- private AsyncUpdater
- {
- private:
- friend class Timer;
- static InternalTimerThread* instance;
- static CriticalSection lock;
-
- Timer* volatile firstTimer;
- bool volatile callbackNeeded;
-
- InternalTimerThread (const InternalTimerThread&);
- const InternalTimerThread& operator= (const InternalTimerThread&);
-
- void addTimer (Timer* const t) throw()
- {
- #ifdef JUCE_DEBUG
- Timer* tt = firstTimer;
-
- while (tt != 0)
- {
- // trying to add a timer that's already here - shouldn't get to this point,
- // so if you get this assertion, let me know!
- jassert (tt != t);
-
- tt = tt->next;
- }
-
- jassert (t->previous == 0 && t->next == 0);
- #endif
-
- Timer* i = firstTimer;
-
- if (i == 0 || i->countdownMs > t->countdownMs)
- {
- t->next = firstTimer;
- firstTimer = t;
- }
- else
- {
- while (i->next != 0 && i->next->countdownMs <= t->countdownMs)
- i = i->next;
-
- jassert (i != 0);
-
- t->next = i->next;
- t->previous = i;
- i->next = t;
- }
-
- if (t->next != 0)
- t->next->previous = t;
-
- jassert ((t->next == 0 || t->next->countdownMs >= t->countdownMs)
- && (t->previous == 0 || t->previous->countdownMs <= t->countdownMs));
-
- notify();
- }
-
- void removeTimer (Timer* const t) throw()
- {
- #ifdef JUCE_DEBUG
- Timer* tt = firstTimer;
- bool found = false;
-
- while (tt != 0)
- {
- if (tt == t)
- {
- found = true;
- break;
- }
-
- tt = tt->next;
- }
-
- // trying to remove a timer that's not here - shouldn't get to this point,
- // so if you get this assertion, let me know!
- jassert (found);
- #endif
-
- if (t->previous != 0)
- {
- jassert (firstTimer != t);
- t->previous->next = t->next;
- }
- else
- {
- jassert (firstTimer == t);
- firstTimer = t->next;
- }
-
- if (t->next != 0)
- t->next->previous = t->previous;
-
- t->next = 0;
- t->previous = 0;
- }
-
- void decrementAllCounters (const int numMillisecs) const
- {
- Timer* t = firstTimer;
-
- while (t != 0)
- {
- t->countdownMs -= numMillisecs;
- t = t->next;
- }
- }
-
- void handleAsyncUpdate()
- {
- startThread (7);
- }
-
- public:
- InternalTimerThread()
- : Thread ("Juce Timer"),
- firstTimer (0),
- callbackNeeded (false)
- {
- triggerAsyncUpdate();
- }
-
- ~InternalTimerThread() throw()
- {
- stopThread (4000);
-
- jassert (instance == this || instance == 0);
- if (instance == this)
- instance = 0;
- }
-
- void run()
- {
- uint32 lastTime = Time::getMillisecondCounter();
- uint32 lastMessageManagerCallback = lastTime;
-
- while (! threadShouldExit())
- {
- uint32 now = Time::getMillisecondCounter();
-
- if (now <= lastTime)
- {
- wait (2);
- continue;
- }
-
- const int elapsed = now - lastTime;
- lastTime = now;
-
- lock.enter();
- decrementAllCounters (elapsed);
- const int timeUntilFirstTimer = (firstTimer != 0) ? firstTimer->countdownMs
- : 1000;
- lock.exit();
-
- if (timeUntilFirstTimer <= 0)
- {
- callbackNeeded = true;
- postMessage (new Message());
-
- // sometimes, our message could get discarded by the OS (particularly when running as an RTAS when the app has a modal loop),
- // so this is how long to wait before assuming the message has been lost and trying again.
- const uint32 messageDeliveryTimeout = now + 2000;
-
- while (callbackNeeded)
- {
- wait (4);
-
- if (threadShouldExit())
- return;
-
- now = Time::getMillisecondCounter();
-
- if (now > lastMessageManagerCallback + 200)
- {
- lastMessageManagerCallback = now;
- MessageManager::inactivityCheckCallback();
- }
-
- if (now > messageDeliveryTimeout)
- break;
- }
- }
- else
- {
- // don't wait for too long because running this loop also helps keep the
- // Time::getApproximateMillisecondTimer value stay up-to-date
- wait (jlimit (1, 50, timeUntilFirstTimer));
- }
-
- if (now > lastMessageManagerCallback + 200)
- {
- lastMessageManagerCallback = now;
- MessageManager::inactivityCheckCallback();
- }
- }
- }
-
- void handleMessage (const Message&)
- {
- const ScopedLock sl (lock);
-
- while (firstTimer != 0 && firstTimer->countdownMs <= 0)
- {
- Timer* const t = firstTimer;
- t->countdownMs = t->periodMs;
-
- removeTimer (t);
- addTimer (t);
-
- const ScopedUnlock ul (lock);
- callbackNeeded = false;
-
- JUCE_TRY
- {
- t->timerCallback();
- }
- JUCE_CATCH_EXCEPTION
- }
-
- callbackNeeded = false;
- }
-
- static void callAnyTimersSynchronously()
- {
- if (InternalTimerThread::instance != 0)
- {
- const Message m;
- InternalTimerThread::instance->handleMessage (m);
- }
- }
-
- static inline void add (Timer* const tim) throw()
- {
- if (instance == 0)
- instance = new InternalTimerThread();
-
- instance->addTimer (tim);
- }
-
- static inline void remove (Timer* const tim) throw()
- {
- if (instance != 0)
- instance->removeTimer (tim);
- }
-
- static inline void resetCounter (Timer* const tim,
- const int newCounter) throw()
- {
- if (instance != 0)
- {
- tim->countdownMs = newCounter;
- tim->periodMs = newCounter;
-
- if ((tim->next != 0 && tim->next->countdownMs < tim->countdownMs)
- || (tim->previous != 0 && tim->previous->countdownMs > tim->countdownMs))
- {
- instance->removeTimer (tim);
- instance->addTimer (tim);
- }
- }
- }
- };
-
- InternalTimerThread* InternalTimerThread::instance = 0;
- CriticalSection InternalTimerThread::lock;
-
- void juce_callAnyTimersSynchronously()
- {
- InternalTimerThread::callAnyTimersSynchronously();
- }
-
- #ifdef JUCE_DEBUG
- static SortedSet <Timer*> activeTimers;
- #endif
-
- Timer::Timer() throw()
- : countdownMs (0),
- periodMs (0),
- previous (0),
- next (0)
- {
- #ifdef JUCE_DEBUG
- activeTimers.add (this);
- #endif
- }
-
- Timer::Timer (const Timer&) throw()
- : countdownMs (0),
- periodMs (0),
- previous (0),
- next (0)
- {
- #ifdef JUCE_DEBUG
- activeTimers.add (this);
- #endif
- }
-
- Timer::~Timer()
- {
- stopTimer();
-
- #ifdef JUCE_DEBUG
- activeTimers.removeValue (this);
- #endif
- }
-
- void Timer::startTimer (const int interval) throw()
- {
- const ScopedLock sl (InternalTimerThread::lock);
-
- #ifdef JUCE_DEBUG
- // this isn't a valid object! Your timer might be a dangling pointer or something..
- jassert (activeTimers.contains (this));
- #endif
-
- if (periodMs == 0)
- {
- countdownMs = interval;
- periodMs = jmax (1, interval);
- InternalTimerThread::add (this);
- }
- else
- {
- InternalTimerThread::resetCounter (this, interval);
- }
- }
-
- void Timer::stopTimer() throw()
- {
- const ScopedLock sl (InternalTimerThread::lock);
-
- #ifdef JUCE_DEBUG
- // this isn't a valid object! Your timer might be a dangling pointer or something..
- jassert (activeTimers.contains (this));
- #endif
-
- if (periodMs > 0)
- {
- InternalTimerThread::remove (this);
- periodMs = 0;
- }
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_Timer.cpp *********/
-
- /********* Start of inlined file: juce_Component.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- Component* Component::componentUnderMouse = 0;
- Component* Component::currentlyFocusedComponent = 0;
-
- static Array <Component*> modalComponentStack (4), modalComponentReturnValueKeys (4);
- static Array <int> modalReturnValues (4);
-
- static const int customCommandMessage = 0x7fff0001;
- static const int exitModalStateMessage = 0x7fff0002;
-
- // these are also used by ComponentPeer
- int64 juce_recentMouseDownTimes [4] = { 0, 0, 0, 0 };
- int juce_recentMouseDownX [4] = { 0, 0, 0, 0 };
- int juce_recentMouseDownY [4] = { 0, 0, 0, 0 };
- Component* juce_recentMouseDownComponent [4] = { 0, 0, 0, 0 };
- int juce_LastMousePosX = 0;
- int juce_LastMousePosY = 0;
- int juce_MouseClickCounter = 0;
- bool juce_MouseHasMovedSignificantlySincePressed = false;
-
- static int countMouseClicks() throw()
- {
- int numClicks = 0;
-
- if (juce_recentMouseDownTimes[0] != 0)
- {
- if (! juce_MouseHasMovedSignificantlySincePressed)
- ++numClicks;
-
- for (int i = 1; i < numElementsInArray (juce_recentMouseDownTimes); ++i)
- {
- if (juce_recentMouseDownTimes[0] - juce_recentMouseDownTimes [i]
- < (int) (MouseEvent::getDoubleClickTimeout() * (1.0 + 0.25 * (i - 1)))
- && abs (juce_recentMouseDownX[0] - juce_recentMouseDownX[i]) < 8
- && abs (juce_recentMouseDownY[0] - juce_recentMouseDownY[i]) < 8
- && juce_recentMouseDownComponent[0] == juce_recentMouseDownComponent [i])
- {
- ++numClicks;
- }
- else
- {
- break;
- }
- }
- }
-
- return numClicks;
- }
-
- static int unboundedMouseOffsetX = 0;
- static int unboundedMouseOffsetY = 0;
- static bool isUnboundedMouseModeOn = false;
- static bool isCursorVisibleUntilOffscreen;
-
- #define checkMessageManagerIsLocked jassert (MessageManager::getInstance()->currentThreadHasLockedMessageManager());
-
- static uint32 nextComponentUID = 0;
-
- Component::Component() throw()
- : parentComponent_ (0),
- componentUID (++nextComponentUID),
- numDeepMouseListeners (0),
- childComponentList_ (16),
- lookAndFeel_ (0),
- effect_ (0),
- bufferedImage_ (0),
- mouseListeners_ (0),
- keyListeners_ (0),
- componentListeners_ (0),
- propertySet_ (0),
- componentFlags_ (0)
- {
- }
-
- Component::Component (const String& name) throw()
- : componentName_ (name),
- parentComponent_ (0),
- componentUID (++nextComponentUID),
- numDeepMouseListeners (0),
- childComponentList_ (16),
- lookAndFeel_ (0),
- effect_ (0),
- bufferedImage_ (0),
- mouseListeners_ (0),
- keyListeners_ (0),
- componentListeners_ (0),
- propertySet_ (0),
- componentFlags_ (0)
- {
- }
-
- Component::~Component()
- {
- if (parentComponent_ != 0)
- {
- parentComponent_->removeChildComponent (this);
- }
- else if ((currentlyFocusedComponent == this)
- || isParentOf (currentlyFocusedComponent))
- {
- giveAwayFocus();
- }
-
- if (componentUnderMouse == this)
- componentUnderMouse = 0;
-
- if (flags.hasHeavyweightPeerFlag)
- removeFromDesktop();
-
- modalComponentStack.removeValue (this);
-
- for (int i = childComponentList_.size(); --i >= 0;)
- childComponentList_.getUnchecked(i)->parentComponent_ = 0;
-
- delete bufferedImage_;
- delete mouseListeners_;
- delete keyListeners_;
- delete componentListeners_;
- delete propertySet_;
- }
-
- void Component::setName (const String& name)
- {
- // if component methods are being called from threads other than the message
- // thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe.
- checkMessageManagerIsLocked
-
- if (componentName_ != name)
- {
- componentName_ = name;
-
- if (flags.hasHeavyweightPeerFlag)
- {
- ComponentPeer* const peer = getPeer();
-
- jassert (peer != 0);
- if (peer != 0)
- peer->setTitle (name);
- }
-
- if (componentListeners_ != 0)
- {
- const ComponentDeletionWatcher deletionChecker (this);
-
- for (int i = componentListeners_->size(); --i >= 0;)
- {
- ((ComponentListener*) componentListeners_->getUnchecked (i))
- ->componentNameChanged (*this);
-
- if (deletionChecker.hasBeenDeleted())
- return;
-
- i = jmin (i, componentListeners_->size());
- }
- }
-
- }
- }
-
- void Component::setVisible (bool shouldBeVisible)
- {
- if (flags.visibleFlag != shouldBeVisible)
- {
- // if component methods are being called from threads other than the message
- // thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe.
- checkMessageManagerIsLocked
-
- const ComponentDeletionWatcher deletionChecker (this);
-
- flags.visibleFlag = shouldBeVisible;
-
- internalRepaint (0, 0, getWidth(), getHeight());
-
- sendFakeMouseMove();
-
- if (! shouldBeVisible)
- {
- if (currentlyFocusedComponent == this
- || isParentOf (currentlyFocusedComponent))
- {
- if (parentComponent_ != 0)
- parentComponent_->grabKeyboardFocus();
- else
- giveAwayFocus();
- }
- }
-
- sendVisibilityChangeMessage();
-
- if ((! deletionChecker.hasBeenDeleted()) && flags.hasHeavyweightPeerFlag)
- {
- ComponentPeer* const peer = getPeer();
-
- jassert (peer != 0);
- if (peer != 0)
- {
- peer->setVisible (shouldBeVisible);
- internalHierarchyChanged();
- }
- }
- }
- }
-
- void Component::visibilityChanged()
- {
- }
-
- void Component::sendVisibilityChangeMessage()
- {
- const ComponentDeletionWatcher deletionChecker (this);
-
- visibilityChanged();
-
- if ((! deletionChecker.hasBeenDeleted()) && componentListeners_ != 0)
- {
- for (int i = componentListeners_->size(); --i >= 0;)
- {
- ((ComponentListener*) componentListeners_->getUnchecked (i))
- ->componentVisibilityChanged (*this);
-
- if (deletionChecker.hasBeenDeleted())
- return;
-
- i = jmin (i, componentListeners_->size());
- }
- }
- }
-
- bool Component::isShowing() const throw()
- {
- if (flags.visibleFlag)
- {
- if (parentComponent_ != 0)
- {
- return parentComponent_->isShowing();
- }
- else
- {
- const ComponentPeer* const peer = getPeer();
-
- return peer != 0 && ! peer->isMinimised();
- }
- }
-
- return false;
- }
-
- class FadeOutProxyComponent : public Component,
- public Timer
- {
- public:
- FadeOutProxyComponent (Component* comp,
- const int fadeLengthMs,
- const int deltaXToMove,
- const int deltaYToMove,
- const float scaleFactorAtEnd)
- : lastTime (0),
- alpha (1.0f),
- scale (1.0f)
- {
- image = comp->createComponentSnapshot (Rectangle (0, 0, comp->getWidth(), comp->getHeight()));
- setBounds (comp->getBounds());
- comp->getParentComponent()->addAndMakeVisible (this);
- toBehind (comp);
-
- alphaChangePerMs = -1.0f / (float)fadeLengthMs;
-
- centreX = comp->getX() + comp->getWidth() * 0.5f;
- xChangePerMs = deltaXToMove / (float)fadeLengthMs;
-
- centreY = comp->getY() + comp->getHeight() * 0.5f;
- yChangePerMs = deltaYToMove / (float)fadeLengthMs;
-
- scaleChangePerMs = (scaleFactorAtEnd - 1.0f) / (float)fadeLengthMs;
-
- setInterceptsMouseClicks (false, false);
-
- // 30 fps is enough for a fade, but we need a higher rate if it's moving as well..
- startTimer (1000 / ((deltaXToMove == 0 && deltaYToMove == 0) ? 30 : 50));
- }
-
- ~FadeOutProxyComponent()
- {
- delete image;
- }
-
- void paint (Graphics& g)
- {
- g.setOpacity (alpha);
-
- g.drawImage (image,
- 0, 0, getWidth(), getHeight(),
- 0, 0, image->getWidth(), image->getHeight());
- }
-
- void timerCallback()
- {
- const uint32 now = Time::getMillisecondCounter();
-
- if (lastTime == 0)
- lastTime = now;
-
- const int msPassed = (now > lastTime) ? now - lastTime : 0;
- lastTime = now;
-
- alpha += alphaChangePerMs * msPassed;
-
- if (alpha > 0)
- {
- if (xChangePerMs != 0.0f || yChangePerMs != 0.0f || scaleChangePerMs != 0.0f)
- {
- centreX += xChangePerMs * msPassed;
- centreY += yChangePerMs * msPassed;
- scale += scaleChangePerMs * msPassed;
-
- const int w = roundFloatToInt (image->getWidth() * scale);
- const int h = roundFloatToInt (image->getHeight() * scale);
-
- setBounds (roundFloatToInt (centreX) - w / 2,
- roundFloatToInt (centreY) - h / 2,
- w, h);
- }
-
- repaint();
- }
- else
- {
- delete this;
- }
- }
-
- juce_UseDebuggingNewOperator
-
- private:
- Image* image;
- uint32 lastTime;
- float alpha, alphaChangePerMs;
- float centreX, xChangePerMs;
- float centreY, yChangePerMs;
- float scale, scaleChangePerMs;
-
- FadeOutProxyComponent (const FadeOutProxyComponent&);
- const FadeOutProxyComponent& operator= (const FadeOutProxyComponent&);
- };
-
- void Component::fadeOutComponent (const int millisecondsToFade,
- const int deltaXToMove,
- const int deltaYToMove,
- const float scaleFactorAtEnd)
- {
- //xxx won't work for comps without parents
- if (isShowing() && millisecondsToFade > 0)
- new FadeOutProxyComponent (this, millisecondsToFade,
- deltaXToMove, deltaYToMove, scaleFactorAtEnd);
-
- setVisible (false);
- }
-
- bool Component::isValidComponent() const throw()
- {
- return (this != 0) && isValidMessageListener();
- }
-
- void* Component::getWindowHandle() const throw()
- {
- const ComponentPeer* const peer = getPeer();
-
- if (peer != 0)
- return peer->getNativeHandle();
-
- return 0;
- }
-
- void Component::addToDesktop (int styleWanted, void* nativeWindowToAttachTo)
- {
- // if component methods are being called from threads other than the message
- // thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe.
- checkMessageManagerIsLocked
-
- if (! isOpaque())
- styleWanted |= ComponentPeer::windowIsSemiTransparent;
-
- int currentStyleFlags = 0;
-
- // don't use getPeer(), so that we only get the peer that's specifically
- // for this comp, and not for one of its parents.
- ComponentPeer* peer = ComponentPeer::getPeerFor (this);
-
- if (peer != 0)
- currentStyleFlags = peer->getStyleFlags();
-
- if (styleWanted != currentStyleFlags || ! flags.hasHeavyweightPeerFlag)
- {
- const ComponentDeletionWatcher deletionChecker (this);
-
- #if JUCE_LINUX
- // it's wise to give the component a non-zero size before
- // putting it on the desktop, as X windows get confused by this, and
- // a (1, 1) minimum size is enforced here.
- setSize (jmax (1, getWidth()),
- jmax (1, getHeight()));
- #endif
-
- int x = 0, y = 0;
- relativePositionToGlobal (x, y);
-
- bool wasFullscreen = false;
- bool wasMinimised = false;
- ComponentBoundsConstrainer* currentConstainer = 0;
- Rectangle oldNonFullScreenBounds;
-
- if (peer != 0)
- {
- wasFullscreen = peer->isFullScreen();
- wasMinimised = peer->isMinimised();
- currentConstainer = peer->getConstrainer();
- oldNonFullScreenBounds = peer->getNonFullScreenBounds();
-
- removeFromDesktop();
- }
-
- if (parentComponent_ != 0)
- parentComponent_->removeChildComponent (this);
-
- if (! deletionChecker.hasBeenDeleted())
- {
- flags.hasHeavyweightPeerFlag = true;
-
- peer = createNewPeer (styleWanted, nativeWindowToAttachTo);
-
- Desktop::getInstance().addDesktopComponent (this);
-
- bounds_.setPosition (x, y);
- peer->setBounds (x, y, getWidth(), getHeight(), false);
-
- peer->setVisible (isVisible());
-
- if (wasFullscreen)
- {
- peer->setFullScreen (true);
- peer->setNonFullScreenBounds (oldNonFullScreenBounds);
- }
-
- if (wasMinimised)
- peer->setMinimised (true);
-
- if (isAlwaysOnTop())
- peer->setAlwaysOnTop (true);
-
- peer->setConstrainer (currentConstainer);
-
- repaint();
- }
-
- internalHierarchyChanged();
- }
- }
-
- void Component::removeFromDesktop()
- {
- // if component methods are being called from threads other than the message
- // thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe.
- checkMessageManagerIsLocked
-
- if (flags.hasHeavyweightPeerFlag)
- {
- ComponentPeer* const peer = ComponentPeer::getPeerFor (this);
-
- flags.hasHeavyweightPeerFlag = false;
-
- jassert (peer != 0);
- delete peer;
-
- Desktop::getInstance().removeDesktopComponent (this);
- }
- }
-
- bool Component::isOnDesktop() const throw()
- {
- return flags.hasHeavyweightPeerFlag;
- }
-
- void Component::userTriedToCloseWindow()
- {
- /* This means that the user's trying to get rid of your window with the 'close window' system
- menu option (on windows) or possibly the task manager - you should really handle this
- and delete or hide your component in an appropriate way.
-
- If you want to ignore the event and don't want to trigger this assertion, just override
- this method and do nothing.
- */
- jassertfalse
- }
-
- void Component::minimisationStateChanged (bool)
- {
- }
-
- void Component::setOpaque (const bool shouldBeOpaque) throw()
- {
- if (shouldBeOpaque != flags.opaqueFlag)
- {
- flags.opaqueFlag = shouldBeOpaque;
-
- if (flags.hasHeavyweightPeerFlag)
- {
- const ComponentPeer* const peer = ComponentPeer::getPeerFor (this);
-
- if (peer != 0)
- {
- // to make it recreate the heavyweight window
- addToDesktop (peer->getStyleFlags());
- }
- }
-
- repaint();
- }
- }
-
- bool Component::isOpaque() const throw()
- {
- return flags.opaqueFlag;
- }
-
- void Component::setBufferedToImage (const bool shouldBeBuffered) throw()
- {
- if (shouldBeBuffered != flags.bufferToImageFlag)
- {
- deleteAndZero (bufferedImage_);
- flags.bufferToImageFlag = shouldBeBuffered;
- }
- }
-
- void Component::toFront (const bool setAsForeground)
- {
- // if component methods are being called from threads other than the message
- // thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe.
- checkMessageManagerIsLocked
-
- if (flags.hasHeavyweightPeerFlag)
- {
- ComponentPeer* const peer = getPeer();
-
- if (peer != 0)
- {
- peer->toFront (setAsForeground);
-
- if (setAsForeground && ! hasKeyboardFocus (true))
- grabKeyboardFocus();
- }
- }
- else if (parentComponent_ != 0)
- {
- if (parentComponent_->childComponentList_.getLast() != this)
- {
- const int index = parentComponent_->childComponentList_.indexOf (this);
-
- if (index >= 0)
- {
- int insertIndex = -1;
-
- if (! flags.alwaysOnTopFlag)
- {
- insertIndex = parentComponent_->childComponentList_.size() - 1;
-
- while (insertIndex > 0
- && parentComponent_->childComponentList_.getUnchecked (insertIndex)->isAlwaysOnTop())
- {
- --insertIndex;
- }
- }
-
- if (index != insertIndex)
- {
- parentComponent_->childComponentList_.move (index, insertIndex);
- sendFakeMouseMove();
-
- repaintParent();
- }
- }
- }
-
- if (setAsForeground)
- {
- internalBroughtToFront();
- grabKeyboardFocus();
- }
- }
- }
-
- void Component::toBehind (Component* const other)
- {
- if (other != 0)
- {
- // the two components must belong to the same parent..
- jassert (parentComponent_ == other->parentComponent_);
-
- if (parentComponent_ != 0)
- {
- const int index = parentComponent_->childComponentList_.indexOf (this);
- int otherIndex = parentComponent_->childComponentList_.indexOf (other);
-
- if (index >= 0
- && otherIndex >= 0
- && index != otherIndex - 1
- && other != this)
- {
- if (index < otherIndex)
- --otherIndex;
-
- parentComponent_->childComponentList_.move (index, otherIndex);
-
- sendFakeMouseMove();
- repaintParent();
- }
- }
- else if (isOnDesktop())
- {
- jassert (other->isOnDesktop());
-
- if (other->isOnDesktop())
- {
- ComponentPeer* const us = getPeer();
- ComponentPeer* const them = other->getPeer();
-
- jassert (us != 0 && them != 0);
- if (us != 0 && them != 0)
- us->toBehind (them);
- }
- }
- }
- }
-
- void Component::toBack()
- {
- if (isOnDesktop())
- {
- jassertfalse //xxx need to add this to native window
- }
- else if (parentComponent_ != 0
- && parentComponent_->childComponentList_.getFirst() != this)
- {
- const int index = parentComponent_->childComponentList_.indexOf (this);
-
- if (index > 0)
- {
- int insertIndex = 0;
-
- if (flags.alwaysOnTopFlag)
- {
- while (insertIndex < parentComponent_->childComponentList_.size()
- && ! parentComponent_->childComponentList_.getUnchecked (insertIndex)->isAlwaysOnTop())
- {
- ++insertIndex;
- }
- }
-
- if (index != insertIndex)
- {
- parentComponent_->childComponentList_.move (index, insertIndex);
-
- sendFakeMouseMove();
- repaintParent();
- }
- }
- }
- }
-
- void Component::setAlwaysOnTop (const bool shouldStayOnTop)
- {
- if (shouldStayOnTop != flags.alwaysOnTopFlag)
- {
- flags.alwaysOnTopFlag = shouldStayOnTop;
-
- if (isOnDesktop())
- {
- ComponentPeer* const peer = getPeer();
-
- jassert (peer != 0);
- if (peer != 0)
- {
- if (! peer->setAlwaysOnTop (shouldStayOnTop))
- {
- // some kinds of peer can't change their always-on-top status, so
- // for these, we'll need to create a new window
- const int oldFlags = peer->getStyleFlags();
- removeFromDesktop();
- addToDesktop (oldFlags);
- }
- }
- }
-
- if (shouldStayOnTop)
- toFront (false);
-
- internalHierarchyChanged();
- }
- }
-
- bool Component::isAlwaysOnTop() const throw()
- {
- return flags.alwaysOnTopFlag;
- }
-
- int Component::proportionOfWidth (const float proportion) const throw()
- {
- return roundDoubleToInt (proportion * bounds_.getWidth());
- }
-
- int Component::proportionOfHeight (const float proportion) const throw()
- {
- return roundDoubleToInt (proportion * bounds_.getHeight());
- }
-
- int Component::getParentWidth() const throw()
- {
- return (parentComponent_ != 0) ? parentComponent_->getWidth()
- : getParentMonitorArea().getWidth();
- }
-
- int Component::getParentHeight() const throw()
- {
- return (parentComponent_ != 0) ? parentComponent_->getHeight()
- : getParentMonitorArea().getHeight();
- }
-
- int Component::getScreenX() const throw()
- {
- return (parentComponent_ != 0) ? parentComponent_->getScreenX() + getX()
- : (flags.hasHeavyweightPeerFlag ? getPeer()->getScreenX()
- : getX());
- }
-
- int Component::getScreenY() const throw()
- {
- return (parentComponent_ != 0) ? parentComponent_->getScreenY() + getY()
- : (flags.hasHeavyweightPeerFlag ? getPeer()->getScreenY()
- : getY());
- }
-
- void Component::relativePositionToGlobal (int& x, int& y) const throw()
- {
- const Component* c = this;
-
- do
- {
- if (c->flags.hasHeavyweightPeerFlag)
- {
- c->getPeer()->relativePositionToGlobal (x, y);
- break;
- }
-
- x += c->getX();
- y += c->getY();
- c = c->parentComponent_;
- }
- while (c != 0);
- }
-
- void Component::globalPositionToRelative (int& x, int& y) const throw()
- {
- if (flags.hasHeavyweightPeerFlag)
- {
- getPeer()->globalPositionToRelative (x, y);
- }
- else
- {
- if (parentComponent_ != 0)
- parentComponent_->globalPositionToRelative (x, y);
-
- x -= getX();
- y -= getY();
- }
- }
-
- void Component::relativePositionToOtherComponent (const Component* const targetComponent, int& x, int& y) const throw()
- {
- if (targetComponent != 0)
- {
- const Component* c = this;
-
- do
- {
- if (c == targetComponent)
- return;
-
- if (c->flags.hasHeavyweightPeerFlag)
- {
- c->getPeer()->relativePositionToGlobal (x, y);
- break;
- }
-
- x += c->getX();
- y += c->getY();
- c = c->parentComponent_;
- }
- while (c != 0);
-
- targetComponent->globalPositionToRelative (x, y);
- }
- }
-
- void Component::setBounds (int x, int y, int w, int h)
- {
- // if component methods are being called from threads other than the message
- // thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe.
- checkMessageManagerIsLocked
-
- if (w < 0) w = 0;
- if (h < 0) h = 0;
-
- const bool wasResized = (getWidth() != w || getHeight() != h);
- const bool wasMoved = (getX() != x || getY() != y);
-
- #ifdef JUCE_DEBUG
- // It's a very bad idea to try to resize a window during its paint() method!
- jassert (! (flags.isInsidePaintCall && wasResized && isOnDesktop()));
- #endif
-
- if (wasMoved || wasResized)
- {
- if (flags.visibleFlag)
- {
- // send a fake mouse move to trigger enter/exit messages if needed..
- sendFakeMouseMove();
-
- if (! flags.hasHeavyweightPeerFlag)
- repaintParent();
- }
-
- bounds_.setBounds (x, y, w, h);
-
- if (wasResized)
- repaint();
- else if (! flags.hasHeavyweightPeerFlag)
- repaintParent();
-
- if (flags.hasHeavyweightPeerFlag)
- {
- ComponentPeer* const peer = getPeer();
-
- if (peer != 0)
- {
- if (wasMoved && wasResized)
- peer->setBounds (getX(), getY(), getWidth(), getHeight(), false);
- else if (wasMoved)
- peer->setPosition (getX(), getY());
- else if (wasResized)
- peer->setSize (getWidth(), getHeight());
- }
- }
-
- sendMovedResizedMessages (wasMoved, wasResized);
- }
- }
-
- void Component::sendMovedResizedMessages (const bool wasMoved, const bool wasResized)
- {
- JUCE_TRY
- {
- if (wasMoved)
- moved();
-
- if (wasResized)
- {
- resized();
-
- for (int i = childComponentList_.size(); --i >= 0;)
- {
- childComponentList_.getUnchecked(i)->parentSizeChanged();
-
- i = jmin (i, childComponentList_.size());
- }
- }
-
- if (parentComponent_ != 0)
- parentComponent_->childBoundsChanged (this);
-
- if (componentListeners_ != 0)
- {
- const ComponentDeletionWatcher deletionChecker (this);
-
- for (int i = componentListeners_->size(); --i >= 0;)
- {
- ((ComponentListener*) componentListeners_->getUnchecked (i))
- ->componentMovedOrResized (*this, wasMoved, wasResized);
-
- if (deletionChecker.hasBeenDeleted())
- return;
-
- i = jmin (i, componentListeners_->size());
- }
- }
- }
- JUCE_CATCH_EXCEPTION
- }
-
- void Component::setSize (const int w, const int h)
- {
- setBounds (getX(), getY(), w, h);
- }
-
- void Component::setTopLeftPosition (const int x, const int y)
- {
- setBounds (x, y, getWidth(), getHeight());
- }
-
- void Component::setTopRightPosition (const int x, const int y)
- {
- setTopLeftPosition (x - getWidth(), y);
- }
-
- void Component::setBounds (const Rectangle& r)
- {
- setBounds (r.getX(),
- r.getY(),
- r.getWidth(),
- r.getHeight());
- }
-
- void Component::setBoundsRelative (const float x, const float y,
- const float w, const float h)
- {
- const int pw = getParentWidth();
- const int ph = getParentHeight();
-
- setBounds (roundFloatToInt (x * pw),
- roundFloatToInt (y * ph),
- roundFloatToInt (w * pw),
- roundFloatToInt (h * ph));
- }
-
- void Component::setCentrePosition (const int x, const int y)
- {
- setTopLeftPosition (x - getWidth() / 2,
- y - getHeight() / 2);
- }
-
- void Component::setCentreRelative (const float x, const float y)
- {
- setCentrePosition (roundFloatToInt (getParentWidth() * x),
- roundFloatToInt (getParentHeight() * y));
- }
-
- void Component::centreWithSize (const int width, const int height)
- {
- setBounds ((getParentWidth() - width) / 2,
- (getParentHeight() - height) / 2,
- width,
- height);
- }
-
- void Component::setBoundsInset (const BorderSize& borders)
- {
- setBounds (borders.getLeft(),
- borders.getTop(),
- getParentWidth() - (borders.getLeftAndRight()),
- getParentHeight() - (borders.getTopAndBottom()));
- }
-
- void Component::setBoundsToFit (int x, int y, int width, int height,
- const Justification& justification,
- const bool onlyReduceInSize)
- {
- // it's no good calling this method unless both the component and
- // target rectangle have a finite size.
- jassert (getWidth() > 0 && getHeight() > 0 && width > 0 && height > 0);
-
- if (getWidth() > 0 && getHeight() > 0
- && width > 0 && height > 0)
- {
- int newW, newH;
-
- if (onlyReduceInSize && getWidth() <= width && getHeight() <= height)
- {
- newW = getWidth();
- newH = getHeight();
- }
- else
- {
- const double imageRatio = getHeight() / (double) getWidth();
- const double targetRatio = height / (double) width;
-
- if (imageRatio <= targetRatio)
- {
- newW = width;
- newH = jmin (height, roundDoubleToInt (newW * imageRatio));
- }
- else
- {
- newH = height;
- newW = jmin (width, roundDoubleToInt (newH / imageRatio));
- }
- }
-
- if (newW > 0 && newH > 0)
- {
- int newX, newY;
- justification.applyToRectangle (newX, newY, newW, newH,
- x, y, width, height);
-
- setBounds (newX, newY, newW, newH);
- }
- }
- }
-
- bool Component::hitTest (int x, int y)
- {
- if (! flags.ignoresMouseClicksFlag)
- return true;
-
- if (flags.allowChildMouseClicksFlag)
- {
- for (int i = getNumChildComponents(); --i >= 0;)
- {
- Component* const c = getChildComponent (i);
-
- if (c->isVisible()
- && c->bounds_.contains (x, y)
- && c->hitTest (x - c->getX(),
- y - c->getY()))
- {
- return true;
- }
- }
- }
-
- return false;
- }
-
- void Component::setInterceptsMouseClicks (const bool allowClicks,
- const bool allowClicksOnChildComponents) throw()
- {
- flags.ignoresMouseClicksFlag = ! allowClicks;
- flags.allowChildMouseClicksFlag = allowClicksOnChildComponents;
- }
-
- void Component::getInterceptsMouseClicks (bool& allowsClicksOnThisComponent,
- bool& allowsClicksOnChildComponents) const throw()
- {
- allowsClicksOnThisComponent = ! flags.ignoresMouseClicksFlag;
- allowsClicksOnChildComponents = flags.allowChildMouseClicksFlag;
- }
-
- bool Component::contains (const int x, const int y)
- {
- if (((unsigned int) x) < (unsigned int) getWidth()
- && ((unsigned int) y) < (unsigned int) getHeight()
- && hitTest (x, y))
- {
- if (parentComponent_ != 0)
- {
- return parentComponent_->contains (x + getX(),
- y + getY());
- }
- else if (flags.hasHeavyweightPeerFlag)
- {
- const ComponentPeer* const peer = getPeer();
-
- if (peer != 0)
- return peer->contains (x, y, true);
- }
- }
-
- return false;
- }
-
- bool Component::reallyContains (int x, int y, const bool returnTrueIfWithinAChild)
- {
- if (! contains (x, y))
- return false;
-
- Component* p = this;
-
- while (p->parentComponent_ != 0)
- {
- x += p->getX();
- y += p->getY();
-
- p = p->parentComponent_;
- }
-
- const Component* const c = p->getComponentAt (x, y);
-
- return (c == this) || (returnTrueIfWithinAChild && isParentOf (c));
- }
-
- Component* Component::getComponentAt (const int x, const int y)
- {
- if (flags.visibleFlag
- && ((unsigned int) x) < (unsigned int) getWidth()
- && ((unsigned int) y) < (unsigned int) getHeight()
- && hitTest (x, y))
- {
- for (int i = childComponentList_.size(); --i >= 0;)
- {
- Component* const child = childComponentList_.getUnchecked(i);
-
- Component* const c = child->getComponentAt (x - child->getX(),
- y - child->getY());
-
- if (c != 0)
- return c;
- }
-
- return this;
- }
-
- return 0;
- }
-
- void Component::addChildComponent (Component* const child, int zOrder)
- {
- // if component methods are being called from threads other than the message
- // thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe.
- checkMessageManagerIsLocked
-
- if (child != 0 && child->parentComponent_ != this)
- {
- if (child->parentComponent_ != 0)
- child->parentComponent_->removeChildComponent (child);
- else
- child->removeFromDesktop();
-
- child->parentComponent_ = this;
-
- if (child->isVisible())
- child->repaintParent();
-
- if (! child->isAlwaysOnTop())
- {
- if (zOrder < 0 || zOrder > childComponentList_.size())
- zOrder = childComponentList_.size();
-
- while (zOrder > 0)
- {
- if (! childComponentList_.getUnchecked (zOrder - 1)->isAlwaysOnTop())
- break;
-
- --zOrder;
- }
- }
-
- childComponentList_.insert (zOrder, child);
-
- child->internalHierarchyChanged();
- internalChildrenChanged();
- }
- }
-
- void Component::addAndMakeVisible (Component* const child, int zOrder)
- {
- if (child != 0)
- {
- child->setVisible (true);
- addChildComponent (child, zOrder);
- }
- }
-
- void Component::removeChildComponent (Component* const child)
- {
- removeChildComponent (childComponentList_.indexOf (child));
- }
-
- Component* Component::removeChildComponent (const int index)
- {
- // if component methods are being called from threads other than the message
- // thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe.
- checkMessageManagerIsLocked
-
- Component* const child = childComponentList_ [index];
-
- if (child != 0)
- {
- sendFakeMouseMove();
- child->repaintParent();
-
- childComponentList_.remove (index);
- child->parentComponent_ = 0;
-
- JUCE_TRY
- {
- if ((currentlyFocusedComponent == child)
- || child->isParentOf (currentlyFocusedComponent))
- {
- // get rid first to force the grabKeyboardFocus to change to us.
- giveAwayFocus();
- grabKeyboardFocus();
- }
- }
- #if JUCE_CATCH_UNHANDLED_EXCEPTIONS
- catch (const std::exception& e)
- {
- currentlyFocusedComponent = 0;
- Desktop::getInstance().triggerFocusCallback();
- JUCEApplication::sendUnhandledException (&e, __FILE__, __LINE__);
- }
- catch (...)
- {
- currentlyFocusedComponent = 0;
- Desktop::getInstance().triggerFocusCallback();
- JUCEApplication::sendUnhandledException (0, __FILE__, __LINE__);
- }
- #endif
-
- child->internalHierarchyChanged();
- internalChildrenChanged();
- }
-
- return child;
- }
-
- void Component::removeAllChildren()
- {
- for (int i = childComponentList_.size(); --i >= 0;)
- removeChildComponent (i);
- }
-
- void Component::deleteAllChildren()
- {
- for (int i = childComponentList_.size(); --i >= 0;)
- delete (removeChildComponent (i));
- }
-
- int Component::getNumChildComponents() const throw()
- {
- return childComponentList_.size();
- }
-
- Component* Component::getChildComponent (const int index) const throw()
- {
- return childComponentList_ [index];
- }
-
- int Component::getIndexOfChildComponent (const Component* const child) const throw()
- {
- return childComponentList_.indexOf (const_cast <Component*> (child));
- }
-
- Component* Component::getTopLevelComponent() const throw()
- {
- const Component* comp = this;
-
- while (comp->parentComponent_ != 0)
- comp = comp->parentComponent_;
-
- return (Component*) comp;
- }
-
- bool Component::isParentOf (const Component* possibleChild) const throw()
- {
- while (possibleChild->isValidComponent())
- {
- possibleChild = possibleChild->parentComponent_;
-
- if (possibleChild == this)
- return true;
- }
-
- return false;
- }
-
- void Component::parentHierarchyChanged()
- {
- }
-
- void Component::childrenChanged()
- {
- }
-
- void Component::internalChildrenChanged()
- {
- const ComponentDeletionWatcher deletionChecker (this);
- const bool hasListeners = componentListeners_ != 0;
-
- childrenChanged();
-
- if (hasListeners)
- {
- if (deletionChecker.hasBeenDeleted())
- return;
-
- for (int i = componentListeners_->size(); --i >= 0;)
- {
- ((ComponentListener*) componentListeners_->getUnchecked (i))
- ->componentChildrenChanged (*this);
-
- if (deletionChecker.hasBeenDeleted())
- return;
-
- i = jmin (i, componentListeners_->size());
- }
- }
- }
-
- void Component::internalHierarchyChanged()
- {
- parentHierarchyChanged();
-
- const ComponentDeletionWatcher deletionChecker (this);
-
- if (componentListeners_ != 0)
- {
- for (int i = componentListeners_->size(); --i >= 0;)
- {
- ((ComponentListener*) componentListeners_->getUnchecked (i))
- ->componentParentHierarchyChanged (*this);
-
- if (deletionChecker.hasBeenDeleted())
- return;
-
- i = jmin (i, componentListeners_->size());
- }
- }
-
- for (int i = childComponentList_.size(); --i >= 0;)
- {
- childComponentList_.getUnchecked (i)->internalHierarchyChanged();
-
- // you really shouldn't delete the parent component during a callback telling you
- // that it's changed..
- jassert (! deletionChecker.hasBeenDeleted());
- if (deletionChecker.hasBeenDeleted())
- return;
-
- i = jmin (i, childComponentList_.size());
- }
- }
-
- void* Component::runModalLoopCallback (void* userData)
- {
- return (void*) (pointer_sized_int) ((Component*) userData)->runModalLoop();
- }
-
- int Component::runModalLoop()
- {
- if (! MessageManager::getInstance()->isThisTheMessageThread())
- {
- // use a callback so this can be called from non-gui threads
- return (int) (pointer_sized_int)
- MessageManager::getInstance()
- ->callFunctionOnMessageThread (&runModalLoopCallback, (void*) this);
- }
-
- Component* const prevFocused = getCurrentlyFocusedComponent();
-
- ComponentDeletionWatcher* deletionChecker = 0;
- if (prevFocused != 0)
- deletionChecker = new ComponentDeletionWatcher (prevFocused);
-
- if (! isCurrentlyModal())
- enterModalState();
-
- JUCE_TRY
- {
- while (flags.currentlyModalFlag && flags.visibleFlag)
- {
- if (! MessageManager::getInstance()->dispatchNextMessage())
- break;
-
- // check whether this component was deleted during the last message
- if (! isValidMessageListener())
- break;
- }
- }
- #if JUCE_CATCH_UNHANDLED_EXCEPTIONS
- catch (const std::exception& e)
- {
- JUCEApplication::sendUnhandledException (&e, __FILE__, __LINE__);
- return 0;
- }
- catch (...)
- {
- JUCEApplication::sendUnhandledException (0, __FILE__, __LINE__);
- return 0;
- }
- #endif
-
- const int modalIndex = modalComponentReturnValueKeys.indexOf (this);
- int returnValue = 0;
-
- if (modalIndex >= 0)
- {
- modalComponentReturnValueKeys.remove (modalIndex);
- returnValue = modalReturnValues.remove (modalIndex);
- }
-
- modalComponentStack.removeValue (this);
-
- if (deletionChecker != 0)
- {
- if (! deletionChecker->hasBeenDeleted())
- prevFocused->grabKeyboardFocus();
-
- delete deletionChecker;
- }
-
- return returnValue;
- }
-
- void Component::enterModalState (const bool takeKeyboardFocus)
- {
- // if component methods are being called from threads other than the message
- // thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe.
- checkMessageManagerIsLocked
-
- // Check for an attempt to make a component modal when it already is!
- // This can cause nasty problems..
- jassert (! flags.currentlyModalFlag);
-
- if (! isCurrentlyModal())
- {
- modalComponentStack.add (this);
- modalComponentReturnValueKeys.add (this);
- modalReturnValues.add (0);
-
- flags.currentlyModalFlag = true;
- setVisible (true);
-
- if (takeKeyboardFocus)
- grabKeyboardFocus();
- }
- }
-
- void Component::exitModalState (const int returnValue)
- {
- if (isCurrentlyModal())
- {
- if (MessageManager::getInstance()->isThisTheMessageThread())
- {
- const int modalIndex = modalComponentReturnValueKeys.indexOf (this);
-
- if (modalIndex >= 0)
- {
- modalReturnValues.set (modalIndex, returnValue);
- }
- else
- {
- modalComponentReturnValueKeys.add (this);
- modalReturnValues.add (returnValue);
- }
-
- modalComponentStack.removeValue (this);
-
- flags.currentlyModalFlag = false;
- }
- else
- {
- postMessage (new Message (exitModalStateMessage, returnValue, 0, 0));
- }
- }
- }
-
- bool Component::isCurrentlyModal() const throw()
- {
- return flags.currentlyModalFlag
- && getCurrentlyModalComponent() == this;
- }
-
- bool Component::isCurrentlyBlockedByAnotherModalComponent() const throw()
- {
- Component* const mc = getCurrentlyModalComponent();
-
- return mc != 0
- && mc != this
- && (! mc->isParentOf (this))
- && ! mc->canModalEventBeSentToComponent (this);
- }
-
- Component* JUCE_CALLTYPE Component::getCurrentlyModalComponent() throw()
- {
- Component* const c = (Component*) modalComponentStack.getLast();
-
- return c->isValidComponent() ? c : 0;
- }
-
- void Component::setBroughtToFrontOnMouseClick (const bool shouldBeBroughtToFront) throw()
- {
- flags.bringToFrontOnClickFlag = shouldBeBroughtToFront;
- }
-
- bool Component::isBroughtToFrontOnMouseClick() const throw()
- {
- return flags.bringToFrontOnClickFlag;
- }
-
- void Component::setMouseCursor (const MouseCursor& cursor) throw()
- {
- cursor_ = cursor;
-
- if (flags.visibleFlag)
- {
- int mx, my;
- getMouseXYRelative (mx, my);
-
- if (flags.draggingFlag || reallyContains (mx, my, false))
- {
- internalUpdateMouseCursor (false);
- }
- }
- }
-
- const MouseCursor Component::getMouseCursor()
- {
- return cursor_;
- }
-
- void Component::updateMouseCursor() const throw()
- {
- sendFakeMouseMove();
- }
-
- void Component::internalUpdateMouseCursor (const bool forcedUpdate) throw()
- {
- ComponentPeer* const peer = getPeer();
-
- if (peer != 0)
- {
- MouseCursor mc (getMouseCursor());
-
- if (isUnboundedMouseModeOn && (unboundedMouseOffsetX != 0
- || unboundedMouseOffsetY != 0
- || ! isCursorVisibleUntilOffscreen))
- {
- mc = MouseCursor::NoCursor;
- }
-
- static void* currentCursorHandle = 0;
-
- if (forcedUpdate || mc.getHandle() != currentCursorHandle)
- {
- currentCursorHandle = mc.getHandle();
- mc.showInWindow (peer);
- }
- }
- }
-
- void Component::setRepaintsOnMouseActivity (const bool shouldRepaint) throw()
- {
- flags.repaintOnMouseActivityFlag = shouldRepaint;
- }
-
- void Component::repaintParent() throw()
- {
- if (flags.visibleFlag)
- internalRepaint (0, 0, getWidth(), getHeight());
- }
-
- void Component::repaint() throw()
- {
- repaint (0, 0, getWidth(), getHeight());
- }
-
- void Component::repaint (const int x, const int y,
- const int w, const int h) throw()
- {
- deleteAndZero (bufferedImage_);
-
- if (flags.visibleFlag)
- internalRepaint (x, y, w, h);
- }
-
- void Component::internalRepaint (int x, int y, int w, int h)
- {
- // if component methods are being called from threads other than the message
- // thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe.
- checkMessageManagerIsLocked
-
- if (x < 0)
- {
- w += x;
- x = 0;
- }
-
- if (x + w > getWidth())
- w = getWidth() - x;
-
- if (w > 0)
- {
- if (y < 0)
- {
- h += y;
- y = 0;
- }
-
- if (y + h > getHeight())
- h = getHeight() - y;
-
- if (h > 0)
- {
- if (parentComponent_ != 0)
- {
- x += getX();
- y += getY();
-
- if (parentComponent_->flags.visibleFlag)
- parentComponent_->internalRepaint (x, y, w, h);
- }
- else if (flags.hasHeavyweightPeerFlag)
- {
- ComponentPeer* const peer = getPeer();
-
- if (peer != 0)
- peer->repaint (x, y, w, h);
- }
- }
- }
- }
-
- void Component::paintEntireComponent (Graphics& originalContext)
- {
- jassert (! originalContext.isClipEmpty());
-
- #ifdef JUCE_DEBUG
- flags.isInsidePaintCall = true;
- #endif
-
- Graphics* g = &originalContext;
- Image* effectImage = 0;
-
- if (effect_ != 0)
- {
- effectImage = new Image (flags.opaqueFlag ? Image::RGB : Image::ARGB,
- getWidth(), getHeight(),
- ! flags.opaqueFlag);
-
- g = new Graphics (*effectImage);
- }
-
- g->saveState();
- clipObscuredRegions (*g, g->getClipBounds(), 0, 0);
-
- if (! g->isClipEmpty())
- {
- if (bufferedImage_ != 0)
- {
- g->setColour (Colours::black);
- g->drawImageAt (bufferedImage_, 0, 0);
- }
- else
- {
- if (flags.bufferToImageFlag)
- {
- if (bufferedImage_ == 0)
- {
- bufferedImage_ = new Image (flags.opaqueFlag ? Image::RGB : Image::ARGB,
- getWidth(), getHeight(), ! flags.opaqueFlag);
-
- Graphics imG (*bufferedImage_);
- paint (imG);
- }
-
- g->setColour (Colours::black);
- g->drawImageAt (bufferedImage_, 0, 0);
- }
- else
- {
- paint (*g);
- g->resetToDefaultState();
- }
- }
- }
-
- g->restoreState();
-
- for (int i = 0; i < childComponentList_.size(); ++i)
- {
- Component* const child = childComponentList_.getUnchecked (i);
-
- if (child->isVisible())
- {
- g->saveState();
-
- if (g->reduceClipRegion (child->getX(), child->getY(),
- child->getWidth(), child->getHeight()))
- {
- for (int j = i + 1; j < childComponentList_.size(); ++j)
- {
- const Component* const sibling = childComponentList_.getUnchecked (j);
-
- if (sibling->flags.opaqueFlag && sibling->isVisible())
- g->excludeClipRegion (sibling->getX(), sibling->getY(),
- sibling->getWidth(), sibling->getHeight());
- }
-
- if (! g->isClipEmpty())
- {
- g->setOrigin (child->getX(), child->getY());
-
- child->paintEntireComponent (*g);
- }
- }
-
- g->restoreState();
- }
- }
-
- JUCE_TRY
- {
- g->saveState();
- paintOverChildren (*g);
- g->restoreState();
- }
- JUCE_CATCH_EXCEPTION
-
- if (effect_ != 0)
- {
- delete g;
-
- effect_->applyEffect (*effectImage, originalContext);
- delete effectImage;
- }
-
- #ifdef JUCE_DEBUG
- flags.isInsidePaintCall = false;
- #endif
- }
-
- Image* Component::createComponentSnapshot (const Rectangle& areaToGrab,
- const bool clipImageToComponentBounds)
- {
- Rectangle r (areaToGrab);
-
- if (clipImageToComponentBounds)
- r = r.getIntersection (Rectangle (0, 0, getWidth(), getHeight()));
-
- Image* const componentImage = new Image (flags.opaqueFlag ? Image::RGB : Image::ARGB,
- jmax (1, r.getWidth()),
- jmax (1, r.getHeight()),
- true);
-
- Graphics imageContext (*componentImage);
- imageContext.setOrigin (-r.getX(),
- -r.getY());
-
- paintEntireComponent (imageContext);
-
- return componentImage;
- }
-
- void Component::setComponentEffect (ImageEffectFilter* const effect)
- {
- if (effect_ != effect)
- {
- effect_ = effect;
- repaint();
- }
- }
-
- LookAndFeel& Component::getLookAndFeel() const throw()
- {
- const Component* c = this;
-
- do
- {
- if (c->lookAndFeel_ != 0)
- return *(c->lookAndFeel_);
-
- c = c->parentComponent_;
- }
- while (c != 0);
-
- return LookAndFeel::getDefaultLookAndFeel();
- }
-
- void Component::setLookAndFeel (LookAndFeel* const newLookAndFeel)
- {
- if (lookAndFeel_ != newLookAndFeel)
- {
- lookAndFeel_ = newLookAndFeel;
-
- sendLookAndFeelChange();
- }
- }
-
- void Component::lookAndFeelChanged()
- {
- }
-
- void Component::sendLookAndFeelChange()
- {
- repaint();
-
- lookAndFeelChanged();
-
- // (it's not a great idea to do anything that would delete this component
- // during the lookAndFeelChanged() callback)
- jassert (isValidComponent());
-
- const ComponentDeletionWatcher deletionChecker (this);
-
- for (int i = childComponentList_.size(); --i >= 0;)
- {
- childComponentList_.getUnchecked (i)->sendLookAndFeelChange();
-
- if (deletionChecker.hasBeenDeleted())
- return;
-
- i = jmin (i, childComponentList_.size());
- }
- }
-
- static const String getColourPropertyName (const int colourId) throw()
- {
- String s;
- s.preallocateStorage (18);
- s << T("jcclr_") << colourId;
- return s;
- }
-
- const Colour Component::findColour (const int colourId, const bool inheritFromParent) const throw()
- {
- const String customColour (getComponentProperty (getColourPropertyName (colourId),
- inheritFromParent,
- String::empty));
-
- if (customColour.isNotEmpty())
- return Colour (customColour.getIntValue());
-
- return getLookAndFeel().findColour (colourId);
- }
-
- bool Component::isColourSpecified (const int colourId) const throw()
- {
- return getComponentProperty (getColourPropertyName (colourId),
- false,
- String::empty).isNotEmpty();
- }
-
- void Component::removeColour (const int colourId)
- {
- if (isColourSpecified (colourId))
- {
- removeComponentProperty (getColourPropertyName (colourId));
- colourChanged();
- }
- }
-
- void Component::setColour (const int colourId, const Colour& colour)
- {
- const String colourName (getColourPropertyName (colourId));
- const String customColour (getComponentProperty (colourName, false, String::empty));
-
- if (customColour.isEmpty() || Colour (customColour.getIntValue()) != colour)
- {
- setComponentProperty (colourName, colour);
- colourChanged();
- }
- }
-
- void Component::copyAllExplicitColoursTo (Component& target) const throw()
- {
- if (propertySet_ != 0)
- {
- const StringPairArray& props = propertySet_->getAllProperties();
- const StringArray& keys = props.getAllKeys();
-
- for (int i = 0; i < keys.size(); ++i)
- {
- if (keys[i].startsWith (T("jcclr_")))
- {
- target.setComponentProperty (keys[i],
- props.getAllValues() [i]);
- }
- }
-
- target.colourChanged();
- }
- }
-
- void Component::colourChanged()
- {
- }
-
- const Rectangle Component::getUnclippedArea() const
- {
- int x = 0, y = 0, w = getWidth(), h = getHeight();
-
- Component* p = parentComponent_;
- int px = getX();
- int py = getY();
-
- while (p != 0)
- {
- if (! Rectangle::intersectRectangles (x, y, w, h, -px, -py, p->getWidth(), p->getHeight()))
- return Rectangle();
-
- px += p->getX();
- py += p->getY();
- p = p->parentComponent_;
- }
-
- return Rectangle (x, y, w, h);
- }
-
- void Component::clipObscuredRegions (Graphics& g, const Rectangle& clipRect,
- const int deltaX, const int deltaY) const throw()
- {
- for (int i = childComponentList_.size(); --i >= 0;)
- {
- const Component* const c = childComponentList_.getUnchecked(i);
-
- if (c->isVisible())
- {
- Rectangle newClip (clipRect.getIntersection (c->bounds_));
-
- if (! newClip.isEmpty())
- {
- if (c->isOpaque())
- {
- g.excludeClipRegion (deltaX + newClip.getX(),
- deltaY + newClip.getY(),
- newClip.getWidth(),
- newClip.getHeight());
- }
- else
- {
- newClip.translate (-c->getX(), -c->getY());
- c->clipObscuredRegions (g, newClip,
- c->getX() + deltaX,
- c->getY() + deltaY);
- }
- }
- }
- }
- }
-
- void Component::getVisibleArea (RectangleList& result,
- const bool includeSiblings) const
- {
- result.clear();
- const Rectangle unclipped (getUnclippedArea());
-
- if (! unclipped.isEmpty())
- {
- result.add (unclipped);
-
- if (includeSiblings)
- {
- const Component* const c = getTopLevelComponent();
-
- int x = 0, y = 0;
- c->relativePositionToOtherComponent (this, x, y);
-
- c->subtractObscuredRegions (result, x, y,
- Rectangle (0, 0, c->getWidth(), c->getHeight()),
- this);
- }
-
- subtractObscuredRegions (result, 0, 0, unclipped, 0);
- result.consolidate();
- }
- }
-
- void Component::subtractObscuredRegions (RectangleList& result,
- const int deltaX,
- const int deltaY,
- const Rectangle& clipRect,
- const Component* const compToAvoid) const throw()
- {
- for (int i = childComponentList_.size(); --i >= 0;)
- {
- const Component* const c = childComponentList_.getUnchecked(i);
-
- if (c != compToAvoid && c->isVisible())
- {
- if (c->isOpaque())
- {
- Rectangle childBounds (c->bounds_.getIntersection (clipRect));
- childBounds.translate (deltaX, deltaY);
-
- result.subtract (childBounds);
- }
- else
- {
- Rectangle newClip (clipRect.getIntersection (c->bounds_));
- newClip.translate (-c->getX(), -c->getY());
-
- c->subtractObscuredRegions (result,
- c->getX() + deltaX,
- c->getY() + deltaY,
- newClip,
- compToAvoid);
- }
- }
- }
- }
-
- void Component::mouseEnter (const MouseEvent&)
- {
- // base class does nothing
- }
-
- void Component::mouseExit (const MouseEvent&)
- {
- // base class does nothing
- }
-
- void Component::mouseDown (const MouseEvent&)
- {
- // base class does nothing
- }
-
- void Component::mouseUp (const MouseEvent&)
- {
- // base class does nothing
- }
-
- void Component::mouseDrag (const MouseEvent&)
- {
- // base class does nothing
- }
-
- void Component::mouseMove (const MouseEvent&)
- {
- // base class does nothing
- }
-
- void Component::mouseDoubleClick (const MouseEvent&)
- {
- // base class does nothing
- }
-
- void Component::mouseWheelMove (const MouseEvent& e, float wheelIncrementX, float wheelIncrementY)
- {
- // the base class just passes this event up to its parent..
-
- if (parentComponent_ != 0)
- parentComponent_->mouseWheelMove (e.getEventRelativeTo (parentComponent_),
- wheelIncrementX, wheelIncrementY);
- }
-
- void Component::resized()
- {
- // base class does nothing
- }
-
- void Component::moved()
- {
- // base class does nothing
- }
-
- void Component::childBoundsChanged (Component*)
- {
- // base class does nothing
- }
-
- void Component::parentSizeChanged()
- {
- // base class does nothing
- }
-
- void Component::addComponentListener (ComponentListener* const newListener) throw()
- {
- if (componentListeners_ == 0)
- componentListeners_ = new VoidArray (4);
-
- componentListeners_->addIfNotAlreadyThere (newListener);
- }
-
- void Component::removeComponentListener (ComponentListener* const listenerToRemove) throw()
- {
- jassert (isValidComponent());
-
- if (componentListeners_ != 0)
- componentListeners_->removeValue (listenerToRemove);
- }
-
- void Component::inputAttemptWhenModal()
- {
- getTopLevelComponent()->toFront (true);
-
- getLookAndFeel().playAlertSound();
- }
-
- bool Component::canModalEventBeSentToComponent (const Component*)
- {
- return false;
- }
-
- void Component::internalModalInputAttempt()
- {
- Component* const current = getCurrentlyModalComponent();
-
- if (current != 0)
- current->inputAttemptWhenModal();
- }
-
- void Component::paint (Graphics&)
- {
- // all painting is done in the subclasses
-
- jassert (! isOpaque()); // if your component's opaque, you've gotta paint it!
- }
-
- void Component::paintOverChildren (Graphics&)
- {
- // all painting is done in the subclasses
- }
-
- void Component::handleMessage (const Message& message)
- {
- if (message.intParameter1 == exitModalStateMessage)
- {
- exitModalState (message.intParameter2);
- }
- else if (message.intParameter1 == customCommandMessage)
- {
- handleCommandMessage (message.intParameter2);
- }
- }
-
- void Component::postCommandMessage (const int commandId) throw()
- {
- postMessage (new Message (customCommandMessage, commandId, 0, 0));
- }
-
- void Component::handleCommandMessage (int)
- {
- // used by subclasses
- }
-
- void Component::addMouseListener (MouseListener* const newListener,
- const bool wantsEventsForAllNestedChildComponents) throw()
- {
- // if component methods are being called from threads other than the message
- // thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe.
- checkMessageManagerIsLocked
-
- if (mouseListeners_ == 0)
- mouseListeners_ = new VoidArray (4);
-
- if (! mouseListeners_->contains (newListener))
- {
- if (wantsEventsForAllNestedChildComponents)
- {
- mouseListeners_->insert (0, newListener);
- ++numDeepMouseListeners;
- }
- else
- {
- mouseListeners_->add (newListener);
- }
- }
- }
-
- void Component::removeMouseListener (MouseListener* const listenerToRemove) throw()
- {
- // if component methods are being called from threads other than the message
- // thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe.
- checkMessageManagerIsLocked
-
- if (mouseListeners_ != 0)
- {
- const int index = mouseListeners_->indexOf (listenerToRemove);
-
- if (index >= 0)
- {
- if (index < numDeepMouseListeners)
- --numDeepMouseListeners;
-
- mouseListeners_->remove (index);
- }
- }
- }
-
- void Component::internalMouseEnter (int x, int y, int64 time)
- {
- if (isCurrentlyBlockedByAnotherModalComponent())
- {
- // if something else is modal, always just show a normal mouse cursor
- if (componentUnderMouse == this)
- {
- ComponentPeer* const peer = getPeer();
-
- if (peer != 0)
- {
- MouseCursor mc (MouseCursor::NormalCursor);
- mc.showInWindow (peer);
- }
- }
-
- return;
- }
-
- if (! flags.mouseInsideFlag)
- {
- flags.mouseInsideFlag = true;
- flags.mouseOverFlag = true;
- flags.draggingFlag = false;
-
- if (isValidComponent())
- {
- const ComponentDeletionWatcher deletionChecker (this);
-
- if (flags.repaintOnMouseActivityFlag)
- repaint();
-
- const MouseEvent me (x, y,
- ModifierKeys::getCurrentModifiers(),
- this,
- Time (time),
- x, y,
- Time (time),
- 0, false);
-
- mouseEnter (me);
-
- if (deletionChecker.hasBeenDeleted())
- return;
-
- Desktop::getInstance().resetTimer();
-
- for (int i = Desktop::getInstance().mouseListeners.size(); --i >= 0;)
- {
- ((MouseListener*) Desktop::getInstance().mouseListeners[i])->mouseEnter (me);
-
- if (deletionChecker.hasBeenDeleted())
- return;
-
- i = jmin (i, Desktop::getInstance().mouseListeners.size());
- }
-
- if (mouseListeners_ != 0)
- {
- for (int i = mouseListeners_->size(); --i >= 0;)
- {
- ((MouseListener*) mouseListeners_->getUnchecked(i))->mouseEnter (me);
-
- if (deletionChecker.hasBeenDeleted())
- return;
-
- i = jmin (i, mouseListeners_->size());
- }
- }
-
- const Component* p = parentComponent_;
-
- while (p != 0)
- {
- const ComponentDeletionWatcher parentDeletionChecker (p);
-
- for (int i = p->numDeepMouseListeners; --i >= 0;)
- {
- ((MouseListener*) (p->mouseListeners_->getUnchecked(i)))->mouseEnter (me);
-
- if (deletionChecker.hasBeenDeleted() || parentDeletionChecker.hasBeenDeleted())
- return;
-
- i = jmin (i, p->numDeepMouseListeners);
- }
-
- p = p->parentComponent_;
- }
- }
- }
-
- if (componentUnderMouse == this)
- internalUpdateMouseCursor (true);
- }
-
- void Component::internalMouseExit (int x, int y, int64 time)
- {
- const ComponentDeletionWatcher deletionChecker (this);
-
- if (flags.draggingFlag)
- {
- internalMouseUp (ModifierKeys::getCurrentModifiers().getRawFlags(), x, y, time);
-
- if (deletionChecker.hasBeenDeleted())
- return;
- }
-
- enableUnboundedMouseMovement (false);
-
- if (flags.mouseInsideFlag || flags.mouseOverFlag)
- {
- flags.mouseInsideFlag = false;
- flags.mouseOverFlag = false;
- flags.draggingFlag = false;
-
- if (flags.repaintOnMouseActivityFlag)
- repaint();
-
- const MouseEvent me (x, y,
- ModifierKeys::getCurrentModifiers(),
- this,
- Time (time),
- x, y,
- Time (time),
- 0, false);
- mouseExit (me);
-
- if (deletionChecker.hasBeenDeleted())
- return;
-
- Desktop::getInstance().resetTimer();
-
- for (int i = Desktop::getInstance().mouseListeners.size(); --i >= 0;)
- {
- ((MouseListener*) Desktop::getInstance().mouseListeners[i])->mouseExit (me);
-
- if (deletionChecker.hasBeenDeleted())
- return;
-
- i = jmin (i, Desktop::getInstance().mouseListeners.size());
- }
-
- if (mouseListeners_ != 0)
- {
- for (int i = mouseListeners_->size(); --i >= 0;)
- {
- ((MouseListener*) mouseListeners_->getUnchecked (i))->mouseExit (me);
-
- if (deletionChecker.hasBeenDeleted())
- return;
-
- i = jmin (i, mouseListeners_->size());
- }
- }
-
- const Component* p = parentComponent_;
-
- while (p != 0)
- {
- const ComponentDeletionWatcher parentDeletionChecker (p);
-
- for (int i = p->numDeepMouseListeners; --i >= 0;)
- {
- ((MouseListener*) (p->mouseListeners_->getUnchecked (i)))->mouseExit (me);
-
- if (deletionChecker.hasBeenDeleted() || parentDeletionChecker.hasBeenDeleted())
- return;
-
- i = jmin (i, p->numDeepMouseListeners);
- }
-
- p = p->parentComponent_;
- }
- }
- }
-
- class InternalDragRepeater : public Timer
- {
- public:
- InternalDragRepeater()
- {}
-
- ~InternalDragRepeater()
- {}
-
- void timerCallback()
- {
- Component* const c = Component::getComponentUnderMouse();
-
- if (c != 0 && c->isMouseButtonDown())
- {
- int x, y;
- c->getMouseXYRelative (x, y);
-
- // the offsets have been added on, so must be taken off before calling the
- // drag.. otherwise they'll be added twice
- x -= unboundedMouseOffsetX;
- y -= unboundedMouseOffsetY;
-
- c->internalMouseDrag (x, y, Time::currentTimeMillis());
- }
- }
-
- juce_UseDebuggingNewOperator
- };
-
- static InternalDragRepeater* dragRepeater = 0;
-
- void Component::beginDragAutoRepeat (const int interval)
- {
- if (interval > 0)
- {
- if (dragRepeater == 0)
- dragRepeater = new InternalDragRepeater();
-
- if (dragRepeater->getTimerInterval() != interval)
- dragRepeater->startTimer (interval);
- }
- else
- {
- deleteAndZero (dragRepeater);
- }
- }
-
- void Component::internalMouseDown (const int x, const int y)
- {
- const ComponentDeletionWatcher deletionChecker (this);
-
- if (isCurrentlyBlockedByAnotherModalComponent())
- {
- internalModalInputAttempt();
-
- if (deletionChecker.hasBeenDeleted())
- return;
-
- // If processing the input attempt has exited the modal loop, we'll allow the event
- // to be delivered..
- if (isCurrentlyBlockedByAnotherModalComponent())
- {
- // allow blocked mouse-events to go to global listeners..
- const MouseEvent me (x, y,
- ModifierKeys::getCurrentModifiers(),
- this,
- Time (juce_recentMouseDownTimes[0]),
- x, y,
- Time (juce_recentMouseDownTimes[0]),
- countMouseClicks(),
- false);
-
- Desktop::getInstance().resetTimer();
-
- for (int i = Desktop::getInstance().mouseListeners.size(); --i >= 0;)
- {
- ((MouseListener*) Desktop::getInstance().mouseListeners[i])->mouseDown (me);
-
- if (deletionChecker.hasBeenDeleted())
- return;
-
- i = jmin (i, Desktop::getInstance().mouseListeners.size());
- }
-
- return;
- }
- }
-
- {
- Component* c = this;
-
- while (c != 0)
- {
- if (c->isBroughtToFrontOnMouseClick())
- {
- c->toFront (true);
-
- if (deletionChecker.hasBeenDeleted())
- return;
- }
-
- c = c->parentComponent_;
- }
- }
-
- if (! flags.dontFocusOnMouseClickFlag)
- grabFocusInternal (focusChangedByMouseClick);
-
- if (! deletionChecker.hasBeenDeleted())
- {
- flags.draggingFlag = true;
- flags.mouseOverFlag = true;
-
- if (flags.repaintOnMouseActivityFlag)
- repaint();
-
- const MouseEvent me (x, y,
- ModifierKeys::getCurrentModifiers(),
- this,
- Time (juce_recentMouseDownTimes[0]),
- x, y,
- Time (juce_recentMouseDownTimes[0]),
- countMouseClicks(),
- false);
- mouseDown (me);
-
- if (deletionChecker.hasBeenDeleted())
- return;
-
- Desktop::getInstance().resetTimer();
-
- for (int i = Desktop::getInstance().mouseListeners.size(); --i >= 0;)
- {
- ((MouseListener*) Desktop::getInstance().mouseListeners[i])->mouseDown (me);
-
- if (deletionChecker.hasBeenDeleted())
- return;
-
- i = jmin (i, Desktop::getInstance().mouseListeners.size());
- }
-
- if (mouseListeners_ != 0)
- {
- for (int i = mouseListeners_->size(); --i >= 0;)
- {
- ((MouseListener*) mouseListeners_->getUnchecked (i))->mouseDown (me);
-
- if (deletionChecker.hasBeenDeleted())
- return;
-
- i = jmin (i, mouseListeners_->size());
- }
- }
-
- const Component* p = parentComponent_;
-
- while (p != 0)
- {
- const ComponentDeletionWatcher parentDeletionChecker (p);
-
- for (int i = p->numDeepMouseListeners; --i >= 0;)
- {
- ((MouseListener*) (p->mouseListeners_->getUnchecked (i)))->mouseDown (me);
-
- if (deletionChecker.hasBeenDeleted() || parentDeletionChecker.hasBeenDeleted())
- return;
-
- i = jmin (i, p->numDeepMouseListeners);
- }
-
- p = p->parentComponent_;
- }
- }
- }
-
- void Component::internalMouseUp (const int oldModifiers, int x, int y, const int64 time)
- {
- if (isValidComponent() && flags.draggingFlag)
- {
- flags.draggingFlag = false;
- deleteAndZero (dragRepeater);
-
- x += unboundedMouseOffsetX;
- y += unboundedMouseOffsetY;
- juce_LastMousePosX = x;
- juce_LastMousePosY = y;
- relativePositionToGlobal (juce_LastMousePosX, juce_LastMousePosY);
-
- const ComponentDeletionWatcher deletionChecker (this);
-
- if (flags.repaintOnMouseActivityFlag)
- repaint();
-
- int mdx = juce_recentMouseDownX[0];
- int mdy = juce_recentMouseDownY[0];
- globalPositionToRelative (mdx, mdy);
-
- const MouseEvent me (x, y,
- oldModifiers,
- this,
- Time (time),
- mdx, mdy,
- Time (juce_recentMouseDownTimes [0]),
- countMouseClicks(),
- juce_MouseHasMovedSignificantlySincePressed
- || juce_recentMouseDownTimes[0] + 300 < time);
-
- mouseUp (me);
-
- if (deletionChecker.hasBeenDeleted())
- return;
-
- Desktop::getInstance().resetTimer();
-
- for (int i = Desktop::getInstance().mouseListeners.size(); --i >= 0;)
- {
- ((MouseListener*) Desktop::getInstance().mouseListeners[i])->mouseUp (me);
-
- if (deletionChecker.hasBeenDeleted())
- return;
-
- i = jmin (i, Desktop::getInstance().mouseListeners.size());
- }
-
- if (mouseListeners_ != 0)
- {
- for (int i = mouseListeners_->size(); --i >= 0;)
- {
- ((MouseListener*) mouseListeners_->getUnchecked (i))->mouseUp (me);
-
- if (deletionChecker.hasBeenDeleted())
- return;
-
- i = jmin (i, mouseListeners_->size());
- }
- }
-
- {
- const Component* p = parentComponent_;
-
- while (p != 0)
- {
- const ComponentDeletionWatcher parentDeletionChecker (p);
-
- for (int i = p->numDeepMouseListeners; --i >= 0;)
- {
- ((MouseListener*) (p->mouseListeners_->getUnchecked (i)))->mouseUp (me);
-
- if (deletionChecker.hasBeenDeleted() || parentDeletionChecker.hasBeenDeleted())
- return;
-
- i = jmin (i, p->numDeepMouseListeners);
- }
-
- p = p->parentComponent_;
- }
- }
-
- // check for double-click
- if (me.getNumberOfClicks() >= 2)
- {
- const int numListeners = (mouseListeners_ != 0) ? mouseListeners_->size() : 0;
-
- mouseDoubleClick (me);
-
- int i;
- for (i = Desktop::getInstance().mouseListeners.size(); --i >= 0;)
- {
- ((MouseListener*) Desktop::getInstance().mouseListeners[i])->mouseDoubleClick (me);
-
- if (deletionChecker.hasBeenDeleted())
- return;
-
- i = jmin (i, Desktop::getInstance().mouseListeners.size());
- }
-
- for (i = numListeners; --i >= 0;)
- {
- if (deletionChecker.hasBeenDeleted() || mouseListeners_ == 0)
- return;
-
- MouseListener* const ml = (MouseListener*)((*mouseListeners_)[i]);
- if (ml != 0)
- ml->mouseDoubleClick (me);
- }
-
- if (deletionChecker.hasBeenDeleted())
- return;
-
- const Component* p = parentComponent_;
-
- while (p != 0)
- {
- const ComponentDeletionWatcher parentDeletionChecker (p);
-
- for (i = p->numDeepMouseListeners; --i >= 0;)
- {
- ((MouseListener*) (p->mouseListeners_->getUnchecked (i)))->mouseDoubleClick (me);
-
- if (deletionChecker.hasBeenDeleted() || parentDeletionChecker.hasBeenDeleted())
- return;
-
- i = jmin (i, p->numDeepMouseListeners);
- }
-
- p = p->parentComponent_;
- }
- }
- }
-
- enableUnboundedMouseMovement (false);
- }
-
- void Component::internalMouseDrag (int x, int y, const int64 time)
- {
- if (isValidComponent() && flags.draggingFlag)
- {
- flags.mouseOverFlag = reallyContains (x, y, false);
-
- x += unboundedMouseOffsetX;
- y += unboundedMouseOffsetY;
- juce_LastMousePosX = x;
- juce_LastMousePosY = y;
- relativePositionToGlobal (juce_LastMousePosX, juce_LastMousePosY);
-
- juce_MouseHasMovedSignificantlySincePressed
- = juce_MouseHasMovedSignificantlySincePressed
- || abs (juce_recentMouseDownX[0] - juce_LastMousePosX) >= 4
- || abs (juce_recentMouseDownY[0] - juce_LastMousePosY) >= 4;
-
- const ComponentDeletionWatcher deletionChecker (this);
-
- int mdx = juce_recentMouseDownX[0];
- int mdy = juce_recentMouseDownY[0];
- globalPositionToRelative (mdx, mdy);
-
- const MouseEvent me (x, y,
- ModifierKeys::getCurrentModifiers(),
- this,
- Time (time),
- mdx, mdy,
- Time (juce_recentMouseDownTimes[0]),
- countMouseClicks(),
- juce_MouseHasMovedSignificantlySincePressed
- || juce_recentMouseDownTimes[0] + 300 < time);
-
- mouseDrag (me);
-
- if (deletionChecker.hasBeenDeleted())
- return;
-
- Desktop::getInstance().resetTimer();
-
- for (int i = Desktop::getInstance().mouseListeners.size(); --i >= 0;)
- {
- ((MouseListener*) Desktop::getInstance().mouseListeners[i])->mouseDrag (me);
-
- if (deletionChecker.hasBeenDeleted())
- return;
-
- i = jmin (i, Desktop::getInstance().mouseListeners.size());
- }
-
- if (mouseListeners_ != 0)
- {
- for (int i = mouseListeners_->size(); --i >= 0;)
- {
- ((MouseListener*) mouseListeners_->getUnchecked (i))->mouseDrag (me);
-
- if (deletionChecker.hasBeenDeleted())
- return;
-
- i = jmin (i, mouseListeners_->size());
- }
- }
-
- const Component* p = parentComponent_;
-
- while (p != 0)
- {
- const ComponentDeletionWatcher parentDeletionChecker (p);
-
- for (int i = p->numDeepMouseListeners; --i >= 0;)
- {
- ((MouseListener*) (p->mouseListeners_->getUnchecked (i)))->mouseDrag (me);
-
- if (deletionChecker.hasBeenDeleted() || parentDeletionChecker.hasBeenDeleted())
- return;
-
- i = jmin (i, p->numDeepMouseListeners);
- }
-
- p = p->parentComponent_;
- }
-
- if (this == componentUnderMouse)
- {
- if (isUnboundedMouseModeOn)
- {
- Rectangle screenArea (getParentMonitorArea().expanded (-2, -2));
-
- int mx, my;
- Desktop::getMousePosition (mx, my);
-
- if (! screenArea.contains (mx, my))
- {
- int deltaX = 0, deltaY = 0;
-
- if (mx <= screenArea.getX() || mx >= screenArea.getRight())
- deltaX = getScreenX() + getWidth() / 2 - mx;
-
- if (my <= screenArea.getY() || my >= screenArea.getBottom())
- deltaY = getScreenY() + getHeight() / 2 - my;
-
- unboundedMouseOffsetX -= deltaX;
- unboundedMouseOffsetY -= deltaY;
-
- Desktop::setMousePosition (mx + deltaX,
- my + deltaY);
- }
- else if (isCursorVisibleUntilOffscreen
- && (unboundedMouseOffsetX != 0 || unboundedMouseOffsetY != 0)
- && screenArea.contains (mx + unboundedMouseOffsetX,
- my + unboundedMouseOffsetY))
- {
- mx += unboundedMouseOffsetX;
- my += unboundedMouseOffsetY;
- unboundedMouseOffsetX = 0;
- unboundedMouseOffsetY = 0;
-
- Desktop::setMousePosition (mx, my);
- }
- }
-
- internalUpdateMouseCursor (false);
- }
- }
- }
-
- void Component::internalMouseMove (const int x, const int y, const int64 time)
- {
- const ComponentDeletionWatcher deletionChecker (this);
-
- if (isValidComponent())
- {
- const MouseEvent me (x, y,
- ModifierKeys::getCurrentModifiers(),
- this,
- Time (time),
- x, y,
- Time (time),
- 0, false);
-
- if (isCurrentlyBlockedByAnotherModalComponent())
- {
- // allow blocked mouse-events to go to global listeners..
- Desktop::getInstance().sendMouseMove();
- }
- else
- {
- if (this == componentUnderMouse)
- internalUpdateMouseCursor (false);
-
- flags.mouseOverFlag = true;
-
- mouseMove (me);
-
- if (deletionChecker.hasBeenDeleted())
- return;
-
- Desktop::getInstance().resetTimer();
-
- for (int i = Desktop::getInstance().mouseListeners.size(); --i >= 0;)
- {
- ((MouseListener*) Desktop::getInstance().mouseListeners[i])->mouseMove (me);
-
- if (deletionChecker.hasBeenDeleted())
- return;
-
- i = jmin (i, Desktop::getInstance().mouseListeners.size());
- }
-
- if (mouseListeners_ != 0)
- {
- for (int i = mouseListeners_->size(); --i >= 0;)
- {
- ((MouseListener*) mouseListeners_->getUnchecked (i))->mouseMove (me);
-
- if (deletionChecker.hasBeenDeleted())
- return;
-
- i = jmin (i, mouseListeners_->size());
- }
- }
-
- const Component* p = parentComponent_;
-
- while (p != 0)
- {
- const ComponentDeletionWatcher parentDeletionChecker (p);
-
- for (int i = p->numDeepMouseListeners; --i >= 0;)
- {
- ((MouseListener*) (p->mouseListeners_->getUnchecked (i)))->mouseMove (me);
-
- if (deletionChecker.hasBeenDeleted() || parentDeletionChecker.hasBeenDeleted())
- return;
-
- i = jmin (i, p->numDeepMouseListeners);
- }
-
- p = p->parentComponent_;
- }
- }
- }
- }
-
- void Component::internalMouseWheel (const int intAmountX, const int intAmountY, const int64 time)
- {
- const ComponentDeletionWatcher deletionChecker (this);
-
- const float wheelIncrementX = intAmountX * (1.0f / 256.0f);
- const float wheelIncrementY = intAmountY * (1.0f / 256.0f);
-
- int mx, my;
- getMouseXYRelative (mx, my);
-
- const MouseEvent me (mx, my,
- ModifierKeys::getCurrentModifiers(),
- this,
- Time (time),
- mx, my,
- Time (time),
- 0, false);
-
- if (isCurrentlyBlockedByAnotherModalComponent())
- {
- // allow blocked mouse-events to go to global listeners..
- for (int i = Desktop::getInstance().mouseListeners.size(); --i >= 0;)
- {
- ((MouseListener*) Desktop::getInstance().mouseListeners[i])->mouseWheelMove (me, wheelIncrementX, wheelIncrementY);
-
- if (deletionChecker.hasBeenDeleted())
- return;
-
- i = jmin (i, Desktop::getInstance().mouseListeners.size());
- }
- }
- else
- {
- mouseWheelMove (me, wheelIncrementX, wheelIncrementY);
-
- if (deletionChecker.hasBeenDeleted())
- return;
-
- for (int i = Desktop::getInstance().mouseListeners.size(); --i >= 0;)
- {
- ((MouseListener*) Desktop::getInstance().mouseListeners[i])->mouseWheelMove (me, wheelIncrementX, wheelIncrementY);
-
- if (deletionChecker.hasBeenDeleted())
- return;
-
- i = jmin (i, Desktop::getInstance().mouseListeners.size());
- }
-
- if (mouseListeners_ != 0)
- {
- for (int i = mouseListeners_->size(); --i >= 0;)
- {
- ((MouseListener*) mouseListeners_->getUnchecked (i))->mouseWheelMove (me, wheelIncrementX, wheelIncrementY);
-
- if (deletionChecker.hasBeenDeleted())
- return;
-
- i = jmin (i, mouseListeners_->size());
- }
- }
-
- const Component* p = parentComponent_;
-
- while (p != 0)
- {
- const ComponentDeletionWatcher parentDeletionChecker (p);
-
- for (int i = p->numDeepMouseListeners; --i >= 0;)
- {
- ((MouseListener*) (p->mouseListeners_->getUnchecked (i)))->mouseWheelMove (me, wheelIncrementX, wheelIncrementY);
-
- if (deletionChecker.hasBeenDeleted() || parentDeletionChecker.hasBeenDeleted())
- return;
-
- i = jmin (i, p->numDeepMouseListeners);
- }
-
- p = p->parentComponent_;
- }
-
- sendFakeMouseMove();
- }
- }
-
- void Component::sendFakeMouseMove() const
- {
- ComponentPeer* const peer = getPeer();
-
- if (peer != 0)
- peer->sendFakeMouseMove();
- }
-
- void Component::broughtToFront()
- {
- }
-
- void Component::internalBroughtToFront()
- {
- if (isValidComponent())
- {
- if (flags.hasHeavyweightPeerFlag)
- Desktop::getInstance().componentBroughtToFront (this);
-
- const ComponentDeletionWatcher deletionChecker (this);
- broughtToFront();
-
- if (deletionChecker.hasBeenDeleted())
- return;
-
- if (componentListeners_ != 0)
- {
- for (int i = componentListeners_->size(); --i >= 0;)
- {
- ((ComponentListener*) componentListeners_->getUnchecked (i))
- ->componentBroughtToFront (*this);
-
- if (deletionChecker.hasBeenDeleted())
- return;
-
- i = jmin (i, componentListeners_->size());
- }
- }
-
- // when brought to the front and there's a modal component blocking this one,
- // we need to bring the modal one to the front instead..
-
- Component* const cm = getCurrentlyModalComponent();
-
- if (cm != 0 && cm->getTopLevelComponent() != getTopLevelComponent())
- {
- cm->getTopLevelComponent()->toFront (false);
- }
- }
- }
-
- void Component::focusGained (FocusChangeType)
- {
- // base class does nothing
- }
-
- void Component::internalFocusGain (const FocusChangeType cause)
- {
- const ComponentDeletionWatcher deletionChecker (this);
-
- focusGained (cause);
-
- if (! deletionChecker.hasBeenDeleted())
- internalChildFocusChange (cause);
- }
-
- void Component::focusLost (FocusChangeType)
- {
- // base class does nothing
- }
-
- void Component::internalFocusLoss (const FocusChangeType cause)
- {
- const ComponentDeletionWatcher deletionChecker (this);
-
- focusLost (focusChangedDirectly);
-
- if (! deletionChecker.hasBeenDeleted())
- internalChildFocusChange (cause);
- }
-
- void Component::focusOfChildComponentChanged (FocusChangeType /*cause*/)
- {
- // base class does nothing
- }
-
- void Component::internalChildFocusChange (FocusChangeType cause)
- {
- const bool childIsNowFocused = hasKeyboardFocus (true);
-
- if (flags.childCompFocusedFlag != childIsNowFocused)
- {
- flags.childCompFocusedFlag = childIsNowFocused;
-
- const ComponentDeletionWatcher deletionChecker (this);
- focusOfChildComponentChanged (cause);
-
- if (deletionChecker.hasBeenDeleted())
- return;
- }
-
- if (parentComponent_ != 0)
- parentComponent_->internalChildFocusChange (cause);
- }
-
- bool Component::isEnabled() const throw()
- {
- return (! flags.isDisabledFlag)
- && (parentComponent_ == 0 || parentComponent_->isEnabled());
- }
-
- void Component::setEnabled (const bool shouldBeEnabled)
- {
- if (flags.isDisabledFlag == shouldBeEnabled)
- {
- flags.isDisabledFlag = ! shouldBeEnabled;
-
- // if any parent components are disabled, setting our flag won't make a difference,
- // so no need to send a change message
- if (parentComponent_ == 0 || parentComponent_->isEnabled())
- sendEnablementChangeMessage();
- }
- }
-
- void Component::sendEnablementChangeMessage()
- {
- const ComponentDeletionWatcher deletionChecker (this);
-
- enablementChanged();
-
- if (deletionChecker.hasBeenDeleted())
- return;
-
- for (int i = getNumChildComponents(); --i >= 0;)
- {
- Component* const c = getChildComponent (i);
-
- if (c != 0)
- {
- c->sendEnablementChangeMessage();
-
- if (deletionChecker.hasBeenDeleted())
- return;
- }
- }
- }
-
- void Component::enablementChanged()
- {
- }
-
- void Component::setWantsKeyboardFocus (const bool wantsFocus) throw()
- {
- flags.wantsFocusFlag = wantsFocus;
- }
-
- void Component::setMouseClickGrabsKeyboardFocus (const bool shouldGrabFocus)
- {
- flags.dontFocusOnMouseClickFlag = ! shouldGrabFocus;
- }
-
- bool Component::getMouseClickGrabsKeyboardFocus() const throw()
- {
- return ! flags.dontFocusOnMouseClickFlag;
- }
-
- bool Component::getWantsKeyboardFocus() const throw()
- {
- return flags.wantsFocusFlag && ! flags.isDisabledFlag;
- }
-
- void Component::setFocusContainer (const bool isFocusContainer) throw()
- {
- flags.isFocusContainerFlag = isFocusContainer;
- }
-
- bool Component::isFocusContainer() const throw()
- {
- return flags.isFocusContainerFlag;
- }
-
- int Component::getExplicitFocusOrder() const throw()
- {
- return getComponentPropertyInt (T("_jexfo"), false, 0);
- }
-
- void Component::setExplicitFocusOrder (const int newFocusOrderIndex) throw()
- {
- setComponentProperty (T("_jexfo"), newFocusOrderIndex);
- }
-
- KeyboardFocusTraverser* Component::createFocusTraverser()
- {
- if (flags.isFocusContainerFlag || parentComponent_ == 0)
- return new KeyboardFocusTraverser();
-
- return parentComponent_->createFocusTraverser();
- }
-
- void Component::takeKeyboardFocus (const FocusChangeType cause)
- {
- // give the focus to this component
- if (currentlyFocusedComponent != this)
- {
- JUCE_TRY
- {
- // get the focus onto our desktop window
- ComponentPeer* const peer = getPeer();
-
- if (peer != 0)
- {
- const ComponentDeletionWatcher deletionChecker (this);
-
- peer->grabFocus();
-
- if (peer->isFocused() && currentlyFocusedComponent != this)
- {
- Component* const componentLosingFocus = currentlyFocusedComponent;
-
- currentlyFocusedComponent = this;
-
- Desktop::getInstance().triggerFocusCallback();
-
- // call this after setting currentlyFocusedComponent so that the one that's
- // losing it has a chance to see where focus is going
- if (componentLosingFocus->isValidComponent())
- componentLosingFocus->internalFocusLoss (cause);
-
- if (currentlyFocusedComponent == this)
- {
- focusGained (cause);
-
- if (! deletionChecker.hasBeenDeleted())
- internalChildFocusChange (cause);
- }
- }
- }
- }
- #if JUCE_CATCH_UNHANDLED_EXCEPTIONS
- catch (const std::exception& e)
- {
- currentlyFocusedComponent = 0;
- Desktop::getInstance().triggerFocusCallback();
- JUCEApplication::sendUnhandledException (&e, __FILE__, __LINE__);
- }
- catch (...)
- {
- currentlyFocusedComponent = 0;
- Desktop::getInstance().triggerFocusCallback();
- JUCEApplication::sendUnhandledException (0, __FILE__, __LINE__);
- }
- #endif
- }
- }
-
- void Component::grabFocusInternal (const FocusChangeType cause, const bool canTryParent)
- {
- if (isShowing())
- {
- if (flags.wantsFocusFlag && (isEnabled() || parentComponent_ == 0))
- {
- takeKeyboardFocus (cause);
- }
- else
- {
- if (isParentOf (currentlyFocusedComponent)
- && currentlyFocusedComponent->isShowing())
- {
- // do nothing if the focused component is actually a child of ours..
- }
- else
- {
- // find the default child component..
- KeyboardFocusTraverser* const traverser = createFocusTraverser();
-
- if (traverser != 0)
- {
- Component* const defaultComp = traverser->getDefaultComponent (this);
- delete traverser;
-
- if (defaultComp != 0)
- {
- defaultComp->grabFocusInternal (cause, false);
- return;
- }
- }
-
- if (canTryParent && parentComponent_ != 0)
- {
- // if no children want it and we're allowed to try our parent comp,
- // then pass up to parent, which will try our siblings.
- parentComponent_->grabFocusInternal (cause, true);
- }
- }
- }
- }
- }
-
- void Component::grabKeyboardFocus()
- {
- // if component methods are being called from threads other than the message
- // thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe.
- checkMessageManagerIsLocked
-
- grabFocusInternal (focusChangedDirectly);
- }
-
- void Component::moveKeyboardFocusToSibling (const bool moveToNext)
- {
- // if component methods are being called from threads other than the message
- // thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe.
- checkMessageManagerIsLocked
-
- if (parentComponent_ != 0)
- {
- KeyboardFocusTraverser* const traverser = createFocusTraverser();
-
- if (traverser != 0)
- {
- Component* const nextComp = moveToNext ? traverser->getNextComponent (this)
- : traverser->getPreviousComponent (this);
- delete traverser;
-
- if (nextComp != 0)
- {
- if (nextComp->isCurrentlyBlockedByAnotherModalComponent())
- {
- const ComponentDeletionWatcher deletionChecker (nextComp);
- internalModalInputAttempt();
-
- if (deletionChecker.hasBeenDeleted()
- || nextComp->isCurrentlyBlockedByAnotherModalComponent())
- return;
- }
-
- nextComp->grabFocusInternal (focusChangedByTabKey);
- return;
- }
- }
-
- parentComponent_->moveKeyboardFocusToSibling (moveToNext);
- }
- }
-
- bool Component::hasKeyboardFocus (const bool trueIfChildIsFocused) const throw()
- {
- return (currentlyFocusedComponent == this)
- || (trueIfChildIsFocused && isParentOf (currentlyFocusedComponent));
- }
-
- Component* JUCE_CALLTYPE Component::getCurrentlyFocusedComponent() throw()
- {
- return currentlyFocusedComponent;
- }
-
- void Component::giveAwayFocus()
- {
- // use a copy so we can clear the value before the call
- Component* const componentLosingFocus = currentlyFocusedComponent;
- currentlyFocusedComponent = 0;
- Desktop::getInstance().triggerFocusCallback();
-
- if (componentLosingFocus->isValidComponent())
- componentLosingFocus->internalFocusLoss (focusChangedDirectly);
- }
-
- bool Component::isMouseOver() const throw()
- {
- return flags.mouseOverFlag;
- }
-
- bool Component::isMouseButtonDown() const throw()
- {
- return flags.draggingFlag;
- }
-
- bool Component::isMouseOverOrDragging() const throw()
- {
- return flags.mouseOverFlag || flags.draggingFlag;
- }
-
- bool JUCE_CALLTYPE Component::isMouseButtonDownAnywhere() throw()
- {
- return ModifierKeys::getCurrentModifiers().isAnyMouseButtonDown();
- }
-
- void Component::getMouseXYRelative (int& mx, int& my) const throw()
- {
- Desktop::getMousePosition (mx, my);
- globalPositionToRelative (mx, my);
-
- mx += unboundedMouseOffsetX;
- my += unboundedMouseOffsetY;
- }
-
- void Component::enableUnboundedMouseMovement (bool enable,
- bool keepCursorVisibleUntilOffscreen) throw()
- {
- enable = enable && isMouseButtonDown();
- isCursorVisibleUntilOffscreen = keepCursorVisibleUntilOffscreen;
-
- if (enable != isUnboundedMouseModeOn)
- {
- if ((! enable) && ((! isCursorVisibleUntilOffscreen)
- || unboundedMouseOffsetX != 0
- || unboundedMouseOffsetY != 0))
- {
- // when released, return the mouse to within the component's bounds
-
- int mx, my;
- getMouseXYRelative (mx, my);
-
- mx = jlimit (0, getWidth(), mx);
- my = jlimit (0, getHeight(), my);
-
- relativePositionToGlobal (mx, my);
-
- Desktop::setMousePosition (mx, my);
- }
-
- isUnboundedMouseModeOn = enable;
- unboundedMouseOffsetX = 0;
- unboundedMouseOffsetY = 0;
-
- internalUpdateMouseCursor (true);
- }
- }
-
- Component* JUCE_CALLTYPE Component::getComponentUnderMouse() throw()
- {
- return componentUnderMouse;
- }
-
- const Rectangle Component::getParentMonitorArea() const throw()
- {
- int centreX = getWidth() / 2;
- int centreY = getHeight() / 2;
- relativePositionToGlobal (centreX, centreY);
-
- return Desktop::getInstance().getMonitorAreaContaining (centreX, centreY);
- }
-
- void Component::addKeyListener (KeyListener* const newListener) throw()
- {
- if (keyListeners_ == 0)
- keyListeners_ = new VoidArray (4);
-
- keyListeners_->addIfNotAlreadyThere (newListener);
- }
-
- void Component::removeKeyListener (KeyListener* const listenerToRemove) throw()
- {
- if (keyListeners_ != 0)
- keyListeners_->removeValue (listenerToRemove);
- }
-
- bool Component::keyPressed (const KeyPress&)
- {
- return false;
- }
-
- bool Component::keyStateChanged()
- {
- return false;
- }
-
- void Component::modifierKeysChanged (const ModifierKeys& modifiers)
- {
- if (parentComponent_ != 0)
- parentComponent_->modifierKeysChanged (modifiers);
- }
-
- void Component::internalModifierKeysChanged()
- {
- sendFakeMouseMove();
-
- modifierKeysChanged (ModifierKeys::getCurrentModifiers());
- }
-
- ComponentPeer* Component::getPeer() const throw()
- {
- if (flags.hasHeavyweightPeerFlag)
- return ComponentPeer::getPeerFor (this);
- else if (parentComponent_ != 0)
- return parentComponent_->getPeer();
- else
- return 0;
- }
-
- const String Component::getComponentProperty (const String& keyName,
- const bool useParentComponentIfNotFound,
- const String& defaultReturnValue) const throw()
- {
- if (propertySet_ != 0 && ((! useParentComponentIfNotFound) || propertySet_->containsKey (keyName)))
- return propertySet_->getValue (keyName, defaultReturnValue);
-
- if (useParentComponentIfNotFound && (parentComponent_ != 0))
- return parentComponent_->getComponentProperty (keyName, true, defaultReturnValue);
-
- return defaultReturnValue;
- }
-
- int Component::getComponentPropertyInt (const String& keyName,
- const bool useParentComponentIfNotFound,
- const int defaultReturnValue) const throw()
- {
- if (propertySet_ != 0 && ((! useParentComponentIfNotFound) || propertySet_->containsKey (keyName)))
- return propertySet_->getIntValue (keyName, defaultReturnValue);
-
- if (useParentComponentIfNotFound && (parentComponent_ != 0))
- return parentComponent_->getComponentPropertyInt (keyName, true, defaultReturnValue);
-
- return defaultReturnValue;
- }
-
- double Component::getComponentPropertyDouble (const String& keyName,
- const bool useParentComponentIfNotFound,
- const double defaultReturnValue) const throw()
- {
- if (propertySet_ != 0 && ((! useParentComponentIfNotFound) || propertySet_->containsKey (keyName)))
- return propertySet_->getDoubleValue (keyName, defaultReturnValue);
-
- if (useParentComponentIfNotFound && (parentComponent_ != 0))
- return parentComponent_->getComponentPropertyDouble (keyName, true, defaultReturnValue);
-
- return defaultReturnValue;
- }
-
- bool Component::getComponentPropertyBool (const String& keyName,
- const bool useParentComponentIfNotFound,
- const bool defaultReturnValue) const throw()
- {
- if (propertySet_ != 0 && ((! useParentComponentIfNotFound) || propertySet_->containsKey (keyName)))
- return propertySet_->getBoolValue (keyName, defaultReturnValue);
-
- if (useParentComponentIfNotFound && (parentComponent_ != 0))
- return parentComponent_->getComponentPropertyBool (keyName, true, defaultReturnValue);
-
- return defaultReturnValue;
- }
-
- const Colour Component::getComponentPropertyColour (const String& keyName,
- const bool useParentComponentIfNotFound,
- const Colour& defaultReturnValue) const throw()
- {
- return Colour ((uint32) getComponentPropertyInt (keyName,
- useParentComponentIfNotFound,
- defaultReturnValue.getARGB()));
- }
-
- void Component::setComponentProperty (const String& keyName, const String& value) throw()
- {
- if (propertySet_ == 0)
- propertySet_ = new PropertySet();
-
- propertySet_->setValue (keyName, value);
- }
-
- void Component::setComponentProperty (const String& keyName, const int value) throw()
- {
- if (propertySet_ == 0)
- propertySet_ = new PropertySet();
-
- propertySet_->setValue (keyName, value);
- }
-
- void Component::setComponentProperty (const String& keyName, const double value) throw()
- {
- if (propertySet_ == 0)
- propertySet_ = new PropertySet();
-
- propertySet_->setValue (keyName, value);
- }
-
- void Component::setComponentProperty (const String& keyName, const bool value) throw()
- {
- if (propertySet_ == 0)
- propertySet_ = new PropertySet();
-
- propertySet_->setValue (keyName, value);
- }
-
- void Component::setComponentProperty (const String& keyName, const Colour& colour) throw()
- {
- setComponentProperty (keyName, (int) colour.getARGB());
- }
-
- void Component::removeComponentProperty (const String& keyName) throw()
- {
- if (propertySet_ != 0)
- propertySet_->removeValue (keyName);
- }
-
- ComponentDeletionWatcher::ComponentDeletionWatcher (const Component* const componentToWatch_) throw()
- : componentToWatch (componentToWatch_),
- componentUID (componentToWatch_->getComponentUID())
- {
- // not possible to check on an already-deleted object..
- jassert (componentToWatch_->isValidComponent());
- }
-
- ComponentDeletionWatcher::~ComponentDeletionWatcher() throw() {}
-
- bool ComponentDeletionWatcher::hasBeenDeleted() const throw()
- {
- return ! (componentToWatch->isValidComponent()
- && componentToWatch->getComponentUID() == componentUID);
- }
-
- const Component* ComponentDeletionWatcher::getComponent() const throw()
- {
- return hasBeenDeleted() ? 0 : componentToWatch;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_Component.cpp *********/
-
- /********* Start of inlined file: juce_ComponentListener.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- void ComponentListener::componentMovedOrResized (Component&, bool, bool)
- {
- }
-
- void ComponentListener::componentBroughtToFront (Component&)
- {
- }
-
- void ComponentListener::componentVisibilityChanged (Component&)
- {
- }
-
- void ComponentListener::componentChildrenChanged (Component&)
- {
- }
-
- void ComponentListener::componentParentHierarchyChanged (Component&)
- {
- }
-
- void ComponentListener::componentNameChanged (Component&)
- {
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_ComponentListener.cpp *********/
-
- /********* Start of inlined file: juce_Desktop.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- extern void juce_updateMultiMonitorInfo (Array <Rectangle>& monitorCoords,
- const bool clipToWorkArea) throw();
-
- static Desktop* juce_desktopInstance = 0;
-
- Desktop::Desktop() throw()
- : mouseListeners (2),
- desktopComponents (4),
- monitorCoordsClipped (2),
- monitorCoordsUnclipped (2),
- lastMouseX (0),
- lastMouseY (0)
- {
- refreshMonitorSizes();
- }
-
- Desktop::~Desktop() throw()
- {
- jassert (juce_desktopInstance == this);
- juce_desktopInstance = 0;
-
- // doh! If you don't delete all your windows before exiting, you're going to
- // be leaking memory!
- jassert (desktopComponents.size() == 0);
- }
-
- Desktop& JUCE_CALLTYPE Desktop::getInstance() throw()
- {
- if (juce_desktopInstance == 0)
- juce_desktopInstance = new Desktop();
-
- return *juce_desktopInstance;
- }
-
- void Desktop::refreshMonitorSizes() throw()
- {
- const Array <Rectangle> oldClipped (monitorCoordsClipped);
- const Array <Rectangle> oldUnclipped (monitorCoordsUnclipped);
-
- monitorCoordsClipped.clear();
- monitorCoordsUnclipped.clear();
- juce_updateMultiMonitorInfo (monitorCoordsClipped, true);
- juce_updateMultiMonitorInfo (monitorCoordsUnclipped, false);
- jassert (monitorCoordsClipped.size() > 0
- && monitorCoordsClipped.size() == monitorCoordsUnclipped.size());
-
- if (oldClipped != monitorCoordsClipped
- || oldUnclipped != monitorCoordsUnclipped)
- {
- for (int i = ComponentPeer::getNumPeers(); --i >= 0;)
- {
- ComponentPeer* const p = ComponentPeer::getPeer (i);
- if (p != 0)
- p->handleScreenSizeChange();
- }
- }
- }
-
- int Desktop::getNumDisplayMonitors() const throw()
- {
- return monitorCoordsClipped.size();
- }
-
- const Rectangle Desktop::getDisplayMonitorCoordinates (const int index, const bool clippedToWorkArea) const throw()
- {
- return clippedToWorkArea ? monitorCoordsClipped [index]
- : monitorCoordsUnclipped [index];
- }
-
- const RectangleList Desktop::getAllMonitorDisplayAreas (const bool clippedToWorkArea) const throw()
- {
- RectangleList rl;
-
- for (int i = 0; i < getNumDisplayMonitors(); ++i)
- rl.addWithoutMerging (getDisplayMonitorCoordinates (i, clippedToWorkArea));
-
- return rl;
- }
-
- const Rectangle Desktop::getMainMonitorArea (const bool clippedToWorkArea) const throw()
- {
- return getDisplayMonitorCoordinates (0, clippedToWorkArea);
- }
-
- const Rectangle Desktop::getMonitorAreaContaining (int cx, int cy, const bool clippedToWorkArea) const throw()
- {
- Rectangle best (getMainMonitorArea (clippedToWorkArea));
- double bestDistance = 1.0e10;
-
- for (int i = getNumDisplayMonitors(); --i >= 0;)
- {
- const Rectangle rect (getDisplayMonitorCoordinates (i, clippedToWorkArea));
-
- if (rect.contains (cx, cy))
- return rect;
-
- const double distance = juce_hypot ((double) (rect.getCentreX() - cx),
- (double) (rect.getCentreY() - cy));
-
- if (distance < bestDistance)
- {
- bestDistance = distance;
- best = rect;
- }
- }
-
- return best;
- }
-
- int Desktop::getNumComponents() const throw()
- {
- return desktopComponents.size();
- }
-
- Component* Desktop::getComponent (const int index) const throw()
- {
- return (Component*) desktopComponents [index];
- }
-
- Component* Desktop::findComponentAt (const int screenX,
- const int screenY) const
- {
- for (int i = desktopComponents.size(); --i >= 0;)
- {
- Component* const c = (Component*) desktopComponents.getUnchecked(i);
-
- int x = screenX, y = screenY;
- c->globalPositionToRelative (x, y);
-
- if (c->contains (x, y))
- return c->getComponentAt (x, y);
- }
-
- return 0;
- }
-
- void Desktop::addDesktopComponent (Component* const c) throw()
- {
- jassert (c != 0);
- jassert (! desktopComponents.contains (c));
- desktopComponents.addIfNotAlreadyThere (c);
- }
-
- void Desktop::removeDesktopComponent (Component* const c) throw()
- {
- desktopComponents.removeValue (c);
- }
-
- void Desktop::componentBroughtToFront (Component* const c) throw()
- {
- const int index = desktopComponents.indexOf (c);
- jassert (index >= 0);
-
- if (index >= 0)
- desktopComponents.move (index, -1);
- }
-
- // from Component.cpp
- extern int juce_recentMouseDownX [4];
- extern int juce_recentMouseDownY [4];
- extern int juce_MouseClickCounter;
-
- void Desktop::getLastMouseDownPosition (int& x, int& y) throw()
- {
- x = juce_recentMouseDownX [0];
- y = juce_recentMouseDownY [0];
- }
-
- int Desktop::getMouseButtonClickCounter() throw()
- {
- return juce_MouseClickCounter;
- }
-
- void Desktop::addGlobalMouseListener (MouseListener* const listener) throw()
- {
- jassert (listener != 0);
-
- if (listener != 0)
- {
- mouseListeners.add (listener);
- resetTimer();
- }
- }
-
- void Desktop::removeGlobalMouseListener (MouseListener* const listener) throw()
- {
- mouseListeners.removeValue (listener);
- resetTimer();
- }
-
- void Desktop::addFocusChangeListener (FocusChangeListener* const listener) throw()
- {
- jassert (listener != 0);
-
- if (listener != 0)
- focusListeners.add (listener);
- }
-
- void Desktop::removeFocusChangeListener (FocusChangeListener* const listener) throw()
- {
- focusListeners.removeValue (listener);
- }
-
- void Desktop::triggerFocusCallback() throw()
- {
- triggerAsyncUpdate();
- }
-
- void Desktop::handleAsyncUpdate()
- {
- for (int i = focusListeners.size(); --i >= 0;)
- {
- ((FocusChangeListener*) focusListeners.getUnchecked (i))->globalFocusChanged (Component::getCurrentlyFocusedComponent());
- i = jmin (i, focusListeners.size());
- }
- }
-
- void Desktop::timerCallback()
- {
- int x, y;
- getMousePosition (x, y);
-
- if (lastMouseX != x || lastMouseY != y)
- sendMouseMove();
- }
-
- void Desktop::sendMouseMove()
- {
- if (mouseListeners.size() > 0)
- {
- startTimer (20);
-
- int x, y;
- getMousePosition (x, y);
- lastMouseX = x;
- lastMouseY = y;
-
- Component* const target = findComponentAt (x, y);
-
- if (target != 0)
- {
- target->globalPositionToRelative (x, y);
-
- ComponentDeletionWatcher deletionChecker (target);
-
- const MouseEvent me (x, y,
- ModifierKeys::getCurrentModifiers(),
- target,
- Time::getCurrentTime(),
- x, y,
- Time::getCurrentTime(),
- 0, false);
-
- for (int i = mouseListeners.size(); --i >= 0;)
- {
- if (ModifierKeys::getCurrentModifiers().isAnyMouseButtonDown())
- ((MouseListener*) mouseListeners[i])->mouseDrag (me);
- else
- ((MouseListener*) mouseListeners[i])->mouseMove (me);
-
- if (deletionChecker.hasBeenDeleted())
- return;
-
- i = jmin (i, mouseListeners.size());
- }
- }
- }
- }
-
- void Desktop::resetTimer() throw()
- {
- if (mouseListeners.size() == 0)
- stopTimer();
- else
- startTimer (100);
-
- getMousePosition (lastMouseX, lastMouseY);
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_Desktop.cpp *********/
-
- /********* Start of inlined file: juce_ArrowButton.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- ArrowButton::ArrowButton (const String& name,
- float arrowDirectionInRadians,
- const Colour& arrowColour)
- : Button (name),
- colour (arrowColour)
- {
- path.lineTo (0.0f, 1.0f);
- path.lineTo (1.0f, 0.5f);
- path.closeSubPath();
-
- path.applyTransform (AffineTransform::rotation (float_Pi * 2.0f * arrowDirectionInRadians,
- 0.5f, 0.5f));
-
- setComponentEffect (&shadow);
- buttonStateChanged();
- }
-
- ArrowButton::~ArrowButton()
- {
- }
-
- void ArrowButton::paintButton (Graphics& g,
- bool /*isMouseOverButton*/,
- bool /*isButtonDown*/)
- {
- g.setColour (colour);
-
- g.fillPath (path, path.getTransformToScaleToFit ((float) offset,
- (float) offset,
- (float) (getWidth() - 3),
- (float) (getHeight() - 3),
- false));
- }
-
- void ArrowButton::buttonStateChanged()
- {
- offset = (isDown()) ? 1 : 0;
-
- shadow.setShadowProperties ((isDown()) ? 1.2f : 3.0f,
- 0.3f, -1, 0);
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_ArrowButton.cpp *********/
-
- /********* Start of inlined file: juce_Button.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- Button::Button (const String& name)
- : Component (name),
- shortcuts (2),
- keySource (0),
- text (name),
- buttonListeners (2),
- repeatTimer (0),
- buttonPressTime (0),
- lastTimeCallbackTime (0),
- commandManagerToUse (0),
- autoRepeatDelay (-1),
- autoRepeatSpeed (0),
- autoRepeatMinimumDelay (-1),
- radioGroupId (0),
- commandID (0),
- connectedEdgeFlags (0),
- buttonState (buttonNormal),
- isOn (false),
- clickTogglesState (false),
- needsToRelease (false),
- needsRepainting (false),
- isKeyDown (false),
- triggerOnMouseDown (false),
- generateTooltip (false)
- {
- setWantsKeyboardFocus (true);
- }
-
- Button::~Button()
- {
- if (commandManagerToUse != 0)
- commandManagerToUse->removeListener (this);
-
- delete repeatTimer;
- clearShortcuts();
- }
-
- void Button::setButtonText (const String& newText) throw()
- {
- if (text != newText)
- {
- text = newText;
- repaint();
- }
- }
-
- void Button::setTooltip (const String& newTooltip)
- {
- SettableTooltipClient::setTooltip (newTooltip);
- generateTooltip = false;
- }
-
- const String Button::getTooltip()
- {
- if (generateTooltip && commandManagerToUse != 0 && commandID != 0)
- {
- String tt (commandManagerToUse->getDescriptionOfCommand (commandID));
-
- Array <KeyPress> keyPresses (commandManagerToUse->getKeyMappings()->getKeyPressesAssignedToCommand (commandID));
-
- for (int i = 0; i < keyPresses.size(); ++i)
- {
- const String key (keyPresses.getReference(i).getTextDescription());
-
- if (key.length() == 1)
- tt << " [shortcut: '" << key << "']";
- else
- tt << " [" << key << ']';
- }
-
- return tt;
- }
-
- return SettableTooltipClient::getTooltip();
- }
-
- void Button::setConnectedEdges (const int connectedEdgeFlags_) throw()
- {
- if (connectedEdgeFlags != connectedEdgeFlags_)
- {
- connectedEdgeFlags = connectedEdgeFlags_;
- repaint();
- }
- }
-
- void Button::setToggleState (const bool shouldBeOn,
- const bool sendChangeNotification)
- {
- if (shouldBeOn != isOn)
- {
- const ComponentDeletionWatcher deletionWatcher (this);
-
- isOn = shouldBeOn;
- repaint();
-
- if (sendChangeNotification)
- sendClickMessage (ModifierKeys());
-
- if ((! deletionWatcher.hasBeenDeleted()) && isOn)
- turnOffOtherButtonsInGroup (sendChangeNotification);
- }
- }
-
- void Button::setClickingTogglesState (const bool shouldToggle) throw()
- {
- clickTogglesState = shouldToggle;
-
- // if you've got clickTogglesState turned on, you shouldn't also connect the button
- // up to be a command invoker. Instead, your command handler must flip the state of whatever
- // it is that this button represents, and the button will update its state to reflect this
- // in the applicationCommandListChanged() method.
- jassert (commandManagerToUse == 0 || ! clickTogglesState);
- }
-
- bool Button::getClickingTogglesState() const throw()
- {
- return clickTogglesState;
- }
-
- void Button::setRadioGroupId (const int newGroupId)
- {
- if (radioGroupId != newGroupId)
- {
- radioGroupId = newGroupId;
-
- if (isOn)
- turnOffOtherButtonsInGroup (true);
- }
- }
-
- void Button::turnOffOtherButtonsInGroup (const bool sendChangeNotification)
- {
- Component* const p = getParentComponent();
-
- if (p != 0 && radioGroupId != 0)
- {
- const ComponentDeletionWatcher deletionWatcher (this);
-
- for (int i = p->getNumChildComponents(); --i >= 0;)
- {
- Component* const c = p->getChildComponent (i);
-
- if (c != this)
- {
- Button* const b = dynamic_cast <Button*> (c);
-
- if (b != 0 && b->getRadioGroupId() == radioGroupId)
- {
- b->setToggleState (false, sendChangeNotification);
-
- if (deletionWatcher.hasBeenDeleted())
- return;
- }
- }
- }
- }
- }
-
- void Button::enablementChanged()
- {
- updateState (0);
- repaint();
- }
-
- Button::ButtonState Button::updateState (const MouseEvent* const e) throw()
- {
- ButtonState state = buttonNormal;
-
- if (isEnabled() && isVisible() && ! isCurrentlyBlockedByAnotherModalComponent())
- {
- int mx, my;
-
- if (e == 0)
- {
- getMouseXYRelative (mx, my);
- }
- else
- {
- const MouseEvent e2 (e->getEventRelativeTo (this));
- mx = e2.x;
- my = e2.y;
- }
-
- const bool over = reallyContains (mx, my, true);
- const bool down = isMouseButtonDown();
-
- if ((down && (over || (triggerOnMouseDown && buttonState == buttonDown))) || isKeyDown)
- state = buttonDown;
- else if (over)
- state = buttonOver;
- }
-
- setState (state);
- return state;
- }
-
- void Button::setState (const ButtonState newState)
- {
- if (buttonState != newState)
- {
- buttonState = newState;
- repaint();
-
- if (buttonState == buttonDown)
- {
- buttonPressTime = Time::getApproximateMillisecondCounter();
- lastTimeCallbackTime = buttonPressTime;
- }
-
- sendStateMessage();
- }
- }
-
- bool Button::isDown() const throw()
- {
- return buttonState == buttonDown;
- }
-
- bool Button::isOver() const throw()
- {
- return buttonState != buttonNormal;
- }
-
- void Button::buttonStateChanged()
- {
- }
-
- uint32 Button::getMillisecondsSinceButtonDown() const throw()
- {
- const uint32 now = Time::getApproximateMillisecondCounter();
- return now > buttonPressTime ? now - buttonPressTime : 0;
- }
-
- void Button::setTriggeredOnMouseDown (const bool isTriggeredOnMouseDown) throw()
- {
- triggerOnMouseDown = isTriggeredOnMouseDown;
- }
-
- void Button::clicked()
- {
- }
-
- void Button::clicked (const ModifierKeys& /*modifiers*/)
- {
- clicked();
- }
-
- static const int clickMessageId = 0x2f3f4f99;
-
- void Button::triggerClick()
- {
- postCommandMessage (clickMessageId);
- }
-
- void Button::internalClickCallback (const ModifierKeys& modifiers)
- {
- if (clickTogglesState)
- setToggleState ((radioGroupId != 0) || ! isOn, false);
-
- sendClickMessage (modifiers);
- }
-
- void Button::flashButtonState() throw()
- {
- if (isEnabled())
- {
- needsToRelease = true;
- setState (buttonDown);
- getRepeatTimer().startTimer (100);
- }
- }
-
- void Button::handleCommandMessage (int commandId)
- {
- if (commandId == clickMessageId)
- {
- if (isEnabled())
- {
- flashButtonState();
- internalClickCallback (ModifierKeys::getCurrentModifiers());
- }
- }
- else
- {
- Component::handleCommandMessage (commandId);
- }
- }
-
- void Button::addButtonListener (ButtonListener* const newListener) throw()
- {
- jassert (newListener != 0);
- jassert (! buttonListeners.contains (newListener)); // trying to add a listener to the list twice!
-
- if (newListener != 0)
- buttonListeners.add (newListener);
- }
-
- void Button::removeButtonListener (ButtonListener* const listener) throw()
- {
- jassert (buttonListeners.contains (listener)); // trying to remove a listener that isn't on the list!
-
- buttonListeners.removeValue (listener);
- }
-
- void Button::sendClickMessage (const ModifierKeys& modifiers)
- {
- const ComponentDeletionWatcher cdw (this);
-
- if (commandManagerToUse != 0 && commandID != 0)
- {
- ApplicationCommandTarget::InvocationInfo info (commandID);
- info.invocationMethod = ApplicationCommandTarget::InvocationInfo::fromButton;
- info.originatingComponent = this;
-
- commandManagerToUse->invoke (info, true);
- }
-
- clicked (modifiers);
-
- if (! cdw.hasBeenDeleted())
- {
- for (int i = buttonListeners.size(); --i >= 0;)
- {
- ButtonListener* const bl = (ButtonListener*) buttonListeners[i];
-
- if (bl != 0)
- {
- bl->buttonClicked (this);
-
- if (cdw.hasBeenDeleted())
- return;
- }
- }
- }
- }
-
- void Button::sendStateMessage()
- {
- const ComponentDeletionWatcher cdw (this);
-
- buttonStateChanged();
-
- if (cdw.hasBeenDeleted())
- return;
-
- for (int i = buttonListeners.size(); --i >= 0;)
- {
- ButtonListener* const bl = (ButtonListener*) buttonListeners[i];
-
- if (bl != 0)
- {
- bl->buttonStateChanged (this);
-
- if (cdw.hasBeenDeleted())
- return;
- }
- }
- }
-
- void Button::paint (Graphics& g)
- {
- if (needsToRelease && isEnabled())
- {
- needsToRelease = false;
- needsRepainting = true;
- }
-
- paintButton (g, isOver(), isDown());
- }
-
- void Button::mouseEnter (const MouseEvent& e)
- {
- updateState (&e);
- }
-
- void Button::mouseExit (const MouseEvent& e)
- {
- updateState (&e);
- }
-
- void Button::mouseDown (const MouseEvent& e)
- {
- updateState (&e);
-
- if (isDown())
- {
- if (autoRepeatDelay >= 0)
- getRepeatTimer().startTimer (autoRepeatDelay);
-
- if (triggerOnMouseDown)
- internalClickCallback (e.mods);
- }
- }
-
- void Button::mouseUp (const MouseEvent& e)
- {
- const bool wasDown = isDown();
- updateState (&e);
-
- if (wasDown && isOver() && ! triggerOnMouseDown)
- internalClickCallback (e.mods);
- }
-
- void Button::mouseDrag (const MouseEvent& e)
- {
- const ButtonState oldState = buttonState;
- updateState (&e);
-
- if (autoRepeatDelay >= 0 && buttonState != oldState && isDown())
- getRepeatTimer().startTimer (autoRepeatSpeed);
- }
-
- void Button::focusGained (FocusChangeType)
- {
- updateState (0);
- repaint();
- }
-
- void Button::focusLost (FocusChangeType)
- {
- updateState (0);
- repaint();
- }
-
- void Button::setVisible (bool shouldBeVisible)
- {
- if (shouldBeVisible != isVisible())
- {
- Component::setVisible (shouldBeVisible);
-
- if (! shouldBeVisible)
- needsToRelease = false;
-
- updateState (0);
- }
- else
- {
- Component::setVisible (shouldBeVisible);
- }
- }
-
- void Button::parentHierarchyChanged()
- {
- Component* const newKeySource = (shortcuts.size() == 0) ? 0 : getTopLevelComponent();
-
- if (newKeySource != keySource)
- {
- if (keySource->isValidComponent())
- keySource->removeKeyListener (this);
-
- keySource = newKeySource;
-
- if (keySource->isValidComponent())
- keySource->addKeyListener (this);
- }
- }
-
- void Button::setCommandToTrigger (ApplicationCommandManager* const commandManagerToUse_,
- const int commandID_,
- const bool generateTooltip_)
- {
- commandID = commandID_;
- generateTooltip = generateTooltip_;
-
- if (commandManagerToUse != commandManagerToUse_)
- {
- if (commandManagerToUse != 0)
- commandManagerToUse->removeListener (this);
-
- commandManagerToUse = commandManagerToUse_;
-
- if (commandManagerToUse != 0)
- commandManagerToUse->addListener (this);
-
- // if you've got clickTogglesState turned on, you shouldn't also connect the button
- // up to be a command invoker. Instead, your command handler must flip the state of whatever
- // it is that this button represents, and the button will update its state to reflect this
- // in the applicationCommandListChanged() method.
- jassert (commandManagerToUse == 0 || ! clickTogglesState);
- }
-
- if (commandManagerToUse != 0)
- applicationCommandListChanged();
- else
- setEnabled (true);
- }
-
- void Button::applicationCommandInvoked (const ApplicationCommandTarget::InvocationInfo& info)
- {
- if (info.commandID == commandID
- && (info.commandFlags & ApplicationCommandInfo::dontTriggerVisualFeedback) == 0)
- {
- flashButtonState();
- }
- }
-
- void Button::applicationCommandListChanged()
- {
- if (commandManagerToUse != 0)
- {
- ApplicationCommandInfo info (0);
-
- ApplicationCommandTarget* const target = commandManagerToUse->getTargetForCommand (commandID, info);
-
- setEnabled (target != 0 && (info.flags & ApplicationCommandInfo::isDisabled) == 0);
-
- if (target != 0)
- setToggleState ((info.flags & ApplicationCommandInfo::isTicked) != 0, false);
- }
- }
-
- void Button::addShortcut (const KeyPress& key)
- {
- if (key.isValid())
- {
- jassert (! isRegisteredForShortcut (key)); // already registered!
-
- shortcuts.add (key);
- parentHierarchyChanged();
- }
- }
-
- void Button::clearShortcuts()
- {
- shortcuts.clear();
-
- parentHierarchyChanged();
- }
-
- bool Button::isShortcutPressed() const throw()
- {
- if (! isCurrentlyBlockedByAnotherModalComponent())
- {
- for (int i = shortcuts.size(); --i >= 0;)
- if (shortcuts.getReference(i).isCurrentlyDown())
- return true;
- }
-
- return false;
- }
-
- bool Button::isRegisteredForShortcut (const KeyPress& key) const throw()
- {
- for (int i = shortcuts.size(); --i >= 0;)
- if (key == shortcuts.getReference(i))
- return true;
-
- return false;
- }
-
- bool Button::keyStateChanged (Component*)
- {
- if (! isEnabled())
- return false;
-
- const bool wasDown = isKeyDown;
- isKeyDown = isShortcutPressed();
-
- if (autoRepeatDelay >= 0 && (isKeyDown && ! wasDown))
- getRepeatTimer().startTimer (autoRepeatDelay);
-
- updateState (0);
-
- if (isEnabled() && wasDown && ! isKeyDown)
- internalClickCallback (ModifierKeys::getCurrentModifiers());
-
- return isKeyDown || wasDown;
- }
-
- bool Button::keyPressed (const KeyPress&, Component*)
- {
- // returning true will avoid forwarding events for keys that we're using as shortcuts
- return isShortcutPressed();
- }
-
- bool Button::keyPressed (const KeyPress& key)
- {
- if (isEnabled() && key.isKeyCode (KeyPress::returnKey))
- {
- triggerClick();
- return true;
- }
-
- return false;
- }
-
- void Button::setRepeatSpeed (const int initialDelayMillisecs,
- const int repeatMillisecs,
- const int minimumDelayInMillisecs) throw()
- {
- autoRepeatDelay = initialDelayMillisecs;
- autoRepeatSpeed = repeatMillisecs;
- autoRepeatMinimumDelay = jmin (autoRepeatSpeed, minimumDelayInMillisecs);
- }
-
- void Button::repeatTimerCallback() throw()
- {
- if (needsRepainting)
- {
- getRepeatTimer().stopTimer();
- updateState (0);
- needsRepainting = false;
- }
- else if (autoRepeatSpeed > 0 && (isKeyDown || (updateState (0) == buttonDown)))
- {
- int repeatSpeed = autoRepeatSpeed;
-
- if (autoRepeatMinimumDelay >= 0)
- {
- double timeHeldDown = jmin (1.0, getMillisecondsSinceButtonDown() / 4000.0);
- timeHeldDown *= timeHeldDown;
-
- repeatSpeed = repeatSpeed + (int) (timeHeldDown * (autoRepeatMinimumDelay - repeatSpeed));
- }
-
- repeatSpeed = jmax (1, repeatSpeed);
-
- getRepeatTimer().startTimer (repeatSpeed);
-
- const uint32 now = Time::getApproximateMillisecondCounter();
- const int numTimesToCallback
- = (now > lastTimeCallbackTime) ? jmax (1, (now - lastTimeCallbackTime) / repeatSpeed) : 1;
-
- lastTimeCallbackTime = now;
-
- const ComponentDeletionWatcher cdw (this);
-
- for (int i = numTimesToCallback; --i >= 0;)
- {
- internalClickCallback (ModifierKeys::getCurrentModifiers());
-
- if (cdw.hasBeenDeleted() || ! isDown())
- return;
- }
- }
- else if (! needsToRelease)
- {
- getRepeatTimer().stopTimer();
- }
- }
-
- class InternalButtonRepeatTimer : public Timer
- {
- public:
- InternalButtonRepeatTimer (Button& owner_) throw()
- : owner (owner_)
- {
- }
-
- ~InternalButtonRepeatTimer()
- {
- }
-
- void timerCallback()
- {
- owner.repeatTimerCallback();
- }
-
- private:
- Button& owner;
-
- InternalButtonRepeatTimer (const InternalButtonRepeatTimer&);
- const InternalButtonRepeatTimer& operator= (const InternalButtonRepeatTimer&);
- };
-
- Timer& Button::getRepeatTimer() throw()
- {
- if (repeatTimer == 0)
- repeatTimer = new InternalButtonRepeatTimer (*this);
-
- return *repeatTimer;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_Button.cpp *********/
-
- /********* Start of inlined file: juce_DrawableButton.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- DrawableButton::DrawableButton (const String& name,
- const DrawableButton::ButtonStyle buttonStyle)
- : Button (name),
- style (buttonStyle),
- normalImage (0),
- overImage (0),
- downImage (0),
- disabledImage (0),
- normalImageOn (0),
- overImageOn (0),
- downImageOn (0),
- disabledImageOn (0),
- edgeIndent (3)
- {
- if (buttonStyle == ImageOnButtonBackground)
- {
- backgroundOff = Colour (0xffbbbbff);
- backgroundOn = Colour (0xff3333ff);
- }
- else
- {
- backgroundOff = Colours::transparentBlack;
- backgroundOn = Colour (0xaabbbbff);
- }
- }
-
- DrawableButton::~DrawableButton()
- {
- deleteImages();
- }
-
- void DrawableButton::deleteImages()
- {
- deleteAndZero (normalImage);
- deleteAndZero (overImage);
- deleteAndZero (downImage);
- deleteAndZero (disabledImage);
- deleteAndZero (normalImageOn);
- deleteAndZero (overImageOn);
- deleteAndZero (downImageOn);
- deleteAndZero (disabledImageOn);
- }
-
- void DrawableButton::setImages (const Drawable* normal,
- const Drawable* over,
- const Drawable* down,
- const Drawable* disabled,
- const Drawable* normalOn,
- const Drawable* overOn,
- const Drawable* downOn,
- const Drawable* disabledOn)
- {
- deleteImages();
-
- jassert (normal != 0); // you really need to give it at least a normal image..
-
- if (normal != 0)
- normalImage = normal->createCopy();
-
- if (over != 0)
- overImage = over->createCopy();
-
- if (down != 0)
- downImage = down->createCopy();
-
- if (disabled != 0)
- disabledImage = disabled->createCopy();
-
- if (normalOn != 0)
- normalImageOn = normalOn->createCopy();
-
- if (overOn != 0)
- overImageOn = overOn->createCopy();
-
- if (downOn != 0)
- downImageOn = downOn->createCopy();
-
- if (disabledOn != 0)
- disabledImageOn = disabledOn->createCopy();
-
- repaint();
- }
-
- void DrawableButton::setButtonStyle (const DrawableButton::ButtonStyle newStyle)
- {
- if (style != newStyle)
- {
- style = newStyle;
- repaint();
- }
- }
-
- void DrawableButton::setBackgroundColours (const Colour& toggledOffColour,
- const Colour& toggledOnColour)
- {
- if (backgroundOff != toggledOffColour
- || backgroundOn != toggledOnColour)
- {
- backgroundOff = toggledOffColour;
- backgroundOn = toggledOnColour;
-
- repaint();
- }
- }
-
- const Colour& DrawableButton::getBackgroundColour() const throw()
- {
- return getToggleState() ? backgroundOn
- : backgroundOff;
- }
-
- void DrawableButton::setEdgeIndent (const int numPixelsIndent)
- {
- edgeIndent = numPixelsIndent;
- repaint();
- }
-
- void DrawableButton::paintButton (Graphics& g,
- bool isMouseOverButton,
- bool isButtonDown)
- {
- Rectangle imageSpace;
-
- if (style == ImageOnButtonBackground)
- {
- const int insetX = getWidth() / 4;
- const int insetY = getHeight() / 4;
-
- imageSpace.setBounds (insetX, insetY, getWidth() - insetX * 2, getHeight() - insetY * 2);
-
- getLookAndFeel().drawButtonBackground (g, *this,
- getBackgroundColour(),
- isMouseOverButton,
- isButtonDown);
- }
- else
- {
- g.fillAll (getBackgroundColour());
-
- const int textH = (style == ImageAboveTextLabel)
- ? jmin (16, proportionOfHeight (0.25f))
- : 0;
-
- const int indentX = jmin (edgeIndent, proportionOfWidth (0.3f));
- const int indentY = jmin (edgeIndent, proportionOfHeight (0.3f));
-
- imageSpace.setBounds (indentX, indentY,
- getWidth() - indentX * 2,
- getHeight() - indentY * 2 - textH);
-
- if (textH > 0)
- {
- g.setFont ((float) textH);
-
- g.setColour (Colours::black.withAlpha (isEnabled() ? 1.0f : 0.4f));
- g.drawFittedText (getName(),
- 2, getHeight() - textH - 1,
- getWidth() - 4, textH,
- Justification::centred, 1);
- }
- }
-
- g.setImageResamplingQuality (Graphics::mediumResamplingQuality);
- g.setOpacity (1.0f);
-
- const Drawable* imageToDraw = 0;
-
- if (isEnabled())
- {
- imageToDraw = getCurrentImage();
- }
- else
- {
- imageToDraw = getToggleState() ? disabledImageOn
- : disabledImage;
-
- if (imageToDraw == 0)
- {
- g.setOpacity (0.4f);
- imageToDraw = getNormalImage();
- }
- }
-
- if (imageToDraw != 0)
- {
- if (style == ImageRaw)
- {
- imageToDraw->draw (g);
- }
- else
- {
- imageToDraw->drawWithin (g,
- imageSpace.getX(),
- imageSpace.getY(),
- imageSpace.getWidth(),
- imageSpace.getHeight(),
- RectanglePlacement::centred);
- }
- }
- }
-
- const Drawable* DrawableButton::getCurrentImage() const throw()
- {
- if (isDown())
- return getDownImage();
-
- if (isOver())
- return getOverImage();
-
- return getNormalImage();
- }
-
- const Drawable* DrawableButton::getNormalImage() const throw()
- {
- return (getToggleState() && normalImageOn != 0) ? normalImageOn
- : normalImage;
- }
-
- const Drawable* DrawableButton::getOverImage() const throw()
- {
- const Drawable* d = normalImage;
-
- if (getToggleState())
- {
- if (overImageOn != 0)
- d = overImageOn;
- else if (normalImageOn != 0)
- d = normalImageOn;
- else if (overImage != 0)
- d = overImage;
- }
- else
- {
- if (overImage != 0)
- d = overImage;
- }
-
- return d;
- }
-
- const Drawable* DrawableButton::getDownImage() const throw()
- {
- const Drawable* d = normalImage;
-
- if (getToggleState())
- {
- if (downImageOn != 0)
- d = downImageOn;
- else if (overImageOn != 0)
- d = overImageOn;
- else if (normalImageOn != 0)
- d = normalImageOn;
- else if (downImage != 0)
- d = downImage;
- else
- d = getOverImage();
- }
- else
- {
- if (downImage != 0)
- d = downImage;
- else
- d = getOverImage();
- }
-
- return d;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_DrawableButton.cpp *********/
-
- /********* Start of inlined file: juce_HyperlinkButton.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- HyperlinkButton::HyperlinkButton (const String& linkText,
- const URL& linkURL)
- : Button (linkText),
- url (linkURL),
- font (14.0f, Font::underlined),
- resizeFont (true),
- justification (Justification::centred)
- {
- setMouseCursor (MouseCursor::PointingHandCursor);
- setTooltip (linkURL.toString (false));
- }
-
- HyperlinkButton::~HyperlinkButton()
- {
- }
-
- void HyperlinkButton::setFont (const Font& newFont,
- const bool resizeToMatchComponentHeight,
- const Justification& justificationType)
- {
- font = newFont;
- resizeFont = resizeToMatchComponentHeight;
- justification = justificationType;
- repaint();
- }
-
- void HyperlinkButton::setURL (const URL& newURL) throw()
- {
- url = newURL;
- setTooltip (newURL.toString (false));
- }
-
- const Font HyperlinkButton::getFontToUse() const
- {
- Font f (font);
-
- if (resizeFont)
- f.setHeight (getHeight() * 0.7f);
-
- return f;
- }
-
- void HyperlinkButton::changeWidthToFitText()
- {
- setSize (getFontToUse().getStringWidth (getName()) + 6, getHeight());
- }
-
- void HyperlinkButton::colourChanged()
- {
- repaint();
- }
-
- void HyperlinkButton::clicked()
- {
- if (url.isWellFormed())
- url.launchInDefaultBrowser();
- }
-
- void HyperlinkButton::paintButton (Graphics& g,
- bool isMouseOverButton,
- bool isButtonDown)
- {
- const Colour textColour (findColour (textColourId));
-
- if (isEnabled())
- g.setColour ((isMouseOverButton) ? textColour.darker ((isButtonDown) ? 1.3f : 0.4f)
- : textColour);
- else
- g.setColour (textColour.withMultipliedAlpha (0.4f));
-
- g.setFont (getFontToUse());
-
- g.drawText (getButtonText(),
- 2, 0, getWidth() - 2, getHeight(),
- justification.getOnlyHorizontalFlags() | Justification::verticallyCentred,
- true);
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_HyperlinkButton.cpp *********/
-
- /********* Start of inlined file: juce_ImageButton.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- ImageButton::ImageButton (const String& text)
- : Button (text),
- scaleImageToFit (true),
- preserveProportions (true),
- alphaThreshold (0),
- imageX (0),
- imageY (0),
- imageW (0),
- imageH (0),
- normalImage (0),
- overImage (0),
- downImage (0)
- {
- }
-
- ImageButton::~ImageButton()
- {
- deleteImages();
- }
-
- void ImageButton::deleteImages()
- {
- if (normalImage != 0)
- {
- if (ImageCache::isImageInCache (normalImage))
- ImageCache::release (normalImage);
- else
- delete normalImage;
- }
-
- if (overImage != 0)
- {
- if (ImageCache::isImageInCache (overImage))
- ImageCache::release (overImage);
- else
- delete overImage;
- }
-
- if (downImage != 0)
- {
- if (ImageCache::isImageInCache (downImage))
- ImageCache::release (downImage);
- else
- delete downImage;
- }
- }
-
- void ImageButton::setImages (const bool resizeButtonNowToFitThisImage,
- const bool rescaleImagesWhenButtonSizeChanges,
- const bool preserveImageProportions,
- Image* const normalImage_,
- const float imageOpacityWhenNormal,
- const Colour& overlayColourWhenNormal,
- Image* const overImage_,
- const float imageOpacityWhenOver,
- const Colour& overlayColourWhenOver,
- Image* const downImage_,
- const float imageOpacityWhenDown,
- const Colour& overlayColourWhenDown,
- const float hitTestAlphaThreshold)
- {
- deleteImages();
-
- normalImage = normalImage_;
- overImage = overImage_;
- downImage = downImage_;
-
- if (resizeButtonNowToFitThisImage && normalImage != 0)
- {
- imageW = normalImage->getWidth();
- imageH = normalImage->getHeight();
-
- setSize (imageW, imageH);
- }
-
- scaleImageToFit = rescaleImagesWhenButtonSizeChanges;
- preserveProportions = preserveImageProportions;
-
- normalOpacity = imageOpacityWhenNormal;
- normalOverlay = overlayColourWhenNormal;
- overOpacity = imageOpacityWhenOver;
- overOverlay = overlayColourWhenOver;
- downOpacity = imageOpacityWhenDown;
- downOverlay = overlayColourWhenDown;
-
- alphaThreshold = (unsigned char) jlimit (0, 0xff, roundFloatToInt (255.0f * hitTestAlphaThreshold));
-
- repaint();
- }
-
- Image* ImageButton::getCurrentImage() const
- {
- if (isDown())
- return getDownImage();
-
- if (isOver())
- return getOverImage();
-
- return getNormalImage();
- }
-
- Image* ImageButton::getNormalImage() const throw()
- {
- return normalImage;
- }
-
- Image* ImageButton::getOverImage() const throw()
- {
- return (overImage != 0) ? overImage
- : normalImage;
- }
-
- Image* ImageButton::getDownImage() const throw()
- {
- return (downImage != 0) ? downImage
- : getOverImage();
- }
-
- void ImageButton::paintButton (Graphics& g,
- bool isMouseOverButton,
- bool isButtonDown)
- {
- if (! isEnabled())
- {
- isMouseOverButton = false;
- isButtonDown = false;
- }
-
- Image* const im = getCurrentImage();
-
- if (im != 0)
- {
- const int iw = im->getWidth();
- const int ih = im->getHeight();
- imageW = getWidth();
- imageH = getHeight();
- imageX = (imageW - iw) >> 1;
- imageY = (imageH - ih) >> 1;
-
- if (scaleImageToFit)
- {
- if (preserveProportions)
- {
- int newW, newH;
- const float imRatio = ih / (float)iw;
- const float destRatio = imageH / (float)imageW;
-
- if (imRatio > destRatio)
- {
- newW = roundFloatToInt (imageH / imRatio);
- newH = imageH;
- }
- else
- {
- newW = imageW;
- newH = roundFloatToInt (imageW * imRatio);
- }
-
- imageX = (imageW - newW) / 2;
- imageY = (imageH - newH) / 2;
- imageW = newW;
- imageH = newH;
- }
- else
- {
- imageX = 0;
- imageY = 0;
- }
- }
-
- const Colour& overlayColour = (isButtonDown) ? downOverlay
- : ((isMouseOverButton) ? overOverlay
- : normalOverlay);
-
- if (! overlayColour.isOpaque())
- {
- g.setOpacity ((isButtonDown) ? downOpacity
- : ((isMouseOverButton) ? overOpacity
- : normalOpacity));
-
- if (scaleImageToFit)
- g.drawImage (im, imageX, imageY, imageW, imageH, 0, 0, iw, ih, false);
- else
- g.drawImageAt (im, imageX, imageY, false);
- }
-
- if (! overlayColour.isTransparent())
- {
- g.setColour (overlayColour);
-
- if (scaleImageToFit)
- g.drawImage (im, imageX, imageY, imageW, imageH, 0, 0, iw, ih, true);
- else
- g.drawImageAt (im, imageX, imageY, true);
- }
- }
- }
-
- bool ImageButton::hitTest (int x, int y)
- {
- if (alphaThreshold == 0)
- return true;
-
- Image* const im = getCurrentImage();
-
- return im == 0
- || (imageW > 0 && imageH > 0
- && alphaThreshold < im->getPixelAt (((x - imageX) * im->getWidth()) / imageW,
- ((y - imageY) * im->getHeight()) / imageH).getAlpha());
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_ImageButton.cpp *********/
-
- /********* Start of inlined file: juce_ShapeButton.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- ShapeButton::ShapeButton (const String& text,
- const Colour& normalColour_,
- const Colour& overColour_,
- const Colour& downColour_)
- : Button (text),
- normalColour (normalColour_),
- overColour (overColour_),
- downColour (downColour_),
- maintainShapeProportions (false),
- outlineWidth (0.0f)
- {
- }
-
- ShapeButton::~ShapeButton()
- {
- }
-
- void ShapeButton::setColours (const Colour& newNormalColour,
- const Colour& newOverColour,
- const Colour& newDownColour)
- {
- normalColour = newNormalColour;
- overColour = newOverColour;
- downColour = newDownColour;
- }
-
- void ShapeButton::setOutline (const Colour& newOutlineColour,
- const float newOutlineWidth)
- {
- outlineColour = newOutlineColour;
- outlineWidth = newOutlineWidth;
- }
-
- void ShapeButton::setShape (const Path& newShape,
- const bool resizeNowToFitThisShape,
- const bool maintainShapeProportions_,
- const bool hasShadow)
- {
- shape = newShape;
- maintainShapeProportions = maintainShapeProportions_;
-
- shadow.setShadowProperties (3.0f, 0.5f, 0, 0);
- setComponentEffect ((hasShadow) ? &shadow : 0);
-
- if (resizeNowToFitThisShape)
- {
- float x, y, w, h;
- shape.getBounds (x, y, w, h);
- shape.applyTransform (AffineTransform::translation (-x, -y));
-
- if (hasShadow)
- {
- w += 4.0f;
- h += 4.0f;
- shape.applyTransform (AffineTransform::translation (2.0f, 2.0f));
- }
-
- setSize (1 + (int) (w + outlineWidth),
- 1 + (int) (h + outlineWidth));
- }
- }
-
- void ShapeButton::paintButton (Graphics& g, bool isMouseOverButton, bool isButtonDown)
- {
- if (! isEnabled())
- {
- isMouseOverButton = false;
- isButtonDown = false;
- }
-
- g.setColour ((isButtonDown) ? downColour
- : (isMouseOverButton) ? overColour
- : normalColour);
-
- int w = getWidth();
- int h = getHeight();
-
- if (getComponentEffect() != 0)
- {
- w -= 4;
- h -= 4;
- }
-
- const float offset = (outlineWidth * 0.5f) + (isButtonDown ? 1.5f : 0.0f);
-
- const AffineTransform trans (shape.getTransformToScaleToFit (offset, offset,
- w - offset - outlineWidth,
- h - offset - outlineWidth,
- maintainShapeProportions));
- g.fillPath (shape, trans);
-
- if (outlineWidth > 0.0f)
- {
- g.setColour (outlineColour);
- g.strokePath (shape, PathStrokeType (outlineWidth), trans);
- }
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_ShapeButton.cpp *********/
-
- /********* Start of inlined file: juce_TextButton.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- TextButton::TextButton (const String& name,
- const String& toolTip)
- : Button (name)
- {
- setTooltip (toolTip);
- }
-
- TextButton::~TextButton()
- {
- }
-
- void TextButton::paintButton (Graphics& g,
- bool isMouseOverButton,
- bool isButtonDown)
- {
- getLookAndFeel().drawButtonBackground (g, *this,
- findColour (getToggleState() ? buttonOnColourId
- : buttonColourId),
- isMouseOverButton,
- isButtonDown);
-
- getLookAndFeel().drawButtonText (g, *this,
- isMouseOverButton,
- isButtonDown);
- }
-
- void TextButton::colourChanged()
- {
- repaint();
- }
-
- const Font TextButton::getFont()
- {
- return Font (jmin (15.0f, getHeight() * 0.6f));
- }
-
- void TextButton::changeWidthToFitText (const int newHeight)
- {
- if (newHeight >= 0)
- setSize (jmax (1, getWidth()), newHeight);
-
- setSize (getFont().getStringWidth (getButtonText()) + getHeight(),
- getHeight());
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_TextButton.cpp *********/
-
- /********* Start of inlined file: juce_ToggleButton.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- ToggleButton::ToggleButton (const String& buttonText)
- : Button (buttonText)
- {
- setClickingTogglesState (true);
- }
-
- ToggleButton::~ToggleButton()
- {
- }
-
- void ToggleButton::paintButton (Graphics& g,
- bool isMouseOverButton,
- bool isButtonDown)
- {
- getLookAndFeel().drawToggleButton (g, *this,
- isMouseOverButton,
- isButtonDown);
- }
-
- void ToggleButton::changeWidthToFitText()
- {
- getLookAndFeel().changeToggleButtonWidthToFitText (*this);
- }
-
- void ToggleButton::colourChanged()
- {
- repaint();
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_ToggleButton.cpp *********/
-
- /********* Start of inlined file: juce_ToolbarButton.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- ToolbarButton::ToolbarButton (const int itemId,
- const String& buttonText,
- Drawable* const normalImage_,
- Drawable* const toggledOnImage_)
- : ToolbarItemComponent (itemId, buttonText, true),
- normalImage (normalImage_),
- toggledOnImage (toggledOnImage_)
- {
- }
-
- ToolbarButton::~ToolbarButton()
- {
- delete normalImage;
- delete toggledOnImage;
- }
-
- bool ToolbarButton::getToolbarItemSizes (int toolbarDepth,
- bool /*isToolbarVertical*/,
- int& preferredSize,
- int& minSize, int& maxSize)
- {
- preferredSize = minSize = maxSize = toolbarDepth;
- return true;
- }
-
- void ToolbarButton::paintButtonArea (Graphics& g,
- int width, int height,
- bool /*isMouseOver*/,
- bool /*isMouseDown*/)
- {
- Drawable* d = normalImage;
-
- if (getToggleState() && toggledOnImage != 0)
- d = toggledOnImage;
-
- if (! isEnabled())
- {
- Image im (Image::ARGB, width, height, true);
- Graphics g2 (im);
- d->drawWithin (g2, 0, 0, width, height, RectanglePlacement::centred);
- im.desaturate();
-
- g.drawImageAt (&im, 0, 0);
- }
- else
- {
- d->drawWithin (g, 0, 0, width, height, RectanglePlacement::centred);
- }
- }
-
- void ToolbarButton::contentAreaChanged (const Rectangle&)
- {
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_ToolbarButton.cpp *********/
-
- /********* Start of inlined file: juce_ComboBox.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- ComboBox::ComboBox (const String& name)
- : Component (name),
- items (4),
- currentIndex (-1),
- isButtonDown (false),
- separatorPending (false),
- menuActive (false),
- listeners (2),
- label (0)
- {
- noChoicesMessage = TRANS("(no choices)");
- setRepaintsOnMouseActivity (true);
-
- lookAndFeelChanged();
- }
-
- ComboBox::~ComboBox()
- {
- if (menuActive)
- PopupMenu::dismissAllActiveMenus();
-
- deleteAllChildren();
- }
-
- void ComboBox::setEditableText (const bool isEditable)
- {
- label->setEditable (isEditable, isEditable, false);
-
- setWantsKeyboardFocus (! isEditable);
- resized();
- }
-
- bool ComboBox::isTextEditable() const throw()
- {
- return label->isEditable();
- }
-
- void ComboBox::setJustificationType (const Justification& justification) throw()
- {
- label->setJustificationType (justification);
- }
-
- const Justification ComboBox::getJustificationType() const throw()
- {
- return label->getJustificationType();
- }
-
- void ComboBox::setTooltip (const String& newTooltip)
- {
- SettableTooltipClient::setTooltip (newTooltip);
- label->setTooltip (newTooltip);
- }
-
- void ComboBox::addItem (const String& newItemText,
- const int newItemId) throw()
- {
- // you can't add empty strings to the list..
- jassert (newItemText.isNotEmpty());
-
- // IDs must be non-zero, as zero is used to indicate a lack of selecion.
- jassert (newItemId != 0);
-
- // you shouldn't use duplicate item IDs!
- jassert (getItemForId (newItemId) == 0);
-
- if (newItemText.isNotEmpty() && newItemId != 0)
- {
- if (separatorPending)
- {
- separatorPending = false;
-
- ItemInfo* const item = new ItemInfo();
- item->itemId = 0;
- item->isEnabled = false;
- item->isHeading = false;
- items.add (item);
- }
-
- ItemInfo* const item = new ItemInfo();
- item->name = newItemText;
- item->itemId = newItemId;
- item->isEnabled = true;
- item->isHeading = false;
- items.add (item);
- }
- }
-
- void ComboBox::addSeparator() throw()
- {
- separatorPending = (items.size() > 0);
- }
-
- void ComboBox::addSectionHeading (const String& headingName) throw()
- {
- // you can't add empty strings to the list..
- jassert (headingName.isNotEmpty());
-
- if (headingName.isNotEmpty())
- {
- if (separatorPending)
- {
- separatorPending = false;
-
- ItemInfo* const item = new ItemInfo();
- item->itemId = 0;
- item->isEnabled = false;
- item->isHeading = false;
- items.add (item);
- }
-
- ItemInfo* const item = new ItemInfo();
- item->name = headingName;
- item->itemId = 0;
- item->isEnabled = true;
- item->isHeading = true;
- items.add (item);
- }
- }
-
- void ComboBox::setItemEnabled (const int itemId,
- const bool isEnabled) throw()
- {
- ItemInfo* const item = getItemForId (itemId);
-
- if (item != 0)
- item->isEnabled = isEnabled;
- }
-
- void ComboBox::changeItemText (const int itemId,
- const String& newText) throw()
- {
- ItemInfo* const item = getItemForId (itemId);
-
- jassert (item != 0);
-
- if (item != 0)
- item->name = newText;
- }
-
- void ComboBox::clear (const bool dontSendChangeMessage)
- {
- items.clear();
- separatorPending = false;
-
- if (! label->isEditable())
- setSelectedItemIndex (-1, dontSendChangeMessage);
- }
-
- ComboBox::ItemInfo* ComboBox::getItemForId (const int itemId) const throw()
- {
- jassert (itemId != 0);
-
- if (itemId != 0)
- {
- for (int i = items.size(); --i >= 0;)
- if (items.getUnchecked(i)->itemId == itemId)
- return items.getUnchecked(i);
- }
-
- return 0;
- }
-
- ComboBox::ItemInfo* ComboBox::getItemForIndex (const int index) const throw()
- {
- int n = 0;
-
- for (int i = 0; i < items.size(); ++i)
- {
- ItemInfo* const item = items.getUnchecked(i);
-
- if (item->isRealItem())
- {
- if (n++ == index)
- return item;
- }
- }
-
- return 0;
- }
-
- int ComboBox::getNumItems() const throw()
- {
- int n = 0;
-
- for (int i = items.size(); --i >= 0;)
- {
- ItemInfo* const item = items.getUnchecked(i);
-
- if (item->isRealItem())
- ++n;
- }
-
- return n;
- }
-
- const String ComboBox::getItemText (const int index) const throw()
- {
- ItemInfo* const item = getItemForIndex (index);
-
- if (item != 0)
- return item->name;
-
- return String::empty;
- }
-
- int ComboBox::getItemId (const int index) const throw()
- {
- ItemInfo* const item = getItemForIndex (index);
-
- return (item != 0) ? item->itemId : 0;
- }
-
- bool ComboBox::ItemInfo::isSeparator() const throw()
- {
- return name.isEmpty();
- }
-
- bool ComboBox::ItemInfo::isRealItem() const throw()
- {
- return ! (isHeading || name.isEmpty());
- }
-
- int ComboBox::getSelectedItemIndex() const throw()
- {
- return (currentIndex >= 0 && getText() == getItemText (currentIndex))
- ? currentIndex
- : -1;
- }
-
- void ComboBox::setSelectedItemIndex (const int index,
- const bool dontSendChangeMessage) throw()
- {
- if (currentIndex != index || label->getText() != getItemText (currentIndex))
- {
- if (((unsigned int) index) < (unsigned int) getNumItems())
- currentIndex = index;
- else
- currentIndex = -1;
-
- label->setText (getItemText (currentIndex), false);
-
- if (! dontSendChangeMessage)
- triggerAsyncUpdate();
- }
- }
-
- void ComboBox::setSelectedId (const int newItemId,
- const bool dontSendChangeMessage) throw()
- {
- for (int i = getNumItems(); --i >= 0;)
- {
- if (getItemId(i) == newItemId)
- {
- setSelectedItemIndex (i, dontSendChangeMessage);
- break;
- }
- }
- }
-
- int ComboBox::getSelectedId() const throw()
- {
- const ItemInfo* const item = getItemForIndex (currentIndex);
-
- return (item != 0 && getText() == item->name)
- ? item->itemId
- : 0;
- }
-
- void ComboBox::addListener (ComboBoxListener* const listener) throw()
- {
- jassert (listener != 0);
- if (listener != 0)
- listeners.add (listener);
- }
-
- void ComboBox::removeListener (ComboBoxListener* const listener) throw()
- {
- listeners.removeValue (listener);
- }
-
- void ComboBox::handleAsyncUpdate()
- {
- for (int i = listeners.size(); --i >= 0;)
- {
- ((ComboBoxListener*) listeners.getUnchecked (i))->comboBoxChanged (this);
- i = jmin (i, listeners.size());
- }
- }
-
- const String ComboBox::getText() const throw()
- {
- return label->getText();
- }
-
- void ComboBox::setText (const String& newText,
- const bool dontSendChangeMessage) throw()
- {
- for (int i = items.size(); --i >= 0;)
- {
- ItemInfo* const item = items.getUnchecked(i);
-
- if (item->isRealItem()
- && item->name == newText)
- {
- setSelectedId (item->itemId, dontSendChangeMessage);
- return;
- }
- }
-
- currentIndex = -1;
-
- if (label->getText() != newText)
- {
- label->setText (newText, false);
-
- if (! dontSendChangeMessage)
- triggerAsyncUpdate();
- }
-
- repaint();
- }
-
- void ComboBox::showEditor()
- {
- jassert (isTextEditable()); // you probably shouldn't do this to a non-editable combo box?
-
- label->showEditor();
- }
-
- void ComboBox::setTextWhenNothingSelected (const String& newMessage) throw()
- {
- textWhenNothingSelected = newMessage;
- repaint();
- }
-
- const String ComboBox::getTextWhenNothingSelected() const throw()
- {
- return textWhenNothingSelected;
- }
-
- void ComboBox::setTextWhenNoChoicesAvailable (const String& newMessage) throw()
- {
- noChoicesMessage = newMessage;
- }
-
- const String ComboBox::getTextWhenNoChoicesAvailable() const throw()
- {
- return noChoicesMessage;
- }
-
- void ComboBox::paint (Graphics& g)
- {
- getLookAndFeel().drawComboBox (g,
- getWidth(),
- getHeight(),
- isButtonDown,
- label->getRight(),
- 0,
- getWidth() - label->getRight(),
- getHeight(),
- *this);
-
- if (textWhenNothingSelected.isNotEmpty()
- && label->getText().isEmpty()
- && ! label->isBeingEdited())
- {
- g.setColour (findColour (textColourId).withMultipliedAlpha (0.5f));
- g.setFont (label->getFont());
- g.drawFittedText (textWhenNothingSelected,
- label->getX() + 2, label->getY() + 1,
- label->getWidth() - 4, label->getHeight() - 2,
- label->getJustificationType(),
- jmax (1, (int) (label->getHeight() / label->getFont().getHeight())));
- }
- }
-
- void ComboBox::resized()
- {
- if (getHeight() > 0 && getWidth() > 0)
- getLookAndFeel().positionComboBoxText (*this, *label);
- }
-
- void ComboBox::enablementChanged()
- {
- repaint();
- }
-
- void ComboBox::lookAndFeelChanged()
- {
- repaint();
-
- Label* const newLabel = getLookAndFeel().createComboBoxTextBox (*this);
-
- if (label != 0)
- {
- newLabel->setEditable (label->isEditable());
- newLabel->setJustificationType (label->getJustificationType());
- newLabel->setTooltip (label->getTooltip());
- newLabel->setText (label->getText(), false);
- }
-
- delete label;
- label = newLabel;
-
- addAndMakeVisible (newLabel);
-
- newLabel->addListener (this);
- newLabel->addMouseListener (this, false);
-
- newLabel->setColour (Label::backgroundColourId, Colours::transparentBlack);
- newLabel->setColour (Label::textColourId, findColour (ComboBox::textColourId));
-
- newLabel->setColour (TextEditor::textColourId, findColour (ComboBox::textColourId));
- newLabel->setColour (TextEditor::backgroundColourId, Colours::transparentBlack);
- newLabel->setColour (TextEditor::highlightColourId, findColour (TextEditor::highlightColourId));
- newLabel->setColour (TextEditor::outlineColourId, Colours::transparentBlack);
-
- resized();
- }
-
- void ComboBox::colourChanged()
- {
- lookAndFeelChanged();
- }
-
- bool ComboBox::keyPressed (const KeyPress& key)
- {
- bool used = false;
-
- if (key.isKeyCode (KeyPress::upKey)
- || key.isKeyCode (KeyPress::leftKey))
- {
- setSelectedItemIndex (jmax (0, currentIndex - 1));
- used = true;
- }
- else if (key.isKeyCode (KeyPress::downKey)
- || key.isKeyCode (KeyPress::rightKey))
- {
- setSelectedItemIndex (jmin (currentIndex + 1, getNumItems() - 1));
- used = true;
- }
- else if (key.isKeyCode (KeyPress::returnKey))
- {
- showPopup();
- used = true;
- }
-
- return used;
- }
-
- bool ComboBox::keyStateChanged()
- {
- // only forward key events that aren't used by this component
- return KeyPress::isKeyCurrentlyDown (KeyPress::upKey)
- || KeyPress::isKeyCurrentlyDown (KeyPress::leftKey)
- || KeyPress::isKeyCurrentlyDown (KeyPress::downKey)
- || KeyPress::isKeyCurrentlyDown (KeyPress::rightKey);
- }
-
- void ComboBox::focusGained (FocusChangeType)
- {
- repaint();
- }
-
- void ComboBox::focusLost (FocusChangeType)
- {
- repaint();
- }
-
- void ComboBox::labelTextChanged (Label*)
- {
- triggerAsyncUpdate();
- }
-
- void ComboBox::showPopup()
- {
- if (! menuActive)
- {
- const int currentId = getSelectedId();
- ComponentDeletionWatcher deletionWatcher (this);
-
- PopupMenu menu;
-
- menu.setLookAndFeel (&getLookAndFeel());
-
- for (int i = 0; i < items.size(); ++i)
- {
- const ItemInfo* const item = items.getUnchecked(i);
-
- if (item->isSeparator())
- menu.addSeparator();
- else if (item->isHeading)
- menu.addSectionHeader (item->name);
- else
- menu.addItem (item->itemId, item->name,
- item->isEnabled, item->itemId == currentId);
- }
-
- if (items.size() == 0)
- menu.addItem (1, noChoicesMessage, false);
-
- const int itemHeight = jlimit (12, 24, getHeight());
-
- menuActive = true;
- const int resultId = menu.showAt (this, currentId,
- getWidth(), 1, itemHeight);
-
- if (deletionWatcher.hasBeenDeleted())
- return;
-
- menuActive = false;
-
- if (resultId != 0)
- setSelectedId (resultId);
- }
- }
-
- void ComboBox::mouseDown (const MouseEvent& e)
- {
- beginDragAutoRepeat (300);
-
- isButtonDown = isEnabled();
-
- if (isButtonDown
- && (e.eventComponent == this || ! label->isEditable()))
- {
- showPopup();
- }
- }
-
- void ComboBox::mouseDrag (const MouseEvent& e)
- {
- beginDragAutoRepeat (50);
-
- if (isButtonDown && ! e.mouseWasClicked())
- showPopup();
- }
-
- void ComboBox::mouseUp (const MouseEvent& e2)
- {
- if (isButtonDown)
- {
- isButtonDown = false;
- repaint();
-
- const MouseEvent e (e2.getEventRelativeTo (this));
-
- if (reallyContains (e.x, e.y, true)
- && (e2.eventComponent == this || ! label->isEditable()))
- {
- showPopup();
- }
- }
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_ComboBox.cpp *********/
-
- /********* Start of inlined file: juce_Label.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- Label::Label (const String& componentName,
- const String& labelText)
- : Component (componentName),
- text (labelText),
- font (15.0f),
- justification (Justification::centredLeft),
- editor (0),
- listeners (2),
- ownerComponent (0),
- deletionWatcher (0),
- editSingleClick (false),
- editDoubleClick (false),
- lossOfFocusDiscardsChanges (false)
- {
- setColour (TextEditor::textColourId, Colours::black);
- setColour (TextEditor::backgroundColourId, Colours::transparentBlack);
- setColour (TextEditor::outlineColourId, Colours::transparentBlack);
- }
-
- Label::~Label()
- {
- if (ownerComponent != 0 && ! deletionWatcher->hasBeenDeleted())
- ownerComponent->removeComponentListener (this);
-
- deleteAndZero (deletionWatcher);
-
- if (editor != 0)
- delete editor;
- }
-
- void Label::setText (const String& newText,
- const bool broadcastChangeMessage)
- {
- hideEditor (true);
-
- if (text != newText)
- {
- text = newText;
-
- if (broadcastChangeMessage)
- triggerAsyncUpdate();
-
- repaint();
-
- if (ownerComponent != 0 && ! deletionWatcher->hasBeenDeleted())
- componentMovedOrResized (*ownerComponent, true, true);
- }
- }
-
- const String Label::getText (const bool returnActiveEditorContents) const throw()
- {
- return (returnActiveEditorContents && isBeingEdited())
- ? editor->getText()
- : text;
- }
-
- void Label::setFont (const Font& newFont) throw()
- {
- font = newFont;
- repaint();
- }
-
- const Font& Label::getFont() const throw()
- {
- return font;
- }
-
- void Label::setEditable (const bool editOnSingleClick,
- const bool editOnDoubleClick,
- const bool lossOfFocusDiscardsChanges_) throw()
- {
- editSingleClick = editOnSingleClick;
- editDoubleClick = editOnDoubleClick;
- lossOfFocusDiscardsChanges = lossOfFocusDiscardsChanges_;
-
- setWantsKeyboardFocus (editOnSingleClick || editOnDoubleClick);
- setFocusContainer (editOnSingleClick || editOnDoubleClick);
- }
-
- void Label::setJustificationType (const Justification& justification_) throw()
- {
- justification = justification_;
- repaint();
- }
-
- void Label::attachToComponent (Component* owner,
- const bool onLeft)
- {
- if (ownerComponent != 0 && ! deletionWatcher->hasBeenDeleted())
- ownerComponent->removeComponentListener (this);
-
- deleteAndZero (deletionWatcher);
- ownerComponent = owner;
-
- leftOfOwnerComp = onLeft;
-
- if (ownerComponent != 0)
- {
- deletionWatcher = new ComponentDeletionWatcher (owner);
-
- setVisible (owner->isVisible());
- ownerComponent->addComponentListener (this);
- componentParentHierarchyChanged (*ownerComponent);
- componentMovedOrResized (*ownerComponent, true, true);
- }
- }
-
- void Label::componentMovedOrResized (Component& component,
- bool /*wasMoved*/,
- bool /*wasResized*/)
- {
- if (leftOfOwnerComp)
- {
- setSize (jmin (getFont().getStringWidth (text) + 8, component.getX()),
- component.getHeight());
-
- setTopRightPosition (component.getX(), component.getY());
- }
- else
- {
- setSize (component.getWidth(),
- 8 + roundFloatToInt (getFont().getHeight()));
-
- setTopLeftPosition (component.getX(), component.getY() - getHeight());
- }
- }
-
- void Label::componentParentHierarchyChanged (Component& component)
- {
- if (component.getParentComponent() != 0)
- component.getParentComponent()->addChildComponent (this);
- }
-
- void Label::componentVisibilityChanged (Component& component)
- {
- setVisible (component.isVisible());
- }
-
- void Label::textWasEdited()
- {
- }
-
- void Label::showEditor()
- {
- if (editor == 0)
- {
- addAndMakeVisible (editor = createEditorComponent());
- editor->setText (getText());
- editor->addListener (this);
- editor->grabKeyboardFocus();
- editor->setHighlightedRegion (0, text.length());
- editor->addListener (this);
-
- resized();
- repaint();
-
- enterModalState();
- editor->grabKeyboardFocus();
- }
- }
-
- bool Label::updateFromTextEditorContents()
- {
- jassert (editor != 0);
- const String newText (editor->getText());
-
- if (text != newText)
- {
- text = newText;
-
- triggerAsyncUpdate();
- repaint();
-
- if (ownerComponent != 0 && ! deletionWatcher->hasBeenDeleted())
- componentMovedOrResized (*ownerComponent, true, true);
-
- return true;
- }
-
- return false;
- }
-
- void Label::hideEditor (const bool discardCurrentEditorContents)
- {
- if (editor != 0)
- {
- const bool changed = (! discardCurrentEditorContents)
- && updateFromTextEditorContents();
-
- deleteAndZero (editor);
- repaint();
-
- if (changed)
- textWasEdited();
-
- exitModalState (0);
- }
- }
-
- void Label::inputAttemptWhenModal()
- {
- if (editor != 0)
- {
- if (lossOfFocusDiscardsChanges)
- textEditorEscapeKeyPressed (*editor);
- else
- textEditorReturnKeyPressed (*editor);
- }
- }
-
- bool Label::isBeingEdited() const throw()
- {
- return editor != 0;
- }
-
- TextEditor* Label::createEditorComponent()
- {
- TextEditor* const ed = new TextEditor (getName());
- ed->setFont (font);
-
- // copy these colours from our own settings..
- const int cols[] = { TextEditor::backgroundColourId,
- TextEditor::textColourId,
- TextEditor::highlightColourId,
- TextEditor::highlightedTextColourId,
- TextEditor::caretColourId,
- TextEditor::outlineColourId,
- TextEditor::focusedOutlineColourId,
- TextEditor::shadowColourId };
-
- for (int i = 0; i < numElementsInArray (cols); ++i)
- ed->setColour (cols[i], findColour (cols[i]));
-
- return ed;
- }
-
- void Label::paint (Graphics& g)
- {
- g.fillAll (findColour (backgroundColourId));
-
- if (editor == 0)
- {
- const float alpha = isEnabled() ? 1.0f : 0.5f;
-
- g.setColour (findColour (textColourId).withMultipliedAlpha (alpha));
- g.setFont (font);
- g.drawFittedText (text,
- 3, 1, getWidth() - 6, getHeight() - 2,
- justification,
- jmax (1, (int) (getHeight() / font.getHeight())));
-
- g.setColour (findColour (outlineColourId).withMultipliedAlpha (alpha));
- g.drawRect (0, 0, getWidth(), getHeight());
- }
- else if (isEnabled())
- {
- g.setColour (editor->findColour (TextEditor::backgroundColourId)
- .overlaidWith (findColour (outlineColourId)));
-
- g.drawRect (0, 0, getWidth(), getHeight());
- }
- }
-
- void Label::mouseUp (const MouseEvent& e)
- {
- if (editSingleClick
- && e.mouseWasClicked()
- && contains (e.x, e.y)
- && ! e.mods.isPopupMenu())
- {
- showEditor();
- }
- }
-
- void Label::mouseDoubleClick (const MouseEvent& e)
- {
- if (editDoubleClick && ! e.mods.isPopupMenu())
- showEditor();
- }
-
- void Label::resized()
- {
- if (editor != 0)
- editor->setBoundsInset (BorderSize (0));
- }
-
- void Label::focusGained (FocusChangeType cause)
- {
- if (editSingleClick && cause == focusChangedByTabKey)
- showEditor();
- }
-
- void Label::enablementChanged()
- {
- repaint();
- }
-
- void Label::colourChanged()
- {
- repaint();
- }
-
- // We'll use a custom focus traverser here to make sure focus goes from the
- // text editor to another component rather than back to the label itself.
- class LabelKeyboardFocusTraverser : public KeyboardFocusTraverser
- {
- public:
- LabelKeyboardFocusTraverser() {}
-
- Component* getNextComponent (Component* current)
- {
- return KeyboardFocusTraverser::getNextComponent (dynamic_cast <TextEditor*> (current) != 0
- ? current->getParentComponent() : current);
- }
-
- Component* getPreviousComponent (Component* current)
- {
- return KeyboardFocusTraverser::getPreviousComponent (dynamic_cast <TextEditor*> (current) != 0
- ? current->getParentComponent() : current);
- }
- };
-
- KeyboardFocusTraverser* Label::createFocusTraverser()
- {
- return new LabelKeyboardFocusTraverser();
- }
-
- void Label::addListener (LabelListener* const listener) throw()
- {
- jassert (listener != 0);
- if (listener != 0)
- listeners.add (listener);
- }
-
- void Label::removeListener (LabelListener* const listener) throw()
- {
- listeners.removeValue (listener);
- }
-
- void Label::handleAsyncUpdate()
- {
- for (int i = listeners.size(); --i >= 0;)
- {
- ((LabelListener*) listeners.getUnchecked (i))->labelTextChanged (this);
- i = jmin (i, listeners.size());
- }
- }
-
- void Label::textEditorTextChanged (TextEditor& ed)
- {
- if (editor != 0)
- {
- jassert (&ed == editor);
-
- if (! (hasKeyboardFocus (true) || isCurrentlyBlockedByAnotherModalComponent()))
- {
- if (lossOfFocusDiscardsChanges)
- textEditorEscapeKeyPressed (ed);
- else
- textEditorReturnKeyPressed (ed);
- }
- }
- }
-
- void Label::textEditorReturnKeyPressed (TextEditor& ed)
- {
- if (editor != 0)
- {
- jassert (&ed == editor);
- (void) ed;
-
- const bool changed = updateFromTextEditorContents();
- hideEditor (true);
-
- if (changed)
- textWasEdited();
- }
- }
-
- void Label::textEditorEscapeKeyPressed (TextEditor& ed)
- {
- if (editor != 0)
- {
- jassert (&ed == editor);
- (void) ed;
-
- editor->setText (text, false);
- hideEditor (true);
- }
- }
-
- void Label::textEditorFocusLost (TextEditor& ed)
- {
- textEditorTextChanged (ed);
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_Label.cpp *********/
-
- /********* Start of inlined file: juce_ListBox.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- class ListBoxRowComponent : public Component
- {
- public:
- ListBoxRowComponent (ListBox& owner_)
- : owner (owner_),
- row (-1),
- selected (false),
- isDragging (false)
- {
- }
-
- ~ListBoxRowComponent()
- {
- deleteAllChildren();
- }
-
- void paint (Graphics& g)
- {
- if (owner.getModel() != 0)
- owner.getModel()->paintListBoxItem (row, g, getWidth(), getHeight(), selected);
- }
-
- void update (const int row_, const bool selected_)
- {
- if (row != row_ || selected != selected_)
- {
- repaint();
- row = row_;
- selected = selected_;
- }
-
- if (owner.getModel() != 0)
- {
- Component* const customComp = owner.getModel()->refreshComponentForRow (row_, selected_, getChildComponent (0));
-
- if (customComp != 0)
- {
- addAndMakeVisible (customComp);
- customComp->setBounds (0, 0, getWidth(), getHeight());
-
- for (int i = getNumChildComponents(); --i >= 0;)
- if (getChildComponent (i) != customComp)
- delete getChildComponent (i);
- }
- else
- {
- deleteAllChildren();
- }
- }
- }
-
- void mouseDown (const MouseEvent& e)
- {
- isDragging = false;
- selectRowOnMouseUp = false;
-
- if (isEnabled())
- {
- if (! selected)
- {
- owner.selectRowsBasedOnModifierKeys (row, e.mods);
-
- if (owner.getModel() != 0)
- owner.getModel()->listBoxItemClicked (row, e);
- }
- else
- {
- selectRowOnMouseUp = true;
- }
- }
- }
-
- void mouseUp (const MouseEvent& e)
- {
- if (isEnabled() && selectRowOnMouseUp && ! isDragging)
- {
- owner.selectRowsBasedOnModifierKeys (row, e.mods);
-
- if (owner.getModel() != 0)
- owner.getModel()->listBoxItemClicked (row, e);
- }
- }
-
- void mouseDoubleClick (const MouseEvent& e)
- {
- if (owner.getModel() != 0 && isEnabled())
- owner.getModel()->listBoxItemDoubleClicked (row, e);
- }
-
- void mouseDrag (const MouseEvent& e)
- {
- if (isEnabled() && owner.getModel() != 0 && ! (e.mouseWasClicked() || isDragging))
- {
- const SparseSet <int> selectedRows (owner.getSelectedRows());
-
- if (selectedRows.size() > 0)
- {
- const String dragDescription (owner.getModel()->getDragSourceDescription (selectedRows));
-
- if (dragDescription.isNotEmpty())
- {
- isDragging = true;
-
- DragAndDropContainer* const dragContainer
- = DragAndDropContainer::findParentDragContainerFor (this);
-
- if (dragContainer != 0)
- {
- Image* dragImage = owner.createSnapshotOfSelectedRows();
- dragImage->multiplyAllAlphas (0.6f);
-
- dragContainer->startDragging (dragDescription, &owner, dragImage, true);
- }
- else
- {
- // to be able to do a drag-and-drop operation, the listbox needs to
- // be inside a component which is also a DragAndDropContainer.
- jassertfalse
- }
- }
- }
- }
- }
-
- void resized()
- {
- if (getNumChildComponents() > 0)
- getChildComponent(0)->setBounds (0, 0, getWidth(), getHeight());
- }
-
- juce_UseDebuggingNewOperator
-
- bool neededFlag;
-
- private:
- ListBox& owner;
- int row;
- bool selected, isDragging, selectRowOnMouseUp;
-
- ListBoxRowComponent (const ListBoxRowComponent&);
- const ListBoxRowComponent& operator= (const ListBoxRowComponent&);
- };
-
- class ListViewport : public Viewport
- {
- public:
- int firstIndex, firstWholeIndex, lastWholeIndex;
- bool hasUpdated;
-
- ListViewport (ListBox& owner_)
- : owner (owner_)
- {
- setWantsKeyboardFocus (false);
-
- setViewedComponent (new Component());
- getViewedComponent()->addMouseListener (this, false);
- getViewedComponent()->setWantsKeyboardFocus (false);
- }
-
- ~ListViewport()
- {
- getViewedComponent()->removeMouseListener (this);
- getViewedComponent()->deleteAllChildren();
- }
-
- ListBoxRowComponent* getComponentForRow (const int row) const throw()
- {
- return (ListBoxRowComponent*) getViewedComponent()
- ->getChildComponent (row % jmax (1, getViewedComponent()->getNumChildComponents()));
- }
-
- int getRowNumberOfComponent (Component* const rowComponent) const throw()
- {
- const int index = getIndexOfChildComponent (rowComponent);
- const int num = getViewedComponent()->getNumChildComponents();
-
- for (int i = num; --i >= 0;)
- if (((firstIndex + i) % jmax (1, num)) == index)
- return firstIndex + i;
-
- return -1;
- }
-
- Component* getComponentForRowIfOnscreen (const int row) const throw()
- {
- return (row >= firstIndex && row < firstIndex + getViewedComponent()->getNumChildComponents())
- ? getComponentForRow (row) : 0;
- }
-
- void visibleAreaChanged (int, int, int, int)
- {
- updateVisibleArea (true);
-
- if (owner.getModel() != 0)
- owner.getModel()->listWasScrolled();
- }
-
- void updateVisibleArea (const bool makeSureItUpdatesContent)
- {
- hasUpdated = false;
-
- const int newX = getViewedComponent()->getX();
- int newY = getViewedComponent()->getY();
- const int newW = jmax (owner.minimumRowWidth, getMaximumVisibleWidth());
- const int newH = owner.totalItems * owner.getRowHeight();
-
- if (newY + newH < getMaximumVisibleHeight() && newH > getMaximumVisibleHeight())
- newY = getMaximumVisibleHeight() - newH;
-
- getViewedComponent()->setBounds (newX, newY, newW, newH);
-
- if (makeSureItUpdatesContent && ! hasUpdated)
- updateContents();
- }
-
- void updateContents()
- {
- hasUpdated = true;
- const int rowHeight = owner.getRowHeight();
-
- if (rowHeight > 0)
- {
- const int y = getViewPositionY();
- const int w = getViewedComponent()->getWidth();
-
- const int numNeeded = 2 + getMaximumVisibleHeight() / rowHeight;
-
- while (numNeeded > getViewedComponent()->getNumChildComponents())
- getViewedComponent()->addAndMakeVisible (new ListBoxRowComponent (owner));
-
- jassert (numNeeded >= 0);
-
- while (numNeeded < getViewedComponent()->getNumChildComponents())
- {
- Component* const rowToRemove
- = getViewedComponent()->getChildComponent (getViewedComponent()->getNumChildComponents() - 1);
-
- delete rowToRemove;
- }
-
- firstIndex = y / rowHeight;
- firstWholeIndex = (y + rowHeight - 1) / rowHeight;
- lastWholeIndex = (y + getMaximumVisibleHeight() - 1) / rowHeight;
-
- for (int i = 0; i < numNeeded; ++i)
- {
- const int row = i + firstIndex;
- ListBoxRowComponent* const rowComp = getComponentForRow (row);
-
- if (rowComp != 0)
- {
- rowComp->setBounds (0, row * rowHeight, w, rowHeight);
- rowComp->update (row, owner.isRowSelected (row));
- }
- }
- }
-
- if (owner.headerComponent != 0)
- owner.headerComponent->setBounds (owner.outlineThickness + getViewedComponent()->getX(),
- owner.outlineThickness,
- jmax (owner.getWidth() - owner.outlineThickness * 2,
- getViewedComponent()->getWidth()),
- owner.headerComponent->getHeight());
- }
-
- void paint (Graphics& g)
- {
- if (isOpaque())
- g.fillAll (owner.findColour (ListBox::backgroundColourId));
- }
-
- bool keyPressed (const KeyPress& key)
- {
- if (key.isKeyCode (KeyPress::upKey)
- || key.isKeyCode (KeyPress::downKey)
- || key.isKeyCode (KeyPress::pageUpKey)
- || key.isKeyCode (KeyPress::pageDownKey)
- || key.isKeyCode (KeyPress::homeKey)
- || key.isKeyCode (KeyPress::endKey))
- {
- // we want to avoid these keypresses going to the viewport, and instead allow
- // them to pass up to our listbox..
- return false;
- }
-
- return Viewport::keyPressed (key);
- }
-
- juce_UseDebuggingNewOperator
-
- private:
- ListBox& owner;
-
- ListViewport (const ListViewport&);
- const ListViewport& operator= (const ListViewport&);
- };
-
- ListBox::ListBox (const String& name, ListBoxModel* const model_)
- : Component (name),
- model (model_),
- headerComponent (0),
- totalItems (0),
- rowHeight (22),
- minimumRowWidth (0),
- outlineThickness (0),
- lastRowSelected (-1),
- mouseMoveSelects (false),
- multipleSelection (false),
- hasDoneInitialUpdate (false)
- {
- addAndMakeVisible (viewport = new ListViewport (*this));
-
- setWantsKeyboardFocus (true);
- }
-
- ListBox::~ListBox()
- {
- deleteAllChildren();
- }
-
- void ListBox::setModel (ListBoxModel* const newModel)
- {
- if (model != newModel)
- {
- model = newModel;
- updateContent();
- }
- }
-
- void ListBox::setMultipleSelectionEnabled (bool b)
- {
- multipleSelection = b;
- }
-
- void ListBox::setMouseMoveSelectsRows (bool b)
- {
- mouseMoveSelects = b;
-
- if (b)
- addMouseListener (this, true);
- }
-
- void ListBox::paint (Graphics& g)
- {
- if (! hasDoneInitialUpdate)
- updateContent();
-
- g.fillAll (findColour (backgroundColourId));
- }
-
- void ListBox::paintOverChildren (Graphics& g)
- {
- if (outlineThickness > 0)
- {
- g.setColour (findColour (outlineColourId));
- g.drawRect (0, 0, getWidth(), getHeight(), outlineThickness);
- }
- }
-
- void ListBox::resized()
- {
- viewport->setBoundsInset (BorderSize (outlineThickness + ((headerComponent != 0) ? headerComponent->getHeight() : 0),
- outlineThickness,
- outlineThickness,
- outlineThickness));
-
- viewport->setSingleStepSizes (20, getRowHeight());
-
- viewport->updateVisibleArea (false);
- }
-
- void ListBox::visibilityChanged()
- {
- viewport->updateVisibleArea (true);
- }
-
- Viewport* ListBox::getViewport() const throw()
- {
- return viewport;
- }
-
- void ListBox::updateContent()
- {
- hasDoneInitialUpdate = true;
- totalItems = (model != 0) ? model->getNumRows() : 0;
-
- bool selectionChanged = false;
-
- if (selected [selected.size() - 1] >= totalItems)
- {
- selected.removeRange (totalItems, INT_MAX - totalItems);
- lastRowSelected = getSelectedRow (0);
- selectionChanged = true;
- }
-
- viewport->updateVisibleArea (isVisible());
- viewport->resized();
-
- if (selectionChanged && model != 0)
- model->selectedRowsChanged (lastRowSelected);
- }
-
- void ListBox::selectRow (const int row,
- bool dontScroll,
- bool deselectOthersFirst)
- {
- selectRowInternal (row, dontScroll, deselectOthersFirst, false);
- }
-
- void ListBox::selectRowInternal (const int row,
- bool dontScroll,
- bool deselectOthersFirst,
- bool isMouseClick)
- {
- if (! multipleSelection)
- deselectOthersFirst = true;
-
- if ((! isRowSelected (row))
- || (deselectOthersFirst && getNumSelectedRows() > 1))
- {
- if (((unsigned int) row) < (unsigned int) totalItems)
- {
- if (deselectOthersFirst)
- selected.clear();
-
- selected.addRange (row, 1);
-
- if (getHeight() == 0 || getWidth() == 0)
- dontScroll = true;
-
- viewport->hasUpdated = false;
-
- if (row < viewport->firstWholeIndex && ! dontScroll)
- {
- viewport->setViewPosition (viewport->getViewPositionX(),
- row * getRowHeight());
- }
- else if (row >= viewport->lastWholeIndex && ! dontScroll)
- {
- const int rowsOnScreen = viewport->lastWholeIndex - viewport->firstWholeIndex;
-
- if (row >= lastRowSelected + rowsOnScreen
- && rowsOnScreen < totalItems - 1
- && ! isMouseClick)
- {
- viewport->setViewPosition (viewport->getViewPositionX(),
- jlimit (0, jmax (0, totalItems - rowsOnScreen), row)
- * getRowHeight());
- }
- else
- {
- viewport->setViewPosition (viewport->getViewPositionX(),
- jmax (0, (row + 1) * getRowHeight() - viewport->getMaximumVisibleHeight()));
- }
- }
-
- if (! viewport->hasUpdated)
- viewport->updateContents();
-
- lastRowSelected = row;
- model->selectedRowsChanged (row);
- }
- else
- {
- if (deselectOthersFirst)
- deselectAllRows();
- }
- }
- }
-
- void ListBox::deselectRow (const int row)
- {
- if (selected.contains (row))
- {
- selected.removeRange (row, 1);
-
- if (row == lastRowSelected)
- lastRowSelected = getSelectedRow (0);
-
- viewport->updateContents();
- model->selectedRowsChanged (lastRowSelected);
- }
- }
-
- void ListBox::setSelectedRows (const SparseSet<int>& setOfRowsToBeSelected,
- const bool sendNotificationEventToModel)
- {
- selected = setOfRowsToBeSelected;
- selected.removeRange (totalItems, INT_MAX - totalItems);
-
- if (! isRowSelected (lastRowSelected))
- lastRowSelected = getSelectedRow (0);
-
- viewport->updateContents();
-
- if ((model != 0) && sendNotificationEventToModel)
- model->selectedRowsChanged (lastRowSelected);
- }
-
- const SparseSet<int> ListBox::getSelectedRows() const
- {
- return selected;
- }
-
- void ListBox::selectRangeOfRows (int firstRow, int lastRow)
- {
- if (multipleSelection && (firstRow != lastRow))
- {
- const int numRows = totalItems - 1;
- firstRow = jlimit (0, jmax (0, numRows), firstRow);
- lastRow = jlimit (0, jmax (0, numRows), lastRow);
-
- selected.addRange (jmin (firstRow, lastRow),
- abs (firstRow - lastRow) + 1);
-
- selected.removeRange (lastRow, 1);
- }
-
- selectRowInternal (lastRow, false, false, true);
- }
-
- void ListBox::flipRowSelection (const int row)
- {
- if (isRowSelected (row))
- deselectRow (row);
- else
- selectRowInternal (row, false, false, true);
- }
-
- void ListBox::deselectAllRows()
- {
- if (! selected.isEmpty())
- {
- selected.clear();
- lastRowSelected = -1;
-
- viewport->updateContents();
-
- if (model != 0)
- model->selectedRowsChanged (lastRowSelected);
- }
- }
-
- void ListBox::selectRowsBasedOnModifierKeys (const int row,
- const ModifierKeys& mods)
- {
- if (multipleSelection && mods.isCommandDown())
- {
- flipRowSelection (row);
- }
- else if (multipleSelection && mods.isShiftDown() && lastRowSelected >= 0)
- {
- selectRangeOfRows (lastRowSelected, row);
- }
- else if ((! mods.isPopupMenu()) || ! isRowSelected (row))
- {
- selectRowInternal (row, false, true, true);
- }
- }
-
- int ListBox::getNumSelectedRows() const
- {
- return selected.size();
- }
-
- int ListBox::getSelectedRow (const int index) const
- {
- return (((unsigned int) index) < (unsigned int) selected.size())
- ? selected [index] : -1;
- }
-
- bool ListBox::isRowSelected (const int row) const
- {
- return selected.contains (row);
- }
-
- int ListBox::getLastRowSelected() const
- {
- return (isRowSelected (lastRowSelected)) ? lastRowSelected : -1;
- }
-
- int ListBox::getRowContainingPosition (const int x, const int y) const throw()
- {
- if (((unsigned int) x) < (unsigned int) getWidth())
- {
- const int row = (viewport->getViewPositionY() + y - viewport->getY()) / rowHeight;
-
- if (((unsigned int) row) < (unsigned int) totalItems)
- return row;
- }
-
- return -1;
- }
-
- int ListBox::getInsertionIndexForPosition (const int x, const int y) const throw()
- {
- if (((unsigned int) x) < (unsigned int) getWidth())
- {
- const int row = (viewport->getViewPositionY() + y + rowHeight / 2 - viewport->getY()) / rowHeight;
- return jlimit (0, totalItems, row);
- }
-
- return -1;
- }
-
- Component* ListBox::getComponentForRowNumber (const int row) const throw()
- {
- Component* const listRowComp = viewport->getComponentForRowIfOnscreen (row);
- return listRowComp != 0 ? listRowComp->getChildComponent (0) : 0;
- }
-
- int ListBox::getRowNumberOfComponent (Component* const rowComponent) const throw()
- {
- return viewport->getRowNumberOfComponent (rowComponent);
- }
-
- const Rectangle ListBox::getRowPosition (const int rowNumber,
- const bool relativeToComponentTopLeft) const throw()
- {
- const int rowHeight = getRowHeight();
- int y = viewport->getY() + rowHeight * rowNumber;
-
- if (relativeToComponentTopLeft)
- y -= viewport->getViewPositionY();
-
- return Rectangle (viewport->getX(), y,
- viewport->getViewedComponent()->getWidth(), rowHeight);
- }
-
- void ListBox::setVerticalPosition (const double proportion)
- {
- const int offscreen = viewport->getViewedComponent()->getHeight() - viewport->getHeight();
-
- viewport->setViewPosition (viewport->getViewPositionX(),
- jmax (0, roundDoubleToInt (proportion * offscreen)));
- }
-
- double ListBox::getVerticalPosition() const
- {
- const int offscreen = viewport->getViewedComponent()->getHeight() - viewport->getHeight();
-
- return (offscreen > 0) ? viewport->getViewPositionY() / (double) offscreen
- : 0;
- }
-
- int ListBox::getVisibleRowWidth() const throw()
- {
- return viewport->getViewWidth();
- }
-
- void ListBox::scrollToEnsureRowIsOnscreen (const int row)
- {
- if (row < viewport->firstWholeIndex)
- {
- viewport->setViewPosition (viewport->getViewPositionX(),
- row * getRowHeight());
- }
- else if (row >= viewport->lastWholeIndex)
- {
- viewport->setViewPosition (viewport->getViewPositionX(),
- jmax (0, (row + 1) * getRowHeight() - viewport->getMaximumVisibleHeight()));
- }
- }
-
- bool ListBox::keyPressed (const KeyPress& key)
- {
- const int numVisibleRows = viewport->getHeight() / getRowHeight();
-
- const bool multiple = multipleSelection
- && (lastRowSelected >= 0)
- && (key.getModifiers().isShiftDown()
- || key.getModifiers().isCtrlDown()
- || key.getModifiers().isCommandDown());
-
- if (key.isKeyCode (KeyPress::upKey))
- {
- if (multiple)
- selectRangeOfRows (lastRowSelected, lastRowSelected - 1);
- else
- selectRow (jmax (0, lastRowSelected - 1));
- }
- else if (key.isKeyCode (KeyPress::returnKey)
- && isRowSelected (lastRowSelected))
- {
- if (model != 0)
- model->returnKeyPressed (lastRowSelected);
- }
- else if (key.isKeyCode (KeyPress::pageUpKey))
- {
- if (multiple)
- selectRangeOfRows (lastRowSelected, lastRowSelected - numVisibleRows);
- else
- selectRow (jmax (0, jmax (0, lastRowSelected) - numVisibleRows));
- }
- else if (key.isKeyCode (KeyPress::pageDownKey))
- {
- if (multiple)
- selectRangeOfRows (lastRowSelected, lastRowSelected + numVisibleRows);
- else
- selectRow (jmin (totalItems - 1, jmax (0, lastRowSelected) + numVisibleRows));
- }
- else if (key.isKeyCode (KeyPress::homeKey))
- {
- if (multiple && key.getModifiers().isShiftDown())
- selectRangeOfRows (lastRowSelected, 0);
- else
- selectRow (0);
- }
- else if (key.isKeyCode (KeyPress::endKey))
- {
- if (multiple && key.getModifiers().isShiftDown())
- selectRangeOfRows (lastRowSelected, totalItems - 1);
- else
- selectRow (totalItems - 1);
- }
- else if (key.isKeyCode (KeyPress::downKey))
- {
- if (multiple)
- selectRangeOfRows (lastRowSelected, lastRowSelected + 1);
- else
- selectRow (jmin (totalItems - 1, jmax (0, lastRowSelected) + 1));
- }
- else if ((key.isKeyCode (KeyPress::deleteKey) || key.isKeyCode (KeyPress::backspaceKey))
- && isRowSelected (lastRowSelected))
- {
- if (model != 0)
- model->deleteKeyPressed (lastRowSelected);
- }
- else if (multiple && key == KeyPress (T('a'), ModifierKeys::commandModifier, 0))
- {
- selectRangeOfRows (0, INT_MAX);
- }
- else
- {
- return false;
- }
-
- return true;
- }
-
- bool ListBox::keyStateChanged()
- {
- return KeyPress::isKeyCurrentlyDown (KeyPress::upKey)
- || KeyPress::isKeyCurrentlyDown (KeyPress::pageUpKey)
- || KeyPress::isKeyCurrentlyDown (KeyPress::downKey)
- || KeyPress::isKeyCurrentlyDown (KeyPress::pageDownKey)
- || KeyPress::isKeyCurrentlyDown (KeyPress::homeKey)
- || KeyPress::isKeyCurrentlyDown (KeyPress::endKey)
- || KeyPress::isKeyCurrentlyDown (KeyPress::returnKey);
- }
-
- void ListBox::mouseWheelMove (const MouseEvent& e, float wheelIncrementX, float wheelIncrementY)
- {
- getHorizontalScrollBar()->mouseWheelMove (e, wheelIncrementX, 0);
- getVerticalScrollBar()->mouseWheelMove (e, 0, wheelIncrementY);
- }
-
- void ListBox::mouseMove (const MouseEvent& e)
- {
- if (mouseMoveSelects)
- {
- const MouseEvent e2 (e.getEventRelativeTo (this));
-
- selectRow (getRowContainingPosition (e2.x, e2.y), true);
-
- lastMouseX = e2.x;
- lastMouseY = e2.y;
- }
- }
-
- void ListBox::mouseExit (const MouseEvent& e)
- {
- mouseMove (e);
- }
-
- void ListBox::mouseUp (const MouseEvent& e)
- {
- if (e.mouseWasClicked() && model != 0)
- model->backgroundClicked();
- }
-
- void ListBox::setRowHeight (const int newHeight)
- {
- rowHeight = jmax (1, newHeight);
- viewport->setSingleStepSizes (20, rowHeight);
- updateContent();
- }
-
- int ListBox::getNumRowsOnScreen() const throw()
- {
- return viewport->getMaximumVisibleHeight() / rowHeight;
- }
-
- void ListBox::setMinimumContentWidth (const int newMinimumWidth)
- {
- minimumRowWidth = newMinimumWidth;
- updateContent();
- }
-
- int ListBox::getVisibleContentWidth() const throw()
- {
- return viewport->getMaximumVisibleWidth();
- }
-
- ScrollBar* ListBox::getVerticalScrollBar() const throw()
- {
- return viewport->getVerticalScrollBar();
- }
-
- ScrollBar* ListBox::getHorizontalScrollBar() const throw()
- {
- return viewport->getHorizontalScrollBar();
- }
-
- void ListBox::colourChanged()
- {
- setOpaque (findColour (backgroundColourId).isOpaque());
- viewport->setOpaque (isOpaque());
- repaint();
- }
-
- void ListBox::setOutlineThickness (const int outlineThickness_)
- {
- outlineThickness = outlineThickness_;
- resized();
- }
-
- void ListBox::setHeaderComponent (Component* const newHeaderComponent)
- {
- if (headerComponent != newHeaderComponent)
- {
- if (headerComponent != 0)
- delete headerComponent;
-
- headerComponent = newHeaderComponent;
-
- addAndMakeVisible (newHeaderComponent);
- ListBox::resized();
- }
- }
-
- void ListBox::repaintRow (const int rowNumber) throw()
- {
- const Rectangle r (getRowPosition (rowNumber, true));
- repaint (r.getX(), r.getY(), r.getWidth(), r.getHeight());
- }
-
- Image* ListBox::createSnapshotOfSelectedRows()
- {
- Image* snapshot = new Image (Image::ARGB, getWidth(), getHeight(), true);
- Graphics g (*snapshot);
-
- const int firstRow = getRowContainingPosition (0, 0);
-
- for (int i = getNumRowsOnScreen() + 2; --i >= 0;)
- {
- Component* rowComp = viewport->getComponentForRowIfOnscreen (firstRow + i);
-
- if (rowComp != 0 && isRowSelected (firstRow + i))
- {
- g.saveState();
-
- int x = 0, y = 0;
- rowComp->relativePositionToOtherComponent (this, x, y);
-
- g.setOrigin (x, y);
- g.reduceClipRegion (0, 0, rowComp->getWidth(), rowComp->getHeight());
-
- rowComp->paintEntireComponent (g);
-
- g.restoreState();
- }
- }
-
- return snapshot;
- }
-
- Component* ListBoxModel::refreshComponentForRow (int, bool, Component* existingComponentToUpdate)
- {
- (void) existingComponentToUpdate;
- jassert (existingComponentToUpdate == 0); // indicates a failure in the code the recycles the components
- return 0;
- }
-
- void ListBoxModel::listBoxItemClicked (int, const MouseEvent&)
- {
- }
-
- void ListBoxModel::listBoxItemDoubleClicked (int, const MouseEvent&)
- {
- }
-
- void ListBoxModel::backgroundClicked()
- {
- }
-
- void ListBoxModel::selectedRowsChanged (int)
- {
- }
-
- void ListBoxModel::deleteKeyPressed (int)
- {
- }
-
- void ListBoxModel::returnKeyPressed (int)
- {
- }
-
- void ListBoxModel::listWasScrolled()
- {
- }
-
- const String ListBoxModel::getDragSourceDescription (const SparseSet<int>&)
- {
- return String::empty;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_ListBox.cpp *********/
-
- /********* Start of inlined file: juce_ProgressBar.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- ProgressBar::ProgressBar (double& progress_)
- : progress (progress_),
- displayPercentage (true)
- {
- currentValue = jlimit (0.0, 1.0, progress);
- }
-
- ProgressBar::~ProgressBar()
- {
- }
-
- void ProgressBar::setPercentageDisplay (const bool shouldDisplayPercentage)
- {
- displayPercentage = shouldDisplayPercentage;
- repaint();
- }
-
- void ProgressBar::setTextToDisplay (const String& text)
- {
- displayPercentage = false;
- displayedMessage = text;
- }
-
- void ProgressBar::lookAndFeelChanged()
- {
- setOpaque (findColour (backgroundColourId).isOpaque());
- }
-
- void ProgressBar::colourChanged()
- {
- lookAndFeelChanged();
- }
-
- void ProgressBar::paint (Graphics& g)
- {
- String text;
-
- if (displayPercentage)
- {
- if (currentValue >= 0 && currentValue <= 1.0)
- text << roundDoubleToInt (currentValue * 100.0) << T("%");
- }
- else
- {
- text = displayedMessage;
- }
-
- getLookAndFeel().drawProgressBar (g, *this,
- getWidth(), getHeight(),
- currentValue, text);
- }
-
- void ProgressBar::visibilityChanged()
- {
- if (isVisible())
- startTimer (30);
- else
- stopTimer();
- }
-
- void ProgressBar::timerCallback()
- {
- double newProgress = progress;
-
- if (currentValue != newProgress
- || newProgress < 0 || newProgress >= 1.0
- || currentMessage != displayedMessage)
- {
- if (currentValue < newProgress
- && newProgress >= 0 && newProgress < 1.0
- && currentValue >= 0 && newProgress < 1.0)
- {
- newProgress = jmin (currentValue + 0.02, newProgress);
- }
-
- currentValue = newProgress;
- currentMessage = displayedMessage;
- repaint();
- }
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_ProgressBar.cpp *********/
-
- /********* Start of inlined file: juce_Slider.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- class SliderPopupDisplayComponent : public BubbleComponent
- {
- public:
-
- SliderPopupDisplayComponent (Slider* const owner_)
- : owner (owner_),
- font (15.0f, Font::bold)
- {
- setAlwaysOnTop (true);
- }
-
- ~SliderPopupDisplayComponent()
- {
- }
-
- void paintContent (Graphics& g, int w, int h)
- {
- g.setFont (font);
- g.setColour (Colours::black);
-
- g.drawFittedText (text, 0, 0, w, h, Justification::centred, 1);
- }
-
- void getContentSize (int& w, int& h)
- {
- w = font.getStringWidth (text) + 18;
- h = (int) (font.getHeight() * 1.6f);
- }
-
- void updatePosition (const String& newText)
- {
- if (text != newText)
- {
- text = newText;
- repaint();
- }
-
- BubbleComponent::setPosition (owner);
- }
-
- juce_UseDebuggingNewOperator
-
- private:
- Slider* owner;
- Font font;
- String text;
-
- SliderPopupDisplayComponent (const SliderPopupDisplayComponent&);
- const SliderPopupDisplayComponent& operator= (const SliderPopupDisplayComponent&);
- };
-
- Slider::Slider (const String& name)
- : Component (name),
- listeners (2),
- currentValue (0.0),
- valueMin (0.0),
- valueMax (0.0),
- minimum (0),
- maximum (10),
- interval (0),
- skewFactor (1.0),
- velocityModeSensitivity (1.0),
- velocityModeOffset (0.0),
- velocityModeThreshold (1),
- rotaryStart (float_Pi * 1.2f),
- rotaryEnd (float_Pi * 2.8f),
- numDecimalPlaces (7),
- sliderRegionStart (0),
- sliderRegionSize (1),
- sliderBeingDragged (-1),
- pixelsForFullDragExtent (250),
- style (LinearHorizontal),
- textBoxPos (TextBoxLeft),
- textBoxWidth (80),
- textBoxHeight (20),
- incDecButtonMode (incDecButtonsNotDraggable),
- editableText (true),
- doubleClickToValue (false),
- isVelocityBased (false),
- userKeyOverridesVelocity (true),
- rotaryStop (true),
- incDecButtonsSideBySide (false),
- sendChangeOnlyOnRelease (false),
- popupDisplayEnabled (false),
- menuEnabled (false),
- menuShown (false),
- scrollWheelEnabled (true),
- snapsToMousePos (true),
- valueBox (0),
- incButton (0),
- decButton (0),
- popupDisplay (0),
- parentForPopupDisplay (0)
- {
- setWantsKeyboardFocus (false);
- setRepaintsOnMouseActivity (true);
-
- lookAndFeelChanged();
- updateText();
- }
-
- Slider::~Slider()
- {
- deleteAndZero (popupDisplay);
- deleteAllChildren();
- }
-
- void Slider::handleAsyncUpdate()
- {
- cancelPendingUpdate();
-
- for (int i = listeners.size(); --i >= 0;)
- {
- ((SliderListener*) listeners.getUnchecked (i))->sliderValueChanged (this);
- i = jmin (i, listeners.size());
- }
- }
-
- void Slider::sendDragStart()
- {
- startedDragging();
-
- for (int i = listeners.size(); --i >= 0;)
- {
- ((SliderListener*) listeners.getUnchecked (i))->sliderDragStarted (this);
- i = jmin (i, listeners.size());
- }
- }
-
- void Slider::sendDragEnd()
- {
- stoppedDragging();
-
- sliderBeingDragged = -1;
-
- for (int i = listeners.size(); --i >= 0;)
- {
- ((SliderListener*) listeners.getUnchecked (i))->sliderDragEnded (this);
- i = jmin (i, listeners.size());
- }
- }
-
- void Slider::addListener (SliderListener* const listener) throw()
- {
- jassert (listener != 0);
- if (listener != 0)
- listeners.add (listener);
- }
-
- void Slider::removeListener (SliderListener* const listener) throw()
- {
- listeners.removeValue (listener);
- }
-
- void Slider::setSliderStyle (const SliderStyle newStyle)
- {
- if (style != newStyle)
- {
- style = newStyle;
- repaint();
- lookAndFeelChanged();
- }
- }
-
- void Slider::setRotaryParameters (const float startAngleRadians,
- const float endAngleRadians,
- const bool stopAtEnd)
- {
- // make sure the values are sensible..
- jassert (rotaryStart >= 0 && rotaryEnd >= 0);
- jassert (rotaryStart < float_Pi * 4.0f && rotaryEnd < float_Pi * 4.0f);
- jassert (rotaryStart < rotaryEnd);
-
- rotaryStart = startAngleRadians;
- rotaryEnd = endAngleRadians;
- rotaryStop = stopAtEnd;
- }
-
- void Slider::setVelocityBasedMode (const bool velBased) throw()
- {
- isVelocityBased = velBased;
- }
-
- void Slider::setVelocityModeParameters (const double sensitivity,
- const int threshold,
- const double offset,
- const bool userCanPressKeyToSwapMode) throw()
- {
- jassert (threshold >= 0);
- jassert (sensitivity > 0);
- jassert (offset >= 0);
-
- velocityModeSensitivity = sensitivity;
- velocityModeOffset = offset;
- velocityModeThreshold = threshold;
- userKeyOverridesVelocity = userCanPressKeyToSwapMode;
- }
-
- void Slider::setSkewFactor (const double factor) throw()
- {
- skewFactor = factor;
- }
-
- void Slider::setSkewFactorFromMidPoint (const double sliderValueToShowAtMidPoint) throw()
- {
- if (maximum > minimum)
- skewFactor = log (0.5) / log ((sliderValueToShowAtMidPoint - minimum)
- / (maximum - minimum));
- }
-
- void Slider::setMouseDragSensitivity (const int distanceForFullScaleDrag)
- {
- jassert (distanceForFullScaleDrag > 0);
-
- pixelsForFullDragExtent = distanceForFullScaleDrag;
- }
-
- void Slider::setIncDecButtonsMode (const IncDecButtonMode mode)
- {
- if (incDecButtonMode != mode)
- {
- incDecButtonMode = mode;
- lookAndFeelChanged();
- }
- }
-
- void Slider::setTextBoxStyle (const TextEntryBoxPosition newPosition,
- const bool isReadOnly,
- const int textEntryBoxWidth,
- const int textEntryBoxHeight)
- {
- textBoxPos = newPosition;
- editableText = ! isReadOnly;
- textBoxWidth = textEntryBoxWidth;
- textBoxHeight = textEntryBoxHeight;
-
- repaint();
- lookAndFeelChanged();
- }
-
- void Slider::setTextBoxIsEditable (const bool shouldBeEditable) throw()
- {
- editableText = shouldBeEditable;
-
- if (valueBox != 0)
- valueBox->setEditable (shouldBeEditable && isEnabled());
- }
-
- void Slider::showTextBox()
- {
- jassert (editableText); // this should probably be avoided in read-only sliders.
-
- if (valueBox != 0)
- valueBox->showEditor();
- }
-
- void Slider::hideTextBox (const bool discardCurrentEditorContents)
- {
- if (valueBox != 0)
- {
- valueBox->hideEditor (discardCurrentEditorContents);
-
- if (discardCurrentEditorContents)
- updateText();
- }
- }
-
- void Slider::setChangeNotificationOnlyOnRelease (const bool onlyNotifyOnRelease) throw()
- {
- sendChangeOnlyOnRelease = onlyNotifyOnRelease;
- }
-
- void Slider::setSliderSnapsToMousePosition (const bool shouldSnapToMouse) throw()
- {
- snapsToMousePos = shouldSnapToMouse;
- }
-
- void Slider::setPopupDisplayEnabled (const bool enabled,
- Component* const parentComponentToUse) throw()
- {
- popupDisplayEnabled = enabled;
- parentForPopupDisplay = parentComponentToUse;
- }
-
- void Slider::colourChanged()
- {
- lookAndFeelChanged();
- }
-
- void Slider::lookAndFeelChanged()
- {
- const String previousTextBoxContent (valueBox != 0 ? valueBox->getText()
- : getTextFromValue (currentValue));
-
- deleteAllChildren();
- valueBox = 0;
-
- LookAndFeel& lf = getLookAndFeel();
-
- if (textBoxPos != NoTextBox)
- {
- addAndMakeVisible (valueBox = getLookAndFeel().createSliderTextBox (*this));
-
- valueBox->setWantsKeyboardFocus (false);
- valueBox->setText (previousTextBoxContent, false);
-
- valueBox->setEditable (editableText && isEnabled());
- valueBox->addListener (this);
-
- if (style == LinearBar)
- valueBox->addMouseListener (this, false);
- }
-
- if (style == IncDecButtons)
- {
- addAndMakeVisible (incButton = lf.createSliderButton (true));
- incButton->addButtonListener (this);
-
- addAndMakeVisible (decButton = lf.createSliderButton (false));
- decButton->addButtonListener (this);
-
- if (incDecButtonMode != incDecButtonsNotDraggable)
- {
- incButton->addMouseListener (this, false);
- decButton->addMouseListener (this, false);
- }
- else
- {
- incButton->setRepeatSpeed (300, 100, 20);
- incButton->addMouseListener (decButton, false);
-
- decButton->setRepeatSpeed (300, 100, 20);
- decButton->addMouseListener (incButton, false);
- }
- }
-
- setComponentEffect (lf.getSliderEffect());
-
- resized();
- repaint();
- }
-
- void Slider::setRange (const double newMin,
- const double newMax,
- const double newInt)
- {
- if (minimum != newMin
- || maximum != newMax
- || interval != newInt)
- {
- minimum = newMin;
- maximum = newMax;
- interval = newInt;
-
- // figure out the number of DPs needed to display all values at this
- // interval setting.
- numDecimalPlaces = 7;
-
- if (newInt != 0)
- {
- int v = abs ((int) (newInt * 10000000));
-
- while ((v % 10) == 0)
- {
- --numDecimalPlaces;
- v /= 10;
- }
- }
-
- // keep the current values inside the new range..
- if (style != TwoValueHorizontal && style != TwoValueVertical)
- {
- setValue (currentValue, false, false);
- }
- else
- {
- setMinValue (getMinValue(), false, false);
- setMaxValue (getMaxValue(), false, false);
- }
-
- updateText();
- }
- }
-
- void Slider::triggerChangeMessage (const bool synchronous)
- {
- if (synchronous)
- handleAsyncUpdate();
- else
- triggerAsyncUpdate();
-
- valueChanged();
- }
-
- double Slider::getValue() const throw()
- {
- // for a two-value style slider, you should use the getMinValue() and getMaxValue()
- // methods to get the two values.
- jassert (style != TwoValueHorizontal && style != TwoValueVertical);
-
- return currentValue;
- }
-
- void Slider::setValue (double newValue,
- const bool sendUpdateMessage,
- const bool sendMessageSynchronously)
- {
- // for a two-value style slider, you should use the setMinValue() and setMaxValue()
- // methods to set the two values.
- jassert (style != TwoValueHorizontal && style != TwoValueVertical);
-
- newValue = constrainedValue (newValue);
-
- if (style == ThreeValueHorizontal || style == ThreeValueVertical)
- {
- jassert (valueMin <= valueMax);
- newValue = jlimit (valueMin, valueMax, newValue);
- }
-
- if (currentValue != newValue)
- {
- if (valueBox != 0)
- valueBox->hideEditor (true);
-
- currentValue = newValue;
- updateText();
- repaint();
-
- if (popupDisplay != 0)
- {
- ((SliderPopupDisplayComponent*) popupDisplay)->updatePosition (getTextFromValue (currentValue));
- popupDisplay->repaint();
- }
-
- if (sendUpdateMessage)
- triggerChangeMessage (sendMessageSynchronously);
- }
- }
-
- double Slider::getMinValue() const throw()
- {
- // The minimum value only applies to sliders that are in two- or three-value mode.
- jassert (style == TwoValueHorizontal || style == TwoValueVertical
- || style == ThreeValueHorizontal || style == ThreeValueVertical);
-
- return valueMin;
- }
-
- double Slider::getMaxValue() const throw()
- {
- // The maximum value only applies to sliders that are in two- or three-value mode.
- jassert (style == TwoValueHorizontal || style == TwoValueVertical
- || style == ThreeValueHorizontal || style == ThreeValueVertical);
-
- return valueMax;
- }
-
- void Slider::setMinValue (double newValue, const bool sendUpdateMessage, const bool sendMessageSynchronously)
- {
- // The minimum value only applies to sliders that are in two- or three-value mode.
- jassert (style == TwoValueHorizontal || style == TwoValueVertical
- || style == ThreeValueHorizontal || style == ThreeValueVertical);
-
- newValue = constrainedValue (newValue);
-
- if (style == TwoValueHorizontal || style == TwoValueVertical)
- newValue = jmin (valueMax, newValue);
- else
- newValue = jmin (currentValue, newValue);
-
- if (valueMin != newValue)
- {
- valueMin = newValue;
- repaint();
-
- if (popupDisplay != 0)
- {
- ((SliderPopupDisplayComponent*) popupDisplay)->updatePosition (getTextFromValue (valueMin));
- popupDisplay->repaint();
- }
-
- if (sendUpdateMessage)
- triggerChangeMessage (sendMessageSynchronously);
- }
- }
-
- void Slider::setMaxValue (double newValue, const bool sendUpdateMessage, const bool sendMessageSynchronously)
- {
- // The maximum value only applies to sliders that are in two- or three-value mode.
- jassert (style == TwoValueHorizontal || style == TwoValueVertical
- || style == ThreeValueHorizontal || style == ThreeValueVertical);
-
- newValue = constrainedValue (newValue);
-
- if (style == TwoValueHorizontal || style == TwoValueVertical)
- newValue = jmax (valueMin, newValue);
- else
- newValue = jmax (currentValue, newValue);
-
- if (valueMax != newValue)
- {
- valueMax = newValue;
- repaint();
-
- if (popupDisplay != 0)
- {
- ((SliderPopupDisplayComponent*) popupDisplay)->updatePosition (getTextFromValue (valueMax));
- popupDisplay->repaint();
- }
-
- if (sendUpdateMessage)
- triggerChangeMessage (sendMessageSynchronously);
- }
- }
-
- void Slider::setDoubleClickReturnValue (const bool isDoubleClickEnabled,
- const double valueToSetOnDoubleClick) throw()
- {
- doubleClickToValue = isDoubleClickEnabled;
- doubleClickReturnValue = valueToSetOnDoubleClick;
- }
-
- double Slider::getDoubleClickReturnValue (bool& isEnabled_) const throw()
- {
- isEnabled_ = doubleClickToValue;
- return doubleClickReturnValue;
- }
-
- void Slider::updateText()
- {
- if (valueBox != 0)
- valueBox->setText (getTextFromValue (currentValue), false);
- }
-
- void Slider::setTextValueSuffix (const String& suffix)
- {
- if (textSuffix != suffix)
- {
- textSuffix = suffix;
- updateText();
- }
- }
-
- const String Slider::getTextFromValue (double v)
- {
- if (numDecimalPlaces > 0)
- return String (v, numDecimalPlaces) + textSuffix;
- else
- return String (roundDoubleToInt (v)) + textSuffix;
- }
-
- double Slider::getValueFromText (const String& text)
- {
- String t (text.trimStart());
-
- if (t.endsWith (textSuffix))
- t = t.substring (0, t.length() - textSuffix.length());
-
- while (t.startsWithChar (T('+')))
- t = t.substring (1).trimStart();
-
- return t.initialSectionContainingOnly (T("0123456789.,-"))
- .getDoubleValue();
- }
-
- double Slider::proportionOfLengthToValue (double proportion)
- {
- if (skewFactor != 1.0 && proportion > 0.0)
- proportion = exp (log (proportion) / skewFactor);
-
- return minimum + (maximum - minimum) * proportion;
- }
-
- double Slider::valueToProportionOfLength (double value)
- {
- const double n = (value - minimum) / (maximum - minimum);
-
- return skewFactor == 1.0 ? n : pow (n, skewFactor);
- }
-
- double Slider::snapValue (double attemptedValue, const bool)
- {
- return attemptedValue;
- }
-
- void Slider::startedDragging()
- {
- }
-
- void Slider::stoppedDragging()
- {
- }
-
- void Slider::valueChanged()
- {
- }
-
- void Slider::enablementChanged()
- {
- repaint();
- }
-
- void Slider::setPopupMenuEnabled (const bool menuEnabled_) throw()
- {
- menuEnabled = menuEnabled_;
- }
-
- void Slider::setScrollWheelEnabled (const bool enabled) throw()
- {
- scrollWheelEnabled = enabled;
- }
-
- void Slider::labelTextChanged (Label* label)
- {
- const double newValue = snapValue (getValueFromText (label->getText()), false);
-
- if (getValue() != newValue)
- {
- sendDragStart();
- setValue (newValue, true, true);
- sendDragEnd();
- }
-
- updateText(); // force a clean-up of the text, needed in case setValue() hasn't done this.
- }
-
- void Slider::buttonClicked (Button* button)
- {
- if (style == IncDecButtons)
- {
- sendDragStart();
-
- if (button == incButton)
- setValue (snapValue (getValue() + interval, false), true, true);
- else if (button == decButton)
- setValue (snapValue (getValue() - interval, false), true, true);
-
- sendDragEnd();
- }
- }
-
- double Slider::constrainedValue (double value) const throw()
- {
- if (interval > 0)
- value = minimum + interval * floor ((value - minimum) / interval + 0.5);
-
- if (value <= minimum || maximum <= minimum)
- value = minimum;
- else if (value >= maximum)
- value = maximum;
-
- return value;
- }
-
- float Slider::getLinearSliderPos (const double value)
- {
- double sliderPosProportional;
-
- if (maximum > minimum)
- {
- if (value < minimum)
- {
- sliderPosProportional = 0.0;
- }
- else if (value > maximum)
- {
- sliderPosProportional = 1.0;
- }
- else
- {
- sliderPosProportional = valueToProportionOfLength (value);
- jassert (sliderPosProportional >= 0 && sliderPosProportional <= 1.0);
- }
- }
- else
- {
- sliderPosProportional = 0.5;
- }
-
- if (style == LinearVertical || style == IncDecButtons)
- sliderPosProportional = 1.0 - sliderPosProportional;
-
- return (float) (sliderRegionStart + sliderPosProportional * sliderRegionSize);
- }
-
- bool Slider::isHorizontal() const throw()
- {
- return style == LinearHorizontal
- || style == LinearBar
- || style == TwoValueHorizontal
- || style == ThreeValueHorizontal;
- }
-
- bool Slider::isVertical() const throw()
- {
- return style == LinearVertical
- || style == TwoValueVertical
- || style == ThreeValueVertical;
- }
-
- bool Slider::incDecDragDirectionIsHorizontal() const throw()
- {
- return incDecButtonMode == incDecButtonsDraggable_Horizontal
- || (incDecButtonMode == incDecButtonsDraggable_AutoDirection && incDecButtonsSideBySide);
- }
-
- float Slider::getPositionOfValue (const double value)
- {
- if (isHorizontal() || isVertical())
- {
- return getLinearSliderPos (value);
- }
- else
- {
- jassertfalse // not a valid call on a slider that doesn't work linearly!
- return 0.0f;
- }
- }
-
- void Slider::paint (Graphics& g)
- {
- if (style != IncDecButtons)
- {
- if (style == Rotary || style == RotaryHorizontalDrag || style == RotaryVerticalDrag)
- {
- const float sliderPos = (float) valueToProportionOfLength (currentValue);
- jassert (sliderPos >= 0 && sliderPos <= 1.0f);
-
- getLookAndFeel().drawRotarySlider (g,
- sliderRect.getX(),
- sliderRect.getY(),
- sliderRect.getWidth(),
- sliderRect.getHeight(),
- sliderPos,
- rotaryStart, rotaryEnd,
- *this);
- }
- else
- {
- getLookAndFeel().drawLinearSlider (g,
- sliderRect.getX(),
- sliderRect.getY(),
- sliderRect.getWidth(),
- sliderRect.getHeight(),
- getLinearSliderPos (currentValue),
- getLinearSliderPos (valueMin),
- getLinearSliderPos (valueMax),
- style,
- *this);
- }
-
- if (style == LinearBar && valueBox == 0)
- {
- g.setColour (findColour (Slider::textBoxOutlineColourId));
- g.drawRect (0, 0, getWidth(), getHeight(), 1);
- }
- }
- }
-
- void Slider::resized()
- {
- int minXSpace = 0;
- int minYSpace = 0;
-
- if (textBoxPos == TextBoxLeft || textBoxPos == TextBoxRight)
- minXSpace = 30;
- else
- minYSpace = 15;
-
- const int tbw = jmax (0, jmin (textBoxWidth, getWidth() - minXSpace));
- const int tbh = jmax (0, jmin (textBoxHeight, getHeight() - minYSpace));
-
- if (style == LinearBar)
- {
- if (valueBox != 0)
- valueBox->setBounds (0, 0, getWidth(), getHeight());
- }
- else
- {
- if (textBoxPos == NoTextBox)
- {
- sliderRect.setBounds (0, 0, getWidth(), getHeight());
- }
- else if (textBoxPos == TextBoxLeft)
- {
- valueBox->setBounds (0, (getHeight() - tbh) / 2, tbw, tbh);
- sliderRect.setBounds (tbw, 0, getWidth() - tbw, getHeight());
- }
- else if (textBoxPos == TextBoxRight)
- {
- valueBox->setBounds (getWidth() - tbw, (getHeight() - tbh) / 2, tbw, tbh);
- sliderRect.setBounds (0, 0, getWidth() - tbw, getHeight());
- }
- else if (textBoxPos == TextBoxAbove)
- {
- valueBox->setBounds ((getWidth() - tbw) / 2, 0, tbw, tbh);
- sliderRect.setBounds (0, tbh, getWidth(), getHeight() - tbh);
- }
- else if (textBoxPos == TextBoxBelow)
- {
- valueBox->setBounds ((getWidth() - tbw) / 2, getHeight() - tbh, tbw, tbh);
- sliderRect.setBounds (0, 0, getWidth(), getHeight() - tbh);
- }
- }
-
- const int indent = getLookAndFeel().getSliderThumbRadius (*this);
-
- if (style == LinearBar)
- {
- const int barIndent = 1;
- sliderRegionStart = barIndent;
- sliderRegionSize = getWidth() - barIndent * 2;
-
- sliderRect.setBounds (sliderRegionStart, barIndent,
- sliderRegionSize, getHeight() - barIndent * 2);
- }
- else if (isHorizontal())
- {
- sliderRegionStart = sliderRect.getX() + indent;
- sliderRegionSize = jmax (1, sliderRect.getWidth() - indent * 2);
-
- sliderRect.setBounds (sliderRegionStart, sliderRect.getY(),
- sliderRegionSize, sliderRect.getHeight());
- }
- else if (isVertical())
- {
- sliderRegionStart = sliderRect.getY() + indent;
- sliderRegionSize = jmax (1, sliderRect.getHeight() - indent * 2);
-
- sliderRect.setBounds (sliderRect.getX(), sliderRegionStart,
- sliderRect.getWidth(), sliderRegionSize);
- }
- else
- {
- sliderRegionStart = 0;
- sliderRegionSize = 100;
- }
-
- if (style == IncDecButtons)
- {
- Rectangle buttonRect (sliderRect);
-
- if (textBoxPos == TextBoxLeft || textBoxPos == TextBoxRight)
- buttonRect.expand (-2, 0);
- else
- buttonRect.expand (0, -2);
-
- incDecButtonsSideBySide = buttonRect.getWidth() > buttonRect.getHeight();
-
- if (incDecButtonsSideBySide)
- {
- decButton->setBounds (buttonRect.getX(),
- buttonRect.getY(),
- buttonRect.getWidth() / 2,
- buttonRect.getHeight());
-
- decButton->setConnectedEdges (Button::ConnectedOnRight);
-
- incButton->setBounds (buttonRect.getCentreX(),
- buttonRect.getY(),
- buttonRect.getWidth() / 2,
- buttonRect.getHeight());
-
- incButton->setConnectedEdges (Button::ConnectedOnLeft);
- }
- else
- {
- incButton->setBounds (buttonRect.getX(),
- buttonRect.getY(),
- buttonRect.getWidth(),
- buttonRect.getHeight() / 2);
-
- incButton->setConnectedEdges (Button::ConnectedOnBottom);
-
- decButton->setBounds (buttonRect.getX(),
- buttonRect.getCentreY(),
- buttonRect.getWidth(),
- buttonRect.getHeight() / 2);
-
- decButton->setConnectedEdges (Button::ConnectedOnTop);
- }
- }
- }
-
- void Slider::focusOfChildComponentChanged (FocusChangeType)
- {
- repaint();
- }
-
- void Slider::mouseDown (const MouseEvent& e)
- {
- mouseWasHidden = false;
- incDecDragged = false;
-
- if (isEnabled())
- {
- if (e.mods.isPopupMenu() && menuEnabled)
- {
- menuShown = true;
-
- PopupMenu m;
- m.addItem (1, TRANS ("velocity-sensitive mode"), true, isVelocityBased);
- m.addSeparator();
-
- if (style == Rotary || style == RotaryHorizontalDrag || style == RotaryVerticalDrag)
- {
- PopupMenu rotaryMenu;
- rotaryMenu.addItem (2, TRANS ("use circular dragging"), true, style == Rotary);
- rotaryMenu.addItem (3, TRANS ("use left-right dragging"), true, style == RotaryHorizontalDrag);
- rotaryMenu.addItem (4, TRANS ("use up-down dragging"), true, style == RotaryVerticalDrag);
-
- m.addSubMenu (TRANS ("rotary mode"), rotaryMenu);
- }
-
- const int r = m.show();
-
- if (r == 1)
- {
- setVelocityBasedMode (! isVelocityBased);
- }
- else if (r == 2)
- {
- setSliderStyle (Rotary);
- }
- else if (r == 3)
- {
- setSliderStyle (RotaryHorizontalDrag);
- }
- else if (r == 4)
- {
- setSliderStyle (RotaryVerticalDrag);
- }
- }
- else if (maximum > minimum)
- {
- menuShown = false;
-
- if (valueBox != 0)
- valueBox->hideEditor (true);
-
- sliderBeingDragged = 0;
-
- if (style == TwoValueHorizontal
- || style == TwoValueVertical
- || style == ThreeValueHorizontal
- || style == ThreeValueVertical)
- {
- const float mousePos = (float) (isVertical() ? e.y : e.x);
-
- const float normalPosDistance = fabsf (getLinearSliderPos (currentValue) - mousePos);
- const float minPosDistance = fabsf (getLinearSliderPos (valueMin) - 0.1f - mousePos);
- const float maxPosDistance = fabsf (getLinearSliderPos (valueMax) + 0.1f - mousePos);
-
- if (style == TwoValueHorizontal || style == TwoValueVertical)
- {
- if (maxPosDistance <= minPosDistance)
- sliderBeingDragged = 2;
- else
- sliderBeingDragged = 1;
- }
- else if (style == ThreeValueHorizontal || style == ThreeValueVertical)
- {
- if (normalPosDistance >= minPosDistance && maxPosDistance >= minPosDistance)
- sliderBeingDragged = 1;
- else if (normalPosDistance >= maxPosDistance)
- sliderBeingDragged = 2;
- }
- }
-
- minMaxDiff = valueMax - valueMin;
-
- mouseXWhenLastDragged = e.x;
- mouseYWhenLastDragged = e.y;
- lastAngle = rotaryStart + (rotaryEnd - rotaryStart)
- * valueToProportionOfLength (currentValue);
-
- if (sliderBeingDragged == 2)
- valueWhenLastDragged = valueMax;
- else if (sliderBeingDragged == 1)
- valueWhenLastDragged = valueMin;
- else
- valueWhenLastDragged = currentValue;
-
- valueOnMouseDown = valueWhenLastDragged;
-
- if (popupDisplayEnabled)
- {
- SliderPopupDisplayComponent* const popup = new SliderPopupDisplayComponent (this);
- popupDisplay = popup;
-
- if (parentForPopupDisplay != 0)
- {
- parentForPopupDisplay->addChildComponent (popup);
- }
- else
- {
- popup->addToDesktop (0);
- }
-
- popup->setVisible (true);
- }
-
- sendDragStart();
-
- mouseDrag (e);
- }
- }
- }
-
- void Slider::mouseUp (const MouseEvent&)
- {
- if (isEnabled()
- && (! menuShown)
- && (maximum > minimum)
- && (style != IncDecButtons || incDecDragged))
- {
- restoreMouseIfHidden();
-
- if (sendChangeOnlyOnRelease && valueOnMouseDown != currentValue)
- triggerChangeMessage (false);
-
- sendDragEnd();
-
- deleteAndZero (popupDisplay);
-
- if (style == IncDecButtons)
- {
- incButton->setState (Button::buttonNormal);
- decButton->setState (Button::buttonNormal);
- }
- }
- }
-
- void Slider::restoreMouseIfHidden()
- {
- if (mouseWasHidden)
- {
- mouseWasHidden = false;
-
- Component* c = Component::getComponentUnderMouse();
-
- if (c == 0)
- c = this;
-
- c->enableUnboundedMouseMovement (false);
-
- const double pos = (sliderBeingDragged == 2) ? getMaxValue()
- : ((sliderBeingDragged == 1) ? getMinValue()
- : currentValue);
-
- const int pixelPos = (int) getLinearSliderPos (pos);
-
- int x = isHorizontal() ? pixelPos : (getWidth() / 2);
- int y = isVertical() ? pixelPos : (getHeight() / 2);
-
- relativePositionToGlobal (x, y);
- Desktop::setMousePosition (x, y);
- }
- }
-
- void Slider::modifierKeysChanged (const ModifierKeys& modifiers)
- {
- if (isEnabled()
- && style != IncDecButtons
- && style != Rotary
- && isVelocityBased == modifiers.isAnyModifierKeyDown())
- {
- restoreMouseIfHidden();
- }
- }
-
- static double smallestAngleBetween (double a1, double a2)
- {
- return jmin (fabs (a1 - a2),
- fabs (a1 + double_Pi * 2.0 - a2),
- fabs (a2 + double_Pi * 2.0 - a1));
- }
-
- void Slider::mouseDrag (const MouseEvent& e)
- {
- if (isEnabled()
- && (! menuShown)
- && (maximum > minimum))
- {
- if (style == Rotary)
- {
- int dx = e.x - sliderRect.getCentreX();
- int dy = e.y - sliderRect.getCentreY();
-
- if (dx * dx + dy * dy > 25)
- {
- double angle = atan2 ((double) dx, (double) -dy);
- while (angle < 0.0)
- angle += double_Pi * 2.0;
-
- if (rotaryStop && ! e.mouseWasClicked())
- {
- if (fabs (angle - lastAngle) > double_Pi)
- {
- if (angle >= lastAngle)
- angle -= double_Pi * 2.0;
- else
- angle += double_Pi * 2.0;
- }
-
- if (angle >= lastAngle)
- angle = jmin (angle, (double) jmax (rotaryStart, rotaryEnd));
- else
- angle = jmax (angle, (double) jmin (rotaryStart, rotaryEnd));
- }
- else
- {
- while (angle < rotaryStart)
- angle += double_Pi * 2.0;
-
- if (angle > rotaryEnd)
- {
- if (smallestAngleBetween (angle, rotaryStart) <= smallestAngleBetween (angle, rotaryEnd))
- angle = rotaryStart;
- else
- angle = rotaryEnd;
- }
- }
-
- const double proportion = (angle - rotaryStart) / (rotaryEnd - rotaryStart);
-
- valueWhenLastDragged = proportionOfLengthToValue (jlimit (0.0, 1.0, proportion));
-
- lastAngle = angle;
- }
- }
- else
- {
- if (style == LinearBar && e.mouseWasClicked()
- && valueBox != 0 && valueBox->isEditable())
- return;
-
- if (style == IncDecButtons)
- {
- if (! incDecDragged)
- incDecDragged = e.getDistanceFromDragStart() > 10 && ! e.mouseWasClicked();
-
- if (! incDecDragged)
- return;
- }
-
- if ((isVelocityBased == (userKeyOverridesVelocity ? e.mods.testFlags (ModifierKeys::ctrlModifier | ModifierKeys::commandModifier | ModifierKeys::altModifier)
- : false))
- || ((maximum - minimum) / sliderRegionSize < interval))
- {
- const int mousePos = (isHorizontal() || style == RotaryHorizontalDrag) ? e.x : e.y;
-
- double scaledMousePos = (mousePos - sliderRegionStart) / (double) sliderRegionSize;
-
- if (style == RotaryHorizontalDrag
- || style == RotaryVerticalDrag
- || style == IncDecButtons
- || ((style == LinearHorizontal || style == LinearVertical || style == LinearBar)
- && ! snapsToMousePos))
- {
- const int mouseDiff = (style == RotaryHorizontalDrag
- || style == LinearHorizontal
- || style == LinearBar
- || (style == IncDecButtons && incDecDragDirectionIsHorizontal()))
- ? e.getDistanceFromDragStartX()
- : -e.getDistanceFromDragStartY();
-
- double newPos = valueToProportionOfLength (valueOnMouseDown)
- + mouseDiff * (1.0 / pixelsForFullDragExtent);
-
- valueWhenLastDragged = proportionOfLengthToValue (jlimit (0.0, 1.0, newPos));
-
- if (style == IncDecButtons)
- {
- incButton->setState (mouseDiff < 0 ? Button::buttonNormal : Button::buttonDown);
- decButton->setState (mouseDiff > 0 ? Button::buttonNormal : Button::buttonDown);
- }
- }
- else
- {
- if (style == LinearVertical)
- scaledMousePos = 1.0 - scaledMousePos;
-
- valueWhenLastDragged = proportionOfLengthToValue (jlimit (0.0, 1.0, scaledMousePos));
- }
- }
- else
- {
- const int mouseDiff = (isHorizontal() || style == RotaryHorizontalDrag
- || (style == IncDecButtons && incDecDragDirectionIsHorizontal()))
- ? e.x - mouseXWhenLastDragged
- : e.y - mouseYWhenLastDragged;
-
- const double maxSpeed = jmax (200, sliderRegionSize);
- double speed = jlimit (0.0, maxSpeed, (double) abs (mouseDiff));
-
- if (speed != 0)
- {
- speed = 0.2 * velocityModeSensitivity
- * (1.0 + sin (double_Pi * (1.5 + jmin (0.5, velocityModeOffset
- + jmax (0.0, (double) (speed - velocityModeThreshold))
- / maxSpeed))));
-
- if (mouseDiff < 0)
- speed = -speed;
-
- if (style == LinearVertical || style == RotaryVerticalDrag
- || (style == IncDecButtons && ! incDecDragDirectionIsHorizontal()))
- speed = -speed;
-
- const double currentPos = valueToProportionOfLength (valueWhenLastDragged);
-
- valueWhenLastDragged = proportionOfLengthToValue (jlimit (0.0, 1.0, currentPos + speed));
-
- e.originalComponent->enableUnboundedMouseMovement (true, false);
- mouseWasHidden = true;
- }
- }
- }
-
- valueWhenLastDragged = jlimit (minimum, maximum, valueWhenLastDragged);
-
- if (sliderBeingDragged == 0)
- {
- setValue (snapValue (valueWhenLastDragged, true),
- ! sendChangeOnlyOnRelease, true);
- }
- else if (sliderBeingDragged == 1)
- {
- setMinValue (snapValue (valueWhenLastDragged, true),
- ! sendChangeOnlyOnRelease, false);
-
- if (e.mods.isShiftDown())
- setMaxValue (getMinValue() + minMaxDiff, false);
- else
- minMaxDiff = valueMax - valueMin;
- }
- else
- {
- jassert (sliderBeingDragged == 2);
-
- setMaxValue (snapValue (valueWhenLastDragged, true),
- ! sendChangeOnlyOnRelease, false);
-
- if (e.mods.isShiftDown())
- setMinValue (getMaxValue() - minMaxDiff, false);
- else
- minMaxDiff = valueMax - valueMin;
- }
-
- mouseXWhenLastDragged = e.x;
- mouseYWhenLastDragged = e.y;
- }
- }
-
- void Slider::mouseDoubleClick (const MouseEvent&)
- {
- if (doubleClickToValue
- && isEnabled()
- && style != IncDecButtons
- && minimum <= doubleClickReturnValue
- && maximum >= doubleClickReturnValue)
- {
- sendDragStart();
- setValue (doubleClickReturnValue, true, true);
- sendDragEnd();
- }
- }
-
- void Slider::mouseWheelMove (const MouseEvent& e, float wheelIncrementX, float wheelIncrementY)
- {
- if (scrollWheelEnabled && isEnabled())
- {
- if (maximum > minimum && ! isMouseButtonDownAnywhere())
- {
- if (valueBox != 0)
- valueBox->hideEditor (false);
-
- const double proportionDelta = (wheelIncrementX != 0 ? -wheelIncrementX : wheelIncrementY) * 0.15f;
- const double currentPos = valueToProportionOfLength (currentValue);
- const double newValue = proportionOfLengthToValue (jlimit (0.0, 1.0, currentPos + proportionDelta));
-
- double delta = (newValue != currentValue)
- ? jmax (fabs (newValue - currentValue), interval) : 0;
-
- if (currentValue > newValue)
- delta = -delta;
-
- sendDragStart();
- setValue (snapValue (currentValue + delta, false), true, true);
- sendDragEnd();
- }
- }
- else
- {
- Component::mouseWheelMove (e, wheelIncrementX, wheelIncrementY);
- }
- }
-
- void SliderListener::sliderDragStarted (Slider*)
- {
- }
-
- void SliderListener::sliderDragEnded (Slider*)
- {
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_Slider.cpp *********/
-
- /********* Start of inlined file: juce_TableHeaderComponent.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- class DragOverlayComp : public Component
- {
- public:
- DragOverlayComp (Image* const image_)
- : image (image_)
- {
- image->multiplyAllAlphas (0.8f);
- setAlwaysOnTop (true);
- }
-
- ~DragOverlayComp()
- {
- delete image;
- }
-
- void paint (Graphics& g)
- {
- g.drawImageAt (image, 0, 0);
- }
-
- private:
- Image* image;
-
- DragOverlayComp (const DragOverlayComp&);
- const DragOverlayComp& operator= (const DragOverlayComp&);
- };
-
- TableHeaderComponent::TableHeaderComponent()
- : listeners (2),
- dragOverlayComp (0),
- columnsChanged (false),
- columnsResized (false),
- sortChanged (false),
- menuActive (true),
- stretchToFit (false),
- columnIdBeingResized (0),
- columnIdBeingDragged (0),
- columnIdUnderMouse (0),
- lastDeliberateWidth (0)
- {
- }
-
- TableHeaderComponent::~TableHeaderComponent()
- {
- delete dragOverlayComp;
- }
-
- void TableHeaderComponent::setPopupMenuActive (const bool hasMenu)
- {
- menuActive = hasMenu;
- }
-
- bool TableHeaderComponent::isPopupMenuActive() const throw() { return menuActive; }
-
- int TableHeaderComponent::getNumColumns (const bool onlyCountVisibleColumns) const throw()
- {
- if (onlyCountVisibleColumns)
- {
- int num = 0;
-
- for (int i = columns.size(); --i >= 0;)
- if (columns.getUnchecked(i)->isVisible())
- ++num;
-
- return num;
- }
- else
- {
- return columns.size();
- }
- }
-
- const String TableHeaderComponent::getColumnName (const int columnId) const throw()
- {
- const ColumnInfo* const ci = getInfoForId (columnId);
- return ci != 0 ? ci->name : String::empty;
- }
-
- void TableHeaderComponent::setColumnName (const int columnId, const String& newName)
- {
- ColumnInfo* const ci = getInfoForId (columnId);
-
- if (ci != 0 && ci->name != newName)
- {
- ci->name = newName;
- sendColumnsChanged();
- }
- }
-
- void TableHeaderComponent::addColumn (const String& columnName,
- const int columnId,
- const int width,
- const int minimumWidth,
- const int maximumWidth,
- const int propertyFlags,
- const int insertIndex)
- {
- // can't have a duplicate or null ID!
- jassert (columnId != 0 && getIndexOfColumnId (columnId, false) < 0);
- jassert (width > 0);
-
- ColumnInfo* const ci = new ColumnInfo();
- ci->name = columnName;
- ci->id = columnId;
- ci->width = width;
- ci->lastDeliberateWidth = width;
- ci->minimumWidth = minimumWidth;
- ci->maximumWidth = maximumWidth;
- if (ci->maximumWidth < 0)
- ci->maximumWidth = INT_MAX;
- jassert (ci->maximumWidth >= ci->minimumWidth);
- ci->propertyFlags = propertyFlags;
-
- columns.insert (insertIndex, ci);
- sendColumnsChanged();
- }
-
- void TableHeaderComponent::removeColumn (const int columnIdToRemove)
- {
- const int index = getIndexOfColumnId (columnIdToRemove, false);
-
- if (index >= 0)
- {
- columns.remove (index);
- sortChanged = true;
- sendColumnsChanged();
- }
- }
-
- void TableHeaderComponent::removeAllColumns()
- {
- if (columns.size() > 0)
- {
- columns.clear();
- sendColumnsChanged();
- }
- }
-
- void TableHeaderComponent::moveColumn (const int columnId, int newIndex)
- {
- const int currentIndex = getIndexOfColumnId (columnId, false);
- newIndex = visibleIndexToTotalIndex (newIndex);
-
- if (columns [currentIndex] != 0 && currentIndex != newIndex)
- {
- columns.move (currentIndex, newIndex);
- sendColumnsChanged();
- }
- }
-
- void TableHeaderComponent::setColumnWidth (const int columnId, const int newWidth)
- {
- ColumnInfo* const ci = getInfoForId (columnId);
-
- if (ci != 0 && ci->width != newWidth)
- {
- const int numColumns = getNumColumns (true);
-
- ci->lastDeliberateWidth = ci->width
- = jlimit (ci->minimumWidth, ci->maximumWidth, newWidth);
-
- if (stretchToFit)
- {
- const int index = getIndexOfColumnId (columnId, true) + 1;
-
- if (((unsigned int) index) < (unsigned int) numColumns)
- {
- const int x = getColumnPosition (index).getX();
-
- if (lastDeliberateWidth == 0)
- lastDeliberateWidth = getTotalWidth();
-
- resizeColumnsToFit (visibleIndexToTotalIndex (index), lastDeliberateWidth - x);
- }
- }
-
- repaint();
- columnsResized = true;
- triggerAsyncUpdate();
- }
- }
-
- int TableHeaderComponent::getIndexOfColumnId (const int columnId, const bool onlyCountVisibleColumns) const throw()
- {
- int n = 0;
-
- for (int i = 0; i < columns.size(); ++i)
- {
- if ((! onlyCountVisibleColumns) || columns.getUnchecked(i)->isVisible())
- {
- if (columns.getUnchecked(i)->id == columnId)
- return n;
-
- ++n;
- }
- }
-
- return -1;
- }
-
- int TableHeaderComponent::getColumnIdOfIndex (int index, const bool onlyCountVisibleColumns) const throw()
- {
- if (onlyCountVisibleColumns)
- index = visibleIndexToTotalIndex (index);
-
- const ColumnInfo* const ci = columns [index];
- return (ci != 0) ? ci->id : 0;
- }
-
- const Rectangle TableHeaderComponent::getColumnPosition (const int index) const throw()
- {
- int x = 0, width = 0, n = 0;
-
- for (int i = 0; i < columns.size(); ++i)
- {
- x += width;
-
- if (columns.getUnchecked(i)->isVisible())
- {
- width = columns.getUnchecked(i)->width;
-
- if (n++ == index)
- break;
- }
- else
- {
- width = 0;
- }
- }
-
- return Rectangle (x, 0, width, getHeight());
- }
-
- int TableHeaderComponent::getColumnIdAtX (const int xToFind) const throw()
- {
- if (xToFind >= 0)
- {
- int x = 0;
-
- for (int i = 0; i < columns.size(); ++i)
- {
- const ColumnInfo* const ci = columns.getUnchecked(i);
-
- if (ci->isVisible())
- {
- x += ci->width;
-
- if (xToFind < x)
- return ci->id;
- }
- }
- }
-
- return 0;
- }
-
- int TableHeaderComponent::getTotalWidth() const throw()
- {
- int w = 0;
-
- for (int i = columns.size(); --i >= 0;)
- if (columns.getUnchecked(i)->isVisible())
- w += columns.getUnchecked(i)->width;
-
- return w;
- }
-
- void TableHeaderComponent::setStretchToFitActive (const bool shouldStretchToFit)
- {
- stretchToFit = shouldStretchToFit;
- lastDeliberateWidth = getTotalWidth();
- resized();
- }
-
- bool TableHeaderComponent::isStretchToFitActive() const throw()
- {
- return stretchToFit;
- }
-
- void TableHeaderComponent::resizeAllColumnsToFit (int targetTotalWidth)
- {
- if (stretchToFit && getWidth() > 0
- && columnIdBeingResized == 0 && columnIdBeingDragged == 0)
- {
- lastDeliberateWidth = targetTotalWidth;
- resizeColumnsToFit (0, targetTotalWidth);
- }
- }
-
- void TableHeaderComponent::resizeColumnsToFit (int firstColumnIndex, int targetTotalWidth)
- {
- targetTotalWidth = jmax (targetTotalWidth, 0);
-
- StretchableObjectResizer sor;
- int i;
- for (i = firstColumnIndex; i < columns.size(); ++i)
- {
- ColumnInfo* const ci = columns.getUnchecked(i);
-
- if (ci->isVisible())
- sor.addItem (ci->lastDeliberateWidth, ci->minimumWidth, ci->maximumWidth);
- }
-
- sor.resizeToFit (targetTotalWidth);
-
- int visIndex = 0;
- for (i = firstColumnIndex; i < columns.size(); ++i)
- {
- ColumnInfo* const ci = columns.getUnchecked(i);
-
- if (ci->isVisible())
- {
- const int newWidth = jlimit (ci->minimumWidth, ci->maximumWidth,
- (int) floor (sor.getItemSize (visIndex++)));
-
- if (newWidth != ci->width)
- {
- ci->width = newWidth;
- repaint();
- columnsResized = true;
- triggerAsyncUpdate();
- }
- }
- }
- }
-
- void TableHeaderComponent::setColumnVisible (const int columnId, const bool shouldBeVisible)
- {
- ColumnInfo* const ci = getInfoForId (columnId);
-
- if (ci != 0 && shouldBeVisible != ci->isVisible())
- {
- if (shouldBeVisible)
- ci->propertyFlags |= visible;
- else
- ci->propertyFlags &= ~visible;
-
- sendColumnsChanged();
- resized();
- }
- }
-
- bool TableHeaderComponent::isColumnVisible (const int columnId) const
- {
- const ColumnInfo* const ci = getInfoForId (columnId);
- return ci != 0 && ci->isVisible();
- }
-
- void TableHeaderComponent::setSortColumnId (const int columnId, const bool sortForwards)
- {
- if (getSortColumnId() != columnId || isSortedForwards() != sortForwards)
- {
- for (int i = columns.size(); --i >= 0;)
- columns.getUnchecked(i)->propertyFlags &= ~(sortedForwards | sortedBackwards);
-
- ColumnInfo* const ci = getInfoForId (columnId);
-
- if (ci != 0)
- ci->propertyFlags |= (sortForwards ? sortedForwards : sortedBackwards);
-
- reSortTable();
- }
- }
-
- int TableHeaderComponent::getSortColumnId() const throw()
- {
- for (int i = columns.size(); --i >= 0;)
- if ((columns.getUnchecked(i)->propertyFlags & (sortedForwards | sortedBackwards)) != 0)
- return columns.getUnchecked(i)->id;
-
- return 0;
- }
-
- bool TableHeaderComponent::isSortedForwards() const throw()
- {
- for (int i = columns.size(); --i >= 0;)
- if ((columns.getUnchecked(i)->propertyFlags & (sortedForwards | sortedBackwards)) != 0)
- return (columns.getUnchecked(i)->propertyFlags & sortedForwards) != 0;
-
- return true;
- }
-
- void TableHeaderComponent::reSortTable()
- {
- sortChanged = true;
- repaint();
- triggerAsyncUpdate();
- }
-
- const String TableHeaderComponent::toString() const
- {
- String s;
-
- XmlElement doc (T("TABLELAYOUT"));
-
- doc.setAttribute (T("sortedCol"), getSortColumnId());
- doc.setAttribute (T("sortForwards"), isSortedForwards());
-
- for (int i = 0; i < columns.size(); ++i)
- {
- const ColumnInfo* const ci = columns.getUnchecked (i);
-
- XmlElement* const e = new XmlElement (T("COLUMN"));
- doc.addChildElement (e);
-
- e->setAttribute (T("id"), ci->id);
- e->setAttribute (T("visible"), ci->isVisible());
- e->setAttribute (T("width"), ci->width);
- }
-
- return doc.createDocument (String::empty, true, false);
- }
-
- void TableHeaderComponent::restoreFromString (const String& storedVersion)
- {
- XmlDocument doc (storedVersion);
- XmlElement* const storedXml = doc.getDocumentElement();
-
- int index = 0;
-
- if (storedXml != 0 && storedXml->hasTagName (T("TABLELAYOUT")))
- {
- forEachXmlChildElement (*storedXml, col)
- {
- const int tabId = col->getIntAttribute (T("id"));
-
- ColumnInfo* const ci = getInfoForId (tabId);
-
- if (ci != 0)
- {
- columns.move (columns.indexOf (ci), index);
- ci->width = col->getIntAttribute (T("width"));
- setColumnVisible (tabId, col->getBoolAttribute (T("visible")));
- }
-
- ++index;
- }
-
- columnsResized = true;
- sendColumnsChanged();
-
- setSortColumnId (storedXml->getIntAttribute (T("sortedCol")),
- storedXml->getBoolAttribute (T("sortForwards"), true));
- }
-
- delete storedXml;
- }
-
- void TableHeaderComponent::addListener (TableHeaderListener* const newListener) throw()
- {
- listeners.addIfNotAlreadyThere (newListener);
- }
-
- void TableHeaderComponent::removeListener (TableHeaderListener* const listenerToRemove) throw()
- {
- listeners.removeValue (listenerToRemove);
- }
-
- void TableHeaderComponent::columnClicked (int columnId, const ModifierKeys& mods)
- {
- const ColumnInfo* const ci = getInfoForId (columnId);
-
- if (ci != 0 && (ci->propertyFlags & sortable) != 0 && ! mods.isPopupMenu())
- setSortColumnId (columnId, (ci->propertyFlags & sortedForwards) == 0);
- }
-
- void TableHeaderComponent::addMenuItems (PopupMenu& menu, const int /*columnIdClicked*/)
- {
- for (int i = 0; i < columns.size(); ++i)
- {
- const ColumnInfo* const ci = columns.getUnchecked(i);
-
- if ((ci->propertyFlags & appearsOnColumnMenu) != 0)
- menu.addItem (ci->id, ci->name,
- (ci->propertyFlags & (sortedForwards | sortedBackwards)) == 0,
- isColumnVisible (ci->id));
- }
- }
-
- void TableHeaderComponent::reactToMenuItem (const int menuReturnId, const int /*columnIdClicked*/)
- {
- if (getIndexOfColumnId (menuReturnId, false) >= 0)
- setColumnVisible (menuReturnId, ! isColumnVisible (menuReturnId));
- }
-
- void TableHeaderComponent::paint (Graphics& g)
- {
- LookAndFeel& lf = getLookAndFeel();
-
- lf.drawTableHeaderBackground (g, *this);
-
- const Rectangle clip (g.getClipBounds());
-
- int x = 0;
- for (int i = 0; i < columns.size(); ++i)
- {
- const ColumnInfo* const ci = columns.getUnchecked(i);
-
- if (ci->isVisible())
- {
- if (x + ci->width > clip.getX()
- && (ci->id != columnIdBeingDragged
- || dragOverlayComp == 0
- || ! dragOverlayComp->isVisible()))
- {
- g.saveState();
- g.setOrigin (x, 0);
- g.reduceClipRegion (0, 0, ci->width, getHeight());
-
- lf.drawTableHeaderColumn (g, ci->name, ci->id, ci->width, getHeight(),
- ci->id == columnIdUnderMouse,
- ci->id == columnIdUnderMouse && isMouseButtonDown(),
- ci->propertyFlags);
-
- g.restoreState();
- }
-
- x += ci->width;
-
- if (x >= clip.getRight())
- break;
- }
- }
- }
-
- void TableHeaderComponent::resized()
- {
- }
-
- void TableHeaderComponent::mouseMove (const MouseEvent& e)
- {
- updateColumnUnderMouse (e.x, e.y);
- }
-
- void TableHeaderComponent::mouseEnter (const MouseEvent& e)
- {
- updateColumnUnderMouse (e.x, e.y);
- }
-
- void TableHeaderComponent::mouseExit (const MouseEvent& e)
- {
- updateColumnUnderMouse (e.x, e.y);
- }
-
- void TableHeaderComponent::mouseDown (const MouseEvent& e)
- {
- repaint();
- columnIdBeingResized = 0;
- columnIdBeingDragged = 0;
-
- if (columnIdUnderMouse != 0)
- {
- draggingColumnOffset = e.x - getColumnPosition (getIndexOfColumnId (columnIdUnderMouse, true)).getX();
-
- if (e.mods.isPopupMenu())
- columnClicked (columnIdUnderMouse, e.mods);
- }
-
- if (menuActive && e.mods.isPopupMenu())
- showColumnChooserMenu (columnIdUnderMouse);
- }
-
- void TableHeaderComponent::mouseDrag (const MouseEvent& e)
- {
- if (columnIdBeingResized == 0
- && columnIdBeingDragged == 0
- && ! (e.mouseWasClicked() || e.mods.isPopupMenu()))
- {
- deleteAndZero (dragOverlayComp);
-
- columnIdBeingResized = getResizeDraggerAt (e.getMouseDownX());
-
- if (columnIdBeingResized != 0)
- {
- const ColumnInfo* const ci = getInfoForId (columnIdBeingResized);
- initialColumnWidth = ci->width;
- }
- else
- {
- beginDrag (e);
- }
- }
-
- if (columnIdBeingResized != 0)
- {
- const ColumnInfo* const ci = getInfoForId (columnIdBeingResized);
-
- if (ci != 0)
- {
- int w = jlimit (ci->minimumWidth, ci->maximumWidth,
- initialColumnWidth + e.getDistanceFromDragStartX());
-
- if (stretchToFit)
- {
- // prevent us dragging a column too far right if we're in stretch-to-fit mode
- int minWidthOnRight = 0;
- for (int i = getIndexOfColumnId (columnIdBeingResized, false) + 1; i < columns.size(); ++i)
- if (columns.getUnchecked (i)->isVisible())
- minWidthOnRight += columns.getUnchecked (i)->minimumWidth;
-
- const Rectangle currentPos (getColumnPosition (getIndexOfColumnId (columnIdBeingResized, true)));
- w = jmax (ci->minimumWidth, jmin (w, getWidth() - minWidthOnRight - currentPos.getX()));
- }
-
- setColumnWidth (columnIdBeingResized, w);
- }
- }
- else if (columnIdBeingDragged != 0)
- {
- if (e.y >= -50 && e.y < getHeight() + 50)
- {
- beginDrag (e);
-
- if (dragOverlayComp != 0)
- {
- dragOverlayComp->setVisible (true);
- dragOverlayComp->setBounds (jlimit (0,
- jmax (0, getTotalWidth() - dragOverlayComp->getWidth()),
- e.x - draggingColumnOffset),
- 0,
- dragOverlayComp->getWidth(),
- getHeight());
-
- for (int i = columns.size(); --i >= 0;)
- {
- const int currentIndex = getIndexOfColumnId (columnIdBeingDragged, true);
- int newIndex = currentIndex;
-
- if (newIndex > 0)
- {
- // if the previous column isn't draggable, we can't move our column
- // past it, because that'd change the undraggable column's position..
- const ColumnInfo* const previous = columns.getUnchecked (newIndex - 1);
-
- if ((previous->propertyFlags & draggable) != 0)
- {
- const int leftOfPrevious = getColumnPosition (newIndex - 1).getX();
- const int rightOfCurrent = getColumnPosition (newIndex).getRight();
-
- if (abs (dragOverlayComp->getX() - leftOfPrevious)
- < abs (dragOverlayComp->getRight() - rightOfCurrent))
- {
- --newIndex;
- }
- }
- }
-
- if (newIndex < columns.size() - 1)
- {
- // if the next column isn't draggable, we can't move our column
- // past it, because that'd change the undraggable column's position..
- const ColumnInfo* const nextCol = columns.getUnchecked (newIndex + 1);
-
- if ((nextCol->propertyFlags & draggable) != 0)
- {
- const int leftOfCurrent = getColumnPosition (newIndex).getX();
- const int rightOfNext = getColumnPosition (newIndex + 1).getRight();
-
- if (abs (dragOverlayComp->getX() - leftOfCurrent)
- > abs (dragOverlayComp->getRight() - rightOfNext))
- {
- ++newIndex;
- }
- }
- }
-
- if (newIndex != currentIndex)
- moveColumn (columnIdBeingDragged, newIndex);
- else
- break;
- }
- }
- }
- else
- {
- endDrag (draggingColumnOriginalIndex);
- }
- }
- }
-
- void TableHeaderComponent::beginDrag (const MouseEvent& e)
- {
- if (columnIdBeingDragged == 0)
- {
- columnIdBeingDragged = getColumnIdAtX (e.getMouseDownX());
-
- const ColumnInfo* const ci = getInfoForId (columnIdBeingDragged);
-
- if (ci == 0 || (ci->propertyFlags & draggable) == 0)
- {
- columnIdBeingDragged = 0;
- }
- else
- {
- draggingColumnOriginalIndex = getIndexOfColumnId (columnIdBeingDragged, true);
-
- const Rectangle columnRect (getColumnPosition (draggingColumnOriginalIndex));
-
- const int temp = columnIdBeingDragged;
- columnIdBeingDragged = 0;
-
- addAndMakeVisible (dragOverlayComp = new DragOverlayComp (createComponentSnapshot (columnRect, false)));
- columnIdBeingDragged = temp;
-
- dragOverlayComp->setBounds (columnRect);
-
- for (int i = listeners.size(); --i >= 0;)
- {
- listeners.getUnchecked(i)->tableColumnDraggingChanged (this, columnIdBeingDragged);
- i = jmin (i, listeners.size() - 1);
- }
- }
- }
- }
-
- void TableHeaderComponent::endDrag (const int finalIndex)
- {
- if (columnIdBeingDragged != 0)
- {
- moveColumn (columnIdBeingDragged, finalIndex);
-
- columnIdBeingDragged = 0;
- repaint();
-
- for (int i = listeners.size(); --i >= 0;)
- {
- listeners.getUnchecked(i)->tableColumnDraggingChanged (this, 0);
- i = jmin (i, listeners.size() - 1);
- }
- }
- }
-
- void TableHeaderComponent::mouseUp (const MouseEvent& e)
- {
- mouseDrag (e);
-
- for (int i = columns.size(); --i >= 0;)
- if (columns.getUnchecked (i)->isVisible())
- columns.getUnchecked (i)->lastDeliberateWidth = columns.getUnchecked (i)->width;
-
- columnIdBeingResized = 0;
- repaint();
-
- endDrag (getIndexOfColumnId (columnIdBeingDragged, true));
-
- updateColumnUnderMouse (e.x, e.y);
-
- if (columnIdUnderMouse != 0 && e.mouseWasClicked() && ! e.mods.isPopupMenu())
- columnClicked (columnIdUnderMouse, e.mods);
-
- deleteAndZero (dragOverlayComp);
- }
-
- const MouseCursor TableHeaderComponent::getMouseCursor()
- {
- int x, y;
- getMouseXYRelative (x, y);
-
- if (columnIdBeingResized != 0 || (getResizeDraggerAt (x) != 0 && ! isMouseButtonDown()))
- return MouseCursor (MouseCursor::LeftRightResizeCursor);
-
- return Component::getMouseCursor();
- }
-
- bool TableHeaderComponent::ColumnInfo::isVisible() const throw()
- {
- return (propertyFlags & TableHeaderComponent::visible) != 0;
- }
-
- TableHeaderComponent::ColumnInfo* TableHeaderComponent::getInfoForId (const int id) const throw()
- {
- for (int i = columns.size(); --i >= 0;)
- if (columns.getUnchecked(i)->id == id)
- return columns.getUnchecked(i);
-
- return 0;
- }
-
- int TableHeaderComponent::visibleIndexToTotalIndex (const int visibleIndex) const throw()
- {
- int n = 0;
-
- for (int i = 0; i < columns.size(); ++i)
- {
- if (columns.getUnchecked(i)->isVisible())
- {
- if (n == visibleIndex)
- return i;
-
- ++n;
- }
- }
-
- return -1;
- }
-
- void TableHeaderComponent::sendColumnsChanged()
- {
- if (stretchToFit && lastDeliberateWidth > 0)
- resizeAllColumnsToFit (lastDeliberateWidth);
-
- repaint();
- columnsChanged = true;
- triggerAsyncUpdate();
- }
-
- void TableHeaderComponent::handleAsyncUpdate()
- {
- const bool changed = columnsChanged || sortChanged;
- const bool sized = columnsResized || changed;
- const bool sorted = sortChanged;
- columnsChanged = false;
- columnsResized = false;
- sortChanged = false;
-
- if (sorted)
- {
- for (int i = listeners.size(); --i >= 0;)
- {
- listeners.getUnchecked(i)->tableSortOrderChanged (this);
- i = jmin (i, listeners.size() - 1);
- }
- }
-
- if (changed)
- {
- for (int i = listeners.size(); --i >= 0;)
- {
- listeners.getUnchecked(i)->tableColumnsChanged (this);
- i = jmin (i, listeners.size() - 1);
- }
- }
-
- if (sized)
- {
- for (int i = listeners.size(); --i >= 0;)
- {
- listeners.getUnchecked(i)->tableColumnsResized (this);
- i = jmin (i, listeners.size() - 1);
- }
- }
- }
-
- int TableHeaderComponent::getResizeDraggerAt (const int mouseX) const throw()
- {
- if (((unsigned int) mouseX) < (unsigned int) getWidth())
- {
- const int draggableDistance = 3;
- int x = 0;
-
- for (int i = 0; i < columns.size(); ++i)
- {
- const ColumnInfo* const ci = columns.getUnchecked(i);
-
- if (ci->isVisible())
- {
- if (abs (mouseX - (x + ci->width)) <= draggableDistance
- && (ci->propertyFlags & resizable) != 0)
- return ci->id;
-
- x += ci->width;
- }
- }
- }
-
- return 0;
- }
-
- void TableHeaderComponent::updateColumnUnderMouse (int x, int y)
- {
- const int newCol = (reallyContains (x, y, true) && getResizeDraggerAt (x) == 0)
- ? getColumnIdAtX (x) : 0;
-
- if (newCol != columnIdUnderMouse)
- {
- columnIdUnderMouse = newCol;
- repaint();
- }
- }
-
- void TableHeaderComponent::showColumnChooserMenu (const int columnIdClicked)
- {
- PopupMenu m;
- addMenuItems (m, columnIdClicked);
-
- if (m.getNumItems() > 0)
- {
- const int result = m.show();
-
- if (result != 0)
- reactToMenuItem (result, columnIdClicked);
- }
- }
-
- void TableHeaderListener::tableColumnDraggingChanged (TableHeaderComponent*, int)
- {
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_TableHeaderComponent.cpp *********/
-
- /********* Start of inlined file: juce_TableListBox.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- static const tchar* const tableColumnPropertyTag = T("_tableColumnID");
-
- class TableListRowComp : public Component
- {
- public:
- TableListRowComp (TableListBox& owner_)
- : owner (owner_),
- row (-1),
- isSelected (false)
- {
- }
-
- ~TableListRowComp()
- {
- deleteAllChildren();
- }
-
- void paint (Graphics& g)
- {
- TableListBoxModel* const model = owner.getModel();
-
- if (model != 0)
- {
- const TableHeaderComponent* const header = owner.getHeader();
-
- model->paintRowBackground (g, row, getWidth(), getHeight(), isSelected);
-
- const int numColumns = header->getNumColumns (true);
-
- for (int i = 0; i < numColumns; ++i)
- {
- if (! columnsWithComponents [i])
- {
- const int columnId = header->getColumnIdOfIndex (i, true);
- Rectangle columnRect (header->getColumnPosition (i));
- columnRect.setSize (columnRect.getWidth(), getHeight());
-
- g.saveState();
-
- g.reduceClipRegion (columnRect);
- g.setOrigin (columnRect.getX(), 0);
-
- model->paintCell (g, row, columnId, columnRect.getWidth(), columnRect.getHeight(), isSelected);
-
- g.restoreState();
- }
- }
- }
- }
-
- void update (const int newRow, const bool isNowSelected)
- {
- if (newRow != row || isNowSelected != isSelected)
- {
- row = newRow;
- isSelected = isNowSelected;
- repaint();
- }
-
- if (row < owner.getNumRows())
- {
- jassert (row >= 0);
-
- const tchar* const tagPropertyName = T("_tableLastUseNum");
- const int newTag = Random::getSystemRandom().nextInt();
-
- const TableHeaderComponent* const header = owner.getHeader();
- const int numColumns = header->getNumColumns (true);
- int i;
-
- columnsWithComponents.clear();
-
- if (owner.getModel() != 0)
- {
- for (i = 0; i < numColumns; ++i)
- {
- const int columnId = header->getColumnIdOfIndex (i, true);
-
- Component* const newComp
- = owner.getModel()->refreshComponentForCell (row, columnId, isSelected,
- findChildComponentForColumn (columnId));
-
- if (newComp != 0)
- {
- addAndMakeVisible (newComp);
- newComp->setComponentProperty (tagPropertyName, newTag);
- newComp->setComponentProperty (tableColumnPropertyTag, columnId);
-
- const Rectangle columnRect (header->getColumnPosition (i));
- newComp->setBounds (columnRect.getX(), 0, columnRect.getWidth(), getHeight());
-
- columnsWithComponents.setBit (i);
- }
- }
- }
-
- for (i = getNumChildComponents(); --i >= 0;)
- {
- Component* const c = getChildComponent (i);
-
- if (c->getComponentPropertyInt (tagPropertyName, false, 0) != newTag)
- delete c;
- }
- }
- else
- {
- columnsWithComponents.clear();
- deleteAllChildren();
- }
- }
-
- void resized()
- {
- for (int i = getNumChildComponents(); --i >= 0;)
- {
- Component* const c = getChildComponent (i);
-
- const int columnId = c->getComponentPropertyInt (tableColumnPropertyTag, false, 0);
-
- if (columnId != 0)
- {
- const Rectangle columnRect (owner.getHeader()->getColumnPosition (owner.getHeader()->getIndexOfColumnId (columnId, true)));
- c->setBounds (columnRect.getX(), 0, columnRect.getWidth(), getHeight());
- }
- }
- }
-
- void mouseDown (const MouseEvent& e)
- {
- isDragging = false;
- selectRowOnMouseUp = false;
-
- if (isEnabled())
- {
- if (! isSelected)
- {
- owner.selectRowsBasedOnModifierKeys (row, e.mods);
-
- const int columnId = owner.getHeader()->getColumnIdAtX (e.x);
-
- if (columnId != 0 && owner.getModel() != 0)
- owner.getModel()->cellClicked (row, columnId, e);
- }
- else
- {
- selectRowOnMouseUp = true;
- }
- }
- }
-
- void mouseDrag (const MouseEvent& e)
- {
- if (isEnabled() && owner.getModel() != 0 && ! (e.mouseWasClicked() || isDragging))
- {
- const SparseSet <int> selectedRows (owner.getSelectedRows());
-
- if (selectedRows.size() > 0)
- {
- const String dragDescription (owner.getModel()->getDragSourceDescription (selectedRows));
-
- if (dragDescription.isNotEmpty())
- {
- isDragging = true;
-
- DragAndDropContainer* const dragContainer
- = DragAndDropContainer::findParentDragContainerFor (this);
-
- if (dragContainer != 0)
- {
- Image* dragImage = owner.createSnapshotOfSelectedRows();
- dragImage->multiplyAllAlphas (0.6f);
-
- dragContainer->startDragging (dragDescription, &owner, dragImage, true);
- }
- else
- {
- // to be able to do a drag-and-drop operation, the listbox needs to
- // be inside a component which is also a DragAndDropContainer.
- jassertfalse
- }
- }
- }
- }
- }
-
- void mouseUp (const MouseEvent& e)
- {
- if (selectRowOnMouseUp && e.mouseWasClicked() && isEnabled())
- {
- owner.selectRowsBasedOnModifierKeys (row, e.mods);
-
- const int columnId = owner.getHeader()->getColumnIdAtX (e.x);
-
- if (columnId != 0 && owner.getModel() != 0)
- owner.getModel()->cellClicked (row, columnId, e);
- }
- }
-
- void mouseDoubleClick (const MouseEvent& e)
- {
- const int columnId = owner.getHeader()->getColumnIdAtX (e.x);
-
- if (columnId != 0 && owner.getModel() != 0)
- owner.getModel()->cellDoubleClicked (row, columnId, e);
- }
-
- juce_UseDebuggingNewOperator
-
- private:
- TableListBox& owner;
- int row;
- bool isSelected, isDragging, selectRowOnMouseUp;
- BitArray columnsWithComponents;
-
- Component* findChildComponentForColumn (const int columnId) const
- {
- for (int i = getNumChildComponents(); --i >= 0;)
- {
- Component* const c = getChildComponent (i);
-
- if (c->getComponentPropertyInt (tableColumnPropertyTag, false, 0) == columnId)
- return c;
- }
-
- return 0;
- }
-
- TableListRowComp (const TableListRowComp&);
- const TableListRowComp& operator= (const TableListRowComp&);
- };
-
- class TableListBoxHeader : public TableHeaderComponent
- {
- public:
- TableListBoxHeader (TableListBox& owner_)
- : owner (owner_)
- {
- }
-
- ~TableListBoxHeader()
- {
- }
-
- void addMenuItems (PopupMenu& menu, const int columnIdClicked)
- {
- if (owner.isAutoSizeMenuOptionShown())
- {
- menu.addItem (0xf836743, TRANS("Auto-size this column"), columnIdClicked != 0);
- menu.addItem (0xf836744, TRANS("Auto-size all columns"), owner.getHeader()->getNumColumns (true) > 0);
- menu.addSeparator();
- }
-
- TableHeaderComponent::addMenuItems (menu, columnIdClicked);
- }
-
- void reactToMenuItem (const int menuReturnId, const int columnIdClicked)
- {
- if (menuReturnId == 0xf836743)
- {
- owner.autoSizeColumn (columnIdClicked);
- }
- else if (menuReturnId == 0xf836744)
- {
- owner.autoSizeAllColumns();
- }
- else
- {
- TableHeaderComponent::reactToMenuItem (menuReturnId, columnIdClicked);
- }
- }
-
- juce_UseDebuggingNewOperator
-
- private:
- TableListBox& owner;
-
- TableListBoxHeader (const TableListBoxHeader&);
- const TableListBoxHeader& operator= (const TableListBoxHeader&);
- };
-
- TableListBox::TableListBox (const String& name, TableListBoxModel* const model_)
- : ListBox (name, 0),
- model (model_),
- autoSizeOptionsShown (true)
- {
- ListBox::model = this;
-
- header = new TableListBoxHeader (*this);
- header->setSize (100, 28);
- header->addListener (this);
-
- setHeaderComponent (header);
- }
-
- TableListBox::~TableListBox()
- {
- deleteAllChildren();
- }
-
- void TableListBox::setModel (TableListBoxModel* const newModel)
- {
- if (model != newModel)
- {
- model = newModel;
- updateContent();
- }
- }
-
- int TableListBox::getHeaderHeight() const throw()
- {
- return header->getHeight();
- }
-
- void TableListBox::setHeaderHeight (const int newHeight)
- {
- header->setSize (header->getWidth(), newHeight);
- resized();
- }
-
- void TableListBox::autoSizeColumn (const int columnId)
- {
- const int width = model != 0 ? model->getColumnAutoSizeWidth (columnId) : 0;
-
- if (width > 0)
- header->setColumnWidth (columnId, width);
- }
-
- void TableListBox::autoSizeAllColumns()
- {
- for (int i = 0; i < header->getNumColumns (true); ++i)
- autoSizeColumn (header->getColumnIdOfIndex (i, true));
- }
-
- void TableListBox::setAutoSizeMenuOptionShown (const bool shouldBeShown)
- {
- autoSizeOptionsShown = shouldBeShown;
- }
-
- bool TableListBox::isAutoSizeMenuOptionShown() const throw()
- {
- return autoSizeOptionsShown;
- }
-
- const Rectangle TableListBox::getCellPosition (const int columnId,
- const int rowNumber,
- const bool relativeToComponentTopLeft) const
- {
- Rectangle headerCell (header->getColumnPosition (header->getIndexOfColumnId (columnId, true)));
-
- if (relativeToComponentTopLeft)
- headerCell.translate (header->getX(), 0);
-
- const Rectangle row (getRowPosition (rowNumber, relativeToComponentTopLeft));
-
- return Rectangle (headerCell.getX(), row.getY(),
- headerCell.getWidth(), row.getHeight());
- }
-
- void TableListBox::scrollToEnsureColumnIsOnscreen (const int columnId)
- {
- ScrollBar* const scrollbar = getHorizontalScrollBar();
-
- if (scrollbar != 0)
- {
- const Rectangle pos (header->getColumnPosition (header->getIndexOfColumnId (columnId, true)));
-
- double x = scrollbar->getCurrentRangeStart();
- const double w = scrollbar->getCurrentRangeSize();
-
- if (pos.getX() < x)
- x = pos.getX();
- else if (pos.getRight() > x + w)
- x += jmax (0.0, pos.getRight() - (x + w));
-
- scrollbar->setCurrentRangeStart (x);
- }
- }
-
- int TableListBox::getNumRows()
- {
- return model != 0 ? model->getNumRows() : 0;
- }
-
- void TableListBox::paintListBoxItem (int, Graphics&, int, int, bool)
- {
- }
-
- Component* TableListBox::refreshComponentForRow (int rowNumber, bool isRowSelected, Component* existingComponentToUpdate)
- {
- if (existingComponentToUpdate == 0)
- existingComponentToUpdate = new TableListRowComp (*this);
-
- ((TableListRowComp*) existingComponentToUpdate)->update (rowNumber, isRowSelected);
-
- return existingComponentToUpdate;
- }
-
- void TableListBox::selectedRowsChanged (int row)
- {
- if (model != 0)
- model->selectedRowsChanged (row);
- }
-
- void TableListBox::deleteKeyPressed (int row)
- {
- if (model != 0)
- model->deleteKeyPressed (row);
- }
-
- void TableListBox::returnKeyPressed (int row)
- {
- if (model != 0)
- model->returnKeyPressed (row);
- }
-
- void TableListBox::backgroundClicked()
- {
- if (model != 0)
- model->backgroundClicked();
- }
-
- void TableListBox::listWasScrolled()
- {
- if (model != 0)
- model->listWasScrolled();
- }
-
- void TableListBox::tableColumnsChanged (TableHeaderComponent*)
- {
- setMinimumContentWidth (header->getTotalWidth());
- repaint();
- updateColumnComponents();
- }
-
- void TableListBox::tableColumnsResized (TableHeaderComponent*)
- {
- setMinimumContentWidth (header->getTotalWidth());
- repaint();
- updateColumnComponents();
- }
-
- void TableListBox::tableSortOrderChanged (TableHeaderComponent*)
- {
- if (model != 0)
- model->sortOrderChanged (header->getSortColumnId(),
- header->isSortedForwards());
- }
-
- void TableListBox::tableColumnDraggingChanged (TableHeaderComponent*, int columnIdNowBeingDragged_)
- {
- columnIdNowBeingDragged = columnIdNowBeingDragged_;
- repaint();
- }
-
- void TableListBox::resized()
- {
- ListBox::resized();
-
- header->resizeAllColumnsToFit (getVisibleContentWidth());
- setMinimumContentWidth (header->getTotalWidth());
- }
-
- void TableListBox::updateColumnComponents() const
- {
- const int firstRow = getRowContainingPosition (0, 0);
-
- for (int i = firstRow + getNumRowsOnScreen() + 2; --i >= firstRow;)
- {
- TableListRowComp* const rowComp = dynamic_cast <TableListRowComp*> (getComponentForRowNumber (i));
-
- if (rowComp != 0)
- rowComp->resized();
- }
- }
-
- void TableListBoxModel::cellClicked (int, int, const MouseEvent&)
- {
- }
-
- void TableListBoxModel::cellDoubleClicked (int, int, const MouseEvent&)
- {
- }
-
- void TableListBoxModel::backgroundClicked()
- {
- }
-
- void TableListBoxModel::sortOrderChanged (int, const bool)
- {
- }
-
- int TableListBoxModel::getColumnAutoSizeWidth (int)
- {
- return 0;
- }
-
- void TableListBoxModel::selectedRowsChanged (int)
- {
- }
-
- void TableListBoxModel::deleteKeyPressed (int)
- {
- }
-
- void TableListBoxModel::returnKeyPressed (int)
- {
- }
-
- void TableListBoxModel::listWasScrolled()
- {
- }
-
- const String TableListBoxModel::getDragSourceDescription (const SparseSet<int>&)
- {
- return String::empty;
- }
-
- Component* TableListBoxModel::refreshComponentForCell (int, int, bool, Component* existingComponentToUpdate)
- {
- (void) existingComponentToUpdate;
- jassert (existingComponentToUpdate == 0); // indicates a failure in the code the recycles the components
- return 0;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_TableListBox.cpp *********/
-
- /********* Start of inlined file: juce_TextEditor.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- #define SHOULD_WRAP(x, wrapwidth) (((x) - 0.0001f) >= (wrapwidth))
-
- // a word or space that can't be broken down any further
- struct TextAtom
- {
-
- String atomText;
- float width;
- uint16 numChars;
-
- bool isWhitespace() const throw() { return CharacterFunctions::isWhitespace (atomText[0]); }
- bool isNewLine() const throw() { return atomText[0] == T('\r') || atomText[0] == T('\n'); }
-
- const String getText (const tchar passwordCharacter) const throw()
- {
- if (passwordCharacter == 0)
- return atomText;
- else
- return String::repeatedString (String::charToString (passwordCharacter),
- atomText.length());
- }
-
- const String getTrimmedText (const tchar passwordCharacter) const throw()
- {
- if (passwordCharacter == 0)
- return atomText.substring (0, numChars);
- else if (isNewLine())
- return String::empty;
- else
- return String::repeatedString (String::charToString (passwordCharacter), numChars);
- }
- };
-
- // a run of text with a single font and colour
- class UniformTextSection
- {
- public:
-
- UniformTextSection (const String& text,
- const Font& font_,
- const Colour& colour_,
- const tchar passwordCharacter) throw()
- : font (font_),
- colour (colour_),
- atoms (64)
- {
- initialiseAtoms (text, passwordCharacter);
- }
-
- UniformTextSection (const UniformTextSection& other) throw()
- : font (other.font),
- colour (other.colour),
- atoms (64)
- {
- for (int i = 0; i < other.atoms.size(); ++i)
- atoms.add (new TextAtom (*(const TextAtom*) other.atoms.getUnchecked(i)));
- }
-
- ~UniformTextSection() throw()
- {
- // (no need to delete the atoms, as they're explicitly deleted by the caller)
- }
-
- void clear() throw()
- {
- for (int i = atoms.size(); --i >= 0;)
- {
- TextAtom* const atom = getAtom(i);
- delete atom;
- }
-
- atoms.clear();
- }
-
- int getNumAtoms() const throw()
- {
- return atoms.size();
- }
-
- TextAtom* getAtom (const int index) const throw()
- {
- return (TextAtom*) atoms.getUnchecked (index);
- }
-
- void append (const UniformTextSection& other, const tchar passwordCharacter) throw()
- {
- if (other.atoms.size() > 0)
- {
- TextAtom* const lastAtom = (TextAtom*) atoms.getLast();
- int i = 0;
-
- if (lastAtom != 0)
- {
- if (! CharacterFunctions::isWhitespace (lastAtom->atomText.getLastCharacter()))
- {
- TextAtom* const first = other.getAtom(0);
-
- if (! CharacterFunctions::isWhitespace (first->atomText[0]))
- {
- lastAtom->atomText += first->atomText;
- lastAtom->numChars = (uint16) (lastAtom->numChars + first->numChars);
- lastAtom->width = font.getStringWidthFloat (lastAtom->getText (passwordCharacter));
- delete first;
- ++i;
- }
- }
- }
-
- while (i < other.atoms.size())
- {
- atoms.add (other.getAtom(i));
- ++i;
- }
- }
- }
-
- UniformTextSection* split (const int indexToBreakAt,
- const tchar passwordCharacter) throw()
- {
- UniformTextSection* const section2 = new UniformTextSection (String::empty,
- font, colour,
- passwordCharacter);
- int index = 0;
-
- for (int i = 0; i < atoms.size(); ++i)
- {
- TextAtom* const atom = getAtom(i);
-
- const int nextIndex = index + atom->numChars;
-
- if (index == indexToBreakAt)
- {
- int j;
- for (j = i; j < atoms.size(); ++j)
- section2->atoms.add (getAtom (j));
-
- for (j = atoms.size(); --j >= i;)
- atoms.remove (j);
-
- break;
- }
- else if (indexToBreakAt >= index && indexToBreakAt < nextIndex)
- {
- TextAtom* const secondAtom = new TextAtom();
-
- secondAtom->atomText = atom->atomText.substring (indexToBreakAt - index);
- secondAtom->width = font.getStringWidthFloat (secondAtom->getText (passwordCharacter));
- secondAtom->numChars = (uint16) secondAtom->atomText.length();
-
- section2->atoms.add (secondAtom);
-
- atom->atomText = atom->atomText.substring (0, indexToBreakAt - index);
- atom->width = font.getStringWidthFloat (atom->getText (passwordCharacter));
- atom->numChars = (uint16) (indexToBreakAt - index);
-
- int j;
- for (j = i + 1; j < atoms.size(); ++j)
- section2->atoms.add (getAtom (j));
-
- for (j = atoms.size(); --j > i;)
- atoms.remove (j);
-
- break;
- }
-
- index = nextIndex;
- }
-
- return section2;
- }
-
- const String getAllText() const throw()
- {
- String s;
- s.preallocateStorage (getTotalLength());
-
- tchar* endOfString = (tchar*) &(s[0]);
-
- for (int i = 0; i < atoms.size(); ++i)
- {
- const TextAtom* const atom = getAtom(i);
-
- memcpy (endOfString, &(atom->atomText[0]), atom->numChars * sizeof (tchar));
- endOfString += atom->numChars;
- }
-
- *endOfString = 0;
-
- jassert ((endOfString - (tchar*) &(s[0])) <= getTotalLength());
- return s;
- }
-
- const String getTextSubstring (const int startCharacter,
- const int endCharacter) const throw()
- {
- int index = 0;
- int totalLen = 0;
- int i;
-
- for (i = 0; i < atoms.size(); ++i)
- {
- const TextAtom* const atom = getAtom (i);
- const int nextIndex = index + atom->numChars;
-
- if (startCharacter < nextIndex)
- {
- if (endCharacter <= index)
- break;
-
- const int start = jmax (0, startCharacter - index);
- const int end = jmin (endCharacter - index, atom->numChars);
- jassert (end >= start);
-
- totalLen += end - start;
- }
-
- index = nextIndex;
- }
-
- String s;
- s.preallocateStorage (totalLen + 1);
- tchar* psz = (tchar*) (const tchar*) s;
-
- index = 0;
-
- for (i = 0; i < atoms.size(); ++i)
- {
- const TextAtom* const atom = getAtom (i);
- const int nextIndex = index + atom->numChars;
-
- if (startCharacter < nextIndex)
- {
- if (endCharacter <= index)
- break;
-
- const int start = jmax (0, startCharacter - index);
- const int len = jmin (endCharacter - index, atom->numChars) - start;
-
- memcpy (psz, ((const tchar*) atom->atomText) + start, len * sizeof (tchar));
- psz += len;
- *psz = 0;
- }
-
- index = nextIndex;
- }
-
- return s;
- }
-
- int getTotalLength() const throw()
- {
- int c = 0;
-
- for (int i = atoms.size(); --i >= 0;)
- c += getAtom(i)->numChars;
-
- return c;
- }
-
- void setFont (const Font& newFont,
- const tchar passwordCharacter) throw()
- {
- if (font != newFont)
- {
- font = newFont;
-
- for (int i = atoms.size(); --i >= 0;)
- {
- TextAtom* const atom = (TextAtom*) atoms.getUnchecked(i);
- atom->width = newFont.getStringWidthFloat (atom->getText (passwordCharacter));
- }
- }
- }
-
- juce_UseDebuggingNewOperator
-
- Font font;
- Colour colour;
-
- private:
- VoidArray atoms;
-
- void initialiseAtoms (const String& textToParse,
- const tchar passwordCharacter) throw()
- {
- int i = 0;
- const int len = textToParse.length();
- const tchar* const text = (const tchar*) textToParse;
-
- while (i < len)
- {
- int start = i;
-
- // create a whitespace atom unless it starts with non-ws
- if (CharacterFunctions::isWhitespace (text[i])
- && text[i] != T('\r')
- && text[i] != T('\n'))
- {
- while (i < len
- && CharacterFunctions::isWhitespace (text[i])
- && text[i] != T('\r')
- && text[i] != T('\n'))
- {
- ++i;
- }
- }
- else
- {
- if (text[i] == T('\r'))
- {
- ++i;
-
- if ((i < len) && (text[i] == T('\n')))
- {
- ++start;
- ++i;
- }
- }
- else if (text[i] == T('\n'))
- {
- ++i;
- }
- else
- {
- while ((i < len) && ! CharacterFunctions::isWhitespace (text[i]))
- ++i;
- }
- }
-
- TextAtom* const atom = new TextAtom();
- atom->atomText = String (text + start, i - start);
-
- atom->width = font.getStringWidthFloat (atom->getText (passwordCharacter));
- atom->numChars = (uint16) (i - start);
-
- atoms.add (atom);
- }
- }
-
- const UniformTextSection& operator= (const UniformTextSection& other);
- };
-
- class TextEditorIterator
- {
- public:
-
- TextEditorIterator (const VoidArray& sections_,
- const float wordWrapWidth_,
- const tchar passwordCharacter_) throw()
- : indexInText (0),
- lineY (0),
- lineHeight (0),
- maxDescent (0),
- atomX (0),
- atomRight (0),
- atom (0),
- currentSection (0),
- sections (sections_),
- sectionIndex (0),
- atomIndex (0),
- wordWrapWidth (wordWrapWidth_),
- passwordCharacter (passwordCharacter_)
- {
- jassert (wordWrapWidth_ > 0);
-
- if (sections.size() > 0)
- currentSection = (const UniformTextSection*) sections.getUnchecked (sectionIndex);
-
- if (currentSection != 0)
- {
- lineHeight = currentSection->font.getHeight();
- maxDescent = currentSection->font.getDescent();
- }
- }
-
- TextEditorIterator (const TextEditorIterator& other) throw()
- : indexInText (other.indexInText),
- lineY (other.lineY),
- lineHeight (other.lineHeight),
- maxDescent (other.maxDescent),
- atomX (other.atomX),
- atomRight (other.atomRight),
- atom (other.atom),
- currentSection (other.currentSection),
- sections (other.sections),
- sectionIndex (other.sectionIndex),
- atomIndex (other.atomIndex),
- wordWrapWidth (other.wordWrapWidth),
- passwordCharacter (other.passwordCharacter),
- tempAtom (other.tempAtom)
- {
- }
-
- ~TextEditorIterator() throw()
- {
- }
-
- bool next() throw()
- {
- if (atom == &tempAtom)
- {
- const int numRemaining = tempAtom.atomText.length() - tempAtom.numChars;
-
- if (numRemaining > 0)
- {
- tempAtom.atomText = tempAtom.atomText.substring (tempAtom.numChars);
-
- atomX = 0;
-
- if (tempAtom.numChars > 0)
- lineY += lineHeight;
-
- indexInText += tempAtom.numChars;
-
- GlyphArrangement g;
- g.addLineOfText (currentSection->font, atom->getText (passwordCharacter), 0.0f, 0.0f);
-
- int split;
- for (split = 0; split < g.getNumGlyphs(); ++split)
- if (SHOULD_WRAP (g.getGlyph (split).getRight(), wordWrapWidth))
- break;
-
- if (split > 0 && split <= numRemaining)
- {
- tempAtom.numChars = (uint16) split;
- tempAtom.width = g.getGlyph (split - 1).getRight();
- atomRight = atomX + tempAtom.width;
- return true;
- }
- }
- }
-
- bool forceNewLine = false;
-
- if (sectionIndex >= sections.size())
- {
- moveToEndOfLastAtom();
- return false;
- }
- else if (atomIndex >= currentSection->getNumAtoms() - 1)
- {
- if (atomIndex >= currentSection->getNumAtoms())
- {
- if (++sectionIndex >= sections.size())
- {
- moveToEndOfLastAtom();
- return false;
- }
-
- atomIndex = 0;
- currentSection = (const UniformTextSection*) sections.getUnchecked (sectionIndex);
-
- lineHeight = jmax (lineHeight, currentSection->font.getHeight());
- maxDescent = jmax (maxDescent, currentSection->font.getDescent());
- }
- else
- {
- const TextAtom* const lastAtom = currentSection->getAtom (atomIndex);
-
- if (! lastAtom->isWhitespace())
- {
- // handle the case where the last atom in a section is actually part of the same
- // word as the first atom of the next section...
- float right = atomRight + lastAtom->width;
- float lineHeight2 = lineHeight;
- float maxDescent2 = maxDescent;
-
- for (int section = sectionIndex + 1; section < sections.size(); ++section)
- {
- const UniformTextSection* const s = (const UniformTextSection*) sections.getUnchecked (section);
-
- if (s->getNumAtoms() == 0)
- break;
-
- const TextAtom* const nextAtom = s->getAtom (0);
-
- if (nextAtom->isWhitespace())
- break;
-
- right += nextAtom->width;
-
- lineHeight2 = jmax (lineHeight2, s->font.getHeight());
- maxDescent2 = jmax (maxDescent2, s->font.getDescent());
-
- if (SHOULD_WRAP (right, wordWrapWidth))
- {
- lineHeight = lineHeight2;
- maxDescent = maxDescent2;
-
- forceNewLine = true;
- break;
- }
-
- if (s->getNumAtoms() > 1)
- break;
- }
- }
- }
- }
-
- if (atom != 0)
- {
- atomX = atomRight;
- indexInText += atom->numChars;
-
- if (atom->isNewLine())
- {
- atomX = 0;
- lineY += lineHeight;
- }
- }
-
- atom = currentSection->getAtom (atomIndex);
- atomRight = atomX + atom->width;
- ++atomIndex;
-
- if (SHOULD_WRAP (atomRight, wordWrapWidth) || forceNewLine)
- {
- if (atom->isWhitespace())
- {
- // leave whitespace at the end of a line, but truncate it to avoid scrolling
- atomRight = jmin (atomRight, wordWrapWidth);
- }
- else
- {
- return wrapCurrentAtom();
- }
- }
-
- return true;
- }
-
- bool wrapCurrentAtom() throw()
- {
- atomRight = atom->width;
-
- if (SHOULD_WRAP (atomRight, wordWrapWidth)) // atom too big to fit on a line, so break it up..
- {
- tempAtom = *atom;
- tempAtom.width = 0;
- tempAtom.numChars = 0;
- atom = &tempAtom;
-
- if (atomX > 0)
- {
- atomX = 0;
- lineY += lineHeight;
- }
-
- return next();
- }
-
- atomX = 0;
- lineY += lineHeight;
- return true;
- }
-
- void draw (Graphics& g, const UniformTextSection*& lastSection) const throw()
- {
- if (passwordCharacter != 0 || ! atom->isWhitespace())
- {
- if (lastSection != currentSection)
- {
- lastSection = currentSection;
- g.setColour (currentSection->colour);
- g.setFont (currentSection->font);
- }
-
- jassert (atom->getTrimmedText (passwordCharacter).isNotEmpty());
-
- GlyphArrangement ga;
- ga.addLineOfText (currentSection->font,
- atom->getTrimmedText (passwordCharacter),
- atomX,
- (float) roundFloatToInt (lineY + lineHeight - maxDescent));
- ga.draw (g);
- }
- }
-
- void drawSelection (Graphics& g,
- const int selectionStart,
- const int selectionEnd) const throw()
- {
- const int startX = roundFloatToInt (indexToX (selectionStart));
- const int endX = roundFloatToInt (indexToX (selectionEnd));
-
- const int y = roundFloatToInt (lineY);
- const int nextY = roundFloatToInt (lineY + lineHeight);
-
- g.fillRect (startX, y, endX - startX, nextY - y);
- }
-
- void drawSelectedText (Graphics& g,
- const int selectionStart,
- const int selectionEnd,
- const Colour& selectedTextColour) const throw()
- {
- if (passwordCharacter != 0 || ! atom->isWhitespace())
- {
- GlyphArrangement ga;
- ga.addLineOfText (currentSection->font,
- atom->getTrimmedText (passwordCharacter),
- atomX,
- (float) roundFloatToInt (lineY + lineHeight - maxDescent));
-
- if (selectionEnd < indexInText + atom->numChars)
- {
- GlyphArrangement ga2 (ga);
- ga2.removeRangeOfGlyphs (0, selectionEnd - indexInText);
- ga.removeRangeOfGlyphs (selectionEnd - indexInText, -1);
-
- g.setColour (currentSection->colour);
- ga2.draw (g);
- }
-
- if (selectionStart > indexInText)
- {
- GlyphArrangement ga2 (ga);
- ga2.removeRangeOfGlyphs (selectionStart - indexInText, -1);
- ga.removeRangeOfGlyphs (0, selectionStart - indexInText);
-
- g.setColour (currentSection->colour);
- ga2.draw (g);
- }
-
- g.setColour (selectedTextColour);
- ga.draw (g);
- }
- }
-
- float indexToX (const int indexToFind) const throw()
- {
- if (indexToFind <= indexInText)
- return atomX;
-
- if (indexToFind >= indexInText + atom->numChars)
- return atomRight;
-
- GlyphArrangement g;
- g.addLineOfText (currentSection->font,
- atom->getText (passwordCharacter),
- atomX, 0.0f);
-
- return jmin (atomRight, g.getGlyph (indexToFind - indexInText).getLeft());
- }
-
- int xToIndex (const float xToFind) const throw()
- {
- if (xToFind <= atomX || atom->isNewLine())
- return indexInText;
-
- if (xToFind >= atomRight)
- return indexInText + atom->numChars;
-
- GlyphArrangement g;
- g.addLineOfText (currentSection->font,
- atom->getText (passwordCharacter),
- atomX, 0.0f);
-
- int j;
- for (j = 0; j < atom->numChars; ++j)
- if ((g.getGlyph(j).getLeft() + g.getGlyph(j).getRight()) / 2 > xToFind)
- break;
-
- return indexInText + j;
- }
-
- void updateLineHeight() throw()
- {
- float x = atomRight;
-
- int tempSectionIndex = sectionIndex;
- int tempAtomIndex = atomIndex;
- const UniformTextSection* currentSection = (const UniformTextSection*) sections.getUnchecked (tempSectionIndex);
-
- while (! SHOULD_WRAP (x, wordWrapWidth))
- {
- if (tempSectionIndex >= sections.size())
- break;
-
- bool checkSize = false;
-
- if (tempAtomIndex >= currentSection->getNumAtoms())
- {
- if (++tempSectionIndex >= sections.size())
- break;
-
- tempAtomIndex = 0;
- currentSection = (const UniformTextSection*) sections.getUnchecked (tempSectionIndex);
- checkSize = true;
- }
-
- const TextAtom* const atom = currentSection->getAtom (tempAtomIndex);
-
- if (atom == 0)
- break;
-
- x += atom->width;
-
- if (SHOULD_WRAP (x, wordWrapWidth) || atom->isNewLine())
- break;
-
- if (checkSize)
- {
- lineHeight = jmax (lineHeight, currentSection->font.getHeight());
- maxDescent = jmax (maxDescent, currentSection->font.getDescent());
- }
-
- ++tempAtomIndex;
- }
- }
-
- bool getCharPosition (const int index, float& cx, float& cy, float& lineHeight_) throw()
- {
- while (next())
- {
- if (indexInText + atom->numChars >= index)
- {
- updateLineHeight();
-
- if (indexInText + atom->numChars > index)
- {
- cx = indexToX (index);
- cy = lineY;
- lineHeight_ = lineHeight;
- return true;
- }
- }
- }
-
- cx = atomX;
- cy = lineY;
- lineHeight_ = lineHeight;
- return false;
- }
-
- juce_UseDebuggingNewOperator
-
- int indexInText;
- float lineY, lineHeight, maxDescent;
- float atomX, atomRight;
- const TextAtom* atom;
- const UniformTextSection* currentSection;
-
- private:
- const VoidArray& sections;
- int sectionIndex, atomIndex;
- const float wordWrapWidth;
- const tchar passwordCharacter;
- TextAtom tempAtom;
-
- const TextEditorIterator& operator= (const TextEditorIterator&);
-
- void moveToEndOfLastAtom() throw()
- {
- if (atom != 0)
- {
- atomX = atomRight;
-
- if (atom->isNewLine())
- {
- atomX = 0.0f;
- lineY += lineHeight;
- }
- }
- }
- };
-
- class TextEditorInsertAction : public UndoableAction
- {
- TextEditor& owner;
- const String text;
- const int insertIndex, oldCaretPos, newCaretPos;
- const Font font;
- const Colour colour;
-
- TextEditorInsertAction (const TextEditorInsertAction&);
- const TextEditorInsertAction& operator= (const TextEditorInsertAction&);
-
- public:
- TextEditorInsertAction (TextEditor& owner_,
- const String& text_,
- const int insertIndex_,
- const Font& font_,
- const Colour& colour_,
- const int oldCaretPos_,
- const int newCaretPos_) throw()
- : owner (owner_),
- text (text_),
- insertIndex (insertIndex_),
- oldCaretPos (oldCaretPos_),
- newCaretPos (newCaretPos_),
- font (font_),
- colour (colour_)
- {
- }
-
- ~TextEditorInsertAction()
- {
- }
-
- bool perform()
- {
- owner.insert (text, insertIndex, font, colour, 0, newCaretPos);
- return true;
- }
-
- bool undo()
- {
- owner.remove (insertIndex, insertIndex + text.length(), 0, oldCaretPos);
- return true;
- }
-
- int getSizeInUnits()
- {
- return text.length() + 16;
- }
- };
-
- class TextEditorRemoveAction : public UndoableAction
- {
- TextEditor& owner;
- const int startIndex, endIndex, oldCaretPos, newCaretPos;
- VoidArray removedSections;
-
- TextEditorRemoveAction (const TextEditorRemoveAction&);
- const TextEditorRemoveAction& operator= (const TextEditorRemoveAction&);
-
- public:
- TextEditorRemoveAction (TextEditor& owner_,
- const int startIndex_,
- const int endIndex_,
- const int oldCaretPos_,
- const int newCaretPos_,
- const VoidArray& removedSections_) throw()
- : owner (owner_),
- startIndex (startIndex_),
- endIndex (endIndex_),
- oldCaretPos (oldCaretPos_),
- newCaretPos (newCaretPos_),
- removedSections (removedSections_)
- {
- }
-
- ~TextEditorRemoveAction()
- {
- for (int i = removedSections.size(); --i >= 0;)
- {
- UniformTextSection* const section = (UniformTextSection*) removedSections.getUnchecked (i);
- section->clear();
- delete section;
- }
- }
-
- bool perform()
- {
- owner.remove (startIndex, endIndex, 0, newCaretPos);
- return true;
- }
-
- bool undo()
- {
- owner.reinsert (startIndex, removedSections);
- owner.moveCursorTo (oldCaretPos, false);
- return true;
- }
-
- int getSizeInUnits()
- {
- int n = 0;
-
- for (int i = removedSections.size(); --i >= 0;)
- {
- UniformTextSection* const section = (UniformTextSection*) removedSections.getUnchecked (i);
- n += section->getTotalLength();
- }
-
- return n + 16;
- }
- };
-
- class TextHolderComponent : public Component,
- public Timer
- {
- TextEditor* const owner;
-
- TextHolderComponent (const TextHolderComponent&);
- const TextHolderComponent& operator= (const TextHolderComponent&);
-
- public:
- TextHolderComponent (TextEditor* const owner_)
- : owner (owner_)
- {
- setWantsKeyboardFocus (false);
- setInterceptsMouseClicks (false, true);
- }
-
- ~TextHolderComponent()
- {
- }
-
- void paint (Graphics& g)
- {
- owner->drawContent (g);
- }
-
- void timerCallback()
- {
- owner->timerCallbackInt();
- }
-
- const MouseCursor getMouseCursor()
- {
- return owner->getMouseCursor();
- }
- };
-
- class TextEditorViewport : public Viewport
- {
- TextEditor* const owner;
- float lastWordWrapWidth;
-
- TextEditorViewport (const TextEditorViewport&);
- const TextEditorViewport& operator= (const TextEditorViewport&);
-
- public:
- TextEditorViewport (TextEditor* const owner_)
- : owner (owner_),
- lastWordWrapWidth (0)
- {
- }
-
- ~TextEditorViewport()
- {
- }
-
- void visibleAreaChanged (int, int, int, int)
- {
- const float wordWrapWidth = owner->getWordWrapWidth();
-
- if (wordWrapWidth != lastWordWrapWidth)
- {
- lastWordWrapWidth = wordWrapWidth;
- owner->updateTextHolderSize();
- }
- }
- };
-
- const int flashSpeedIntervalMs = 380;
-
- const int textChangeMessageId = 0x10003001;
- const int returnKeyMessageId = 0x10003002;
- const int escapeKeyMessageId = 0x10003003;
- const int focusLossMessageId = 0x10003004;
-
- TextEditor::TextEditor (const String& name,
- const tchar passwordCharacter_)
- : Component (name),
- borderSize (1, 1, 1, 3),
- readOnly (false),
- multiline (false),
- wordWrap (false),
- returnKeyStartsNewLine (false),
- caretVisible (true),
- popupMenuEnabled (true),
- selectAllTextWhenFocused (false),
- scrollbarVisible (true),
- wasFocused (false),
- caretFlashState (true),
- keepCursorOnScreen (true),
- tabKeyUsed (false),
- menuActive (false),
- cursorX (0),
- cursorY (0),
- cursorHeight (0),
- maxTextLength (0),
- selectionStart (0),
- selectionEnd (0),
- leftIndent (4),
- topIndent (4),
- lastTransactionTime (0),
- currentFont (14.0f),
- totalNumChars (0),
- caretPosition (0),
- sections (8),
- passwordCharacter (passwordCharacter_),
- dragType (notDragging),
- listeners (2)
- {
- setOpaque (true);
-
- addAndMakeVisible (viewport = new TextEditorViewport (this));
- viewport->setViewedComponent (textHolder = new TextHolderComponent (this));
- viewport->setWantsKeyboardFocus (false);
- viewport->setScrollBarsShown (false, false);
-
- setMouseCursor (MouseCursor::IBeamCursor);
- setWantsKeyboardFocus (true);
- }
-
- TextEditor::~TextEditor()
- {
- clearInternal (0);
- delete viewport;
- }
-
- void TextEditor::newTransaction() throw()
- {
- lastTransactionTime = Time::getApproximateMillisecondCounter();
- undoManager.beginNewTransaction();
- }
-
- void TextEditor::doUndoRedo (const bool isRedo)
- {
- if (! isReadOnly())
- {
- if ((isRedo) ? undoManager.redo()
- : undoManager.undo())
- {
- scrollToMakeSureCursorIsVisible();
- repaint();
- textChanged();
- }
- }
- }
-
- void TextEditor::setMultiLine (const bool shouldBeMultiLine,
- const bool shouldWordWrap)
- {
- multiline = shouldBeMultiLine;
- wordWrap = shouldWordWrap && shouldBeMultiLine;
-
- setScrollbarsShown (scrollbarVisible);
-
- viewport->setViewPosition (0, 0);
-
- resized();
- scrollToMakeSureCursorIsVisible();
- }
-
- bool TextEditor::isMultiLine() const throw()
- {
- return multiline;
- }
-
- void TextEditor::setScrollbarsShown (bool enabled) throw()
- {
- scrollbarVisible = enabled;
-
- enabled = enabled && isMultiLine();
-
- viewport->setScrollBarsShown (enabled, enabled);
- }
-
- void TextEditor::setReadOnly (const bool shouldBeReadOnly)
- {
- readOnly = shouldBeReadOnly;
- enablementChanged();
- }
-
- bool TextEditor::isReadOnly() const throw()
- {
- return readOnly || ! isEnabled();
- }
-
- void TextEditor::setReturnKeyStartsNewLine (const bool shouldStartNewLine)
- {
- returnKeyStartsNewLine = shouldStartNewLine;
- }
-
- void TextEditor::setTabKeyUsedAsCharacter (const bool shouldTabKeyBeUsed) throw()
- {
- tabKeyUsed = shouldTabKeyBeUsed;
- }
-
- void TextEditor::setPopupMenuEnabled (const bool b) throw()
- {
- popupMenuEnabled = b;
- }
-
- void TextEditor::setSelectAllWhenFocused (const bool b) throw()
- {
- selectAllTextWhenFocused = b;
- }
-
- const Font TextEditor::getFont() const throw()
- {
- return currentFont;
- }
-
- void TextEditor::setFont (const Font& newFont) throw()
- {
- currentFont = newFont;
- scrollToMakeSureCursorIsVisible();
- }
-
- void TextEditor::applyFontToAllText (const Font& newFont)
- {
- currentFont = newFont;
-
- const Colour overallColour (findColour (textColourId));
-
- for (int i = sections.size(); --i >= 0;)
- {
- UniformTextSection* const uts = (UniformTextSection*) sections.getUnchecked(i);
- uts->setFont (newFont, passwordCharacter);
- uts->colour = overallColour;
- }
-
- coalesceSimilarSections();
- updateTextHolderSize();
- scrollToMakeSureCursorIsVisible();
- repaint();
- }
-
- void TextEditor::colourChanged()
- {
- setOpaque (findColour (backgroundColourId).isOpaque());
- repaint();
- }
-
- void TextEditor::setCaretVisible (const bool shouldCaretBeVisible) throw()
- {
- caretVisible = shouldCaretBeVisible;
-
- if (shouldCaretBeVisible)
- textHolder->startTimer (flashSpeedIntervalMs);
-
- setMouseCursor (shouldCaretBeVisible ? MouseCursor::IBeamCursor
- : MouseCursor::NormalCursor);
- }
-
- void TextEditor::setInputRestrictions (const int maxLen,
- const String& chars) throw()
- {
- maxTextLength = jmax (0, maxLen);
- allowedCharacters = chars;
- }
-
- void TextEditor::setTextToShowWhenEmpty (const String& text, const Colour& colourToUse) throw()
- {
- textToShowWhenEmpty = text;
- colourForTextWhenEmpty = colourToUse;
- }
-
- void TextEditor::setPasswordCharacter (const tchar newPasswordCharacter) throw()
- {
- if (passwordCharacter != newPasswordCharacter)
- {
- passwordCharacter = newPasswordCharacter;
- resized();
- repaint();
- }
- }
-
- void TextEditor::setScrollBarThickness (const int newThicknessPixels)
- {
- viewport->setScrollBarThickness (newThicknessPixels);
- }
-
- void TextEditor::setScrollBarButtonVisibility (const bool buttonsVisible)
- {
- viewport->setScrollBarButtonVisibility (buttonsVisible);
- }
-
- void TextEditor::clear()
- {
- clearInternal (0);
- updateTextHolderSize();
- undoManager.clearUndoHistory();
- }
-
- void TextEditor::setText (const String& newText,
- const bool sendTextChangeMessage)
- {
- const int newLength = newText.length();
-
- if (newLength != getTotalNumChars() || getText() != newText)
- {
- const int oldCursorPos = caretPosition;
- const bool cursorWasAtEnd = oldCursorPos >= getTotalNumChars();
-
- clearInternal (0);
- insert (newText, 0, currentFont, findColour (textColourId), 0, caretPosition);
-
- // if you're adding text with line-feeds to a single-line text editor, it
- // ain't gonna look right!
- jassert (multiline || ! newText.containsAnyOf (T("\r\n")));
-
- if (cursorWasAtEnd && ! isMultiLine())
- moveCursorTo (getTotalNumChars(), false);
- else
- moveCursorTo (oldCursorPos, false);
-
- if (sendTextChangeMessage)
- textChanged();
-
- repaint();
- }
-
- updateTextHolderSize();
- scrollToMakeSureCursorIsVisible();
- undoManager.clearUndoHistory();
- }
-
- void TextEditor::textChanged() throw()
- {
- updateTextHolderSize();
- postCommandMessage (textChangeMessageId);
- }
-
- void TextEditor::returnPressed()
- {
- postCommandMessage (returnKeyMessageId);
- }
-
- void TextEditor::escapePressed()
- {
- postCommandMessage (escapeKeyMessageId);
- }
-
- void TextEditor::addListener (TextEditorListener* const newListener) throw()
- {
- jassert (newListener != 0)
-
- if (newListener != 0)
- listeners.add (newListener);
- }
-
- void TextEditor::removeListener (TextEditorListener* const listenerToRemove) throw()
- {
- listeners.removeValue (listenerToRemove);
- }
-
- void TextEditor::timerCallbackInt()
- {
- const bool newState = (! caretFlashState) && ! isCurrentlyBlockedByAnotherModalComponent();
-
- if (caretFlashState != newState)
- {
- caretFlashState = newState;
-
- if (caretFlashState)
- wasFocused = true;
-
- if (caretVisible
- && hasKeyboardFocus (false)
- && ! isReadOnly())
- {
- repaintCaret();
- }
- }
-
- const unsigned int now = Time::getApproximateMillisecondCounter();
-
- if (now > lastTransactionTime + 200)
- newTransaction();
- }
-
- void TextEditor::repaintCaret()
- {
- if (! findColour (caretColourId).isTransparent())
- repaint (borderSize.getLeft() + textHolder->getX() + leftIndent + roundFloatToInt (cursorX) - 1,
- borderSize.getTop() + textHolder->getY() + topIndent + roundFloatToInt (cursorY) - 1,
- 4,
- roundFloatToInt (cursorHeight) + 2);
- }
-
- void TextEditor::repaintText (int textStartIndex, int textEndIndex)
- {
- if (textStartIndex > textEndIndex && textEndIndex > 0)
- swapVariables (textStartIndex, textEndIndex);
-
- float x = 0, y = 0, lh = currentFont.getHeight();
-
- const float wordWrapWidth = getWordWrapWidth();
-
- if (wordWrapWidth > 0)
- {
- TextEditorIterator i (sections, wordWrapWidth, passwordCharacter);
-
- i.getCharPosition (textStartIndex, x, y, lh);
-
- const int y1 = (int) y;
- int y2;
-
- if (textEndIndex >= 0)
- {
- i.getCharPosition (textEndIndex, x, y, lh);
- y2 = (int) (y + lh * 2.0f);
- }
- else
- {
- y2 = textHolder->getHeight();
- }
-
- textHolder->repaint (0, y1, textHolder->getWidth(), y2 - y1);
- }
- }
-
- void TextEditor::moveCaret (int newCaretPos) throw()
- {
- if (newCaretPos < 0)
- newCaretPos = 0;
- else if (newCaretPos > getTotalNumChars())
- newCaretPos = getTotalNumChars();
-
- if (newCaretPos != getCaretPosition())
- {
- repaintCaret();
- caretFlashState = true;
- caretPosition = newCaretPos;
- textHolder->startTimer (flashSpeedIntervalMs);
- scrollToMakeSureCursorIsVisible();
- repaintCaret();
- }
- }
-
- void TextEditor::setCaretPosition (const int newIndex) throw()
- {
- moveCursorTo (newIndex, false);
- }
-
- int TextEditor::getCaretPosition() const throw()
- {
- return caretPosition;
- }
-
- float TextEditor::getWordWrapWidth() const throw()
- {
- return (wordWrap) ? (float) (viewport->getMaximumVisibleWidth() - leftIndent - leftIndent / 2)
- : 1.0e10f;
- }
-
- void TextEditor::updateTextHolderSize() throw()
- {
- const float wordWrapWidth = getWordWrapWidth();
-
- if (wordWrapWidth > 0)
- {
- float maxWidth = 0.0f;
-
- TextEditorIterator i (sections, wordWrapWidth, passwordCharacter);
-
- while (i.next())
- maxWidth = jmax (maxWidth, i.atomRight);
-
- const int w = leftIndent + roundFloatToInt (maxWidth);
- const int h = topIndent + roundFloatToInt (jmax (i.lineY + i.lineHeight,
- currentFont.getHeight()));
-
- textHolder->setSize (w + 1, h + 1);
- }
- }
-
- int TextEditor::getTextWidth() const throw()
- {
- return textHolder->getWidth();
- }
-
- int TextEditor::getTextHeight() const throw()
- {
- return textHolder->getHeight();
- }
-
- void TextEditor::setIndents (const int newLeftIndent,
- const int newTopIndent) throw()
- {
- leftIndent = newLeftIndent;
- topIndent = newTopIndent;
- }
-
- void TextEditor::setBorder (const BorderSize& border) throw()
- {
- borderSize = border;
- resized();
- }
-
- const BorderSize TextEditor::getBorder() const throw()
- {
- return borderSize;
- }
-
- void TextEditor::setScrollToShowCursor (const bool shouldScrollToShowCursor) throw()
- {
- keepCursorOnScreen = shouldScrollToShowCursor;
- }
-
- void TextEditor::scrollToMakeSureCursorIsVisible() throw()
- {
- cursorHeight = currentFont.getHeight(); // (in case the text is empty and the call below doesn't set this value)
-
- getCharPosition (caretPosition,
- cursorX, cursorY,
- cursorHeight);
-
- if (keepCursorOnScreen)
- {
- int x = viewport->getViewPositionX();
- int y = viewport->getViewPositionY();
-
- const int relativeCursorX = roundFloatToInt (cursorX) - x;
- const int relativeCursorY = roundFloatToInt (cursorY) - y;
-
- if (relativeCursorX < jmax (1, proportionOfWidth (0.05f)))
- {
- x += relativeCursorX - proportionOfWidth (0.2f);
- }
- else if (relativeCursorX > jmax (0, viewport->getMaximumVisibleWidth() - (wordWrap ? 2 : 10)))
- {
- x += relativeCursorX + (isMultiLine() ? proportionOfWidth (0.2f) : 10) - viewport->getMaximumVisibleWidth();
- }
-
- x = jlimit (0, jmax (0, textHolder->getWidth() + 8 - viewport->getMaximumVisibleWidth()), x);
-
- if (! isMultiLine())
- {
- y = (getHeight() - textHolder->getHeight() - topIndent) / -2;
- }
- else
- {
- const int curH = roundFloatToInt (cursorHeight);
-
- if (relativeCursorY < 0)
- {
- y = jmax (0, relativeCursorY + y);
- }
- else if (relativeCursorY > jmax (0, viewport->getMaximumVisibleHeight() - topIndent - curH))
- {
- y += relativeCursorY + 2 + curH + topIndent - viewport->getMaximumVisibleHeight();
- }
- }
-
- viewport->setViewPosition (x, y);
- }
- }
-
- void TextEditor::moveCursorTo (const int newPosition,
- const bool isSelecting) throw()
- {
- if (isSelecting)
- {
- moveCaret (newPosition);
-
- const int oldSelStart = selectionStart;
- const int oldSelEnd = selectionEnd;
-
- if (dragType == notDragging)
- {
- if (abs (getCaretPosition() - selectionStart) < abs (getCaretPosition() - selectionEnd))
- dragType = draggingSelectionStart;
- else
- dragType = draggingSelectionEnd;
- }
-
- if (dragType == draggingSelectionStart)
- {
- selectionStart = getCaretPosition();
-
- if (selectionEnd < selectionStart)
- {
- swapVariables (selectionStart, selectionEnd);
- dragType = draggingSelectionEnd;
- }
- }
- else
- {
- selectionEnd = getCaretPosition();
-
- if (selectionEnd < selectionStart)
- {
- swapVariables (selectionStart, selectionEnd);
- dragType = draggingSelectionStart;
- }
- }
-
- jassert (selectionStart <= selectionEnd);
- jassert (oldSelStart <= oldSelEnd);
-
- repaintText (jmin (oldSelStart, selectionStart),
- jmax (oldSelEnd, selectionEnd));
- }
- else
- {
- dragType = notDragging;
-
- if (selectionEnd > selectionStart)
- repaintText (selectionStart, selectionEnd);
-
- moveCaret (newPosition);
- selectionStart = getCaretPosition();
- selectionEnd = getCaretPosition();
- }
- }
-
- int TextEditor::getTextIndexAt (const int x,
- const int y) throw()
- {
- return indexAtPosition ((float) (x + viewport->getViewPositionX() - leftIndent),
- (float) (y + viewport->getViewPositionY() - topIndent));
- }
-
- void TextEditor::insertTextAtCursor (String newText)
- {
- if (allowedCharacters.isNotEmpty())
- newText = newText.retainCharacters (allowedCharacters);
-
- if (! isMultiLine())
- newText = newText.replaceCharacters (T("\r\n"), T(" "));
- else
- newText = newText.replace (T("\r\n"), T("\n"));
-
- const int newCaretPos = selectionStart + newText.length();
- const int insertIndex = selectionStart;
-
- remove (selectionStart, selectionEnd,
- &undoManager,
- newCaretPos);
-
- if (maxTextLength > 0)
- newText = newText.substring (0, maxTextLength - getTotalNumChars());
-
- if (newText.isNotEmpty())
- insert (newText,
- insertIndex,
- currentFont,
- findColour (textColourId),
- &undoManager,
- newCaretPos);
-
- textChanged();
- }
-
- void TextEditor::setHighlightedRegion (int startPos, int numChars) throw()
- {
- moveCursorTo (startPos, false);
- moveCursorTo (startPos + numChars, true);
- }
-
- void TextEditor::copy()
- {
- const String selection (getTextSubstring (selectionStart, selectionEnd));
-
- if (selection.isNotEmpty())
- SystemClipboard::copyTextToClipboard (selection);
- }
-
- void TextEditor::paste()
- {
- if (! isReadOnly())
- {
- const String clip (SystemClipboard::getTextFromClipboard());
-
- if (clip.isNotEmpty())
- insertTextAtCursor (clip);
- }
- }
-
- void TextEditor::cut()
- {
- if (! isReadOnly())
- {
- moveCaret (selectionEnd);
- insertTextAtCursor (String::empty);
- }
- }
-
- void TextEditor::drawContent (Graphics& g)
- {
- const float wordWrapWidth = getWordWrapWidth();
-
- if (wordWrapWidth > 0)
- {
- g.setOrigin (leftIndent, topIndent);
- const Rectangle clip (g.getClipBounds());
- Colour selectedTextColour;
-
- TextEditorIterator i (sections, wordWrapWidth, passwordCharacter);
-
- while (i.lineY + 200.0 < clip.getY() && i.next())
- {}
-
- if (selectionStart < selectionEnd)
- {
- g.setColour (findColour (highlightColourId)
- .withMultipliedAlpha (hasKeyboardFocus (true) ? 1.0f : 0.5f));
-
- selectedTextColour = findColour (highlightedTextColourId);
-
- TextEditorIterator i2 (i);
-
- while (i2.next() && i2.lineY < clip.getBottom())
- {
- i2.updateLineHeight();
-
- if (i2.lineY + i2.lineHeight >= clip.getY()
- && selectionEnd >= i2.indexInText
- && selectionStart <= i2.indexInText + i2.atom->numChars)
- {
- i2.drawSelection (g, selectionStart, selectionEnd);
- }
- }
- }
-
- const UniformTextSection* lastSection = 0;
-
- while (i.next() && i.lineY < clip.getBottom())
- {
- i.updateLineHeight();
-
- if (i.lineY + i.lineHeight >= clip.getY())
- {
- if (selectionEnd >= i.indexInText
- && selectionStart <= i.indexInText + i.atom->numChars)
- {
- i.drawSelectedText (g, selectionStart, selectionEnd, selectedTextColour);
- lastSection = 0;
- }
- else
- {
- i.draw (g, lastSection);
- }
- }
- }
- }
- }
-
- void TextEditor::paint (Graphics& g)
- {
- getLookAndFeel().fillTextEditorBackground (g, getWidth(), getHeight(), *this);
- }
-
- void TextEditor::paintOverChildren (Graphics& g)
- {
- if (caretFlashState
- && hasKeyboardFocus (false)
- && caretVisible
- && ! isReadOnly())
- {
- g.setColour (findColour (caretColourId));
-
- g.fillRect (borderSize.getLeft() + textHolder->getX() + leftIndent + cursorX,
- borderSize.getTop() + textHolder->getY() + topIndent + cursorY,
- 2.0f, cursorHeight);
- }
-
- if (textToShowWhenEmpty.isNotEmpty()
- && (! hasKeyboardFocus (false))
- && getTotalNumChars() == 0)
- {
- g.setColour (colourForTextWhenEmpty);
- g.setFont (getFont());
-
- if (isMultiLine())
- {
- g.drawText (textToShowWhenEmpty,
- 0, 0, getWidth(), getHeight(),
- Justification::centred, true);
- }
- else
- {
- g.drawText (textToShowWhenEmpty,
- leftIndent, topIndent,
- viewport->getWidth() - leftIndent,
- viewport->getHeight() - topIndent,
- Justification::centredLeft, true);
- }
- }
-
- getLookAndFeel().drawTextEditorOutline (g, getWidth(), getHeight(), *this);
- }
-
- void TextEditor::mouseDown (const MouseEvent& e)
- {
- beginDragAutoRepeat (100);
- newTransaction();
-
- if (wasFocused || ! selectAllTextWhenFocused)
- {
- if (! (popupMenuEnabled && e.mods.isPopupMenu()))
- {
- moveCursorTo (getTextIndexAt (e.x, e.y),
- e.mods.isShiftDown());
- }
- else
- {
- PopupMenu m;
- addPopupMenuItems (m, &e);
-
- menuActive = true;
- const int result = m.show();
- menuActive = false;
-
- if (result != 0)
- performPopupMenuAction (result);
- }
- }
- }
-
- void TextEditor::mouseDrag (const MouseEvent& e)
- {
- if (wasFocused || ! selectAllTextWhenFocused)
- {
- if (! (popupMenuEnabled && e.mods.isPopupMenu()))
- {
- moveCursorTo (getTextIndexAt (e.x, e.y), true);
- }
- }
- }
-
- void TextEditor::mouseUp (const MouseEvent& e)
- {
- newTransaction();
- textHolder->startTimer (flashSpeedIntervalMs);
-
- if (wasFocused || ! selectAllTextWhenFocused)
- {
- if (! (popupMenuEnabled && e.mods.isPopupMenu()))
- {
- moveCaret (getTextIndexAt (e.x, e.y));
- }
- }
-
- wasFocused = true;
- }
-
- void TextEditor::mouseDoubleClick (const MouseEvent& e)
- {
- int tokenEnd = getTextIndexAt (e.x, e.y);
- int tokenStart = tokenEnd;
-
- if (e.getNumberOfClicks() > 3)
- {
- tokenStart = 0;
- tokenEnd = getTotalNumChars();
- }
- else
- {
- const String t (getText());
- const int totalLength = getTotalNumChars();
-
- while (tokenEnd < totalLength)
- {
- if (CharacterFunctions::isLetterOrDigit (t [tokenEnd]))
- ++tokenEnd;
- else
- break;
- }
-
- tokenStart = tokenEnd;
-
- while (tokenStart > 0)
- {
- if (CharacterFunctions::isLetterOrDigit (t [tokenStart - 1]))
- --tokenStart;
- else
- break;
- }
-
- if (e.getNumberOfClicks() > 2)
- {
- while (tokenEnd < totalLength)
- {
- if (t [tokenEnd] != T('\r') && t [tokenEnd] != T('\n'))
- ++tokenEnd;
- else
- break;
- }
-
- while (tokenStart > 0)
- {
- if (t [tokenStart - 1] != T('\r') && t [tokenStart - 1] != T('\n'))
- --tokenStart;
- else
- break;
- }
- }
- }
-
- moveCursorTo (tokenEnd, false);
- moveCursorTo (tokenStart, true);
- }
-
- void TextEditor::mouseWheelMove (const MouseEvent& e, float wheelIncrementX, float wheelIncrementY)
- {
- if (! viewport->useMouseWheelMoveIfNeeded (e, wheelIncrementX, wheelIncrementY))
- Component::mouseWheelMove (e, wheelIncrementX, wheelIncrementY);
- }
-
- bool TextEditor::keyPressed (const KeyPress& key)
- {
- if (isReadOnly() && key != KeyPress (T('c'), ModifierKeys::commandModifier, 0))
- return false;
-
- const bool moveInWholeWordSteps = key.getModifiers().isCtrlDown() || key.getModifiers().isAltDown();
-
- if (key.isKeyCode (KeyPress::leftKey)
- || key.isKeyCode (KeyPress::upKey))
- {
- newTransaction();
-
- int newPos;
-
- if (isMultiLine() && key.isKeyCode (KeyPress::upKey))
- newPos = indexAtPosition (cursorX, cursorY - 1);
- else if (moveInWholeWordSteps)
- newPos = findWordBreakBefore (getCaretPosition());
- else
- newPos = getCaretPosition() - 1;
-
- moveCursorTo (newPos, key.getModifiers().isShiftDown());
- }
- else if (key.isKeyCode (KeyPress::rightKey)
- || key.isKeyCode (KeyPress::downKey))
- {
- newTransaction();
-
- int newPos;
-
- if (isMultiLine() && key.isKeyCode (KeyPress::downKey))
- newPos = indexAtPosition (cursorX, cursorY + cursorHeight + 1);
- else if (moveInWholeWordSteps)
- newPos = findWordBreakAfter (getCaretPosition());
- else
- newPos = getCaretPosition() + 1;
-
- moveCursorTo (newPos, key.getModifiers().isShiftDown());
- }
- else if (key.isKeyCode (KeyPress::pageDownKey) && isMultiLine())
- {
- newTransaction();
-
- moveCursorTo (indexAtPosition (cursorX, cursorY + cursorHeight + viewport->getViewHeight()),
- key.getModifiers().isShiftDown());
- }
- else if (key.isKeyCode (KeyPress::pageUpKey) && isMultiLine())
- {
- newTransaction();
-
- moveCursorTo (indexAtPosition (cursorX, cursorY - viewport->getViewHeight()),
- key.getModifiers().isShiftDown());
- }
- else if (key.isKeyCode (KeyPress::homeKey))
- {
- newTransaction();
-
- if (isMultiLine() && ! moveInWholeWordSteps)
- moveCursorTo (indexAtPosition (0.0f, cursorY),
- key.getModifiers().isShiftDown());
- else
- moveCursorTo (0, key.getModifiers().isShiftDown());
- }
- else if (key.isKeyCode (KeyPress::endKey))
- {
- newTransaction();
-
- if (isMultiLine() && ! moveInWholeWordSteps)
- moveCursorTo (indexAtPosition ((float) textHolder->getWidth(), cursorY),
- key.getModifiers().isShiftDown());
- else
- moveCursorTo (getTotalNumChars(), key.getModifiers().isShiftDown());
- }
- else if (key.isKeyCode (KeyPress::backspaceKey))
- {
- if (moveInWholeWordSteps)
- {
- moveCursorTo (findWordBreakBefore (getCaretPosition()), true);
- }
- else
- {
- if (selectionStart == selectionEnd && selectionStart > 0)
- --selectionStart;
- }
-
- cut();
- }
- else if (key.isKeyCode (KeyPress::deleteKey))
- {
- if (key.getModifiers().isShiftDown())
- copy();
-
- if (selectionStart == selectionEnd
- && selectionEnd < getTotalNumChars())
- {
- ++selectionEnd;
- }
-
- cut();
- }
- else if (key == KeyPress (T('c'), ModifierKeys::commandModifier, 0)
- || key == KeyPress (KeyPress::insertKey, ModifierKeys::ctrlModifier, 0))
- {
- newTransaction();
- copy();
- }
- else if (key == KeyPress (T('x'), ModifierKeys::commandModifier, 0))
- {
- newTransaction();
- copy();
- cut();
- }
- else if (key == KeyPress (T('v'), ModifierKeys::commandModifier, 0)
- || key == KeyPress (KeyPress::insertKey, ModifierKeys::shiftModifier, 0))
- {
- newTransaction();
- paste();
- }
- else if (key == KeyPress (T('z'), ModifierKeys::commandModifier, 0))
- {
- newTransaction();
- doUndoRedo (false);
- }
- else if (key == KeyPress (T('y'), ModifierKeys::commandModifier, 0))
- {
- newTransaction();
- doUndoRedo (true);
- }
- else if (key == KeyPress (T('a'), ModifierKeys::commandModifier, 0))
- {
- newTransaction();
- moveCursorTo (getTotalNumChars(), false);
- moveCursorTo (0, true);
- }
- else if (key == KeyPress::returnKey)
- {
- newTransaction();
-
- if (returnKeyStartsNewLine)
- insertTextAtCursor (T("\n"));
- else
- returnPressed();
- }
- else if (key.isKeyCode (KeyPress::escapeKey))
- {
- newTransaction();
- moveCursorTo (getCaretPosition(), false);
- escapePressed();
- }
- else if (key.getTextCharacter() >= ' '
- || (tabKeyUsed && (key.getTextCharacter() == '\t')))
- {
- insertTextAtCursor (String::charToString (key.getTextCharacter()));
-
- lastTransactionTime = Time::getApproximateMillisecondCounter();
- }
- else
- {
- return false;
- }
-
- return true;
- }
-
- bool TextEditor::keyStateChanged()
- {
- // (overridden to avoid forwarding key events to the parent)
- return true;
- }
-
- const int baseMenuItemID = 0x7fff0000;
-
- void TextEditor::addPopupMenuItems (PopupMenu& m, const MouseEvent*)
- {
- const bool writable = ! isReadOnly();
-
- m.addItem (baseMenuItemID + 1, TRANS("cut"), writable);
- m.addItem (baseMenuItemID + 2, TRANS("copy"), selectionStart < selectionEnd);
- m.addItem (baseMenuItemID + 3, TRANS("paste"), writable);
- m.addItem (baseMenuItemID + 4, TRANS("delete"), writable);
- m.addSeparator();
- m.addItem (baseMenuItemID + 5, TRANS("select all"));
- m.addSeparator();
- m.addItem (baseMenuItemID + 6, TRANS("undo"), undoManager.canUndo());
- m.addItem (baseMenuItemID + 7, TRANS("redo"), undoManager.canRedo());
- }
-
- void TextEditor::performPopupMenuAction (const int menuItemID)
- {
- switch (menuItemID)
- {
- case baseMenuItemID + 1:
- copy();
- cut();
- break;
-
- case baseMenuItemID + 2:
- copy();
- break;
-
- case baseMenuItemID + 3:
- paste();
- break;
-
- case baseMenuItemID + 4:
- cut();
- break;
-
- case baseMenuItemID + 5:
- moveCursorTo (getTotalNumChars(), false);
- moveCursorTo (0, true);
- break;
-
- case baseMenuItemID + 6:
- doUndoRedo (false);
- break;
-
- case baseMenuItemID + 7:
- doUndoRedo (true);
- break;
-
- default:
- break;
- }
- }
-
- void TextEditor::focusGained (FocusChangeType)
- {
- newTransaction();
-
- caretFlashState = true;
-
- if (selectAllTextWhenFocused)
- {
- moveCursorTo (0, false);
- moveCursorTo (getTotalNumChars(), true);
- }
-
- repaint();
-
- if (caretVisible)
- textHolder->startTimer (flashSpeedIntervalMs);
-
- ComponentPeer* const peer = getPeer();
- if (peer != 0)
- peer->textInputRequired (getScreenX() - peer->getScreenX(),
- getScreenY() - peer->getScreenY());
- }
-
- void TextEditor::focusLost (FocusChangeType)
- {
- newTransaction();
-
- wasFocused = false;
- textHolder->stopTimer();
- caretFlashState = false;
-
- postCommandMessage (focusLossMessageId);
- repaint();
- }
-
- void TextEditor::resized()
- {
- viewport->setBoundsInset (borderSize);
- viewport->setSingleStepSizes (16, roundFloatToInt (currentFont.getHeight()));
-
- updateTextHolderSize();
-
- if (! isMultiLine())
- {
- scrollToMakeSureCursorIsVisible();
- }
- else
- {
- cursorHeight = currentFont.getHeight(); // (in case the text is empty and the call below doesn't set this value)
-
- getCharPosition (caretPosition,
- cursorX, cursorY,
- cursorHeight);
- }
- }
-
- void TextEditor::handleCommandMessage (const int commandId)
- {
- const ComponentDeletionWatcher deletionChecker (this);
-
- for (int i = listeners.size(); --i >= 0;)
- {
- TextEditorListener* const tl = (TextEditorListener*) listeners [i];
-
- if (tl != 0)
- {
- switch (commandId)
- {
- case textChangeMessageId:
- tl->textEditorTextChanged (*this);
- break;
-
- case returnKeyMessageId:
- tl->textEditorReturnKeyPressed (*this);
- break;
-
- case escapeKeyMessageId:
- tl->textEditorEscapeKeyPressed (*this);
- break;
-
- case focusLossMessageId:
- tl->textEditorFocusLost (*this);
- break;
-
- default:
- jassertfalse
- break;
- }
-
- if (i > 0 && deletionChecker.hasBeenDeleted())
- return;
- }
- }
- }
-
- void TextEditor::enablementChanged()
- {
- setMouseCursor (MouseCursor (isReadOnly() ? MouseCursor::NormalCursor
- : MouseCursor::IBeamCursor));
- repaint();
- }
-
- void TextEditor::clearInternal (UndoManager* const um) throw()
- {
- remove (0, getTotalNumChars(), um, caretPosition);
- }
-
- void TextEditor::insert (const String& text,
- const int insertIndex,
- const Font& font,
- const Colour& colour,
- UndoManager* const um,
- const int caretPositionToMoveTo) throw()
- {
- if (text.isNotEmpty())
- {
- if (um != 0)
- {
- um->perform (new TextEditorInsertAction (*this,
- text,
- insertIndex,
- font,
- colour,
- caretPosition,
- caretPositionToMoveTo));
- }
- else
- {
- repaintText (insertIndex, -1); // must do this before and after changing the data, in case
- // a line gets moved due to word wrap
-
- int index = 0;
- int nextIndex = 0;
-
- for (int i = 0; i < sections.size(); ++i)
- {
- nextIndex = index + ((UniformTextSection*) sections.getUnchecked(i))->getTotalLength();
-
- if (insertIndex == index)
- {
- sections.insert (i, new UniformTextSection (text,
- font, colour,
- passwordCharacter));
- break;
- }
- else if (insertIndex > index && insertIndex < nextIndex)
- {
- splitSection (i, insertIndex - index);
- sections.insert (i + 1, new UniformTextSection (text,
- font, colour,
- passwordCharacter));
- break;
- }
-
- index = nextIndex;
- }
-
- if (nextIndex == insertIndex)
- sections.add (new UniformTextSection (text,
- font, colour,
- passwordCharacter));
-
- coalesceSimilarSections();
- totalNumChars = -1;
-
- moveCursorTo (caretPositionToMoveTo, false);
-
- repaintText (insertIndex, -1);
- }
- }
- }
-
- void TextEditor::reinsert (const int insertIndex,
- const VoidArray& sectionsToInsert) throw()
- {
- int index = 0;
- int nextIndex = 0;
-
- for (int i = 0; i < sections.size(); ++i)
- {
- nextIndex = index + ((UniformTextSection*) sections.getUnchecked(i))->getTotalLength();
-
- if (insertIndex == index)
- {
- for (int j = sectionsToInsert.size(); --j >= 0;)
- sections.insert (i, new UniformTextSection (*(UniformTextSection*) sectionsToInsert.getUnchecked(j)));
-
- break;
- }
- else if (insertIndex > index && insertIndex < nextIndex)
- {
- splitSection (i, insertIndex - index);
-
- for (int j = sectionsToInsert.size(); --j >= 0;)
- sections.insert (i + 1, new UniformTextSection (*(UniformTextSection*) sectionsToInsert.getUnchecked(j)));
-
- break;
- }
-
- index = nextIndex;
- }
-
- if (nextIndex == insertIndex)
- {
- for (int j = 0; j < sectionsToInsert.size(); ++j)
- sections.add (new UniformTextSection (*(UniformTextSection*) sectionsToInsert.getUnchecked(j)));
- }
-
- coalesceSimilarSections();
- totalNumChars = -1;
- }
-
- void TextEditor::remove (const int startIndex,
- int endIndex,
- UndoManager* const um,
- const int caretPositionToMoveTo) throw()
- {
- if (endIndex > startIndex)
- {
- int index = 0;
-
- for (int i = 0; i < sections.size(); ++i)
- {
- const int nextIndex = index + ((UniformTextSection*) sections[i])->getTotalLength();
-
- if (startIndex > index && startIndex < nextIndex)
- {
- splitSection (i, startIndex - index);
- --i;
- }
- else if (endIndex > index && endIndex < nextIndex)
- {
- splitSection (i, endIndex - index);
- --i;
- }
- else
- {
- index = nextIndex;
-
- if (index > endIndex)
- break;
- }
- }
-
- index = 0;
-
- if (um != 0)
- {
- VoidArray removedSections;
-
- for (int i = 0; i < sections.size(); ++i)
- {
- if (endIndex <= startIndex)
- break;
-
- UniformTextSection* const section = (UniformTextSection*) sections.getUnchecked (i);
-
- const int nextIndex = index + section->getTotalLength();
-
- if (startIndex <= index && endIndex >= nextIndex)
- removedSections.add (new UniformTextSection (*section));
-
- index = nextIndex;
- }
-
- um->perform (new TextEditorRemoveAction (*this,
- startIndex,
- endIndex,
- caretPosition,
- caretPositionToMoveTo,
- removedSections));
- }
- else
- {
- for (int i = 0; i < sections.size(); ++i)
- {
- if (endIndex <= startIndex)
- break;
-
- UniformTextSection* const section = (UniformTextSection*) sections.getUnchecked (i);
-
- const int nextIndex = index + section->getTotalLength();
-
- if (startIndex <= index && endIndex >= nextIndex)
- {
- sections.remove(i);
- endIndex -= (nextIndex - index);
- section->clear();
- delete section;
- --i;
- }
- else
- {
- index = nextIndex;
- }
- }
-
- coalesceSimilarSections();
- totalNumChars = -1;
-
- moveCursorTo (caretPositionToMoveTo, false);
-
- repaintText (startIndex, -1);
- }
- }
- }
-
- const String TextEditor::getText() const throw()
- {
- String t;
-
- for (int i = 0; i < sections.size(); ++i)
- t += ((const UniformTextSection*) sections.getUnchecked(i))->getAllText();
-
- return t;
- }
-
- const String TextEditor::getTextSubstring (const int startCharacter, const int endCharacter) const throw()
- {
- String t;
- int index = 0;
-
- for (int i = 0; i < sections.size(); ++i)
- {
- const UniformTextSection* const s = (const UniformTextSection*) sections.getUnchecked(i);
- const int nextIndex = index + s->getTotalLength();
-
- if (startCharacter < nextIndex)
- {
- if (endCharacter <= index)
- break;
-
- const int start = jmax (index, startCharacter);
- t += s->getTextSubstring (start - index, endCharacter - index);
- }
-
- index = nextIndex;
- }
-
- return t;
- }
-
- const String TextEditor::getHighlightedText() const throw()
- {
- return getTextSubstring (getHighlightedRegionStart(),
- getHighlightedRegionStart() + getHighlightedRegionLength());
- }
-
- int TextEditor::getTotalNumChars() throw()
- {
- if (totalNumChars < 0)
- {
- totalNumChars = 0;
-
- for (int i = sections.size(); --i >= 0;)
- totalNumChars += ((const UniformTextSection*) sections.getUnchecked(i))->getTotalLength();
- }
-
- return totalNumChars;
- }
-
- bool TextEditor::isEmpty() const throw()
- {
- if (totalNumChars != 0)
- {
- for (int i = sections.size(); --i >= 0;)
- if (((const UniformTextSection*) sections.getUnchecked(i))->getTotalLength() > 0)
- return false;
- }
-
- return true;
- }
-
- void TextEditor::getCharPosition (const int index, float& cx, float& cy, float& lineHeight) const throw()
- {
- const float wordWrapWidth = getWordWrapWidth();
-
- if (wordWrapWidth > 0 && sections.size() > 0)
- {
- TextEditorIterator i (sections, wordWrapWidth, passwordCharacter);
-
- i.getCharPosition (index, cx, cy, lineHeight);
- }
- else
- {
- cx = cy = 0;
- lineHeight = currentFont.getHeight();
- }
- }
-
- int TextEditor::indexAtPosition (const float x, const float y) throw()
- {
- const float wordWrapWidth = getWordWrapWidth();
-
- if (wordWrapWidth > 0)
- {
- TextEditorIterator i (sections, wordWrapWidth, passwordCharacter);
-
- while (i.next())
- {
- if (i.lineY + getHeight() > y)
- i.updateLineHeight();
-
- if (i.lineY + i.lineHeight > y)
- {
- if (i.lineY > y)
- return jmax (0, i.indexInText - 1);
-
- if (i.atomX >= x)
- return i.indexInText;
-
- if (x < i.atomRight)
- return i.xToIndex (x);
- }
- }
- }
-
- return getTotalNumChars();
- }
-
- static int getCharacterCategory (const tchar character) throw()
- {
- return CharacterFunctions::isLetterOrDigit (character)
- ? 2 : (CharacterFunctions::isWhitespace (character) ? 0 : 1);
- }
-
- int TextEditor::findWordBreakAfter (const int position) const throw()
- {
- const String t (getTextSubstring (position, position + 512));
- const int totalLength = t.length();
- int i = 0;
-
- while (i < totalLength && CharacterFunctions::isWhitespace (t[i]))
- ++i;
-
- const int type = getCharacterCategory (t[i]);
-
- while (i < totalLength && type == getCharacterCategory (t[i]))
- ++i;
-
- while (i < totalLength && CharacterFunctions::isWhitespace (t[i]))
- ++i;
-
- return position + i;
- }
-
- int TextEditor::findWordBreakBefore (const int position) const throw()
- {
- if (position <= 0)
- return 0;
-
- const int startOfBuffer = jmax (0, position - 512);
- const String t (getTextSubstring (startOfBuffer, position));
-
- int i = position - startOfBuffer;
-
- while (i > 0 && CharacterFunctions::isWhitespace (t [i - 1]))
- --i;
-
- if (i > 0)
- {
- const int type = getCharacterCategory (t [i - 1]);
-
- while (i > 0 && type == getCharacterCategory (t [i - 1]))
- --i;
- }
-
- jassert (startOfBuffer + i >= 0);
- return startOfBuffer + i;
- }
-
- void TextEditor::splitSection (const int sectionIndex,
- const int charToSplitAt) throw()
- {
- jassert (sections[sectionIndex] != 0);
-
- sections.insert (sectionIndex + 1,
- ((UniformTextSection*) sections.getUnchecked (sectionIndex))
- ->split (charToSplitAt, passwordCharacter));
- }
-
- void TextEditor::coalesceSimilarSections() throw()
- {
- for (int i = 0; i < sections.size() - 1; ++i)
- {
- UniformTextSection* const s1 = (UniformTextSection*) (sections.getUnchecked (i));
- UniformTextSection* const s2 = (UniformTextSection*) (sections.getUnchecked (i + 1));
-
- if (s1->font == s2->font
- && s1->colour == s2->colour)
- {
- s1->append (*s2, passwordCharacter);
- sections.remove (i + 1);
- delete s2;
- --i;
- }
- }
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_TextEditor.cpp *********/
-
- /********* Start of inlined file: juce_Toolbar.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- const tchar* const Toolbar::toolbarDragDescriptor = T("_toolbarItem_");
-
- class ToolbarSpacerComp : public ToolbarItemComponent
- {
- public:
- ToolbarSpacerComp (const int itemId, const float fixedSize_, const bool drawBar_)
- : ToolbarItemComponent (itemId, String::empty, false),
- fixedSize (fixedSize_),
- drawBar (drawBar_)
- {
- }
-
- ~ToolbarSpacerComp()
- {
- }
-
- bool getToolbarItemSizes (int toolbarThickness, bool /*isToolbarVertical*/,
- int& preferredSize, int& minSize, int& maxSize)
- {
- if (fixedSize <= 0)
- {
- preferredSize = toolbarThickness * 2;
- minSize = 4;
- maxSize = 32768;
- }
- else
- {
- maxSize = roundFloatToInt (toolbarThickness * fixedSize);
- minSize = drawBar ? maxSize : jmin (4, maxSize);
- preferredSize = maxSize;
-
- if (getEditingMode() == editableOnPalette)
- preferredSize = maxSize = toolbarThickness / (drawBar ? 3 : 2);
- }
-
- return true;
- }
-
- void paintButtonArea (Graphics&, int, int, bool, bool)
- {
- }
-
- void contentAreaChanged (const Rectangle&)
- {
- }
-
- int getResizeOrder() const throw()
- {
- return fixedSize <= 0 ? 0 : 1;
- }
-
- void paint (Graphics& g)
- {
- const int w = getWidth();
- const int h = getHeight();
-
- if (drawBar)
- {
- g.setColour (findColour (Toolbar::separatorColourId, true));
-
- const float thickness = 0.2f;
-
- if (isToolbarVertical())
- g.fillRect (w * 0.1f, h * (0.5f - thickness * 0.5f), w * 0.8f, h * thickness);
- else
- g.fillRect (w * (0.5f - thickness * 0.5f), h * 0.1f, w * thickness, h * 0.8f);
- }
-
- if (getEditingMode() != normalMode && ! drawBar)
- {
- g.setColour (findColour (Toolbar::separatorColourId, true));
-
- const int indentX = jmin (2, (w - 3) / 2);
- const int indentY = jmin (2, (h - 3) / 2);
- g.drawRect (indentX, indentY, w - indentX * 2, h - indentY * 2, 1);
-
- if (fixedSize <= 0)
- {
- float x1, y1, x2, y2, x3, y3, x4, y4, hw, hl;
-
- if (isToolbarVertical())
- {
- x1 = w * 0.5f;
- y1 = h * 0.4f;
- x2 = x1;
- y2 = indentX * 2.0f;
-
- x3 = x1;
- y3 = h * 0.6f;
- x4 = x1;
- y4 = h - y2;
-
- hw = w * 0.15f;
- hl = w * 0.2f;
- }
- else
- {
- x1 = w * 0.4f;
- y1 = h * 0.5f;
- x2 = indentX * 2.0f;
- y2 = y1;
-
- x3 = w * 0.6f;
- y3 = y1;
- x4 = w - x2;
- y4 = y1;
-
- hw = h * 0.15f;
- hl = h * 0.2f;
- }
-
- Path p;
- p.addArrow (x1, y1, x2, y2, 1.5f, hw, hl);
- p.addArrow (x3, y3, x4, y4, 1.5f, hw, hl);
- g.fillPath (p);
- }
- }
- }
-
- juce_UseDebuggingNewOperator
-
- private:
- const float fixedSize;
- const bool drawBar;
-
- ToolbarSpacerComp (const ToolbarSpacerComp&);
- const ToolbarSpacerComp& operator= (const ToolbarSpacerComp&);
- };
-
- class MissingItemsComponent : public PopupMenuCustomComponent
- {
- public:
- MissingItemsComponent (Toolbar& owner_, const int height_)
- : PopupMenuCustomComponent (true),
- owner (owner_),
- height (height_)
- {
- for (int i = owner_.items.size(); --i >= 0;)
- {
- ToolbarItemComponent* const tc = owner_.items.getUnchecked(i);
-
- if (dynamic_cast <ToolbarSpacerComp*> (tc) == 0 && ! tc->isVisible())
- {
- oldIndexes.insert (0, i);
- addAndMakeVisible (tc, 0);
- }
- }
-
- layout (400);
- }
-
- ~MissingItemsComponent()
- {
- // deleting the toolbar while its menu it open??
- jassert (owner.isValidComponent());
-
- for (int i = 0; i < getNumChildComponents(); ++i)
- {
- ToolbarItemComponent* const tc = dynamic_cast <ToolbarItemComponent*> (getChildComponent (i));
-
- if (tc != 0)
- {
- tc->setVisible (false);
- const int index = oldIndexes.remove (i);
- owner.addChildComponent (tc, index);
- --i;
- }
- }
-
- owner.resized();
- }
-
- void layout (const int preferredWidth)
- {
- const int indent = 8;
- int x = indent;
- int y = indent;
- int maxX = 0;
-
- for (int i = 0; i < getNumChildComponents(); ++i)
- {
- ToolbarItemComponent* const tc = dynamic_cast <ToolbarItemComponent*> (getChildComponent (i));
-
- if (tc != 0)
- {
- int preferredSize = 1, minSize = 1, maxSize = 1;
-
- if (tc->getToolbarItemSizes (height, false, preferredSize, minSize, maxSize))
- {
- if (x + preferredSize > preferredWidth && x > indent)
- {
- x = indent;
- y += height;
- }
-
- tc->setBounds (x, y, preferredSize, height);
-
- x += preferredSize;
- maxX = jmax (maxX, x);
- }
- }
- }
-
- setSize (maxX + 8, y + height + 8);
- }
-
- void getIdealSize (int& idealWidth, int& idealHeight)
- {
- idealWidth = getWidth();
- idealHeight = getHeight();
- }
-
- juce_UseDebuggingNewOperator
-
- private:
- Toolbar& owner;
- const int height;
- Array <int> oldIndexes;
-
- MissingItemsComponent (const MissingItemsComponent&);
- const MissingItemsComponent& operator= (const MissingItemsComponent&);
- };
-
- Toolbar::Toolbar()
- : vertical (false),
- isEditingActive (false),
- toolbarStyle (Toolbar::iconsOnly)
- {
- addChildComponent (missingItemsButton = getLookAndFeel().createToolbarMissingItemsButton (*this));
-
- missingItemsButton->setAlwaysOnTop (true);
- missingItemsButton->addButtonListener (this);
- }
-
- Toolbar::~Toolbar()
- {
- animator.cancelAllAnimations (true);
- deleteAllChildren();
- }
-
- void Toolbar::setVertical (const bool shouldBeVertical)
- {
- if (vertical != shouldBeVertical)
- {
- vertical = shouldBeVertical;
- resized();
- }
- }
-
- void Toolbar::clear()
- {
- for (int i = items.size(); --i >= 0;)
- {
- ToolbarItemComponent* const tc = items.getUnchecked(i);
- items.remove (i);
- delete tc;
- }
-
- resized();
- }
-
- ToolbarItemComponent* Toolbar::createItem (ToolbarItemFactory& factory, const int itemId)
- {
- if (itemId == ToolbarItemFactory::separatorBarId)
- return new ToolbarSpacerComp (itemId, 0.1f, true);
- else if (itemId == ToolbarItemFactory::spacerId)
- return new ToolbarSpacerComp (itemId, 0.5f, false);
- else if (itemId == ToolbarItemFactory::flexibleSpacerId)
- return new ToolbarSpacerComp (itemId, 0, false);
-
- return factory.createItem (itemId);
- }
-
- void Toolbar::addItemInternal (ToolbarItemFactory& factory,
- const int itemId,
- const int insertIndex)
- {
- // An ID can't be zero - this might indicate a mistake somewhere?
- jassert (itemId != 0);
-
- ToolbarItemComponent* const tc = createItem (factory, itemId);
-
- if (tc != 0)
- {
- #ifdef JUCE_DEBUG
- Array <int> allowedIds;
- factory.getAllToolbarItemIds (allowedIds);
-
- // If your factory can create an item for a given ID, it must also return
- // that ID from its getAllToolbarItemIds() method!
- jassert (allowedIds.contains (itemId));
- #endif
-
- items.insert (insertIndex, tc);
- addAndMakeVisible (tc, insertIndex);
- }
- }
-
- void Toolbar::addItem (ToolbarItemFactory& factory,
- const int itemId,
- const int insertIndex)
- {
- addItemInternal (factory, itemId, insertIndex);
- resized();
- }
-
- void Toolbar::addDefaultItems (ToolbarItemFactory& factoryToUse)
- {
- Array <int> ids;
- factoryToUse.getDefaultItemSet (ids);
-
- clear();
-
- for (int i = 0; i < ids.size(); ++i)
- addItemInternal (factoryToUse, ids.getUnchecked (i), -1);
-
- resized();
- }
-
- void Toolbar::removeToolbarItem (const int itemIndex)
- {
- ToolbarItemComponent* const tc = getItemComponent (itemIndex);
-
- if (tc != 0)
- {
- items.removeValue (tc);
- delete tc;
- resized();
- }
- }
-
- int Toolbar::getNumItems() const throw()
- {
- return items.size();
- }
-
- int Toolbar::getItemId (const int itemIndex) const throw()
- {
- ToolbarItemComponent* const tc = getItemComponent (itemIndex);
- return tc != 0 ? tc->getItemId() : 0;
- }
-
- ToolbarItemComponent* Toolbar::getItemComponent (const int itemIndex) const throw()
- {
- return items [itemIndex];
- }
-
- ToolbarItemComponent* Toolbar::getNextActiveComponent (int index, const int delta) const
- {
- for (;;)
- {
- index += delta;
- ToolbarItemComponent* const tc = getItemComponent (index);
-
- if (tc == 0)
- break;
-
- if (tc->isActive)
- return tc;
- }
-
- return 0;
- }
-
- void Toolbar::setStyle (const ToolbarItemStyle& newStyle)
- {
- if (toolbarStyle != newStyle)
- {
- toolbarStyle = newStyle;
- updateAllItemPositions (false);
- }
- }
-
- const String Toolbar::toString() const
- {
- String s (T("TB:"));
-
- for (int i = 0; i < getNumItems(); ++i)
- s << getItemId(i) << T(' ');
-
- return s.trimEnd();
- }
-
- bool Toolbar::restoreFromString (ToolbarItemFactory& factoryToUse,
- const String& savedVersion)
- {
- if (! savedVersion.startsWith (T("TB:")))
- return false;
-
- StringArray tokens;
- tokens.addTokens (savedVersion.substring (3), false);
-
- clear();
-
- for (int i = 0; i < tokens.size(); ++i)
- addItemInternal (factoryToUse, tokens[i].getIntValue(), -1);
-
- resized();
- return true;
- }
-
- void Toolbar::paint (Graphics& g)
- {
- getLookAndFeel().paintToolbarBackground (g, getWidth(), getHeight(), *this);
- }
-
- int Toolbar::getThickness() const throw()
- {
- return vertical ? getWidth() : getHeight();
- }
-
- int Toolbar::getLength() const throw()
- {
- return vertical ? getHeight() : getWidth();
- }
-
- void Toolbar::setEditingActive (const bool active)
- {
- if (isEditingActive != active)
- {
- isEditingActive = active;
- updateAllItemPositions (false);
- }
- }
-
- void Toolbar::resized()
- {
- updateAllItemPositions (false);
- }
-
- void Toolbar::updateAllItemPositions (const bool animate)
- {
- if (getWidth() > 0 && getHeight() > 0)
- {
- StretchableObjectResizer resizer;
-
- int i;
- for (i = 0; i < items.size(); ++i)
- {
- ToolbarItemComponent* const tc = items.getUnchecked(i);
-
- tc->setEditingMode (isEditingActive ? ToolbarItemComponent::editableOnToolbar
- : ToolbarItemComponent::normalMode);
-
- tc->setStyle (toolbarStyle);
-
- ToolbarSpacerComp* const spacer = dynamic_cast <ToolbarSpacerComp*> (tc);
-
- int preferredSize = 1, minSize = 1, maxSize = 1;
-
- if (tc->getToolbarItemSizes (getThickness(), isVertical(),
- preferredSize, minSize, maxSize))
- {
- tc->isActive = true;
- resizer.addItem (preferredSize, minSize, maxSize,
- spacer != 0 ? spacer->getResizeOrder() : 2);
- }
- else
- {
- tc->isActive = false;
- tc->setVisible (false);
- }
- }
-
- resizer.resizeToFit (getLength());
-
- int totalLength = 0;
-
- for (i = 0; i < resizer.getNumItems(); ++i)
- totalLength += (int) resizer.getItemSize (i);
-
- const bool itemsOffTheEnd = totalLength > getLength();
-
- const int extrasButtonSize = getThickness() / 2;
- missingItemsButton->setSize (extrasButtonSize, extrasButtonSize);
- missingItemsButton->setVisible (itemsOffTheEnd);
- missingItemsButton->setEnabled (! isEditingActive);
-
- if (vertical)
- missingItemsButton->setCentrePosition (getWidth() / 2,
- getHeight() - 4 - extrasButtonSize / 2);
- else
- missingItemsButton->setCentrePosition (getWidth() - 4 - extrasButtonSize / 2,
- getHeight() / 2);
-
- const int maxLength = itemsOffTheEnd ? (vertical ? missingItemsButton->getY()
- : missingItemsButton->getX()) - 4
- : getLength();
-
- int pos = 0, activeIndex = 0;
- for (i = 0; i < items.size(); ++i)
- {
- ToolbarItemComponent* const tc = items.getUnchecked(i);
-
- if (tc->isActive)
- {
- const int size = (int) resizer.getItemSize (activeIndex++);
-
- Rectangle newBounds;
- if (vertical)
- newBounds.setBounds (0, pos, getWidth(), size);
- else
- newBounds.setBounds (pos, 0, size, getHeight());
-
- if (animate)
- {
- animator.animateComponent (tc, newBounds, 200, 3.0, 0.0);
- }
- else
- {
- animator.cancelAnimation (tc, false);
- tc->setBounds (newBounds);
- }
-
- pos += size;
- tc->setVisible (pos <= maxLength
- && ((! tc->isBeingDragged)
- || tc->getEditingMode() == ToolbarItemComponent::editableOnPalette));
- }
- }
- }
- }
-
- void Toolbar::buttonClicked (Button*)
- {
- jassert (missingItemsButton->isShowing());
-
- if (missingItemsButton->isShowing())
- {
- PopupMenu m;
- m.addCustomItem (1, new MissingItemsComponent (*this, getThickness()));
- m.showAt (missingItemsButton);
- }
- }
-
- bool Toolbar::isInterestedInDragSource (const String& sourceDescription,
- Component* /*sourceComponent*/)
- {
- return sourceDescription == toolbarDragDescriptor && isEditingActive;
- }
-
- void Toolbar::itemDragMove (const String&, Component* sourceComponent, int x, int y)
- {
- ToolbarItemComponent* const tc = dynamic_cast <ToolbarItemComponent*> (sourceComponent);
-
- if (tc != 0)
- {
- if (getNumItems() == 0)
- {
- if (tc->getEditingMode() == ToolbarItemComponent::editableOnPalette)
- {
- ToolbarItemPalette* const palette = tc->findParentComponentOfClass ((ToolbarItemPalette*) 0);
-
- if (palette != 0)
- palette->replaceComponent (tc);
- }
- else
- {
- jassert (tc->getEditingMode() == ToolbarItemComponent::editableOnToolbar);
- }
-
- items.add (tc);
- addChildComponent (tc);
- updateAllItemPositions (false);
- }
- else
- {
- for (int i = getNumItems(); --i >= 0;)
- {
- int currentIndex = getIndexOfChildComponent (tc);
-
- if (currentIndex < 0)
- {
- if (tc->getEditingMode() == ToolbarItemComponent::editableOnPalette)
- {
- ToolbarItemPalette* const palette = tc->findParentComponentOfClass ((ToolbarItemPalette*) 0);
-
- if (palette != 0)
- palette->replaceComponent (tc);
- }
- else
- {
- jassert (tc->getEditingMode() == ToolbarItemComponent::editableOnToolbar);
- }
-
- items.add (tc);
- addChildComponent (tc);
- currentIndex = getIndexOfChildComponent (tc);
- updateAllItemPositions (true);
- }
-
- int newIndex = currentIndex;
-
- const int dragObjectLeft = vertical ? (y - tc->dragOffsetY) : (x - tc->dragOffsetX);
- const int dragObjectRight = dragObjectLeft + (vertical ? tc->getHeight() : tc->getWidth());
-
- const Rectangle current (animator.getComponentDestination (getChildComponent (newIndex)));
- ToolbarItemComponent* const prev = getNextActiveComponent (newIndex, -1);
-
- if (prev != 0)
- {
- const Rectangle previousPos (animator.getComponentDestination (prev));
-
- if (abs (dragObjectLeft - (vertical ? previousPos.getY() : previousPos.getX())
- < abs (dragObjectRight - (vertical ? current.getBottom() : current.getRight()))))
- {
- newIndex = getIndexOfChildComponent (prev);
- }
- }
-
- ToolbarItemComponent* const next = getNextActiveComponent (newIndex, 1);
- if (next != 0)
- {
- const Rectangle nextPos (animator.getComponentDestination (next));
-
- if (abs (dragObjectLeft - (vertical ? current.getY() : current.getX())
- > abs (dragObjectRight - (vertical ? nextPos.getBottom() : nextPos.getRight()))))
- {
- newIndex = getIndexOfChildComponent (next) + 1;
- }
- }
-
- if (newIndex != currentIndex)
- {
- items.removeValue (tc);
- removeChildComponent (tc);
- addChildComponent (tc, newIndex);
- items.insert (newIndex, tc);
- updateAllItemPositions (true);
- }
- else
- {
- break;
- }
- }
- }
- }
- }
-
- void Toolbar::itemDragExit (const String&, Component* sourceComponent)
- {
- ToolbarItemComponent* const tc = dynamic_cast <ToolbarItemComponent*> (sourceComponent);
-
- if (tc != 0)
- {
- if (isParentOf (tc))
- {
- items.removeValue (tc);
- removeChildComponent (tc);
- updateAllItemPositions (true);
- }
- }
- }
-
- void Toolbar::itemDropped (const String&, Component*, int, int)
- {
- }
-
- void Toolbar::mouseDown (const MouseEvent& e)
- {
- if (e.mods.isPopupMenu())
- {
- }
- }
-
- class ToolbarCustomisationDialog : public DialogWindow
- {
- public:
- ToolbarCustomisationDialog (ToolbarItemFactory& factory,
- Toolbar* const toolbar_,
- const int optionFlags)
- : DialogWindow (TRANS("Add/remove items from toolbar"), Colours::white, true, true),
- toolbar (toolbar_)
- {
- setContentComponent (new CustomiserPanel (factory, toolbar, optionFlags), true, true);
- setResizable (true, true);
- setResizeLimits (400, 300, 1500, 1000);
- positionNearBar();
- }
-
- ~ToolbarCustomisationDialog()
- {
- setContentComponent (0, true);
- }
-
- void closeButtonPressed()
- {
- setVisible (false);
- }
-
- bool canModalEventBeSentToComponent (const Component* comp)
- {
- return toolbar->isParentOf (comp);
- }
-
- void positionNearBar()
- {
- const Rectangle screenSize (toolbar->getParentMonitorArea());
- const int tbx = toolbar->getScreenX();
- const int tby = toolbar->getScreenY();
- const int gap = 8;
-
- int x, y;
-
- if (toolbar->isVertical())
- {
- y = tby;
-
- if (tbx > screenSize.getCentreX())
- x = tbx - getWidth() - gap;
- else
- x = tbx + toolbar->getWidth() + gap;
- }
- else
- {
- x = tbx + (toolbar->getWidth() - getWidth()) / 2;
-
- if (tby > screenSize.getCentreY())
- y = tby - getHeight() - gap;
- else
- y = tby + toolbar->getHeight() + gap;
- }
-
- setTopLeftPosition (x, y);
- }
-
- private:
- Toolbar* const toolbar;
-
- class CustomiserPanel : public Component,
- private ComboBoxListener,
- private ButtonListener
- {
- public:
- CustomiserPanel (ToolbarItemFactory& factory_,
- Toolbar* const toolbar_,
- const int optionFlags)
- : factory (factory_),
- toolbar (toolbar_),
- styleBox (0),
- defaultButton (0)
- {
- addAndMakeVisible (palette = new ToolbarItemPalette (factory, toolbar));
-
- if ((optionFlags & (Toolbar::allowIconsOnlyChoice
- | Toolbar::allowIconsWithTextChoice
- | Toolbar::allowTextOnlyChoice)) != 0)
- {
- addAndMakeVisible (styleBox = new ComboBox (String::empty));
- styleBox->setEditableText (false);
-
- if ((optionFlags & Toolbar::allowIconsOnlyChoice) != 0)
- styleBox->addItem (TRANS("Show icons only"), 1);
- if ((optionFlags & Toolbar::allowIconsWithTextChoice) != 0)
- styleBox->addItem (TRANS("Show icons and descriptions"), 2);
- if ((optionFlags & Toolbar::allowTextOnlyChoice) != 0)
- styleBox->addItem (TRANS("Show descriptions only"), 3);
-
- if (toolbar_->getStyle() == Toolbar::iconsOnly)
- styleBox->setSelectedId (1);
- else if (toolbar_->getStyle() == Toolbar::iconsWithText)
- styleBox->setSelectedId (2);
- else if (toolbar_->getStyle() == Toolbar::textOnly)
- styleBox->setSelectedId (3);
-
- styleBox->addListener (this);
- }
-
- if ((optionFlags & Toolbar::showResetToDefaultsButton) != 0)
- {
- addAndMakeVisible (defaultButton = new TextButton (TRANS ("Restore to default set of items")));
- defaultButton->addButtonListener (this);
- }
-
- addAndMakeVisible (instructions = new Label (String::empty,
- TRANS ("You can drag the items above and drop them onto a toolbar to add them.\n\nItems on the toolbar can also be dragged around to change their order, or dragged off the edge to delete them.")));
- instructions->setFont (Font (13.0f));
-
- setSize (500, 300);
- }
-
- ~CustomiserPanel()
- {
- deleteAllChildren();
- }
-
- void comboBoxChanged (ComboBox*)
- {
- if (styleBox->getSelectedId() == 1)
- toolbar->setStyle (Toolbar::iconsOnly);
- else if (styleBox->getSelectedId() == 2)
- toolbar->setStyle (Toolbar::iconsWithText);
- else if (styleBox->getSelectedId() == 3)
- toolbar->setStyle (Toolbar::textOnly);
-
- palette->resized(); // to make it update the styles
- }
-
- void buttonClicked (Button*)
- {
- toolbar->addDefaultItems (factory);
- }
-
- void paint (Graphics& g)
- {
- Colour background;
-
- DialogWindow* const dw = findParentComponentOfClass ((DialogWindow*) 0);
-
- if (dw != 0)
- background = dw->getBackgroundColour();
-
- g.setColour (background.contrasting().withAlpha (0.3f));
- g.fillRect (palette->getX(), palette->getBottom() - 1, palette->getWidth(), 1);
- }
-
- void resized()
- {
- palette->setBounds (0, 0, getWidth(), getHeight() - 120);
-
- if (styleBox != 0)
- styleBox->setBounds (10, getHeight() - 110, 200, 22);
-
- if (defaultButton != 0)
- {
- defaultButton->changeWidthToFitText (22);
- defaultButton->setTopLeftPosition (240, getHeight() - 110);
- }
-
- instructions->setBounds (10, getHeight() - 80, getWidth() - 20, 80);
- }
-
- private:
- ToolbarItemFactory& factory;
- Toolbar* const toolbar;
-
- Label* instructions;
- ToolbarItemPalette* palette;
- ComboBox* styleBox;
- TextButton* defaultButton;
- };
- };
-
- void Toolbar::showCustomisationDialog (ToolbarItemFactory& factory, const int optionFlags)
- {
- setEditingActive (true);
-
- ToolbarCustomisationDialog dw (factory, this, optionFlags);
- dw.runModalLoop();
-
- jassert (isValidComponent()); // ? deleting the toolbar while it's being edited?
- setEditingActive (false);
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_Toolbar.cpp *********/
-
- /********* Start of inlined file: juce_ToolbarItemComponent.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- ToolbarItemFactory::ToolbarItemFactory()
- {
- }
-
- ToolbarItemFactory::~ToolbarItemFactory()
- {
- }
-
- class ItemDragAndDropOverlayComponent : public Component
- {
- public:
- ItemDragAndDropOverlayComponent()
- : isDragging (false)
- {
- setAlwaysOnTop (true);
- setRepaintsOnMouseActivity (true);
- setMouseCursor (MouseCursor::DraggingHandCursor);
- }
-
- ~ItemDragAndDropOverlayComponent()
- {
- }
-
- void paint (Graphics& g)
- {
- ToolbarItemComponent* const tc = dynamic_cast <ToolbarItemComponent*> (getParentComponent());
-
- if (isMouseOverOrDragging()
- && tc != 0
- && tc->getEditingMode() == ToolbarItemComponent::editableOnToolbar)
- {
- g.setColour (findColour (Toolbar::editingModeOutlineColourId, true));
- g.drawRect (0, 0, getWidth(), getHeight(),
- jmin (2, (getWidth() - 1) / 2, (getHeight() - 1) / 2));
- }
- }
-
- void mouseDown (const MouseEvent& e)
- {
- isDragging = false;
- ToolbarItemComponent* const tc = dynamic_cast <ToolbarItemComponent*> (getParentComponent());
-
- if (tc != 0)
- {
- tc->dragOffsetX = e.x;
- tc->dragOffsetY = e.y;
- }
- }
-
- void mouseDrag (const MouseEvent& e)
- {
- if (! (isDragging || e.mouseWasClicked()))
- {
- isDragging = true;
- DragAndDropContainer* const dnd = DragAndDropContainer::findParentDragContainerFor (this);
-
- if (dnd != 0)
- {
- dnd->startDragging (Toolbar::toolbarDragDescriptor, getParentComponent(), 0, true);
-
- ToolbarItemComponent* const tc = dynamic_cast <ToolbarItemComponent*> (getParentComponent());
-
- if (tc != 0)
- {
- tc->isBeingDragged = true;
-
- if (tc->getEditingMode() == ToolbarItemComponent::editableOnToolbar)
- tc->setVisible (false);
- }
- }
- }
- }
-
- void mouseUp (const MouseEvent&)
- {
- isDragging = false;
- ToolbarItemComponent* const tc = dynamic_cast <ToolbarItemComponent*> (getParentComponent());
-
- if (tc != 0)
- {
- tc->isBeingDragged = false;
-
- Toolbar* const tb = tc->getToolbar();
-
- if (tb != 0)
- tb->updateAllItemPositions (true);
- else if (tc->getEditingMode() == ToolbarItemComponent::editableOnToolbar)
- delete tc;
- }
- }
-
- void parentSizeChanged()
- {
- setBounds (0, 0, getParentWidth(), getParentHeight());
- }
-
- juce_UseDebuggingNewOperator
-
- private:
- bool isDragging;
-
- ItemDragAndDropOverlayComponent (const ItemDragAndDropOverlayComponent&);
- const ItemDragAndDropOverlayComponent& operator= (const ItemDragAndDropOverlayComponent&);
- };
-
- ToolbarItemComponent::ToolbarItemComponent (const int itemId_,
- const String& labelText,
- const bool isBeingUsedAsAButton_)
- : Button (labelText),
- itemId (itemId_),
- mode (normalMode),
- toolbarStyle (Toolbar::iconsOnly),
- overlayComp (0),
- dragOffsetX (0),
- dragOffsetY (0),
- isActive (true),
- isBeingDragged (false),
- isBeingUsedAsAButton (isBeingUsedAsAButton_)
- {
- // Your item ID can't be 0!
- jassert (itemId_ != 0);
- }
-
- ToolbarItemComponent::~ToolbarItemComponent()
- {
- jassert (overlayComp == 0 || overlayComp->isValidComponent());
- delete overlayComp;
- }
-
- Toolbar* ToolbarItemComponent::getToolbar() const
- {
- return dynamic_cast <Toolbar*> (getParentComponent());
- }
-
- bool ToolbarItemComponent::isToolbarVertical() const
- {
- const Toolbar* const t = getToolbar();
- return t != 0 && t->isVertical();
- }
-
- void ToolbarItemComponent::setStyle (const Toolbar::ToolbarItemStyle& newStyle)
- {
- if (toolbarStyle != newStyle)
- {
- toolbarStyle = newStyle;
- repaint();
- resized();
- }
- }
-
- void ToolbarItemComponent::paintButton (Graphics& g, bool isMouseOver, bool isMouseDown)
- {
- if (isBeingUsedAsAButton)
- getLookAndFeel().paintToolbarButtonBackground (g, getWidth(), getHeight(),
- isMouseOver, isMouseDown, *this);
-
- if (toolbarStyle != Toolbar::iconsOnly)
- {
- const int indent = contentArea.getX();
- int y = indent;
- int h = getHeight() - indent * 2;
-
- if (toolbarStyle == Toolbar::iconsWithText)
- {
- y = contentArea.getBottom() + indent / 2;
- h -= contentArea.getHeight();
- }
-
- getLookAndFeel().paintToolbarButtonLabel (g, indent, y, getWidth() - indent * 2, h,
- getButtonText(), *this);
- }
-
- if (! contentArea.isEmpty())
- {
- g.saveState();
- g.setOrigin (contentArea.getX(), contentArea.getY());
- g.reduceClipRegion (0, 0, contentArea.getWidth(), contentArea.getHeight());
-
- paintButtonArea (g, contentArea.getWidth(), contentArea.getHeight(), isMouseOver, isMouseDown);
-
- g.restoreState();
- }
- }
-
- void ToolbarItemComponent::resized()
- {
- if (toolbarStyle != Toolbar::textOnly)
- {
- const int indent = jmin (proportionOfWidth (0.08f),
- proportionOfHeight (0.08f));
-
- contentArea = Rectangle (indent, indent,
- getWidth() - indent * 2,
- toolbarStyle == Toolbar::iconsWithText ? proportionOfHeight (0.55f)
- : (getHeight() - indent * 2));
- }
- else
- {
- contentArea = Rectangle();
- }
-
- contentAreaChanged (contentArea);
- }
-
- void ToolbarItemComponent::setEditingMode (const ToolbarEditingMode newMode)
- {
- if (mode != newMode)
- {
- mode = newMode;
- repaint();
-
- if (mode == normalMode)
- {
- jassert (overlayComp == 0 || overlayComp->isValidComponent());
- delete overlayComp;
- overlayComp = 0;
- }
- else if (overlayComp == 0)
- {
- addAndMakeVisible (overlayComp = new ItemDragAndDropOverlayComponent());
- overlayComp->parentSizeChanged();
- }
-
- resized();
- }
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_ToolbarItemComponent.cpp *********/
-
- /********* Start of inlined file: juce_ToolbarItemPalette.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- ToolbarItemPalette::ToolbarItemPalette (ToolbarItemFactory& factory_,
- Toolbar* const toolbar_)
- : factory (factory_),
- toolbar (toolbar_)
- {
- Component* const itemHolder = new Component();
-
- Array <int> allIds;
- factory_.getAllToolbarItemIds (allIds);
-
- for (int i = 0; i < allIds.size(); ++i)
- {
- ToolbarItemComponent* const tc = Toolbar::createItem (factory_, allIds.getUnchecked (i));
-
- jassert (tc != 0);
- if (tc != 0)
- {
- itemHolder->addAndMakeVisible (tc);
- tc->setEditingMode (ToolbarItemComponent::editableOnPalette);
- }
- }
-
- viewport = new Viewport();
- viewport->setViewedComponent (itemHolder);
- addAndMakeVisible (viewport);
- }
-
- ToolbarItemPalette::~ToolbarItemPalette()
- {
- viewport->getViewedComponent()->deleteAllChildren();
- deleteAllChildren();
- }
-
- void ToolbarItemPalette::resized()
- {
- viewport->setBoundsInset (BorderSize (1));
-
- Component* const itemHolder = viewport->getViewedComponent();
-
- const int indent = 8;
- const int preferredWidth = viewport->getWidth() - viewport->getScrollBarThickness() - indent;
- const int height = toolbar->getThickness();
- int x = indent;
- int y = indent;
- int maxX = 0;
-
- for (int i = 0; i < itemHolder->getNumChildComponents(); ++i)
- {
- ToolbarItemComponent* const tc = dynamic_cast <ToolbarItemComponent*> (itemHolder->getChildComponent (i));
-
- if (tc != 0)
- {
- tc->setStyle (toolbar->getStyle());
-
- int preferredSize = 1, minSize = 1, maxSize = 1;
-
- if (tc->getToolbarItemSizes (height, false, preferredSize, minSize, maxSize))
- {
- if (x + preferredSize > preferredWidth && x > indent)
- {
- x = indent;
- y += height;
- }
-
- tc->setBounds (x, y, preferredSize, height);
-
- x += preferredSize + 8;
- maxX = jmax (maxX, x);
- }
- }
- }
-
- itemHolder->setSize (maxX, y + height + 8);
- }
-
- void ToolbarItemPalette::replaceComponent (ToolbarItemComponent* const comp)
- {
- ToolbarItemComponent* const tc = Toolbar::createItem (factory, comp->getItemId());
-
- jassert (tc != 0);
-
- if (tc != 0)
- {
- tc->setBounds (comp->getBounds());
- tc->setStyle (toolbar->getStyle());
- tc->setEditingMode (comp->getEditingMode());
- viewport->getViewedComponent()->addAndMakeVisible (tc, getIndexOfChildComponent (comp));
- }
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_ToolbarItemPalette.cpp *********/
-
- /********* Start of inlined file: juce_TreeView.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- class TreeViewContentComponent : public Component
- {
- public:
- TreeViewContentComponent (TreeView* const owner_)
- : owner (owner_),
- isDragging (false)
- {
- }
-
- ~TreeViewContentComponent()
- {
- deleteAllChildren();
- }
-
- void mouseDown (const MouseEvent& e)
- {
- isDragging = false;
- needSelectionOnMouseUp = false;
-
- Rectangle pos;
- TreeViewItem* const item = findItemAt (e.y, pos);
-
- if (item != 0 && e.x >= pos.getX())
- {
- if (! owner->isMultiSelectEnabled())
- item->setSelected (true, true);
- else if (item->isSelected())
- needSelectionOnMouseUp = ! e.mods.isPopupMenu();
- else
- selectBasedOnModifiers (item, e.mods);
-
- MouseEvent e2 (e);
- e2.x -= pos.getX();
- e2.y -= pos.getY();
- item->itemClicked (e2);
- }
- }
-
- void mouseUp (const MouseEvent& e)
- {
- Rectangle pos;
- TreeViewItem* const item = findItemAt (e.y, pos);
-
- if (item != 0 && e.mouseWasClicked())
- {
- if (needSelectionOnMouseUp)
- {
- selectBasedOnModifiers (item, e.mods);
- }
- else if (e.mouseWasClicked())
- {
- if (e.x >= pos.getX() - owner->getIndentSize()
- && e.x < pos.getX())
- {
- item->setOpen (! item->isOpen());
- }
- }
- }
- }
-
- void mouseDoubleClick (const MouseEvent& e)
- {
- if (e.getNumberOfClicks() != 3) // ignore triple clicks
- {
- Rectangle pos;
- TreeViewItem* const item = findItemAt (e.y, pos);
-
- if (item != 0 && e.x >= pos.getX())
- {
- MouseEvent e2 (e);
- e2.x -= pos.getX();
- e2.y -= pos.getY();
- item->itemDoubleClicked (e2);
- }
- }
- }
-
- void mouseDrag (const MouseEvent& e)
- {
- if (isEnabled() && ! (e.mouseWasClicked() || isDragging))
- {
- isDragging = true;
-
- Rectangle pos;
- TreeViewItem* const item = findItemAt (e.getMouseDownY(), pos);
-
- if (item != 0 && e.getMouseDownX() >= pos.getX())
- {
- const String dragDescription (item->getDragSourceDescription());
-
- if (dragDescription.isNotEmpty())
- {
- DragAndDropContainer* const dragContainer
- = DragAndDropContainer::findParentDragContainerFor (this);
-
- if (dragContainer != 0)
- {
- pos.setSize (pos.getWidth(), item->itemHeight);
- Image* dragImage = Component::createComponentSnapshot (pos, true);
- dragImage->multiplyAllAlphas (0.6f);
-
- dragContainer->startDragging (dragDescription, owner, dragImage, true);
- }
- else
- {
- // to be able to do a drag-and-drop operation, the treeview needs to
- // be inside a component which is also a DragAndDropContainer.
- jassertfalse
- }
- }
- }
- }
- }
-
- void paint (Graphics& g);
- TreeViewItem* findItemAt (int y, Rectangle& itemPosition) const;
-
- void updateComponents()
- {
- int xAdjust = 0, yAdjust = 0;
-
- if ((! owner->rootItemVisible) && owner->rootItem != 0)
- {
- yAdjust = owner->rootItem->itemHeight;
- xAdjust = owner->getIndentSize();
- }
-
- const int visibleTop = -getY();
- const int visibleBottom = visibleTop + getParentHeight();
-
- BitArray itemsToKeep;
- TreeViewItem* item = owner->rootItem;
- int y = -yAdjust;
-
- while (item != 0 && y < visibleBottom)
- {
- y += item->itemHeight;
-
- if (y >= visibleTop)
- {
- const int index = rowComponentIds.indexOf (item->uid);
-
- if (index < 0)
- {
- Component* const comp = item->createItemComponent();
-
- if (comp != 0)
- {
- addAndMakeVisible (comp);
- itemsToKeep.setBit (rowComponentItems.size());
- rowComponentItems.add (item);
- rowComponentIds.add (item->uid);
- rowComponents.add (comp);
- }
- }
- else
- {
- itemsToKeep.setBit (index);
- }
- }
-
- item = item->getNextVisibleItem (true);
- }
-
- for (int i = rowComponentItems.size(); --i >= 0;)
- {
- Component* const comp = (Component*) (rowComponents.getUnchecked(i));
-
- bool keep = false;
-
- if ((itemsToKeep[i] || (comp == Component::getComponentUnderMouse() && comp->isMouseButtonDown()))
- && isParentOf (comp))
- {
- if (itemsToKeep[i])
- {
- const TreeViewItem* const item = (TreeViewItem*) rowComponentItems.getUnchecked(i);
-
- Rectangle pos (item->getItemPosition (false));
- pos.translate (-xAdjust, -yAdjust);
- pos.setSize (pos.getWidth() + xAdjust, item->itemHeight);
-
- if (pos.getBottom() >= visibleTop && pos.getY() < visibleBottom)
- {
- keep = true;
- comp->setBounds (pos);
- }
- }
- else
- {
- comp->setSize (0, 0);
- }
- }
-
- if (! keep)
- {
- delete comp;
- rowComponents.remove (i);
- rowComponentIds.remove (i);
- rowComponentItems.remove (i);
- }
- }
- }
-
- void resized()
- {
- owner->itemsChanged();
- }
-
- juce_UseDebuggingNewOperator
-
- private:
- TreeView* const owner;
-
- VoidArray rowComponentItems;
- Array <int> rowComponentIds;
- VoidArray rowComponents;
- bool isDragging, needSelectionOnMouseUp;
-
- TreeViewContentComponent (const TreeViewContentComponent&);
- const TreeViewContentComponent& operator= (const TreeViewContentComponent&);
-
- void selectBasedOnModifiers (TreeViewItem* const item, const ModifierKeys& modifiers)
- {
- TreeViewItem* firstSelected = 0;
-
- if (modifiers.isShiftDown() && ((firstSelected = owner->getSelectedItem (0)) != 0))
- {
- TreeViewItem* const lastSelected = owner->getSelectedItem (owner->getNumSelectedItems() - 1);
- jassert (lastSelected != 0);
-
- int rowStart = firstSelected->getRowNumberInTree();
- int rowEnd = lastSelected->getRowNumberInTree();
- if (rowStart > rowEnd)
- swapVariables (rowStart, rowEnd);
-
- int ourRow = item->getRowNumberInTree();
- int otherEnd = ourRow < rowEnd ? rowStart : rowEnd;
-
- if (ourRow > otherEnd)
- swapVariables (ourRow, otherEnd);
-
- for (int i = ourRow; i <= otherEnd; ++i)
- owner->getItemOnRow (i)->setSelected (true, false);
- }
- else
- {
- const bool cmd = modifiers.isCommandDown();
-
- item->setSelected ((! cmd) || (! item->isSelected()), ! cmd);
- }
- }
- };
-
- class TreeViewport : public Viewport
- {
- public:
- TreeViewport() throw() {}
- ~TreeViewport() throw() {}
-
- void updateComponents()
- {
- if (getViewedComponent() != 0)
- ((TreeViewContentComponent*) getViewedComponent())->updateComponents();
-
- repaint();
- }
-
- void visibleAreaChanged (int, int, int, int)
- {
- updateComponents();
- }
-
- juce_UseDebuggingNewOperator
-
- private:
- TreeViewport (const TreeViewport&);
- const TreeViewport& operator= (const TreeViewport&);
- };
-
- TreeView::TreeView (const String& componentName)
- : Component (componentName),
- rootItem (0),
- indentSize (24),
- defaultOpenness (false),
- needsRecalculating (true),
- rootItemVisible (true),
- multiSelectEnabled (false)
- {
- addAndMakeVisible (viewport = new TreeViewport());
- viewport->setViewedComponent (new TreeViewContentComponent (this));
- viewport->setWantsKeyboardFocus (false);
- setWantsKeyboardFocus (true);
- }
-
- TreeView::~TreeView()
- {
- if (rootItem != 0)
- rootItem->setOwnerView (0);
-
- deleteAllChildren();
- }
-
- void TreeView::setRootItem (TreeViewItem* const newRootItem)
- {
- if (rootItem != newRootItem)
- {
- if (newRootItem != 0)
- {
- jassert (newRootItem->ownerView == 0); // can't use a tree item in more than one tree at once..
-
- if (newRootItem->ownerView != 0)
- newRootItem->ownerView->setRootItem (0);
- }
-
- if (rootItem != 0)
- rootItem->setOwnerView (0);
-
- rootItem = newRootItem;
-
- if (newRootItem != 0)
- newRootItem->setOwnerView (this);
-
- needsRecalculating = true;
- handleAsyncUpdate();
-
- if (rootItem != 0 && (defaultOpenness || ! rootItemVisible))
- {
- rootItem->setOpen (false); // force a re-open
- rootItem->setOpen (true);
- }
- }
- }
-
- void TreeView::setRootItemVisible (const bool shouldBeVisible)
- {
- rootItemVisible = shouldBeVisible;
-
- if (rootItem != 0 && (defaultOpenness || ! rootItemVisible))
- {
- rootItem->setOpen (false); // force a re-open
- rootItem->setOpen (true);
- }
-
- itemsChanged();
- }
-
- void TreeView::colourChanged()
- {
- setOpaque (findColour (backgroundColourId).isOpaque());
- repaint();
- }
-
- void TreeView::setIndentSize (const int newIndentSize)
- {
- if (indentSize != newIndentSize)
- {
- indentSize = newIndentSize;
- resized();
- }
- }
-
- void TreeView::setDefaultOpenness (const bool isOpenByDefault)
- {
- if (defaultOpenness != isOpenByDefault)
- {
- defaultOpenness = isOpenByDefault;
- itemsChanged();
- }
- }
-
- void TreeView::setMultiSelectEnabled (const bool canMultiSelect)
- {
- multiSelectEnabled = canMultiSelect;
- }
-
- void TreeView::clearSelectedItems()
- {
- if (rootItem != 0)
- rootItem->deselectAllRecursively();
- }
-
- int TreeView::getNumSelectedItems() const throw()
- {
- return (rootItem != 0) ? rootItem->countSelectedItemsRecursively() : 0;
- }
-
- TreeViewItem* TreeView::getSelectedItem (const int index) const throw()
- {
- return (rootItem != 0) ? rootItem->getSelectedItemWithIndex (index) : 0;
- }
-
- int TreeView::getNumRowsInTree() const
- {
- if (rootItem != 0)
- return rootItem->getNumRows() - (rootItemVisible ? 0 : 1);
-
- return 0;
- }
-
- TreeViewItem* TreeView::getItemOnRow (int index) const
- {
- if (! rootItemVisible)
- ++index;
-
- if (rootItem != 0 && index >= 0)
- return rootItem->getItemOnRow (index);
-
- return 0;
- }
-
- XmlElement* TreeView::getOpennessState (const bool alsoIncludeScrollPosition) const
- {
- XmlElement* e = 0;
-
- if (rootItem != 0)
- {
- e = rootItem->createXmlOpenness();
-
- if (e != 0 && alsoIncludeScrollPosition)
- e->setAttribute (T("scrollPos"), viewport->getViewPositionY());
- }
-
- return e;
- }
-
- void TreeView::restoreOpennessState (const XmlElement& newState)
- {
- if (rootItem != 0)
- {
- rootItem->restoreFromXml (newState);
-
- if (newState.hasAttribute (T("scrollPos")))
- viewport->setViewPosition (viewport->getViewPositionX(),
- newState.getIntAttribute (T("scrollPos")));
- }
- }
-
- void TreeView::paint (Graphics& g)
- {
- g.fillAll (findColour (backgroundColourId));
- }
-
- void TreeView::resized()
- {
- viewport->setBounds (0, 0, getWidth(), getHeight());
- itemsChanged();
- }
-
- void TreeView::moveSelectedRow (int delta)
- {
- int rowSelected = 0;
-
- TreeViewItem* const firstSelected = getSelectedItem (0);
- if (firstSelected != 0)
- rowSelected = firstSelected->getRowNumberInTree();
-
- rowSelected = jlimit (0, getNumRowsInTree() - 1, rowSelected + delta);
-
- TreeViewItem* item = getItemOnRow (rowSelected);
-
- if (item != 0)
- {
- item->setSelected (true, true);
-
- scrollToKeepItemVisible (item);
- }
- }
-
- void TreeView::scrollToKeepItemVisible (TreeViewItem* item)
- {
- if (item != 0 && item->ownerView == this)
- {
- handleAsyncUpdate();
-
- item = item->getDeepestOpenParentItem();
-
- int y = item->y;
- if (! rootItemVisible)
- y -= rootItem->itemHeight;
-
- int viewTop = viewport->getViewPositionY();
-
- if (y < viewTop)
- {
- viewport->setViewPosition (viewport->getViewPositionX(), y);
- }
- else if (y + item->itemHeight > viewTop + viewport->getViewHeight())
- {
- viewport->setViewPosition (viewport->getViewPositionX(),
- (y + item->itemHeight) - viewport->getViewHeight());
- }
- }
- }
-
- bool TreeView::keyPressed (const KeyPress& key)
- {
- if (key.isKeyCode (KeyPress::upKey))
- {
- moveSelectedRow (-1);
- }
- else if (key.isKeyCode (KeyPress::downKey))
- {
- moveSelectedRow (1);
- }
- else if (key.isKeyCode (KeyPress::pageDownKey) || key.isKeyCode (KeyPress::pageUpKey))
- {
- if (rootItem != 0)
- {
- int rowsOnScreen = getHeight() / jmax (1, rootItem->itemHeight);
-
- if (key.isKeyCode (KeyPress::pageUpKey))
- rowsOnScreen = -rowsOnScreen;
-
- moveSelectedRow (rowsOnScreen);
- }
- }
- else if (key.isKeyCode (KeyPress::homeKey))
- {
- moveSelectedRow (-0x3fffffff);
- }
- else if (key.isKeyCode (KeyPress::endKey))
- {
- moveSelectedRow (0x3fffffff);
- }
- else if (key.isKeyCode (KeyPress::returnKey))
- {
- TreeViewItem* const firstSelected = getSelectedItem (0);
- if (firstSelected != 0)
- firstSelected->setOpen (! firstSelected->isOpen());
- }
- else if (key.isKeyCode (KeyPress::leftKey))
- {
- TreeViewItem* const firstSelected = getSelectedItem (0);
-
- if (firstSelected != 0)
- {
- if (firstSelected->isOpen())
- {
- firstSelected->setOpen (false);
- }
- else
- {
- TreeViewItem* parent = firstSelected->parentItem;
-
- if ((! rootItemVisible) && parent == rootItem)
- parent = 0;
-
- if (parent != 0)
- {
- parent->setSelected (true, true);
- scrollToKeepItemVisible (parent);
- }
- }
- }
- }
- else if (key.isKeyCode (KeyPress::rightKey))
- {
- TreeViewItem* const firstSelected = getSelectedItem (0);
-
- if (firstSelected != 0)
- {
- if (firstSelected->isOpen() || ! firstSelected->mightContainSubItems())
- moveSelectedRow (1);
- else
- firstSelected->setOpen (true);
- }
- }
- else
- {
- return false;
- }
-
- return true;
- }
-
- void TreeView::itemsChanged() throw()
- {
- needsRecalculating = true;
- repaint();
- triggerAsyncUpdate();
- }
-
- void TreeView::handleAsyncUpdate()
- {
- if (needsRecalculating)
- {
- needsRecalculating = false;
-
- const ScopedLock sl (nodeAlterationLock);
-
- if (rootItem != 0)
- rootItem->updatePositions (0);
-
- ((TreeViewport*) viewport)->updateComponents();
-
- if (rootItem != 0)
- {
- viewport->getViewedComponent()
- ->setSize (jmax (viewport->getMaximumVisibleWidth(), rootItem->totalWidth),
- rootItem->totalHeight - (rootItemVisible ? 0 : rootItem->itemHeight));
- }
- else
- {
- viewport->getViewedComponent()->setSize (0, 0);
- }
- }
- }
-
- void TreeViewContentComponent::paint (Graphics& g)
- {
- if (owner->rootItem != 0)
- {
- owner->handleAsyncUpdate();
-
- int w = getWidth();
-
- if (! owner->rootItemVisible)
- {
- const int indentWidth = owner->getIndentSize();
-
- g.setOrigin (-indentWidth, -owner->rootItem->itemHeight);
- w += indentWidth;
- }
-
- owner->rootItem->paintRecursively (g, w);
- }
- }
-
- TreeViewItem* TreeViewContentComponent::findItemAt (int y, Rectangle& itemPosition) const
- {
- if (owner->rootItem != 0)
- {
- owner->handleAsyncUpdate();
-
- if (! owner->rootItemVisible)
- y += owner->rootItem->itemHeight;
-
- TreeViewItem* const ti = owner->rootItem->findItemRecursively (y);
-
- if (ti != 0)
- {
- itemPosition = ti->getItemPosition (false);
-
- if (! owner->rootItemVisible)
- itemPosition.translate (-owner->getIndentSize(),
- -owner->rootItem->itemHeight);
- }
-
- return ti;
- }
-
- return 0;
- }
-
- #define opennessDefault 0
- #define opennessClosed 1
- #define opennessOpen 2
-
- TreeViewItem::TreeViewItem()
- : ownerView (0),
- parentItem (0),
- subItems (8),
- y (0),
- itemHeight (0),
- totalHeight (0),
- selected (false),
- redrawNeeded (true),
- drawLinesInside (true),
- openness (opennessDefault)
- {
- static int nextUID = 0;
- uid = nextUID++;
- }
-
- TreeViewItem::~TreeViewItem()
- {
- }
-
- const String TreeViewItem::getUniqueName() const
- {
- return String::empty;
- }
-
- void TreeViewItem::itemOpennessChanged (bool)
- {
- }
-
- int TreeViewItem::getNumSubItems() const throw()
- {
- return subItems.size();
- }
-
- TreeViewItem* TreeViewItem::getSubItem (const int index) const throw()
- {
- return subItems [index];
- }
-
- void TreeViewItem::clearSubItems()
- {
- if (subItems.size() > 0)
- {
- if (ownerView != 0)
- {
- const ScopedLock sl (ownerView->nodeAlterationLock);
- subItems.clear();
- treeHasChanged();
- }
- else
- {
- subItems.clear();
- }
- }
- }
-
- void TreeViewItem::addSubItem (TreeViewItem* const newItem, const int insertPosition)
- {
- if (newItem != 0)
- {
- newItem->parentItem = this;
- newItem->setOwnerView (ownerView);
- newItem->y = 0;
- newItem->itemHeight = newItem->getItemHeight();
- newItem->totalHeight = 0;
- newItem->itemWidth = newItem->getItemWidth();
- newItem->totalWidth = 0;
-
- if (ownerView != 0)
- {
- const ScopedLock sl (ownerView->nodeAlterationLock);
- subItems.insert (insertPosition, newItem);
- treeHasChanged();
-
- if (newItem->isOpen())
- newItem->itemOpennessChanged (true);
- }
- else
- {
- subItems.insert (insertPosition, newItem);
-
- if (newItem->isOpen())
- newItem->itemOpennessChanged (true);
- }
- }
- }
-
- void TreeViewItem::removeSubItem (const int index, const bool deleteItem)
- {
- if (ownerView != 0)
- ownerView->nodeAlterationLock.enter();
-
- if (((unsigned int) index) < (unsigned int) subItems.size())
- {
- subItems.remove (index, deleteItem);
- treeHasChanged();
- }
-
- if (ownerView != 0)
- ownerView->nodeAlterationLock.exit();
- }
-
- bool TreeViewItem::isOpen() const throw()
- {
- if (openness == opennessDefault)
- return ownerView != 0 && ownerView->defaultOpenness;
- else
- return openness == opennessOpen;
- }
-
- void TreeViewItem::setOpen (const bool shouldBeOpen)
- {
- if (isOpen() != shouldBeOpen)
- {
- openness = shouldBeOpen ? opennessOpen
- : opennessClosed;
-
- treeHasChanged();
-
- itemOpennessChanged (isOpen());
- }
- }
-
- bool TreeViewItem::isSelected() const throw()
- {
- return selected;
- }
-
- void TreeViewItem::deselectAllRecursively()
- {
- setSelected (false, false);
-
- for (int i = 0; i < subItems.size(); ++i)
- subItems.getUnchecked(i)->deselectAllRecursively();
- }
-
- void TreeViewItem::setSelected (const bool shouldBeSelected,
- const bool deselectOtherItemsFirst)
- {
- if (deselectOtherItemsFirst)
- getTopLevelItem()->deselectAllRecursively();
-
- if (shouldBeSelected != selected)
- {
- selected = shouldBeSelected;
- if (ownerView != 0)
- ownerView->repaint();
-
- itemSelectionChanged (shouldBeSelected);
- }
- }
-
- void TreeViewItem::paintItem (Graphics&, int, int)
- {
- }
-
- void TreeViewItem::itemClicked (const MouseEvent&)
- {
- }
-
- void TreeViewItem::itemDoubleClicked (const MouseEvent&)
- {
- if (mightContainSubItems())
- setOpen (! isOpen());
- }
-
- void TreeViewItem::itemSelectionChanged (bool)
- {
- }
-
- const String TreeViewItem::getDragSourceDescription()
- {
- return String::empty;
- }
-
- const Rectangle TreeViewItem::getItemPosition (const bool relativeToTreeViewTopLeft) const throw()
- {
- const int indentX = getIndentX();
-
- int width = itemWidth;
-
- if (ownerView != 0 && width < 0)
- width = ownerView->viewport->getViewWidth() - indentX;
-
- Rectangle r (indentX, y, jmax (0, width), totalHeight);
-
- if (relativeToTreeViewTopLeft)
- r.setPosition (r.getX() - ownerView->viewport->getViewPositionX(),
- r.getY() - ownerView->viewport->getViewPositionY());
-
- return r;
- }
-
- void TreeViewItem::treeHasChanged() const throw()
- {
- if (ownerView != 0)
- ownerView->itemsChanged();
- }
-
- void TreeViewItem::updatePositions (int newY)
- {
- y = newY;
- itemHeight = getItemHeight();
- totalHeight = itemHeight;
- itemWidth = getItemWidth();
- totalWidth = jmax (itemWidth, 0);
-
- if (isOpen())
- {
- const int ourIndent = getIndentX();
- newY += totalHeight;
-
- for (int i = 0; i < subItems.size(); ++i)
- {
- TreeViewItem* const ti = subItems.getUnchecked(i);
-
- ti->updatePositions (newY);
- newY += ti->totalHeight;
- totalHeight += ti->totalHeight;
- totalWidth = jmax (totalWidth, ti->totalWidth + ourIndent);
- }
- }
- }
-
- TreeViewItem* TreeViewItem::getDeepestOpenParentItem() throw()
- {
- TreeViewItem* result = this;
- TreeViewItem* item = this;
-
- while (item->parentItem != 0)
- {
- item = item->parentItem;
-
- if (! item->isOpen())
- result = item;
- }
-
- return result;
- }
-
- void TreeViewItem::setOwnerView (TreeView* const newOwner) throw()
- {
- ownerView = newOwner;
-
- for (int i = subItems.size(); --i >= 0;)
- subItems.getUnchecked(i)->setOwnerView (newOwner);
- }
-
- int TreeViewItem::getIndentX() const throw()
- {
- const int indentWidth = ownerView->getIndentSize();
- int x = indentWidth;
-
- TreeViewItem* p = parentItem;
-
- while (p != 0)
- {
- x += indentWidth;
- p = p->parentItem;
- }
-
- return x;
- }
-
- void TreeViewItem::paintRecursively (Graphics& g, int width)
- {
- jassert (ownerView != 0);
- if (ownerView == 0)
- return;
-
- const int indent = getIndentX();
- const int itemW = itemWidth < 0 ? width - indent : itemWidth;
-
- g.setColour (ownerView->findColour (TreeView::linesColourId));
-
- const float halfH = itemHeight * 0.5f;
- int depth = 0;
- TreeViewItem* p = parentItem;
-
- while (p != 0)
- {
- ++depth;
- p = p->parentItem;
- }
-
- const int indentWidth = ownerView->getIndentSize();
- float x = (depth + 0.5f) * indentWidth;
-
- if (x > 0)
- {
- if (depth >= 0)
- {
- if (parentItem != 0 && parentItem->drawLinesInside)
- g.drawLine (x, 0, x, isLastOfSiblings() ? halfH : (float) itemHeight);
-
- if ((parentItem != 0 && parentItem->drawLinesInside)
- || (parentItem == 0 && drawLinesInside))
- g.drawLine (x, halfH, x + indentWidth / 2, halfH);
- }
-
- p = parentItem;
- int d = depth;
-
- while (p != 0 && --d >= 0)
- {
- x -= (float) indentWidth;
-
- if ((p->parentItem == 0 || p->parentItem->drawLinesInside)
- && ! p->isLastOfSiblings())
- {
- g.drawLine (x, 0, x, (float) itemHeight);
- }
-
- p = p->parentItem;
- }
-
- if (mightContainSubItems())
- {
- ownerView->getLookAndFeel()
- .drawTreeviewPlusMinusBox (g,
- depth * indentWidth, 0,
- indentWidth, itemHeight,
- ! isOpen());
- }
- }
-
- {
- g.saveState();
- g.setOrigin (indent, 0);
-
- if (g.reduceClipRegion (0, 0, itemW, itemHeight))
- paintItem (g, itemW, itemHeight);
-
- g.restoreState();
- }
-
- if (isOpen())
- {
- const Rectangle clip (g.getClipBounds());
-
- for (int i = 0; i < subItems.size(); ++i)
- {
- TreeViewItem* const ti = subItems.getUnchecked(i);
-
- const int relY = ti->y - y;
-
- if (relY >= clip.getBottom())
- break;
-
- if (relY + ti->totalHeight >= clip.getY())
- {
- g.saveState();
- g.setOrigin (0, relY);
-
- if (g.reduceClipRegion (0, 0, width, ti->totalHeight))
- ti->paintRecursively (g, width);
-
- g.restoreState();
- }
- }
- }
- }
-
- bool TreeViewItem::isLastOfSiblings() const throw()
- {
- return parentItem == 0
- || parentItem->subItems.getLast() == this;
- }
-
- TreeViewItem* TreeViewItem::getTopLevelItem() throw()
- {
- return (parentItem == 0) ? this
- : parentItem->getTopLevelItem();
- }
-
- int TreeViewItem::getNumRows() const throw()
- {
- int num = 1;
-
- if (isOpen())
- {
- for (int i = subItems.size(); --i >= 0;)
- num += subItems.getUnchecked(i)->getNumRows();
- }
-
- return num;
- }
-
- TreeViewItem* TreeViewItem::getItemOnRow (int index) throw()
- {
- if (index == 0)
- return this;
-
- if (index > 0 && isOpen())
- {
- --index;
-
- for (int i = 0; i < subItems.size(); ++i)
- {
- TreeViewItem* const item = subItems.getUnchecked(i);
-
- if (index == 0)
- return item;
-
- const int numRows = item->getNumRows();
-
- if (numRows > index)
- return item->getItemOnRow (index);
-
- index -= numRows;
- }
- }
-
- return 0;
- }
-
- TreeViewItem* TreeViewItem::findItemRecursively (int y) throw()
- {
- if (((unsigned int) y) < (unsigned int) totalHeight)
- {
- const int h = itemHeight;
-
- if (y < h)
- return this;
-
- if (isOpen())
- {
- y -= h;
-
- for (int i = 0; i < subItems.size(); ++i)
- {
- TreeViewItem* const ti = subItems.getUnchecked(i);
-
- if (ti->totalHeight >= y)
- return ti->findItemRecursively (y);
-
- y -= ti->totalHeight;
- }
- }
- }
-
- return 0;
- }
-
- int TreeViewItem::countSelectedItemsRecursively() const throw()
- {
- int total = 0;
-
- if (isSelected())
- ++total;
-
- for (int i = subItems.size(); --i >= 0;)
- total += subItems.getUnchecked(i)->countSelectedItemsRecursively();
-
- return total;
- }
-
- TreeViewItem* TreeViewItem::getSelectedItemWithIndex (int index) throw()
- {
- if (isSelected())
- {
- if (index == 0)
- return this;
-
- --index;
- }
-
- if (index >= 0)
- {
- for (int i = 0; i < subItems.size(); ++i)
- {
- TreeViewItem* const item = subItems.getUnchecked(i);
-
- TreeViewItem* const found = item->getSelectedItemWithIndex (index);
-
- if (found != 0)
- return found;
-
- index -= item->countSelectedItemsRecursively();
- }
- }
-
- return 0;
- }
-
- int TreeViewItem::getRowNumberInTree() const throw()
- {
- if (parentItem != 0 && ownerView != 0)
- {
- int n = 1 + parentItem->getRowNumberInTree();
-
- int ourIndex = parentItem->subItems.indexOf (this);
- jassert (ourIndex >= 0);
-
- while (--ourIndex >= 0)
- n += parentItem->subItems [ourIndex]->getNumRows();
-
- if (parentItem->parentItem == 0
- && ! ownerView->rootItemVisible)
- --n;
-
- return n;
- }
- else
- {
- return 0;
- }
- }
-
- void TreeViewItem::setLinesDrawnForSubItems (const bool drawLines) throw()
- {
- drawLinesInside = drawLines;
- }
-
- TreeViewItem* TreeViewItem::getNextVisibleItem (const bool recurse) const throw()
- {
- if (recurse && isOpen() && subItems.size() > 0)
- return subItems [0];
-
- if (parentItem != 0)
- {
- const int nextIndex = parentItem->subItems.indexOf (this) + 1;
-
- if (nextIndex >= parentItem->subItems.size())
- return parentItem->getNextVisibleItem (false);
-
- return parentItem->subItems [nextIndex];
- }
-
- return 0;
- }
-
- void TreeViewItem::restoreFromXml (const XmlElement& e)
- {
- if (e.hasTagName (T("CLOSED")))
- {
- setOpen (false);
- }
- else if (e.hasTagName (T("OPEN")))
- {
- setOpen (true);
-
- forEachXmlChildElement (e, n)
- {
- const String id (n->getStringAttribute (T("id")));
-
- for (int i = 0; i < subItems.size(); ++i)
- {
- TreeViewItem* const ti = subItems.getUnchecked(i);
-
- if (ti->getUniqueName() == id)
- {
- ti->restoreFromXml (*n);
- break;
- }
- }
- }
- }
- }
-
- XmlElement* TreeViewItem::createXmlOpenness() const
- {
- if (openness != opennessDefault)
- {
- const String name (getUniqueName());
-
- if (name.isNotEmpty())
- {
- XmlElement* e;
-
- if (isOpen())
- {
- e = new XmlElement (T("OPEN"));
-
- for (int i = 0; i < subItems.size(); ++i)
- e->addChildElement (subItems.getUnchecked(i)->createXmlOpenness());
- }
- else
- {
- e = new XmlElement (T("CLOSED"));
- }
-
- e->setAttribute (T("id"), name);
-
- return e;
- }
- else
- {
- // trying to save the openness for an element that has no name - this won't
- // work because it needs the names to identify what to open.
- jassertfalse
- }
- }
-
- return 0;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_TreeView.cpp *********/
-
- /********* Start of inlined file: juce_DirectoryContentsDisplayComponent.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- DirectoryContentsDisplayComponent::DirectoryContentsDisplayComponent (DirectoryContentsList& listToShow)
- : fileList (listToShow),
- listeners (2)
- {
- }
-
- DirectoryContentsDisplayComponent::~DirectoryContentsDisplayComponent()
- {
- }
-
- FileBrowserListener::~FileBrowserListener()
- {
- }
-
- void DirectoryContentsDisplayComponent::addListener (FileBrowserListener* const listener) throw()
- {
- jassert (listener != 0);
-
- if (listener != 0)
- listeners.add (listener);
- }
-
- void DirectoryContentsDisplayComponent::removeListener (FileBrowserListener* const listener) throw()
- {
- listeners.removeValue (listener);
- }
-
- void DirectoryContentsDisplayComponent::sendSelectionChangeMessage()
- {
- const ComponentDeletionWatcher deletionWatcher (dynamic_cast <Component*> (this));
-
- for (int i = listeners.size(); --i >= 0;)
- {
- ((FileBrowserListener*) listeners.getUnchecked (i))->selectionChanged();
-
- if (deletionWatcher.hasBeenDeleted())
- return;
-
- i = jmin (i, listeners.size() - 1);
- }
- }
-
- void DirectoryContentsDisplayComponent::sendMouseClickMessage (const File& file, const MouseEvent& e)
- {
- if (fileList.getDirectory().exists())
- {
- const ComponentDeletionWatcher deletionWatcher (dynamic_cast <Component*> (this));
-
- for (int i = listeners.size(); --i >= 0;)
- {
- ((FileBrowserListener*) listeners.getUnchecked (i))->fileClicked (file, e);
-
- if (deletionWatcher.hasBeenDeleted())
- return;
-
- i = jmin (i, listeners.size() - 1);
- }
- }
- }
-
- void DirectoryContentsDisplayComponent::sendDoubleClickMessage (const File& file)
- {
- if (fileList.getDirectory().exists())
- {
- const ComponentDeletionWatcher deletionWatcher (dynamic_cast <Component*> (this));
-
- for (int i = listeners.size(); --i >= 0;)
- {
- ((FileBrowserListener*) listeners.getUnchecked (i))->fileDoubleClicked (file);
-
- if (deletionWatcher.hasBeenDeleted())
- return;
-
- i = jmin (i, listeners.size() - 1);
- }
- }
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_DirectoryContentsDisplayComponent.cpp *********/
-
- /********* Start of inlined file: juce_DirectoryContentsList.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- void* juce_findFileStart (const String& directory, const String& wildCard, String& firstResultFile,
- bool* isDirectory, bool* isHidden, int64* fileSize, Time* modTime,
- Time* creationTime, bool* isReadOnly) throw();
- bool juce_findFileNext (void* handle, String& resultFile,
- bool* isDirectory, bool* isHidden, int64* fileSize,
- Time* modTime, Time* creationTime, bool* isReadOnly) throw();
- void juce_findFileClose (void* handle) throw();
-
- DirectoryContentsList::DirectoryContentsList (const FileFilter* const fileFilter_,
- TimeSliceThread& thread_)
- : fileFilter (fileFilter_),
- thread (thread_),
- includeDirectories (false),
- includeFiles (false),
- ignoreHiddenFiles (true),
- fileFindHandle (0),
- shouldStop (true)
- {
- }
-
- DirectoryContentsList::~DirectoryContentsList()
- {
- clear();
- }
-
- void DirectoryContentsList::setIgnoresHiddenFiles (const bool shouldIgnoreHiddenFiles)
- {
- ignoreHiddenFiles = shouldIgnoreHiddenFiles;
- }
-
- const File& DirectoryContentsList::getDirectory() const throw()
- {
- return root;
- }
-
- void DirectoryContentsList::setDirectory (const File& directory,
- const bool includeDirectories_,
- const bool includeFiles_)
- {
- if (directory != root
- || includeDirectories != includeDirectories_
- || includeFiles != includeFiles_)
- {
- clear();
-
- root = directory;
- includeDirectories = includeDirectories_;
- includeFiles = includeFiles_;
-
- refresh();
- }
- }
-
- void DirectoryContentsList::clear()
- {
- shouldStop = true;
- thread.removeTimeSliceClient (this);
-
- if (fileFindHandle != 0)
- {
- juce_findFileClose (fileFindHandle);
- fileFindHandle = 0;
- }
-
- if (files.size() > 0)
- {
- files.clear();
- changed();
- }
- }
-
- void DirectoryContentsList::refresh()
- {
- clear();
-
- if (root.isDirectory())
- {
- String fileFound;
- bool fileFoundIsDir, isHidden, isReadOnly;
- int64 fileSize;
- Time modTime, creationTime;
-
- String path (root.getFullPathName());
- if (! path.endsWithChar (File::separator))
- path += File::separator;
-
- jassert (fileFindHandle == 0);
-
- fileFindHandle = juce_findFileStart (path, T("*"), fileFound,
- &fileFoundIsDir,
- &isHidden,
- &fileSize,
- &modTime,
- &creationTime,
- &isReadOnly);
-
- if (fileFindHandle != 0 && fileFound.isNotEmpty())
- {
- if (addFile (fileFound, fileFoundIsDir, isHidden,
- fileSize, modTime, creationTime, isReadOnly))
- {
- changed();
- }
- }
-
- shouldStop = false;
-
- thread.addTimeSliceClient (this);
- }
- }
-
- int DirectoryContentsList::getNumFiles() const
- {
- return files.size();
- }
-
- bool DirectoryContentsList::getFileInfo (const int index,
- FileInfo& result) const
- {
- const ScopedLock sl (fileListLock);
- const FileInfo* const info = files [index];
-
- if (info != 0)
- {
- result = *info;
- return true;
- }
-
- return false;
- }
-
- const File DirectoryContentsList::getFile (const int index) const
- {
- const ScopedLock sl (fileListLock);
- const FileInfo* const info = files [index];
-
- if (info != 0)
- return root.getChildFile (info->filename);
-
- return File::nonexistent;
- }
-
- bool DirectoryContentsList::isStillLoading() const
- {
- return fileFindHandle != 0;
- }
-
- void DirectoryContentsList::changed()
- {
- sendChangeMessage (this);
- }
-
- bool DirectoryContentsList::useTimeSlice()
- {
- const uint32 startTime = Time::getApproximateMillisecondCounter();
- bool hasChanged = false;
-
- for (int i = 100; --i >= 0;)
- {
- if (! checkNextFile (hasChanged))
- {
- if (hasChanged)
- changed();
-
- return false;
- }
-
- if (shouldStop || (Time::getApproximateMillisecondCounter() > startTime + 150))
- break;
- }
-
- if (hasChanged)
- changed();
-
- return true;
- }
-
- bool DirectoryContentsList::checkNextFile (bool& hasChanged)
- {
- if (fileFindHandle != 0)
- {
- String fileFound;
- bool fileFoundIsDir, isHidden, isReadOnly;
- int64 fileSize;
- Time modTime, creationTime;
-
- if (juce_findFileNext (fileFindHandle, fileFound,
- &fileFoundIsDir, &isHidden,
- &fileSize,
- &modTime,
- &creationTime,
- &isReadOnly))
- {
- if (addFile (fileFound, fileFoundIsDir, isHidden, fileSize,
- modTime, creationTime, isReadOnly))
- {
- hasChanged = true;
- }
-
- return true;
- }
- else
- {
- juce_findFileClose (fileFindHandle);
- fileFindHandle = 0;
- }
- }
-
- return false;
- }
-
- int DirectoryContentsList::compareElements (const DirectoryContentsList::FileInfo* const first,
- const DirectoryContentsList::FileInfo* const second) throw()
- {
- #if JUCE_WIN32
- if (first->isDirectory != second->isDirectory)
- return first->isDirectory ? -1 : 1;
- #endif
-
- return first->filename.compareIgnoreCase (second->filename);
- }
-
- bool DirectoryContentsList::addFile (const String& filename,
- const bool isDir,
- const bool isHidden,
- const int64 fileSize,
- const Time& modTime,
- const Time& creationTime,
- const bool isReadOnly)
- {
- if (filename == T("..")
- || filename == T(".")
- || (ignoreHiddenFiles && isHidden))
- return false;
-
- const File file (root.getChildFile (filename));
-
- if (((isDir && includeDirectories) || ((! isDir) && includeFiles))
- && (fileFilter == 0
- || ((! isDir) && fileFilter->isFileSuitable (file))
- || (isDir && fileFilter->isDirectorySuitable (file))))
- {
- FileInfo* const info = new FileInfo();
-
- info->filename = filename;
- info->fileSize = fileSize;
- info->modificationTime = modTime;
- info->creationTime = creationTime;
- info->isDirectory = isDir;
- info->isReadOnly = isReadOnly;
-
- const ScopedLock sl (fileListLock);
-
- for (int i = files.size(); --i >= 0;)
- {
- if (files.getUnchecked(i)->filename == info->filename)
- {
- delete info;
- return false;
- }
- }
-
- files.addSorted (*this, info);
- return true;
- }
-
- return false;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_DirectoryContentsList.cpp *********/
-
- /********* Start of inlined file: juce_FileBrowserComponent.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- class DirectoriesOnlyFilter : public FileFilter
- {
- public:
- DirectoriesOnlyFilter() : FileFilter (String::empty) {}
-
- bool isFileSuitable (const File&) const { return false; }
- bool isDirectorySuitable (const File&) const { return true; }
- };
-
- FileBrowserComponent::FileBrowserComponent (FileChooserMode mode_,
- const File& initialFileOrDirectory,
- const FileFilter* fileFilter,
- FilePreviewComponent* previewComp_,
- const bool useTreeView,
- const bool filenameTextBoxIsReadOnly)
- : directoriesOnlyFilter (0),
- mode (mode_),
- listeners (2),
- previewComp (previewComp_),
- thread ("Juce FileBrowser")
- {
- String filename;
-
- if (initialFileOrDirectory == File::nonexistent)
- {
- currentRoot = File::getCurrentWorkingDirectory();
- }
- else if (initialFileOrDirectory.isDirectory())
- {
- currentRoot = initialFileOrDirectory;
- }
- else
- {
- currentRoot = initialFileOrDirectory.getParentDirectory();
- filename = initialFileOrDirectory.getFileName();
- }
-
- if (mode_ == chooseDirectoryMode)
- fileFilter = directoriesOnlyFilter = new DirectoriesOnlyFilter();
-
- fileList = new DirectoryContentsList (fileFilter, thread);
-
- if (useTreeView)
- {
- FileTreeComponent* const tree = new FileTreeComponent (*fileList);
- addAndMakeVisible (tree);
- fileListComponent = tree;
- }
- else
- {
- FileListComponent* const list = new FileListComponent (*fileList);
- list->setOutlineThickness (1);
- addAndMakeVisible (list);
- fileListComponent = list;
- }
-
- fileListComponent->addListener (this);
-
- addAndMakeVisible (currentPathBox = new ComboBox ("path"));
- currentPathBox->setEditableText (true);
-
- StringArray rootNames, rootPaths;
- const BitArray separators (getRoots (rootNames, rootPaths));
-
- for (int i = 0; i < rootNames.size(); ++i)
- {
- if (separators [i])
- currentPathBox->addSeparator();
-
- currentPathBox->addItem (rootNames[i], i + 1);
- }
-
- currentPathBox->addSeparator();
- currentPathBox->addListener (this);
-
- addAndMakeVisible (filenameBox = new TextEditor());
- filenameBox->setMultiLine (false);
- filenameBox->setSelectAllWhenFocused (true);
- filenameBox->setText (filename, false);
- filenameBox->addListener (this);
- filenameBox->setReadOnly (filenameTextBoxIsReadOnly);
-
- Label* label = new Label ("f", (mode == chooseDirectoryMode) ? TRANS("folder:")
- : TRANS("file:"));
- addAndMakeVisible (label);
- label->attachToComponent (filenameBox, true);
-
- addAndMakeVisible (goUpButton = getLookAndFeel().createFileBrowserGoUpButton());
-
- goUpButton->addButtonListener (this);
- goUpButton->setTooltip (TRANS ("go up to parent directory"));
-
- if (previewComp != 0)
- addAndMakeVisible (previewComp);
-
- setRoot (currentRoot);
-
- thread.startThread (4);
- }
-
- FileBrowserComponent::~FileBrowserComponent()
- {
- if (previewComp != 0)
- removeChildComponent (previewComp);
-
- deleteAllChildren();
-
- deleteAndZero (fileList);
- delete directoriesOnlyFilter;
-
- thread.stopThread (10000);
- }
-
- void FileBrowserComponent::addListener (FileBrowserListener* const newListener) throw()
- {
- jassert (newListener != 0)
-
- if (newListener != 0)
- listeners.add (newListener);
- }
-
- void FileBrowserComponent::removeListener (FileBrowserListener* const listener) throw()
- {
- listeners.removeValue (listener);
- }
-
- const File FileBrowserComponent::getCurrentFile() const throw()
- {
- return currentRoot.getChildFile (filenameBox->getText());
- }
-
- bool FileBrowserComponent::currentFileIsValid() const
- {
- if (mode == saveFileMode)
- return ! getCurrentFile().isDirectory();
- else if (mode == loadFileMode)
- return getCurrentFile().existsAsFile();
- else if (mode == chooseDirectoryMode)
- return getCurrentFile().isDirectory();
-
- jassertfalse
- return false;
- }
-
- const File FileBrowserComponent::getRoot() const
- {
- return currentRoot;
- }
-
- void FileBrowserComponent::setRoot (const File& newRootDirectory)
- {
- if (currentRoot != newRootDirectory)
- {
- fileListComponent->scrollToTop();
-
- if (mode == chooseDirectoryMode)
- filenameBox->setText (String::empty, false);
-
- String path (newRootDirectory.getFullPathName());
-
- if (path.isEmpty())
- path += File::separator;
-
- StringArray rootNames, rootPaths;
- getRoots (rootNames, rootPaths);
-
- if (! rootPaths.contains (path, true))
- {
- bool alreadyListed = false;
-
- for (int i = currentPathBox->getNumItems(); --i >= 0;)
- {
- if (currentPathBox->getItemText (i).equalsIgnoreCase (path))
- {
- alreadyListed = true;
- break;
- }
- }
-
- if (! alreadyListed)
- currentPathBox->addItem (path, currentPathBox->getNumItems() + 2);
- }
- }
-
- currentRoot = newRootDirectory;
- fileList->setDirectory (currentRoot, true, true);
-
- String currentRootName (currentRoot.getFullPathName());
- if (currentRootName.isEmpty())
- currentRootName += File::separator;
-
- currentPathBox->setText (currentRootName, true);
-
- goUpButton->setEnabled (currentRoot.getParentDirectory().isDirectory()
- && currentRoot.getParentDirectory() != currentRoot);
- }
-
- void FileBrowserComponent::goUp()
- {
- setRoot (getRoot().getParentDirectory());
- }
-
- void FileBrowserComponent::refresh()
- {
- fileList->refresh();
- }
-
- const String FileBrowserComponent::getActionVerb() const
- {
- return (mode == chooseDirectoryMode) ? TRANS("Choose")
- : ((mode == saveFileMode) ? TRANS("Save") : TRANS("Open"));
- }
-
- FilePreviewComponent* FileBrowserComponent::getPreviewComponent() const throw()
- {
- return previewComp;
- }
-
- void FileBrowserComponent::resized()
- {
- getLookAndFeel()
- .layoutFileBrowserComponent (*this, fileListComponent,
- previewComp, currentPathBox,
- filenameBox, goUpButton);
- }
-
- void FileBrowserComponent::sendListenerChangeMessage()
- {
- ComponentDeletionWatcher deletionWatcher (this);
-
- if (previewComp != 0)
- previewComp->selectedFileChanged (getCurrentFile());
-
- jassert (! deletionWatcher.hasBeenDeleted());
-
- for (int i = listeners.size(); --i >= 0;)
- {
- ((FileBrowserListener*) listeners.getUnchecked (i))->selectionChanged();
-
- if (deletionWatcher.hasBeenDeleted())
- return;
-
- i = jmin (i, listeners.size() - 1);
- }
- }
-
- void FileBrowserComponent::selectionChanged()
- {
- const File selected (fileListComponent->getSelectedFile());
-
- if ((mode == chooseDirectoryMode && selected.isDirectory())
- || selected.existsAsFile())
- {
- filenameBox->setText (selected.getRelativePathFrom (getRoot()), false);
- }
-
- sendListenerChangeMessage();
- }
-
- void FileBrowserComponent::fileClicked (const File& f, const MouseEvent& e)
- {
- ComponentDeletionWatcher deletionWatcher (this);
-
- for (int i = listeners.size(); --i >= 0;)
- {
- ((FileBrowserListener*) listeners.getUnchecked (i))->fileClicked (f, e);
-
- if (deletionWatcher.hasBeenDeleted())
- return;
-
- i = jmin (i, listeners.size() - 1);
- }
- }
-
- void FileBrowserComponent::fileDoubleClicked (const File& f)
- {
- if (f.isDirectory())
- {
- setRoot (f);
- }
- else
- {
- ComponentDeletionWatcher deletionWatcher (this);
-
- for (int i = listeners.size(); --i >= 0;)
- {
- ((FileBrowserListener*) listeners.getUnchecked (i))->fileDoubleClicked (f);
-
- if (deletionWatcher.hasBeenDeleted())
- return;
-
- i = jmin (i, listeners.size() - 1);
- }
- }
- }
-
- void FileBrowserComponent::textEditorTextChanged (TextEditor&)
- {
- sendListenerChangeMessage();
- }
-
- void FileBrowserComponent::textEditorReturnKeyPressed (TextEditor&)
- {
- if (filenameBox->getText().containsChar (File::separator))
- {
- const File f (currentRoot.getChildFile (filenameBox->getText()));
-
- if (f.isDirectory())
- {
- setRoot (f);
- filenameBox->setText (String::empty);
- }
- else
- {
- setRoot (f.getParentDirectory());
- filenameBox->setText (f.getFileName());
- }
- }
- else
- {
- fileDoubleClicked (getCurrentFile());
- }
- }
-
- void FileBrowserComponent::textEditorEscapeKeyPressed (TextEditor&)
- {
- }
-
- void FileBrowserComponent::textEditorFocusLost (TextEditor&)
- {
- if (mode != saveFileMode)
- selectionChanged();
- }
-
- void FileBrowserComponent::buttonClicked (Button*)
- {
- goUp();
- }
-
- void FileBrowserComponent::comboBoxChanged (ComboBox*)
- {
- const String newText (currentPathBox->getText().trim().unquoted());
-
- if (newText.isNotEmpty())
- {
- const int index = currentPathBox->getSelectedId() - 1;
-
- StringArray rootNames, rootPaths;
- getRoots (rootNames, rootPaths);
-
- if (rootPaths [index].isNotEmpty())
- {
- setRoot (File (rootPaths [index]));
- }
- else
- {
- File f (newText);
-
- for (;;)
- {
- if (f.isDirectory())
- {
- setRoot (f);
- break;
- }
-
- if (f.getParentDirectory() == f)
- break;
-
- f = f.getParentDirectory();
- }
- }
- }
- }
-
- const BitArray FileBrowserComponent::getRoots (StringArray& rootNames, StringArray& rootPaths)
- {
- BitArray separators;
-
- #if JUCE_WIN32
- OwnedArray<File> roots;
- File::findFileSystemRoots (roots);
- rootPaths.clear();
-
- for (int i = 0; i < roots.size(); ++i)
- {
- const File* const drive = roots.getUnchecked(i);
-
- String name (drive->getFullPathName());
- rootPaths.add (name);
-
- if (drive->isOnHardDisk())
- {
- String volume (drive->getVolumeLabel());
-
- if (volume.isEmpty())
- volume = TRANS("Hard Drive");
-
- name << " [" << drive->getVolumeLabel() << ']';
- }
- else if (drive->isOnCDRomDrive())
- {
- name << TRANS(" [CD/DVD drive]");
- }
-
- rootNames.add (name);
- }
-
- separators.setBit (rootPaths.size());
-
- rootPaths.add (File::getSpecialLocation (File::userDocumentsDirectory).getFullPathName());
- rootNames.add ("Documents");
- rootPaths.add (File::getSpecialLocation (File::userDesktopDirectory).getFullPathName());
- rootNames.add ("Desktop");
- #endif
-
- #if JUCE_MAC
- rootPaths.add (File::getSpecialLocation (File::userHomeDirectory).getFullPathName());
- rootNames.add ("Home folder");
- rootPaths.add (File::getSpecialLocation (File::userDocumentsDirectory).getFullPathName());
- rootNames.add ("Documents");
- rootPaths.add (File::getSpecialLocation (File::userDesktopDirectory).getFullPathName());
- rootNames.add ("Desktop");
-
- separators.setBit (rootPaths.size());
-
- OwnedArray <File> volumes;
- File vol ("/Volumes");
- vol.findChildFiles (volumes, File::findDirectories, false);
-
- for (int i = 0; i < volumes.size(); ++i)
- {
- const File* const volume = volumes.getUnchecked(i);
-
- if (volume->isDirectory() && ! volume->getFileName().startsWithChar (T('.')))
- {
- rootPaths.add (volume->getFullPathName());
- rootNames.add (volume->getFileName());
- }
- }
- #endif
-
- #if JUCE_LINUX
- rootPaths.add ("/");
- rootNames.add ("/");
- rootPaths.add (File::getSpecialLocation (File::userHomeDirectory).getFullPathName());
- rootNames.add ("Home folder");
- rootPaths.add (File::getSpecialLocation (File::userDesktopDirectory).getFullPathName());
- rootNames.add ("Desktop");
- #endif
-
- return separators;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_FileBrowserComponent.cpp *********/
-
- /********* Start of inlined file: juce_FileChooser.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- FileChooser::FileChooser (const String& chooserBoxTitle,
- const File& currentFileOrDirectory,
- const String& fileFilters,
- const bool useNativeDialogBox_)
- : title (chooserBoxTitle),
- filters (fileFilters),
- startingFile (currentFileOrDirectory),
- useNativeDialogBox (useNativeDialogBox_)
- {
- #if JUCE_LINUX
- useNativeDialogBox = false;
- #endif
-
- if (fileFilters.trim().isEmpty())
- filters = T("*");
- }
-
- FileChooser::~FileChooser()
- {
- }
-
- bool FileChooser::browseForFileToOpen (FilePreviewComponent* previewComponent)
- {
- return showDialog (false, false, false, false, previewComponent);
- }
-
- bool FileChooser::browseForMultipleFilesToOpen (FilePreviewComponent* previewComponent)
- {
- return showDialog (false, false, false, true, previewComponent);
- }
-
- bool FileChooser::browseForFileToSave (const bool warnAboutOverwritingExistingFiles)
- {
- return showDialog (false, true, warnAboutOverwritingExistingFiles, false, 0);
- }
-
- bool FileChooser::browseForDirectory()
- {
- return showDialog (true, false, false, false, 0);
- }
-
- const File FileChooser::getResult() const
- {
- // if you've used a multiple-file select, you should use the getResults() method
- // to retrieve all the files that were chosen.
- jassert (results.size() <= 1);
-
- const File* const f = results.getFirst();
-
- if (f != 0)
- return *f;
-
- return File::nonexistent;
- }
-
- const OwnedArray <File>& FileChooser::getResults() const
- {
- return results;
- }
-
- bool FileChooser::showDialog (const bool isDirectory,
- const bool isSave,
- const bool warnAboutOverwritingExistingFiles,
- const bool selectMultipleFiles,
- FilePreviewComponent* const previewComponent)
- {
- ComponentDeletionWatcher* currentlyFocusedChecker = 0;
- Component* const currentlyFocused = Component::getCurrentlyFocusedComponent();
-
- if (currentlyFocused != 0)
- currentlyFocusedChecker = new ComponentDeletionWatcher (currentlyFocused);
-
- results.clear();
-
- // the preview component needs to be the right size before you pass it in here..
- jassert (previewComponent == 0 || (previewComponent->getWidth() > 10
- && previewComponent->getHeight() > 10));
-
- #if JUCE_WIN32
- if (useNativeDialogBox)
- #else
- if (useNativeDialogBox && (previewComponent == 0))
- #endif
- {
- showPlatformDialog (results, title, startingFile, filters,
- isDirectory, isSave,
- warnAboutOverwritingExistingFiles,
- selectMultipleFiles,
- previewComponent);
- }
- else
- {
- jassert (! selectMultipleFiles); // not yet implemented for juce dialogs!
-
- WildcardFileFilter wildcard (filters, String::empty);
-
- FileBrowserComponent browserComponent (isDirectory ? FileBrowserComponent::chooseDirectoryMode
- : (isSave ? FileBrowserComponent::saveFileMode
- : FileBrowserComponent::loadFileMode),
- startingFile, &wildcard, previewComponent);
-
- FileChooserDialogBox box (title, String::empty,
- browserComponent,
- warnAboutOverwritingExistingFiles,
- browserComponent.findColour (AlertWindow::backgroundColourId));
-
- if (box.show())
- results.add (new File (browserComponent.getCurrentFile()));
- }
-
- if (currentlyFocused != 0 && ! currentlyFocusedChecker->hasBeenDeleted())
- currentlyFocused->grabKeyboardFocus();
-
- delete currentlyFocusedChecker;
-
- return results.size() > 0;
- }
-
- FilePreviewComponent::FilePreviewComponent()
- {
- }
-
- FilePreviewComponent::~FilePreviewComponent()
- {
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_FileChooser.cpp *********/
-
- /********* Start of inlined file: juce_FileChooserDialogBox.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- FileChooserDialogBox::FileChooserDialogBox (const String& name,
- const String& instructions,
- FileBrowserComponent& chooserComponent,
- const bool warnAboutOverwritingExistingFiles_,
- const Colour& backgroundColour)
- : ResizableWindow (name, backgroundColour, true),
- warnAboutOverwritingExistingFiles (warnAboutOverwritingExistingFiles_)
- {
- content = new ContentComponent();
- content->setName (name);
- content->instructions = instructions;
- content->chooserComponent = &chooserComponent;
-
- content->addAndMakeVisible (&chooserComponent);
-
- content->okButton = new TextButton (chooserComponent.getActionVerb());
- content->addAndMakeVisible (content->okButton);
- content->okButton->addButtonListener (this);
- content->okButton->setEnabled (chooserComponent.currentFileIsValid());
- content->okButton->addShortcut (KeyPress (KeyPress::returnKey, 0, 0));
-
- content->cancelButton = new TextButton (TRANS("Cancel"));
- content->addAndMakeVisible (content->cancelButton);
- content->cancelButton->addButtonListener (this);
- content->cancelButton->addShortcut (KeyPress (KeyPress::escapeKey, 0, 0));
-
- setContentComponent (content);
-
- setResizable (true, true);
- setResizeLimits (300, 300, 1200, 1000);
-
- content->chooserComponent->addListener (this);
- }
-
- FileChooserDialogBox::~FileChooserDialogBox()
- {
- content->chooserComponent->removeListener (this);
- }
-
- bool FileChooserDialogBox::show (int w, int h)
- {
- if (w <= 0)
- {
- Component* const previewComp = content->chooserComponent->getPreviewComponent();
- if (previewComp != 0)
- w = 400 + previewComp->getWidth();
- else
- w = 600;
- }
-
- if (h <= 0)
- h = 500;
-
- centreWithSize (w, h);
-
- const bool ok = (runModalLoop() != 0);
- setVisible (false);
- return ok;
- }
-
- void FileChooserDialogBox::buttonClicked (Button* button)
- {
- if (button == content->okButton)
- {
- if (warnAboutOverwritingExistingFiles
- && content->chooserComponent->getMode() == FileBrowserComponent::saveFileMode
- && content->chooserComponent->getCurrentFile().exists())
- {
- if (! AlertWindow::showOkCancelBox (AlertWindow::WarningIcon,
- TRANS("File already exists"),
- TRANS("There's already a file called:\n\n")
- + content->chooserComponent->getCurrentFile().getFullPathName()
- + T("\n\nAre you sure you want to overwrite it?"),
- TRANS("overwrite"),
- TRANS("cancel")))
- {
- return;
- }
- }
-
- exitModalState (1);
- }
- else if (button == content->cancelButton)
- closeButtonPressed();
- }
-
- void FileChooserDialogBox::closeButtonPressed()
- {
- setVisible (false);
- }
-
- void FileChooserDialogBox::selectionChanged()
- {
- content->okButton->setEnabled (content->chooserComponent->currentFileIsValid());
- }
-
- void FileChooserDialogBox::fileClicked (const File&, const MouseEvent&)
- {
- }
-
- void FileChooserDialogBox::fileDoubleClicked (const File&)
- {
- selectionChanged();
- content->okButton->triggerClick();
- }
-
- FileChooserDialogBox::ContentComponent::ContentComponent()
- {
- setInterceptsMouseClicks (false, true);
- }
-
- FileChooserDialogBox::ContentComponent::~ContentComponent()
- {
- delete okButton;
- delete cancelButton;
- }
-
- void FileChooserDialogBox::ContentComponent::paint (Graphics& g)
- {
- g.setColour (Colours::black);
- text.draw (g);
- }
-
- void FileChooserDialogBox::ContentComponent::resized()
- {
- getLookAndFeel().createFileChooserHeaderText (getName(), instructions, text, getWidth());
-
- float left, top, right, bottom;
- text.getBoundingBox (0, text.getNumGlyphs(), left, top, right, bottom, false);
-
- const int y = roundFloatToInt (bottom) + 10;
- const int buttonHeight = 26;
- const int buttonY = getHeight() - buttonHeight - 8;
-
- chooserComponent->setBounds (0, y, getWidth(), buttonY - y - 20);
-
- okButton->setBounds (proportionOfWidth (0.25f), buttonY,
- proportionOfWidth (0.2f), buttonHeight);
-
- cancelButton->setBounds (proportionOfWidth (0.55f), buttonY,
- proportionOfWidth (0.2f), buttonHeight);
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_FileChooserDialogBox.cpp *********/
-
- /********* Start of inlined file: juce_FileFilter.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- FileFilter::FileFilter (const String& filterDescription)
- : description (filterDescription)
- {
- }
-
- FileFilter::~FileFilter()
- {
- }
-
- const String& FileFilter::getDescription() const throw()
- {
- return description;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_FileFilter.cpp *********/
-
- /********* Start of inlined file: juce_FileListComponent.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- Image* juce_createIconForFile (const File& file);
-
- FileListComponent::FileListComponent (DirectoryContentsList& listToShow)
- : ListBox (String::empty, 0),
- DirectoryContentsDisplayComponent (listToShow)
- {
- setModel (this);
- fileList.addChangeListener (this);
- }
-
- FileListComponent::~FileListComponent()
- {
- fileList.removeChangeListener (this);
- deleteAllChildren();
- }
-
- const File FileListComponent::getSelectedFile() const
- {
- return fileList.getFile (getSelectedRow());
- }
-
- void FileListComponent::scrollToTop()
- {
- getVerticalScrollBar()->setCurrentRangeStart (0);
- }
-
- void FileListComponent::changeListenerCallback (void*)
- {
- updateContent();
-
- if (lastDirectory != fileList.getDirectory())
- {
- lastDirectory = fileList.getDirectory();
- deselectAllRows();
- }
- }
-
- class FileListItemComponent : public Component,
- public TimeSliceClient,
- public AsyncUpdater
- {
- public:
-
- FileListItemComponent (FileListComponent& owner_,
- TimeSliceThread& thread_) throw()
- : owner (owner_),
- thread (thread_),
- icon (0)
- {
- }
-
- ~FileListItemComponent() throw()
- {
- thread.removeTimeSliceClient (this);
-
- clearIcon();
- }
-
- void paint (Graphics& g)
- {
- getLookAndFeel().drawFileBrowserRow (g, getWidth(), getHeight(),
- file.getFileName(),
- icon,
- fileSize, modTime,
- isDirectory, highlighted,
- index);
- }
-
- void mouseDown (const MouseEvent& e)
- {
- owner.selectRowsBasedOnModifierKeys (index, e.mods);
- owner.sendMouseClickMessage (file, e);
- }
-
- void mouseDoubleClick (const MouseEvent&)
- {
- owner.sendDoubleClickMessage (file);
- }
-
- void update (const File& root,
- const DirectoryContentsList::FileInfo* const fileInfo,
- const int index_,
- const bool highlighted_) throw()
- {
- thread.removeTimeSliceClient (this);
-
- if (highlighted_ != highlighted
- || index_ != index)
- {
- index = index_;
- highlighted = highlighted_;
- repaint();
- }
-
- File newFile;
- String newFileSize;
- String newModTime;
-
- if (fileInfo != 0)
- {
- newFile = root.getChildFile (fileInfo->filename);
- newFileSize = File::descriptionOfSizeInBytes (fileInfo->fileSize);
- newModTime = fileInfo->modificationTime.formatted (T("%d %b '%y %H:%M"));
- }
-
- if (newFile != file
- || fileSize != newFileSize
- || modTime != newModTime)
- {
- file = newFile;
- fileSize = newFileSize;
- modTime = newModTime;
-
- isDirectory = fileInfo != 0 && fileInfo->isDirectory;
- repaint();
-
- clearIcon();
- }
-
- if (file != File::nonexistent
- && icon == 0 && ! isDirectory)
- {
- updateIcon (true);
-
- if (icon == 0)
- thread.addTimeSliceClient (this);
- }
- }
-
- bool useTimeSlice()
- {
- updateIcon (false);
- return false;
- }
-
- void handleAsyncUpdate()
- {
- repaint();
- }
-
- juce_UseDebuggingNewOperator
-
- private:
- FileListComponent& owner;
- TimeSliceThread& thread;
- bool highlighted;
- int index;
- File file;
- String fileSize;
- String modTime;
- Image* icon;
- bool isDirectory;
-
- void clearIcon() throw()
- {
- ImageCache::release (icon);
- icon = 0;
- }
-
- void updateIcon (const bool onlyUpdateIfCached) throw()
- {
- if (icon == 0)
- {
- const int hashCode = (file.getFullPathName() + T("_iconCacheSalt")).hashCode();
- Image* im = ImageCache::getFromHashCode (hashCode);
-
- if (im == 0 && ! onlyUpdateIfCached)
- {
- im = juce_createIconForFile (file);
-
- if (im != 0)
- ImageCache::addImageToCache (im, hashCode);
- }
-
- if (im != 0)
- {
- icon = im;
- triggerAsyncUpdate();
- }
- }
- }
- };
-
- int FileListComponent::getNumRows()
- {
- return fileList.getNumFiles();
- }
-
- void FileListComponent::paintListBoxItem (int, Graphics&, int, int, bool)
- {
- }
-
- Component* FileListComponent::refreshComponentForRow (int row, bool isSelected, Component* existingComponentToUpdate)
- {
- FileListItemComponent* comp = dynamic_cast <FileListItemComponent*> (existingComponentToUpdate);
-
- if (comp == 0)
- {
- delete existingComponentToUpdate;
- existingComponentToUpdate = comp = new FileListItemComponent (*this, fileList.getTimeSliceThread());
- }
-
- DirectoryContentsList::FileInfo fileInfo;
-
- if (fileList.getFileInfo (row, fileInfo))
- comp->update (fileList.getDirectory(), &fileInfo, row, isSelected);
- else
- comp->update (fileList.getDirectory(), 0, row, isSelected);
-
- return comp;
- }
-
- void FileListComponent::selectedRowsChanged (int /*lastRowSelected*/)
- {
- sendSelectionChangeMessage();
- }
-
- void FileListComponent::deleteKeyPressed (int /*currentSelectedRow*/)
- {
- }
-
- void FileListComponent::returnKeyPressed (int currentSelectedRow)
- {
- sendDoubleClickMessage (fileList.getFile (currentSelectedRow));
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_FileListComponent.cpp *********/
-
- /********* Start of inlined file: juce_FilenameComponent.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- FilenameComponent::FilenameComponent (const String& name,
- const File& currentFile,
- const bool canEditFilename,
- const bool isDirectory,
- const bool isForSaving,
- const String& fileBrowserWildcard,
- const String& enforcedSuffix_,
- const String& textWhenNothingSelected)
- : Component (name),
- maxRecentFiles (30),
- isDir (isDirectory),
- isSaving (isForSaving),
- isFileDragOver (false),
- wildcard (fileBrowserWildcard),
- enforcedSuffix (enforcedSuffix_)
- {
- addAndMakeVisible (filenameBox = new ComboBox (T("fn")));
- filenameBox->setEditableText (canEditFilename);
- filenameBox->addListener (this);
- filenameBox->setTextWhenNothingSelected (textWhenNothingSelected);
- filenameBox->setTextWhenNoChoicesAvailable (TRANS("(no recently seleced files)"));
-
- browseButton = 0;
- setBrowseButtonText (T("..."));
-
- setCurrentFile (currentFile, true);
- }
-
- FilenameComponent::~FilenameComponent()
- {
- deleteAllChildren();
- }
-
- void FilenameComponent::paintOverChildren (Graphics& g)
- {
- if (isFileDragOver)
- {
- g.setColour (Colours::red.withAlpha (0.2f));
- g.drawRect (0, 0, getWidth(), getHeight(), 3);
- }
- }
-
- void FilenameComponent::resized()
- {
- getLookAndFeel().layoutFilenameComponent (*this, filenameBox, browseButton);
- }
-
- void FilenameComponent::setBrowseButtonText (const String& newBrowseButtonText)
- {
- browseButtonText = newBrowseButtonText;
- lookAndFeelChanged();
- }
-
- void FilenameComponent::lookAndFeelChanged()
- {
- deleteAndZero (browseButton);
-
- addAndMakeVisible (browseButton = getLookAndFeel().createFilenameComponentBrowseButton (browseButtonText));
- browseButton->setConnectedEdges (Button::ConnectedOnLeft);
- resized();
-
- browseButton->addButtonListener (this);
- }
-
- void FilenameComponent::setTooltip (const String& newTooltip)
- {
- SettableTooltipClient::setTooltip (newTooltip);
- filenameBox->setTooltip (newTooltip);
- }
-
- void FilenameComponent::setDefaultBrowseTarget (const File& newDefaultDirectory) throw()
- {
- defaultBrowseFile = newDefaultDirectory;
- }
-
- void FilenameComponent::buttonClicked (Button*)
- {
- FileChooser fc (TRANS("Choose a new file"),
- getCurrentFile() == File::nonexistent ? defaultBrowseFile
- : getCurrentFile(),
- wildcard);
-
- if (isDir ? fc.browseForDirectory()
- : (isSaving ? fc.browseForFileToSave (false)
- : fc.browseForFileToOpen()))
- {
- setCurrentFile (fc.getResult(), true);
- }
- }
-
- void FilenameComponent::comboBoxChanged (ComboBox*)
- {
- setCurrentFile (getCurrentFile(), true);
- }
-
- bool FilenameComponent::isInterestedInFileDrag (const StringArray&)
- {
- return true;
- }
-
- void FilenameComponent::filesDropped (const StringArray& filenames, int, int)
- {
- isFileDragOver = false;
- repaint();
-
- const File f (filenames[0]);
-
- if (f.exists() && (f.isDirectory() == isDir))
- setCurrentFile (f, true);
- }
-
- void FilenameComponent::fileDragEnter (const StringArray&, int, int)
- {
- isFileDragOver = true;
- repaint();
- }
-
- void FilenameComponent::fileDragExit (const StringArray&)
- {
- isFileDragOver = false;
- repaint();
- }
-
- const File FilenameComponent::getCurrentFile() const
- {
- File f (filenameBox->getText());
-
- if (enforcedSuffix.isNotEmpty())
- f = f.withFileExtension (enforcedSuffix);
-
- return f;
- }
-
- void FilenameComponent::setCurrentFile (File newFile,
- const bool addToRecentlyUsedList,
- const bool sendChangeNotification)
- {
- if (enforcedSuffix.isNotEmpty())
- newFile = newFile.withFileExtension (enforcedSuffix);
-
- if (newFile.getFullPathName() != lastFilename)
- {
- lastFilename = newFile.getFullPathName();
-
- if (addToRecentlyUsedList)
- addRecentlyUsedFile (newFile);
-
- filenameBox->setText (lastFilename, true);
-
- if (sendChangeNotification)
- triggerAsyncUpdate();
- }
- }
-
- void FilenameComponent::setFilenameIsEditable (const bool shouldBeEditable)
- {
- filenameBox->setEditableText (shouldBeEditable);
- }
-
- const StringArray FilenameComponent::getRecentlyUsedFilenames() const
- {
- StringArray names;
-
- for (int i = 0; i < filenameBox->getNumItems(); ++i)
- names.add (filenameBox->getItemText (i));
-
- return names;
- }
-
- void FilenameComponent::setRecentlyUsedFilenames (const StringArray& filenames)
- {
- if (filenames != getRecentlyUsedFilenames())
- {
- filenameBox->clear();
-
- for (int i = 0; i < jmin (filenames.size(), maxRecentFiles); ++i)
- filenameBox->addItem (filenames[i], i + 1);
- }
- }
-
- void FilenameComponent::setMaxNumberOfRecentFiles (const int newMaximum)
- {
- maxRecentFiles = jmax (1, newMaximum);
-
- setRecentlyUsedFilenames (getRecentlyUsedFilenames());
- }
-
- void FilenameComponent::addRecentlyUsedFile (const File& file)
- {
- StringArray files (getRecentlyUsedFilenames());
-
- if (file.getFullPathName().isNotEmpty())
- {
- files.removeString (file.getFullPathName(), true);
- files.insert (0, file.getFullPathName());
-
- setRecentlyUsedFilenames (files);
- }
- }
-
- void FilenameComponent::addListener (FilenameComponentListener* const listener) throw()
- {
- jassert (listener != 0);
-
- if (listener != 0)
- listeners.add (listener);
- }
-
- void FilenameComponent::removeListener (FilenameComponentListener* const listener) throw()
- {
- listeners.removeValue (listener);
- }
-
- void FilenameComponent::handleAsyncUpdate()
- {
- for (int i = listeners.size(); --i >= 0;)
- {
- ((FilenameComponentListener*) listeners.getUnchecked (i))->filenameComponentChanged (this);
- i = jmin (i, listeners.size());
- }
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_FilenameComponent.cpp *********/
-
- /********* Start of inlined file: juce_FileSearchPathListComponent.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- FileSearchPathListComponent::FileSearchPathListComponent()
- {
- addAndMakeVisible (listBox = new ListBox (String::empty, this));
- listBox->setColour (ListBox::backgroundColourId, Colours::black.withAlpha (0.02f));
- listBox->setColour (ListBox::outlineColourId, Colours::black.withAlpha (0.1f));
- listBox->setOutlineThickness (1);
-
- addAndMakeVisible (addButton = new TextButton ("+"));
- addButton->addButtonListener (this);
- addButton->setConnectedEdges (Button::ConnectedOnLeft | Button::ConnectedOnRight | Button::ConnectedOnBottom | Button::ConnectedOnTop);
-
- addAndMakeVisible (removeButton = new TextButton ("-"));
- removeButton->addButtonListener (this);
- removeButton->setConnectedEdges (Button::ConnectedOnLeft | Button::ConnectedOnRight | Button::ConnectedOnBottom | Button::ConnectedOnTop);
-
- addAndMakeVisible (changeButton = new TextButton (TRANS("change...")));
- changeButton->addButtonListener (this);
-
- addAndMakeVisible (upButton = new DrawableButton (String::empty, DrawableButton::ImageOnButtonBackground));
- upButton->addButtonListener (this);
-
- {
- Path arrowPath;
- arrowPath.addArrow (50.0f, 100.0f, 50.0f, 0.0, 40.0f, 100.0f, 50.0f);
- DrawablePath arrowImage;
- arrowImage.setSolidFill (Colours::black.withAlpha (0.4f));
- arrowImage.setPath (arrowPath);
-
- ((DrawableButton*) upButton)->setImages (&arrowImage);
- }
-
- addAndMakeVisible (downButton = new DrawableButton (String::empty, DrawableButton::ImageOnButtonBackground));
- downButton->addButtonListener (this);
-
- {
- Path arrowPath;
- arrowPath.addArrow (50.0f, 0.0f, 50.0f, 100.0f, 40.0f, 100.0f, 50.0f);
- DrawablePath arrowImage;
- arrowImage.setSolidFill (Colours::black.withAlpha (0.4f));
- arrowImage.setPath (arrowPath);
-
- ((DrawableButton*) downButton)->setImages (&arrowImage);
- }
-
- updateButtons();
- }
-
- FileSearchPathListComponent::~FileSearchPathListComponent()
- {
- deleteAllChildren();
- }
-
- void FileSearchPathListComponent::updateButtons() throw()
- {
- const bool anythingSelected = listBox->getNumSelectedRows() > 0;
-
- removeButton->setEnabled (anythingSelected);
- changeButton->setEnabled (anythingSelected);
- upButton->setEnabled (anythingSelected);
- downButton->setEnabled (anythingSelected);
- }
-
- void FileSearchPathListComponent::changed() throw()
- {
- listBox->updateContent();
- listBox->repaint();
- updateButtons();
- }
-
- void FileSearchPathListComponent::setPath (const FileSearchPath& newPath)
- {
- if (newPath.toString() != path.toString())
- {
- path = newPath;
- changed();
- }
- }
-
- void FileSearchPathListComponent::setDefaultBrowseTarget (const File& newDefaultDirectory) throw()
- {
- defaultBrowseTarget = newDefaultDirectory;
- }
-
- int FileSearchPathListComponent::getNumRows()
- {
- return path.getNumPaths();
- }
-
- void FileSearchPathListComponent::paintListBoxItem (int rowNumber, Graphics& g, int width, int height, bool rowIsSelected)
- {
- if (rowIsSelected)
- g.fillAll (findColour (TextEditor::highlightColourId));
-
- g.setColour (findColour (ListBox::textColourId));
- Font f (height * 0.7f);
- f.setHorizontalScale (0.9f);
- g.setFont (f);
-
- g.drawText (path [rowNumber].getFullPathName(),
- 4, 0, width - 6, height,
- Justification::centredLeft, true);
- }
-
- void FileSearchPathListComponent::deleteKeyPressed (int row)
- {
- if (((unsigned int) row) < (unsigned int) path.getNumPaths())
- {
- path.remove (row);
- changed();
- }
- }
-
- void FileSearchPathListComponent::returnKeyPressed (int row)
- {
- FileChooser chooser (TRANS("Change folder..."), path [row], T("*"));
-
- if (chooser.browseForDirectory())
- {
- path.remove (row);
- path.add (chooser.getResult(), row);
- changed();
- }
- }
-
- void FileSearchPathListComponent::listBoxItemDoubleClicked (int row, const MouseEvent&)
- {
- returnKeyPressed (row);
- }
-
- void FileSearchPathListComponent::selectedRowsChanged (int)
- {
- updateButtons();
- }
-
- void FileSearchPathListComponent::paint (Graphics& g)
- {
- g.fillAll (findColour (backgroundColourId));
- }
-
- void FileSearchPathListComponent::resized()
- {
- const int buttonH = 22;
- const int buttonY = getHeight() - buttonH - 4;
- listBox->setBounds (2, 2, getWidth() - 4, buttonY - 5);
-
- addButton->setBounds (2, buttonY, buttonH, buttonH);
- removeButton->setBounds (addButton->getRight(), buttonY, buttonH, buttonH);
-
- ((TextButton*) changeButton)->changeWidthToFitText (buttonH);
- downButton->setSize (buttonH * 2, buttonH);
- upButton->setSize (buttonH * 2, buttonH);
-
- downButton->setTopRightPosition (getWidth() - 2, buttonY);
- upButton->setTopRightPosition (downButton->getX() - 4, buttonY);
- changeButton->setTopRightPosition (upButton->getX() - 8, buttonY);
- }
-
- bool FileSearchPathListComponent::isInterestedInFileDrag (const StringArray&)
- {
- return true;
- }
-
- void FileSearchPathListComponent::filesDropped (const StringArray& filenames, int, int mouseY)
- {
- for (int i = filenames.size(); --i >= 0;)
- {
- const File f (filenames[i]);
-
- if (f.isDirectory())
- {
- const int row = listBox->getRowContainingPosition (0, mouseY - listBox->getY());
- path.add (f, row);
- changed();
- }
- }
- }
-
- void FileSearchPathListComponent::buttonClicked (Button* button)
- {
- const int currentRow = listBox->getSelectedRow();
-
- if (button == removeButton)
- {
- deleteKeyPressed (currentRow);
- }
- else if (button == addButton)
- {
- File start (defaultBrowseTarget);
-
- if (start == File::nonexistent)
- start = path [0];
-
- if (start == File::nonexistent)
- start = File::getCurrentWorkingDirectory();
-
- FileChooser chooser (TRANS("Add a folder..."), start, T("*"));
-
- if (chooser.browseForDirectory())
- {
- path.add (chooser.getResult(), currentRow);
- }
- }
- else if (button == changeButton)
- {
- returnKeyPressed (currentRow);
- }
- else if (button == upButton)
- {
- if (currentRow > 0 && currentRow < path.getNumPaths())
- {
- const File f (path[currentRow]);
- path.remove (currentRow);
- path.add (f, currentRow - 1);
- listBox->selectRow (currentRow - 1);
- }
- }
- else if (button == downButton)
- {
- if (currentRow >= 0 && currentRow < path.getNumPaths() - 1)
- {
- const File f (path[currentRow]);
- path.remove (currentRow);
- path.add (f, currentRow + 1);
- listBox->selectRow (currentRow + 1);
- }
- }
-
- changed();
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_FileSearchPathListComponent.cpp *********/
-
- /********* Start of inlined file: juce_FileTreeComponent.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- Image* juce_createIconForFile (const File& file);
-
- class FileListTreeItem : public TreeViewItem,
- public TimeSliceClient,
- public AsyncUpdater,
- public ChangeListener
- {
- public:
-
- FileListTreeItem (FileTreeComponent& owner_,
- DirectoryContentsList* const parentContentsList_,
- const int indexInContentsList_,
- const File& file_,
- TimeSliceThread& thread_) throw()
- : file (file_),
- owner (owner_),
- parentContentsList (parentContentsList_),
- indexInContentsList (indexInContentsList_),
- subContentsList (0),
- canDeleteSubContentsList (false),
- thread (thread_),
- icon (0)
- {
- DirectoryContentsList::FileInfo fileInfo;
-
- if (parentContentsList_ != 0
- && parentContentsList_->getFileInfo (indexInContentsList_, fileInfo))
- {
- fileSize = File::descriptionOfSizeInBytes (fileInfo.fileSize);
- modTime = fileInfo.modificationTime.formatted (T("%d %b '%y %H:%M"));
- isDirectory = fileInfo.isDirectory;
- }
- else
- {
- isDirectory = true;
- }
- }
-
- ~FileListTreeItem() throw()
- {
- thread.removeTimeSliceClient (this);
-
- clearSubItems();
- ImageCache::release (icon);
-
- if (canDeleteSubContentsList)
- delete subContentsList;
- }
-
- bool mightContainSubItems() { return isDirectory; }
- const String getUniqueName() const { return file.getFullPathName(); }
- int getItemHeight() const { return 22; }
-
- const String getDragSourceDescription() { return owner.getDragAndDropDescription(); }
-
- void itemOpennessChanged (bool isNowOpen)
- {
- if (isNowOpen)
- {
- clearSubItems();
-
- isDirectory = file.isDirectory();
-
- if (isDirectory)
- {
- if (subContentsList == 0)
- {
- jassert (parentContentsList != 0);
-
- DirectoryContentsList* const l = new DirectoryContentsList (parentContentsList->getFilter(), thread);
- l->setDirectory (file, true, true);
-
- setSubContentsList (l);
- canDeleteSubContentsList = true;
- }
-
- changeListenerCallback (0);
- }
- }
- }
-
- void setSubContentsList (DirectoryContentsList* newList) throw()
- {
- jassert (subContentsList == 0);
- subContentsList = newList;
- newList->addChangeListener (this);
- }
-
- void changeListenerCallback (void*)
- {
- clearSubItems();
-
- if (isOpen() && subContentsList != 0)
- {
- for (int i = 0; i < subContentsList->getNumFiles(); ++i)
- {
- FileListTreeItem* const item
- = new FileListTreeItem (owner, subContentsList, i, subContentsList->getFile(i), thread);
-
- addSubItem (item);
- }
- }
- }
-
- void paintItem (Graphics& g, int width, int height)
- {
- if (file != File::nonexistent && ! isDirectory)
- {
- updateIcon (true);
-
- if (icon == 0)
- thread.addTimeSliceClient (this);
- }
-
- owner.getLookAndFeel()
- .drawFileBrowserRow (g, width, height,
- file.getFileName(),
- icon,
- fileSize, modTime,
- isDirectory, isSelected(),
- indexInContentsList);
- }
-
- void itemClicked (const MouseEvent& e)
- {
- owner.sendMouseClickMessage (file, e);
- }
-
- void itemDoubleClicked (const MouseEvent& e)
- {
- TreeViewItem::itemDoubleClicked (e);
-
- owner.sendDoubleClickMessage (file);
- }
-
- void itemSelectionChanged (bool)
- {
- owner.sendSelectionChangeMessage();
- }
-
- bool useTimeSlice()
- {
- updateIcon (false);
- thread.removeTimeSliceClient (this);
- return false;
- }
-
- void handleAsyncUpdate()
- {
- owner.repaint();
- }
-
- const File file;
-
- juce_UseDebuggingNewOperator
-
- private:
- FileTreeComponent& owner;
- DirectoryContentsList* parentContentsList;
- int indexInContentsList;
- DirectoryContentsList* subContentsList;
- bool isDirectory, canDeleteSubContentsList;
- TimeSliceThread& thread;
- Image* icon;
- String fileSize;
- String modTime;
-
- void updateIcon (const bool onlyUpdateIfCached) throw()
- {
- if (icon == 0)
- {
- const int hashCode = (file.getFullPathName() + T("_iconCacheSalt")).hashCode();
- Image* im = ImageCache::getFromHashCode (hashCode);
-
- if (im == 0 && ! onlyUpdateIfCached)
- {
- im = juce_createIconForFile (file);
-
- if (im != 0)
- ImageCache::addImageToCache (im, hashCode);
- }
-
- if (im != 0)
- {
- icon = im;
- triggerAsyncUpdate();
- }
- }
- }
- };
-
- FileTreeComponent::FileTreeComponent (DirectoryContentsList& listToShow)
- : DirectoryContentsDisplayComponent (listToShow)
- {
- FileListTreeItem* const root
- = new FileListTreeItem (*this, 0, 0, listToShow.getDirectory(),
- listToShow.getTimeSliceThread());
-
- root->setSubContentsList (&listToShow);
- setRootItemVisible (false);
- setRootItem (root);
- }
-
- FileTreeComponent::~FileTreeComponent()
- {
- TreeViewItem* const root = getRootItem();
- setRootItem (0);
- delete root;
- }
-
- const File FileTreeComponent::getSelectedFile() const
- {
- return getSelectedFile (0);
- }
-
- const File FileTreeComponent::getSelectedFile (const int index) const throw()
- {
- const FileListTreeItem* const item = dynamic_cast <const FileListTreeItem*> (getSelectedItem (index));
-
- if (item != 0)
- return item->file;
-
- return File::nonexistent;
- }
-
- void FileTreeComponent::scrollToTop()
- {
- getViewport()->getVerticalScrollBar()->setCurrentRangeStart (0);
- }
-
- void FileTreeComponent::setDragAndDropDescription (const String& description) throw()
- {
- dragAndDropDescription = description;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_FileTreeComponent.cpp *********/
-
- /********* Start of inlined file: juce_ImagePreviewComponent.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- ImagePreviewComponent::ImagePreviewComponent()
- : currentThumbnail (0)
- {
- }
-
- ImagePreviewComponent::~ImagePreviewComponent()
- {
- delete currentThumbnail;
- }
-
- void ImagePreviewComponent::getThumbSize (int& w, int& h) const
- {
- const int availableW = proportionOfWidth (0.97f);
- const int availableH = getHeight() - 13 * 4;
-
- const double scale = jmin (1.0,
- availableW / (double) w,
- availableH / (double) h);
-
- w = roundDoubleToInt (scale * w);
- h = roundDoubleToInt (scale * h);
- }
-
- void ImagePreviewComponent::selectedFileChanged (const File& file)
- {
- if (fileToLoad != file)
- {
- fileToLoad = file;
- startTimer (100);
- }
- }
-
- void ImagePreviewComponent::timerCallback()
- {
- stopTimer();
-
- deleteAndZero (currentThumbnail);
- currentDetails = String::empty;
- repaint();
-
- FileInputStream* const in = fileToLoad.createInputStream();
-
- if (in != 0)
- {
- ImageFileFormat* const format = ImageFileFormat::findImageFormatForStream (*in);
-
- if (format != 0)
- {
- currentThumbnail = format->decodeImage (*in);
-
- if (currentThumbnail != 0)
- {
- int w = currentThumbnail->getWidth();
- int h = currentThumbnail->getHeight();
-
- currentDetails
- << fileToLoad.getFileName() << "\n"
- << format->getFormatName() << "\n"
- << w << " x " << h << " pixels\n"
- << File::descriptionOfSizeInBytes (fileToLoad.getSize());
-
- getThumbSize (w, h);
-
- Image* const reduced = currentThumbnail->createCopy (w, h);
-
- delete currentThumbnail;
- currentThumbnail = reduced;
- }
- }
-
- delete in;
- }
- }
-
- void ImagePreviewComponent::paint (Graphics& g)
- {
- if (currentThumbnail != 0)
- {
- g.setFont (13.0f);
-
- int w = currentThumbnail->getWidth();
- int h = currentThumbnail->getHeight();
- getThumbSize (w, h);
-
- const int numLines = 4;
- const int totalH = 13 * numLines + h + 4;
- const int y = (getHeight() - totalH) / 2;
-
- g.drawImageWithin (currentThumbnail,
- (getWidth() - w) / 2, y, w, h,
- RectanglePlacement::centred | RectanglePlacement::onlyReduceInSize,
- false);
-
- g.drawFittedText (currentDetails,
- 0, y + h + 4, getWidth(), 100,
- Justification::centredTop, numLines);
- }
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_ImagePreviewComponent.cpp *********/
-
- /********* Start of inlined file: juce_WildcardFileFilter.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- WildcardFileFilter::WildcardFileFilter (const String& wildcardPatterns,
- const String& description)
- : FileFilter (description.isEmpty() ? wildcardPatterns
- : (description + T(" (") + wildcardPatterns + T(")")))
- {
- wildcards.addTokens (wildcardPatterns.toLowerCase(), T(";,"), T("\"'"));
-
- wildcards.trim();
- wildcards.removeEmptyStrings();
-
- // special case for *.*, because people use it to mean "any file", but it
- // would actually ignore files with no extension.
- for (int i = wildcards.size(); --i >= 0;)
- if (wildcards[i] == T("*.*"))
- wildcards.set (i, T("*"));
- }
-
- WildcardFileFilter::~WildcardFileFilter()
- {
- }
-
- bool WildcardFileFilter::isFileSuitable (const File& file) const
- {
- const String filename (file.getFileName());
-
- for (int i = wildcards.size(); --i >= 0;)
- if (filename.matchesWildcard (wildcards[i], true))
- return true;
-
- return false;
- }
-
- bool WildcardFileFilter::isDirectorySuitable (const File&) const
- {
- return true;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_WildcardFileFilter.cpp *********/
-
- /********* Start of inlined file: juce_KeyboardFocusTraverser.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- KeyboardFocusTraverser::KeyboardFocusTraverser()
- {
- }
-
- KeyboardFocusTraverser::~KeyboardFocusTraverser()
- {
- }
-
- // This will sort a set of components, so that they are ordered in terms of
- // left-to-right and then top-to-bottom.
- class ScreenPositionComparator
- {
- public:
- ScreenPositionComparator() {}
-
- static int compareElements (const Component* const first, const Component* const second) throw()
- {
- int explicitOrder1 = first->getExplicitFocusOrder();
- if (explicitOrder1 <= 0)
- explicitOrder1 = INT_MAX / 2;
-
- int explicitOrder2 = second->getExplicitFocusOrder();
- if (explicitOrder2 <= 0)
- explicitOrder2 = INT_MAX / 2;
-
- if (explicitOrder1 != explicitOrder2)
- return explicitOrder1 - explicitOrder2;
-
- const int diff = first->getY() - second->getY();
-
- return (diff == 0) ? first->getX() - second->getX()
- : diff;
- }
- };
-
- static void findAllFocusableComponents (Component* const parent, Array <Component*>& comps)
- {
- if (parent->getNumChildComponents() > 0)
- {
- Array <Component*> localComps;
- ScreenPositionComparator comparator;
-
- int i;
- for (i = parent->getNumChildComponents(); --i >= 0;)
- {
- Component* const c = parent->getChildComponent (i);
-
- if (c->isVisible() && c->isEnabled())
- localComps.addSorted (comparator, c);
- }
-
- for (i = 0; i < localComps.size(); ++i)
- {
- Component* const c = localComps.getUnchecked (i);
-
- if (c->getWantsKeyboardFocus())
- comps.add (c);
-
- if (! c->isFocusContainer())
- findAllFocusableComponents (c, comps);
- }
- }
- }
-
- static Component* getIncrementedComponent (Component* const current, const int delta) throw()
- {
- Component* focusContainer = current->getParentComponent();
-
- if (focusContainer != 0)
- {
- while (focusContainer->getParentComponent() != 0 && ! focusContainer->isFocusContainer())
- focusContainer = focusContainer->getParentComponent();
-
- if (focusContainer != 0)
- {
- Array <Component*> comps;
- findAllFocusableComponents (focusContainer, comps);
-
- if (comps.size() > 0)
- {
- const int index = comps.indexOf (current);
- return comps [(index + comps.size() + delta) % comps.size()];
- }
- }
- }
-
- return 0;
- }
-
- Component* KeyboardFocusTraverser::getNextComponent (Component* current)
- {
- return getIncrementedComponent (current, 1);
- }
-
- Component* KeyboardFocusTraverser::getPreviousComponent (Component* current)
- {
- return getIncrementedComponent (current, -1);
- }
-
- Component* KeyboardFocusTraverser::getDefaultComponent (Component* parentComponent)
- {
- Array <Component*> comps;
-
- if (parentComponent != 0)
- findAllFocusableComponents (parentComponent, comps);
-
- return comps.getFirst();
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_KeyboardFocusTraverser.cpp *********/
-
- /********* Start of inlined file: juce_KeyListener.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- bool KeyListener::keyStateChanged (Component*)
- {
- return false;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_KeyListener.cpp *********/
-
- /********* Start of inlined file: juce_KeyMappingEditorComponent.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- // N.B. these two includes are put here deliberately to avoid problems with
- // old GCCs failing on long include paths
-
- const int maxKeys = 3;
-
- class KeyMappingChangeButton : public Button
- {
- public:
- KeyMappingChangeButton (KeyMappingEditorComponent* const owner_,
- const CommandID commandID_,
- const String& keyName,
- const int keyNum_)
- : Button (keyName),
- owner (owner_),
- commandID (commandID_),
- keyNum (keyNum_)
- {
- setWantsKeyboardFocus (false);
- setTriggeredOnMouseDown (keyNum >= 0);
-
- if (keyNum_ < 0)
- setTooltip (TRANS("adds a new key-mapping"));
- else
- setTooltip (TRANS("click to change this key-mapping"));
- }
-
- ~KeyMappingChangeButton()
- {
- }
-
- void paintButton (Graphics& g, bool isOver, bool isDown)
- {
- if (keyNum >= 0)
- {
- if (isEnabled())
- {
- const float alpha = isDown ? 0.3f : (isOver ? 0.15f : 0.08f);
- g.fillAll (owner->textColour.withAlpha (alpha));
-
- g.setOpacity (0.3f);
- g.drawBevel (0, 0, getWidth(), getHeight(), 2);
- }
-
- g.setColour (owner->textColour);
- g.setFont (getHeight() * 0.6f);
- g.drawFittedText (getName(),
- 3, 0, getWidth() - 6, getHeight(),
- Justification::centred, 1);
- }
- else
- {
- const float thickness = 7.0f;
- const float indent = 22.0f;
-
- Path p;
- p.addEllipse (0.0f, 0.0f, 100.0f, 100.0f);
- p.addRectangle (indent, 50.0f - thickness, 100.0f - indent * 2.0f, thickness * 2.0f);
- p.addRectangle (50.0f - thickness, indent, thickness * 2.0f, 50.0f - indent - thickness);
- p.addRectangle (50.0f - thickness, 50.0f + thickness, thickness * 2.0f, 50.0f - indent - thickness);
- p.setUsingNonZeroWinding (false);
-
- g.setColour (owner->textColour.withAlpha (isDown ? 0.7f : (isOver ? 0.5f : 0.3f)));
- g.fillPath (p, p.getTransformToScaleToFit (2.0f, 2.0f, getWidth() - 4.0f, getHeight() - 4.0f, true));
- }
-
- if (hasKeyboardFocus (false))
- {
- g.setColour (owner->textColour.withAlpha (0.4f));
- g.drawRect (0, 0, getWidth(), getHeight());
- }
- }
-
- void clicked()
- {
- if (keyNum >= 0)
- {
- // existing key clicked..
- PopupMenu m;
- m.addItem (1, TRANS("change this key-mapping"));
- m.addSeparator();
- m.addItem (2, TRANS("remove this key-mapping"));
-
- const int res = m.show();
-
- if (res == 1)
- {
- owner->assignNewKey (commandID, keyNum);
- }
- else if (res == 2)
- {
- owner->getMappings()->removeKeyPress (commandID, keyNum);
- }
- }
- else
- {
- // + button pressed..
- owner->assignNewKey (commandID, -1);
- }
- }
-
- void fitToContent (const int h) throw()
- {
- if (keyNum < 0)
- {
- setSize (h, h);
- }
- else
- {
- Font f (h * 0.6f);
- setSize (jlimit (h * 4, h * 8, 6 + f.getStringWidth (getName())), h);
- }
- }
-
- juce_UseDebuggingNewOperator
-
- private:
- KeyMappingEditorComponent* const owner;
- const CommandID commandID;
- const int keyNum;
-
- KeyMappingChangeButton (const KeyMappingChangeButton&);
- const KeyMappingChangeButton& operator= (const KeyMappingChangeButton&);
- };
-
- class KeyMappingItemComponent : public Component
- {
- public:
- KeyMappingItemComponent (KeyMappingEditorComponent* const owner_,
- const CommandID commandID_)
- : owner (owner_),
- commandID (commandID_)
- {
- setInterceptsMouseClicks (false, true);
-
- const bool isReadOnly = owner_->isCommandReadOnly (commandID);
-
- const Array <KeyPress> keyPresses (owner_->getMappings()->getKeyPressesAssignedToCommand (commandID));
-
- for (int i = 0; i < jmin (maxKeys, keyPresses.size()); ++i)
- {
- KeyMappingChangeButton* const kb
- = new KeyMappingChangeButton (owner_, commandID,
- owner_->getDescriptionForKeyPress (keyPresses.getReference (i)), i);
-
- kb->setEnabled (! isReadOnly);
- addAndMakeVisible (kb);
- }
-
- KeyMappingChangeButton* const kb
- = new KeyMappingChangeButton (owner_, commandID, String::empty, -1);
-
- addChildComponent (kb);
- kb->setVisible (keyPresses.size() < maxKeys && ! isReadOnly);
- }
-
- ~KeyMappingItemComponent()
- {
- deleteAllChildren();
- }
-
- void paint (Graphics& g)
- {
- g.setFont (getHeight() * 0.7f);
- g.setColour (owner->textColour);
-
- g.drawFittedText (owner->getMappings()->getCommandManager()->getNameOfCommand (commandID),
- 4, 0, jmax (40, getChildComponent (0)->getX() - 5), getHeight(),
- Justification::centredLeft, true);
- }
-
- void resized()
- {
- int x = getWidth() - 4;
-
- for (int i = getNumChildComponents(); --i >= 0;)
- {
- KeyMappingChangeButton* const kb = dynamic_cast <KeyMappingChangeButton*> (getChildComponent (i));
-
- kb->fitToContent (getHeight() - 2);
- kb->setTopRightPosition (x, 1);
- x -= kb->getWidth() + 5;
- }
- }
-
- juce_UseDebuggingNewOperator
-
- private:
- KeyMappingEditorComponent* const owner;
- const CommandID commandID;
-
- KeyMappingItemComponent (const KeyMappingItemComponent&);
- const KeyMappingItemComponent& operator= (const KeyMappingItemComponent&);
- };
-
- class KeyMappingTreeViewItem : public TreeViewItem
- {
- public:
- KeyMappingTreeViewItem (KeyMappingEditorComponent* const owner_,
- const CommandID commandID_)
- : owner (owner_),
- commandID (commandID_)
- {
- }
-
- ~KeyMappingTreeViewItem()
- {
- }
-
- const String getUniqueName() const { return String ((int) commandID) + "_id"; }
- bool mightContainSubItems() { return false; }
- int getItemHeight() const { return 20; }
-
- Component* createItemComponent()
- {
- return new KeyMappingItemComponent (owner, commandID);
- }
-
- juce_UseDebuggingNewOperator
-
- private:
- KeyMappingEditorComponent* const owner;
- const CommandID commandID;
-
- KeyMappingTreeViewItem (const KeyMappingTreeViewItem&);
- const KeyMappingTreeViewItem& operator= (const KeyMappingTreeViewItem&);
- };
-
- class KeyCategoryTreeViewItem : public TreeViewItem
- {
- public:
- KeyCategoryTreeViewItem (KeyMappingEditorComponent* const owner_,
- const String& name)
- : owner (owner_),
- categoryName (name)
- {
- }
-
- ~KeyCategoryTreeViewItem()
- {
- }
-
- const String getUniqueName() const { return categoryName + "_cat"; }
- bool mightContainSubItems() { return true; }
- int getItemHeight() const { return 28; }
-
- void paintItem (Graphics& g, int width, int height)
- {
- g.setFont (height * 0.6f, Font::bold);
- g.setColour (owner->textColour);
-
- g.drawText (categoryName,
- 2, 0, width - 2, height,
- Justification::centredLeft, true);
- }
-
- void itemOpennessChanged (bool isNowOpen)
- {
- if (isNowOpen)
- {
- if (getNumSubItems() == 0)
- {
- Array <CommandID> commands (owner->getMappings()->getCommandManager()->getCommandsInCategory (categoryName));
-
- for (int i = 0; i < commands.size(); ++i)
- {
- if (owner->shouldCommandBeIncluded (commands[i]))
- addSubItem (new KeyMappingTreeViewItem (owner, commands[i]));
- }
- }
- }
- else
- {
- clearSubItems();
- }
- }
-
- juce_UseDebuggingNewOperator
-
- private:
- KeyMappingEditorComponent* owner;
- String categoryName;
-
- KeyCategoryTreeViewItem (const KeyCategoryTreeViewItem&);
- const KeyCategoryTreeViewItem& operator= (const KeyCategoryTreeViewItem&);
- };
-
- KeyMappingEditorComponent::KeyMappingEditorComponent (KeyPressMappingSet* const mappingManager,
- const bool showResetToDefaultButton)
- : mappings (mappingManager),
- textColour (Colours::black)
- {
- jassert (mappingManager != 0); // can't be null!
-
- mappingManager->addChangeListener (this);
-
- setLinesDrawnForSubItems (false);
-
- resetButton = 0;
-
- if (showResetToDefaultButton)
- {
- addAndMakeVisible (resetButton = new TextButton (TRANS("reset to defaults")));
- resetButton->addButtonListener (this);
- }
-
- addAndMakeVisible (tree = new TreeView());
- tree->setColour (TreeView::backgroundColourId, backgroundColour);
- tree->setRootItemVisible (false);
- tree->setDefaultOpenness (true);
- tree->setRootItem (this);
- }
-
- KeyMappingEditorComponent::~KeyMappingEditorComponent()
- {
- mappings->removeChangeListener (this);
- deleteAllChildren();
- }
-
- bool KeyMappingEditorComponent::mightContainSubItems()
- {
- return true;
- }
-
- const String KeyMappingEditorComponent::getUniqueName() const
- {
- return T("keys");
- }
-
- void KeyMappingEditorComponent::setColours (const Colour& mainBackground,
- const Colour& textColour_)
- {
- backgroundColour = mainBackground;
- textColour = textColour_;
- tree->setColour (TreeView::backgroundColourId, backgroundColour);
- }
-
- void KeyMappingEditorComponent::parentHierarchyChanged()
- {
- changeListenerCallback (0);
- }
-
- void KeyMappingEditorComponent::resized()
- {
- int h = getHeight();
-
- if (resetButton != 0)
- {
- const int buttonHeight = 20;
- h -= buttonHeight + 8;
- int x = getWidth() - 8;
- const int y = h + 6;
-
- resetButton->changeWidthToFitText (buttonHeight);
- resetButton->setTopRightPosition (x, y);
- }
-
- tree->setBounds (0, 0, getWidth(), h);
- }
-
- void KeyMappingEditorComponent::buttonClicked (Button* button)
- {
- if (button == resetButton)
- {
- if (AlertWindow::showOkCancelBox (AlertWindow::QuestionIcon,
- TRANS("Reset to defaults"),
- TRANS("Are you sure you want to reset all the key-mappings to their default state?"),
- TRANS("Reset")))
- {
- mappings->resetToDefaultMappings();
- }
- }
- }
-
- void KeyMappingEditorComponent::changeListenerCallback (void*)
- {
- XmlElement* openness = tree->getOpennessState (true);
-
- clearSubItems();
-
- const StringArray categories (mappings->getCommandManager()->getCommandCategories());
-
- for (int i = 0; i < categories.size(); ++i)
- {
- const Array <CommandID> commands (mappings->getCommandManager()->getCommandsInCategory (categories[i]));
- int count = 0;
-
- for (int j = 0; j < commands.size(); ++j)
- if (shouldCommandBeIncluded (commands[j]))
- ++count;
-
- if (count > 0)
- addSubItem (new KeyCategoryTreeViewItem (this, categories[i]));
- }
-
- if (openness != 0)
- {
- tree->restoreOpennessState (*openness);
- delete openness;
- }
- }
-
- class KeyEntryWindow : public AlertWindow
- {
- public:
- KeyEntryWindow (KeyMappingEditorComponent* const owner_)
- : AlertWindow (TRANS("New key-mapping"),
- TRANS("Please press a key combination now..."),
- AlertWindow::NoIcon),
- owner (owner_)
- {
- addButton (TRANS("ok"), 1);
- addButton (TRANS("cancel"), 0);
-
- // (avoid return + escape keys getting processed by the buttons..)
- for (int i = getNumChildComponents(); --i >= 0;)
- getChildComponent (i)->setWantsKeyboardFocus (false);
-
- setWantsKeyboardFocus (true);
- grabKeyboardFocus();
- }
-
- ~KeyEntryWindow()
- {
- }
-
- bool keyPressed (const KeyPress& key)
- {
- lastPress = key;
- String message (TRANS("Key: ") + owner->getDescriptionForKeyPress (key));
-
- const CommandID previousCommand = owner->getMappings()->findCommandForKeyPress (key);
-
- if (previousCommand != 0)
- {
- message << "\n\n"
- << TRANS("(Currently assigned to \"")
- << owner->getMappings()->getCommandManager()->getNameOfCommand (previousCommand)
- << "\")";
- }
-
- setMessage (message);
-
- return true;
- }
-
- bool keyStateChanged()
- {
- return true;
- }
-
- KeyPress lastPress;
-
- juce_UseDebuggingNewOperator
-
- private:
- KeyMappingEditorComponent* owner;
-
- KeyEntryWindow (const KeyEntryWindow&);
- const KeyEntryWindow& operator= (const KeyEntryWindow&);
- };
-
- void KeyMappingEditorComponent::assignNewKey (const CommandID commandID, const int index)
- {
- KeyEntryWindow entryWindow (this);
-
- if (entryWindow.runModalLoop() != 0)
- {
- entryWindow.setVisible (false);
-
- if (entryWindow.lastPress.isValid())
- {
- const CommandID previousCommand = mappings->findCommandForKeyPress (entryWindow.lastPress);
-
- if (previousCommand != 0)
- {
- if (! AlertWindow::showOkCancelBox (AlertWindow::WarningIcon,
- TRANS("Change key-mapping"),
- TRANS("This key is already assigned to the command \"")
- + mappings->getCommandManager()->getNameOfCommand (previousCommand)
- + TRANS("\"\n\nDo you want to re-assign it to this new command instead?"),
- TRANS("re-assign"),
- TRANS("cancel")))
- {
- return;
- }
- }
-
- mappings->removeKeyPress (entryWindow.lastPress);
-
- if (index >= 0)
- mappings->removeKeyPress (commandID, index);
-
- mappings->addKeyPress (commandID, entryWindow.lastPress, index);
- }
- }
- }
-
- bool KeyMappingEditorComponent::shouldCommandBeIncluded (const CommandID commandID)
- {
- const ApplicationCommandInfo* const ci = mappings->getCommandManager()->getCommandForID (commandID);
-
- return (ci != 0) && ((ci->flags & ApplicationCommandInfo::hiddenFromKeyEditor) == 0);
- }
-
- bool KeyMappingEditorComponent::isCommandReadOnly (const CommandID commandID)
- {
- const ApplicationCommandInfo* const ci = mappings->getCommandManager()->getCommandForID (commandID);
-
- return (ci != 0) && ((ci->flags & ApplicationCommandInfo::readOnlyInKeyEditor) != 0);
- }
-
- const String KeyMappingEditorComponent::getDescriptionForKeyPress (const KeyPress& key)
- {
- return key.getTextDescription();
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_KeyMappingEditorComponent.cpp *********/
-
- /********* Start of inlined file: juce_KeyPress.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- KeyPress::KeyPress() throw()
- : keyCode (0),
- mods (0),
- textCharacter (0)
- {
- }
-
- KeyPress::KeyPress (const int keyCode_,
- const ModifierKeys& mods_,
- const juce_wchar textCharacter_) throw()
- : keyCode (keyCode_),
- mods (mods_),
- textCharacter (textCharacter_)
- {
- }
-
- KeyPress::KeyPress (const int keyCode_) throw()
- : keyCode (keyCode_),
- textCharacter (0)
- {
- }
-
- KeyPress::KeyPress (const KeyPress& other) throw()
- : keyCode (other.keyCode),
- mods (other.mods),
- textCharacter (other.textCharacter)
- {
- }
-
- const KeyPress& KeyPress::operator= (const KeyPress& other) throw()
- {
- keyCode = other.keyCode;
- mods = other.mods;
- textCharacter = other.textCharacter;
-
- return *this;
- }
-
- bool KeyPress::operator== (const KeyPress& other) const throw()
- {
- return mods.getRawFlags() == other.mods.getRawFlags()
- && (textCharacter == other.textCharacter
- || textCharacter == 0
- || other.textCharacter == 0)
- && (keyCode == other.keyCode
- || (keyCode < 256
- && other.keyCode < 256
- && CharacterFunctions::toLowerCase ((tchar) keyCode)
- == CharacterFunctions::toLowerCase ((tchar) other.keyCode)));
- }
-
- bool KeyPress::operator!= (const KeyPress& other) const throw()
- {
- return ! operator== (other);
- }
-
- bool KeyPress::isCurrentlyDown() const throw()
- {
- return isKeyCurrentlyDown (keyCode)
- && (ModifierKeys::getCurrentModifiers().getRawFlags() & ModifierKeys::allKeyboardModifiers)
- == (mods.getRawFlags() & ModifierKeys::allKeyboardModifiers);
- }
-
- struct KeyNameAndCode
- {
- const char* name;
- int code;
- };
-
- static const KeyNameAndCode keyNameTranslations[] =
- {
- { "spacebar", KeyPress::spaceKey },
- { "return", KeyPress::returnKey },
- { "escape", KeyPress::escapeKey },
- { "backspace", KeyPress::backspaceKey },
- { "cursor left", KeyPress::leftKey },
- { "cursor right", KeyPress::rightKey },
- { "cursor up", KeyPress::upKey },
- { "cursor down", KeyPress::downKey },
- { "page up", KeyPress::pageUpKey },
- { "page down", KeyPress::pageDownKey },
- { "home", KeyPress::homeKey },
- { "end", KeyPress::endKey },
- { "delete", KeyPress::deleteKey },
- { "insert", KeyPress::insertKey },
- { "tab", KeyPress::tabKey },
- { "play", KeyPress::playKey },
- { "stop", KeyPress::stopKey },
- { "fast forward", KeyPress::fastForwardKey },
- { "rewind", KeyPress::rewindKey }
- };
-
- static const tchar* const numberPadPrefix = T("numpad ");
-
- const KeyPress KeyPress::createFromDescription (const String& desc) throw()
- {
- int modifiers = 0;
-
- if (desc.containsWholeWordIgnoreCase (T("ctrl"))
- || desc.containsWholeWordIgnoreCase (T("control"))
- || desc.containsWholeWordIgnoreCase (T("ctl")))
- modifiers |= ModifierKeys::ctrlModifier;
-
- if (desc.containsWholeWordIgnoreCase (T("shift"))
- || desc.containsWholeWordIgnoreCase (T("shft")))
- modifiers |= ModifierKeys::shiftModifier;
-
- if (desc.containsWholeWordIgnoreCase (T("alt"))
- || desc.containsWholeWordIgnoreCase (T("option")))
- modifiers |= ModifierKeys::altModifier;
-
- if (desc.containsWholeWordIgnoreCase (T("command"))
- || desc.containsWholeWordIgnoreCase (T("cmd")))
- modifiers |= ModifierKeys::commandModifier;
-
- int key = 0;
-
- for (int i = 0; i < numElementsInArray (keyNameTranslations); ++i)
- {
- if (desc.containsWholeWordIgnoreCase (String (keyNameTranslations[i].name)))
- {
- key = keyNameTranslations[i].code;
- break;
- }
- }
-
- if (key == 0)
- {
- // see if it's a numpad key..
- if (desc.containsIgnoreCase (numberPadPrefix))
- {
- const tchar lastChar = desc.trimEnd().getLastCharacter();
-
- if (lastChar >= T('0') && lastChar <= T('9'))
- key = numberPad0 + lastChar - T('0');
- else if (lastChar == T('+'))
- key = numberPadAdd;
- else if (lastChar == T('-'))
- key = numberPadSubtract;
- else if (lastChar == T('*'))
- key = numberPadMultiply;
- else if (lastChar == T('/'))
- key = numberPadDivide;
- else if (lastChar == T('.'))
- key = numberPadDecimalPoint;
- else if (lastChar == T('='))
- key = numberPadEquals;
- else if (desc.endsWith (T("separator")))
- key = numberPadSeparator;
- else if (desc.endsWith (T("delete")))
- key = numberPadDelete;
- }
-
- if (key == 0)
- {
- // see if it's a function key..
- for (int i = 1; i <= 12; ++i)
- if (desc.containsWholeWordIgnoreCase (T("f") + String (i)))
- key = F1Key + i - 1;
-
- if (key == 0)
- {
- // give up and use the hex code..
- const int hexCode = desc.fromFirstOccurrenceOf (T("#"), false, false)
- .toLowerCase()
- .retainCharacters (T("0123456789abcdef"))
- .getHexValue32();
-
- if (hexCode > 0)
- key = hexCode;
- else
- key = CharacterFunctions::toUpperCase (desc.getLastCharacter());
- }
- }
- }
-
- return KeyPress (key, ModifierKeys (modifiers), 0);
- }
-
- const String KeyPress::getTextDescription() const throw()
- {
- String desc;
-
- if (keyCode > 0)
- {
- // some keyboard layouts use a shift-key to get the slash, but in those cases, we
- // want to store it as being a slash, not shift+whatever.
- if (textCharacter == T('/'))
- return "/";
-
- if (mods.isCtrlDown())
- desc << "ctrl + ";
-
- if (mods.isShiftDown())
- desc << "shift + ";
-
- #if JUCE_MAC
- // only do this on the mac, because on Windows ctrl and command are the same,
- // and this would get confusing
- if (mods.isCommandDown())
- desc << "command + ";
-
- if (mods.isAltDown())
- desc << "option + ";
- #else
- if (mods.isAltDown())
- desc << "alt + ";
- #endif
-
- for (int i = 0; i < numElementsInArray (keyNameTranslations); ++i)
- if (keyCode == keyNameTranslations[i].code)
- return desc + keyNameTranslations[i].name;
-
- if (keyCode >= F1Key && keyCode <= F16Key)
- desc << 'F' << (1 + keyCode - F1Key);
- else if (keyCode >= numberPad0 && keyCode <= numberPad9)
- desc << numberPadPrefix << (keyCode - numberPad0);
- else if (keyCode >= 33 && keyCode < 176)
- desc += CharacterFunctions::toUpperCase ((tchar) keyCode);
- else if (keyCode == numberPadAdd)
- desc << numberPadPrefix << '+';
- else if (keyCode == numberPadSubtract)
- desc << numberPadPrefix << '-';
- else if (keyCode == numberPadMultiply)
- desc << numberPadPrefix << '*';
- else if (keyCode == numberPadDivide)
- desc << numberPadPrefix << '/';
- else if (keyCode == numberPadSeparator)
- desc << numberPadPrefix << "separator";
- else if (keyCode == numberPadDecimalPoint)
- desc << numberPadPrefix << '.';
- else if (keyCode == numberPadDelete)
- desc << numberPadPrefix << "delete";
- else
- desc << '#' << String::toHexString (keyCode);
- }
-
- return desc;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_KeyPress.cpp *********/
-
- /********* Start of inlined file: juce_KeyPressMappingSet.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- KeyPressMappingSet::KeyPressMappingSet (ApplicationCommandManager* const commandManager_) throw()
- : commandManager (commandManager_)
- {
- // A manager is needed to get the descriptions of commands, and will be called when
- // a command is invoked. So you can't leave this null..
- jassert (commandManager_ != 0);
-
- Desktop::getInstance().addFocusChangeListener (this);
- }
-
- KeyPressMappingSet::KeyPressMappingSet (const KeyPressMappingSet& other) throw()
- : commandManager (other.commandManager)
- {
- Desktop::getInstance().addFocusChangeListener (this);
- }
-
- KeyPressMappingSet::~KeyPressMappingSet()
- {
- Desktop::getInstance().removeFocusChangeListener (this);
- }
-
- const Array <KeyPress> KeyPressMappingSet::getKeyPressesAssignedToCommand (const CommandID commandID) const throw()
- {
- for (int i = 0; i < mappings.size(); ++i)
- if (mappings.getUnchecked(i)->commandID == commandID)
- return mappings.getUnchecked (i)->keypresses;
-
- return Array <KeyPress> ();
- }
-
- void KeyPressMappingSet::addKeyPress (const CommandID commandID,
- const KeyPress& newKeyPress,
- int insertIndex) throw()
- {
- if (findCommandForKeyPress (newKeyPress) != commandID)
- {
- removeKeyPress (newKeyPress);
-
- if (newKeyPress.isValid())
- {
- for (int i = mappings.size(); --i >= 0;)
- {
- if (mappings.getUnchecked(i)->commandID == commandID)
- {
- mappings.getUnchecked(i)->keypresses.insert (insertIndex, newKeyPress);
-
- sendChangeMessage (this);
- return;
- }
- }
-
- const ApplicationCommandInfo* const ci = commandManager->getCommandForID (commandID);
-
- if (ci != 0)
- {
- CommandMapping* const cm = new CommandMapping();
- cm->commandID = commandID;
- cm->keypresses.add (newKeyPress);
- cm->wantsKeyUpDownCallbacks = (ci->flags & ApplicationCommandInfo::wantsKeyUpDownCallbacks) != 0;
-
- mappings.add (cm);
- sendChangeMessage (this);
- }
- }
- }
- }
-
- void KeyPressMappingSet::resetToDefaultMappings() throw()
- {
- mappings.clear();
-
- for (int i = 0; i < commandManager->getNumCommands(); ++i)
- {
- const ApplicationCommandInfo* const ci = commandManager->getCommandForIndex (i);
-
- for (int j = 0; j < ci->defaultKeypresses.size(); ++j)
- {
- addKeyPress (ci->commandID,
- ci->defaultKeypresses.getReference (j));
- }
- }
-
- sendChangeMessage (this);
- }
-
- void KeyPressMappingSet::resetToDefaultMapping (const CommandID commandID) throw()
- {
- clearAllKeyPresses (commandID);
-
- const ApplicationCommandInfo* const ci = commandManager->getCommandForID (commandID);
-
- for (int j = 0; j < ci->defaultKeypresses.size(); ++j)
- {
- addKeyPress (ci->commandID,
- ci->defaultKeypresses.getReference (j));
- }
- }
-
- void KeyPressMappingSet::clearAllKeyPresses() throw()
- {
- if (mappings.size() > 0)
- {
- sendChangeMessage (this);
- mappings.clear();
- }
- }
-
- void KeyPressMappingSet::clearAllKeyPresses (const CommandID commandID) throw()
- {
- for (int i = mappings.size(); --i >= 0;)
- {
- if (mappings.getUnchecked(i)->commandID == commandID)
- {
- mappings.remove (i);
- sendChangeMessage (this);
- }
- }
- }
-
- void KeyPressMappingSet::removeKeyPress (const KeyPress& keypress) throw()
- {
- if (keypress.isValid())
- {
- for (int i = mappings.size(); --i >= 0;)
- {
- CommandMapping* const cm = mappings.getUnchecked(i);
-
- for (int j = cm->keypresses.size(); --j >= 0;)
- {
- if (keypress == cm->keypresses [j])
- {
- cm->keypresses.remove (j);
- sendChangeMessage (this);
- }
- }
- }
- }
- }
-
- void KeyPressMappingSet::removeKeyPress (const CommandID commandID,
- const int keyPressIndex) throw()
- {
- for (int i = mappings.size(); --i >= 0;)
- {
- if (mappings.getUnchecked(i)->commandID == commandID)
- {
- mappings.getUnchecked(i)->keypresses.remove (keyPressIndex);
- sendChangeMessage (this);
- break;
- }
- }
- }
-
- CommandID KeyPressMappingSet::findCommandForKeyPress (const KeyPress& keyPress) const throw()
- {
- for (int i = 0; i < mappings.size(); ++i)
- if (mappings.getUnchecked(i)->keypresses.contains (keyPress))
- return mappings.getUnchecked(i)->commandID;
-
- return 0;
- }
-
- bool KeyPressMappingSet::containsMapping (const CommandID commandID,
- const KeyPress& keyPress) const throw()
- {
- for (int i = mappings.size(); --i >= 0;)
- if (mappings.getUnchecked(i)->commandID == commandID)
- return mappings.getUnchecked(i)->keypresses.contains (keyPress);
-
- return false;
- }
-
- void KeyPressMappingSet::invokeCommand (const CommandID commandID,
- const KeyPress& key,
- const bool isKeyDown,
- const int millisecsSinceKeyPressed,
- Component* const originatingComponent) const
- {
- ApplicationCommandTarget::InvocationInfo info (commandID);
-
- info.invocationMethod = ApplicationCommandTarget::InvocationInfo::fromKeyPress;
- info.isKeyDown = isKeyDown;
- info.keyPress = key;
- info.millisecsSinceKeyPressed = millisecsSinceKeyPressed;
- info.originatingComponent = originatingComponent;
-
- commandManager->invoke (info, false);
- }
-
- bool KeyPressMappingSet::restoreFromXml (const XmlElement& xmlVersion)
- {
- if (xmlVersion.hasTagName (T("KEYMAPPINGS")))
- {
- if (xmlVersion.getBoolAttribute (T("basedOnDefaults"), true))
- {
- // if the XML was created as a set of differences from the default mappings,
- // (i.e. by calling createXml (true)), then we need to first restore the defaults.
- resetToDefaultMappings();
- }
- else
- {
- // if the XML was created calling createXml (false), then we need to clear all
- // the keys and treat the xml as describing the entire set of mappings.
- clearAllKeyPresses();
- }
-
- forEachXmlChildElement (xmlVersion, map)
- {
- const CommandID commandId = map->getStringAttribute (T("commandId")).getHexValue32();
-
- if (commandId != 0)
- {
- const KeyPress key (KeyPress::createFromDescription (map->getStringAttribute (T("key"))));
-
- if (map->hasTagName (T("MAPPING")))
- {
- addKeyPress (commandId, key);
- }
- else if (map->hasTagName (T("UNMAPPING")))
- {
- if (containsMapping (commandId, key))
- removeKeyPress (key);
- }
- }
- }
-
- return true;
- }
-
- return false;
- }
-
- XmlElement* KeyPressMappingSet::createXml (const bool saveDifferencesFromDefaultSet) const
- {
- KeyPressMappingSet* defaultSet = 0;
-
- if (saveDifferencesFromDefaultSet)
- {
- defaultSet = new KeyPressMappingSet (commandManager);
- defaultSet->resetToDefaultMappings();
- }
-
- XmlElement* const doc = new XmlElement (T("KEYMAPPINGS"));
-
- doc->setAttribute (T("basedOnDefaults"), saveDifferencesFromDefaultSet);
-
- int i;
- for (i = 0; i < mappings.size(); ++i)
- {
- const CommandMapping* const cm = mappings.getUnchecked(i);
-
- for (int j = 0; j < cm->keypresses.size(); ++j)
- {
- if (defaultSet == 0
- || ! defaultSet->containsMapping (cm->commandID, cm->keypresses.getReference (j)))
- {
- XmlElement* const map = new XmlElement (T("MAPPING"));
-
- map->setAttribute (T("commandId"), String::toHexString ((int) cm->commandID));
- map->setAttribute (T("description"), commandManager->getDescriptionOfCommand (cm->commandID));
- map->setAttribute (T("key"), cm->keypresses.getReference (j).getTextDescription());
-
- doc->addChildElement (map);
- }
- }
- }
-
- if (defaultSet != 0)
- {
- for (i = 0; i < defaultSet->mappings.size(); ++i)
- {
- const CommandMapping* const cm = defaultSet->mappings.getUnchecked(i);
-
- for (int j = 0; j < cm->keypresses.size(); ++j)
- {
- if (! containsMapping (cm->commandID, cm->keypresses.getReference (j)))
- {
- XmlElement* const map = new XmlElement (T("UNMAPPING"));
-
- map->setAttribute (T("commandId"), String::toHexString ((int) cm->commandID));
- map->setAttribute (T("description"), commandManager->getDescriptionOfCommand (cm->commandID));
- map->setAttribute (T("key"), cm->keypresses.getReference (j).getTextDescription());
-
- doc->addChildElement (map);
- }
- }
- }
-
- delete defaultSet;
- }
-
- return doc;
- }
-
- bool KeyPressMappingSet::keyPressed (const KeyPress& key,
- Component* originatingComponent)
- {
- bool used = false;
-
- const CommandID commandID = findCommandForKeyPress (key);
-
- const ApplicationCommandInfo* const ci = commandManager->getCommandForID (commandID);
-
- if (ci != 0
- && (ci->flags & ApplicationCommandInfo::wantsKeyUpDownCallbacks) == 0)
- {
- ApplicationCommandInfo info (0);
-
- if (commandManager->getTargetForCommand (commandID, info) != 0
- && (info.flags & ApplicationCommandInfo::isDisabled) == 0)
- {
- invokeCommand (commandID, key, true, 0, originatingComponent);
- used = true;
- }
- else
- {
- if (originatingComponent != 0)
- originatingComponent->getLookAndFeel().playAlertSound();
- }
- }
-
- return used;
- }
-
- bool KeyPressMappingSet::keyStateChanged (Component* originatingComponent)
- {
- bool used = false;
- const uint32 now = Time::getMillisecondCounter();
-
- for (int i = mappings.size(); --i >= 0;)
- {
- CommandMapping* const cm = mappings.getUnchecked(i);
-
- if (cm->wantsKeyUpDownCallbacks)
- {
- for (int j = cm->keypresses.size(); --j >= 0;)
- {
- const KeyPress key (cm->keypresses.getReference (j));
- const bool isDown = key.isCurrentlyDown();
-
- int keyPressEntryIndex = 0;
- bool wasDown = false;
-
- for (int k = keysDown.size(); --k >= 0;)
- {
- if (key == keysDown.getUnchecked(k)->key)
- {
- keyPressEntryIndex = k;
- wasDown = true;
- break;
- }
- }
-
- if (isDown != wasDown)
- {
- int millisecs = 0;
-
- if (isDown)
- {
- KeyPressTime* const k = new KeyPressTime();
- k->key = key;
- k->timeWhenPressed = now;
-
- keysDown.add (k);
- }
- else
- {
- const uint32 pressTime = keysDown.getUnchecked (keyPressEntryIndex)->timeWhenPressed;
-
- if (now > pressTime)
- millisecs = now - pressTime;
-
- keysDown.remove (keyPressEntryIndex);
- }
-
- invokeCommand (cm->commandID, key, isDown, millisecs, originatingComponent);
- used = true;
- }
- }
- }
- }
-
- return used;
- }
-
- void KeyPressMappingSet::globalFocusChanged (Component* focusedComponent)
- {
- if (focusedComponent != 0)
- focusedComponent->keyStateChanged();
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_KeyPressMappingSet.cpp *********/
-
- /********* Start of inlined file: juce_ModifierKeys.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- ModifierKeys::ModifierKeys (const int flags_) throw()
- : flags (flags_)
- {
- }
-
- ModifierKeys::ModifierKeys (const ModifierKeys& other) throw()
- : flags (other.flags)
- {
- }
-
- const ModifierKeys& ModifierKeys::operator= (const ModifierKeys& other) throw()
- {
- flags = other.flags;
- return *this;
- }
-
- int ModifierKeys::currentModifierFlags = 0;
-
- const ModifierKeys ModifierKeys::getCurrentModifiers() throw()
- {
- return ModifierKeys (currentModifierFlags);
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_ModifierKeys.cpp *********/
-
- /********* Start of inlined file: juce_ComponentAnimator.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- struct AnimationTask
- {
- AnimationTask (Component* const comp)
- : component (comp),
- watcher (comp)
- {
- }
-
- Component* component;
- ComponentDeletionWatcher watcher;
- Rectangle destination;
- int msElapsed, msTotal;
- double startSpeed, midSpeed, endSpeed, lastProgress;
- double left, top, right, bottom;
-
- bool useTimeslice (const int elapsed)
- {
- if (watcher.hasBeenDeleted())
- return false;
-
- msElapsed += elapsed;
- double newProgress = msElapsed / (double) msTotal;
-
- if (newProgress >= 0 && newProgress < 1.0)
- {
- newProgress = timeToDistance (newProgress);
- const double delta = (newProgress - lastProgress) / (1.0 - lastProgress);
- jassert (newProgress >= lastProgress);
- lastProgress = newProgress;
-
- left += (destination.getX() - left) * delta;
- top += (destination.getY() - top) * delta;
- right += (destination.getRight() - right) * delta;
- bottom += (destination.getBottom() - bottom) * delta;
-
- if (delta < 1.0)
- {
- const Rectangle newBounds (roundDoubleToInt (left),
- roundDoubleToInt (top),
- roundDoubleToInt (right - left),
- roundDoubleToInt (bottom - top));
-
- if (newBounds != destination)
- {
- component->setBounds (newBounds);
- return true;
- }
- }
- }
-
- component->setBounds (destination);
- return false;
- }
-
- void moveToFinalDestination()
- {
- if (! watcher.hasBeenDeleted())
- component->setBounds (destination);
- }
-
- private:
- inline double timeToDistance (const double time) const
- {
- return (time < 0.5) ? time * (startSpeed + time * (midSpeed - startSpeed))
- : 0.5 * (startSpeed + 0.5 * (midSpeed - startSpeed))
- + (time - 0.5) * (midSpeed + (time - 0.5) * (endSpeed - midSpeed));
- }
- };
-
- ComponentAnimator::ComponentAnimator()
- : lastTime (0)
- {
- }
-
- ComponentAnimator::~ComponentAnimator()
- {
- cancelAllAnimations (false);
- jassert (tasks.size() == 0);
- }
-
- void* ComponentAnimator::findTaskFor (Component* const component) const
- {
- for (int i = tasks.size(); --i >= 0;)
- if (component == ((AnimationTask*) tasks.getUnchecked(i))->component)
- return tasks.getUnchecked(i);
-
- return 0;
- }
-
- void ComponentAnimator::animateComponent (Component* const component,
- const Rectangle& finalPosition,
- const int millisecondsToSpendMoving,
- const double startSpeed,
- const double endSpeed)
- {
- if (component != 0)
- {
- AnimationTask* at = (AnimationTask*) findTaskFor (component);
-
- if (at == 0)
- {
- at = new AnimationTask (component);
- tasks.add (at);
- }
-
- at->msElapsed = 0;
- at->lastProgress = 0;
- at->msTotal = jmax (1, millisecondsToSpendMoving);
- at->destination = finalPosition;
-
- // the speeds must be 0 or greater!
- jassert (startSpeed >= 0 && endSpeed >= 0)
-
- const double invTotalDistance = 4.0 / (startSpeed + endSpeed + 2.0);
- at->startSpeed = jmax (0.0, startSpeed * invTotalDistance);
- at->midSpeed = invTotalDistance;
- at->endSpeed = jmax (0.0, endSpeed * invTotalDistance);
-
- at->left = component->getX();
- at->top = component->getY();
- at->right = component->getRight();
- at->bottom = component->getBottom();
-
- if (! isTimerRunning())
- {
- lastTime = Time::getMillisecondCounter();
- startTimer (1000 / 50);
- }
- }
- }
-
- void ComponentAnimator::cancelAllAnimations (const bool moveComponentsToTheirFinalPositions)
- {
- for (int i = tasks.size(); --i >= 0;)
- {
- AnimationTask* const at = (AnimationTask*) tasks.getUnchecked(i);
-
- if (moveComponentsToTheirFinalPositions)
- at->moveToFinalDestination();
-
- delete at;
- tasks.remove (i);
- }
- }
-
- void ComponentAnimator::cancelAnimation (Component* const component,
- const bool moveComponentToItsFinalPosition)
- {
- AnimationTask* const at = (AnimationTask*) findTaskFor (component);
-
- if (at != 0)
- {
- if (moveComponentToItsFinalPosition)
- at->moveToFinalDestination();
-
- tasks.removeValue (at);
- delete at;
- }
- }
-
- const Rectangle ComponentAnimator::getComponentDestination (Component* const component)
- {
- AnimationTask* const at = (AnimationTask*) findTaskFor (component);
-
- if (at != 0)
- return at->destination;
- else if (component != 0)
- return component->getBounds();
-
- return Rectangle();
- }
-
- void ComponentAnimator::timerCallback()
- {
- const uint32 timeNow = Time::getMillisecondCounter();
-
- if (lastTime == 0 || lastTime == timeNow)
- lastTime = timeNow;
-
- const int elapsed = timeNow - lastTime;
-
- for (int i = tasks.size(); --i >= 0;)
- {
- AnimationTask* const at = (AnimationTask*) tasks.getUnchecked(i);
-
- if (! at->useTimeslice (elapsed))
- {
- tasks.remove (i);
- delete at;
- }
- }
-
- lastTime = timeNow;
-
- if (tasks.size() == 0)
- stopTimer();
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_ComponentAnimator.cpp *********/
-
- /********* Start of inlined file: juce_ComponentBoundsConstrainer.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- ComponentBoundsConstrainer::ComponentBoundsConstrainer() throw()
- : minW (0),
- maxW (0x3fffffff),
- minH (0),
- maxH (0x3fffffff),
- minOffTop (0),
- minOffLeft (0),
- minOffBottom (0),
- minOffRight (0),
- aspectRatio (0.0)
- {
- }
-
- ComponentBoundsConstrainer::~ComponentBoundsConstrainer()
- {
- }
-
- void ComponentBoundsConstrainer::setMinimumWidth (const int minimumWidth) throw()
- {
- minW = minimumWidth;
- }
-
- void ComponentBoundsConstrainer::setMaximumWidth (const int maximumWidth) throw()
- {
- maxW = maximumWidth;
- }
-
- void ComponentBoundsConstrainer::setMinimumHeight (const int minimumHeight) throw()
- {
- minH = minimumHeight;
- }
-
- void ComponentBoundsConstrainer::setMaximumHeight (const int maximumHeight) throw()
- {
- maxH = maximumHeight;
- }
-
- void ComponentBoundsConstrainer::setMinimumSize (const int minimumWidth, const int minimumHeight) throw()
- {
- jassert (maxW >= minimumWidth);
- jassert (maxH >= minimumHeight);
- jassert (minimumWidth > 0 && minimumHeight > 0);
-
- minW = minimumWidth;
- minH = minimumHeight;
-
- if (minW > maxW)
- maxW = minW;
-
- if (minH > maxH)
- maxH = minH;
- }
-
- void ComponentBoundsConstrainer::setMaximumSize (const int maximumWidth, const int maximumHeight) throw()
- {
- jassert (maximumWidth >= minW);
- jassert (maximumHeight >= minH);
- jassert (maximumWidth > 0 && maximumHeight > 0);
-
- maxW = jmax (minW, maximumWidth);
- maxH = jmax (minH, maximumHeight);
- }
-
- void ComponentBoundsConstrainer::setSizeLimits (const int minimumWidth,
- const int minimumHeight,
- const int maximumWidth,
- const int maximumHeight) throw()
- {
- jassert (maximumWidth >= minimumWidth);
- jassert (maximumHeight >= minimumHeight);
- jassert (maximumWidth > 0 && maximumHeight > 0);
- jassert (minimumWidth > 0 && minimumHeight > 0);
-
- minW = jmax (0, minimumWidth);
- minH = jmax (0, minimumHeight);
- maxW = jmax (minW, maximumWidth);
- maxH = jmax (minH, maximumHeight);
- }
-
- void ComponentBoundsConstrainer::setMinimumOnscreenAmounts (const int minimumWhenOffTheTop,
- const int minimumWhenOffTheLeft,
- const int minimumWhenOffTheBottom,
- const int minimumWhenOffTheRight) throw()
- {
- minOffTop = minimumWhenOffTheTop;
- minOffLeft = minimumWhenOffTheLeft;
- minOffBottom = minimumWhenOffTheBottom;
- minOffRight = minimumWhenOffTheRight;
- }
-
- void ComponentBoundsConstrainer::setFixedAspectRatio (const double widthOverHeight) throw()
- {
- aspectRatio = jmax (0.0, widthOverHeight);
- }
-
- double ComponentBoundsConstrainer::getFixedAspectRatio() const throw()
- {
- return aspectRatio;
- }
-
- void ComponentBoundsConstrainer::setBoundsForComponent (Component* const component,
- int x, int y, int w, int h,
- const bool isStretchingTop,
- const bool isStretchingLeft,
- const bool isStretchingBottom,
- const bool isStretchingRight)
- {
- jassert (component != 0);
-
- Rectangle limits;
- Component* const p = component->getParentComponent();
-
- if (p == 0)
- limits = Desktop::getInstance().getAllMonitorDisplayAreas().getBounds();
- else
- limits.setSize (p->getWidth(), p->getHeight());
-
- if (component->isOnDesktop())
- {
- ComponentPeer* const peer = component->getPeer();
- const BorderSize border (peer->getFrameSize());
-
- x -= border.getLeft();
- y -= border.getTop();
- w += border.getLeftAndRight();
- h += border.getTopAndBottom();
-
- checkBounds (x, y, w, h,
- border.addedTo (component->getBounds()), limits,
- isStretchingTop, isStretchingLeft,
- isStretchingBottom, isStretchingRight);
-
- x += border.getLeft();
- y += border.getTop();
- w -= border.getLeftAndRight();
- h -= border.getTopAndBottom();
- }
- else
- {
- checkBounds (x, y, w, h,
- component->getBounds(), limits,
- isStretchingTop, isStretchingLeft,
- isStretchingBottom, isStretchingRight);
- }
-
- applyBoundsToComponent (component, x, y, w, h);
- }
-
- void ComponentBoundsConstrainer::applyBoundsToComponent (Component* component,
- int x, int y, int w, int h)
- {
- component->setBounds (x, y, w, h);
- }
-
- void ComponentBoundsConstrainer::resizeStart()
- {
- }
-
- void ComponentBoundsConstrainer::resizeEnd()
- {
- }
-
- void ComponentBoundsConstrainer::checkBounds (int& x, int& y, int& w, int& h,
- const Rectangle& old,
- const Rectangle& limits,
- const bool isStretchingTop,
- const bool isStretchingLeft,
- const bool isStretchingBottom,
- const bool isStretchingRight)
- {
- // constrain the size if it's being stretched..
- if (isStretchingLeft)
- {
- x = jlimit (old.getRight() - maxW, old.getRight() - minW, x);
- w = old.getRight() - x;
- }
-
- if (isStretchingRight)
- {
- w = jlimit (minW, maxW, w);
- }
-
- if (isStretchingTop)
- {
- y = jlimit (old.getBottom() - maxH, old.getBottom() - minH, y);
- h = old.getBottom() - y;
- }
-
- if (isStretchingBottom)
- {
- h = jlimit (minH, maxH, h);
- }
-
- // constrain the aspect ratio if one has been specified..
- if (aspectRatio > 0.0 && w > 0 && h > 0)
- {
- bool adjustWidth;
-
- if ((isStretchingTop || isStretchingBottom) && ! (isStretchingLeft || isStretchingRight))
- {
- adjustWidth = true;
- }
- else if ((isStretchingLeft || isStretchingRight) && ! (isStretchingTop || isStretchingBottom))
- {
- adjustWidth = false;
- }
- else
- {
- const double oldRatio = (old.getHeight() > 0) ? fabs (old.getWidth() / (double) old.getHeight()) : 0.0;
- const double newRatio = fabs (w / (double) h);
-
- adjustWidth = (oldRatio > newRatio);
- }
-
- if (adjustWidth)
- {
- w = roundDoubleToInt (h * aspectRatio);
-
- if (w > maxW || w < minW)
- {
- w = jlimit (minW, maxW, w);
- h = roundDoubleToInt (w / aspectRatio);
- }
- }
- else
- {
- h = roundDoubleToInt (w / aspectRatio);
-
- if (h > maxH || h < minH)
- {
- h = jlimit (minH, maxH, h);
- w = roundDoubleToInt (h * aspectRatio);
- }
- }
-
- if ((isStretchingTop || isStretchingBottom) && ! (isStretchingLeft || isStretchingRight))
- {
- x = old.getX() + (old.getWidth() - w) / 2;
- }
- else if ((isStretchingLeft || isStretchingRight) && ! (isStretchingTop || isStretchingBottom))
- {
- y = old.getY() + (old.getHeight() - h) / 2;
- }
- else
- {
- if (isStretchingLeft)
- x = old.getRight() - w;
-
- if (isStretchingTop)
- y = old.getBottom() - h;
- }
- }
-
- // ...and constrain the position if limits have been set for that.
- if (minOffTop > 0 || minOffLeft > 0 || minOffBottom > 0 || minOffRight > 0)
- {
- if (minOffTop > 0)
- {
- const int limit = limits.getY() + jmin (minOffTop - h, 0);
-
- if (y < limit)
- {
- if (isStretchingTop)
- h -= (limit - y);
-
- y = limit;
- }
- }
-
- if (minOffLeft > 0)
- {
- const int limit = limits.getX() + jmin (minOffLeft - w, 0);
-
- if (x < limit)
- {
- if (isStretchingLeft)
- w -= (limit - x);
-
- x = limit;
- }
- }
-
- if (minOffBottom > 0)
- {
- const int limit = limits.getBottom() - jmin (minOffBottom, h);
-
- if (y > limit)
- {
- if (isStretchingBottom)
- h += (limit - y);
- else
- y = limit;
- }
- }
-
- if (minOffRight > 0)
- {
- const int limit = limits.getRight() - jmin (minOffRight, w);
-
- if (x > limit)
- {
- if (isStretchingRight)
- w += (limit - x);
- else
- x = limit;
- }
- }
- }
-
- jassert (w >= 0 && h >= 0);
-
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_ComponentBoundsConstrainer.cpp *********/
-
- /********* Start of inlined file: juce_ComponentMovementWatcher.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- ComponentMovementWatcher::ComponentMovementWatcher (Component* const component_)
- : component (component_),
- lastPeer (0),
- registeredParentComps (4),
- reentrant (false)
- {
- jassert (component != 0); // can't use this with a null pointer..
-
- #ifdef JUCE_DEBUG
- deletionWatcher = new ComponentDeletionWatcher (component_);
- #endif
-
- component->addComponentListener (this);
-
- registerWithParentComps();
- }
-
- ComponentMovementWatcher::~ComponentMovementWatcher()
- {
- component->removeComponentListener (this);
-
- unregister();
-
- #ifdef JUCE_DEBUG
- delete deletionWatcher;
- #endif
- }
-
- void ComponentMovementWatcher::componentParentHierarchyChanged (Component&)
- {
- #ifdef JUCE_DEBUG
- // agh! don't delete the target component without deleting this object first!
- jassert (! deletionWatcher->hasBeenDeleted());
- #endif
-
- if (! reentrant)
- {
- reentrant = true;
-
- ComponentPeer* const peer = component->getPeer();
-
- if (peer != lastPeer)
- {
- ComponentDeletionWatcher watcher (component);
-
- componentPeerChanged();
-
- if (watcher.hasBeenDeleted())
- return;
-
- lastPeer = peer;
- }
-
- unregister();
- registerWithParentComps();
-
- reentrant = false;
-
- componentMovedOrResized (*component, true, true);
- }
- }
-
- void ComponentMovementWatcher::componentMovedOrResized (Component&, bool wasMoved, bool wasResized)
- {
- #ifdef JUCE_DEBUG
- // agh! don't delete the target component without deleting this object first!
- jassert (! deletionWatcher->hasBeenDeleted());
- #endif
-
- if (wasMoved)
- {
- int x = 0, y = 0;
- component->relativePositionToOtherComponent (component->getTopLevelComponent(), x, y);
-
- wasMoved = (lastX != x || lastY != y);
- lastX = x;
- lastY = y;
- }
-
- wasResized = (lastWidth != component->getWidth() || lastHeight != component->getHeight());
- lastWidth = component->getWidth();
- lastHeight = component->getHeight();
-
- if (wasMoved || wasResized)
- componentMovedOrResized (wasMoved, wasResized);
- }
-
- void ComponentMovementWatcher::registerWithParentComps() throw()
- {
- Component* p = component->getParentComponent();
-
- while (p != 0)
- {
- p->addComponentListener (this);
- registeredParentComps.add (p);
- p = p->getParentComponent();
- }
- }
-
- void ComponentMovementWatcher::unregister() throw()
- {
- for (int i = registeredParentComps.size(); --i >= 0;)
- ((Component*) registeredParentComps.getUnchecked(i))->removeComponentListener (this);
-
- registeredParentComps.clear();
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_ComponentMovementWatcher.cpp *********/
-
- /********* Start of inlined file: juce_GroupComponent.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- GroupComponent::GroupComponent (const String& componentName,
- const String& labelText)
- : Component (componentName),
- text (labelText),
- justification (Justification::left)
- {
- setInterceptsMouseClicks (false, true);
- }
-
- GroupComponent::~GroupComponent()
- {
- }
-
- void GroupComponent::setText (const String& newText) throw()
- {
- if (text != newText)
- {
- text = newText;
- repaint();
- }
- }
-
- const String GroupComponent::getText() const throw()
- {
- return text;
- }
-
- void GroupComponent::setTextLabelPosition (const Justification& newJustification)
- {
- if (justification.getFlags() != newJustification.getFlags())
- {
- justification = newJustification;
- repaint();
- }
- }
-
- void GroupComponent::paint (Graphics& g)
- {
- getLookAndFeel()
- .drawGroupComponentOutline (g, getWidth(), getHeight(),
- text, justification,
- *this);
- }
-
- void GroupComponent::enablementChanged()
- {
- repaint();
- }
-
- void GroupComponent::colourChanged()
- {
- repaint();
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_GroupComponent.cpp *********/
-
- /********* Start of inlined file: juce_MultiDocumentPanel.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- MultiDocumentPanelWindow::MultiDocumentPanelWindow (const Colour& backgroundColour)
- : DocumentWindow (String::empty, backgroundColour,
- DocumentWindow::maximiseButton | DocumentWindow::closeButton, false)
- {
- }
-
- MultiDocumentPanelWindow::~MultiDocumentPanelWindow()
- {
- }
-
- void MultiDocumentPanelWindow::maximiseButtonPressed()
- {
- MultiDocumentPanel* const owner = getOwner();
-
- jassert (owner != 0); // these windows are only designed to be used inside a MultiDocumentPanel!
- if (owner != 0)
- owner->setLayoutMode (MultiDocumentPanel::MaximisedWindowsWithTabs);
- }
-
- void MultiDocumentPanelWindow::closeButtonPressed()
- {
- MultiDocumentPanel* const owner = getOwner();
-
- jassert (owner != 0); // these windows are only designed to be used inside a MultiDocumentPanel!
- if (owner != 0)
- owner->closeDocument (getContentComponent(), true);
- }
-
- void MultiDocumentPanelWindow::activeWindowStatusChanged()
- {
- DocumentWindow::activeWindowStatusChanged();
- updateOrder();
- }
-
- void MultiDocumentPanelWindow::broughtToFront()
- {
- DocumentWindow::broughtToFront();
- updateOrder();
- }
-
- void MultiDocumentPanelWindow::updateOrder()
- {
- MultiDocumentPanel* const owner = getOwner();
-
- if (owner != 0)
- owner->updateOrder();
- }
-
- MultiDocumentPanel* MultiDocumentPanelWindow::getOwner() const throw()
- {
- // (unable to use the syntax findParentComponentOfClass <MultiDocumentPanel> () because of a VC6 compiler bug)
- return findParentComponentOfClass ((MultiDocumentPanel*) 0);
- }
-
- class MDITabbedComponentInternal : public TabbedComponent
- {
- public:
- MDITabbedComponentInternal()
- : TabbedComponent (TabbedButtonBar::TabsAtTop)
- {
- }
-
- ~MDITabbedComponentInternal()
- {
- }
-
- void currentTabChanged (const int, const String&)
- {
- // (unable to use the syntax findParentComponentOfClass <MultiDocumentPanel> () because of a VC6 compiler bug)
- MultiDocumentPanel* const owner = findParentComponentOfClass ((MultiDocumentPanel*) 0);
-
- if (owner != 0)
- owner->updateOrder();
- }
- };
-
- MultiDocumentPanel::MultiDocumentPanel()
- : mode (MaximisedWindowsWithTabs),
- tabComponent (0),
- backgroundColour (Colours::lightblue),
- maximumNumDocuments (0),
- numDocsBeforeTabsUsed (0)
- {
- setOpaque (true);
- }
-
- MultiDocumentPanel::~MultiDocumentPanel()
- {
- closeAllDocuments (false);
- }
-
- static bool shouldDeleteComp (Component* const c)
- {
- return c->getComponentPropertyBool (T("mdiDocumentDelete_"), false);
- }
-
- bool MultiDocumentPanel::closeAllDocuments (const bool checkItsOkToCloseFirst)
- {
- while (components.size() > 0)
- if (! closeDocument (components.getLast(), checkItsOkToCloseFirst))
- return false;
-
- return true;
- }
-
- MultiDocumentPanelWindow* MultiDocumentPanel::createNewDocumentWindow()
- {
- return new MultiDocumentPanelWindow (backgroundColour);
- }
-
- void MultiDocumentPanel::addWindow (Component* component)
- {
- MultiDocumentPanelWindow* const dw = createNewDocumentWindow();
-
- dw->setResizable (true, false);
- dw->setContentComponent (component, false, true);
- dw->setName (component->getName());
- dw->setBackgroundColour (component->getComponentPropertyColour (T("mdiDocumentBkg_"), false, backgroundColour));
-
- int x = 4;
- Component* const topComp = getChildComponent (getNumChildComponents() - 1);
-
- if (topComp != 0 && topComp->getX() == x && topComp->getY() == x)
- x += 16;
-
- dw->setTopLeftPosition (x, x);
-
- if (component->getComponentProperty (T("mdiDocumentPos_"), false, String::empty).isNotEmpty())
- dw->restoreWindowStateFromString (component->getComponentProperty (T("mdiDocumentPos_"), false, String::empty));
-
- addAndMakeVisible (dw);
- dw->toFront (true);
- }
-
- bool MultiDocumentPanel::addDocument (Component* const component,
- const Colour& backgroundColour,
- const bool deleteWhenRemoved)
- {
- // If you try passing a full DocumentWindow or ResizableWindow in here, you'll end up
- // with a frame-within-a-frame! Just pass in the bare content component.
- jassert (dynamic_cast <ResizableWindow*> (component) == 0);
-
- if (component == 0 || (maximumNumDocuments > 0 && components.size() >= maximumNumDocuments))
- return false;
-
- components.add (component);
- component->setComponentProperty (T("mdiDocumentDelete_"), deleteWhenRemoved);
- component->setComponentProperty (T("mdiDocumentBkg_"), backgroundColour);
- component->addComponentListener (this);
-
- if (mode == FloatingWindows)
- {
- if (isFullscreenWhenOneDocument())
- {
- if (components.size() == 1)
- {
- addAndMakeVisible (component);
- }
- else
- {
- if (components.size() == 2)
- addWindow (components.getFirst());
-
- addWindow (component);
- }
- }
- else
- {
- addWindow (component);
- }
- }
- else
- {
- if (tabComponent == 0 && components.size() > numDocsBeforeTabsUsed)
- {
- addAndMakeVisible (tabComponent = new MDITabbedComponentInternal());
-
- Array <Component*> temp (components);
-
- for (int i = 0; i < temp.size(); ++i)
- tabComponent->addTab (temp[i]->getName(), backgroundColour, temp[i], false);
-
- resized();
- }
- else
- {
- if (tabComponent != 0)
- tabComponent->addTab (component->getName(), backgroundColour, component, false);
- else
- addAndMakeVisible (component);
- }
-
- setActiveDocument (component);
- }
-
- resized();
- activeDocumentChanged();
- return true;
- }
-
- bool MultiDocumentPanel::closeDocument (Component* component,
- const bool checkItsOkToCloseFirst)
- {
- if (components.contains (component))
- {
- if (checkItsOkToCloseFirst && ! tryToCloseDocument (component))
- return false;
-
- component->removeComponentListener (this);
-
- const bool shouldDelete = shouldDeleteComp (component);
- component->removeComponentProperty (T("mdiDocumentDelete_"));
- component->removeComponentProperty (T("mdiDocumentBkg_"));
-
- if (mode == FloatingWindows)
- {
- for (int i = getNumChildComponents(); --i >= 0;)
- {
- MultiDocumentPanelWindow* const dw = dynamic_cast <MultiDocumentPanelWindow*> (getChildComponent (i));
-
- if (dw != 0 && dw->getContentComponent() == component)
- {
- dw->setContentComponent (0, false);
- delete dw;
- break;
- }
- }
-
- if (shouldDelete)
- delete component;
-
- components.removeValue (component);
-
- if (isFullscreenWhenOneDocument() && components.size() == 1)
- {
- for (int i = getNumChildComponents(); --i >= 0;)
- {
- MultiDocumentPanelWindow* const dw = dynamic_cast <MultiDocumentPanelWindow*> (getChildComponent (i));
-
- if (dw != 0)
- {
- dw->setContentComponent (0, false);
- delete dw;
- }
- }
-
- addAndMakeVisible (components.getFirst());
- }
- }
- else
- {
- jassert (components.indexOf (component) >= 0);
-
- if (tabComponent != 0)
- {
- for (int i = tabComponent->getNumTabs(); --i >= 0;)
- if (tabComponent->getTabContentComponent (i) == component)
- tabComponent->removeTab (i);
- }
- else
- {
- removeChildComponent (component);
- }
-
- if (shouldDelete)
- delete component;
-
- if (tabComponent != 0 && tabComponent->getNumTabs() <= numDocsBeforeTabsUsed)
- deleteAndZero (tabComponent);
-
- components.removeValue (component);
-
- if (components.size() > 0 && tabComponent == 0)
- addAndMakeVisible (components.getFirst());
- }
-
- resized();
- activeDocumentChanged();
- }
- else
- {
- jassertfalse
- }
-
- return true;
- }
-
- int MultiDocumentPanel::getNumDocuments() const throw()
- {
- return components.size();
- }
-
- Component* MultiDocumentPanel::getDocument (const int index) const throw()
- {
- return components [index];
- }
-
- Component* MultiDocumentPanel::getActiveDocument() const throw()
- {
- if (mode == FloatingWindows)
- {
- for (int i = getNumChildComponents(); --i >= 0;)
- {
- MultiDocumentPanelWindow* const dw = dynamic_cast <MultiDocumentPanelWindow*> (getChildComponent (i));
-
- if (dw != 0 && dw->isActiveWindow())
- return dw->getContentComponent();
- }
- }
-
- return components.getLast();
- }
-
- void MultiDocumentPanel::setActiveDocument (Component* component)
- {
- if (mode == FloatingWindows)
- {
- component = getContainerComp (component);
-
- if (component != 0)
- component->toFront (true);
- }
- else if (tabComponent != 0)
- {
- jassert (components.indexOf (component) >= 0);
-
- for (int i = tabComponent->getNumTabs(); --i >= 0;)
- {
- if (tabComponent->getTabContentComponent (i) == component)
- {
- tabComponent->setCurrentTabIndex (i);
- break;
- }
- }
- }
- else
- {
- component->grabKeyboardFocus();
- }
- }
-
- void MultiDocumentPanel::activeDocumentChanged()
- {
- }
-
- void MultiDocumentPanel::setMaximumNumDocuments (const int newNumber)
- {
- maximumNumDocuments = newNumber;
- }
-
- void MultiDocumentPanel::useFullscreenWhenOneDocument (const bool shouldUseTabs)
- {
- numDocsBeforeTabsUsed = shouldUseTabs ? 1 : 0;
- }
-
- bool MultiDocumentPanel::isFullscreenWhenOneDocument() const throw()
- {
- return numDocsBeforeTabsUsed != 0;
- }
-
- void MultiDocumentPanel::setLayoutMode (const LayoutMode newLayoutMode)
- {
- if (mode != newLayoutMode)
- {
- mode = newLayoutMode;
-
- if (mode == FloatingWindows)
- {
- deleteAndZero (tabComponent);
- }
- else
- {
- for (int i = getNumChildComponents(); --i >= 0;)
- {
- MultiDocumentPanelWindow* const dw = dynamic_cast <MultiDocumentPanelWindow*> (getChildComponent (i));
-
- if (dw != 0)
- {
- dw->getContentComponent()->setComponentProperty (T("mdiDocumentPos_"), dw->getWindowStateAsString());
- dw->setContentComponent (0, false);
- delete dw;
- }
- }
- }
-
- resized();
-
- const Array <Component*> tempComps (components);
- components.clear();
-
- for (int i = 0; i < tempComps.size(); ++i)
- {
- Component* const c = tempComps.getUnchecked(i);
- addDocument (c,
- c->getComponentPropertyColour (T("mdiDocumentBkg_"), false, Colours::white),
- shouldDeleteComp (c));
- }
- }
- }
-
- void MultiDocumentPanel::setBackgroundColour (const Colour& newBackgroundColour)
- {
- if (backgroundColour != newBackgroundColour)
- {
- backgroundColour = newBackgroundColour;
- setOpaque (newBackgroundColour.isOpaque());
- repaint();
- }
- }
-
- void MultiDocumentPanel::paint (Graphics& g)
- {
- g.fillAll (backgroundColour);
- }
-
- void MultiDocumentPanel::resized()
- {
- if (mode == MaximisedWindowsWithTabs || components.size() == numDocsBeforeTabsUsed)
- {
- for (int i = getNumChildComponents(); --i >= 0;)
- getChildComponent (i)->setBounds (0, 0, getWidth(), getHeight());
- }
-
- setWantsKeyboardFocus (components.size() == 0);
- }
-
- Component* MultiDocumentPanel::getContainerComp (Component* c) const
- {
- if (mode == FloatingWindows)
- {
- for (int i = 0; i < getNumChildComponents(); ++i)
- {
- MultiDocumentPanelWindow* const dw = dynamic_cast <MultiDocumentPanelWindow*> (getChildComponent (i));
-
- if (dw != 0 && dw->getContentComponent() == c)
- {
- c = dw;
- break;
- }
- }
- }
-
- return c;
- }
-
- void MultiDocumentPanel::componentNameChanged (Component&)
- {
- if (mode == FloatingWindows)
- {
- for (int i = 0; i < getNumChildComponents(); ++i)
- {
- MultiDocumentPanelWindow* const dw = dynamic_cast <MultiDocumentPanelWindow*> (getChildComponent (i));
-
- if (dw != 0)
- dw->setName (dw->getContentComponent()->getName());
- }
- }
- else if (tabComponent != 0)
- {
- for (int i = tabComponent->getNumTabs(); --i >= 0;)
- tabComponent->setTabName (i, tabComponent->getTabContentComponent (i)->getName());
- }
- }
-
- void MultiDocumentPanel::updateOrder()
- {
- const Array <Component*> oldList (components);
-
- if (mode == FloatingWindows)
- {
- components.clear();
-
- for (int i = 0; i < getNumChildComponents(); ++i)
- {
- MultiDocumentPanelWindow* const dw = dynamic_cast <MultiDocumentPanelWindow*> (getChildComponent (i));
-
- if (dw != 0)
- components.add (dw->getContentComponent());
- }
- }
- else
- {
- if (tabComponent != 0)
- {
- Component* const current = tabComponent->getCurrentContentComponent();
-
- if (current != 0)
- {
- components.removeValue (current);
- components.add (current);
- }
- }
- }
-
- if (components != oldList)
- activeDocumentChanged();
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_MultiDocumentPanel.cpp *********/
-
- /********* Start of inlined file: juce_ResizableBorderComponent.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- const int zoneL = 1;
- const int zoneR = 2;
- const int zoneT = 4;
- const int zoneB = 8;
-
- ResizableBorderComponent::ResizableBorderComponent (Component* const componentToResize,
- ComponentBoundsConstrainer* const constrainer_)
- : component (componentToResize),
- constrainer (constrainer_),
- borderSize (5),
- mouseZone (0)
- {
- }
-
- ResizableBorderComponent::~ResizableBorderComponent()
- {
- }
-
- void ResizableBorderComponent::paint (Graphics& g)
- {
- getLookAndFeel().drawResizableFrame (g, getWidth(), getHeight(), borderSize);
- }
-
- void ResizableBorderComponent::mouseEnter (const MouseEvent& e)
- {
- updateMouseZone (e);
- }
-
- void ResizableBorderComponent::mouseMove (const MouseEvent& e)
- {
- updateMouseZone (e);
- }
-
- void ResizableBorderComponent::mouseDown (const MouseEvent& e)
- {
- if (component->isValidComponent())
- {
- updateMouseZone (e);
-
- originalX = component->getX();
- originalY = component->getY();
- originalW = component->getWidth();
- originalH = component->getHeight();
-
- if (constrainer != 0)
- constrainer->resizeStart();
- }
- else
- {
- jassertfalse
- }
- }
-
- void ResizableBorderComponent::mouseDrag (const MouseEvent& e)
- {
- if (! component->isValidComponent())
- {
- jassertfalse
- return;
- }
-
- int x = originalX;
- int y = originalY;
- int w = originalW;
- int h = originalH;
-
- const int dx = e.getDistanceFromDragStartX();
- const int dy = e.getDistanceFromDragStartY();
-
- if ((mouseZone & zoneL) != 0)
- {
- x += dx;
- w -= dx;
- }
-
- if ((mouseZone & zoneT) != 0)
- {
- y += dy;
- h -= dy;
- }
-
- if ((mouseZone & zoneR) != 0)
- w += dx;
-
- if ((mouseZone & zoneB) != 0)
- h += dy;
-
- if (constrainer != 0)
- constrainer->setBoundsForComponent (component,
- x, y, w, h,
- (mouseZone & zoneT) != 0,
- (mouseZone & zoneL) != 0,
- (mouseZone & zoneB) != 0,
- (mouseZone & zoneR) != 0);
- else
- component->setBounds (x, y, w, h);
- }
-
- void ResizableBorderComponent::mouseUp (const MouseEvent&)
- {
- if (constrainer != 0)
- constrainer->resizeEnd();
- }
-
- bool ResizableBorderComponent::hitTest (int x, int y)
- {
- return x < borderSize.getLeft()
- || x >= getWidth() - borderSize.getRight()
- || y < borderSize.getTop()
- || y >= getHeight() - borderSize.getBottom();
- }
-
- void ResizableBorderComponent::setBorderThickness (const BorderSize& newBorderSize) throw()
- {
- if (borderSize != newBorderSize)
- {
- borderSize = newBorderSize;
- repaint();
- }
- }
-
- const BorderSize ResizableBorderComponent::getBorderThickness() const throw()
- {
- return borderSize;
- }
-
- void ResizableBorderComponent::updateMouseZone (const MouseEvent& e) throw()
- {
- int newZone = 0;
-
- if (ResizableBorderComponent::hitTest (e.x, e.y))
- {
- if (e.x < jmax (borderSize.getLeft(), proportionOfWidth (0.1f)))
- newZone |= zoneL;
- else if (e.x >= jmin (getWidth() - borderSize.getRight(), proportionOfWidth (0.9f)))
- newZone |= zoneR;
-
- if (e.y < jmax (borderSize.getTop(), proportionOfHeight (0.1f)))
- newZone |= zoneT;
- else if (e.y >= jmin (getHeight() - borderSize.getBottom(), proportionOfHeight (0.9f)))
- newZone |= zoneB;
- }
-
- if (mouseZone != newZone)
- {
- mouseZone = newZone;
-
- MouseCursor::StandardCursorType mc = MouseCursor::NormalCursor;
-
- switch (newZone)
- {
- case (zoneL | zoneT):
- mc = MouseCursor::TopLeftCornerResizeCursor;
- break;
-
- case zoneT:
- mc = MouseCursor::TopEdgeResizeCursor;
- break;
-
- case (zoneR | zoneT):
- mc = MouseCursor::TopRightCornerResizeCursor;
- break;
-
- case zoneL:
- mc = MouseCursor::LeftEdgeResizeCursor;
- break;
-
- case zoneR:
- mc = MouseCursor::RightEdgeResizeCursor;
- break;
-
- case (zoneL | zoneB):
- mc = MouseCursor::BottomLeftCornerResizeCursor;
- break;
-
- case zoneB:
- mc = MouseCursor::BottomEdgeResizeCursor;
- break;
-
- case (zoneR | zoneB):
- mc = MouseCursor::BottomRightCornerResizeCursor;
- break;
-
- default:
- break;
- }
-
- setMouseCursor (mc);
- }
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_ResizableBorderComponent.cpp *********/
-
- /********* Start of inlined file: juce_ResizableCornerComponent.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- ResizableCornerComponent::ResizableCornerComponent (Component* const componentToResize,
- ComponentBoundsConstrainer* const constrainer_)
- : component (componentToResize),
- constrainer (constrainer_)
- {
- setRepaintsOnMouseActivity (true);
- setMouseCursor (MouseCursor::BottomRightCornerResizeCursor);
- }
-
- ResizableCornerComponent::~ResizableCornerComponent()
- {
- }
-
- void ResizableCornerComponent::paint (Graphics& g)
- {
- getLookAndFeel()
- .drawCornerResizer (g, getWidth(), getHeight(),
- isMouseOverOrDragging(),
- isMouseButtonDown());
- }
-
- void ResizableCornerComponent::mouseDown (const MouseEvent&)
- {
- if (component->isValidComponent())
- {
- originalX = component->getX();
- originalY = component->getY();
- originalW = component->getWidth();
- originalH = component->getHeight();
-
- if (constrainer != 0)
- constrainer->resizeStart();
- }
- else
- {
- jassertfalse
- }
- }
-
- void ResizableCornerComponent::mouseDrag (const MouseEvent& e)
- {
- if (! component->isValidComponent())
- {
- jassertfalse
- return;
- }
-
- int x = originalX;
- int y = originalY;
- int w = originalW + e.getDistanceFromDragStartX();
- int h = originalH + e.getDistanceFromDragStartY();
-
- if (constrainer != 0)
- constrainer->setBoundsForComponent (component, x, y, w, h,
- false, false, true, true);
- else
- component->setBounds (x, y, w, h);
- }
-
- void ResizableCornerComponent::mouseUp (const MouseEvent&)
- {
- if (constrainer != 0)
- constrainer->resizeStart();
- }
-
- bool ResizableCornerComponent::hitTest (int x, int y)
- {
- if (getWidth() <= 0)
- return false;
-
- const int yAtX = getHeight() - (getHeight() * x / getWidth());
-
- return y >= yAtX - getHeight() / 4;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_ResizableCornerComponent.cpp *********/
-
- /********* Start of inlined file: juce_ScrollBar.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- class ScrollbarButton : public Button
- {
- public:
- int direction;
-
- ScrollbarButton (const int direction_,
- ScrollBar& owner_) throw()
- : Button (String::empty),
- direction (direction_),
- owner (owner_)
- {
- setWantsKeyboardFocus (false);
- }
-
- ~ScrollbarButton()
- {
- }
-
- void paintButton (Graphics& g,
- bool isMouseOver,
- bool isMouseDown)
- {
- getLookAndFeel()
- .drawScrollbarButton (g, owner,
- getWidth(), getHeight(),
- direction,
- owner.isVertical(),
- isMouseOver, isMouseDown);
- }
-
- void clicked()
- {
- owner.moveScrollbarInSteps ((direction == 1 || direction == 2) ? 1 : -1);
- }
-
- juce_UseDebuggingNewOperator
-
- private:
- ScrollBar& owner;
-
- ScrollbarButton (const ScrollbarButton&);
- const ScrollbarButton& operator= (const ScrollbarButton&);
- };
-
- ScrollBar::ScrollBar (const bool vertical_,
- const bool buttonsAreVisible)
- : minimum (0.0),
- maximum (1.0),
- rangeStart (0.0),
- rangeSize (0.1),
- singleStepSize (0.1),
- thumbAreaStart (0),
- thumbAreaSize (0),
- thumbStart (0),
- thumbSize (0),
- initialDelayInMillisecs (100),
- repeatDelayInMillisecs (50),
- minimumDelayInMillisecs (10),
- vertical (vertical_),
- isDraggingThumb (false),
- alwaysVisible (false),
- upButton (0),
- downButton (0),
- listeners (2)
- {
- setButtonVisibility (buttonsAreVisible);
-
- setRepaintsOnMouseActivity (true);
- setFocusContainer (true);
- }
-
- ScrollBar::~ScrollBar()
- {
- deleteAllChildren();
- }
-
- void ScrollBar::setRangeLimits (const double newMinimum,
- const double newMaximum) throw()
- {
- minimum = newMinimum;
- maximum = newMaximum;
-
- jassert (maximum >= minimum); // these can't be the wrong way round!
-
- setCurrentRangeStart (rangeStart);
- updateThumbPosition();
- }
-
- void ScrollBar::setCurrentRange (double newStart,
- double newSize) throw()
- {
- newSize = jlimit (0.0, maximum - minimum, newSize);
- newStart = jlimit (minimum, maximum - newSize, newStart);
-
- if (rangeStart != newStart
- || rangeSize != newSize)
- {
- rangeStart = newStart;
- rangeSize = newSize;
-
- updateThumbPosition();
- triggerAsyncUpdate();
- }
- }
-
- void ScrollBar::setCurrentRangeStart (double newStart) throw()
- {
- setCurrentRange (newStart, rangeSize);
- }
-
- void ScrollBar::setSingleStepSize (const double newSingleStepSize) throw()
- {
- singleStepSize = newSingleStepSize;
- }
-
- void ScrollBar::moveScrollbarInSteps (const int howManySteps) throw()
- {
- setCurrentRangeStart (rangeStart + howManySteps * singleStepSize);
- }
-
- void ScrollBar::moveScrollbarInPages (const int howManyPages) throw()
- {
- setCurrentRangeStart (rangeStart + howManyPages * rangeSize);
- }
-
- void ScrollBar::scrollToTop() throw()
- {
- setCurrentRangeStart (minimum);
- }
-
- void ScrollBar::scrollToBottom() throw()
- {
- setCurrentRangeStart (maximum - rangeSize);
- }
-
- void ScrollBar::setButtonRepeatSpeed (const int initialDelayInMillisecs_,
- const int repeatDelayInMillisecs_,
- const int minimumDelayInMillisecs_) throw()
- {
- initialDelayInMillisecs = initialDelayInMillisecs_;
- repeatDelayInMillisecs = repeatDelayInMillisecs_;
- minimumDelayInMillisecs = minimumDelayInMillisecs_;
-
- if (upButton != 0)
- {
- upButton->setRepeatSpeed (initialDelayInMillisecs, repeatDelayInMillisecs, minimumDelayInMillisecs);
- downButton->setRepeatSpeed (initialDelayInMillisecs, repeatDelayInMillisecs, minimumDelayInMillisecs);
- }
- }
-
- void ScrollBar::addListener (ScrollBarListener* const listener) throw()
- {
- jassert (listener != 0);
- if (listener != 0)
- listeners.add (listener);
- }
-
- void ScrollBar::removeListener (ScrollBarListener* const listener) throw()
- {
- listeners.removeValue (listener);
- }
-
- void ScrollBar::handleAsyncUpdate()
- {
- const double value = getCurrentRangeStart();
-
- for (int i = listeners.size(); --i >= 0;)
- {
- ((ScrollBarListener*) listeners.getUnchecked (i))->scrollBarMoved (this, value);
- i = jmin (i, listeners.size());
- }
- }
-
- void ScrollBar::updateThumbPosition() throw()
- {
- int newThumbSize = roundDoubleToInt ((maximum > minimum) ? (rangeSize * thumbAreaSize) / (maximum - minimum)
- : thumbAreaSize);
-
- if (newThumbSize < getLookAndFeel().getMinimumScrollbarThumbSize (*this))
- newThumbSize = jmin (getLookAndFeel().getMinimumScrollbarThumbSize (*this), thumbAreaSize - 1);
-
- if (newThumbSize > thumbAreaSize)
- newThumbSize = thumbAreaSize;
-
- int newThumbStart = thumbAreaStart;
-
- if (maximum - minimum > rangeSize)
- newThumbStart += roundDoubleToInt (((rangeStart - minimum) * (thumbAreaSize - newThumbSize))
- / ((maximum - minimum) - rangeSize));
-
- setVisible (alwaysVisible || (maximum - minimum > rangeSize && rangeSize > 0.0));
-
- if (thumbStart != newThumbStart || thumbSize != newThumbSize)
- {
- const int repaintStart = jmin (thumbStart, newThumbStart) - 4;
- const int repaintSize = jmax (thumbStart + thumbSize, newThumbStart + newThumbSize) + 8 - repaintStart;
-
- if (vertical)
- repaint (0, repaintStart, getWidth(), repaintSize);
- else
- repaint (repaintStart, 0, repaintSize, getHeight());
-
- thumbStart = newThumbStart;
- thumbSize = newThumbSize;
- }
- }
-
- void ScrollBar::setOrientation (const bool shouldBeVertical) throw()
- {
- if (vertical != shouldBeVertical)
- {
- vertical = shouldBeVertical;
-
- if (upButton != 0)
- {
- ((ScrollbarButton*) upButton)->direction = (vertical) ? 0 : 3;
- ((ScrollbarButton*) downButton)->direction = (vertical) ? 2 : 1;
- }
-
- updateThumbPosition();
- }
- }
-
- void ScrollBar::setButtonVisibility (const bool buttonsAreVisible)
- {
- deleteAndZero (upButton);
- deleteAndZero (downButton);
-
- if (buttonsAreVisible)
- {
- addAndMakeVisible (upButton = new ScrollbarButton ((vertical) ? 0 : 3, *this));
- addAndMakeVisible (downButton = new ScrollbarButton ((vertical) ? 2 : 1, *this));
-
- setButtonRepeatSpeed (initialDelayInMillisecs, repeatDelayInMillisecs, minimumDelayInMillisecs);
- }
-
- updateThumbPosition();
- }
-
- void ScrollBar::setAutoHide (const bool shouldHideWhenFullRange)
- {
- alwaysVisible = ! shouldHideWhenFullRange;
- updateThumbPosition();
- }
-
- void ScrollBar::paint (Graphics& g)
- {
- if (thumbAreaSize > 0)
- {
- LookAndFeel& lf = getLookAndFeel();
-
- const int thumb = (thumbAreaSize > lf.getMinimumScrollbarThumbSize (*this))
- ? thumbSize : 0;
-
- if (vertical)
- {
- lf.drawScrollbar (g, *this,
- 0, thumbAreaStart,
- getWidth(), thumbAreaSize,
- vertical,
- thumbStart, thumb,
- isMouseOver(), isMouseButtonDown());
- }
- else
- {
- lf.drawScrollbar (g, *this,
- thumbAreaStart, 0,
- thumbAreaSize, getHeight(),
- vertical,
- thumbStart, thumb,
- isMouseOver(), isMouseButtonDown());
- }
- }
- }
-
- void ScrollBar::lookAndFeelChanged()
- {
- setComponentEffect (getLookAndFeel().getScrollbarEffect());
- }
-
- void ScrollBar::resized()
- {
- const int length = ((vertical) ? getHeight() : getWidth());
-
- const int buttonSize = (upButton != 0) ? jmin (getLookAndFeel().getScrollbarButtonSize (*this), (length >> 1))
- : 0;
-
- if (length < 32 + getLookAndFeel().getMinimumScrollbarThumbSize (*this))
- {
- thumbAreaStart = length >> 1;
- thumbAreaSize = 0;
- }
- else
- {
- thumbAreaStart = buttonSize;
- thumbAreaSize = length - (buttonSize << 1);
- }
-
- if (upButton != 0)
- {
- if (vertical)
- {
- upButton->setBounds (0, 0, getWidth(), buttonSize);
- downButton->setBounds (0, thumbAreaStart + thumbAreaSize, getWidth(), buttonSize);
- }
- else
- {
- upButton->setBounds (0, 0, buttonSize, getHeight());
- downButton->setBounds (thumbAreaStart + thumbAreaSize, 0, buttonSize, getHeight());
- }
- }
-
- updateThumbPosition();
- }
-
- void ScrollBar::mouseDown (const MouseEvent& e)
- {
- isDraggingThumb = false;
- lastMousePos = vertical ? e.y : e.x;
- dragStartMousePos = lastMousePos;
- dragStartRange = rangeStart;
-
- if (dragStartMousePos < thumbStart)
- {
- moveScrollbarInPages (-1);
- startTimer (400);
- }
- else if (dragStartMousePos >= thumbStart + thumbSize)
- {
- moveScrollbarInPages (1);
- startTimer (400);
- }
- else
- {
- isDraggingThumb = (thumbAreaSize > getLookAndFeel().getMinimumScrollbarThumbSize (*this))
- && (thumbAreaSize > thumbSize);
- }
- }
-
- void ScrollBar::mouseDrag (const MouseEvent& e)
- {
- if (isDraggingThumb)
- {
- const int deltaPixels = ((vertical) ? e.y : e.x) - dragStartMousePos;
-
- setCurrentRangeStart (dragStartRange
- + deltaPixels * ((maximum - minimum) - rangeSize)
- / (thumbAreaSize - thumbSize));
- }
- else
- {
- lastMousePos = (vertical) ? e.y : e.x;
- }
- }
-
- void ScrollBar::mouseUp (const MouseEvent&)
- {
- isDraggingThumb = false;
- stopTimer();
- repaint();
- }
-
- void ScrollBar::mouseWheelMove (const MouseEvent&,
- float wheelIncrementX,
- float wheelIncrementY)
- {
- float increment = vertical ? wheelIncrementY : wheelIncrementX;
-
- if (increment < 0)
- increment = jmin (increment * 10.0f, -1.0f);
- else if (increment > 0)
- increment = jmax (increment * 10.0f, 1.0f);
-
- setCurrentRangeStart (rangeStart - singleStepSize * increment);
- }
-
- void ScrollBar::timerCallback()
- {
- if (isMouseButtonDown())
- {
- startTimer (40);
-
- if (lastMousePos < thumbStart)
- setCurrentRangeStart (rangeStart - rangeSize);
- else if (lastMousePos > thumbStart + thumbSize)
- setCurrentRangeStart (rangeStart + rangeSize);
- }
- else
- {
- stopTimer();
- }
- }
-
- bool ScrollBar::keyPressed (const KeyPress& key)
- {
- if (! isVisible())
- return false;
-
- if (key.isKeyCode (KeyPress::upKey) || key.isKeyCode (KeyPress::leftKey))
- moveScrollbarInSteps (-1);
- else if (key.isKeyCode (KeyPress::downKey) || key.isKeyCode (KeyPress::rightKey))
- moveScrollbarInSteps (1);
- else if (key.isKeyCode (KeyPress::pageUpKey))
- moveScrollbarInPages (-1);
- else if (key.isKeyCode (KeyPress::pageDownKey))
- moveScrollbarInPages (1);
- else if (key.isKeyCode (KeyPress::homeKey))
- scrollToTop();
- else if (key.isKeyCode (KeyPress::endKey))
- scrollToBottom();
- else
- return false;
-
- return true;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_ScrollBar.cpp *********/
-
- /********* Start of inlined file: juce_StretchableLayoutManager.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- StretchableLayoutManager::StretchableLayoutManager()
- : totalSize (0)
- {
- }
-
- StretchableLayoutManager::~StretchableLayoutManager()
- {
- }
-
- void StretchableLayoutManager::clearAllItems()
- {
- items.clear();
- totalSize = 0;
- }
-
- void StretchableLayoutManager::setItemLayout (const int itemIndex,
- const double minimumSize,
- const double maximumSize,
- const double preferredSize)
- {
- ItemLayoutProperties* layout = getInfoFor (itemIndex);
-
- if (layout == 0)
- {
- layout = new ItemLayoutProperties();
- layout->itemIndex = itemIndex;
-
- int i;
- for (i = 0; i < items.size(); ++i)
- if (items.getUnchecked (i)->itemIndex > itemIndex)
- break;
-
- items.insert (i, layout);
- }
-
- layout->minSize = minimumSize;
- layout->maxSize = maximumSize;
- layout->preferredSize = preferredSize;
- layout->currentSize = 0;
- }
-
- bool StretchableLayoutManager::getItemLayout (const int itemIndex,
- double& minimumSize,
- double& maximumSize,
- double& preferredSize) const
- {
- const ItemLayoutProperties* const layout = getInfoFor (itemIndex);
-
- if (layout != 0)
- {
- minimumSize = layout->minSize;
- maximumSize = layout->maxSize;
- preferredSize = layout->preferredSize;
- return true;
- }
-
- return false;
- }
-
- void StretchableLayoutManager::setTotalSize (const int newTotalSize)
- {
- totalSize = newTotalSize;
-
- fitComponentsIntoSpace (0, items.size(), totalSize, 0);
- }
-
- int StretchableLayoutManager::getItemCurrentPosition (const int itemIndex) const
- {
- int pos = 0;
-
- for (int i = 0; i < itemIndex; ++i)
- {
- const ItemLayoutProperties* const layout = getInfoFor (i);
-
- if (layout != 0)
- pos += layout->currentSize;
- }
-
- return pos;
- }
-
- int StretchableLayoutManager::getItemCurrentAbsoluteSize (const int itemIndex) const
- {
- const ItemLayoutProperties* const layout = getInfoFor (itemIndex);
-
- if (layout != 0)
- return layout->currentSize;
-
- return 0;
- }
-
- double StretchableLayoutManager::getItemCurrentRelativeSize (const int itemIndex) const
- {
- const ItemLayoutProperties* const layout = getInfoFor (itemIndex);
-
- if (layout != 0)
- return -layout->currentSize / (double) totalSize;
-
- return 0;
- }
-
- void StretchableLayoutManager::setItemPosition (const int itemIndex,
- int newPosition)
- {
- for (int i = items.size(); --i >= 0;)
- {
- const ItemLayoutProperties* const layout = items.getUnchecked(i);
-
- if (layout->itemIndex == itemIndex)
- {
- int realTotalSize = jmax (totalSize, getMinimumSizeOfItems (0, items.size()));
- const int minSizeAfterThisComp = getMinimumSizeOfItems (i, items.size());
- const int maxSizeAfterThisComp = getMaximumSizeOfItems (i + 1, items.size());
-
- newPosition = jmax (newPosition, totalSize - maxSizeAfterThisComp - layout->currentSize);
- newPosition = jmin (newPosition, realTotalSize - minSizeAfterThisComp);
-
- int endPos = fitComponentsIntoSpace (0, i, newPosition, 0);
-
- endPos += layout->currentSize;
-
- fitComponentsIntoSpace (i + 1, items.size(), totalSize - endPos, endPos);
- updatePrefSizesToMatchCurrentPositions();
- break;
- }
- }
- }
-
- void StretchableLayoutManager::layOutComponents (Component** const components,
- int numComponents,
- int x, int y, int w, int h,
- const bool vertically,
- const bool resizeOtherDimension)
- {
- setTotalSize (vertically ? h : w);
- int pos = vertically ? y : x;
-
- for (int i = 0; i < numComponents; ++i)
- {
- const ItemLayoutProperties* const layout = getInfoFor (i);
-
- if (layout != 0)
- {
- Component* const c = components[i];
-
- if (c != 0)
- {
- if (i == numComponents - 1)
- {
- // if it's the last item, crop it to exactly fit the available space..
- if (resizeOtherDimension)
- {
- if (vertically)
- c->setBounds (x, pos, w, jmax (layout->currentSize, h - pos));
- else
- c->setBounds (pos, y, jmax (layout->currentSize, w - pos), h);
- }
- else
- {
- if (vertically)
- c->setBounds (c->getX(), pos, c->getWidth(), jmax (layout->currentSize, h - pos));
- else
- c->setBounds (pos, c->getY(), jmax (layout->currentSize, w - pos), c->getHeight());
- }
- }
- else
- {
- if (resizeOtherDimension)
- {
- if (vertically)
- c->setBounds (x, pos, w, layout->currentSize);
- else
- c->setBounds (pos, y, layout->currentSize, h);
- }
- else
- {
- if (vertically)
- c->setBounds (c->getX(), pos, c->getWidth(), layout->currentSize);
- else
- c->setBounds (pos, c->getY(), layout->currentSize, c->getHeight());
- }
- }
- }
-
- pos += layout->currentSize;
- }
- }
- }
-
- StretchableLayoutManager::ItemLayoutProperties* StretchableLayoutManager::getInfoFor (const int itemIndex) const
- {
- for (int i = items.size(); --i >= 0;)
- if (items.getUnchecked(i)->itemIndex == itemIndex)
- return items.getUnchecked(i);
-
- return 0;
- }
-
- int StretchableLayoutManager::fitComponentsIntoSpace (const int startIndex,
- const int endIndex,
- const int availableSpace,
- int startPos)
- {
- // calculate the total sizes
- int i;
- double totalIdealSize = 0.0;
- int totalMinimums = 0;
-
- for (i = startIndex; i < endIndex; ++i)
- {
- ItemLayoutProperties* const layout = items.getUnchecked (i);
-
- layout->currentSize = sizeToRealSize (layout->minSize, totalSize);
-
- totalMinimums += layout->currentSize;
- totalIdealSize += sizeToRealSize (layout->preferredSize, availableSpace);
- }
-
- if (totalIdealSize <= 0)
- totalIdealSize = 1.0;
-
- // now calc the best sizes..
- int extraSpace = availableSpace - totalMinimums;
-
- while (extraSpace > 0)
- {
- int numWantingMoreSpace = 0;
- int numHavingTakenExtraSpace = 0;
-
- // first figure out how many comps want a slice of the extra space..
- for (i = startIndex; i < endIndex; ++i)
- {
- ItemLayoutProperties* const layout = items.getUnchecked (i);
-
- double sizeWanted = sizeToRealSize (layout->preferredSize, availableSpace);
-
- const int bestSize = jlimit (layout->currentSize,
- jmax (layout->currentSize,
- sizeToRealSize (layout->maxSize, totalSize)),
- roundDoubleToInt (sizeWanted * availableSpace / totalIdealSize));
-
- if (bestSize > layout->currentSize)
- ++numWantingMoreSpace;
- }
-
- // ..share out the extra space..
- for (i = startIndex; i < endIndex; ++i)
- {
- ItemLayoutProperties* const layout = items.getUnchecked (i);
-
- double sizeWanted = sizeToRealSize (layout->preferredSize, availableSpace);
-
- int bestSize = jlimit (layout->currentSize,
- jmax (layout->currentSize, sizeToRealSize (layout->maxSize, totalSize)),
- roundDoubleToInt (sizeWanted * availableSpace / totalIdealSize));
-
- const int extraWanted = bestSize - layout->currentSize;
-
- if (extraWanted > 0)
- {
- const int extraAllowed = jmin (extraWanted,
- extraSpace / jmax (1, numWantingMoreSpace));
-
- if (extraAllowed > 0)
- {
- ++numHavingTakenExtraSpace;
- --numWantingMoreSpace;
-
- layout->currentSize += extraAllowed;
- extraSpace -= extraAllowed;
- }
- }
- }
-
- if (numHavingTakenExtraSpace <= 0)
- break;
- }
-
- // ..and calculate the end position
- for (i = startIndex; i < endIndex; ++i)
- {
- ItemLayoutProperties* const layout = items.getUnchecked(i);
- startPos += layout->currentSize;
- }
-
- return startPos;
- }
-
- int StretchableLayoutManager::getMinimumSizeOfItems (const int startIndex,
- const int endIndex) const
- {
- int totalMinimums = 0;
-
- for (int i = startIndex; i < endIndex; ++i)
- totalMinimums += sizeToRealSize (items.getUnchecked (i)->minSize, totalSize);
-
- return totalMinimums;
- }
-
- int StretchableLayoutManager::getMaximumSizeOfItems (const int startIndex, const int endIndex) const
- {
- int totalMaximums = 0;
-
- for (int i = startIndex; i < endIndex; ++i)
- totalMaximums += sizeToRealSize (items.getUnchecked (i)->maxSize, totalSize);
-
- return totalMaximums;
- }
-
- void StretchableLayoutManager::updatePrefSizesToMatchCurrentPositions()
- {
- for (int i = 0; i < items.size(); ++i)
- {
- ItemLayoutProperties* const layout = items.getUnchecked (i);
-
- layout->preferredSize
- = (layout->preferredSize < 0) ? getItemCurrentRelativeSize (i)
- : getItemCurrentAbsoluteSize (i);
- }
- }
-
- int StretchableLayoutManager::sizeToRealSize (double size, int totalSpace)
- {
- if (size < 0)
- size *= -totalSpace;
-
- return roundDoubleToInt (size);
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_StretchableLayoutManager.cpp *********/
-
- /********* Start of inlined file: juce_StretchableLayoutResizerBar.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- StretchableLayoutResizerBar::StretchableLayoutResizerBar (StretchableLayoutManager* layout_,
- const int itemIndex_,
- const bool isVertical_)
- : layout (layout_),
- itemIndex (itemIndex_),
- isVertical (isVertical_)
- {
- setRepaintsOnMouseActivity (true);
- setMouseCursor (MouseCursor (isVertical_ ? MouseCursor::LeftRightResizeCursor
- : MouseCursor::UpDownResizeCursor));
- }
-
- StretchableLayoutResizerBar::~StretchableLayoutResizerBar()
- {
- }
-
- void StretchableLayoutResizerBar::paint (Graphics& g)
- {
- getLookAndFeel().drawStretchableLayoutResizerBar (g,
- getWidth(), getHeight(),
- isVertical,
- isMouseOver(),
- isMouseButtonDown());
- }
-
- void StretchableLayoutResizerBar::mouseDown (const MouseEvent&)
- {
- mouseDownPos = layout->getItemCurrentPosition (itemIndex);
- }
-
- void StretchableLayoutResizerBar::mouseDrag (const MouseEvent& e)
- {
- const int desiredPos = mouseDownPos + (isVertical ? e.getDistanceFromDragStartX()
- : e.getDistanceFromDragStartY());
-
- layout->setItemPosition (itemIndex, desiredPos);
-
- hasBeenMoved();
- }
-
- void StretchableLayoutResizerBar::hasBeenMoved()
- {
- if (getParentComponent() != 0)
- getParentComponent()->resized();
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_StretchableLayoutResizerBar.cpp *********/
-
- /********* Start of inlined file: juce_StretchableObjectResizer.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- StretchableObjectResizer::StretchableObjectResizer()
- {
- }
-
- StretchableObjectResizer::~StretchableObjectResizer()
- {
- }
-
- void StretchableObjectResizer::addItem (const double size,
- const double minSize, const double maxSize,
- const int order)
- {
- jassert (order >= 0 && order < INT_MAX); // the order must be >= 0 and less than INT_MAX
-
- Item* const item = new Item();
- item->size = size;
- item->minSize = minSize;
- item->maxSize = maxSize;
- item->order = order;
- items.add (item);
- }
-
- double StretchableObjectResizer::getItemSize (const int index) const throw()
- {
- const Item* const it = items [index];
- return it != 0 ? it->size : 0;
- }
-
- void StretchableObjectResizer::resizeToFit (const double targetSize)
- {
- int order = 0;
-
- for (;;)
- {
- double currentSize = 0;
- double minSize = 0;
- double maxSize = 0;
-
- int nextHighestOrder = INT_MAX;
-
- for (int i = 0; i < items.size(); ++i)
- {
- const Item* const it = items.getUnchecked(i);
- currentSize += it->size;
-
- if (it->order <= order)
- {
- minSize += it->minSize;
- maxSize += it->maxSize;
- }
- else
- {
- minSize += it->size;
- maxSize += it->size;
- nextHighestOrder = jmin (nextHighestOrder, it->order);
- }
- }
-
- const double thisIterationTarget = jlimit (minSize, maxSize, targetSize);
-
- if (thisIterationTarget >= currentSize)
- {
- const double availableExtraSpace = maxSize - currentSize;
- const double targetAmountOfExtraSpace = thisIterationTarget - currentSize;
- const double scale = targetAmountOfExtraSpace / availableExtraSpace;
-
- for (int i = 0; i < items.size(); ++i)
- {
- Item* const it = items.getUnchecked(i);
-
- if (it->order <= order)
- it->size = jmin (it->maxSize, it->size + (it->maxSize - it->size) * scale);
- }
- }
- else
- {
- const double amountOfSlack = currentSize - minSize;
- const double targetAmountOfSlack = thisIterationTarget - minSize;
- const double scale = targetAmountOfSlack / amountOfSlack;
-
- for (int i = 0; i < items.size(); ++i)
- {
- Item* const it = items.getUnchecked(i);
-
- if (it->order <= order)
- it->size = jmax (it->minSize, it->minSize + (it->size - it->minSize) * scale);
- }
- }
-
- if (nextHighestOrder < INT_MAX)
- order = nextHighestOrder;
- else
- break;
- }
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_StretchableObjectResizer.cpp *********/
-
- /********* Start of inlined file: juce_TabbedButtonBar.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- TabBarButton::TabBarButton (const String& name,
- TabbedButtonBar* const owner_,
- const int index)
- : Button (name),
- owner (owner_),
- tabIndex (index),
- overlapPixels (0)
- {
- shadow.setShadowProperties (2.2f, 0.7f, 0, 0);
- setComponentEffect (&shadow);
- setWantsKeyboardFocus (false);
- }
-
- TabBarButton::~TabBarButton()
- {
- }
-
- void TabBarButton::paintButton (Graphics& g,
- bool isMouseOverButton,
- bool isButtonDown)
- {
- int x, y, w, h;
- getActiveArea (x, y, w, h);
-
- g.setOrigin (x, y);
-
- getLookAndFeel()
- .drawTabButton (g, w, h,
- owner->getTabBackgroundColour (tabIndex),
- tabIndex, getButtonText(), *this,
- owner->getOrientation(),
- isMouseOverButton, isButtonDown,
- getToggleState());
- }
-
- void TabBarButton::clicked (const ModifierKeys& mods)
- {
- if (mods.isPopupMenu())
- owner->popupMenuClickOnTab (tabIndex, getButtonText());
- else
- owner->setCurrentTabIndex (tabIndex);
- }
-
- bool TabBarButton::hitTest (int mx, int my)
- {
- int x, y, w, h;
- getActiveArea (x, y, w, h);
-
- if (owner->getOrientation() == TabbedButtonBar::TabsAtLeft
- || owner->getOrientation() == TabbedButtonBar::TabsAtRight)
- {
- if (((unsigned int) mx) < (unsigned int) getWidth()
- && my >= y + overlapPixels
- && my < y + h - overlapPixels)
- return true;
- }
- else
- {
- if (mx >= x + overlapPixels && mx < x + w - overlapPixels
- && ((unsigned int) my) < (unsigned int) getHeight())
- return true;
- }
-
- Path p;
- getLookAndFeel()
- .createTabButtonShape (p, w, h, tabIndex, getButtonText(), *this,
- owner->getOrientation(),
- false, false, getToggleState());
-
- return p.contains ((float) (mx - x),
- (float) (my - y));
- }
-
- int TabBarButton::getBestTabLength (const int depth)
- {
- return jlimit (depth * 2,
- depth * 7,
- getLookAndFeel().getTabButtonBestWidth (tabIndex, getButtonText(), depth, *this));
- }
-
- void TabBarButton::getActiveArea (int& x, int& y, int& w, int& h)
- {
- x = 0;
- y = 0;
- int r = getWidth();
- int b = getHeight();
-
- const int spaceAroundImage = getLookAndFeel().getTabButtonSpaceAroundImage();
-
- if (owner->getOrientation() != TabbedButtonBar::TabsAtLeft)
- r -= spaceAroundImage;
-
- if (owner->getOrientation() != TabbedButtonBar::TabsAtRight)
- x += spaceAroundImage;
-
- if (owner->getOrientation() != TabbedButtonBar::TabsAtBottom)
- y += spaceAroundImage;
-
- if (owner->getOrientation() != TabbedButtonBar::TabsAtTop)
- b -= spaceAroundImage;
-
- w = r - x;
- h = b - y;
- }
-
- class TabAreaBehindFrontButtonComponent : public Component
- {
- public:
- TabAreaBehindFrontButtonComponent (TabbedButtonBar* const owner_)
- : owner (owner_)
- {
- setInterceptsMouseClicks (false, false);
- }
-
- ~TabAreaBehindFrontButtonComponent()
- {
- }
-
- void paint (Graphics& g)
- {
- getLookAndFeel()
- .drawTabAreaBehindFrontButton (g, getWidth(), getHeight(),
- *owner, owner->getOrientation());
- }
-
- void enablementChanged()
- {
- repaint();
- }
-
- private:
- TabbedButtonBar* const owner;
-
- TabAreaBehindFrontButtonComponent (const TabAreaBehindFrontButtonComponent&);
- const TabAreaBehindFrontButtonComponent& operator= (const TabAreaBehindFrontButtonComponent&);
- };
-
- TabbedButtonBar::TabbedButtonBar (const Orientation orientation_)
- : orientation (orientation_),
- currentTabIndex (-1),
- extraTabsButton (0)
- {
- setInterceptsMouseClicks (false, true);
- addAndMakeVisible (behindFrontTab = new TabAreaBehindFrontButtonComponent (this));
- setFocusContainer (true);
- }
-
- TabbedButtonBar::~TabbedButtonBar()
- {
- deleteAllChildren();
- }
-
- void TabbedButtonBar::setOrientation (const Orientation newOrientation)
- {
- orientation = newOrientation;
-
- for (int i = getNumChildComponents(); --i >= 0;)
- getChildComponent (i)->resized();
-
- resized();
- }
-
- TabBarButton* TabbedButtonBar::createTabButton (const String& name, const int index)
- {
- return new TabBarButton (name, this, index);
- }
-
- void TabbedButtonBar::clearTabs()
- {
- tabs.clear();
- tabColours.clear();
- currentTabIndex = -1;
-
- deleteAndZero (extraTabsButton);
- removeChildComponent (behindFrontTab);
- deleteAllChildren();
- addChildComponent (behindFrontTab);
-
- setCurrentTabIndex (-1);
- }
-
- void TabbedButtonBar::addTab (const String& tabName,
- const Colour& tabBackgroundColour,
- int insertIndex)
- {
- jassert (tabName.isNotEmpty()); // you have to give them all a name..
-
- if (tabName.isNotEmpty())
- {
- if (((unsigned int) insertIndex) > (unsigned int) tabs.size())
- insertIndex = tabs.size();
-
- for (int i = tabs.size(); --i >= insertIndex;)
- {
- TabBarButton* const tb = getTabButton (i);
-
- if (tb != 0)
- tb->tabIndex++;
- }
-
- tabs.insert (insertIndex, tabName);
- tabColours.insert (insertIndex, tabBackgroundColour);
-
- TabBarButton* const tb = createTabButton (tabName, insertIndex);
- jassert (tb != 0); // your createTabButton() mustn't return zero!
-
- addAndMakeVisible (tb, insertIndex);
-
- resized();
-
- if (currentTabIndex < 0)
- setCurrentTabIndex (0);
- }
- }
-
- void TabbedButtonBar::setTabName (const int tabIndex,
- const String& newName)
- {
- if (((unsigned int) tabIndex) < (unsigned int) tabs.size()
- && tabs[tabIndex] != newName)
- {
- tabs.set (tabIndex, newName);
-
- TabBarButton* const tb = getTabButton (tabIndex);
-
- if (tb != 0)
- tb->setButtonText (newName);
-
- resized();
- }
- }
-
- void TabbedButtonBar::removeTab (const int tabIndex)
- {
- if (((unsigned int) tabIndex) < (unsigned int) tabs.size())
- {
- const int oldTabIndex = currentTabIndex;
- if (currentTabIndex == tabIndex)
- currentTabIndex = -1;
-
- tabs.remove (tabIndex);
- tabColours.remove (tabIndex);
-
- TabBarButton* const tb = getTabButton (tabIndex);
-
- if (tb != 0)
- delete tb;
-
- for (int i = tabIndex + 1; i <= tabs.size(); ++i)
- {
- TabBarButton* const tb = getTabButton (i);
-
- if (tb != 0)
- tb->tabIndex--;
- }
-
- resized();
-
- setCurrentTabIndex (jlimit (0, jmax (0, tabs.size() - 1), oldTabIndex));
- }
- }
-
- void TabbedButtonBar::moveTab (const int currentIndex,
- const int newIndex)
- {
- tabs.move (currentIndex, newIndex);
- tabColours.move (currentIndex, newIndex);
- resized();
- }
-
- int TabbedButtonBar::getNumTabs() const
- {
- return tabs.size();
- }
-
- const StringArray TabbedButtonBar::getTabNames() const
- {
- return tabs;
- }
-
- void TabbedButtonBar::setCurrentTabIndex (int newIndex)
- {
- if (currentTabIndex != newIndex)
- {
- if (((unsigned int) newIndex) >= (unsigned int) tabs.size())
- newIndex = -1;
-
- currentTabIndex = newIndex;
-
- for (int i = 0; i < getNumChildComponents(); ++i)
- {
- TabBarButton* const tb = dynamic_cast <TabBarButton*> (getChildComponent (i));
-
- if (tb != 0)
- tb->setToggleState (tb->tabIndex == newIndex, false);
- }
-
- resized();
- sendChangeMessage (this);
-
- currentTabChanged (newIndex, newIndex >= 0 ? tabs [newIndex] : String::empty);
- }
- }
-
- TabBarButton* TabbedButtonBar::getTabButton (const int index) const
- {
- for (int i = getNumChildComponents(); --i >= 0;)
- {
- TabBarButton* const tb = dynamic_cast <TabBarButton*> (getChildComponent (i));
-
- if (tb != 0 && tb->tabIndex == index)
- return tb;
- }
-
- return 0;
- }
-
- void TabbedButtonBar::lookAndFeelChanged()
- {
- deleteAndZero (extraTabsButton);
- resized();
- }
-
- void TabbedButtonBar::resized()
- {
- const double minimumScale = 0.7;
- int depth = getWidth();
- int length = getHeight();
-
- if (orientation == TabsAtTop || orientation == TabsAtBottom)
- swapVariables (depth, length);
-
- const int overlap = getLookAndFeel().getTabButtonOverlap (depth)
- + getLookAndFeel().getTabButtonSpaceAroundImage() * 2;
-
- int i, totalLength = overlap;
- int numVisibleButtons = tabs.size();
-
- for (i = 0; i < getNumChildComponents(); ++i)
- {
- TabBarButton* const tb = dynamic_cast <TabBarButton*> (getChildComponent (i));
-
- if (tb != 0)
- {
- totalLength += tb->getBestTabLength (depth) - overlap;
- tb->overlapPixels = overlap / 2;
- }
- }
-
- double scale = 1.0;
-
- if (totalLength > length)
- scale = jmax (minimumScale, length / (double) totalLength);
-
- const bool isTooBig = totalLength * scale > length;
- int tabsButtonPos = 0;
-
- if (isTooBig)
- {
- if (extraTabsButton == 0)
- {
- addAndMakeVisible (extraTabsButton = getLookAndFeel().createTabBarExtrasButton());
- extraTabsButton->addButtonListener (this);
- extraTabsButton->setAlwaysOnTop (true);
- extraTabsButton->setTriggeredOnMouseDown (true);
- }
-
- const int buttonSize = jmin (proportionOfWidth (0.7f), proportionOfHeight (0.7f));
- extraTabsButton->setSize (buttonSize, buttonSize);
-
- if (orientation == TabsAtTop || orientation == TabsAtBottom)
- {
- tabsButtonPos = getWidth() - buttonSize / 2 - 1;
- extraTabsButton->setCentrePosition (tabsButtonPos, getHeight() / 2);
- }
- else
- {
- tabsButtonPos = getHeight() - buttonSize / 2 - 1;
- extraTabsButton->setCentrePosition (getWidth() / 2, tabsButtonPos);
- }
-
- totalLength = 0;
-
- for (i = 0; i < tabs.size(); ++i)
- {
- TabBarButton* const tb = getTabButton (i);
-
- if (tb != 0)
- {
- const int newLength = totalLength + tb->getBestTabLength (depth);
-
- if (i > 0 && newLength * minimumScale > tabsButtonPos)
- {
- totalLength += overlap;
- break;
- }
-
- numVisibleButtons = i + 1;
- totalLength = newLength - overlap;
-
- }
- }
-
- scale = jmax (minimumScale, tabsButtonPos / (double) totalLength);
- }
- else
- {
- deleteAndZero (extraTabsButton);
- }
-
- int pos = 0;
-
- TabBarButton* frontTab = 0;
-
- for (i = 0; i < tabs.size(); ++i)
- {
- TabBarButton* const tb = getTabButton (i);
-
- if (tb != 0)
- {
- const int bestLength = roundDoubleToInt (scale * tb->getBestTabLength (depth));
-
- if (i < numVisibleButtons)
- {
- if (orientation == TabsAtTop || orientation == TabsAtBottom)
- tb->setBounds (pos, 0, bestLength, getHeight());
- else
- tb->setBounds (0, pos, getWidth(), bestLength);
-
- tb->toBack();
-
- if (tb->tabIndex == currentTabIndex)
- frontTab = tb;
-
- tb->setVisible (true);
- }
- else
- {
- tb->setVisible (false);
- }
-
- pos += bestLength - overlap;
- }
- }
-
- behindFrontTab->setBounds (0, 0, getWidth(), getHeight());
-
- if (frontTab != 0)
- {
- frontTab->toFront (false);
- behindFrontTab->toBehind (frontTab);
- }
- }
-
- const Colour TabbedButtonBar::getTabBackgroundColour (const int tabIndex)
- {
- return tabColours [tabIndex];
- }
-
- void TabbedButtonBar::setTabBackgroundColour (const int tabIndex, const Colour& newColour)
- {
- if (((unsigned int) tabIndex) < (unsigned int) tabColours.size()
- && tabColours [tabIndex] != newColour)
- {
- tabColours.set (tabIndex, newColour);
- repaint();
- }
- }
-
- void TabbedButtonBar::buttonClicked (Button* button)
- {
- if (extraTabsButton == button)
- {
- PopupMenu m;
-
- for (int i = 0; i < tabs.size(); ++i)
- {
- TabBarButton* const tb = getTabButton (i);
-
- if (tb != 0 && ! tb->isVisible())
- m.addItem (tb->tabIndex + 1, tabs[i], true, i == currentTabIndex);
- }
-
- const int res = m.showAt (extraTabsButton);
-
- if (res != 0)
- setCurrentTabIndex (res - 1);
- }
- }
-
- void TabbedButtonBar::currentTabChanged (const int, const String&)
- {
- }
-
- void TabbedButtonBar::popupMenuClickOnTab (const int, const String&)
- {
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_TabbedButtonBar.cpp *********/
-
- /********* Start of inlined file: juce_TabbedComponent.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- class TabCompButtonBar : public TabbedButtonBar
- {
- public:
- TabCompButtonBar (TabbedComponent* const owner_,
- const TabbedButtonBar::Orientation orientation)
- : TabbedButtonBar (orientation),
- owner (owner_)
- {
- }
-
- ~TabCompButtonBar()
- {
- }
-
- void currentTabChanged (const int newCurrentTabIndex,
- const String& newTabName)
- {
- owner->changeCallback (newCurrentTabIndex, newTabName);
- }
-
- void popupMenuClickOnTab (const int tabIndex,
- const String& tabName)
- {
- owner->popupMenuClickOnTab (tabIndex, tabName);
- }
-
- const Colour getTabBackgroundColour (const int tabIndex)
- {
- return owner->tabs->getTabBackgroundColour (tabIndex);
- }
-
- TabBarButton* createTabButton (const String& tabName, const int tabIndex)
- {
- return owner->createTabButton (tabName, tabIndex);
- }
-
- juce_UseDebuggingNewOperator
-
- private:
- TabbedComponent* const owner;
-
- TabCompButtonBar (const TabCompButtonBar&);
- const TabCompButtonBar& operator= (const TabCompButtonBar&);
- };
-
- TabbedComponent::TabbedComponent (const TabbedButtonBar::Orientation orientation)
- : panelComponent (0),
- tabDepth (30),
- outlineColour (Colours::grey),
- outlineThickness (1),
- edgeIndent (0)
- {
- addAndMakeVisible (tabs = new TabCompButtonBar (this, orientation));
- }
-
- TabbedComponent::~TabbedComponent()
- {
- clearTabs();
- delete tabs;
- }
-
- void TabbedComponent::setOrientation (const TabbedButtonBar::Orientation orientation)
- {
- tabs->setOrientation (orientation);
- resized();
- }
-
- TabbedButtonBar::Orientation TabbedComponent::getOrientation() const throw()
- {
- return tabs->getOrientation();
- }
-
- void TabbedComponent::setTabBarDepth (const int newDepth)
- {
- if (tabDepth != newDepth)
- {
- tabDepth = newDepth;
- resized();
- }
- }
-
- TabBarButton* TabbedComponent::createTabButton (const String& tabName, const int tabIndex)
- {
- return new TabBarButton (tabName, tabs, tabIndex);
- }
-
- void TabbedComponent::clearTabs()
- {
- if (panelComponent != 0)
- {
- panelComponent->setVisible (false);
- removeChildComponent (panelComponent);
- panelComponent = 0;
- }
-
- tabs->clearTabs();
-
- for (int i = contentComponents.size(); --i >= 0;)
- {
- Component* const c = contentComponents.getUnchecked(i);
-
- // be careful not to delete these components until they've been removed from the tab component
- jassert (c == 0 || c->isValidComponent());
-
- if (c != 0 && c->getComponentPropertyBool (T("deleteByTabComp_"), false, false))
- delete c;
- }
-
- contentComponents.clear();
- }
-
- void TabbedComponent::addTab (const String& tabName,
- const Colour& tabBackgroundColour,
- Component* const contentComponent,
- const bool deleteComponentWhenNotNeeded,
- const int insertIndex)
- {
- contentComponents.insert (insertIndex, contentComponent);
-
- if (contentComponent != 0)
- contentComponent->setComponentProperty (T("deleteByTabComp_"), deleteComponentWhenNotNeeded);
-
- tabs->addTab (tabName, tabBackgroundColour, insertIndex);
- }
-
- void TabbedComponent::setTabName (const int tabIndex,
- const String& newName)
- {
- tabs->setTabName (tabIndex, newName);
- }
-
- void TabbedComponent::removeTab (const int tabIndex)
- {
- Component* const c = contentComponents [tabIndex];
-
- if (c != 0 && c->getComponentPropertyBool (T("deleteByTabComp_"), false, false))
- {
- if (c == panelComponent)
- panelComponent = 0;
-
- delete c;
- }
-
- contentComponents.remove (tabIndex);
-
- tabs->removeTab (tabIndex);
- }
-
- int TabbedComponent::getNumTabs() const
- {
- return tabs->getNumTabs();
- }
-
- const StringArray TabbedComponent::getTabNames() const
- {
- return tabs->getTabNames();
- }
-
- Component* TabbedComponent::getTabContentComponent (const int tabIndex) const throw()
- {
- return contentComponents [tabIndex];
- }
-
- const Colour TabbedComponent::getTabBackgroundColour (const int tabIndex) const throw()
- {
- return tabs->getTabBackgroundColour (tabIndex);
- }
-
- void TabbedComponent::setTabBackgroundColour (const int tabIndex, const Colour& newColour)
- {
- tabs->setTabBackgroundColour (tabIndex, newColour);
-
- if (getCurrentTabIndex() == tabIndex)
- repaint();
- }
-
- void TabbedComponent::setCurrentTabIndex (const int newTabIndex)
- {
- tabs->setCurrentTabIndex (newTabIndex);
- }
-
- int TabbedComponent::getCurrentTabIndex() const
- {
- return tabs->getCurrentTabIndex();
- }
-
- const String& TabbedComponent::getCurrentTabName() const
- {
- return tabs->getCurrentTabName();
- }
-
- void TabbedComponent::setOutline (const Colour& colour, int thickness)
- {
- outlineColour = colour;
- outlineThickness = thickness;
- repaint();
- }
-
- void TabbedComponent::setIndent (const int indentThickness)
- {
- edgeIndent = indentThickness;
- }
-
- void TabbedComponent::paint (Graphics& g)
- {
- const TabbedButtonBar::Orientation o = getOrientation();
-
- int x = 0;
- int y = 0;
- int r = getWidth();
- int b = getHeight();
-
- if (o == TabbedButtonBar::TabsAtTop)
- y += tabDepth;
- else if (o == TabbedButtonBar::TabsAtBottom)
- b -= tabDepth;
- else if (o == TabbedButtonBar::TabsAtLeft)
- x += tabDepth;
- else if (o == TabbedButtonBar::TabsAtRight)
- r -= tabDepth;
-
- g.reduceClipRegion (x, y, r - x, b - y);
- g.fillAll (tabs->getTabBackgroundColour (getCurrentTabIndex()));
-
- if (outlineThickness > 0)
- {
- if (o == TabbedButtonBar::TabsAtTop)
- --y;
- else if (o == TabbedButtonBar::TabsAtBottom)
- ++b;
- else if (o == TabbedButtonBar::TabsAtLeft)
- --x;
- else if (o == TabbedButtonBar::TabsAtRight)
- ++r;
-
- g.setColour (outlineColour);
- g.drawRect (x, y, r - x, b - y, outlineThickness);
- }
- }
-
- void TabbedComponent::resized()
- {
- const TabbedButtonBar::Orientation o = getOrientation();
- const int indent = edgeIndent + outlineThickness;
- BorderSize indents (indent);
-
- if (o == TabbedButtonBar::TabsAtTop)
- {
- tabs->setBounds (0, 0, getWidth(), tabDepth);
- indents.setTop (tabDepth + edgeIndent);
- }
- else if (o == TabbedButtonBar::TabsAtBottom)
- {
- tabs->setBounds (0, getHeight() - tabDepth, getWidth(), tabDepth);
- indents.setBottom (tabDepth + edgeIndent);
- }
- else if (o == TabbedButtonBar::TabsAtLeft)
- {
- tabs->setBounds (0, 0, tabDepth, getHeight());
- indents.setLeft (tabDepth + edgeIndent);
- }
- else if (o == TabbedButtonBar::TabsAtRight)
- {
- tabs->setBounds (getWidth() - tabDepth, 0, tabDepth, getHeight());
- indents.setRight (tabDepth + edgeIndent);
- }
-
- const Rectangle bounds (indents.subtractedFrom (Rectangle (0, 0, getWidth(), getHeight())));
-
- for (int i = contentComponents.size(); --i >= 0;)
- if (contentComponents.getUnchecked (i) != 0)
- contentComponents.getUnchecked (i)->setBounds (bounds);
- }
-
- void TabbedComponent::lookAndFeelChanged()
- {
- for (int i = contentComponents.size(); --i >= 0;)
- if (contentComponents.getUnchecked (i) != 0)
- contentComponents.getUnchecked (i)->lookAndFeelChanged();
- }
-
- void TabbedComponent::changeCallback (const int newCurrentTabIndex,
- const String& newTabName)
- {
- if (panelComponent != 0)
- {
- panelComponent->setVisible (false);
- removeChildComponent (panelComponent);
- panelComponent = 0;
- }
-
- if (getCurrentTabIndex() >= 0)
- {
- panelComponent = contentComponents [getCurrentTabIndex()];
-
- if (panelComponent != 0)
- {
- // do these ops as two stages instead of addAndMakeVisible() so that the
- // component has always got a parent when it gets the visibilityChanged() callback
- addChildComponent (panelComponent);
- panelComponent->setVisible (true);
- panelComponent->toFront (true);
- }
-
- repaint();
- }
-
- resized();
-
- currentTabChanged (newCurrentTabIndex, newTabName);
- }
-
- void TabbedComponent::currentTabChanged (const int, const String&)
- {
- }
-
- void TabbedComponent::popupMenuClickOnTab (const int, const String&)
- {
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_TabbedComponent.cpp *********/
-
- /********* Start of inlined file: juce_Viewport.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- Viewport::Viewport (const String& componentName)
- : Component (componentName),
- contentComp (0),
- lastVX (0),
- lastVY (0),
- lastVW (0),
- lastVH (0),
- scrollBarThickness (0),
- singleStepX (16),
- singleStepY (16),
- showHScrollbar (true),
- showVScrollbar (true)
- {
- // content holder is used to clip the contents so they don't overlap the scrollbars
- addAndMakeVisible (contentHolder = new Component());
- contentHolder->setInterceptsMouseClicks (false, true);
-
- verticalScrollBar = new ScrollBar (true);
- horizontalScrollBar = new ScrollBar (false);
-
- addChildComponent (verticalScrollBar);
- addChildComponent (horizontalScrollBar);
-
- verticalScrollBar->addListener (this);
- horizontalScrollBar->addListener (this);
-
- setInterceptsMouseClicks (false, true);
- setWantsKeyboardFocus (true);
- }
-
- Viewport::~Viewport()
- {
- contentHolder->deleteAllChildren();
- deleteAllChildren();
- }
-
- void Viewport::visibleAreaChanged (int, int, int, int)
- {
- }
-
- void Viewport::setViewedComponent (Component* const newViewedComponent)
- {
- if (contentComp != newViewedComponent)
- {
- if (contentComp->isValidComponent())
- {
- Component* const oldComp = contentComp;
- contentComp = 0;
- delete oldComp;
- }
-
- contentComp = newViewedComponent;
-
- if (contentComp != 0)
- {
- contentComp->setTopLeftPosition (0, 0);
- contentHolder->addAndMakeVisible (contentComp);
- contentComp->addComponentListener (this);
- }
-
- updateVisibleRegion();
- }
- }
-
- int Viewport::getMaximumVisibleWidth() const throw()
- {
- return jmax (0, getWidth() - (verticalScrollBar->isVisible() ? getScrollBarThickness() : 0));
- }
-
- int Viewport::getMaximumVisibleHeight() const throw()
- {
- return jmax (0, getHeight() - (horizontalScrollBar->isVisible() ? getScrollBarThickness() : 0));
- }
-
- void Viewport::setViewPosition (const int xPixelsOffset,
- const int yPixelsOffset)
- {
- if (contentComp != 0)
- contentComp->setTopLeftPosition (-xPixelsOffset,
- -yPixelsOffset);
- }
-
- void Viewport::setViewPositionProportionately (const double x,
- const double y)
- {
- if (contentComp != 0)
- setViewPosition (jmax (0, roundDoubleToInt (x * (contentComp->getWidth() - getWidth()))),
- jmax (0, roundDoubleToInt (y * (contentComp->getHeight() - getHeight()))));
- }
-
- void Viewport::componentMovedOrResized (Component&, bool, bool)
- {
- updateVisibleRegion();
- }
-
- void Viewport::resized()
- {
- updateVisibleRegion();
- }
-
- void Viewport::updateVisibleRegion()
- {
- if (contentComp != 0)
- {
- const int newVX = -contentComp->getX();
- const int newVY = -contentComp->getY();
-
- if (newVX == 0 && newVY == 0
- && contentComp->getWidth() <= getWidth()
- && contentComp->getHeight() <= getHeight())
- {
- horizontalScrollBar->setVisible (false);
- verticalScrollBar->setVisible (false);
- }
-
- if ((contentComp->getWidth() > 0) && showHScrollbar
- && getHeight() > getScrollBarThickness())
- {
- horizontalScrollBar->setRangeLimits (0.0, contentComp->getWidth());
- horizontalScrollBar->setCurrentRange (newVX, getMaximumVisibleWidth());
- horizontalScrollBar->setSingleStepSize (singleStepX);
- }
- else
- {
- horizontalScrollBar->setVisible (false);
- }
-
- if ((contentComp->getHeight() > 0) && showVScrollbar
- && getWidth() > getScrollBarThickness())
- {
- verticalScrollBar->setRangeLimits (0.0, contentComp->getHeight());
- verticalScrollBar->setCurrentRange (newVY, getMaximumVisibleHeight());
- verticalScrollBar->setSingleStepSize (singleStepY);
- }
- else
- {
- verticalScrollBar->setVisible (false);
- }
-
- if (verticalScrollBar->isVisible())
- {
- horizontalScrollBar->setCurrentRange (newVX, getMaximumVisibleWidth());
- verticalScrollBar->setCurrentRange (newVY, getMaximumVisibleHeight());
-
- verticalScrollBar
- ->setBounds (getMaximumVisibleWidth(), 0,
- getScrollBarThickness(), getMaximumVisibleHeight());
- }
-
- if (horizontalScrollBar->isVisible())
- {
- horizontalScrollBar->setCurrentRange (newVX, getMaximumVisibleWidth());
-
- horizontalScrollBar
- ->setBounds (0, getMaximumVisibleHeight(),
- getMaximumVisibleWidth(), getScrollBarThickness());
- }
-
- contentHolder->setSize (getMaximumVisibleWidth(),
- getMaximumVisibleHeight());
-
- const int newVW = jmin (contentComp->getRight(), getMaximumVisibleWidth());
- const int newVH = jmin (contentComp->getBottom(), getMaximumVisibleHeight());
-
- if (newVX != lastVX
- || newVY != lastVY
- || newVW != lastVW
- || newVH != lastVH)
- {
- lastVX = newVX;
- lastVY = newVY;
- lastVW = newVW;
- lastVH = newVH;
-
- visibleAreaChanged (newVX, newVY, newVW, newVH);
- }
-
- horizontalScrollBar->handleUpdateNowIfNeeded();
- verticalScrollBar->handleUpdateNowIfNeeded();
- }
- else
- {
- horizontalScrollBar->setVisible (false);
- verticalScrollBar->setVisible (false);
- }
- }
-
- void Viewport::setSingleStepSizes (const int stepX,
- const int stepY)
- {
- singleStepX = stepX;
- singleStepY = stepY;
- updateVisibleRegion();
- }
-
- void Viewport::setScrollBarsShown (const bool showVerticalScrollbarIfNeeded,
- const bool showHorizontalScrollbarIfNeeded)
- {
- showVScrollbar = showVerticalScrollbarIfNeeded;
- showHScrollbar = showHorizontalScrollbarIfNeeded;
- updateVisibleRegion();
- }
-
- void Viewport::setScrollBarThickness (const int thickness)
- {
- scrollBarThickness = thickness;
- updateVisibleRegion();
- }
-
- int Viewport::getScrollBarThickness() const throw()
- {
- return (scrollBarThickness > 0) ? scrollBarThickness
- : getLookAndFeel().getDefaultScrollbarWidth();
- }
-
- void Viewport::setScrollBarButtonVisibility (const bool buttonsVisible)
- {
- verticalScrollBar->setButtonVisibility (buttonsVisible);
- horizontalScrollBar->setButtonVisibility (buttonsVisible);
- }
-
- void Viewport::scrollBarMoved (ScrollBar* scrollBarThatHasMoved, const double newRangeStart)
- {
- if (scrollBarThatHasMoved == horizontalScrollBar)
- {
- setViewPosition (roundDoubleToInt (newRangeStart), getViewPositionY());
- }
- else if (scrollBarThatHasMoved == verticalScrollBar)
- {
- setViewPosition (getViewPositionX(), roundDoubleToInt (newRangeStart));
- }
- }
-
- void Viewport::mouseWheelMove (const MouseEvent& e, float wheelIncrementX, float wheelIncrementY)
- {
- if (! useMouseWheelMoveIfNeeded (e, wheelIncrementX, wheelIncrementY))
- Component::mouseWheelMove (e, wheelIncrementX, wheelIncrementY);
- }
-
- bool Viewport::useMouseWheelMoveIfNeeded (const MouseEvent& e, float wheelIncrementX, float wheelIncrementY)
- {
- if (! (e.mods.isAltDown() || e.mods.isCtrlDown()))
- {
- const bool hasVertBar = verticalScrollBar->isVisible();
- const bool hasHorzBar = horizontalScrollBar->isVisible();
-
- if (hasHorzBar && (wheelIncrementX != 0 || e.mods.isShiftDown() || ! hasVertBar))
- {
- horizontalScrollBar->mouseWheelMove (e.getEventRelativeTo (horizontalScrollBar),
- wheelIncrementX, wheelIncrementY);
- return true;
- }
- else if (hasVertBar && wheelIncrementY != 0)
- {
- verticalScrollBar->mouseWheelMove (e.getEventRelativeTo (verticalScrollBar),
- wheelIncrementX, wheelIncrementY);
- return true;
- }
- }
-
- return false;
- }
-
- bool Viewport::keyPressed (const KeyPress& key)
- {
- const bool isUpDownKey = key.isKeyCode (KeyPress::upKey)
- || key.isKeyCode (KeyPress::downKey)
- || key.isKeyCode (KeyPress::pageUpKey)
- || key.isKeyCode (KeyPress::pageDownKey)
- || key.isKeyCode (KeyPress::homeKey)
- || key.isKeyCode (KeyPress::endKey);
-
- if (verticalScrollBar->isVisible() && isUpDownKey)
- return verticalScrollBar->keyPressed (key);
-
- const bool isLeftRightKey = key.isKeyCode (KeyPress::leftKey)
- || key.isKeyCode (KeyPress::rightKey);
-
- if (horizontalScrollBar->isVisible() && (isUpDownKey || isLeftRightKey))
- return horizontalScrollBar->keyPressed (key);
-
- return false;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_Viewport.cpp *********/
-
- /********* Start of inlined file: juce_LookAndFeel.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- static const Colour createBaseColour (const Colour& buttonColour,
- const bool hasKeyboardFocus,
- const bool isMouseOverButton,
- const bool isButtonDown) throw()
- {
- const float sat = hasKeyboardFocus ? 1.3f : 0.9f;
- const Colour baseColour (buttonColour.withMultipliedSaturation (sat));
-
- if (isButtonDown)
- return baseColour.contrasting (0.2f);
- else if (isMouseOverButton)
- return baseColour.contrasting (0.1f);
-
- return baseColour;
- }
-
- LookAndFeel::LookAndFeel()
- {
- /* if this fails it means you're trying to create a LookAndFeel object before
- the static Colours have been initialised. That ain't gonna work. It probably
- means that you're using a static LookAndFeel object and that your compiler has
- decided to intialise it before the Colours class.
- */
- jassert (Colours::white == Colour (0xffffffff));
-
- // set up the standard set of colours..
- #define textButtonColour 0xffbbbbff
- #define textHighlightColour 0x401111ee
- #define standardOutlineColour 0xb2808080
-
- static const int standardColours[] =
- {
- TextButton::buttonColourId, textButtonColour,
- TextButton::buttonOnColourId, 0xff4444ff,
- TextButton::textColourId, 0xff000000,
-
- ComboBox::buttonColourId, 0xffbbbbff,
- ComboBox::outlineColourId, standardOutlineColour,
-
- ToggleButton::textColourId, 0xff000000,
-
- TextEditor::backgroundColourId, 0xffffffff,
- TextEditor::textColourId, 0xff000000,
- TextEditor::highlightColourId, textHighlightColour,
- TextEditor::highlightedTextColourId, 0xff000000,
- TextEditor::caretColourId, 0xff000000,
- TextEditor::outlineColourId, 0x00000000,
- TextEditor::focusedOutlineColourId, textButtonColour,
- TextEditor::shadowColourId, 0x38000000,
-
- Label::backgroundColourId, 0x00000000,
- Label::textColourId, 0xff000000,
- Label::outlineColourId, 0x00000000,
-
- ScrollBar::backgroundColourId, 0x00000000,
- ScrollBar::thumbColourId, 0xffffffff,
- ScrollBar::trackColourId, 0xffffffff,
-
- TreeView::linesColourId, 0x4c000000,
- TreeView::backgroundColourId, 0x00000000,
-
- PopupMenu::backgroundColourId, 0xffffffff,
- PopupMenu::textColourId, 0xff000000,
- PopupMenu::headerTextColourId, 0xff000000,
- PopupMenu::highlightedTextColourId, 0xffffffff,
- PopupMenu::highlightedBackgroundColourId, 0x991111aa,
-
- ComboBox::textColourId, 0xff000000,
- ComboBox::backgroundColourId, 0xffffffff,
- ComboBox::arrowColourId, 0x99000000,
-
- ListBox::backgroundColourId, 0xffffffff,
- ListBox::outlineColourId, standardOutlineColour,
- ListBox::textColourId, 0xff000000,
-
- Slider::backgroundColourId, 0x00000000,
- Slider::thumbColourId, textButtonColour,
- Slider::trackColourId, 0x7fffffff,
- Slider::rotarySliderFillColourId, 0x7f0000ff,
- Slider::rotarySliderOutlineColourId, 0x66000000,
- Slider::textBoxTextColourId, 0xff000000,
- Slider::textBoxBackgroundColourId, 0xffffffff,
- Slider::textBoxHighlightColourId, textHighlightColour,
- Slider::textBoxOutlineColourId, standardOutlineColour,
-
- AlertWindow::backgroundColourId, 0xffededed,
- AlertWindow::textColourId, 0xff000000,
- AlertWindow::outlineColourId, 0xff666666,
-
- ProgressBar::backgroundColourId, 0xffeeeeee,
- ProgressBar::foregroundColourId, 0xffaaaaee,
-
- TooltipWindow::backgroundColourId, 0xffeeeebb,
- TooltipWindow::textColourId, 0xff000000,
- TooltipWindow::outlineColourId, 0x4c000000,
-
- Toolbar::backgroundColourId, 0xfff6f8f9,
- Toolbar::separatorColourId, 0x4c000000,
- Toolbar::buttonMouseOverBackgroundColourId, 0x4c0000ff,
- Toolbar::buttonMouseDownBackgroundColourId, 0x800000ff,
- Toolbar::labelTextColourId, 0xff000000,
- Toolbar::editingModeOutlineColourId, 0xffff0000,
-
- HyperlinkButton::textColourId, 0xcc1111ee,
-
- GroupComponent::outlineColourId, 0x66000000,
- GroupComponent::textColourId, 0xff000000,
-
- DirectoryContentsDisplayComponent::highlightColourId, textHighlightColour,
- DirectoryContentsDisplayComponent::textColourId, 0xff000000,
-
- 0x1000440, /*LassoComponent::lassoFillColourId*/ 0x66dddddd,
- 0x1000441, /*LassoComponent::lassoOutlineColourId*/ 0x99111111,
-
- MidiKeyboardComponent::whiteNoteColourId, 0xffffffff,
- MidiKeyboardComponent::blackNoteColourId, 0xff000000,
- MidiKeyboardComponent::keySeparatorLineColourId, 0x66000000,
- MidiKeyboardComponent::mouseOverKeyOverlayColourId, 0x80ffff00,
- MidiKeyboardComponent::keyDownOverlayColourId, 0xffb6b600,
- MidiKeyboardComponent::textLabelColourId, 0xff000000,
- MidiKeyboardComponent::upDownButtonBackgroundColourId, 0xffd3d3d3,
- MidiKeyboardComponent::upDownButtonArrowColourId, 0xff000000,
-
- ColourSelector::backgroundColourId, 0xffe5e5e5,
- ColourSelector::labelTextColourId, 0xff000000,
-
- FileSearchPathListComponent::backgroundColourId, 0xffffffff,
- };
-
- for (int i = 0; i < numElementsInArray (standardColours); i += 2)
- setColour (standardColours [i], Colour (standardColours [i + 1]));
- }
-
- LookAndFeel::~LookAndFeel()
- {
- }
-
- const Colour LookAndFeel::findColour (const int colourId) const throw()
- {
- const int index = colourIds.indexOf (colourId);
-
- if (index >= 0)
- return colours [index];
-
- jassertfalse
- return Colours::black;
- }
-
- void LookAndFeel::setColour (const int colourId, const Colour& colour) throw()
- {
- const int index = colourIds.indexOf (colourId);
-
- if (index >= 0)
- colours.set (index, colour);
-
- colourIds.add (colourId);
- colours.add (colour);
- }
-
- static LookAndFeel* defaultLF = 0;
- static LookAndFeel* currentDefaultLF = 0;
-
- LookAndFeel& LookAndFeel::getDefaultLookAndFeel() throw()
- {
- // if this happens, your app hasn't initialised itself properly.. if you're
- // trying to hack your own main() function, have a look at
- // JUCEApplication::initialiseForGUI()
- jassert (currentDefaultLF != 0);
-
- return *currentDefaultLF;
- }
-
- void LookAndFeel::setDefaultLookAndFeel (LookAndFeel* newDefaultLookAndFeel) throw()
- {
- if (newDefaultLookAndFeel == 0)
- {
- if (defaultLF == 0)
- defaultLF = new LookAndFeel();
-
- newDefaultLookAndFeel = defaultLF;
- }
-
- currentDefaultLF = newDefaultLookAndFeel;
-
- for (int i = Desktop::getInstance().getNumComponents(); --i >= 0;)
- {
- Component* const c = Desktop::getInstance().getComponent (i);
-
- if (c != 0)
- c->sendLookAndFeelChange();
- }
- }
-
- void LookAndFeel::clearDefaultLookAndFeel() throw()
- {
- if (currentDefaultLF == defaultLF)
- currentDefaultLF = 0;
-
- deleteAndZero (defaultLF);
- }
-
- void LookAndFeel::drawButtonBackground (Graphics& g,
- Button& button,
- const Colour& backgroundColour,
- bool isMouseOverButton,
- bool isButtonDown)
- {
- const int width = button.getWidth();
- const int height = button.getHeight();
-
- const float outlineThickness = button.isEnabled() ? ((isButtonDown || isMouseOverButton) ? 1.2f : 0.7f) : 0.4f;
- const float halfThickness = outlineThickness * 0.5f;
-
- const float indentL = button.isConnectedOnLeft() ? 0.1f : halfThickness;
- const float indentR = button.isConnectedOnRight() ? 0.1f : halfThickness;
- const float indentT = button.isConnectedOnTop() ? 0.1f : halfThickness;
- const float indentB = button.isConnectedOnBottom() ? 0.1f : halfThickness;
-
- const Colour baseColour (createBaseColour (backgroundColour,
- button.hasKeyboardFocus (true),
- isMouseOverButton, isButtonDown)
- .withMultipliedAlpha (button.isEnabled() ? 1.0f : 0.5f));
-
- drawGlassLozenge (g,
- indentL,
- indentT,
- width - indentL - indentR,
- height - indentT - indentB,
- baseColour, outlineThickness, -1.0f,
- button.isConnectedOnLeft(),
- button.isConnectedOnRight(),
- button.isConnectedOnTop(),
- button.isConnectedOnBottom());
- }
-
- void LookAndFeel::drawButtonText (Graphics& g, TextButton& button,
- bool /*isMouseOverButton*/, bool /*isButtonDown*/)
- {
- g.setFont (button.getFont());
- g.setColour (button.findColour (TextButton::textColourId)
- .withMultipliedAlpha (button.isEnabled() ? 1.0f : 0.5f));
-
- const int yIndent = jmin (4, button.proportionOfHeight (0.3f));
- const int cornerSize = jmin (button.getHeight(), button.getWidth()) / 2;
-
- const int fontHeight = roundFloatToInt (g.getCurrentFont().getHeight() * 0.6f);
- const int leftIndent = jmin (fontHeight, 2 + cornerSize / (button.isConnectedOnLeft() ? 4 : 2));
- const int rightIndent = jmin (fontHeight, 2 + cornerSize / (button.isConnectedOnRight() ? 4 : 2));
-
- g.drawFittedText (button.getButtonText(),
- leftIndent,
- yIndent,
- button.getWidth() - leftIndent - rightIndent,
- button.getHeight() - yIndent * 2,
- Justification::centred, 2);
- }
-
- void LookAndFeel::drawTickBox (Graphics& g,
- Component& component,
- int x, int y, int w, int h,
- const bool ticked,
- const bool isEnabled,
- const bool isMouseOverButton,
- const bool isButtonDown)
- {
- const float boxSize = w * 0.7f;
-
- drawGlassSphere (g, (float) x, y + (h - boxSize) * 0.5f, boxSize,
- createBaseColour (component.findColour (TextButton::buttonColourId)
- .withMultipliedAlpha (isEnabled ? 1.0f : 0.5f),
- true,
- isMouseOverButton,
- isButtonDown),
- isEnabled ? ((isButtonDown || isMouseOverButton) ? 1.1f : 0.5f) : 0.3f);
-
- if (ticked)
- {
- Path tick;
- tick.startNewSubPath (1.5f, 3.0f);
- tick.lineTo (3.0f, 6.0f);
- tick.lineTo (6.0f, 0.0f);
-
- g.setColour (isEnabled ? Colours::black : Colours::grey);
-
- const AffineTransform trans (AffineTransform::scale (w / 9.0f, h / 9.0f)
- .translated ((float) x, (float) y));
-
- g.strokePath (tick, PathStrokeType (2.5f), trans);
- }
- }
-
- void LookAndFeel::drawToggleButton (Graphics& g,
- ToggleButton& button,
- bool isMouseOverButton,
- bool isButtonDown)
- {
- if (button.hasKeyboardFocus (true))
- {
- g.setColour (button.findColour (TextEditor::focusedOutlineColourId));
- g.drawRect (0, 0, button.getWidth(), button.getHeight());
- }
-
- const int tickWidth = jmin (20, button.getHeight() - 4);
-
- drawTickBox (g, button, 4, (button.getHeight() - tickWidth) / 2,
- tickWidth, tickWidth,
- button.getToggleState(),
- button.isEnabled(),
- isMouseOverButton,
- isButtonDown);
-
- g.setColour (button.findColour (ToggleButton::textColourId));
- g.setFont (jmin (15.0f, button.getHeight() * 0.6f));
-
- if (! button.isEnabled())
- g.setOpacity (0.5f);
-
- const int textX = tickWidth + 5;
-
- g.drawFittedText (button.getButtonText(),
- textX, 4,
- button.getWidth() - textX - 2, button.getHeight() - 8,
- Justification::centredLeft, 10);
- }
-
- void LookAndFeel::changeToggleButtonWidthToFitText (ToggleButton& button)
- {
- Font font (jmin (15.0f, button.getHeight() * 0.6f));
-
- const int tickWidth = jmin (24, button.getHeight());
-
- button.setSize (font.getStringWidth (button.getButtonText()) + tickWidth + 8,
- button.getHeight());
- }
-
- void LookAndFeel::drawAlertBox (Graphics& g,
- AlertWindow& alert,
- const Rectangle& textArea,
- TextLayout& textLayout)
- {
- const int iconWidth = 80;
-
- const Colour background (alert.findColour (AlertWindow::backgroundColourId));
-
- g.fillAll (background);
-
- int iconSpaceUsed = 0;
- Justification alignment (Justification::horizontallyCentred);
-
- int iconSize = jmin (iconWidth + 50, alert.getHeight() + 20);
-
- if (alert.containsAnyExtraComponents() || alert.getNumButtons() > 2)
- iconSize = jmin (iconSize, textArea.getHeight() + 50);
-
- const Rectangle iconRect (iconSize / -10,
- iconSize / -10,
- iconSize,
- iconSize);
-
- if (alert.getAlertType() == AlertWindow::QuestionIcon
- || alert.getAlertType() == AlertWindow::InfoIcon)
- {
- if (alert.getAlertType() == AlertWindow::InfoIcon)
- g.setColour (background.overlaidWith (Colour (0x280000ff)));
- else
- g.setColour (background.overlaidWith (Colours::gold.darker().withAlpha (0.25f)));
-
- g.fillEllipse ((float) iconRect.getX(),
- (float) iconRect.getY(),
- (float) iconRect.getWidth(),
- (float) iconRect.getHeight());
-
- g.setColour (background);
- g.setFont (iconRect.getHeight() * 0.9f, Font::bold);
- g.drawText ((alert.getAlertType() == AlertWindow::InfoIcon) ? "i"
- : "?",
- iconRect.getX(),
- iconRect.getY(),
- iconRect.getWidth(),
- iconRect.getHeight(),
- Justification::centred, false);
-
- iconSpaceUsed = iconWidth;
- alignment = Justification::left;
- }
- else if (alert.getAlertType() == AlertWindow::WarningIcon)
- {
- Path p;
- p.addTriangle (iconRect.getX() + iconRect.getWidth() * 0.5f,
- (float) iconRect.getY(),
- (float) iconRect.getRight(),
- (float) iconRect.getBottom(),
- (float) iconRect.getX(),
- (float) iconRect.getBottom());
-
- g.setColour (background.overlaidWith (Colour (0x33ff0000)));
- g.fillPath (p.createPathWithRoundedCorners (5.0f));
-
- g.setColour (background);
- g.setFont (iconRect.getHeight() * 0.9f, Font::bold);
-
- g.drawText (T("!"),
- iconRect.getX(),
- iconRect.getY(),
- iconRect.getWidth(),
- iconRect.getHeight() + iconRect.getHeight() / 8,
- Justification::centred, false);
-
- iconSpaceUsed = iconWidth;
- alignment = Justification::left;
- }
-
- g.setColour (alert.findColour (AlertWindow::textColourId));
-
- textLayout.drawWithin (g,
- textArea.getX() + iconSpaceUsed,
- textArea.getY(),
- textArea.getWidth() - iconSpaceUsed,
- textArea.getHeight(),
- alignment.getFlags() | Justification::top);
-
- g.setColour (alert.findColour (AlertWindow::outlineColourId));
- g.drawRect (0, 0, alert.getWidth(), alert.getHeight());
- }
-
- int LookAndFeel::getAlertBoxWindowFlags()
- {
- return ComponentPeer::windowAppearsOnTaskbar
- | ComponentPeer::windowHasDropShadow;
- }
-
- void LookAndFeel::drawProgressBar (Graphics& g, ProgressBar& progressBar,
- int width, int height,
- double progress, const String& textToShow)
- {
- const Colour background (progressBar.findColour (ProgressBar::backgroundColourId));
- const Colour foreground (progressBar.findColour (ProgressBar::foregroundColourId));
-
- g.fillAll (background);
-
- if (progress >= 0.0f && progress < 1.0f)
- {
- drawGlassLozenge (g, 1.0f, 1.0f,
- (float) jlimit (0.0, width - 2.0, progress * (width - 2.0)),
- (float) (height - 2),
- foreground,
- 0.5f, 0.0f,
- true, true, true, true);
- }
- else
- {
- // spinning bar..
- g.setColour (foreground);
-
- const int stripeWidth = height * 2;
- const int position = (Time::getMillisecondCounter() / 15) % stripeWidth;
-
- Path p;
-
- for (float x = (float) (-stripeWidth - position); x < width + stripeWidth; x += stripeWidth)
- p.addQuadrilateral (x, 0.0f,
- x + stripeWidth * 0.5f, 0.0f,
- x, (float) height,
- x - stripeWidth * 0.5f, (float) height);
-
- Image im (Image::ARGB, width, height, true);
-
- {
- Graphics g (im);
- drawGlassLozenge (g, 1.0f, 1.0f,
- (float) (width - 2),
- (float) (height - 2),
- foreground,
- 0.5f, 0.0f,
- true, true, true, true);
- }
-
- ImageBrush ib (&im, 0, 0, 0.85f);
- g.setBrush (&ib);
-
- g.fillPath (p);
- }
-
- if (textToShow.isNotEmpty())
- {
- g.setColour (Colour::contrasting (background, foreground));
- g.setFont (height * 0.6f);
-
- g.drawText (textToShow, 0, 0, width, height, Justification::centred, false);
- }
- }
-
- void LookAndFeel::drawScrollbarButton (Graphics& g,
- ScrollBar& scrollbar,
- int width, int height,
- int buttonDirection,
- bool /*isScrollbarVertical*/,
- bool /*isMouseOverButton*/,
- bool isButtonDown)
- {
- Path p;
-
- if (buttonDirection == 0)
- p.addTriangle (width * 0.5f, height * 0.2f,
- width * 0.1f, height * 0.7f,
- width * 0.9f, height * 0.7f);
- else if (buttonDirection == 1)
- p.addTriangle (width * 0.8f, height * 0.5f,
- width * 0.3f, height * 0.1f,
- width * 0.3f, height * 0.9f);
- else if (buttonDirection == 2)
- p.addTriangle (width * 0.5f, height * 0.8f,
- width * 0.1f, height * 0.3f,
- width * 0.9f, height * 0.3f);
- else if (buttonDirection == 3)
- p.addTriangle (width * 0.2f, height * 0.5f,
- width * 0.7f, height * 0.1f,
- width * 0.7f, height * 0.9f);
-
- if (isButtonDown)
- g.setColour (scrollbar.findColour (ScrollBar::thumbColourId).contrasting (0.2f));
- else
- g.setColour (scrollbar.findColour (ScrollBar::thumbColourId));
-
- g.fillPath (p);
-
- g.setColour (Colour (0x80000000));
- g.strokePath (p, PathStrokeType (0.5f));
- }
-
- void LookAndFeel::drawScrollbar (Graphics& g,
- ScrollBar& scrollbar,
- int x, int y,
- int width, int height,
- bool isScrollbarVertical,
- int thumbStartPosition,
- int thumbSize,
- bool /*isMouseOver*/,
- bool /*isMouseDown*/)
- {
- g.fillAll (scrollbar.findColour (ScrollBar::backgroundColourId));
-
- Path slotPath, thumbPath;
-
- const float slotIndent = jmin (width, height) > 15 ? 1.0f : 0.0f;
- const float slotIndentx2 = slotIndent * 2.0f;
- const float thumbIndent = slotIndent + 1.0f;
- const float thumbIndentx2 = thumbIndent * 2.0f;
-
- float gx1 = 0.0f, gy1 = 0.0f, gx2 = 0.0f, gy2 = 0.0f;
-
- if (isScrollbarVertical)
- {
- slotPath.addRoundedRectangle (x + slotIndent,
- y + slotIndent,
- width - slotIndentx2,
- height - slotIndentx2,
- (width - slotIndentx2) * 0.5f);
-
- if (thumbSize > 0)
- thumbPath.addRoundedRectangle (x + thumbIndent,
- thumbStartPosition + thumbIndent,
- width - thumbIndentx2,
- thumbSize - thumbIndentx2,
- (width - thumbIndentx2) * 0.5f);
- gx1 = (float) x;
- gx2 = x + width * 0.7f;
- }
- else
- {
- slotPath.addRoundedRectangle (x + slotIndent,
- y + slotIndent,
- width - slotIndentx2,
- height - slotIndentx2,
- (height - slotIndentx2) * 0.5f);
-
- if (thumbSize > 0)
- thumbPath.addRoundedRectangle (thumbStartPosition + thumbIndent,
- y + thumbIndent,
- thumbSize - thumbIndentx2,
- height - thumbIndentx2,
- (height - thumbIndentx2) * 0.5f);
- gy1 = (float) y;
- gy2 = y + height * 0.7f;
- }
-
- const Colour thumbColour (scrollbar.findColour (ScrollBar::trackColourId));
-
- GradientBrush gb (thumbColour.overlaidWith (Colour (0x44000000)),
- gx1, gy1,
- thumbColour.overlaidWith (Colour (0x19000000)),
- gx2, gy2, false);
-
- g.setBrush (&gb);
- g.fillPath (slotPath);
-
- if (isScrollbarVertical)
- {
- gx1 = x + width * 0.6f;
- gx2 = (float) x + width;
- }
- else
- {
- gy1 = y + height * 0.6f;
- gy2 = (float) y + height;
- }
-
- GradientBrush gb2 (Colours::transparentBlack,
- gx1, gy1,
- Colour (0x19000000),
- gx2, gy2, false);
-
- g.setBrush (&gb2);
- g.fillPath (slotPath);
-
- g.setColour (thumbColour);
- g.fillPath (thumbPath);
-
- GradientBrush gb3 (Colour (0x10000000),
- gx1, gy1,
- Colours::transparentBlack,
- gx2, gy2, false);
-
- g.saveState();
- g.setBrush (&gb3);
-
- if (isScrollbarVertical)
- g.reduceClipRegion (x + width / 2, y, width, height);
- else
- g.reduceClipRegion (x, y + height / 2, width, height);
-
- g.fillPath (thumbPath);
- g.restoreState();
-
- g.setColour (Colour (0x4c000000));
- g.strokePath (thumbPath, PathStrokeType (0.4f));
- }
-
- ImageEffectFilter* LookAndFeel::getScrollbarEffect()
- {
- return 0;
- }
-
- int LookAndFeel::getMinimumScrollbarThumbSize (ScrollBar& scrollbar)
- {
- return jmin (scrollbar.getWidth(), scrollbar.getHeight()) * 2;
- }
-
- int LookAndFeel::getDefaultScrollbarWidth()
- {
- return 18;
- }
-
- int LookAndFeel::getScrollbarButtonSize (ScrollBar& scrollbar)
- {
- return 2 + (scrollbar.isVertical() ? scrollbar.getWidth()
- : scrollbar.getHeight());
- }
-
- const Path LookAndFeel::getTickShape (const float height)
- {
- static const unsigned char tickShapeData[] =
- {
- 109,0,224,168,68,0,0,119,67,108,0,224,172,68,0,128,146,67,113,0,192,148,68,0,0,219,67,0,96,110,68,0,224,56,68,113,0,64,51,68,0,32,130,68,0,64,20,68,0,224,
- 162,68,108,0,128,3,68,0,128,168,68,113,0,128,221,67,0,192,175,68,0,0,207,67,0,32,179,68,113,0,0,201,67,0,224,173,68,0,0,181,67,0,224,161,68,108,0,128,168,67,
- 0,128,154,68,113,0,128,141,67,0,192,138,68,0,128,108,67,0,64,131,68,113,0,0,62,67,0,128,119,68,0,0,5,67,0,128,114,68,113,0,0,102,67,0,192,88,68,0,128,155,
- 67,0,192,88,68,113,0,0,190,67,0,192,88,68,0,128,232,67,0,224,131,68,108,0,128,246,67,0,192,139,68,113,0,64,33,68,0,128,87,68,0,0,93,68,0,224,26,68,113,0,
- 96,140,68,0,128,188,67,0,224,168,68,0,0,119,67,99,101
- };
-
- Path p;
- p.loadPathFromData (tickShapeData, sizeof (tickShapeData));
- p.scaleToFit (0, 0, height * 2.0f, height, true);
- return p;
- }
-
- const Path LookAndFeel::getCrossShape (const float height)
- {
- static const unsigned char crossShapeData[] =
- {
- 109,0,0,17,68,0,96,145,68,108,0,192,13,68,0,192,147,68,113,0,0,213,67,0,64,174,68,0,0,168,67,0,64,174,68,113,0,0,104,67,0,64,174,68,0,0,5,67,0,64,
- 153,68,113,0,0,18,67,0,64,153,68,0,0,24,67,0,64,153,68,113,0,0,135,67,0,64,153,68,0,128,207,67,0,224,130,68,108,0,0,220,67,0,0,126,68,108,0,0,204,67,
- 0,128,117,68,113,0,0,138,67,0,64,82,68,0,0,138,67,0,192,57,68,113,0,0,138,67,0,192,37,68,0,128,210,67,0,64,10,68,113,0,128,220,67,0,64,45,68,0,0,8,
- 68,0,128,78,68,108,0,192,14,68,0,0,87,68,108,0,64,20,68,0,0,80,68,113,0,192,57,68,0,0,32,68,0,128,88,68,0,0,32,68,113,0,64,112,68,0,0,32,68,0,
- 128,124,68,0,64,68,68,113,0,0,121,68,0,192,67,68,0,128,119,68,0,192,67,68,113,0,192,108,68,0,192,67,68,0,32,89,68,0,96,82,68,113,0,128,69,68,0,0,97,68,
- 0,0,56,68,0,64,115,68,108,0,64,49,68,0,128,124,68,108,0,192,55,68,0,96,129,68,113,0,0,92,68,0,224,146,68,0,192,129,68,0,224,146,68,113,0,64,110,68,0,64,
- 168,68,0,64,87,68,0,64,168,68,113,0,128,66,68,0,64,168,68,0,64,27,68,0,32,150,68,99,101
- };
-
- Path p;
- p.loadPathFromData (crossShapeData, sizeof (crossShapeData));
- p.scaleToFit (0, 0, height * 2.0f, height, true);
- return p;
- }
-
- void LookAndFeel::drawTreeviewPlusMinusBox (Graphics& g, int x, int y, int w, int h, bool isPlus)
- {
- const int boxSize = ((jmin (16, w, h) << 1) / 3) | 1;
-
- x += (w - boxSize) >> 1;
- y += (h - boxSize) >> 1;
- w = boxSize;
- h = boxSize;
-
- g.setColour (Colour (0xe5ffffff));
- g.fillRect (x, y, w, h);
-
- g.setColour (Colour (0x80000000));
- g.drawRect (x, y, w, h);
-
- const float size = boxSize / 2 + 1.0f;
- const float centre = (float) (boxSize / 2);
-
- g.fillRect (x + (w - size) * 0.5f, y + centre, size, 1.0f);
-
- if (isPlus)
- g.fillRect (x + centre, y + (h - size) * 0.5f, 1.0f, size);
- }
-
- void LookAndFeel::drawBubble (Graphics& g,
- float tipX, float tipY,
- float boxX, float boxY,
- float boxW, float boxH)
- {
- int side = 0;
-
- if (tipX < boxX)
- side = 1;
- else if (tipX > boxX + boxW)
- side = 3;
- else if (tipY > boxY + boxH)
- side = 2;
-
- const float indent = 2.0f;
- Path p;
- p.addBubble (boxX + indent,
- boxY + indent,
- boxW - indent * 2.0f,
- boxH - indent * 2.0f,
- 5.0f,
- tipX, tipY,
- side,
- 0.5f,
- jmin (15.0f, boxW * 0.3f, boxH * 0.3f));
-
- //xxx need to take comp as param for colour
- g.setColour (findColour (TooltipWindow::backgroundColourId).withAlpha (0.9f));
- g.fillPath (p);
-
- //xxx as above
- g.setColour (findColour (TooltipWindow::textColourId).withAlpha (0.4f));
- g.strokePath (p, PathStrokeType (1.33f));
- }
-
- const Font LookAndFeel::getPopupMenuFont()
- {
- return Font (17.0f);
- }
-
- void LookAndFeel::getIdealPopupMenuItemSize (const String& text,
- const bool isSeparator,
- int standardMenuItemHeight,
- int& idealWidth,
- int& idealHeight)
- {
- if (isSeparator)
- {
- idealWidth = 50;
- idealHeight = standardMenuItemHeight > 0 ? standardMenuItemHeight / 2 : 10;
- }
- else
- {
- Font font (getPopupMenuFont());
-
- if (standardMenuItemHeight > 0 && font.getHeight() > standardMenuItemHeight / 1.3f)
- font.setHeight (standardMenuItemHeight / 1.3f);
-
- idealHeight = standardMenuItemHeight > 0 ? standardMenuItemHeight : roundFloatToInt (font.getHeight() * 1.3f);
- idealWidth = font.getStringWidth (text) + idealHeight * 2;
- }
- }
-
- void LookAndFeel::drawPopupMenuBackground (Graphics& g, int width, int height)
- {
- const Colour background (findColour (PopupMenu::backgroundColourId));
-
- g.fillAll (background);
- g.setColour (background.overlaidWith (Colour (0x2badd8e6)));
-
- for (int i = 0; i < height; i += 3)
- g.fillRect (0, i, width, 1);
-
- g.setColour (findColour (PopupMenu::textColourId).withAlpha (0.6f));
- g.drawRect (0, 0, width, height);
- }
-
- void LookAndFeel::drawPopupMenuUpDownArrow (Graphics& g,
- int width, int height,
- bool isScrollUpArrow)
- {
- const Colour background (findColour (PopupMenu::backgroundColourId));
-
- GradientBrush gb (background,
- 0.0f, height * 0.5f,
- background.withAlpha (0.0f),
- 0.0f, isScrollUpArrow ? ((float) height) : 0.0f,
- false);
-
- g.setBrush (&gb);
- g.fillRect (1, 1, width - 2, height - 2);
-
- const float hw = width * 0.5f;
- const float arrowW = height * 0.3f;
- const float y1 = height * (isScrollUpArrow ? 0.6f : 0.3f);
- const float y2 = height * (isScrollUpArrow ? 0.3f : 0.6f);
-
- Path p;
- p.addTriangle (hw - arrowW, y1,
- hw + arrowW, y1,
- hw, y2);
-
- g.setColour (findColour (PopupMenu::textColourId).withAlpha (0.5f));
- g.fillPath (p);
- }
-
- void LookAndFeel::drawPopupMenuItem (Graphics& g,
- int width, int height,
- const bool isSeparator,
- const bool isActive,
- const bool isHighlighted,
- const bool isTicked,
- const bool hasSubMenu,
- const String& text,
- const String& shortcutKeyText,
- Image* image,
- const Colour* const textColourToUse)
- {
- const float halfH = height * 0.5f;
-
- if (isSeparator)
- {
- const float separatorIndent = 5.5f;
-
- g.setColour (Colour (0x33000000));
- g.drawLine (separatorIndent, halfH, width - separatorIndent, halfH);
-
- g.setColour (Colour (0x66ffffff));
- g.drawLine (separatorIndent, halfH + 1.0f, width - separatorIndent, halfH + 1.0f);
- }
- else
- {
- Colour textColour (findColour (PopupMenu::textColourId));
-
- if (textColourToUse != 0)
- textColour = *textColourToUse;
-
- if (isHighlighted)
- {
- g.setColour (findColour (PopupMenu::highlightedBackgroundColourId));
- g.fillRect (1, 1, width - 2, height - 2);
-
- g.setColour (findColour (PopupMenu::highlightedTextColourId));
- }
- else
- {
- g.setColour (textColour);
- }
-
- if (! isActive)
- g.setOpacity (0.3f);
-
- Font font (getPopupMenuFont());
-
- if (font.getHeight() > height / 1.3f)
- font.setHeight (height / 1.3f);
-
- g.setFont (font);
-
- const int leftBorder = (height * 5) / 4;
- const int rightBorder = 4;
-
- if (image != 0)
- {
- g.drawImageWithin (image,
- 2, 1, leftBorder - 4, height - 2,
- RectanglePlacement::centred | RectanglePlacement::onlyReduceInSize, false);
- }
- else if (isTicked)
- {
- const Path tick (getTickShape (1.0f));
- const float th = font.getAscent();
- const float ty = halfH - th * 0.5f;
-
- g.fillPath (tick, tick.getTransformToScaleToFit (2.0f, ty, (float) (leftBorder - 4),
- th, true));
- }
-
- g.drawFittedText (text,
- leftBorder, 0,
- width - (leftBorder + rightBorder), height,
- Justification::centredLeft, 1);
-
- if (shortcutKeyText.isNotEmpty())
- {
- Font f2 (g.getCurrentFont());
- f2.setHeight (f2.getHeight() * 0.75f);
- f2.setHorizontalScale (0.95f);
- g.setFont (f2);
-
- g.drawText (shortcutKeyText,
- leftBorder,
- 0,
- width - (leftBorder + rightBorder + 4),
- height,
- Justification::centredRight,
- true);
- }
-
- if (hasSubMenu)
- {
- const float arrowH = 0.6f * getPopupMenuFont().getAscent();
- const float x = width - height * 0.6f;
-
- Path p;
- p.addTriangle (x, halfH - arrowH * 0.5f,
- x, halfH + arrowH * 0.5f,
- x + arrowH * 0.6f, halfH);
-
- g.fillPath (p);
- }
- }
- }
-
- int LookAndFeel::getMenuWindowFlags()
- {
- return ComponentPeer::windowHasDropShadow;
- }
-
- void LookAndFeel::drawMenuBarBackground (Graphics& g, int width, int height,
- bool, MenuBarComponent& menuBar)
- {
- const Colour baseColour (createBaseColour (menuBar.findColour (PopupMenu::backgroundColourId), false, false, false));
-
- if (menuBar.isEnabled())
- {
- drawShinyButtonShape (g,
- -4.0f, 0.0f,
- width + 8.0f, (float) height,
- 0.0f,
- baseColour,
- 0.4f,
- true, true, true, true);
- }
- else
- {
- g.fillAll (baseColour);
- }
- }
-
- const Font LookAndFeel::getMenuBarFont (MenuBarComponent& menuBar, int /*itemIndex*/, const String& /*itemText*/)
- {
- return Font (menuBar.getHeight() * 0.7f);
- }
-
- int LookAndFeel::getMenuBarItemWidth (MenuBarComponent& menuBar, int itemIndex, const String& itemText)
- {
- return getMenuBarFont (menuBar, itemIndex, itemText)
- .getStringWidth (itemText) + menuBar.getHeight();
- }
-
- void LookAndFeel::drawMenuBarItem (Graphics& g,
- int width, int height,
- int itemIndex,
- const String& itemText,
- bool isMouseOverItem,
- bool isMenuOpen,
- bool /*isMouseOverBar*/,
- MenuBarComponent& menuBar)
- {
- if (! menuBar.isEnabled())
- {
- g.setColour (menuBar.findColour (PopupMenu::textColourId)
- .withMultipliedAlpha (0.5f));
- }
- else if (isMenuOpen || isMouseOverItem)
- {
- g.fillAll (menuBar.findColour (PopupMenu::highlightedBackgroundColourId));
- g.setColour (menuBar.findColour (PopupMenu::highlightedTextColourId));
- }
- else
- {
- g.setColour (menuBar.findColour (PopupMenu::textColourId));
- }
-
- g.setFont (getMenuBarFont (menuBar, itemIndex, itemText));
- g.drawFittedText (itemText, 0, 0, width, height, Justification::centred, 1);
- }
-
- void LookAndFeel::fillTextEditorBackground (Graphics& g, int /*width*/, int /*height*/,
- TextEditor& textEditor)
- {
- g.fillAll (textEditor.findColour (TextEditor::backgroundColourId));
- }
-
- void LookAndFeel::drawTextEditorOutline (Graphics& g, int width, int height, TextEditor& textEditor)
- {
- if (textEditor.isEnabled())
- {
- if (textEditor.hasKeyboardFocus (true) && ! textEditor.isReadOnly())
- {
- const int border = 2;
-
- g.setColour (textEditor.findColour (TextEditor::focusedOutlineColourId));
- g.drawRect (0, 0, width, height, border);
-
- g.setOpacity (1.0f);
- const Colour shadowColour (textEditor.findColour (TextEditor::shadowColourId).withMultipliedAlpha (0.75f));
- g.drawBevel (0, 0, width, height + 2, border + 2, shadowColour, shadowColour);
- }
- else
- {
- g.setColour (textEditor.findColour (TextEditor::outlineColourId));
- g.drawRect (0, 0, width, height);
-
- g.setOpacity (1.0f);
- const Colour shadowColour (textEditor.findColour (TextEditor::shadowColourId));
- g.drawBevel (0, 0, width, height + 2, 3, shadowColour, shadowColour);
- }
- }
- }
-
- void LookAndFeel::drawComboBox (Graphics& g, int width, int height,
- const bool isButtonDown,
- int buttonX, int buttonY,
- int buttonW, int buttonH,
- ComboBox& box)
- {
- g.fillAll (box.findColour (ComboBox::backgroundColourId));
-
- if (box.isEnabled() && box.hasKeyboardFocus (false))
- {
- g.setColour (box.findColour (TextButton::buttonColourId));
- g.drawRect (0, 0, width, height, 2);
- }
- else
- {
- g.setColour (box.findColour (ComboBox::outlineColourId));
- g.drawRect (0, 0, width, height);
- }
-
- const float outlineThickness = box.isEnabled() ? (isButtonDown ? 1.2f : 0.5f) : 0.3f;
-
- const Colour baseColour (createBaseColour (box.findColour (ComboBox::buttonColourId),
- box.hasKeyboardFocus (true),
- false, isButtonDown)
- .withMultipliedAlpha (box.isEnabled() ? 1.0f : 0.5f));
-
- drawGlassLozenge (g,
- buttonX + outlineThickness, buttonY + outlineThickness,
- buttonW - outlineThickness * 2.0f, buttonH - outlineThickness * 2.0f,
- baseColour, outlineThickness, -1.0f,
- true, true, true, true);
-
- if (box.isEnabled())
- {
- const float arrowX = 0.3f;
- const float arrowH = 0.2f;
-
- Path p;
- p.addTriangle (buttonX + buttonW * 0.5f, buttonY + buttonH * (0.45f - arrowH),
- buttonX + buttonW * (1.0f - arrowX), buttonY + buttonH * 0.45f,
- buttonX + buttonW * arrowX, buttonY + buttonH * 0.45f);
-
- p.addTriangle (buttonX + buttonW * 0.5f, buttonY + buttonH * (0.55f + arrowH),
- buttonX + buttonW * (1.0f - arrowX), buttonY + buttonH * 0.55f,
- buttonX + buttonW * arrowX, buttonY + buttonH * 0.55f);
-
- g.setColour (box.findColour (ComboBox::arrowColourId));
- g.fillPath (p);
- }
- }
-
- const Font LookAndFeel::getComboBoxFont (ComboBox& box)
- {
- return Font (jmin (15.0f, box.getHeight() * 0.85f));
- }
-
- Label* LookAndFeel::createComboBoxTextBox (ComboBox&)
- {
- return new Label (String::empty, String::empty);
- }
-
- void LookAndFeel::positionComboBoxText (ComboBox& box, Label& label)
- {
- label.setBounds (1, 1,
- box.getWidth() + 3 - box.getHeight(),
- box.getHeight() - 2);
-
- label.setFont (getComboBoxFont (box));
- }
-
- void LookAndFeel::drawLinearSliderBackground (Graphics& g,
- int x, int y,
- int width, int height,
- float /*sliderPos*/,
- float /*minSliderPos*/,
- float /*maxSliderPos*/,
- const Slider::SliderStyle /*style*/,
- Slider& slider)
- {
- const float sliderRadius = (float) (getSliderThumbRadius (slider) - 2);
-
- const Colour trackColour (slider.findColour (Slider::trackColourId));
- const Colour gradCol1 (trackColour.overlaidWith (Colours::black.withAlpha (slider.isEnabled() ? 0.25f : 0.13f)));
- const Colour gradCol2 (trackColour.overlaidWith (Colour (0x14000000)));
- Path indent;
-
- if (slider.isHorizontal())
- {
- const float iy = y + height * 0.5f - sliderRadius * 0.5f;
- const float ih = sliderRadius;
-
- GradientBrush gb (gradCol1, 0.0f, iy,
- gradCol2, 0.0f, iy + ih, false);
- g.setBrush (&gb);
-
- indent.addRoundedRectangle (x - sliderRadius * 0.5f, iy,
- width + sliderRadius, ih,
- 5.0f);
- g.fillPath (indent);
- }
- else
- {
- const float ix = x + width * 0.5f - sliderRadius * 0.5f;
- const float iw = sliderRadius;
-
- GradientBrush gb (gradCol1, ix, 0.0f,
- gradCol2, ix + iw, 0.0f, false);
- g.setBrush (&gb);
-
- indent.addRoundedRectangle (ix, y - sliderRadius * 0.5f,
- iw, height + sliderRadius,
- 5.0f);
- g.fillPath (indent);
- }
-
- g.setColour (Colour (0x4c000000));
- g.strokePath (indent, PathStrokeType (0.5f));
- }
-
- void LookAndFeel::drawLinearSliderThumb (Graphics& g,
- int x, int y,
- int width, int height,
- float sliderPos,
- float minSliderPos,
- float maxSliderPos,
- const Slider::SliderStyle style,
- Slider& slider)
- {
- const float sliderRadius = (float) (getSliderThumbRadius (slider) - 2);
-
- Colour knobColour (createBaseColour (slider.findColour (Slider::thumbColourId),
- slider.hasKeyboardFocus (false) && slider.isEnabled(),
- slider.isMouseOverOrDragging() && slider.isEnabled(),
- slider.isMouseButtonDown() && slider.isEnabled()));
-
- const float outlineThickness = slider.isEnabled() ? 0.8f : 0.3f;
-
- if (style == Slider::LinearHorizontal || style == Slider::LinearVertical)
- {
- float kx, ky;
-
- if (style == Slider::LinearVertical)
- {
- kx = x + width * 0.5f;
- ky = sliderPos;
- }
- else
- {
- kx = sliderPos;
- ky = y + height * 0.5f;
- }
-
- drawGlassSphere (g,
- kx - sliderRadius,
- ky - sliderRadius,
- sliderRadius * 2.0f,
- knobColour, outlineThickness);
- }
- else
- {
- if (style == Slider::ThreeValueVertical)
- {
- drawGlassSphere (g, x + width * 0.5f - sliderRadius,
- sliderPos - sliderRadius,
- sliderRadius * 2.0f,
- knobColour, outlineThickness);
- }
- else if (style == Slider::ThreeValueHorizontal)
- {
- drawGlassSphere (g,sliderPos - sliderRadius,
- y + height * 0.5f - sliderRadius,
- sliderRadius * 2.0f,
- knobColour, outlineThickness);
- }
-
- if (style == Slider::TwoValueVertical || style == Slider::ThreeValueVertical)
- {
- const float sr = jmin (sliderRadius, width * 0.4f);
-
- drawGlassPointer (g, jmax (0.0f, x + width * 0.5f - sliderRadius * 2.0f),
- minSliderPos - sliderRadius,
- sliderRadius * 2.0f, knobColour, outlineThickness, 1);
-
- drawGlassPointer (g, jmin (x + width - sliderRadius * 2.0f, x + width * 0.5f), maxSliderPos - sr,
- sliderRadius * 2.0f, knobColour, outlineThickness, 3);
- }
- else if (style == Slider::TwoValueHorizontal || style == Slider::ThreeValueHorizontal)
- {
- const float sr = jmin (sliderRadius, height * 0.4f);
-
- drawGlassPointer (g, minSliderPos - sr,
- jmax (0.0f, y + height * 0.5f - sliderRadius * 2.0f),
- sliderRadius * 2.0f, knobColour, outlineThickness, 2);
-
- drawGlassPointer (g, maxSliderPos - sliderRadius,
- jmin (y + height - sliderRadius * 2.0f, y + height * 0.5f),
- sliderRadius * 2.0f, knobColour, outlineThickness, 4);
- }
- }
- }
-
- void LookAndFeel::drawLinearSlider (Graphics& g,
- int x, int y,
- int width, int height,
- float sliderPos,
- float minSliderPos,
- float maxSliderPos,
- const Slider::SliderStyle style,
- Slider& slider)
- {
- g.fillAll (slider.findColour (Slider::backgroundColourId));
-
- if (style == Slider::LinearBar)
- {
- const bool isMouseOver = slider.isMouseOverOrDragging() && slider.isEnabled();
-
- Colour baseColour (createBaseColour (slider.findColour (Slider::thumbColourId)
- .withMultipliedSaturation (slider.isEnabled() ? 1.0f : 0.5f),
- false,
- isMouseOver,
- isMouseOver || slider.isMouseButtonDown()));
-
- drawShinyButtonShape (g,
- (float) x, (float) y, sliderPos - (float) x, (float) height, 0.0f,
- baseColour,
- slider.isEnabled() ? 0.9f : 0.3f,
- true, true, true, true);
- }
- else
- {
- drawLinearSliderBackground (g, x, y, width, height, sliderPos, minSliderPos, maxSliderPos, style, slider);
- drawLinearSliderThumb (g, x, y, width, height, sliderPos, minSliderPos, maxSliderPos, style, slider);
- }
- }
-
- int LookAndFeel::getSliderThumbRadius (Slider& slider)
- {
- return jmin (7,
- slider.getHeight() / 2,
- slider.getWidth() / 2) + 2;
- }
-
- void LookAndFeel::drawRotarySlider (Graphics& g,
- int x, int y,
- int width, int height,
- float sliderPos,
- const float rotaryStartAngle,
- const float rotaryEndAngle,
- Slider& slider)
- {
- const float radius = jmin (width / 2, height / 2) - 2.0f;
- const float centreX = x + width * 0.5f;
- const float centreY = y + height * 0.5f;
- const float rx = centreX - radius;
- const float ry = centreY - radius;
- const float rw = radius * 2.0f;
- const float angle = rotaryStartAngle + sliderPos * (rotaryEndAngle - rotaryStartAngle);
- const bool isMouseOver = slider.isMouseOverOrDragging() && slider.isEnabled();
-
- if (radius > 12.0f)
- {
- if (slider.isEnabled())
- g.setColour (slider.findColour (Slider::rotarySliderFillColourId).withAlpha (isMouseOver ? 1.0f : 0.7f));
- else
- g.setColour (Colour (0x80808080));
-
- const float thickness = 0.7f;
-
- {
- Path filledArc;
- filledArc.addPieSegment (rx, ry, rw, rw,
- rotaryStartAngle,
- angle,
- thickness);
-
- g.fillPath (filledArc);
- }
-
- if (thickness > 0)
- {
- const float innerRadius = radius * 0.2f;
- Path p;
- p.addTriangle (-innerRadius, 0.0f,
- 0.0f, -radius * thickness * 1.1f,
- innerRadius, 0.0f);
-
- p.addEllipse (-innerRadius, -innerRadius, innerRadius * 2.0f, innerRadius * 2.0f);
-
- g.fillPath (p, AffineTransform::rotation (angle).translated (centreX, centreY));
- }
-
- if (slider.isEnabled())
- {
- g.setColour (slider.findColour (Slider::rotarySliderOutlineColourId));
- Path outlineArc;
- outlineArc.addPieSegment (rx, ry, rw, rw, rotaryStartAngle, rotaryEndAngle, thickness);
- outlineArc.closeSubPath();
-
- g.strokePath (outlineArc, PathStrokeType (slider.isEnabled() ? (isMouseOver ? 2.0f : 1.2f) : 0.3f));
- }
- }
- else
- {
- if (slider.isEnabled())
- g.setColour (slider.findColour (Slider::rotarySliderFillColourId).withAlpha (isMouseOver ? 1.0f : 0.7f));
- else
- g.setColour (Colour (0x80808080));
-
- Path p;
- p.addEllipse (-0.4f * rw, -0.4f * rw, rw * 0.8f, rw * 0.8f);
- PathStrokeType (rw * 0.1f).createStrokedPath (p, p);
-
- p.addLineSegment (0.0f, 0.0f, 0.0f, -radius, rw * 0.2f);
-
- g.fillPath (p, AffineTransform::rotation (angle).translated (centreX, centreY));
- }
- }
-
- Button* LookAndFeel::createSliderButton (const bool isIncrement)
- {
- return new TextButton (isIncrement ? "+" : "-", String::empty);
- }
-
- Label* LookAndFeel::createSliderTextBox (Slider& slider)
- {
- Label* const l = new Label (T("n"), String::empty);
-
- l->setJustificationType (Justification::centred);
-
- l->setColour (Label::textColourId, slider.findColour (Slider::textBoxTextColourId));
-
- l->setColour (Label::backgroundColourId,
- (slider.getSliderStyle() == Slider::LinearBar) ? Colours::transparentBlack
- : slider.findColour (Slider::textBoxBackgroundColourId));
- l->setColour (Label::outlineColourId, slider.findColour (Slider::textBoxOutlineColourId));
-
- l->setColour (TextEditor::textColourId, slider.findColour (Slider::textBoxTextColourId));
-
- l->setColour (TextEditor::backgroundColourId,
- slider.findColour (Slider::textBoxBackgroundColourId)
- .withAlpha (slider.getSliderStyle() == Slider::LinearBar ? 0.7f : 1.0f));
-
- l->setColour (TextEditor::outlineColourId, slider.findColour (Slider::textBoxOutlineColourId));
-
- return l;
- }
-
- ImageEffectFilter* LookAndFeel::getSliderEffect()
- {
- return 0;
- }
-
- static const TextLayout layoutTooltipText (const String& text) throw()
- {
- const float tooltipFontSize = 15.0f;
- const int maxToolTipWidth = 400;
-
- const Font f (tooltipFontSize, Font::bold);
- TextLayout tl (text, f);
- tl.layout (maxToolTipWidth, Justification::left, true);
-
- return tl;
- }
-
- void LookAndFeel::getTooltipSize (const String& tipText, int& width, int& height)
- {
- const TextLayout tl (layoutTooltipText (tipText));
-
- width = tl.getWidth() + 14;
- height = tl.getHeight() + 10;
- }
-
- void LookAndFeel::drawTooltip (Graphics& g, const String& text, int width, int height)
- {
- g.fillAll (findColour (TooltipWindow::backgroundColourId));
-
- const Colour textCol (findColour (TooltipWindow::textColourId));
-
- g.setColour (findColour (TooltipWindow::outlineColourId));
- g.drawRect (0, 0, width, height);
-
- const TextLayout tl (layoutTooltipText (text));
-
- g.setColour (findColour (TooltipWindow::textColourId));
- tl.drawWithin (g, 0, 0, width, height, Justification::centred);
- }
-
- Button* LookAndFeel::createFilenameComponentBrowseButton (const String& text)
- {
- return new TextButton (text, TRANS("click to browse for a different file"));
- }
-
- void LookAndFeel::layoutFilenameComponent (FilenameComponent& filenameComp,
- ComboBox* filenameBox,
- Button* browseButton)
- {
- browseButton->setSize (80, filenameComp.getHeight());
-
- TextButton* const tb = dynamic_cast <TextButton*> (browseButton);
-
- if (tb != 0)
- tb->changeWidthToFitText();
-
- browseButton->setTopRightPosition (filenameComp.getWidth(), 0);
-
- filenameBox->setBounds (0, 0, browseButton->getX(), filenameComp.getHeight());
- }
-
- void LookAndFeel::drawCornerResizer (Graphics& g,
- int w, int h,
- bool /*isMouseOver*/,
- bool /*isMouseDragging*/)
- {
- const float lineThickness = jmin (w, h) * 0.075f;
-
- for (float i = 0.0f; i < 1.0f; i += 0.3f)
- {
- g.setColour (Colours::lightgrey);
-
- g.drawLine (w * i,
- h + 1.0f,
- w + 1.0f,
- h * i,
- lineThickness);
-
- g.setColour (Colours::darkgrey);
-
- g.drawLine (w * i + lineThickness,
- h + 1.0f,
- w + 1.0f,
- h * i + lineThickness,
- lineThickness);
- }
- }
-
- void LookAndFeel::drawResizableFrame (Graphics&, int /*w*/, int /*h*/,
- const BorderSize& /*borders*/)
- {
- }
-
- void LookAndFeel::drawResizableWindowBorder (Graphics& g, int w, int h,
- const BorderSize& border, ResizableWindow&)
- {
- g.setColour (Colour (0x80000000));
- g.drawRect (0, 0, w, h);
-
- g.setColour (Colour (0x19000000));
- g.drawRect (border.getLeft() - 1,
- border.getTop() - 1,
- w + 2 - border.getLeftAndRight(),
- h + 2 - border.getTopAndBottom());
- }
-
- void LookAndFeel::drawDocumentWindowTitleBar (DocumentWindow& window,
- Graphics& g, int w, int h,
- int titleSpaceX, int titleSpaceW,
- const Image* icon,
- bool drawTitleTextOnLeft)
- {
- const bool isActive = window.isActiveWindow();
-
- GradientBrush gb (window.getBackgroundColour(),
- 0.0f, 0.0f,
- window.getBackgroundColour().contrasting (isActive ? 0.15f : 0.05f),
- 0.0f, (float) h, false);
- g.setBrush (&gb);
- g.fillAll();
-
- g.setFont (h * 0.65f, Font::bold);
-
- int textW = g.getCurrentFont().getStringWidth (window.getName());
- int iconW = 0;
- int iconH = 0;
-
- if (icon != 0)
- {
- iconH = (int) g.getCurrentFont().getHeight();
- iconW = icon->getWidth() * iconH / icon->getHeight() + 4;
- }
-
- textW = jmin (titleSpaceW, textW + iconW);
- int textX = drawTitleTextOnLeft ? titleSpaceX
- : jmax (titleSpaceX, (w - textW) / 2);
-
- if (textX + textW > titleSpaceX + titleSpaceW)
- textX = titleSpaceX + titleSpaceW - textW;
-
- if (icon != 0)
- {
- g.setOpacity (isActive ? 1.0f : 0.6f);
- g.drawImageWithin (icon, textX, (h - iconH) / 2, iconW, iconH,
- RectanglePlacement::centred, false);
- textX += iconW;
- textW -= iconW;
- }
-
- g.setColour (window.getBackgroundColour().contrasting (isActive ? 0.7f : 0.4f));
- g.drawText (window.getName(), textX, 0, textW, h, Justification::centredLeft, true);
- }
-
- class GlassWindowButton : public Button
- {
- public:
-
- GlassWindowButton (const String& name, const Colour& col,
- const Path& normalShape_,
- const Path& toggledShape_) throw()
- : Button (name),
- colour (col),
- normalShape (normalShape_),
- toggledShape (toggledShape_)
- {
- }
-
- ~GlassWindowButton()
- {
- }
-
- void paintButton (Graphics& g, bool isMouseOverButton, bool isButtonDown)
- {
- float alpha = isMouseOverButton ? (isButtonDown ? 1.0f : 0.8f) : 0.55f;
-
- if (! isEnabled())
- alpha *= 0.5f;
-
- float x = 0, y = 0, diam;
-
- if (getWidth() < getHeight())
- {
- diam = (float) getWidth();
- y = (getHeight() - getWidth()) * 0.5f;
- }
- else
- {
- diam = (float) getHeight();
- y = (getWidth() - getHeight()) * 0.5f;
- }
-
- x += diam * 0.05f;
- y += diam * 0.05f;
- diam *= 0.9f;
-
- GradientBrush gb1 (Colour::greyLevel (0.9f).withAlpha (alpha), 0, y + diam,
- Colour::greyLevel (0.6f).withAlpha (alpha), 0, y, false);
-
- g.setBrush (&gb1);
- g.fillEllipse (x, y, diam, diam);
-
- x += 2.0f;
- y += 2.0f;
- diam -= 4.0f;
-
- LookAndFeel::drawGlassSphere (g, x, y, diam, colour.withAlpha (alpha), 1.0f);
-
- Path& p = getToggleState() ? toggledShape : normalShape;
-
- const AffineTransform t (p.getTransformToScaleToFit (x + diam * 0.3f, y + diam * 0.3f,
- diam * 0.4f, diam * 0.4f, true));
-
- g.setColour (Colours::black.withAlpha (alpha * 0.6f));
- g.fillPath (p, t);
- }
-
- juce_UseDebuggingNewOperator
-
- private:
- Colour colour;
- Path normalShape, toggledShape;
-
- GlassWindowButton (const GlassWindowButton&);
- const GlassWindowButton& operator= (const GlassWindowButton&);
- };
-
- Button* LookAndFeel::createDocumentWindowButton (int buttonType)
- {
- Path shape;
- const float crossThickness = 0.25f;
-
- if (buttonType == DocumentWindow::closeButton)
- {
- shape.addLineSegment (0.0f, 0.0f, 1.0f, 1.0f, crossThickness * 1.4f);
- shape.addLineSegment (1.0f, 0.0f, 0.0f, 1.0f, crossThickness * 1.4f);
-
- return new GlassWindowButton ("close", Colour (0xffdd1100), shape, shape);
- }
- else if (buttonType == DocumentWindow::minimiseButton)
- {
- shape.addLineSegment (0.0f, 0.5f, 1.0f, 0.5f, crossThickness);
-
- return new GlassWindowButton ("minimise", Colour (0xffaa8811), shape, shape);
- }
- else if (buttonType == DocumentWindow::maximiseButton)
- {
- shape.addLineSegment (0.5f, 0.0f, 0.5f, 1.0f, crossThickness);
- shape.addLineSegment (0.0f, 0.5f, 1.0f, 0.5f, crossThickness);
-
- Path fullscreenShape;
- fullscreenShape.startNewSubPath (45.0f, 100.0f);
- fullscreenShape.lineTo (0.0f, 100.0f);
- fullscreenShape.lineTo (0.0f, 0.0f);
- fullscreenShape.lineTo (100.0f, 0.0f);
- fullscreenShape.lineTo (100.0f, 45.0f);
- fullscreenShape.addRectangle (45.0f, 45.0f, 100.0f, 100.0f);
- PathStrokeType (30.0f).createStrokedPath (fullscreenShape, fullscreenShape);
-
- return new GlassWindowButton ("maximise", Colour (0xff119911), shape, fullscreenShape);
- }
-
- jassertfalse
- return 0;
- }
-
- void LookAndFeel::positionDocumentWindowButtons (DocumentWindow&,
- int titleBarX,
- int titleBarY,
- int titleBarW,
- int titleBarH,
- Button* minimiseButton,
- Button* maximiseButton,
- Button* closeButton,
- bool positionTitleBarButtonsOnLeft)
- {
- const int buttonW = titleBarH - titleBarH / 8;
-
- int x = positionTitleBarButtonsOnLeft ? titleBarX + 4
- : titleBarX + titleBarW - buttonW - buttonW / 4;
-
- if (closeButton != 0)
- {
- closeButton->setBounds (x, titleBarY, buttonW, titleBarH);
- x += positionTitleBarButtonsOnLeft ? buttonW : -(buttonW + buttonW / 4);
- }
-
- if (positionTitleBarButtonsOnLeft)
- swapVariables (minimiseButton, maximiseButton);
-
- if (maximiseButton != 0)
- {
- maximiseButton->setBounds (x, titleBarY, buttonW, titleBarH);
- x += positionTitleBarButtonsOnLeft ? buttonW : -buttonW;
- }
-
- if (minimiseButton != 0)
- minimiseButton->setBounds (x, titleBarY, buttonW, titleBarH);
- }
-
- int LookAndFeel::getDefaultMenuBarHeight()
- {
- return 24;
- }
-
- DropShadower* LookAndFeel::createDropShadowerForComponent (Component*)
- {
- return new DropShadower (0.4f, 1, 5, 10);
- }
-
- void LookAndFeel::drawStretchableLayoutResizerBar (Graphics& g,
- int w, int h,
- bool /*isVerticalBar*/,
- bool isMouseOver,
- bool isMouseDragging)
- {
- float alpha = 0.5f;
-
- if (isMouseOver || isMouseDragging)
- {
- g.fillAll (Colour (0x190000ff));
- alpha = 1.0f;
- }
-
- const float cx = w * 0.5f;
- const float cy = h * 0.5f;
- const float cr = jmin (w, h) * 0.4f;
-
- GradientBrush gb (Colours::white.withAlpha (alpha), cx + cr * 0.1f, cy + cr,
- Colours::black.withAlpha (alpha), cx, cy - cr * 4.0f,
- true);
-
- g.setBrush (&gb);
- g.fillEllipse (cx - cr, cy - cr, cr * 2.0f, cr * 2.0f);
- }
-
- void LookAndFeel::drawGroupComponentOutline (Graphics& g, int width, int height,
- const String& text,
- const Justification& position,
- GroupComponent& group)
- {
- const float textH = 15.0f;
- const float indent = 3.0f;
- const float textEdgeGap = 4.0f;
- float cs = 5.0f;
-
- Font f (textH);
-
- Path p;
- float x = indent;
- float y = f.getAscent() - 3.0f;
- float w = jmax (0.0f, width - x * 2.0f);
- float h = jmax (0.0f, height - y - indent);
- cs = jmin (cs, w * 0.5f, h * 0.5f);
- const float cs2 = 2.0f * cs;
-
- float textW = text.isEmpty() ? 0 : jlimit (0.0f, jmax (0.0f, w - cs2 - textEdgeGap * 2), f.getStringWidth (text) + textEdgeGap * 2.0f);
- float textX = cs + textEdgeGap;
-
- if (position.testFlags (Justification::horizontallyCentred))
- textX = cs + (w - cs2 - textW) * 0.5f;
- else if (position.testFlags (Justification::right))
- textX = w - cs - textW - textEdgeGap;
-
- p.startNewSubPath (x + textX + textW, y);
- p.lineTo (x + w - cs, y);
-
- p.addArc (x + w - cs2, y, cs2, cs2, 0, float_Pi * 0.5f);
- p.lineTo (x + w, y + h - cs);
-
- p.addArc (x + w - cs2, y + h - cs2, cs2, cs2, float_Pi * 0.5f, float_Pi);
- p.lineTo (x + cs, y + h);
-
- p.addArc (x, y + h - cs2, cs2, cs2, float_Pi, float_Pi * 1.5f);
- p.lineTo (x, y + cs);
-
- p.addArc (x, y, cs2, cs2, float_Pi * 1.5f, float_Pi * 2.0f);
- p.lineTo (x + textX, y);
-
- const float alpha = group.isEnabled() ? 1.0f : 0.5f;
-
- g.setColour (group.findColour (GroupComponent::outlineColourId)
- .withMultipliedAlpha (alpha));
-
- g.strokePath (p, PathStrokeType (2.0f));
-
- g.setColour (group.findColour (GroupComponent::textColourId)
- .withMultipliedAlpha (alpha));
- g.setFont (f);
- g.drawText (text,
- roundFloatToInt (x + textX), 0,
- roundFloatToInt (textW),
- roundFloatToInt (textH),
- Justification::centred, true);
- }
-
- int LookAndFeel::getTabButtonOverlap (int tabDepth)
- {
- return 1 + tabDepth / 3;
- }
-
- int LookAndFeel::getTabButtonSpaceAroundImage()
- {
- return 4;
- }
-
- void LookAndFeel::createTabButtonShape (Path& p,
- int width, int height,
- int /*tabIndex*/,
- const String& /*text*/,
- Button& /*button*/,
- TabbedButtonBar::Orientation orientation,
- const bool /*isMouseOver*/,
- const bool /*isMouseDown*/,
- const bool /*isFrontTab*/)
- {
- const float w = (float) width;
- const float h = (float) height;
-
- float length = w;
- float depth = h;
-
- if (orientation == TabbedButtonBar::TabsAtLeft
- || orientation == TabbedButtonBar::TabsAtRight)
- {
- swapVariables (length, depth);
- }
-
- const float indent = (float) getTabButtonOverlap ((int) depth);
- const float overhang = 4.0f;
-
- if (orientation == TabbedButtonBar::TabsAtLeft)
- {
- p.startNewSubPath (w, 0.0f);
- p.lineTo (0.0f, indent);
- p.lineTo (0.0f, h - indent);
- p.lineTo (w, h);
- p.lineTo (w + overhang, h + overhang);
- p.lineTo (w + overhang, -overhang);
- }
- else if (orientation == TabbedButtonBar::TabsAtRight)
- {
- p.startNewSubPath (0.0f, 0.0f);
- p.lineTo (w, indent);
- p.lineTo (w, h - indent);
- p.lineTo (0.0f, h);
- p.lineTo (-overhang, h + overhang);
- p.lineTo (-overhang, -overhang);
- }
- else if (orientation == TabbedButtonBar::TabsAtBottom)
- {
- p.startNewSubPath (0.0f, 0.0f);
- p.lineTo (indent, h);
- p.lineTo (w - indent, h);
- p.lineTo (w, 0.0f);
- p.lineTo (w + overhang, -overhang);
- p.lineTo (-overhang, -overhang);
- }
- else
- {
- p.startNewSubPath (0.0f, h);
- p.lineTo (indent, 0.0f);
- p.lineTo (w - indent, 0.0f);
- p.lineTo (w, h);
- p.lineTo (w + overhang, h + overhang);
- p.lineTo (-overhang, h + overhang);
- }
-
- p.closeSubPath();
-
- p = p.createPathWithRoundedCorners (3.0f);
- }
-
- void LookAndFeel::fillTabButtonShape (Graphics& g,
- const Path& path,
- const Colour& preferredColour,
- int /*tabIndex*/,
- const String& /*text*/,
- Button& button,
- TabbedButtonBar::Orientation /*orientation*/,
- const bool /*isMouseOver*/,
- const bool /*isMouseDown*/,
- const bool isFrontTab)
- {
- g.setColour (isFrontTab ? preferredColour
- : preferredColour.withMultipliedAlpha (0.9f));
-
- g.fillPath (path);
-
- g.setColour (Colours::black.withAlpha (button.isEnabled() ? 0.5f : 0.25f));
- g.strokePath (path, PathStrokeType (isFrontTab ? 1.0f : 0.5f));
- }
-
- void LookAndFeel::drawTabButtonText (Graphics& g,
- int x, int y, int w, int h,
- const Colour& preferredBackgroundColour,
- int /*tabIndex*/,
- const String& text,
- Button& button,
- TabbedButtonBar::Orientation orientation,
- const bool isMouseOver,
- const bool isMouseDown,
- const bool /*isFrontTab*/)
- {
- int length = w;
- int depth = h;
-
- if (orientation == TabbedButtonBar::TabsAtLeft
- || orientation == TabbedButtonBar::TabsAtRight)
- {
- swapVariables (length, depth);
- }
-
- Font font (depth * 0.6f);
- font.setUnderline (button.hasKeyboardFocus (false));
-
- GlyphArrangement textLayout;
- textLayout.addFittedText (font, text.trim(),
- 0.0f, 0.0f, (float) length, (float) depth,
- Justification::centred,
- jmax (1, depth / 12));
-
- AffineTransform transform;
-
- if (orientation == TabbedButtonBar::TabsAtLeft)
- {
- transform = transform.rotated (float_Pi * -0.5f)
- .translated ((float) x, (float) (y + h));
- }
- else if (orientation == TabbedButtonBar::TabsAtRight)
- {
- transform = transform.rotated (float_Pi * 0.5f)
- .translated ((float) (x + w), (float) y);
- }
- else
- {
- transform = transform.translated ((float) x, (float) y);
- }
-
- g.setColour (preferredBackgroundColour.contrasting());
-
- if (! (isMouseOver || isMouseDown))
- g.setOpacity (0.8f);
-
- if (! button.isEnabled())
- g.setOpacity (0.3f);
-
- textLayout.draw (g, transform);
- }
-
- int LookAndFeel::getTabButtonBestWidth (int /*tabIndex*/,
- const String& text,
- int tabDepth,
- Button&)
- {
- Font f (tabDepth * 0.6f);
- return f.getStringWidth (text.trim()) + getTabButtonOverlap (tabDepth) * 2;
- }
-
- void LookAndFeel::drawTabButton (Graphics& g,
- int w, int h,
- const Colour& preferredColour,
- int tabIndex,
- const String& text,
- Button& button,
- TabbedButtonBar::Orientation orientation,
- const bool isMouseOver,
- const bool isMouseDown,
- const bool isFrontTab)
- {
- int length = w;
- int depth = h;
-
- if (orientation == TabbedButtonBar::TabsAtLeft
- || orientation == TabbedButtonBar::TabsAtRight)
- {
- swapVariables (length, depth);
- }
-
- Path tabShape;
-
- createTabButtonShape (tabShape, w, h,
- tabIndex, text, button, orientation,
- isMouseOver, isMouseDown, isFrontTab);
-
- fillTabButtonShape (g, tabShape, preferredColour,
- tabIndex, text, button, orientation,
- isMouseOver, isMouseDown, isFrontTab);
-
- const int indent = getTabButtonOverlap (depth);
- int x = 0, y = 0;
-
- if (orientation == TabbedButtonBar::TabsAtLeft
- || orientation == TabbedButtonBar::TabsAtRight)
- {
- y += indent;
- h -= indent * 2;
- }
- else
- {
- x += indent;
- w -= indent * 2;
- }
-
- drawTabButtonText (g, x, y, w, h, preferredColour,
- tabIndex, text, button, orientation,
- isMouseOver, isMouseDown, isFrontTab);
- }
-
- void LookAndFeel::drawTabAreaBehindFrontButton (Graphics& g,
- int w, int h,
- TabbedButtonBar& tabBar,
- TabbedButtonBar::Orientation orientation)
- {
- const float shadowSize = 0.2f;
-
- float x1 = 0.0f, y1 = 0.0f, x2 = 0.0f, y2 = 0.0f;
- Rectangle shadowRect;
-
- if (orientation == TabbedButtonBar::TabsAtLeft)
- {
- x1 = (float) w;
- x2 = w * (1.0f - shadowSize);
- shadowRect.setBounds ((int) x2, 0, w - (int) x2, h);
- }
- else if (orientation == TabbedButtonBar::TabsAtRight)
- {
- x2 = w * shadowSize;
- shadowRect.setBounds (0, 0, (int) x2, h);
- }
- else if (orientation == TabbedButtonBar::TabsAtBottom)
- {
- y2 = h * shadowSize;
- shadowRect.setBounds (0, 0, w, (int) y2);
- }
- else
- {
- y1 = (float) h;
- y2 = h * (1.0f - shadowSize);
- shadowRect.setBounds (0, (int) y2, w, h - (int) y2);
- }
-
- GradientBrush gb (Colours::black.withAlpha (tabBar.isEnabled() ? 0.3f : 0.15f), x1, y1,
- Colours::transparentBlack, x2, y2,
- false);
-
- g.setBrush (&gb);
- shadowRect.expand (2, 2);
- g.fillRect (shadowRect);
-
- g.setColour (Colour (0x80000000));
-
- if (orientation == TabbedButtonBar::TabsAtLeft)
- {
- g.fillRect (w - 1, 0, 1, h);
- }
- else if (orientation == TabbedButtonBar::TabsAtRight)
- {
- g.fillRect (0, 0, 1, h);
- }
- else if (orientation == TabbedButtonBar::TabsAtBottom)
- {
- g.fillRect (0, 0, w, 1);
- }
- else
- {
- g.fillRect (0, h - 1, w, 1);
- }
- }
-
- Button* LookAndFeel::createTabBarExtrasButton()
- {
- const float thickness = 7.0f;
- const float indent = 22.0f;
-
- Path p;
- p.addEllipse (-10.0f, -10.0f, 120.0f, 120.0f);
-
- DrawablePath ellipse;
- ellipse.setPath (p);
- ellipse.setSolidFill (Colour (0x99ffffff));
-
- p.clear();
- p.addEllipse (0.0f, 0.0f, 100.0f, 100.0f);
- p.addRectangle (indent, 50.0f - thickness, 100.0f - indent * 2.0f, thickness * 2.0f);
- p.addRectangle (50.0f - thickness, indent, thickness * 2.0f, 50.0f - indent - thickness);
- p.addRectangle (50.0f - thickness, 50.0f + thickness, thickness * 2.0f, 50.0f - indent - thickness);
- p.setUsingNonZeroWinding (false);
-
- DrawablePath dp;
- dp.setPath (p);
- dp.setSolidFill (Colour (0x59000000));
-
- DrawableComposite normalImage;
- normalImage.insertDrawable (ellipse);
- normalImage.insertDrawable (dp);
-
- dp.setSolidFill (Colour (0xcc000000));
-
- DrawableComposite overImage;
- overImage.insertDrawable (ellipse);
- overImage.insertDrawable (dp);
-
- DrawableButton* db = new DrawableButton (T("tabs"), DrawableButton::ImageFitted);
- db->setImages (&normalImage, &overImage, 0);
- return db;
- }
-
- void LookAndFeel::drawTableHeaderBackground (Graphics& g, TableHeaderComponent& header)
- {
- g.fillAll (Colours::white);
-
- const int w = header.getWidth();
- const int h = header.getHeight();
-
- GradientBrush gb (Colour (0xffe8ebf9), 0.0f, h * 0.5f,
- Colour (0xfff6f8f9), 0.0f, h - 1.0f,
- false);
-
- g.setBrush (&gb);
- g.fillRect (0, h / 2, w, h);
-
- g.setColour (Colour (0x33000000));
- g.fillRect (0, h - 1, w, 1);
-
- for (int i = header.getNumColumns (true); --i >= 0;)
- g.fillRect (header.getColumnPosition (i).getRight() - 1, 0, 1, h - 1);
- }
-
- void LookAndFeel::drawTableHeaderColumn (Graphics& g, const String& columnName, int /*columnId*/,
- int width, int height,
- bool isMouseOver, bool isMouseDown,
- int columnFlags)
- {
- if (isMouseDown)
- g.fillAll (Colour (0x8899aadd));
- else if (isMouseOver)
- g.fillAll (Colour (0x5599aadd));
-
- int rightOfText = width - 4;
-
- if ((columnFlags & (TableHeaderComponent::sortedForwards | TableHeaderComponent::sortedBackwards)) != 0)
- {
- const float top = height * ((columnFlags & TableHeaderComponent::sortedForwards) != 0 ? 0.35f : (1.0f - 0.35f));
- const float bottom = height - top;
-
- const float w = height * 0.5f;
- const float x = rightOfText - (w * 1.25f);
- rightOfText = (int) x;
-
- Path sortArrow;
- sortArrow.addTriangle (x, bottom, x + w * 0.5f, top, x + w, bottom);
-
- g.setColour (Colour (0x99000000));
- g.fillPath (sortArrow);
- }
-
- g.setColour (Colours::black);
- g.setFont (height * 0.5f, Font::bold);
- const int textX = 4;
- g.drawFittedText (columnName, textX, 0, rightOfText - textX, height, Justification::centredLeft, 1);
- }
-
- void LookAndFeel::paintToolbarBackground (Graphics& g, int w, int h, Toolbar& toolbar)
- {
- const Colour background (toolbar.findColour (Toolbar::backgroundColourId));
-
- GradientBrush gb (background, 0.0f, 0.0f,
- background.darker (0.1f),
- toolbar.isVertical() ? w - 1.0f : 0.0f,
- toolbar.isVertical() ? 0.0f : h - 1.0f,
- false);
-
- g.setBrush (&gb);
- g.fillAll();
- }
-
- Button* LookAndFeel::createToolbarMissingItemsButton (Toolbar& /*toolbar*/)
- {
- return createTabBarExtrasButton();
- }
-
- void LookAndFeel::paintToolbarButtonBackground (Graphics& g, int /*width*/, int /*height*/,
- bool isMouseOver, bool isMouseDown,
- ToolbarItemComponent& component)
- {
- if (isMouseDown)
- g.fillAll (component.findColour (Toolbar::buttonMouseDownBackgroundColourId, true));
- else if (isMouseOver)
- g.fillAll (component.findColour (Toolbar::buttonMouseOverBackgroundColourId, true));
- }
-
- void LookAndFeel::paintToolbarButtonLabel (Graphics& g, int x, int y, int width, int height,
- const String& text, ToolbarItemComponent& component)
- {
- g.setColour (component.findColour (Toolbar::labelTextColourId, true)
- .withAlpha (component.isEnabled() ? 1.0f : 0.25f));
-
- const float fontHeight = jmin (14.0f, height * 0.85f);
- g.setFont (fontHeight);
-
- g.drawFittedText (text,
- x, y, width, height,
- Justification::centred,
- jmax (1, height / (int) fontHeight));
- }
-
- void LookAndFeel::drawPropertyPanelSectionHeader (Graphics& g, const String& name,
- bool isOpen, int width, int height)
- {
- const int buttonSize = (height * 3) / 4;
- const int buttonIndent = (height - buttonSize) / 2;
-
- drawTreeviewPlusMinusBox (g, buttonIndent, buttonIndent, buttonSize, buttonSize, ! isOpen);
-
- const int textX = buttonIndent * 2 + buttonSize + 2;
-
- g.setColour (Colours::black);
- g.setFont (height * 0.7f, Font::bold);
- g.drawText (name, textX, 0, width - textX - 4, height, Justification::centredLeft, true);
- }
-
- void LookAndFeel::drawPropertyComponentBackground (Graphics& g, int width, int height,
- PropertyComponent&)
- {
- g.setColour (Colour (0x66ffffff));
- g.fillRect (0, 0, width, height - 1);
- }
-
- void LookAndFeel::drawPropertyComponentLabel (Graphics& g, int, int height,
- PropertyComponent& component)
- {
- g.setColour (Colours::black);
-
- if (! component.isEnabled())
- g.setOpacity (g.getCurrentColour().getAlpha() * 0.6f);
-
- g.setFont (jmin (height, 24) * 0.65f);
-
- const Rectangle r (getPropertyComponentContentPosition (component));
-
- g.drawFittedText (component.getName(),
- 3, r.getY(), r.getX() - 5, r.getHeight(),
- Justification::centredLeft, 2);
- }
-
- const Rectangle LookAndFeel::getPropertyComponentContentPosition (PropertyComponent& component)
- {
- return Rectangle (component.getWidth() / 3, 1,
- component.getWidth() - component.getWidth() / 3 - 1, component.getHeight() - 3);
- }
-
- void LookAndFeel::createFileChooserHeaderText (const String& title,
- const String& instructions,
- GlyphArrangement& text,
- int width)
- {
- text.clear();
-
- text.addJustifiedText (Font (17.0f, Font::bold), title,
- 8.0f, 22.0f, width - 16.0f,
- Justification::centred);
-
- text.addJustifiedText (Font (14.0f), instructions,
- 8.0f, 24.0f + 16.0f, width - 16.0f,
- Justification::centred);
- }
-
- void LookAndFeel::drawFileBrowserRow (Graphics& g, int width, int height,
- const String& filename, Image* icon,
- const String& fileSizeDescription,
- const String& fileTimeDescription,
- const bool isDirectory,
- const bool isItemSelected,
- const int /*itemIndex*/)
- {
- if (isItemSelected)
- g.fillAll (findColour (DirectoryContentsDisplayComponent::highlightColourId));
-
- g.setColour (findColour (DirectoryContentsDisplayComponent::textColourId));
- g.setFont (height * 0.7f);
-
- Image* im = icon;
- Image* toRelease = 0;
-
- if (im == 0)
- {
- toRelease = im = (isDirectory ? getDefaultFolderImage()
- : getDefaultDocumentFileImage());
- }
-
- const int x = 32;
-
- if (im != 0)
- {
- g.drawImageWithin (im, 2, 2, x - 4, height - 4,
- RectanglePlacement::centred | RectanglePlacement::onlyReduceInSize,
- false);
-
- ImageCache::release (toRelease);
- }
-
- if (width > 450 && ! isDirectory)
- {
- const int sizeX = roundFloatToInt (width * 0.7f);
- const int dateX = roundFloatToInt (width * 0.8f);
-
- g.drawFittedText (filename,
- x, 0, sizeX - x, height,
- Justification::centredLeft, 1);
-
- g.setFont (height * 0.5f);
- g.setColour (Colours::darkgrey);
-
- if (! isDirectory)
- {
- g.drawFittedText (fileSizeDescription,
- sizeX, 0, dateX - sizeX - 8, height,
- Justification::centredRight, 1);
-
- g.drawFittedText (fileTimeDescription,
- dateX, 0, width - 8 - dateX, height,
- Justification::centredRight, 1);
- }
- }
- else
- {
- g.drawFittedText (filename,
- x, 0, width - x, height,
- Justification::centredLeft, 1);
-
- }
- }
-
- Button* LookAndFeel::createFileBrowserGoUpButton()
- {
- DrawableButton* goUpButton = new DrawableButton ("up", DrawableButton::ImageOnButtonBackground);
-
- Path arrowPath;
- arrowPath.addArrow (50.0f, 100.0f, 50.0f, 0.0, 40.0f, 100.0f, 50.0f);
-
- DrawablePath arrowImage;
- arrowImage.setSolidFill (Colours::black.withAlpha (0.4f));
- arrowImage.setPath (arrowPath);
-
- goUpButton->setImages (&arrowImage);
-
- return goUpButton;
- }
-
- void LookAndFeel::layoutFileBrowserComponent (FileBrowserComponent& browserComp,
- DirectoryContentsDisplayComponent* fileListComponent,
- FilePreviewComponent* previewComp,
- ComboBox* currentPathBox,
- TextEditor* filenameBox,
- Button* goUpButton)
- {
- const int x = 8;
- int w = browserComp.getWidth() - x - x;
-
- if (previewComp != 0)
- {
- const int previewWidth = w / 3;
- previewComp->setBounds (x + w - previewWidth, 0, previewWidth, browserComp.getHeight());
-
- w -= previewWidth + 4;
- }
-
- int y = 4;
-
- const int controlsHeight = 22;
- const int bottomSectionHeight = controlsHeight + 8;
- const int upButtonWidth = 50;
-
- currentPathBox->setBounds (x, y, w - upButtonWidth - 6, controlsHeight);
- goUpButton->setBounds (x + w - upButtonWidth, y, upButtonWidth, controlsHeight);
-
- y += controlsHeight + 4;
-
- Component* const listAsComp = dynamic_cast <Component*> (fileListComponent);
- listAsComp->setBounds (x, y, w, browserComp.getHeight() - y - bottomSectionHeight);
-
- y = listAsComp->getBottom() + 4;
- filenameBox->setBounds (x + 50, y, w - 50, controlsHeight);
- }
-
- Image* LookAndFeel::getDefaultFolderImage()
- {
- static const unsigned char foldericon_png[] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,32,0,0,0,28,8,6,0,0,0,0,194,189,34,0,0,0,4,103,65,77,65,0,0,175,200,55,5,
- 138,233,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101,0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101,60,0,0,9,46,73,68,65,84,120,218,98,252,255,255,63,3,50,240,41,95,192,
- 197,205,198,32,202,204,202,33,241,254,235,47,133,47,191,24,180,213,164,133,152,69,24,222,44,234,42,77,188,245,31,170,129,145,145,145,1,29,128,164,226,91,86,113,252,248,207,200,171,37,39,204,239,170,43,
- 254,206,218,88,231,61,62,61,0,1,196,2,149,96,116,200,158,102,194,202,201,227,197,193,206,166,194,204,193,33,195,202,204,38,42,197,197,42,196,193,202,33,240,241,231,15,134,151,95,127,9,2,149,22,0,241,47,
- 152,230,128,134,245,204,63,191,188,103,83,144,16,16,228,229,102,151,76,239,217,32,199,204,198,169,205,254,159,65,245,203,79,6,169,131,151,30,47,1,42,91,10,196,127,208,236,101,76,235,90,43,101,160,40,242,
- 19,32,128,64,78,98,52,12,41,149,145,215,52,89,162,38,35,107,39,196,203,203,192,206,194,206,192,197,198,202,192,203,197,198,192,205,193,206,240,252,227,103,134,139,55,175,191,127,243,242,78,219,187,207,
- 63,215,255,98,23,48,228,227,96,83,98,102,102,85,225,224,228,80,20,224,230,86,226,225,228,150,103,101,97,101,230,227,228,96,224,0,234,191,243,252,5,195,222,19,199,38,191,127,112,161,83,66,199,86,141,131,
- 149,69,146,133,153,69,137,149,133,89,157,141,131,77,83,140,143,243,219,255,31,159,123,0,2,136,69,90,207,129,157,71,68,42,66,71,73,209,210,81,91,27,24,142,140,12,127,255,253,103,0,185,236,31,3,144,6,50,
- 148,68,216,25,216,24,117,4,239,11,243,214,49,50,51,84,178,48,114,240,112,177,114,177,240,115,113,49,241,112,112,48,176,179,178,51,176,48,49,3,85,255,99,248,253,247,15,195,247,159,191,25,30,191,126,253,
- 71,74,76,200,66,75,197,119,138,168,144,160,150,168,0,183,160,152,32,15,175,188,184,32,199,175,191,127,25,214,31,184,120,247,236,209,253,159,0,2,136,133,95,70,93,74,88,80,196,83,69,66,130,149,9,104,219,
- 151,31,191,193,150,194,146,6,136,102,102,98,100,16,227,231,103,16,23,210,230,101,101,102,100,248,255,143,137,225,223,63,6,6,22,102,38,134,239,191,126,49,220,123,241,134,225,227,247,175,64,7,252,101,96,
- 97,249,207,192,193,198,200,160,171,34,192,108,165,235,104,42,204,207,101,42,194,199,197,192,199,201,198,192,197,193,202,192,198,202,194,176,247,194,3,134,155,183,110,61,188,127,124,221,19,128,0,92,146,
- 49,14,64,64,16,69,63,153,85,16,52,18,74,71,112,6,87,119,0,165,160,86,138,32,172,216,29,49,182,84,253,169,94,94,230,127,17,87,133,34,146,174,3,88,126,240,219,164,147,113,31,145,244,152,112,179,211,130,
- 34,31,203,113,162,233,6,36,49,163,174,74,124,140,60,141,144,165,161,220,228,25,3,24,105,255,17,168,101,1,139,245,188,93,104,251,73,239,235,50,90,189,111,175,0,98,249,254,254,249,175,239,223,190,126,6,
- 5,27,19,47,90,170,102,0,249,158,129,129,141,133,25,228,20,6,38,38,72,74,7,185,243,243,247,239,12,23,31,60,98,228,231,253,207,144,227,107,206,32,202,199,193,240,249,251,127,134,95,191,255,49,124,249,250,
- 159,225,237,239,95,12,63,127,1,35,229,31,194,71,32,71,63,123,251,245,223,197,27,183,159,189,187,178,103,61,80,232,59,64,0,177,48,252,5,134,225,255,191,223,126,254,250,13,182,132,1,41,167,176,3,53,128,
- 188,254,226,253,103,96,212,252,96,120,247,249,203,255,79,223,191,254,255,250,235,199,191,239,63,191,255,87,145,17,100,73,116,181,100,252,249,243,63,195,149,123,223,193,14,132,101,55,96,52,3,125,255,15,
- 204,254,15,132,160,232,253,13,20,124,248,226,227,223,23,207,30,221,120,119,255,226,109,160,210,31,0,1,196,242,231,219,135,175,140,255,126,190,7,197,37,35,19,34,216,65,248,211,143,111,255,79,223,121,240,
- 255,211,183,79,76,220,156,172,12,236,204,140,140,252,124,28,140,250,226,82,140,106,82,34,140,124,156,156,12,175,222,253,1,90,4,137,162,63,127,33,161,6,178,242,215,239,255,224,160,255,15,198,12,64,7,48,
- 128,211,200,253,151,111,254,254,248,240,236,44,80,217,71,80,246,4,8,32,160,31,255,255,100,102,248,243,238,199,159,63,16,221,16,19,128,248,31,195,181,199,207,254,255,253,247,133,49,212,78,27,104,8,11,40,
- 94,25,184,216,89,129,108,38,70,144,242,183,31,17,105,230,63,148,248,15,97,49,252,248,249,15,20,85,72,105,9,148,187,254,49,220,127,254,242,207,243,75,135,14,128,130,31,84,64,1,4,16,203,247,143,175,127,
- 48,253,254,246,234,7,48,206,96,137,13,4,64,65,248,234,195,7,6,7,3,57,70,33,46,97,134,111,63,254,50,252,5,250,244,51,216,103,255,192,185,0,150,91,80,44,135,242,127,253,129,164,23,24,96,102,250,207,112,
- 255,213,219,255,247,31,63,188,251,246,201,173,199,176,2,13,32,128,88,62,188,121,241,243,211,231,207,31,126,2,147,236,63,168,6,144,193,223,190,255,254,207,198,198,192,40,35,44,206,240,252,205,79,6,132,
- 223,24,224,150,32,251,28,25,128,211,29,19,170,24,51,48,88,111,61,127,206,248,254,245,179,139,192,18,247,219,239,239,95,192,249,9,32,128,88,126,124,249,248,231,203,183,111,159,128,33,240,15,24,68,160,180,
- 2,204,223,140,12,111,63,127,102,16,228,229,4,6,53,35,195,31,176,119,25,112,3,70,84,55,0,203,50,112,33,134,108,249,103,160,7,159,189,126,253,235,235,227,203,7,255,255,251,247,13,86,63,0,4,16,168,46,248,
- 199,250,231,243,235,159,191,126,254,248,245,251,47,23,11,51,51,48,184,152,24,94,127,250,248,95,68,136,151,241,243,55,96,208,51,160,218,255,31,139,27,144,197,254,98,201,202,79,223,124,96,120,245,232,250,
- 185,119,143,174,95,250,243,243,219,119,152,60,64,0,129,2,234,223,183,215,15,95,48,254,255,253,3,146,109,192,229,5,195,135,47,159,25,248,184,121,24,126,0,227,29,88,240,49,252,101,36,14,255,1,90,249,7,156,
- 222,17,24,24,164,12,207,223,189,99,248,250,252,230,97,96,229,245,2,104,231,111,152,3,0,2,8,228,128,191,15,239,220,120,255,255,223,159,47,160,116,0,42,44,222,124,250,244,239,207,255,63,12,236,108,236,64,
- 67,65,81,0,52,244,63,113,248,47,52,10,96,14,98,2,230,191,119,223,127,48,60,121,254,248,235,151,55,207,46,1,163,252,35,114,128,1,4,16,40,10,254,191,121,249,252,199,175,159,63,191,254,2,230,45,118,22,22,
- 134,219,207,94,252,231,224,100,103,250,247,15,148,32,64,85,12,34,14,254,227,72,6,255,225,9,240,63,138,26,46,96,214,189,249,244,37,195,139,167,143,30,124,253,246,253,9,40,245,255,71,202,30,0,1,196,2,226,
- 0,243,232,159,239,63,127,124,253,11,202,94,64,169,23,31,62,50,138,137,242,49,50,0,211,195,223,255,80,7,252,199,159,6,224,137,145,9,146,231,153,160,165,218,23,96,29,240,244,237,59,134,111,175,31,95,250,
- 252,230,241,83,244,182,1,64,0,177,192,28,14,76,132,31,128,169,19,88,220,126,253,207,206,198,196,32,38,36,0,244,61,11,176,148,251,139,145,3,208,29,0,178,16,82,228,66,42,174,223,192,26,8,152,162,25,222,
- 125,248,200,240,242,253,39,134,151,79,238,126,254,242,242,238,177,15,47,30,190,5,215,242,72,0,32,128,224,14,96,254,255,231,61,168,92,123,241,254,253,127,1,62,78,6,78,110,78,134,223,64,195,254,50,98,183,
- 24,36,12,202,179,224,202,9,88,228,253,132,90,250,246,211,71,134,55,175,94,254,122,255,250,249,247,15,175,159,126,249,251,237,195,135,95,175,110,31,122,117,251,244,49,160,150,111,255,209,218,128,0,1,152,
- 44,183,21,0,65,32,136,110,247,254,255,243,122,9,187,64,105,174,74,22,138,25,173,80,208,194,188,238,156,151,217,217,15,32,182,197,37,83,201,4,31,243,178,169,232,242,214,224,223,252,103,175,35,85,1,41,129,
- 228,148,142,8,214,30,32,149,6,161,204,109,182,53,236,184,156,78,142,147,195,153,89,35,198,3,87,166,249,220,227,198,59,218,48,252,223,185,111,30,1,132,228,128,127,31,222,124,248,248,27,24,152,28,60,220,
- 220,12,44,172,172,224,224,103,5,102,98,144,133,160,236,244,229,231,47,134,239,223,127,49,188,121,251,158,225,241,179,103,12,31,223,189,254,251,227,221,139,55,191,62,188,120,246,235,205,189,59,207,238,
- 94,58,241,228,254,109,144,101,159,128,248,51,40,9,32,97,80,217,255,15,221,1,0,1,4,143,130,207,159,191,126,252,246,234,213,111,94,126,94,118,73,94,9,198,127,64,223,126,252,246,147,225,243,215,239,12,223,
- 128,229,198,251,15,239,24,62,189,126,249,227,203,171,135,47,63,189,122,252,228,235,155,199,247,95,63,188,118,227,197,227,123,247,127,255,250,249,30,104,198,7,32,126,11,181,252,7,212,183,160,4,247,7,155,
- 197,48,0,16,64,112,7,60,121,241,238,189,16,207,15,134,63,63,216,25,95,125,248,198,112,227,241,27,134,15,239,223,50,124,126,245,228,253,143,55,143,158,191,123,116,237,226,171,135,55,175,126,253,252,225,
- 229,183,47,159,95,254,253,245,227,253,175,159,223,223,193,124,7,181,20,84,105,252,70,143,103,124,0,32,128,224,14,224,102,253,251,81,144,253,223,235,167,207,30,254,124,127,231,252,155,143,175,159,188,250,
- 246,254,249,125,96,60,62,248,250,233,253,147,119,207,238,221,6,150,214,175,129,106,191,130,18,19,146,133,120,125,72,8,0,4,16,34,27,190,121,112,251,3,211,159,69,143,110,223,229,120,255,232,230,221,215,
- 79,239,62,4,102,203,207,72,241,9,11,218,63,72,89,137,20,207,98,100,93,16,0,8,32,70,144,1,64,14,168,209,199,7,196,194,160,166,27,212,135,95,96,65,10,173,95,254,34,219,6,51,128,88,7,96,235,21,129,0,64,0,
- 193,28,192,8,174,53,33,152,1,155,133,184,12,196,165,4,151,133,232,0,32,192,0,151,97,210,163,246,134,208,52,0,0,0,0,73,69,78,68,174,66,96,130,0,0};
-
- return ImageCache::getFromMemory (foldericon_png, sizeof (foldericon_png));
- }
-
- Image* LookAndFeel::getDefaultDocumentFileImage()
- {
- static const unsigned char fileicon_png[] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,32,0,0,0,32,8,6,0,0,0,115,122,122,244,0,0,0,4,103,65,77,65,0,0,175,200,55,5,
- 138,233,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101,0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101,60,0,0,4,99,73,68,65,84,120,218,98,252,255,255,63,3,12,48,50,50,50,1,
- 169,127,200,98,148,2,160,153,204,64,243,254,226,146,7,8,32,22,52,203,255,107,233,233,91,76,93,176,184,232,239,239,95,127,24,40,112,8,19,51,203,255,179,23,175,108,1,90,190,28,104,54,43,80,232,207,127,44,
- 62,3,8,32,6,144,24,84,156,25,132,189,252,3,146,255,83,9,220,127,254,242,134,162,138,170,10,208,92,144,3,152,97,118,33,99,128,0,98,66,114,11,200,1,92,255,254,252,225,32,215,215,32,127,64,240,127,80,60,
- 50,40,72,136,169,47,95,179,118,130,136,148,140,0,40,80,128,33,193,136,174,7,32,128,144,29,192,8,117,41,59,209,22,66,241,191,255,16,12,244,19,195,63,48,134,240,255,0,9,115,125,93,239,252,130,130,108,168,
- 249,44,232,102,0,4,16,19,22,62,51,33,11,255,195,44,4,211,255,25,96,16,33,6,117,24,56,226,25,24,202,139,10,75,226,51,115,66,160,105,13,197,17,0,1,196,68,172,79,255,33,91,206,192,192,128,176,22,17,10,200,
- 234,32,161,240,31,24,10,255,24,152,153,153,184,39,244,247,117,107,234,234,105,131,66,1,154,224,193,0,32,128,240,58,0,22,180,255,144,18,13,40,136,33,113,140,36,255,15,17,26,48,12,81,15,145,255,254,251,
- 31,131,0,59,171,84,81,73,105,33,208,216,191,200,161,12,16,64,44,248,131,251,63,10,31,198,253,143,38,6,83,7,11,33,228,232,2,123,4,202,226,228,96,151,132,166,49,144,35,126,131,196,0,2,136,5,103,60,51,252,
- 71,49,12,213,130,255,168,226,232,150,254,255,15,143,6,80,202,3,133,16,200,198,63,127,193,229,17,39,16,127,135,217,7,16,64,88,67,0,28,143,255,25,225,46,135,249,18,155,133,240,178,4,205,145,8,62,52,186,
- 32,234,152,160,118,194,179,35,64,0,177,96,11,123,144,236,95,104,92,162,228,113,36,11,81,125,140,112,56,186,131,96,226,176,172,137,148,229,193,0,32,128,88,112,167,248,255,112,223,48,34,165,110,6,124,190,
- 253,143,61,106,192,9,19,73,28,25,0,4,16,206,40,248,251,15,45,104,209,130,21,51,222,145,18,238,127,180,68,8,244,250,95,164,16,66,6,0,1,196,130,45,253,195,12,250,135,53,206,255,195,131,18,213,98,236,81,
- 243,31,154,11,144,115,8,50,0,8,32,156,81,0,203,227,12,80,223,98,230,4,68,72,96,38,78,84,11,65,9,250,47,146,3,145,1,64,0,97,117,192,95,112,34,68,138,130,255,176,224,251,143,226,51,6,6,68,29,192,136,20,
- 77,200,69,54,35,3,36,49,255,69,77,132,112,0,16,64,44,56,139,94,36,7,96,102,59,164,108,249,31,181,82,98,64,203,174,255,144,234,142,127,88,146,33,64,0,97,205,134,240,120,67,75,76,136,224,198,140,22,6,44,
- 142,66,201,41,255,177,231,2,128,0,194,25,5,255,254,161,134,192,127,6,28,229,0,129,242,1,150,56,33,81,138,209,28,96,0,8,32,172,81,0,78,3,104,190,68,182,224,31,146,197,224,56,6,146,140,176,202,135,17,169,
- 96,130,40,64,56,0,139,93,0,1,132,61,10,64,248,31,106,156,162,199,55,204,65,255,144,178,38,74,84,252,71,51,239,63,246,68,8,16,64,44,216,74,1,88,217,13,203,191,32,1,80,58,7,133,224,127,6,68,114,6,241,65,
- 81,197,8,101,255,71,114,33,92,237,127,228,52,128,233,2,128,0,98,193,149,3,64,117,193,255,127,255,81,75,191,127,168,5,18,136,255,31,45,161,49,32,151,134,72,252,127,12,216,203,98,128,0,98,193,210,144,135,
- 248,30,201,242,127,208,252,140,145,27,160,113,206,136,148,197,192,121,159,17,53,184,225,149,17,22,23,0,4,16,11,182,150,237,63,168,207,96,142,248,143,163,72,6,203,253,67,13,61,6,104,14,66,46,17,254,65,
- 19,40,182,16,0,8,32,22,108,109,235,255,176,234,24,35,79,255,199,222,30,64,81,135,90,35,194,211,4,142,92,0,16,64,88,29,0,107,7,254,251,247,31,53,78,241,54,207,80,29,135,209,96,249,143,189,46,0,8,32,116,
- 7,252,101,102,103,103,228,103,99,96,248,193,198,137,53,248,49,125,204,128,225,227,255,88,18,54,47,176,25,202,205,195,205,6,109,11,194,149,0,4,16,35,204,85,208,254,27,159,128,176,176,142,166,182,142,21,
- 48,4,248,129,41,143,13,217,16,70,52,95,147,0,254,0,187,69,95,223,188,122,125,235,206,141,107,7,129,252,247,64,123,193,237,66,128,0,66,118,0,168,189,198,3,196,252,32,135,64,105,54,228,230,19,185,29,100,
- 168,175,191,0,241,7,32,254,4,196,159,129,246,254,2,73,2,4,16,11,90,72,125,135,210,63,161,138,153,169,212,75,255,15,117,196,15,40,134,119,215,1,2,12,0,187,0,132,247,216,161,197,124,0,0,0,0,73,69,78,68,
- 174,66,96,130,0,0};
-
- return ImageCache::getFromMemory (fileicon_png, sizeof (fileicon_png));
- }
-
- void LookAndFeel::playAlertSound()
- {
- PlatformUtilities::beep();
- }
-
- void LookAndFeel::drawLevelMeter (Graphics& g, int width, int height, float level)
- {
- g.setColour (Colours::white.withAlpha (0.7f));
- g.fillRoundedRectangle (0.0f, 0.0f, (float) width, (float) height, 3.0f);
- g.setColour (Colours::black.withAlpha (0.2f));
- g.drawRoundedRectangle (1.0f, 1.0f, width - 2.0f, height - 2.0f, 3.0f, 1.0f);
-
- const int totalBlocks = 7;
- const int numBlocks = roundDoubleToInt (totalBlocks * level);
- const float w = (width - 6.0f) / (float) totalBlocks;
-
- for (int i = 0; i < totalBlocks; ++i)
- {
- if (i >= numBlocks)
- g.setColour (Colours::lightblue.withAlpha (0.6f));
- else
- g.setColour (i < totalBlocks - 1 ? Colours::blue.withAlpha (0.5f)
- : Colours::red);
-
- g.fillRoundedRectangle (3.0f + i * w + w * 0.1f, 3.0f, w * 0.8f, height - 6.0f, w * 0.4f);
- }
- }
-
- static void createRoundedPath (Path& p,
- const float x, const float y,
- const float w, const float h,
- const float cs,
- const bool curveTopLeft, const bool curveTopRight,
- const bool curveBottomLeft, const bool curveBottomRight) throw()
- {
- const float cs2 = 2.0f * cs;
-
- if (curveTopLeft)
- {
- p.startNewSubPath (x, y + cs);
- p.addArc (x, y, cs2, cs2, float_Pi * 1.5f, float_Pi * 2.0f);
- }
- else
- {
- p.startNewSubPath (x, y);
- }
-
- if (curveTopRight)
- {
- p.lineTo (x + w - cs, y);
- p.addArc (x + w - cs2, y, cs2, cs2, 0.0f, float_Pi * 0.5f);
- }
- else
- {
- p.lineTo (x + w, y);
- }
-
- if (curveBottomRight)
- {
- p.lineTo (x + w, y + h - cs);
- p.addArc (x + w - cs2, y + h - cs2, cs2, cs2, float_Pi * 0.5f, float_Pi);
- }
- else
- {
- p.lineTo (x + w, y + h);
- }
-
- if (curveBottomLeft)
- {
- p.lineTo (x + cs, y + h);
- p.addArc (x, y + h - cs2, cs2, cs2, float_Pi, float_Pi * 1.5f);
- }
- else
- {
- p.lineTo (x, y + h);
- }
-
- p.closeSubPath();
- }
-
- void LookAndFeel::drawShinyButtonShape (Graphics& g,
- float x, float y, float w, float h,
- float maxCornerSize,
- const Colour& baseColour,
- const float strokeWidth,
- const bool flatOnLeft,
- const bool flatOnRight,
- const bool flatOnTop,
- const bool flatOnBottom) throw()
- {
- if (w <= strokeWidth * 1.1f || h <= strokeWidth * 1.1f)
- return;
-
- const float cs = jmin (maxCornerSize, w * 0.5f, h * 0.5f);
-
- Path outline;
- createRoundedPath (outline, x, y, w, h, cs,
- ! (flatOnLeft || flatOnTop),
- ! (flatOnRight || flatOnTop),
- ! (flatOnLeft || flatOnBottom),
- ! (flatOnRight || flatOnBottom));
-
- ColourGradient cg (baseColour, 0.0f, y,
- baseColour.overlaidWith (Colour (0x070000ff)), 0.0f, y + h,
- false);
-
- cg.addColour (0.5, baseColour.overlaidWith (Colour (0x33ffffff)));
- cg.addColour (0.51, baseColour.overlaidWith (Colour (0x110000ff)));
-
- GradientBrush gb (cg);
- g.setBrush (&gb);
- g.fillPath (outline);
-
- g.setColour (Colour (0x80000000));
- g.strokePath (outline, PathStrokeType (strokeWidth));
- }
-
- void LookAndFeel::drawGlassSphere (Graphics& g,
- const float x, const float y,
- const float diameter,
- const Colour& colour,
- const float outlineThickness) throw()
- {
- if (diameter <= outlineThickness)
- return;
-
- Path p;
- p.addEllipse (x, y, diameter, diameter);
-
- {
- ColourGradient cg (Colours::white.overlaidWith (colour.withMultipliedAlpha (0.3f)), 0, y,
- Colours::white.overlaidWith (colour.withMultipliedAlpha (0.3f)), 0, y + diameter, false);
-
- cg.addColour (0.4, Colours::white.overlaidWith (colour));
-
- GradientBrush gb (cg);
- g.setBrush (&gb);
- g.fillPath (p);
- }
-
- {
- GradientBrush gb (Colours::white, 0, y + diameter * 0.06f,
- Colours::transparentWhite, 0, y + diameter * 0.3f, false);
-
- g.setBrush (&gb);
- g.fillEllipse (x + diameter * 0.2f, y + diameter * 0.05f, diameter * 0.6f, diameter * 0.4f);
- }
-
- {
- ColourGradient cg (Colours::transparentBlack,
- x + diameter * 0.5f, y + diameter * 0.5f,
- Colours::black.withAlpha (0.5f * outlineThickness * colour.getFloatAlpha()),
- x, y + diameter * 0.5f, true);
-
- cg.addColour (0.7, Colours::transparentBlack);
- cg.addColour (0.8, Colours::black.withAlpha (0.1f * outlineThickness));
-
- GradientBrush gb (cg);
- g.setBrush (&gb);
- g.fillPath (p);
- }
-
- g.setColour (Colours::black.withAlpha (0.5f * colour.getFloatAlpha()));
- g.drawEllipse (x, y, diameter, diameter, outlineThickness);
- }
-
- void LookAndFeel::drawGlassPointer (Graphics& g,
- const float x, const float y,
- const float diameter,
- const Colour& colour, const float outlineThickness,
- const int direction) throw()
- {
- if (diameter <= outlineThickness)
- return;
-
- Path p;
- p.startNewSubPath (x + diameter * 0.5f, y);
- p.lineTo (x + diameter, y + diameter * 0.6f);
- p.lineTo (x + diameter, y + diameter);
- p.lineTo (x, y + diameter);
- p.lineTo (x, y + diameter * 0.6f);
- p.closeSubPath();
-
- p.applyTransform (AffineTransform::rotation (direction * (float_Pi * 0.5f), x + diameter * 0.5f, y + diameter * 0.5f));
-
- {
- ColourGradient cg (Colours::white.overlaidWith (colour.withMultipliedAlpha (0.3f)), 0, y,
- Colours::white.overlaidWith (colour.withMultipliedAlpha (0.3f)), 0, y + diameter, false);
-
- cg.addColour (0.4, Colours::white.overlaidWith (colour));
-
- GradientBrush gb (cg);
- g.setBrush (&gb);
- g.fillPath (p);
- }
-
- {
- ColourGradient cg (Colours::transparentBlack,
- x + diameter * 0.5f, y + diameter * 0.5f,
- Colours::black.withAlpha (0.5f * outlineThickness * colour.getFloatAlpha()),
- x - diameter * 0.2f, y + diameter * 0.5f, true);
-
- cg.addColour (0.5, Colours::transparentBlack);
- cg.addColour (0.7, Colours::black.withAlpha (0.07f * outlineThickness));
-
- GradientBrush gb (cg);
- g.setBrush (&gb);
- g.fillPath (p);
- }
-
- g.setColour (Colours::black.withAlpha (0.5f * colour.getFloatAlpha()));
- g.strokePath (p, PathStrokeType (outlineThickness));
- }
-
- void LookAndFeel::drawGlassLozenge (Graphics& g,
- const float x, const float y,
- const float width, const float height,
- const Colour& colour,
- const float outlineThickness,
- const float cornerSize,
- const bool flatOnLeft,
- const bool flatOnRight,
- const bool flatOnTop,
- const bool flatOnBottom) throw()
- {
- if (width <= outlineThickness || height <= outlineThickness)
- return;
-
- const int intX = (int) x;
- const int intY = (int) y;
- const int intW = (int) width;
- const int intH = (int) height;
-
- const float cs = cornerSize < 0 ? jmin (width * 0.5f, height * 0.5f) : cornerSize;
- const float edgeBlurRadius = height * 0.75f + (height - cs * 2.0f);
- const int intEdge = (int) edgeBlurRadius;
-
- Path outline;
- createRoundedPath (outline, x, y, width, height, cs,
- ! (flatOnLeft || flatOnTop),
- ! (flatOnRight || flatOnTop),
- ! (flatOnLeft || flatOnBottom),
- ! (flatOnRight || flatOnBottom));
-
- {
- ColourGradient cg (colour.darker (0.2f), 0, y,
- colour.darker (0.2f), 0, y + height, false);
-
- cg.addColour (0.03, colour.withMultipliedAlpha (0.3f));
- cg.addColour (0.4, colour);
- cg.addColour (0.97, colour.withMultipliedAlpha (0.3f));
-
- GradientBrush gb (cg);
- g.setBrush (&gb);
- g.fillPath (outline);
- }
-
- ColourGradient cg (Colours::transparentBlack, x + edgeBlurRadius, y + height * 0.5f,
- colour.darker (0.2f), x, y + height * 0.5f, true);
-
- cg.addColour (jlimit (0.0, 1.0, 1.0 - (cs * 0.5f) / edgeBlurRadius), Colours::transparentBlack);
- cg.addColour (jlimit (0.0, 1.0, 1.0 - (cs * 0.25f) / edgeBlurRadius), colour.darker (0.2f).withMultipliedAlpha (0.3f));
-
- if (! (flatOnLeft || flatOnTop || flatOnBottom))
- {
- GradientBrush gb (cg);
-
- g.saveState();
- g.setBrush (&gb);
- g.reduceClipRegion (intX, intY, intEdge, intH);
- g.fillPath (outline);
- g.restoreState();
- }
-
- if (! (flatOnRight || flatOnTop || flatOnBottom))
- {
- cg.x1 = x + width - edgeBlurRadius;
- cg.x2 = x + width;
- GradientBrush gb (cg);
-
- g.saveState();
- g.setBrush (&gb);
- g.reduceClipRegion (intX + intW - intEdge, intY, 2 + intEdge, intH);
- g.fillPath (outline);
- g.restoreState();
- }
-
- {
- const float leftIndent = flatOnLeft ? 0.0f : cs * 0.4f;
- const float rightIndent = flatOnRight ? 0.0f : cs * 0.4f;
-
- Path highlight;
- createRoundedPath (highlight,
- x + leftIndent,
- y + cs * 0.1f,
- width - (leftIndent + rightIndent),
- height * 0.4f, cs * 0.4f,
- ! (flatOnLeft || flatOnTop),
- ! (flatOnRight || flatOnTop),
- ! (flatOnLeft || flatOnBottom),
- ! (flatOnRight || flatOnBottom));
-
- GradientBrush gb (colour.brighter (10.0f), 0, y + height * 0.06f,
- Colours::transparentWhite, 0, y + height * 0.4f, false);
-
- g.setBrush (&gb);
- g.fillPath (highlight);
- }
-
- g.setColour (colour.darker().withMultipliedAlpha (1.5f));
- g.strokePath (outline, PathStrokeType (outlineThickness));
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_LookAndFeel.cpp *********/
-
- /********* Start of inlined file: juce_OldSchoolLookAndFeel.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- OldSchoolLookAndFeel::OldSchoolLookAndFeel()
- {
- setColour (TextButton::buttonColourId, Colour (0xffbbbbff));
- setColour (ListBox::outlineColourId, findColour (ComboBox::outlineColourId));
- setColour (ScrollBar::thumbColourId, Colour (0xffbbbbdd));
- setColour (ScrollBar::backgroundColourId, Colours::transparentBlack);
- setColour (Slider::thumbColourId, Colours::white);
- setColour (Slider::trackColourId, Colour (0x7f000000));
- setColour (Slider::textBoxOutlineColourId, Colours::grey);
- setColour (ProgressBar::backgroundColourId, Colours::white.withAlpha (0.6f));
- setColour (ProgressBar::foregroundColourId, Colours::green.withAlpha (0.7f));
- setColour (PopupMenu::backgroundColourId, Colour (0xffeef5f8));
- setColour (PopupMenu::highlightedBackgroundColourId, Colour (0xbfa4c2ce));
- setColour (PopupMenu::highlightedTextColourId, Colours::black);
- setColour (TextEditor::focusedOutlineColourId, findColour (TextButton::buttonColourId));
-
- scrollbarShadow.setShadowProperties (2.2f, 0.5f, 0, 0);
- }
-
- OldSchoolLookAndFeel::~OldSchoolLookAndFeel()
- {
- }
-
- void OldSchoolLookAndFeel::drawButtonBackground (Graphics& g,
- Button& button,
- const Colour& backgroundColour,
- bool isMouseOverButton,
- bool isButtonDown)
- {
- const int width = button.getWidth();
- const int height = button.getHeight();
-
- const float indent = 2.0f;
- const int cornerSize = jmin (roundFloatToInt (width * 0.4f),
- roundFloatToInt (height * 0.4f));
-
- Path p;
- p.addRoundedRectangle (indent, indent,
- width - indent * 2.0f,
- height - indent * 2.0f,
- (float) cornerSize);
-
- Colour bc (backgroundColour.withMultipliedSaturation (0.3f));
-
- if (isMouseOverButton)
- {
- if (isButtonDown)
- bc = bc.brighter();
- else if (bc.getBrightness() > 0.5f)
- bc = bc.darker (0.1f);
- else
- bc = bc.brighter (0.1f);
- }
-
- g.setColour (bc);
- g.fillPath (p);
-
- g.setColour (bc.contrasting().withAlpha ((isMouseOverButton) ? 0.6f : 0.4f));
- g.strokePath (p, PathStrokeType ((isMouseOverButton) ? 2.0f : 1.4f));
- }
-
- void OldSchoolLookAndFeel::drawTickBox (Graphics& g,
- Component& /*component*/,
- int x, int y, int w, int h,
- const bool ticked,
- const bool isEnabled,
- const bool /*isMouseOverButton*/,
- const bool isButtonDown)
- {
- Path box;
- box.addRoundedRectangle (0.0f, 2.0f, 6.0f, 6.0f, 1.0f);
-
- g.setColour (isEnabled ? Colours::blue.withAlpha (isButtonDown ? 0.3f : 0.1f)
- : Colours::lightgrey.withAlpha (0.1f));
-
- AffineTransform trans (AffineTransform::scale (w / 9.0f, h / 9.0f)
- .translated ((float) x, (float) y));
-
- g.fillPath (box, trans);
-
- g.setColour (Colours::black.withAlpha (0.6f));
- g.strokePath (box, PathStrokeType (0.9f), trans);
-
- if (ticked)
- {
- Path tick;
- tick.startNewSubPath (1.5f, 3.0f);
- tick.lineTo (3.0f, 6.0f);
- tick.lineTo (6.0f, 0.0f);
-
- g.setColour (isEnabled ? Colours::black : Colours::grey);
- g.strokePath (tick, PathStrokeType (2.5f), trans);
- }
- }
-
- void OldSchoolLookAndFeel::drawToggleButton (Graphics& g,
- ToggleButton& button,
- bool isMouseOverButton,
- bool isButtonDown)
- {
- if (button.hasKeyboardFocus (true))
- {
- g.setColour (button.findColour (TextEditor::focusedOutlineColourId));
- g.drawRect (0, 0, button.getWidth(), button.getHeight());
- }
-
- const int tickWidth = jmin (20, button.getHeight() - 4);
-
- drawTickBox (g, button, 4, (button.getHeight() - tickWidth) / 2,
- tickWidth, tickWidth,
- button.getToggleState(),
- button.isEnabled(),
- isMouseOverButton,
- isButtonDown);
-
- g.setColour (button.findColour (ToggleButton::textColourId));
- g.setFont (jmin (15.0f, button.getHeight() * 0.6f));
-
- if (! button.isEnabled())
- g.setOpacity (0.5f);
-
- const int textX = tickWidth + 5;
-
- g.drawFittedText (button.getButtonText(),
- textX, 4,
- button.getWidth() - textX - 2, button.getHeight() - 8,
- Justification::centredLeft, 10);
- }
-
- void OldSchoolLookAndFeel::drawProgressBar (Graphics& g, ProgressBar& progressBar,
- int width, int height,
- double progress, const String& textToShow)
- {
- if (progress < 0 || progress >= 1.0)
- {
- LookAndFeel::drawProgressBar (g, progressBar, width, height, progress, textToShow);
- }
- else
- {
- const Colour background (progressBar.findColour (ProgressBar::backgroundColourId));
- const Colour foreground (progressBar.findColour (ProgressBar::foregroundColourId));
-
- g.fillAll (background);
- g.setColour (foreground);
-
- g.fillRect (1, 1,
- jlimit (0, width - 2, roundDoubleToInt (progress * (width - 2))),
- height - 2);
-
- if (textToShow.isNotEmpty())
- {
- g.setColour (Colour::contrasting (background, foreground));
- g.setFont (height * 0.6f);
-
- g.drawText (textToShow, 0, 0, width, height, Justification::centred, false);
- }
- }
- }
-
- void OldSchoolLookAndFeel::drawScrollbarButton (Graphics& g,
- ScrollBar& bar,
- int width, int height,
- int buttonDirection,
- bool isScrollbarVertical,
- bool isMouseOverButton,
- bool isButtonDown)
- {
- if (isScrollbarVertical)
- width -= 2;
- else
- height -= 2;
-
- Path p;
-
- if (buttonDirection == 0)
- p.addTriangle (width * 0.5f, height * 0.2f,
- width * 0.1f, height * 0.7f,
- width * 0.9f, height * 0.7f);
- else if (buttonDirection == 1)
- p.addTriangle (width * 0.8f, height * 0.5f,
- width * 0.3f, height * 0.1f,
- width * 0.3f, height * 0.9f);
- else if (buttonDirection == 2)
- p.addTriangle (width * 0.5f, height * 0.8f,
- width * 0.1f, height * 0.3f,
- width * 0.9f, height * 0.3f);
- else if (buttonDirection == 3)
- p.addTriangle (width * 0.2f, height * 0.5f,
- width * 0.7f, height * 0.1f,
- width * 0.7f, height * 0.9f);
-
- if (isButtonDown)
- g.setColour (Colours::white);
- else if (isMouseOverButton)
- g.setColour (Colours::white.withAlpha (0.7f));
- else
- g.setColour (bar.findColour (ScrollBar::thumbColourId).withAlpha (0.5f));
-
- g.fillPath (p);
-
- g.setColour (Colours::black.withAlpha (0.5f));
- g.strokePath (p, PathStrokeType (0.5f));
- }
-
- void OldSchoolLookAndFeel::drawScrollbar (Graphics& g,
- ScrollBar& bar,
- int x, int y,
- int width, int height,
- bool isScrollbarVertical,
- int thumbStartPosition,
- int thumbSize,
- bool isMouseOver,
- bool isMouseDown)
- {
- g.fillAll (bar.findColour (ScrollBar::backgroundColourId));
-
- g.setColour (bar.findColour (ScrollBar::thumbColourId)
- .withAlpha ((isMouseOver || isMouseDown) ? 0.4f : 0.15f));
-
- if (thumbSize > 0.0f)
- {
- Rectangle thumb;
-
- if (isScrollbarVertical)
- {
- width -= 2;
- g.fillRect (x + roundFloatToInt (width * 0.35f), y,
- roundFloatToInt (width * 0.3f), height);
-
- thumb.setBounds (x + 1, thumbStartPosition,
- width - 2, thumbSize);
- }
- else
- {
- height -= 2;
- g.fillRect (x, y + roundFloatToInt (height * 0.35f),
- width, roundFloatToInt (height * 0.3f));
-
- thumb.setBounds (thumbStartPosition, y + 1,
- thumbSize, height - 2);
- }
-
- g.setColour (bar.findColour (ScrollBar::thumbColourId)
- .withAlpha ((isMouseOver || isMouseDown) ? 0.95f : 0.7f));
-
- g.fillRect (thumb);
-
- g.setColour (Colours::black.withAlpha ((isMouseOver || isMouseDown) ? 0.4f : 0.25f));
- g.drawRect (thumb.getX(), thumb.getY(), thumb.getWidth(), thumb.getHeight());
-
- if (thumbSize > 16)
- {
- for (int i = 3; --i >= 0;)
- {
- const float linePos = thumbStartPosition + thumbSize / 2 + (i - 1) * 4.0f;
- g.setColour (Colours::black.withAlpha (0.15f));
-
- if (isScrollbarVertical)
- {
- g.drawLine (x + width * 0.2f, linePos, width * 0.8f, linePos);
- g.setColour (Colours::white.withAlpha (0.15f));
- g.drawLine (width * 0.2f, linePos - 1, width * 0.8f, linePos - 1);
- }
- else
- {
- g.drawLine (linePos, height * 0.2f, linePos, height * 0.8f);
- g.setColour (Colours::white.withAlpha (0.15f));
- g.drawLine (linePos - 1, height * 0.2f, linePos - 1, height * 0.8f);
- }
- }
- }
- }
- }
-
- ImageEffectFilter* OldSchoolLookAndFeel::getScrollbarEffect()
- {
- return &scrollbarShadow;
- }
-
- void OldSchoolLookAndFeel::drawPopupMenuBackground (Graphics& g, int width, int height)
- {
- g.fillAll (findColour (PopupMenu::backgroundColourId));
-
- g.setColour (Colours::black.withAlpha (0.6f));
- g.drawRect (0, 0, width, height);
- }
-
- void OldSchoolLookAndFeel::drawMenuBarBackground (Graphics& g, int /*width*/, int /*height*/,
- bool, MenuBarComponent& menuBar)
- {
- g.fillAll (menuBar.findColour (PopupMenu::backgroundColourId));
- }
-
- void OldSchoolLookAndFeel::drawTextEditorOutline (Graphics& g, int width, int height, TextEditor& textEditor)
- {
- if (textEditor.isEnabled())
- {
- g.setColour (textEditor.findColour (TextEditor::outlineColourId));
- g.drawRect (0, 0, width, height);
- }
- }
-
- void OldSchoolLookAndFeel::drawComboBox (Graphics& g, int width, int height,
- const bool isButtonDown,
- int buttonX, int buttonY,
- int buttonW, int buttonH,
- ComboBox& box)
- {
- g.fillAll (box.findColour (ComboBox::backgroundColourId));
-
- g.setColour (box.findColour ((isButtonDown) ? ComboBox::buttonColourId
- : ComboBox::backgroundColourId));
- g.fillRect (buttonX, buttonY, buttonW, buttonH);
-
- g.setColour (box.findColour (ComboBox::outlineColourId));
- g.drawRect (0, 0, width, height);
-
- const float arrowX = 0.2f;
- const float arrowH = 0.3f;
-
- if (box.isEnabled())
- {
- Path p;
- p.addTriangle (buttonX + buttonW * 0.5f, buttonY + buttonH * (0.45f - arrowH),
- buttonX + buttonW * (1.0f - arrowX), buttonY + buttonH * 0.45f,
- buttonX + buttonW * arrowX, buttonY + buttonH * 0.45f);
-
- p.addTriangle (buttonX + buttonW * 0.5f, buttonY + buttonH * (0.55f + arrowH),
- buttonX + buttonW * (1.0f - arrowX), buttonY + buttonH * 0.55f,
- buttonX + buttonW * arrowX, buttonY + buttonH * 0.55f);
-
- g.setColour (box.findColour ((isButtonDown) ? ComboBox::backgroundColourId
- : ComboBox::buttonColourId));
- g.fillPath (p);
- }
- }
-
- const Font OldSchoolLookAndFeel::getComboBoxFont (ComboBox& box)
- {
- Font f (jmin (15.0f, box.getHeight() * 0.85f));
- f.setHorizontalScale (0.9f);
- return f;
- }
-
- static void drawTriangle (Graphics& g, float x1, float y1, float x2, float y2, float x3, float y3, const Colour& fill, const Colour& outline) throw()
- {
- Path p;
- p.addTriangle (x1, y1, x2, y2, x3, y3);
- g.setColour (fill);
- g.fillPath (p);
-
- g.setColour (outline);
- g.strokePath (p, PathStrokeType (0.3f));
- }
-
- void OldSchoolLookAndFeel::drawLinearSlider (Graphics& g,
- int x, int y,
- int w, int h,
- float sliderPos,
- float minSliderPos,
- float maxSliderPos,
- const Slider::SliderStyle style,
- Slider& slider)
- {
- g.fillAll (slider.findColour (Slider::backgroundColourId));
-
- if (style == Slider::LinearBar)
- {
- g.setColour (slider.findColour (Slider::thumbColourId));
- g.fillRect (x, y, (int) sliderPos - x, h);
-
- g.setColour (slider.findColour (Slider::textBoxTextColourId).withMultipliedAlpha (0.5f));
- g.drawRect (x, y, (int) sliderPos - x, h);
- }
- else
- {
- g.setColour (slider.findColour (Slider::trackColourId)
- .withMultipliedAlpha (slider.isEnabled() ? 1.0f : 0.3f));
-
- if (slider.isHorizontal())
- {
- g.fillRect (x, y + roundFloatToInt (h * 0.6f),
- w, roundFloatToInt (h * 0.2f));
- }
- else
- {
- g.fillRect (x + roundFloatToInt (w * 0.5f - jmin (3.0f, w * 0.1f)), y,
- jmin (4, roundFloatToInt (w * 0.2f)), h);
- }
-
- float alpha = 0.35f;
-
- if (slider.isEnabled())
- alpha = slider.isMouseOverOrDragging() ? 1.0f : 0.7f;
-
- const Colour fill (slider.findColour (Slider::thumbColourId).withAlpha (alpha));
- const Colour outline (Colours::black.withAlpha (slider.isEnabled() ? 0.7f : 0.35f));
-
- if (style == Slider::TwoValueVertical || style == Slider::ThreeValueVertical)
- {
- drawTriangle (g, x + w * 0.5f + jmin (4.0f, w * 0.3f), minSliderPos,
- x + w * 0.5f - jmin (8.0f, w * 0.4f), minSliderPos - 7.0f,
- x + w * 0.5f - jmin (8.0f, w * 0.4f), minSliderPos,
- fill, outline);
-
- drawTriangle (g, x + w * 0.5f + jmin (4.0f, w * 0.3f), maxSliderPos,
- x + w * 0.5f - jmin (8.0f, w * 0.4f), maxSliderPos,
- x + w * 0.5f - jmin (8.0f, w * 0.4f), maxSliderPos + 7.0f,
- fill, outline);
- }
- else if (style == Slider::TwoValueHorizontal || style == Slider::ThreeValueHorizontal)
- {
- drawTriangle (g, minSliderPos, y + h * 0.6f - jmin (4.0f, h * 0.3f),
- minSliderPos - 7.0f, y + h * 0.9f ,
- minSliderPos, y + h * 0.9f,
- fill, outline);
-
- drawTriangle (g, maxSliderPos, y + h * 0.6f - jmin (4.0f, h * 0.3f),
- maxSliderPos, y + h * 0.9f,
- maxSliderPos + 7.0f, y + h * 0.9f,
- fill, outline);
- }
-
- if (style == Slider::LinearHorizontal || style == Slider::ThreeValueHorizontal)
- {
- drawTriangle (g, sliderPos, y + h * 0.9f,
- sliderPos - 7.0f, y + h * 0.2f,
- sliderPos + 7.0f, y + h * 0.2f,
- fill, outline);
- }
- else if (style == Slider::LinearVertical || style == Slider::ThreeValueVertical)
- {
- drawTriangle (g, x + w * 0.5f - jmin (4.0f, w * 0.3f), sliderPos,
- x + w * 0.5f + jmin (8.0f, w * 0.4f), sliderPos - 7.0f,
- x + w * 0.5f + jmin (8.0f, w * 0.4f), sliderPos + 7.0f,
- fill, outline);
- }
- }
- }
-
- Button* OldSchoolLookAndFeel::createSliderButton (const bool isIncrement)
- {
- if (isIncrement)
- return new ArrowButton ("u", 0.75f, Colours::white.withAlpha (0.8f));
- else
- return new ArrowButton ("d", 0.25f, Colours::white.withAlpha (0.8f));
- }
-
- ImageEffectFilter* OldSchoolLookAndFeel::getSliderEffect()
- {
- return &scrollbarShadow;
- }
-
- int OldSchoolLookAndFeel::getSliderThumbRadius (Slider&)
- {
- return 8;
- }
-
- void OldSchoolLookAndFeel::drawCornerResizer (Graphics& g,
- int w, int h,
- bool isMouseOver,
- bool isMouseDragging)
- {
- g.setColour ((isMouseOver || isMouseDragging) ? Colours::lightgrey
- : Colours::darkgrey);
-
- const float lineThickness = jmin (w, h) * 0.1f;
-
- for (float i = 0.0f; i < 1.0f; i += 0.3f)
- {
- g.drawLine (w * i,
- h + 1.0f,
- w + 1.0f,
- h * i,
- lineThickness);
- }
- }
-
- Button* OldSchoolLookAndFeel::createDocumentWindowButton (int buttonType)
- {
- Path shape;
-
- if (buttonType == DocumentWindow::closeButton)
- {
- shape.addLineSegment (0.0f, 0.0f, 1.0f, 1.0f, 0.35f);
- shape.addLineSegment (1.0f, 0.0f, 0.0f, 1.0f, 0.35f);
-
- ShapeButton* const b = new ShapeButton ("close",
- Colour (0x7fff3333),
- Colour (0xd7ff3333),
- Colour (0xf7ff3333));
-
- b->setShape (shape, true, true, true);
- return b;
- }
- else if (buttonType == DocumentWindow::minimiseButton)
- {
- shape.addLineSegment (0.0f, 0.5f, 1.0f, 0.5f, 0.25f);
-
- DrawableButton* b = new DrawableButton ("minimise", DrawableButton::ImageFitted);
- DrawablePath dp;
- dp.setPath (shape);
- dp.setSolidFill (Colours::black.withAlpha (0.3f));
- b->setImages (&dp);
- return b;
- }
- else if (buttonType == DocumentWindow::maximiseButton)
- {
- shape.addLineSegment (0.5f, 0.0f, 0.5f, 1.0f, 0.25f);
- shape.addLineSegment (0.0f, 0.5f, 1.0f, 0.5f, 0.25f);
-
- DrawableButton* b = new DrawableButton ("maximise", DrawableButton::ImageFitted);
- DrawablePath dp;
- dp.setPath (shape);
- dp.setSolidFill (Colours::black.withAlpha (0.3f));
- b->setImages (&dp);
- return b;
- }
-
- jassertfalse
- return 0;
- }
-
- void OldSchoolLookAndFeel::positionDocumentWindowButtons (DocumentWindow&,
- int titleBarX,
- int titleBarY,
- int titleBarW,
- int titleBarH,
- Button* minimiseButton,
- Button* maximiseButton,
- Button* closeButton,
- bool positionTitleBarButtonsOnLeft)
- {
- titleBarY += titleBarH / 8;
- titleBarH -= titleBarH / 4;
-
- const int buttonW = titleBarH;
-
- int x = positionTitleBarButtonsOnLeft ? titleBarX + 4
- : titleBarX + titleBarW - buttonW - 4;
-
- if (closeButton != 0)
- {
- closeButton->setBounds (x, titleBarY, buttonW, titleBarH);
- x += positionTitleBarButtonsOnLeft ? buttonW + buttonW / 5
- : -(buttonW + buttonW / 5);
- }
-
- if (positionTitleBarButtonsOnLeft)
- swapVariables (minimiseButton, maximiseButton);
-
- if (maximiseButton != 0)
- {
- maximiseButton->setBounds (x, titleBarY - 2, buttonW, titleBarH);
- x += positionTitleBarButtonsOnLeft ? buttonW : -buttonW;
- }
-
- if (minimiseButton != 0)
- minimiseButton->setBounds (x, titleBarY - 2, buttonW, titleBarH);
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_OldSchoolLookAndFeel.cpp *********/
-
- /********* Start of inlined file: juce_MenuBarComponent.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- class DummyMenuComponent : public Component
- {
- DummyMenuComponent (const DummyMenuComponent&);
- const DummyMenuComponent& operator= (const DummyMenuComponent&);
-
- public:
- DummyMenuComponent() {}
- ~DummyMenuComponent() {}
-
- void inputAttemptWhenModal()
- {
- exitModalState (0);
- }
- };
-
- MenuBarComponent::MenuBarComponent (MenuBarModel* model_)
- : model (0),
- itemUnderMouse (-1),
- currentPopupIndex (-1),
- indexToShowAgain (-1),
- lastMouseX (0),
- lastMouseY (0),
- inModalState (false),
- currentPopup (0)
- {
- setRepaintsOnMouseActivity (true);
- setWantsKeyboardFocus (false);
- setMouseClickGrabsKeyboardFocus (false);
-
- setModel (model_);
- }
-
- MenuBarComponent::~MenuBarComponent()
- {
- setModel (0);
-
- Desktop::getInstance().removeGlobalMouseListener (this);
- deleteAndZero (currentPopup);
- }
-
- void MenuBarComponent::setModel (MenuBarModel* const newModel)
- {
- if (model != newModel)
- {
- if (model != 0)
- model->removeListener (this);
-
- model = newModel;
-
- if (model != 0)
- model->addListener (this);
-
- repaint();
- menuBarItemsChanged (0);
- }
- }
-
- void MenuBarComponent::paint (Graphics& g)
- {
- const bool isMouseOverBar = currentPopupIndex >= 0 || itemUnderMouse >= 0 || isMouseOver();
-
- getLookAndFeel().drawMenuBarBackground (g,
- getWidth(),
- getHeight(),
- isMouseOverBar,
- *this);
-
- if (model != 0)
- {
- for (int i = 0; i < menuNames.size(); ++i)
- {
- g.saveState();
- g.setOrigin (xPositions [i], 0);
- g.reduceClipRegion (0, 0, xPositions[i + 1] - xPositions[i], getHeight());
-
- getLookAndFeel().drawMenuBarItem (g,
- xPositions[i + 1] - xPositions[i],
- getHeight(),
- i,
- menuNames[i],
- i == itemUnderMouse,
- i == currentPopupIndex,
- isMouseOverBar,
- *this);
-
- g.restoreState();
- }
- }
- }
-
- void MenuBarComponent::resized()
- {
- xPositions.clear();
- int x = 2;
- xPositions.add (x);
-
- for (int i = 0; i < menuNames.size(); ++i)
- {
- x += getLookAndFeel().getMenuBarItemWidth (*this, i, menuNames[i]);
-
- xPositions.add (x);
- }
- }
-
- int MenuBarComponent::getItemAt (const int x, const int y)
- {
- for (int i = 0; i < xPositions.size(); ++i)
- if (x >= xPositions[i] && x < xPositions[i + 1])
- return reallyContains (x, y, true) ? i : -1;
-
- return -1;
- }
-
- void MenuBarComponent::repaintMenuItem (int index)
- {
- if (((unsigned int) index) < (unsigned int) xPositions.size())
- {
- const int x1 = xPositions [index];
- const int x2 = xPositions [index + 1];
-
- repaint (x1 - 2, 0, x2 - x1 + 4, getHeight());
- }
- }
-
- void MenuBarComponent::updateItemUnderMouse (int x, int y)
- {
- const int newItem = getItemAt (x, y);
-
- if (itemUnderMouse != newItem)
- {
- repaintMenuItem (itemUnderMouse);
- itemUnderMouse = newItem;
- repaintMenuItem (itemUnderMouse);
- }
- }
-
- void MenuBarComponent::hideCurrentMenu()
- {
- deleteAndZero (currentPopup);
- repaint();
- }
-
- void MenuBarComponent::showMenu (int index)
- {
- if (index != currentPopupIndex)
- {
- if (inModalState)
- {
- hideCurrentMenu();
- indexToShowAgain = index;
- return;
- }
-
- indexToShowAgain = -1;
- currentPopupIndex = -1;
- deleteAndZero (currentPopup);
- menuBarItemsChanged (0);
-
- Component* const prevFocused = getCurrentlyFocusedComponent();
-
- ComponentDeletionWatcher* prevCompDeletionChecker = 0;
- if (prevFocused != 0)
- prevCompDeletionChecker = new ComponentDeletionWatcher (prevFocused);
-
- ComponentDeletionWatcher deletionChecker (this);
-
- enterModalState (false);
- inModalState = true;
- int result = 0;
- ApplicationCommandManager* managerOfChosenCommand = 0;
-
- Desktop::getInstance().addGlobalMouseListener (this);
-
- for (;;)
- {
- const int x = getScreenX() + xPositions [itemUnderMouse];
- const int w = xPositions [itemUnderMouse + 1] - xPositions [itemUnderMouse];
-
- currentPopupIndex = itemUnderMouse;
- indexToShowAgain = -1;
- repaint();
-
- if (((unsigned int) itemUnderMouse) < (unsigned int) menuNames.size())
- {
- PopupMenu m (model->getMenuForIndex (itemUnderMouse,
- menuNames [itemUnderMouse]));
-
- currentPopup = m.createMenuComponent (x, getScreenY(),
- w, getHeight(),
- 0, w, 0, 0,
- true, this,
- &managerOfChosenCommand,
- this);
- }
-
- if (currentPopup == 0)
- {
- currentPopup = new DummyMenuComponent();
- addAndMakeVisible (currentPopup);
- }
-
- currentPopup->enterModalState (false);
- currentPopup->toFront (false); // need to do this after making it modal, or it could
- // be stuck behind other comps that are already modal..
- result = currentPopup->runModalLoop();
-
- if (deletionChecker.hasBeenDeleted())
- {
- delete prevCompDeletionChecker;
- return;
- }
-
- const int lastPopupIndex = currentPopupIndex;
- deleteAndZero (currentPopup);
- currentPopupIndex = -1;
-
- if (result != 0)
- {
- topLevelIndexClicked = lastPopupIndex;
- break;
- }
- else if (indexToShowAgain >= 0)
- {
- menuBarItemsChanged (0);
- repaint();
- itemUnderMouse = indexToShowAgain;
-
- if (((unsigned int) itemUnderMouse) >= (unsigned int) menuNames.size())
- break;
- }
- else
- {
- break;
- }
- }
-
- Desktop::getInstance().removeGlobalMouseListener (this);
-
- inModalState = false;
- exitModalState (0);
-
- if (prevCompDeletionChecker != 0)
- {
- if (! prevCompDeletionChecker->hasBeenDeleted())
- prevFocused->grabKeyboardFocus();
-
- delete prevCompDeletionChecker;
- }
-
- int mx, my;
- getMouseXYRelative (mx, my);
- updateItemUnderMouse (mx, my);
- repaint();
-
- if (result != 0)
- {
- if (managerOfChosenCommand != 0)
- {
- ApplicationCommandTarget::InvocationInfo info (result);
- info.invocationMethod = ApplicationCommandTarget::InvocationInfo::fromMenu;
-
- managerOfChosenCommand->invoke (info, true);
- }
-
- postCommandMessage (result);
- }
- }
- }
-
- void MenuBarComponent::handleCommandMessage (int commandId)
- {
- if (model != 0)
- model->menuItemSelected (commandId, topLevelIndexClicked);
- }
-
- void MenuBarComponent::mouseEnter (const MouseEvent& e)
- {
- if (e.eventComponent == this)
- updateItemUnderMouse (e.x, e.y);
- }
-
- void MenuBarComponent::mouseExit (const MouseEvent& e)
- {
- if (e.eventComponent == this)
- updateItemUnderMouse (e.x, e.y);
- }
-
- void MenuBarComponent::mouseDown (const MouseEvent& e)
- {
- const MouseEvent e2 (e.getEventRelativeTo (this));
-
- if (currentPopupIndex < 0)
- {
- updateItemUnderMouse (e2.x, e2.y);
-
- currentPopupIndex = -2;
- showMenu (itemUnderMouse);
- }
- }
-
- void MenuBarComponent::mouseDrag (const MouseEvent& e)
- {
- const MouseEvent e2 (e.getEventRelativeTo (this));
-
- const int item = getItemAt (e2.x, e2.y);
-
- if (item >= 0)
- showMenu (item);
- }
-
- void MenuBarComponent::mouseUp (const MouseEvent& e)
- {
- const MouseEvent e2 (e.getEventRelativeTo (this));
-
- updateItemUnderMouse (e2.x, e2.y);
-
- if (itemUnderMouse < 0 && dynamic_cast <DummyMenuComponent*> (currentPopup) != 0)
- hideCurrentMenu();
- }
-
- void MenuBarComponent::mouseMove (const MouseEvent& e)
- {
- const MouseEvent e2 (e.getEventRelativeTo (this));
-
- if (lastMouseX != e2.x || lastMouseY != e2.y)
- {
- if (currentPopupIndex >= 0)
- {
- const int item = getItemAt (e2.x, e2.y);
-
- if (item >= 0)
- showMenu (item);
- }
- else
- {
- updateItemUnderMouse (e2.x, e2.y);
- }
-
- lastMouseX = e2.x;
- lastMouseY = e2.y;
- }
- }
-
- bool MenuBarComponent::keyPressed (const KeyPress& key)
- {
- bool used = false;
- const int numMenus = menuNames.size();
- const int currentIndex = jlimit (0, menuNames.size() - 1, currentPopupIndex);
-
- if (key.isKeyCode (KeyPress::leftKey))
- {
- showMenu ((currentIndex + numMenus - 1) % numMenus);
- used = true;
- }
- else if (key.isKeyCode (KeyPress::rightKey))
- {
- showMenu ((currentIndex + 1) % numMenus);
- used = true;
- }
-
- return used;
- }
-
- void MenuBarComponent::inputAttemptWhenModal()
- {
- hideCurrentMenu();
- }
-
- void MenuBarComponent::menuBarItemsChanged (MenuBarModel* /*menuBarModel*/)
- {
- StringArray newNames;
-
- if (model != 0)
- newNames = model->getMenuBarNames();
-
- if (newNames != menuNames)
- {
- menuNames = newNames;
- repaint();
- resized();
- }
- }
-
- void MenuBarComponent::menuCommandInvoked (MenuBarModel* /*menuBarModel*/,
- const ApplicationCommandTarget::InvocationInfo& info)
- {
- if (model == 0
- || (info.commandFlags & ApplicationCommandInfo::dontTriggerVisualFeedback) != 0)
- return;
-
- for (int i = 0; i < menuNames.size(); ++i)
- {
- const PopupMenu menu (model->getMenuForIndex (i, menuNames [i]));
-
- if (menu.containsCommandItem (info.commandID))
- {
- itemUnderMouse = i;
- repaintMenuItem (i);
- startTimer (200);
-
- break;
- }
- }
- }
-
- void MenuBarComponent::timerCallback()
- {
- stopTimer();
-
- int mx, my;
- getMouseXYRelative (mx, my);
- updateItemUnderMouse (mx, my);
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_MenuBarComponent.cpp *********/
-
- /********* Start of inlined file: juce_MenuBarModel.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- MenuBarModel::MenuBarModel() throw()
- : manager (0)
- {
- }
-
- MenuBarModel::~MenuBarModel()
- {
- setApplicationCommandManagerToWatch (0);
- }
-
- void MenuBarModel::menuItemsChanged()
- {
- triggerAsyncUpdate();
- }
-
- void MenuBarModel::setApplicationCommandManagerToWatch (ApplicationCommandManager* const newManager) throw()
- {
- if (manager != newManager)
- {
- if (manager != 0)
- manager->removeListener (this);
-
- manager = newManager;
-
- if (manager != 0)
- manager->addListener (this);
- }
- }
-
- void MenuBarModel::addListener (MenuBarModelListener* const newListener) throw()
- {
- jassert (newListener != 0);
- jassert (! listeners.contains (newListener)); // trying to add a listener to the list twice!
-
- if (newListener != 0)
- listeners.add (newListener);
- }
-
- void MenuBarModel::removeListener (MenuBarModelListener* const listenerToRemove) throw()
- {
- // Trying to remove a listener that isn't on the list!
- // If this assertion happens because this object is a dangling pointer, make sure you've not
- // deleted this menu model while it's still being used by something (e.g. by a MenuBarComponent)
- jassert (listeners.contains (listenerToRemove));
-
- listeners.removeValue (listenerToRemove);
- }
-
- void MenuBarModel::handleAsyncUpdate()
- {
- for (int i = listeners.size(); --i >= 0;)
- {
- ((MenuBarModelListener*) listeners.getUnchecked (i))->menuBarItemsChanged (this);
- i = jmin (i, listeners.size());
- }
- }
-
- void MenuBarModel::applicationCommandInvoked (const ApplicationCommandTarget::InvocationInfo& info)
- {
- for (int i = listeners.size(); --i >= 0;)
- {
- ((MenuBarModelListener*) listeners.getUnchecked (i))->menuCommandInvoked (this, info);
- i = jmin (i, listeners.size());
- }
- }
-
- void MenuBarModel::applicationCommandListChanged()
- {
- menuItemsChanged();
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_MenuBarModel.cpp *********/
-
- /********* Start of inlined file: juce_PopupMenu.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- static VoidArray activeMenuWindows;
-
- class MenuItemInfo
- {
- public:
-
- const int itemId;
- String text;
- const Colour textColour;
- const bool active, isSeparator, isTicked, usesColour;
- Image* image;
- PopupMenuCustomComponent* const customComp;
- PopupMenu* subMenu;
- ApplicationCommandManager* const commandManager;
-
- MenuItemInfo() throw()
- : itemId (0),
- active (true),
- isSeparator (true),
- isTicked (false),
- usesColour (false),
- image (0),
- customComp (0),
- subMenu (0),
- commandManager (0)
- {
- }
-
- MenuItemInfo (const int itemId_,
- const String& text_,
- const bool active_,
- const bool isTicked_,
- const Image* im,
- const Colour& textColour_,
- const bool usesColour_,
- PopupMenuCustomComponent* const customComp_,
- const PopupMenu* const subMenu_,
- ApplicationCommandManager* const commandManager_) throw()
- : itemId (itemId_),
- text (text_),
- textColour (textColour_),
- active (active_),
- isSeparator (false),
- isTicked (isTicked_),
- usesColour (usesColour_),
- image (0),
- customComp (customComp_),
- commandManager (commandManager_)
- {
- subMenu = (subMenu_ != 0) ? new PopupMenu (*subMenu_) : 0;
-
- if (customComp != 0)
- customComp->refCount_++;
-
- if (im != 0)
- image = im->createCopy();
-
- if (commandManager_ != 0 && itemId_ != 0)
- {
- String shortcutKey;
-
- Array <KeyPress> keyPresses (commandManager_->getKeyMappings()
- ->getKeyPressesAssignedToCommand (itemId_));
-
- for (int i = 0; i < keyPresses.size(); ++i)
- {
- const String key (keyPresses.getReference(i).getTextDescription());
-
- if (shortcutKey.isNotEmpty())
- shortcutKey << ", ";
-
- if (key.length() == 1)
- shortcutKey << "shortcut: '" << key << '\'';
- else
- shortcutKey << key;
- }
-
- shortcutKey = shortcutKey.trim();
-
- if (shortcutKey.isNotEmpty())
- text << "<end>" << shortcutKey;
- }
- }
-
- MenuItemInfo (const MenuItemInfo& other) throw()
- : itemId (other.itemId),
- text (other.text),
- textColour (other.textColour),
- active (other.active),
- isSeparator (other.isSeparator),
- isTicked (other.isTicked),
- usesColour (other.usesColour),
- customComp (other.customComp),
- commandManager (other.commandManager)
- {
- if (other.subMenu != 0)
- subMenu = new PopupMenu (*(other.subMenu));
- else
- subMenu = 0;
-
- if (other.image != 0)
- image = other.image->createCopy();
- else
- image = 0;
-
- if (customComp != 0)
- customComp->refCount_++;
- }
-
- ~MenuItemInfo() throw()
- {
- delete subMenu;
- delete image;
-
- if (customComp != 0 && --(customComp->refCount_) == 0)
- delete customComp;
- }
-
- bool canBeTriggered() const throw()
- {
- return active && ! (isSeparator || (subMenu != 0));
- }
-
- bool hasActiveSubMenu() const throw()
- {
- return active && (subMenu != 0);
- }
-
- juce_UseDebuggingNewOperator
-
- private:
- const MenuItemInfo& operator= (const MenuItemInfo&);
- };
-
- class MenuItemComponent : public Component
- {
- bool isHighlighted;
-
- public:
- MenuItemInfo itemInfo;
-
- MenuItemComponent (const MenuItemInfo& itemInfo_)
- : isHighlighted (false),
- itemInfo (itemInfo_)
- {
- if (itemInfo.customComp != 0)
- addAndMakeVisible (itemInfo.customComp);
- }
-
- ~MenuItemComponent()
- {
- if (itemInfo.customComp != 0)
- removeChildComponent (itemInfo.customComp);
- }
-
- void getIdealSize (int& idealWidth,
- int& idealHeight,
- const int standardItemHeight)
- {
- if (itemInfo.customComp != 0)
- {
- itemInfo.customComp->getIdealSize (idealWidth, idealHeight);
- }
- else
- {
- getLookAndFeel().getIdealPopupMenuItemSize (itemInfo.text,
- itemInfo.isSeparator,
- standardItemHeight,
- idealWidth,
- idealHeight);
- }
- }
-
- void paint (Graphics& g)
- {
- if (itemInfo.customComp == 0)
- {
- String mainText (itemInfo.text);
- String endText;
- const int endIndex = mainText.indexOf (T("<end>"));
-
- if (endIndex >= 0)
- {
- endText = mainText.substring (endIndex + 5).trim();
- mainText = mainText.substring (0, endIndex);
- }
-
- getLookAndFeel()
- .drawPopupMenuItem (g, getWidth(), getHeight(),
- itemInfo.isSeparator,
- itemInfo.active,
- isHighlighted,
- itemInfo.isTicked,
- itemInfo.subMenu != 0,
- mainText, endText,
- itemInfo.image,
- itemInfo.usesColour ? &(itemInfo.textColour) : 0);
- }
- }
-
- void resized()
- {
- if (getNumChildComponents() > 0)
- getChildComponent(0)->setBounds (2, 0, getWidth() - 4, getHeight());
- }
-
- void setHighlighted (bool shouldBeHighlighted)
- {
- shouldBeHighlighted = shouldBeHighlighted && itemInfo.active;
-
- if (isHighlighted != shouldBeHighlighted)
- {
- isHighlighted = shouldBeHighlighted;
-
- if (itemInfo.customComp != 0)
- {
- itemInfo.customComp->isHighlighted = shouldBeHighlighted;
- itemInfo.customComp->repaint();
- }
-
- repaint();
- }
- }
-
- private:
- MenuItemComponent (const MenuItemComponent&);
- const MenuItemComponent& operator= (const MenuItemComponent&);
- };
-
- static const int scrollZone = 24;
- static const int borderSize = 2;
- static const int timerInterval = 50;
- static const int dismissCommandId = 0x6287345f;
-
- static bool wasHiddenBecauseOfAppChange = false;
-
- class PopupMenuWindow : public Component,
- private Timer
- {
- public:
-
- PopupMenuWindow() throw()
- : Component (T("menu")),
- owner (0),
- currentChild (0),
- activeSubMenu (0),
- menuBarComponent (0),
- managerOfChosenCommand (0),
- componentAttachedTo (0),
- attachedCompWatcher (0),
- lastMouseX (0),
- lastMouseY (0),
- minimumWidth (0),
- maximumNumColumns (7),
- standardItemHeight (0),
- isOver (false),
- hasBeenOver (false),
- isDown (false),
- needsToScroll (false),
- hideOnExit (false),
- disableMouseMoves (false),
- hasAnyJuceCompHadFocus (false),
- numColumns (0),
- contentHeight (0),
- childYOffset (0),
- timeEnteredCurrentChildComp (0),
- scrollAcceleration (1.0)
- {
- menuCreationTime = lastFocused = lastScroll = Time::getMillisecondCounter();
- setWantsKeyboardFocus (true);
-
- setOpaque (true);
- setAlwaysOnTop (true);
-
- Desktop::getInstance().addGlobalMouseListener (this);
-
- activeMenuWindows.add (this);
- }
-
- ~PopupMenuWindow()
- {
- activeMenuWindows.removeValue (this);
-
- Desktop::getInstance().removeGlobalMouseListener (this);
-
- jassert (activeSubMenu == 0 || activeSubMenu->isValidComponent());
- delete activeSubMenu;
-
- deleteAllChildren();
- delete attachedCompWatcher;
- }
-
- static PopupMenuWindow* create (const PopupMenu& menu,
- const bool dismissOnMouseUp,
- PopupMenuWindow* const owner_,
- const int minX, const int maxX,
- const int minY, const int maxY,
- const int minimumWidth,
- const int maximumNumColumns,
- const int standardItemHeight,
- const bool alignToRectangle,
- const int itemIdThatMustBeVisible,
- Component* const menuBarComponent,
- ApplicationCommandManager** managerOfChosenCommand,
- Component* const componentAttachedTo) throw()
- {
- if (menu.items.size() > 0)
- {
- int totalItems = 0;
-
- PopupMenuWindow* const mw = new PopupMenuWindow();
- mw->setLookAndFeel (menu.lookAndFeel);
- mw->setWantsKeyboardFocus (false);
- mw->minimumWidth = minimumWidth;
- mw->maximumNumColumns = maximumNumColumns;
- mw->standardItemHeight = standardItemHeight;
- mw->dismissOnMouseUp = dismissOnMouseUp;
-
- for (int i = 0; i < menu.items.size(); ++i)
- {
- MenuItemInfo* const item = (MenuItemInfo*) menu.items.getUnchecked(i);
-
- mw->addItem (*item);
- ++totalItems;
- }
-
- if (totalItems == 0)
- {
- delete mw;
- }
- else
- {
- mw->owner = owner_;
- mw->menuBarComponent = menuBarComponent;
- mw->managerOfChosenCommand = managerOfChosenCommand;
- mw->componentAttachedTo = componentAttachedTo;
- delete mw->attachedCompWatcher;
- mw->attachedCompWatcher = componentAttachedTo != 0 ? new ComponentDeletionWatcher (componentAttachedTo) : 0;
-
- mw->calculateWindowPos (minX, maxX, minY, maxY, alignToRectangle);
- mw->setTopLeftPosition (mw->windowPos.getX(),
- mw->windowPos.getY());
- mw->updateYPositions();
-
- if (itemIdThatMustBeVisible != 0)
- {
- const int y = minY - mw->windowPos.getY();
- mw->ensureItemIsVisible (itemIdThatMustBeVisible,
- (((unsigned int) y) < (unsigned int) mw->windowPos.getHeight()) ? y : -1);
- }
-
- mw->resizeToBestWindowPos();
- mw->addToDesktop (ComponentPeer::windowIsTemporary
- | mw->getLookAndFeel().getMenuWindowFlags());
-
- return mw;
- }
- }
-
- return 0;
- }
-
- void paint (Graphics& g)
- {
- getLookAndFeel().drawPopupMenuBackground (g, getWidth(), getHeight());
- }
-
- void paintOverChildren (Graphics& g)
- {
- if (isScrolling())
- {
- LookAndFeel& lf = getLookAndFeel();
-
- if (isScrollZoneActive (false))
- lf.drawPopupMenuUpDownArrow (g, getWidth(), scrollZone, true);
-
- if (isScrollZoneActive (true))
- {
- g.setOrigin (0, getHeight() - scrollZone);
- lf.drawPopupMenuUpDownArrow (g, getWidth(), scrollZone, false);
- }
- }
- }
-
- bool isScrollZoneActive (bool bottomOne) const
- {
- return isScrolling()
- && (bottomOne
- ? childYOffset < contentHeight - windowPos.getHeight()
- : childYOffset > 0);
- }
-
- void addItem (const MenuItemInfo& item) throw()
- {
- MenuItemComponent* const mic = new MenuItemComponent (item);
- addAndMakeVisible (mic);
-
- int itemW = 80;
- int itemH = 16;
- mic->getIdealSize (itemW, itemH, standardItemHeight);
- mic->setSize (itemW, jlimit (10, 600, itemH));
- mic->addMouseListener (this, false);
- }
-
- // hide this and all sub-comps
- void hide (const MenuItemInfo* const item) throw()
- {
- if (isVisible())
- {
- jassert (activeSubMenu == 0 || activeSubMenu->isValidComponent());
-
- deleteAndZero (activeSubMenu);
- currentChild = 0;
-
- exitModalState (item != 0 ? item->itemId : 0);
- setVisible (false);
-
- if (item != 0
- && item->commandManager != 0
- && item->itemId != 0)
- {
- *managerOfChosenCommand = item->commandManager;
- }
- }
- }
-
- void dismissMenu (const MenuItemInfo* const item) throw()
- {
- if (owner != 0)
- {
- owner->dismissMenu (item);
- }
- else
- {
- if (item != 0)
- {
- // need a copy of this on the stack as the one passed in will get deleted during this call
- const MenuItemInfo mi (*item);
- hide (&mi);
- }
- else
- {
- hide (0);
- }
- }
- }
-
- void mouseMove (const MouseEvent&)
- {
- timerCallback();
- }
-
- void mouseDown (const MouseEvent&)
- {
- timerCallback();
- }
-
- void mouseDrag (const MouseEvent&)
- {
- timerCallback();
- }
-
- void mouseUp (const MouseEvent&)
- {
- timerCallback();
- }
-
- void mouseWheelMove (const MouseEvent&, float /*amountX*/, float amountY)
- {
- alterChildYPos (roundFloatToInt (-10.0f * amountY * scrollZone));
- lastMouseX = -1;
- }
-
- bool keyPressed (const KeyPress& key)
- {
- if (key.isKeyCode (KeyPress::downKey))
- {
- selectNextItem (1);
- }
- else if (key.isKeyCode (KeyPress::upKey))
- {
- selectNextItem (-1);
- }
- else if (key.isKeyCode (KeyPress::leftKey))
- {
- PopupMenuWindow* parentWindow = owner;
-
- if (parentWindow != 0)
- {
- MenuItemComponent* currentChildOfParent
- = (parentWindow != 0) ? parentWindow->currentChild : 0;
-
- hide (0);
-
- if (parentWindow->isValidComponent())
- parentWindow->setCurrentlyHighlightedChild (currentChildOfParent);
-
- disableTimerUntilMouseMoves();
- }
- else if (menuBarComponent != 0)
- {
- menuBarComponent->keyPressed (key);
- }
- }
- else if (key.isKeyCode (KeyPress::rightKey))
- {
- disableTimerUntilMouseMoves();
-
- if (showSubMenuFor (currentChild))
- {
- jassert (activeSubMenu == 0 || activeSubMenu->isValidComponent());
-
- if (activeSubMenu != 0 && activeSubMenu->isVisible())
- activeSubMenu->selectNextItem (1);
- }
- else if (menuBarComponent != 0)
- {
- menuBarComponent->keyPressed (key);
- }
- }
- else if (key.isKeyCode (KeyPress::returnKey))
- {
- triggerCurrentlyHighlightedItem();
- }
- else if (key.isKeyCode (KeyPress::escapeKey))
- {
- dismissMenu (0);
- }
- else
- {
- return false;
- }
-
- return true;
- }
-
- void inputAttemptWhenModal()
- {
- timerCallback();
-
- if (! isOverAnyMenu())
- {
- if (componentAttachedTo != 0 && ! attachedCompWatcher->hasBeenDeleted())
- {
- // we want to dismiss the menu, but if we do it synchronously, then
- // the mouse-click will be allowed to pass through. That's good, except
- // when the user clicks on the button that orginally popped the menu up,
- // as they'll expect the menu to go away, and in fact it'll just
- // come back. So only dismiss synchronously if they're not on the original
- // comp that we're attached to.
- int mx, my;
- componentAttachedTo->getMouseXYRelative (mx, my);
-
- if (componentAttachedTo->reallyContains (mx, my, true))
- {
- postCommandMessage (dismissCommandId); // dismiss asynchrounously
- return;
- }
- }
-
- dismissMenu (0);
- }
- }
-
- void handleCommandMessage (int commandId)
- {
- Component::handleCommandMessage (commandId);
-
- if (commandId == dismissCommandId)
- dismissMenu (0);
- }
-
- void timerCallback()
- {
- if (! isVisible())
- return;
-
- if (attachedCompWatcher != 0 && attachedCompWatcher->hasBeenDeleted())
- {
- dismissMenu (0);
- return;
- }
-
- PopupMenuWindow* currentlyModalWindow = dynamic_cast <PopupMenuWindow*> (Component::getCurrentlyModalComponent());
-
- if (currentlyModalWindow != 0 && ! treeContains (currentlyModalWindow))
- return;
-
- startTimer (timerInterval); // do this in case it was called from a mouse
- // move rather than a real timer callback
-
- int mx, my;
- Desktop::getMousePosition (mx, my);
-
- int x = mx, y = my;
- globalPositionToRelative (x, y);
-
- const uint32 now = Time::getMillisecondCounter();
-
- if (now > timeEnteredCurrentChildComp + 100
- && reallyContains (x, y, true)
- && currentChild->isValidComponent()
- && (! disableMouseMoves)
- && ! (activeSubMenu != 0 && activeSubMenu->isVisible()))
- {
- showSubMenuFor (currentChild);
- }
-
- if (mx != lastMouseX || my != lastMouseY || now > lastMouseMoveTime + 350)
- {
- highlightItemUnderMouse (mx, my, x, y);
- }
-
- bool overScrollArea = false;
-
- if (isScrolling()
- && (isOver || (isDown && ((unsigned int) x) < (unsigned int) getWidth()))
- && ((isScrollZoneActive (false) && y < scrollZone)
- || (isScrollZoneActive (true) && y > getHeight() - scrollZone)))
- {
- if (now > lastScroll + 20)
- {
- scrollAcceleration = jmin (4.0, scrollAcceleration * 1.04);
- int amount = 0;
-
- for (int i = 0; i < getNumChildComponents() && amount == 0; ++i)
- amount = ((int) scrollAcceleration) * getChildComponent (i)->getHeight();
-
- alterChildYPos (y < scrollZone ? -amount : amount);
-
- lastScroll = now;
- }
-
- overScrollArea = true;
- lastMouseX = -1; // trigger a mouse-move
- }
- else
- {
- scrollAcceleration = 1.0;
- }
-
- const bool wasDown = isDown;
- bool isOverAny = isOverAnyMenu();
-
- if (hideOnExit && hasBeenOver && (! isOverAny) && activeSubMenu != 0)
- {
- activeSubMenu->updateMouseOverStatus (mx, my);
- isOverAny = isOverAnyMenu();
- }
-
- if (hideOnExit && hasBeenOver && ! isOverAny)
- {
- hide (0);
- }
- else
- {
- isDown = hasBeenOver
- && (ModifierKeys::getCurrentModifiers().isAnyMouseButtonDown()
- || ModifierKeys::getCurrentModifiersRealtime().isAnyMouseButtonDown());
-
- bool anyFocused = Process::isForegroundProcess();
-
- if (anyFocused && Component::getCurrentlyFocusedComponent() == 0)
- {
- // because no component at all may have focus, our test here will
- // only be triggered when something has focus and then loses it.
- anyFocused = ! hasAnyJuceCompHadFocus;
-
- for (int i = ComponentPeer::getNumPeers(); --i >= 0;)
- {
- if (ComponentPeer::getPeer (i)->isFocused())
- {
- anyFocused = true;
- hasAnyJuceCompHadFocus = true;
- break;
- }
- }
- }
-
- if (! anyFocused)
- {
- if (now > lastFocused + 10)
- {
- wasHiddenBecauseOfAppChange = true;
- dismissMenu (0);
-
- return; // may have been deleted by the previous call..
- }
- }
- else if (wasDown && now > menuCreationTime + 250
- && ! (isDown || overScrollArea))
- {
- isOver = reallyContains (x, y, true);
-
- if (isOver)
- {
- triggerCurrentlyHighlightedItem();
- }
- else if ((hasBeenOver || ! dismissOnMouseUp) && ! isOverAny)
- {
- dismissMenu (0);
- }
-
- return; // may have been deleted by the previous calls..
- }
- else
- {
- lastFocused = now;
- }
- }
- }
-
- juce_UseDebuggingNewOperator
-
- private:
- PopupMenuWindow* owner;
- MenuItemComponent* currentChild;
- PopupMenuWindow* activeSubMenu;
- Component* menuBarComponent;
- ApplicationCommandManager** managerOfChosenCommand;
- Component* componentAttachedTo;
- ComponentDeletionWatcher* attachedCompWatcher;
- Rectangle windowPos;
- int lastMouseX, lastMouseY;
- int minimumWidth, maximumNumColumns, standardItemHeight;
- bool isOver, hasBeenOver, isDown, needsToScroll;
- bool dismissOnMouseUp, hideOnExit, disableMouseMoves, hasAnyJuceCompHadFocus;
- int numColumns, contentHeight, childYOffset;
- Array <int> columnWidths;
- uint32 menuCreationTime, lastFocused, lastScroll, lastMouseMoveTime, timeEnteredCurrentChildComp;
- double scrollAcceleration;
-
- bool overlaps (const Rectangle& r) const throw()
- {
- return r.intersects (getBounds())
- || (owner != 0 && owner->overlaps (r));
- }
-
- bool isOverAnyMenu() const throw()
- {
- return (owner != 0) ? owner->isOverAnyMenu()
- : isOverChildren();
- }
-
- bool isOverChildren() const throw()
- {
- jassert (activeSubMenu == 0 || activeSubMenu->isValidComponent());
-
- return isVisible()
- && (isOver || (activeSubMenu != 0 && activeSubMenu->isOverChildren()));
- }
-
- void updateMouseOverStatus (const int mx, const int my) throw()
- {
- int rx = mx, ry = my;
- globalPositionToRelative (rx, ry);
- isOver = reallyContains (rx, ry, true);
-
- if (activeSubMenu != 0)
- activeSubMenu->updateMouseOverStatus (mx, my);
- }
-
- bool treeContains (const PopupMenuWindow* const window) const throw()
- {
- const PopupMenuWindow* mw = this;
-
- while (mw->owner != 0)
- mw = mw->owner;
-
- while (mw != 0)
- {
- if (mw == window)
- return true;
-
- mw = mw->activeSubMenu;
- }
-
- return false;
- }
-
- void calculateWindowPos (const int minX, const int maxX,
- const int minY, const int maxY,
- const bool alignToRectangle)
- {
- const Rectangle mon (Desktop::getInstance()
- .getMonitorAreaContaining ((minX + maxX) / 2,
- (minY + maxY) / 2,
- true));
-
- int x, y, widthToUse, heightToUse;
- layoutMenuItems (mon.getWidth() - 24, widthToUse, heightToUse);
-
- if (alignToRectangle)
- {
- x = minX;
-
- const int spaceUnder = mon.getHeight() - (maxY - mon.getY());
- const int spaceOver = minY - mon.getY();
-
- if (heightToUse < spaceUnder - 30 || spaceUnder >= spaceOver)
- y = maxY;
- else
- y = minY - heightToUse;
- }
- else
- {
- bool tendTowardsRight = (minX + maxX) / 2 < mon.getCentreX();
-
- if (owner != 0)
- {
- if (owner->owner != 0)
- {
- const bool ownerGoingRight = (owner->getX() + owner->getWidth() / 2
- > owner->owner->getX() + owner->owner->getWidth() / 2);
-
- if (ownerGoingRight && maxX + widthToUse < mon.getRight() - 4)
- tendTowardsRight = true;
- else if ((! ownerGoingRight) && minX > widthToUse + 4)
- tendTowardsRight = false;
- }
- else if (maxX + widthToUse < mon.getRight() - 32)
- {
- tendTowardsRight = true;
- }
- }
-
- const int biggestSpace = jmax (mon.getRight() - maxX,
- minX - mon.getX()) - 32;
-
- if (biggestSpace < widthToUse)
- {
- layoutMenuItems (biggestSpace + (maxX - minX) / 3, widthToUse, heightToUse);
-
- if (numColumns > 1)
- layoutMenuItems (biggestSpace - 4, widthToUse, heightToUse);
-
- tendTowardsRight = (mon.getRight() - maxX) >= (minX - mon.getX());
- }
-
- if (tendTowardsRight)
- x = jmin (mon.getRight() - widthToUse - 4, maxX);
- else
- x = jmax (mon.getX() + 4, minX - widthToUse);
-
- y = minY;
- if ((minY + maxY) / 2 > mon.getCentreY())
- y = jmax (mon.getY(), maxY - heightToUse);
- }
-
- x = jlimit (mon.getX() + 1, mon.getRight() - (widthToUse + 6), x);
- y = jlimit (mon.getY() + 1, mon.getBottom() - (heightToUse + 6), y);
-
- windowPos.setBounds (x, y, widthToUse, heightToUse);
-
- // sets this flag if it's big enough to obscure any of its parent menus
- hideOnExit = (owner != 0)
- && owner->windowPos.intersects (windowPos.expanded (-4, -4));
- }
-
- void layoutMenuItems (const int maxMenuW, int& width, int& height)
- {
- numColumns = 0;
- contentHeight = 0;
- const int maxMenuH = getParentHeight() - 24;
- int totalW;
-
- do
- {
- ++numColumns;
- totalW = workOutBestSize (numColumns, maxMenuW);
-
- if (totalW > maxMenuW)
- {
- numColumns = jmax (1, numColumns - 1);
- totalW = workOutBestSize (numColumns, maxMenuW); // to update col widths
- break;
- }
- else if (totalW > maxMenuW / 2 || contentHeight < maxMenuH)
- {
- break;
- }
-
- } while (numColumns < maximumNumColumns);
-
- const int actualH = jmin (contentHeight, maxMenuH);
-
- needsToScroll = contentHeight > actualH;
-
- width = updateYPositions();
- height = actualH + borderSize * 2;
- }
-
- int workOutBestSize (const int numColumns, const int maxMenuW)
- {
- int totalW = 0;
- contentHeight = 0;
- int childNum = 0;
-
- for (int col = 0; col < numColumns; ++col)
- {
- int i, colW = 50, colH = 0;
-
- const int numChildren = jmin (getNumChildComponents() - childNum,
- (getNumChildComponents() + numColumns - 1) / numColumns);
-
- for (i = numChildren; --i >= 0;)
- {
- colW = jmax (colW, getChildComponent (childNum + i)->getWidth());
- colH += getChildComponent (childNum + i)->getHeight();
- }
-
- colW = jmin (maxMenuW / jmax (1, numColumns - 2), colW + borderSize * 2);
-
- columnWidths.set (col, colW);
- totalW += colW;
- contentHeight = jmax (contentHeight, colH);
-
- childNum += numChildren;
- }
-
- if (totalW < minimumWidth)
- {
- totalW = minimumWidth;
-
- for (int col = 0; col < numColumns; ++col)
- columnWidths.set (0, totalW / numColumns);
- }
-
- return totalW;
- }
-
- void ensureItemIsVisible (const int itemId, int wantedY)
- {
- jassert (itemId != 0)
-
- for (int i = getNumChildComponents(); --i >= 0;)
- {
- MenuItemComponent* const m = (MenuItemComponent*) getChildComponent (i);
-
- if (m != 0
- && m->itemInfo.itemId == itemId
- && windowPos.getHeight() > scrollZone * 4)
- {
- const int currentY = m->getY();
-
- if (wantedY > 0 || currentY < 0 || m->getBottom() > windowPos.getHeight())
- {
- if (wantedY < 0)
- wantedY = jlimit (scrollZone,
- jmax (scrollZone, windowPos.getHeight() - (scrollZone + m->getHeight())),
- currentY);
-
- const Rectangle mon (Desktop::getInstance()
- .getMonitorAreaContaining (windowPos.getX(),
- windowPos.getY(),
- true));
-
- int deltaY = wantedY - currentY;
-
- const int newY = jlimit (mon.getY(),
- mon.getBottom() - windowPos.getHeight(),
- windowPos.getY() + deltaY);
-
- deltaY -= newY - windowPos.getY();
-
- childYOffset -= deltaY;
- windowPos.setPosition (windowPos.getX(), newY);
-
- updateYPositions();
- }
-
- break;
- }
- }
- }
-
- void resizeToBestWindowPos()
- {
- Rectangle r (windowPos);
-
- if (childYOffset < 0)
- {
- r.setBounds (r.getX(), r.getY() - childYOffset,
- r.getWidth(), r.getHeight() + childYOffset);
- }
- else if (childYOffset > 0)
- {
- const int spaceAtBottom = r.getHeight() - (contentHeight - childYOffset);
-
- if (spaceAtBottom > 0)
- r.setSize (r.getWidth(), r.getHeight() - spaceAtBottom);
- }
-
- setBounds (r);
- updateYPositions();
- }
-
- void alterChildYPos (const int delta)
- {
- if (isScrolling())
- {
- childYOffset += delta;
-
- if (delta < 0)
- {
- childYOffset = jmax (childYOffset, 0);
- }
- else if (delta > 0)
- {
- childYOffset = jmin (childYOffset,
- contentHeight - windowPos.getHeight() + borderSize);
- }
-
- updateYPositions();
- }
- else
- {
- childYOffset = 0;
- }
-
- resizeToBestWindowPos();
- repaint();
- }
-
- int updateYPositions()
- {
- int x = 0;
- int childNum = 0;
-
- for (int col = 0; col < numColumns; ++col)
- {
- const int numChildren = jmin (getNumChildComponents() - childNum,
- (getNumChildComponents() + numColumns - 1) / numColumns);
-
- const int colW = columnWidths [col];
-
- int y = borderSize - (childYOffset + (getY() - windowPos.getY()));
-
- for (int i = 0; i < numChildren; ++i)
- {
- Component* const c = getChildComponent (childNum + i);
- c->setBounds (x, y, colW, c->getHeight());
- y += c->getHeight();
- }
-
- x += colW;
- childNum += numChildren;
- }
-
- return x;
- }
-
- bool isScrolling() const throw()
- {
- return childYOffset != 0 || needsToScroll;
- }
-
- void setCurrentlyHighlightedChild (MenuItemComponent* const child) throw()
- {
- if (currentChild->isValidComponent())
- currentChild->setHighlighted (false);
-
- currentChild = child;
-
- if (currentChild != 0)
- {
- currentChild->setHighlighted (true);
- timeEnteredCurrentChildComp = Time::getApproximateMillisecondCounter();
- }
- }
-
- bool showSubMenuFor (MenuItemComponent* const childComp)
- {
- jassert (activeSubMenu == 0 || activeSubMenu->isValidComponent());
- deleteAndZero (activeSubMenu);
-
- if (childComp->isValidComponent() && childComp->itemInfo.hasActiveSubMenu())
- {
- int left = 0, top = 0;
- childComp->relativePositionToGlobal (left, top);
- int right = childComp->getWidth(), bottom = childComp->getHeight();
- childComp->relativePositionToGlobal (right, bottom);
-
- activeSubMenu = PopupMenuWindow::create (*(childComp->itemInfo.subMenu),
- dismissOnMouseUp,
- this,
- left, right, top, bottom,
- 0, maximumNumColumns,
- standardItemHeight,
- false, 0, menuBarComponent,
- managerOfChosenCommand,
- componentAttachedTo);
-
- if (activeSubMenu != 0)
- {
- activeSubMenu->setVisible (true);
- activeSubMenu->enterModalState (false);
- activeSubMenu->toFront (false);
- return true;
- }
- }
-
- return false;
- }
-
- void highlightItemUnderMouse (const int mx, const int my, const int x, const int y)
- {
- isOver = reallyContains (x, y, true);
-
- if (isOver)
- hasBeenOver = true;
-
- if (abs (lastMouseX - mx) > 2 || abs (lastMouseY - my) > 2)
- {
- lastMouseMoveTime = Time::getApproximateMillisecondCounter();
-
- if (disableMouseMoves && isOver)
- disableMouseMoves = false;
- }
-
- if (disableMouseMoves)
- return;
-
- bool isMovingTowardsMenu = false;
-
- jassert (activeSubMenu == 0 || activeSubMenu->isValidComponent())
-
- if (isOver && (activeSubMenu != 0) && (mx != lastMouseX || my != lastMouseY))
- {
- // try to intelligently guess whether the user is moving the mouse towards a currently-open
- // submenu. To do this, look at whether the mouse stays inside a triangular region that
- // extends from the last mouse pos to the submenu's rectangle..
-
- float subX = (float) activeSubMenu->getScreenX();
-
- if (activeSubMenu->getX() > getX())
- {
- lastMouseX -= 2; // to enlarge the triangle a bit, in case the mouse only moves a couple of pixels
- }
- else
- {
- lastMouseX += 2;
- subX += activeSubMenu->getWidth();
- }
-
- Path areaTowardsSubMenu;
- areaTowardsSubMenu.addTriangle ((float) lastMouseX,
- (float) lastMouseY,
- subX,
- (float) activeSubMenu->getScreenY(),
- subX,
- (float) (activeSubMenu->getScreenY() + activeSubMenu->getHeight()));
-
- isMovingTowardsMenu = areaTowardsSubMenu.contains ((float) mx, (float) my);
- }
-
- lastMouseX = mx;
- lastMouseY = my;
-
- if (! isMovingTowardsMenu)
- {
- Component* c = getComponentAt (x, y);
- if (c == this)
- c = 0;
-
- MenuItemComponent* mic = dynamic_cast <MenuItemComponent*> (c);
-
- if (mic == 0 && c != 0)
- mic = c->findParentComponentOfClass ((MenuItemComponent*) 0);
-
- if (mic != currentChild
- && (isOver || (activeSubMenu == 0) || ! activeSubMenu->isVisible()))
- {
- if (isOver && (c != 0) && (activeSubMenu != 0))
- {
- activeSubMenu->hide (0);
- }
-
- if (! isOver)
- mic = 0;
-
- setCurrentlyHighlightedChild (mic);
- }
- }
- }
-
- void triggerCurrentlyHighlightedItem()
- {
- if (currentChild->isValidComponent()
- && currentChild->itemInfo.canBeTriggered()
- && (currentChild->itemInfo.customComp == 0
- || currentChild->itemInfo.customComp->isTriggeredAutomatically))
- {
- dismissMenu (¤tChild->itemInfo);
- }
- }
-
- void selectNextItem (const int delta)
- {
- disableTimerUntilMouseMoves();
- MenuItemComponent* mic = 0;
- bool wasLastOne = (currentChild == 0);
- const int numItems = getNumChildComponents();
-
- for (int i = 0; i < numItems + 1; ++i)
- {
- int index = (delta > 0) ? i : (numItems - 1 - i);
- index = (index + numItems) % numItems;
-
- mic = dynamic_cast <MenuItemComponent*> (getChildComponent (index));
-
- if (mic != 0 && (mic->itemInfo.canBeTriggered() || mic->itemInfo.hasActiveSubMenu())
- && wasLastOne)
- break;
-
- if (mic == currentChild)
- wasLastOne = true;
- }
-
- setCurrentlyHighlightedChild (mic);
- }
-
- void disableTimerUntilMouseMoves() throw()
- {
- disableMouseMoves = true;
-
- if (owner != 0)
- owner->disableTimerUntilMouseMoves();
- }
-
- PopupMenuWindow (const PopupMenuWindow&);
- const PopupMenuWindow& operator= (const PopupMenuWindow&);
- };
-
- PopupMenu::PopupMenu() throw()
- : items (8),
- lookAndFeel (0),
- separatorPending (false)
- {
- }
-
- PopupMenu::PopupMenu (const PopupMenu& other) throw()
- : items (8),
- lookAndFeel (other.lookAndFeel),
- separatorPending (false)
- {
- items.ensureStorageAllocated (other.items.size());
-
- for (int i = 0; i < other.items.size(); ++i)
- items.add (new MenuItemInfo (*(const MenuItemInfo*) other.items.getUnchecked(i)));
- }
-
- const PopupMenu& PopupMenu::operator= (const PopupMenu& other) throw()
- {
- if (this != &other)
- {
- lookAndFeel = other.lookAndFeel;
-
- clear();
- items.ensureStorageAllocated (other.items.size());
-
- for (int i = 0; i < other.items.size(); ++i)
- items.add (new MenuItemInfo (*(const MenuItemInfo*) other.items.getUnchecked(i)));
- }
-
- return *this;
- }
-
- PopupMenu::~PopupMenu() throw()
- {
- clear();
- }
-
- void PopupMenu::clear() throw()
- {
- for (int i = items.size(); --i >= 0;)
- {
- MenuItemInfo* const mi = (MenuItemInfo*) items.getUnchecked(i);
- delete mi;
- }
-
- items.clear();
- separatorPending = false;
- }
-
- void PopupMenu::addSeparatorIfPending()
- {
- if (separatorPending)
- {
- separatorPending = false;
-
- if (items.size() > 0)
- items.add (new MenuItemInfo());
- }
- }
-
- void PopupMenu::addItem (const int itemResultId,
- const String& itemText,
- const bool isActive,
- const bool isTicked,
- const Image* const iconToUse) throw()
- {
- jassert (itemResultId != 0); // 0 is used as a return value to indicate that the user
- // didn't pick anything, so you shouldn't use it as the id
- // for an item..
-
- addSeparatorIfPending();
-
- items.add (new MenuItemInfo (itemResultId,
- itemText,
- isActive,
- isTicked,
- iconToUse,
- Colours::black,
- false,
- 0, 0, 0));
- }
-
- void PopupMenu::addCommandItem (ApplicationCommandManager* commandManager,
- const int commandID,
- const String& displayName) throw()
- {
- jassert (commandManager != 0 && commandID != 0);
-
- const ApplicationCommandInfo* const registeredInfo = commandManager->getCommandForID (commandID);
-
- if (registeredInfo != 0)
- {
- ApplicationCommandInfo info (*registeredInfo);
- ApplicationCommandTarget* const target = commandManager->getTargetForCommand (commandID, info);
-
- addSeparatorIfPending();
-
- items.add (new MenuItemInfo (commandID,
- displayName.isNotEmpty() ? displayName
- : info.shortName,
- target != 0 && (info.flags & ApplicationCommandInfo::isDisabled) == 0,
- (info.flags & ApplicationCommandInfo::isTicked) != 0,
- 0,
- Colours::black,
- false,
- 0, 0,
- commandManager));
- }
- }
-
- void PopupMenu::addColouredItem (const int itemResultId,
- const String& itemText,
- const Colour& itemTextColour,
- const bool isActive,
- const bool isTicked,
- const Image* const iconToUse) throw()
- {
- jassert (itemResultId != 0); // 0 is used as a return value to indicate that the user
- // didn't pick anything, so you shouldn't use it as the id
- // for an item..
-
- addSeparatorIfPending();
-
- items.add (new MenuItemInfo (itemResultId,
- itemText,
- isActive,
- isTicked,
- iconToUse,
- itemTextColour,
- true,
- 0, 0, 0));
- }
-
- void PopupMenu::addCustomItem (const int itemResultId,
- PopupMenuCustomComponent* const customComponent) throw()
- {
- jassert (itemResultId != 0); // 0 is used as a return value to indicate that the user
- // didn't pick anything, so you shouldn't use it as the id
- // for an item..
-
- addSeparatorIfPending();
-
- items.add (new MenuItemInfo (itemResultId,
- String::empty,
- true,
- false,
- 0,
- Colours::black,
- false,
- customComponent,
- 0, 0));
- }
-
- class NormalComponentWrapper : public PopupMenuCustomComponent
- {
- public:
- NormalComponentWrapper (Component* const comp,
- const int w, const int h,
- const bool triggerMenuItemAutomaticallyWhenClicked)
- : PopupMenuCustomComponent (triggerMenuItemAutomaticallyWhenClicked),
- width (w),
- height (h)
- {
- addAndMakeVisible (comp);
- }
-
- ~NormalComponentWrapper() {}
-
- void getIdealSize (int& idealWidth, int& idealHeight)
- {
- idealWidth = width;
- idealHeight = height;
- }
-
- void resized()
- {
- if (getChildComponent(0) != 0)
- getChildComponent(0)->setBounds (0, 0, getWidth(), getHeight());
- }
-
- juce_UseDebuggingNewOperator
-
- private:
- const int width, height;
-
- NormalComponentWrapper (const NormalComponentWrapper&);
- const NormalComponentWrapper& operator= (const NormalComponentWrapper&);
- };
-
- void PopupMenu::addCustomItem (const int itemResultId,
- Component* customComponent,
- int idealWidth, int idealHeight,
- const bool triggerMenuItemAutomaticallyWhenClicked) throw()
- {
- addCustomItem (itemResultId,
- new NormalComponentWrapper (customComponent,
- idealWidth, idealHeight,
- triggerMenuItemAutomaticallyWhenClicked));
- }
-
- void PopupMenu::addSubMenu (const String& subMenuName,
- const PopupMenu& subMenu,
- const bool isActive,
- Image* const iconToUse) throw()
- {
- addSeparatorIfPending();
-
- items.add (new MenuItemInfo (0,
- subMenuName,
- isActive && (subMenu.getNumItems() > 0),
- false,
- iconToUse,
- Colours::black,
- false,
- 0,
- &subMenu,
- 0));
- }
-
- void PopupMenu::addSeparator() throw()
- {
- separatorPending = true;
- }
-
- class HeaderItemComponent : public PopupMenuCustomComponent
- {
- public:
- HeaderItemComponent (const String& name)
- : PopupMenuCustomComponent (false)
- {
- setName (name);
- }
-
- ~HeaderItemComponent()
- {
- }
-
- void paint (Graphics& g)
- {
- Font f (getLookAndFeel().getPopupMenuFont());
- f.setBold (true);
- g.setFont (f);
-
- g.setColour (findColour (PopupMenu::headerTextColourId));
-
- g.drawFittedText (getName(),
- 12, 0, getWidth() - 16, proportionOfHeight (0.8f),
- Justification::bottomLeft, 1);
- }
-
- void getIdealSize (int& idealWidth,
- int& idealHeight)
- {
- getLookAndFeel().getIdealPopupMenuItemSize (getName(), false, -1, idealWidth, idealHeight);
- idealHeight += idealHeight / 2;
- idealWidth += idealWidth / 4;
- }
-
- juce_UseDebuggingNewOperator
- };
-
- void PopupMenu::addSectionHeader (const String& title) throw()
- {
- addCustomItem (0X4734a34f, new HeaderItemComponent (title));
- }
-
- Component* PopupMenu::createMenuComponent (const int x, const int y, const int w, const int h,
- const int itemIdThatMustBeVisible,
- const int minimumWidth,
- const int maximumNumColumns,
- const int standardItemHeight,
- const bool alignToRectangle,
- Component* menuBarComponent,
- ApplicationCommandManager** managerOfChosenCommand,
- Component* const componentAttachedTo) throw()
- {
- PopupMenuWindow* const pw
- = PopupMenuWindow::create (*this,
- ModifierKeys::getCurrentModifiers().isAnyMouseButtonDown(),
- 0,
- x, x + w,
- y, y + h,
- minimumWidth,
- maximumNumColumns,
- standardItemHeight,
- alignToRectangle,
- itemIdThatMustBeVisible,
- menuBarComponent,
- managerOfChosenCommand,
- componentAttachedTo);
-
- if (pw != 0)
- pw->setVisible (true);
-
- return pw;
- }
-
- int PopupMenu::showMenu (const int x, const int y, const int w, const int h,
- const int itemIdThatMustBeVisible,
- const int minimumWidth,
- const int maximumNumColumns,
- const int standardItemHeight,
- const bool alignToRectangle,
- Component* const componentAttachedTo) throw()
- {
- Component* const prevFocused = Component::getCurrentlyFocusedComponent();
-
- ComponentDeletionWatcher* deletionChecker1 = 0;
- if (prevFocused != 0)
- deletionChecker1 = new ComponentDeletionWatcher (prevFocused);
-
- Component* const prevTopLevel = (prevFocused != 0) ? prevFocused->getTopLevelComponent() : 0;
-
- ComponentDeletionWatcher* deletionChecker2 = 0;
- if (prevTopLevel != 0)
- deletionChecker2 = new ComponentDeletionWatcher (prevTopLevel);
-
- wasHiddenBecauseOfAppChange = false;
-
- int result = 0;
- ApplicationCommandManager* managerOfChosenCommand = 0;
-
- Component* const popupComp = createMenuComponent (x, y, w, h,
- itemIdThatMustBeVisible,
- minimumWidth,
- maximumNumColumns > 0 ? maximumNumColumns : 7,
- standardItemHeight,
- alignToRectangle, 0,
- &managerOfChosenCommand,
- componentAttachedTo);
-
- if (popupComp != 0)
- {
- popupComp->enterModalState (false);
- popupComp->toFront (false); // need to do this after making it modal, or it could
- // be stuck behind other comps that are already modal..
-
- result = popupComp->runModalLoop();
- delete popupComp;
-
- if (! wasHiddenBecauseOfAppChange)
- {
- if (deletionChecker2 != 0 && ! deletionChecker2->hasBeenDeleted())
- prevTopLevel->toFront (true);
-
- if (deletionChecker1 != 0 && ! deletionChecker1->hasBeenDeleted())
- prevFocused->grabKeyboardFocus();
- }
- }
-
- delete deletionChecker1;
- delete deletionChecker2;
-
- if (managerOfChosenCommand != 0 && result != 0)
- {
- ApplicationCommandTarget::InvocationInfo info (result);
- info.invocationMethod = ApplicationCommandTarget::InvocationInfo::fromMenu;
-
- managerOfChosenCommand->invoke (info, true);
- }
-
- return result;
- }
-
- int PopupMenu::show (const int itemIdThatMustBeVisible,
- const int minimumWidth,
- const int maximumNumColumns,
- const int standardItemHeight)
- {
- int x, y;
- Desktop::getMousePosition (x, y);
-
- return showAt (x, y,
- itemIdThatMustBeVisible,
- minimumWidth,
- maximumNumColumns,
- standardItemHeight);
- }
-
- int PopupMenu::showAt (const int screenX,
- const int screenY,
- const int itemIdThatMustBeVisible,
- const int minimumWidth,
- const int maximumNumColumns,
- const int standardItemHeight)
- {
- return showMenu (screenX, screenY, 1, 1,
- itemIdThatMustBeVisible,
- minimumWidth, maximumNumColumns,
- standardItemHeight,
- false, 0);
- }
-
- int PopupMenu::showAt (Component* componentToAttachTo,
- const int itemIdThatMustBeVisible,
- const int minimumWidth,
- const int maximumNumColumns,
- const int standardItemHeight)
- {
- if (componentToAttachTo != 0)
- {
- return showMenu (componentToAttachTo->getScreenX(),
- componentToAttachTo->getScreenY(),
- componentToAttachTo->getWidth(),
- componentToAttachTo->getHeight(),
- itemIdThatMustBeVisible,
- minimumWidth,
- maximumNumColumns,
- standardItemHeight,
- true, componentToAttachTo);
- }
- else
- {
- return show (itemIdThatMustBeVisible,
- minimumWidth,
- maximumNumColumns,
- standardItemHeight);
- }
- }
-
- void JUCE_CALLTYPE PopupMenu::dismissAllActiveMenus() throw()
- {
- for (int i = activeMenuWindows.size(); --i >= 0;)
- {
- PopupMenuWindow* const pmw = (PopupMenuWindow*) activeMenuWindows[i];
-
- if (pmw != 0)
- pmw->dismissMenu (0);
- }
- }
-
- int PopupMenu::getNumItems() const throw()
- {
- int num = 0;
-
- for (int i = items.size(); --i >= 0;)
- if (! ((MenuItemInfo*) items.getUnchecked(i))->isSeparator)
- ++num;
-
- return num;
- }
-
- bool PopupMenu::containsCommandItem (const int commandID) const throw()
- {
- for (int i = items.size(); --i >= 0;)
- {
- const MenuItemInfo* mi = (const MenuItemInfo*) items.getUnchecked (i);
-
- if ((mi->itemId == commandID && mi->commandManager != 0)
- || (mi->subMenu != 0 && mi->subMenu->containsCommandItem (commandID)))
- {
- return true;
- }
- }
-
- return false;
- }
-
- bool PopupMenu::containsAnyActiveItems() const throw()
- {
- for (int i = items.size(); --i >= 0;)
- {
- const MenuItemInfo* const mi = (const MenuItemInfo*) items.getUnchecked (i);
-
- if (mi->subMenu != 0)
- {
- if (mi->subMenu->containsAnyActiveItems())
- return true;
- }
- else if (mi->active)
- {
- return true;
- }
- }
-
- return false;
- }
-
- void PopupMenu::setLookAndFeel (LookAndFeel* const newLookAndFeel) throw()
- {
- lookAndFeel = newLookAndFeel;
- }
-
- PopupMenuCustomComponent::PopupMenuCustomComponent (const bool isTriggeredAutomatically_)
- : refCount_ (0),
- isHighlighted (false),
- isTriggeredAutomatically (isTriggeredAutomatically_)
- {
- }
-
- PopupMenuCustomComponent::~PopupMenuCustomComponent()
- {
- jassert (refCount_ == 0); // should be deleted only by the menu component, as they keep a ref-count.
- }
-
- void PopupMenuCustomComponent::triggerMenuItem()
- {
- MenuItemComponent* const mic = dynamic_cast<MenuItemComponent*> (getParentComponent());
-
- if (mic != 0)
- {
- PopupMenuWindow* const pmw = dynamic_cast<PopupMenuWindow*> (mic->getParentComponent());
-
- if (pmw != 0)
- {
- pmw->dismissMenu (&mic->itemInfo);
- }
- else
- {
- // something must have gone wrong with the component hierarchy if this happens..
- jassertfalse
- }
- }
- else
- {
- // why isn't this component inside a menu? Not much point triggering the item if
- // there's no menu.
- jassertfalse
- }
- }
-
- PopupMenu::MenuItemIterator::MenuItemIterator (const PopupMenu& menu_) throw()
- : subMenu (0),
- itemId (0),
- isSeparator (false),
- isTicked (false),
- isEnabled (false),
- isCustomComponent (false),
- isSectionHeader (false),
- customColour (0),
- customImage (0),
- menu (menu_),
- index (0)
- {
- }
-
- PopupMenu::MenuItemIterator::~MenuItemIterator() throw()
- {
- }
-
- bool PopupMenu::MenuItemIterator::next() throw()
- {
- if (index >= menu.items.size())
- return false;
-
- const MenuItemInfo* const item = (const MenuItemInfo*) menu.items.getUnchecked (index);
- ++index;
-
- itemName = item->customComp != 0 ? item->customComp->getName() : item->text;
- subMenu = item->subMenu;
- itemId = item->itemId;
-
- isSeparator = item->isSeparator;
- isTicked = item->isTicked;
- isEnabled = item->active;
- isSectionHeader = dynamic_cast <HeaderItemComponent*> (item->customComp) != 0;
- isCustomComponent = (! isSectionHeader) && item->customComp != 0;
- customColour = item->usesColour ? &(item->textColour) : 0;
- customImage = item->image;
- commandManager = item->commandManager;
-
- return true;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_PopupMenu.cpp *********/
-
- /********* Start of inlined file: juce_ComponentDragger.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- ComponentDragger::ComponentDragger()
- : constrainer (0),
- originalX (0),
- originalY (0)
- {
- }
-
- ComponentDragger::~ComponentDragger()
- {
- }
-
- void ComponentDragger::startDraggingComponent (Component* const componentToDrag,
- ComponentBoundsConstrainer* const constrainer_)
- {
- jassert (componentToDrag->isValidComponent());
-
- if (componentToDrag->isValidComponent())
- {
- constrainer = constrainer_;
- originalX = 0;
- originalY = 0;
- componentToDrag->relativePositionToGlobal (originalX, originalY);
- }
- }
-
- void ComponentDragger::dragComponent (Component* const componentToDrag, const MouseEvent& e)
- {
- jassert (componentToDrag->isValidComponent());
- jassert (e.mods.isAnyMouseButtonDown()); // (the event has to be a drag event..)
-
- if (componentToDrag->isValidComponent())
- {
- int x = originalX + e.getDistanceFromDragStartX();
- int y = originalY + e.getDistanceFromDragStartY();
- int w = componentToDrag->getWidth();
- int h = componentToDrag->getHeight();
-
- const Component* const parentComp = componentToDrag->getParentComponent();
- if (parentComp != 0)
- parentComp->globalPositionToRelative (x, y);
-
- if (constrainer != 0)
- constrainer->setBoundsForComponent (componentToDrag, x, y, w, h,
- false, false, false, false);
- else
- componentToDrag->setBounds (x, y, w, h);
- }
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_ComponentDragger.cpp *********/
-
- /********* Start of inlined file: juce_DragAndDropContainer.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- bool juce_performDragDropFiles (const StringArray& files, const bool copyFiles, bool& shouldStop);
- bool juce_performDragDropText (const String& text, bool& shouldStop);
-
- class DragImageComponent : public Component,
- public Timer
- {
- private:
- Image* image;
- Component* const source;
- DragAndDropContainer* const owner;
-
- ComponentDeletionWatcher* sourceWatcher;
- Component* mouseDragSource;
- ComponentDeletionWatcher* mouseDragSourceWatcher;
-
- DragAndDropTarget* currentlyOver;
- String dragDesc;
- int xOff, yOff;
- bool hasCheckedForExternalDrag, drawImage;
-
- DragImageComponent (const DragImageComponent&);
- const DragImageComponent& operator= (const DragImageComponent&);
-
- public:
- DragImageComponent (Image* const im,
- const String& desc,
- Component* const s,
- DragAndDropContainer* const o)
- : image (im),
- source (s),
- owner (o),
- currentlyOver (0),
- dragDesc (desc),
- hasCheckedForExternalDrag (false),
- drawImage (true)
- {
- setSize (im->getWidth(), im->getHeight());
-
- sourceWatcher = new ComponentDeletionWatcher (source);
-
- mouseDragSource = Component::getComponentUnderMouse();
-
- if (mouseDragSource == 0)
- mouseDragSource = source;
-
- mouseDragSourceWatcher = new ComponentDeletionWatcher (mouseDragSource);
- mouseDragSource->addMouseListener (this, false);
-
- int mx, my;
- Desktop::getLastMouseDownPosition (mx, my);
- source->globalPositionToRelative (mx, my);
-
- xOff = jlimit (0, im->getWidth(), mx);
- yOff = jlimit (0, im->getHeight(), my);
-
- startTimer (200);
-
- setInterceptsMouseClicks (false, false);
- setAlwaysOnTop (true);
- }
-
- ~DragImageComponent()
- {
- if (owner->dragImageComponent == this)
- owner->dragImageComponent = 0;
-
- if (((Component*) currentlyOver)->isValidComponent())
- {
- Component* const over = dynamic_cast <Component*> (currentlyOver);
-
- if (over != 0
- && over->isValidComponent()
- && source->isValidComponent()
- && currentlyOver->isInterestedInDragSource (dragDesc, source))
- {
- currentlyOver->itemDragExit (dragDesc, source);
- }
- }
-
- if (! mouseDragSourceWatcher->hasBeenDeleted())
- mouseDragSource->removeMouseListener (this);
-
- delete mouseDragSourceWatcher;
- delete sourceWatcher;
- delete image;
- }
-
- void paint (Graphics& g)
- {
- if (isOpaque())
- g.fillAll (Colours::white);
-
- if (drawImage)
- {
- g.setOpacity (1.0f);
- g.drawImageAt (image, 0, 0);
- }
- }
-
- DragAndDropTarget* findTarget (const int screenX, const int screenY,
- int& relX, int& relY) const throw()
- {
- Component* hit = getParentComponent();
-
- if (hit == 0)
- {
- hit = Desktop::getInstance().findComponentAt (screenX, screenY);
- }
- else
- {
- int rx = screenX, ry = screenY;
- hit->globalPositionToRelative (rx, ry);
-
- hit = hit->getComponentAt (rx, ry);
- }
-
- while (hit != 0)
- {
- DragAndDropTarget* const ddt = dynamic_cast <DragAndDropTarget*> (hit);
-
- if (ddt != 0 && ddt->isInterestedInDragSource (dragDesc, source))
- {
- relX = screenX;
- relY = screenY;
- hit->globalPositionToRelative (relX, relY);
- return ddt;
- }
-
- hit = hit->getParentComponent();
- }
-
- return 0;
- }
-
- void mouseUp (const MouseEvent& e)
- {
- if (e.originalComponent != this)
- {
- if (! mouseDragSourceWatcher->hasBeenDeleted())
- mouseDragSource->removeMouseListener (this);
-
- bool dropAccepted = false;
- DragAndDropTarget* ddt = 0;
- int relX = 0, relY = 0;
-
- if (isVisible())
- {
- setVisible (false);
- ddt = findTarget (e.getScreenX(),
- e.getScreenY(),
- relX, relY);
-
- // fade this component and remove it - it'll be deleted later by the timer callback
-
- dropAccepted = ddt != 0;
-
- setVisible (true);
-
- if (dropAccepted || sourceWatcher->hasBeenDeleted())
- {
- fadeOutComponent (120);
- }
- else
- {
- int targetX = source->getWidth() / 2;
- int targetY = source->getHeight() / 2;
- source->relativePositionToGlobal (targetX, targetY);
-
- int ourCentreX = getWidth() / 2;
- int ourCentreY = getHeight() / 2;
- relativePositionToGlobal (ourCentreX, ourCentreY);
-
- fadeOutComponent (120,
- targetX - ourCentreX,
- targetY - ourCentreY);
- }
- }
-
- if (getParentComponent() != 0)
- getParentComponent()->removeChildComponent (this);
-
- if (dropAccepted && ddt != 0)
- ddt->itemDropped (dragDesc, source, relX, relY);
-
- // careful - this object could now be deleted..
- }
- }
-
- void updateLocation (const bool canDoExternalDrag, int x, int y)
- {
- int newX = x - xOff;
- int newY = y - yOff;
-
- if (getParentComponent() != 0)
- getParentComponent()->globalPositionToRelative (newX, newY);
-
- if (newX != getX() || newY != getY())
- {
- setTopLeftPosition (newX, newY);
-
- int relX = 0, relY = 0;
- DragAndDropTarget* const ddt = findTarget (x, y, relX, relY);
-
- drawImage = (ddt == 0) || ddt->shouldDrawDragImageWhenOver();
-
- if (ddt != currentlyOver)
- {
- Component* const over = dynamic_cast <Component*> (currentlyOver);
-
- if (over != 0
- && over->isValidComponent()
- && ! (sourceWatcher->hasBeenDeleted())
- && currentlyOver->isInterestedInDragSource (dragDesc, source))
- {
- currentlyOver->itemDragExit (dragDesc, source);
- }
-
- currentlyOver = ddt;
-
- if (currentlyOver != 0
- && currentlyOver->isInterestedInDragSource (dragDesc, source))
- currentlyOver->itemDragEnter (dragDesc, source, relX, relY);
- }
-
- if (currentlyOver != 0
- && currentlyOver->isInterestedInDragSource (dragDesc, source))
- currentlyOver->itemDragMove (dragDesc, source, relX, relY);
-
- if (currentlyOver == 0
- && canDoExternalDrag
- && ! hasCheckedForExternalDrag)
- {
- if (Desktop::getInstance().findComponentAt (x, y) == 0)
- {
- hasCheckedForExternalDrag = true;
- StringArray files;
- bool canMoveFiles = false;
-
- if (owner->shouldDropFilesWhenDraggedExternally (dragDesc, source, files, canMoveFiles)
- && files.size() > 0)
- {
- ComponentDeletionWatcher cdw (this);
- setVisible (false);
-
- if (ModifierKeys::getCurrentModifiersRealtime().isAnyMouseButtonDown())
- DragAndDropContainer::performExternalDragDropOfFiles (files, canMoveFiles);
-
- if (! cdw.hasBeenDeleted())
- delete this;
-
- return;
- }
- }
- }
- }
- }
-
- void mouseDrag (const MouseEvent& e)
- {
- if (e.originalComponent != this)
- updateLocation (true, e.getScreenX(), e.getScreenY());
- }
-
- void timerCallback()
- {
- if (sourceWatcher->hasBeenDeleted())
- {
- delete this;
- }
- else if (! isMouseButtonDownAnywhere())
- {
- if (! mouseDragSourceWatcher->hasBeenDeleted())
- mouseDragSource->removeMouseListener (this);
-
- delete this;
- }
- }
- };
-
- DragAndDropContainer::DragAndDropContainer()
- : dragImageComponent (0)
- {
- }
-
- DragAndDropContainer::~DragAndDropContainer()
- {
- if (dragImageComponent != 0)
- delete dragImageComponent;
- }
-
- void DragAndDropContainer::startDragging (const String& sourceDescription,
- Component* sourceComponent,
- Image* im,
- const bool allowDraggingToExternalWindows)
- {
- if (dragImageComponent != 0)
- {
- if (im != 0)
- delete im;
- }
- else
- {
- Component* const thisComp = dynamic_cast <Component*> (this);
-
- if (thisComp != 0)
- {
- int mx, my;
- Desktop::getLastMouseDownPosition (mx, my);
-
- if (im == 0)
- {
- im = sourceComponent->createComponentSnapshot (Rectangle (0, 0, sourceComponent->getWidth(), sourceComponent->getHeight()));
-
- if (im->getFormat() != Image::ARGB)
- {
- Image* newIm = new Image (Image::ARGB, im->getWidth(), im->getHeight(), true);
- Graphics g2 (*newIm);
- g2.drawImageAt (im, 0, 0);
-
- delete im;
- im = newIm;
- }
-
- im->multiplyAllAlphas (0.6f);
-
- const int lo = 150;
- const int hi = 400;
-
- int rx = mx, ry = my;
- sourceComponent->globalPositionToRelative (rx, ry);
- const int cx = jlimit (0, im->getWidth(), rx);
- const int cy = jlimit (0, im->getHeight(), ry);
-
- for (int y = im->getHeight(); --y >= 0;)
- {
- const double dy = (y - cy) * (y - cy);
-
- for (int x = im->getWidth(); --x >= 0;)
- {
- const int dx = x - cx;
- const int distance = roundDoubleToInt (sqrt (dx * dx + dy));
-
- if (distance > lo)
- {
- const float alpha = (distance > hi) ? 0
- : (hi - distance) / (float) (hi - lo)
- + Random::getSystemRandom().nextFloat() * 0.008f;
-
- im->multiplyAlphaAt (x, y, alpha);
- }
- }
- }
- }
-
- DragImageComponent* const dic
- = new DragImageComponent (im,
- sourceDescription,
- sourceComponent,
- this);
-
- dragImageComponent = dic;
- currentDragDesc = sourceDescription;
-
- if (allowDraggingToExternalWindows)
- {
- if (! Desktop::canUseSemiTransparentWindows())
- dic->setOpaque (true);
-
- dic->addToDesktop (ComponentPeer::windowIgnoresMouseClicks
- | ComponentPeer::windowIsTemporary);
- }
- else
- thisComp->addChildComponent (dic);
-
- dic->updateLocation (false, mx, my);
- dic->setVisible (true);
- }
- else
- {
- // this class must only be implemented by an object that
- // is also a Component.
- jassertfalse
-
- if (im != 0)
- delete im;
- }
- }
- }
-
- bool DragAndDropContainer::isDragAndDropActive() const
- {
- return dragImageComponent != 0;
- }
-
- const String DragAndDropContainer::getCurrentDragDescription() const
- {
- return (dragImageComponent != 0) ? currentDragDesc
- : String::empty;
- }
-
- DragAndDropContainer* DragAndDropContainer::findParentDragContainerFor (Component* c)
- {
- if (c == 0)
- return 0;
-
- // (unable to use the syntax findParentComponentOfClass <DragAndDropContainer> () because of a VC6 compiler bug)
- return c->findParentComponentOfClass ((DragAndDropContainer*) 0);
- }
-
- bool DragAndDropContainer::shouldDropFilesWhenDraggedExternally (const String&, Component*, StringArray&, bool&)
- {
- return false;
- }
-
- void DragAndDropTarget::itemDragEnter (const String&, Component*, int, int)
- {
- }
-
- void DragAndDropTarget::itemDragMove (const String&, Component*, int, int)
- {
- }
-
- void DragAndDropTarget::itemDragExit (const String&, Component*)
- {
- }
-
- bool DragAndDropTarget::shouldDrawDragImageWhenOver()
- {
- return true;
- }
-
- void FileDragAndDropTarget::fileDragEnter (const StringArray&, int, int)
- {
- }
-
- void FileDragAndDropTarget::fileDragMove (const StringArray&, int, int)
- {
- }
-
- void FileDragAndDropTarget::fileDragExit (const StringArray&)
- {
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_DragAndDropContainer.cpp *********/
-
- /********* Start of inlined file: juce_MouseCursor.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- void* juce_createMouseCursorFromImage (const Image& image, int hotspotX, int hotspotY) throw();
- void* juce_createStandardMouseCursor (MouseCursor::StandardCursorType type) throw();
- // isStandard set depending on which interface was used to create the cursor
- void juce_deleteMouseCursor (void* const cursorHandle, const bool isStandard) throw();
-
- static CriticalSection mouseCursorLock;
- static VoidArray standardCursors (2);
-
- class RefCountedMouseCursor
- {
- public:
- RefCountedMouseCursor (const MouseCursor::StandardCursorType t) throw()
- : refCount (1),
- standardType (t),
- isStandard (true)
- {
- handle = juce_createStandardMouseCursor (standardType);
- standardCursors.add (this);
- }
-
- RefCountedMouseCursor (Image& image,
- const int hotSpotX,
- const int hotSpotY) throw()
- : refCount (1),
- standardType (MouseCursor::NormalCursor),
- isStandard (false)
- {
- handle = juce_createMouseCursorFromImage (image, hotSpotX, hotSpotY);
- }
-
- ~RefCountedMouseCursor() throw()
- {
- juce_deleteMouseCursor (handle, isStandard);
- standardCursors.removeValue (this);
- }
-
- void decRef() throw()
- {
- if (--refCount == 0)
- delete this;
- }
-
- void incRef() throw()
- {
- ++refCount;
- }
-
- void* getHandle() const throw()
- {
- return handle;
- }
-
- static RefCountedMouseCursor* findInstance (MouseCursor::StandardCursorType type) throw()
- {
- const ScopedLock sl (mouseCursorLock);
-
- for (int i = 0; i < standardCursors.size(); i++)
- {
- RefCountedMouseCursor* const r = (RefCountedMouseCursor*) standardCursors.getUnchecked(i);
-
- if (r->standardType == type)
- {
- r->incRef();
- return r;
- }
- }
-
- return new RefCountedMouseCursor (type);
- }
-
- juce_UseDebuggingNewOperator
-
- private:
- void* handle;
- int refCount;
- const MouseCursor::StandardCursorType standardType;
- const bool isStandard;
-
- const RefCountedMouseCursor& operator= (const RefCountedMouseCursor&);
- };
-
- MouseCursor::MouseCursor() throw()
- {
- cursorHandle = RefCountedMouseCursor::findInstance (NormalCursor);
- }
-
- MouseCursor::MouseCursor (const StandardCursorType type) throw()
- {
- cursorHandle = RefCountedMouseCursor::findInstance (type);
- }
-
- MouseCursor::MouseCursor (Image& image,
- const int hotSpotX,
- const int hotSpotY) throw()
- {
- cursorHandle = new RefCountedMouseCursor (image, hotSpotX, hotSpotY);
- }
-
- MouseCursor::MouseCursor (const MouseCursor& other) throw()
- : cursorHandle (other.cursorHandle)
- {
- const ScopedLock sl (mouseCursorLock);
- cursorHandle->incRef();
- }
-
- MouseCursor::~MouseCursor() throw()
- {
- const ScopedLock sl (mouseCursorLock);
- cursorHandle->decRef();
- }
-
- const MouseCursor& MouseCursor::operator= (const MouseCursor& other) throw()
- {
- if (this != &other)
- {
- const ScopedLock sl (mouseCursorLock);
-
- cursorHandle->decRef();
- cursorHandle = other.cursorHandle;
- cursorHandle->incRef();
- }
-
- return *this;
- }
-
- bool MouseCursor::operator== (const MouseCursor& other) const throw()
- {
- return cursorHandle == other.cursorHandle;
- }
-
- bool MouseCursor::operator!= (const MouseCursor& other) const throw()
- {
- return cursorHandle != other.cursorHandle;
- }
-
- void* MouseCursor::getHandle() const throw()
- {
- return cursorHandle->getHandle();
- }
-
- void MouseCursor::showWaitCursor() throw()
- {
- const MouseCursor mc (MouseCursor::WaitCursor);
- mc.showInAllWindows();
- }
-
- void MouseCursor::hideWaitCursor() throw()
- {
- if (Component::getComponentUnderMouse()->isValidComponent())
- {
- Component::getComponentUnderMouse()->getMouseCursor().showInAllWindows();
- }
- else
- {
- const MouseCursor mc (MouseCursor::NormalCursor);
- mc.showInAllWindows();
- }
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_MouseCursor.cpp *********/
-
- /********* Start of inlined file: juce_MouseEvent.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- MouseEvent::MouseEvent (const int x_,
- const int y_,
- const ModifierKeys& mods_,
- Component* const originator,
- const Time& eventTime_,
- const int mouseDownX_,
- const int mouseDownY_,
- const Time& mouseDownTime_,
- const int numberOfClicks_,
- const bool mouseWasDragged) throw()
- : x (x_),
- y (y_),
- mods (mods_),
- eventComponent (originator),
- originalComponent (originator),
- eventTime (eventTime_),
- mouseDownX (mouseDownX_),
- mouseDownY (mouseDownY_),
- mouseDownTime (mouseDownTime_),
- numberOfClicks (numberOfClicks_),
- wasMovedSinceMouseDown (mouseWasDragged)
- {
- }
-
- MouseEvent::~MouseEvent() throw()
- {
- }
-
- bool MouseEvent::mouseWasClicked() const throw()
- {
- return ! wasMovedSinceMouseDown;
- }
-
- int MouseEvent::getMouseDownX() const throw()
- {
- return mouseDownX;
- }
-
- int MouseEvent::getMouseDownY() const throw()
- {
- return mouseDownY;
- }
-
- int MouseEvent::getDistanceFromDragStartX() const throw()
- {
- return x - mouseDownX;
- }
-
- int MouseEvent::getDistanceFromDragStartY() const throw()
- {
- return y - mouseDownY;
- }
-
- int MouseEvent::getDistanceFromDragStart() const throw()
- {
- return roundDoubleToInt (juce_hypot (getDistanceFromDragStartX(),
- getDistanceFromDragStartY()));
- }
-
- int MouseEvent::getLengthOfMousePress() const throw()
- {
- if (mouseDownTime.toMilliseconds() > 0)
- return jmax (0, (int) (eventTime - mouseDownTime).inMilliseconds());
-
- return 0;
- }
-
- int MouseEvent::getScreenX() const throw()
- {
- int sx = x, sy = y;
- eventComponent->relativePositionToGlobal (sx, sy);
- return sx;
- }
-
- int MouseEvent::getScreenY() const throw()
- {
- int sx = x, sy = y;
- eventComponent->relativePositionToGlobal (sx, sy);
- return sy;
- }
-
- int MouseEvent::getMouseDownScreenX() const throw()
- {
- int sx = mouseDownX, sy = mouseDownY;
- eventComponent->relativePositionToGlobal (sx, sy);
- return sx;
- }
-
- int MouseEvent::getMouseDownScreenY() const throw()
- {
- int sx = mouseDownX, sy = mouseDownY;
- eventComponent->relativePositionToGlobal (sx, sy);
- return sy;
- }
-
- const MouseEvent MouseEvent::getEventRelativeTo (Component* const otherComponent) const throw()
- {
- if (otherComponent == 0)
- {
- jassertfalse
- return *this;
- }
-
- MouseEvent me (*this);
-
- eventComponent->relativePositionToOtherComponent (otherComponent, me.x, me.y);
- eventComponent->relativePositionToOtherComponent (otherComponent, me.mouseDownX, me.mouseDownY);
- me.eventComponent = otherComponent;
-
- return me;
- }
-
- static int doubleClickTimeOutMs = 400;
-
- void MouseEvent::setDoubleClickTimeout (const int newTime) throw()
- {
- doubleClickTimeOutMs = newTime;
- }
-
- int MouseEvent::getDoubleClickTimeout() throw()
- {
- return doubleClickTimeOutMs;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_MouseEvent.cpp *********/
-
- /********* Start of inlined file: juce_MouseHoverDetector.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- MouseHoverDetector::MouseHoverDetector (const int hoverTimeMillisecs_)
- : source (0),
- hoverTimeMillisecs (hoverTimeMillisecs_),
- hasJustHovered (false)
- {
- internalTimer.owner = this;
- }
-
- MouseHoverDetector::~MouseHoverDetector()
- {
- setHoverComponent (0);
- }
-
- void MouseHoverDetector::setHoverTimeMillisecs (const int newTimeInMillisecs)
- {
- hoverTimeMillisecs = newTimeInMillisecs;
- }
-
- void MouseHoverDetector::setHoverComponent (Component* const newSourceComponent)
- {
- if (source != newSourceComponent)
- {
- internalTimer.stopTimer();
- hasJustHovered = false;
-
- if (source != 0)
- {
- // ! you need to delete the hover detector before deleting its component
- jassert (source->isValidComponent());
-
- source->removeMouseListener (&internalTimer);
- }
-
- source = newSourceComponent;
-
- if (newSourceComponent != 0)
- newSourceComponent->addMouseListener (&internalTimer, false);
- }
- }
-
- void MouseHoverDetector::hoverTimerCallback()
- {
- internalTimer.stopTimer();
-
- if (source != 0)
- {
- int mx, my;
- source->getMouseXYRelative (mx, my);
-
- if (source->reallyContains (mx, my, false))
- {
- hasJustHovered = true;
- mouseHovered (mx, my);
- }
- }
- }
-
- void MouseHoverDetector::checkJustHoveredCallback()
- {
- if (hasJustHovered)
- {
- hasJustHovered = false;
- mouseMovedAfterHover();
- }
- }
-
- void MouseHoverDetector::HoverDetectorInternal::timerCallback()
- {
- owner->hoverTimerCallback();
- }
-
- void MouseHoverDetector::HoverDetectorInternal::mouseEnter (const MouseEvent&)
- {
- stopTimer();
- owner->checkJustHoveredCallback();
- }
-
- void MouseHoverDetector::HoverDetectorInternal::mouseExit (const MouseEvent&)
- {
- stopTimer();
- owner->checkJustHoveredCallback();
- }
-
- void MouseHoverDetector::HoverDetectorInternal::mouseDown (const MouseEvent&)
- {
- stopTimer();
- owner->checkJustHoveredCallback();
- }
-
- void MouseHoverDetector::HoverDetectorInternal::mouseUp (const MouseEvent&)
- {
- stopTimer();
- owner->checkJustHoveredCallback();
- }
-
- void MouseHoverDetector::HoverDetectorInternal::mouseMove (const MouseEvent& e)
- {
- if (lastX != e.x || lastY != e.y) // to avoid fake mouse-moves setting it off
- {
- lastX = e.x;
- lastY = e.y;
-
- if (owner->source != 0)
- startTimer (owner->hoverTimeMillisecs);
-
- owner->checkJustHoveredCallback();
- }
- }
-
- void MouseHoverDetector::HoverDetectorInternal::mouseWheelMove (const MouseEvent&, float, float)
- {
- stopTimer();
- owner->checkJustHoveredCallback();
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_MouseHoverDetector.cpp *********/
-
- /********* Start of inlined file: juce_MouseListener.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- void MouseListener::mouseEnter (const MouseEvent&)
- {
- }
-
- void MouseListener::mouseExit (const MouseEvent&)
- {
- }
-
- void MouseListener::mouseDown (const MouseEvent&)
- {
- }
-
- void MouseListener::mouseUp (const MouseEvent&)
- {
- }
-
- void MouseListener::mouseDrag (const MouseEvent&)
- {
- }
-
- void MouseListener::mouseMove (const MouseEvent&)
- {
- }
-
- void MouseListener::mouseDoubleClick (const MouseEvent&)
- {
- }
-
- void MouseListener::mouseWheelMove (const MouseEvent&, float, float)
- {
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_MouseListener.cpp *********/
-
- /********* Start of inlined file: juce_BooleanPropertyComponent.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- BooleanPropertyComponent::BooleanPropertyComponent (const String& name,
- const String& buttonTextWhenTrue,
- const String& buttonTextWhenFalse)
- : PropertyComponent (name),
- onText (buttonTextWhenTrue),
- offText (buttonTextWhenFalse)
- {
- addAndMakeVisible (button = new ToggleButton (String::empty));
- button->setClickingTogglesState (false);
- button->addButtonListener (this);
- }
-
- BooleanPropertyComponent::~BooleanPropertyComponent()
- {
- deleteAllChildren();
- }
-
- void BooleanPropertyComponent::paint (Graphics& g)
- {
- PropertyComponent::paint (g);
-
- const Rectangle r (button->getBounds());
- g.setColour (Colours::white);
- g.fillRect (r);
-
- g.setColour (findColour (ComboBox::outlineColourId));
- g.drawRect (r.getX(), r.getY(), r.getWidth(), r.getHeight());
- }
-
- void BooleanPropertyComponent::refresh()
- {
- button->setToggleState (getState(), false);
- button->setButtonText (button->getToggleState() ? onText : offText);
- }
-
- void BooleanPropertyComponent::buttonClicked (Button*)
- {
- setState (! getState());
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_BooleanPropertyComponent.cpp *********/
-
- /********* Start of inlined file: juce_ButtonPropertyComponent.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- ButtonPropertyComponent::ButtonPropertyComponent (const String& name,
- const bool triggerOnMouseDown)
- : PropertyComponent (name)
- {
- addAndMakeVisible (button = new TextButton (String::empty));
- button->setTriggeredOnMouseDown (triggerOnMouseDown);
- button->addButtonListener (this);
- }
-
- ButtonPropertyComponent::~ButtonPropertyComponent()
- {
- deleteAllChildren();
- }
-
- void ButtonPropertyComponent::refresh()
- {
- button->setButtonText (getButtonText());
- }
-
- void ButtonPropertyComponent::buttonClicked (Button*)
- {
- buttonClicked();
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_ButtonPropertyComponent.cpp *********/
-
- /********* Start of inlined file: juce_ChoicePropertyComponent.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- ChoicePropertyComponent::ChoicePropertyComponent (const String& name)
- : PropertyComponent (name),
- comboBox (0)
- {
- }
-
- ChoicePropertyComponent::~ChoicePropertyComponent()
- {
- deleteAllChildren();
- }
-
- const StringArray& ChoicePropertyComponent::getChoices() const throw()
- {
- return choices;
- }
-
- void ChoicePropertyComponent::refresh()
- {
- if (comboBox == 0)
- {
- addAndMakeVisible (comboBox = new ComboBox (String::empty));
-
- for (int i = 0; i < choices.size(); ++i)
- {
- if (choices[i].isNotEmpty())
- comboBox->addItem (choices[i], i + 1);
- else
- comboBox->addSeparator();
- }
-
- comboBox->setEditableText (false);
- comboBox->addListener (this);
- }
-
- comboBox->setSelectedId (getIndex() + 1, true);
- }
-
- void ChoicePropertyComponent::comboBoxChanged (ComboBox*)
- {
- const int newIndex = comboBox->getSelectedId() - 1;
-
- if (newIndex != getIndex())
- setIndex (newIndex);
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_ChoicePropertyComponent.cpp *********/
-
- /********* Start of inlined file: juce_PropertyComponent.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- PropertyComponent::PropertyComponent (const String& name,
- const int preferredHeight_)
- : Component (name),
- preferredHeight (preferredHeight_)
- {
- jassert (name.isNotEmpty());
- }
-
- PropertyComponent::~PropertyComponent()
- {
- }
-
- void PropertyComponent::paint (Graphics& g)
- {
- getLookAndFeel().drawPropertyComponentBackground (g, getWidth(), getHeight(), *this);
- getLookAndFeel().drawPropertyComponentLabel (g, getWidth(), getHeight(), *this);
- }
-
- void PropertyComponent::resized()
- {
- if (getNumChildComponents() > 0)
- getChildComponent (0)->setBounds (getLookAndFeel().getPropertyComponentContentPosition (*this));
- }
-
- void PropertyComponent::enablementChanged()
- {
- repaint();
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_PropertyComponent.cpp *********/
-
- /********* Start of inlined file: juce_PropertyPanel.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- class PropertyHolderComponent : public Component
- {
- public:
- PropertyHolderComponent()
- {
- }
-
- ~PropertyHolderComponent()
- {
- deleteAllChildren();
- }
-
- void paint (Graphics&)
- {
- }
-
- void updateLayout (const int width);
-
- void refreshAll() const;
- };
-
- class PropertySectionComponent : public Component
- {
- public:
- PropertySectionComponent (const String& sectionTitle,
- const Array <PropertyComponent*>& newProperties,
- const bool open)
- : Component (sectionTitle),
- titleHeight (sectionTitle.isNotEmpty() ? 22 : 0),
- isOpen_ (open)
- {
- for (int i = newProperties.size(); --i >= 0;)
- {
- addAndMakeVisible (newProperties.getUnchecked(i));
- newProperties.getUnchecked(i)->refresh();
- }
- }
-
- ~PropertySectionComponent()
- {
- deleteAllChildren();
- }
-
- void paint (Graphics& g)
- {
- if (titleHeight > 0)
- getLookAndFeel().drawPropertyPanelSectionHeader (g, getName(), isOpen(), getWidth(), titleHeight);
- }
-
- void resized()
- {
- int y = titleHeight;
-
- for (int i = getNumChildComponents(); --i >= 0;)
- {
- PropertyComponent* const pec = dynamic_cast <PropertyComponent*> (getChildComponent (i));
-
- if (pec != 0)
- {
- const int prefH = pec->getPreferredHeight();
- pec->setBounds (1, y, getWidth() - 2, prefH);
- y += prefH;
- }
- }
- }
-
- int getPreferredHeight() const
- {
- int y = titleHeight;
-
- if (isOpen())
- {
- for (int i = 0; i < getNumChildComponents(); ++i)
- {
- PropertyComponent* pec = dynamic_cast <PropertyComponent*> (getChildComponent (i));
-
- if (pec != 0)
- y += pec->getPreferredHeight();
- }
- }
-
- return y;
- }
-
- void setOpen (const bool open)
- {
- if (isOpen_ != open)
- {
- isOpen_ = open;
-
- for (int i = 0; i < getNumChildComponents(); ++i)
- {
- PropertyComponent* pec = dynamic_cast <PropertyComponent*> (getChildComponent (i));
-
- if (pec != 0)
- pec->setVisible (open);
- }
-
- // (unable to use the syntax findParentComponentOfClass <DragAndDropContainer> () because of a VC6 compiler bug)
- PropertyPanel* const pp = findParentComponentOfClass ((PropertyPanel*) 0);
-
- if (pp != 0)
- pp->resized();
- }
- }
-
- bool isOpen() const throw()
- {
- return isOpen_;
- }
-
- void refreshAll() const
- {
- for (int i = 0; i < getNumChildComponents(); ++i)
- {
- PropertyComponent* pec = dynamic_cast <PropertyComponent*> (getChildComponent (i));
-
- if (pec != 0)
- pec->refresh();
- }
- }
-
- void mouseDown (const MouseEvent&)
- {
- }
-
- void mouseUp (const MouseEvent& e)
- {
- if (e.getMouseDownX() < titleHeight
- && e.x < titleHeight
- && e.y < titleHeight
- && e.getNumberOfClicks() != 2)
- {
- setOpen (! isOpen());
- }
- }
-
- void mouseDoubleClick (const MouseEvent& e)
- {
- if (e.y < titleHeight)
- setOpen (! isOpen());
- }
-
- private:
- int titleHeight;
- bool isOpen_;
- };
-
- void PropertyHolderComponent::updateLayout (const int width)
- {
- int y = 0;
-
- for (int i = getNumChildComponents(); --i >= 0;)
- {
- PropertySectionComponent* const section
- = dynamic_cast <PropertySectionComponent*> (getChildComponent (i));
-
- if (section != 0)
- {
- const int prefH = section->getPreferredHeight();
- section->setBounds (0, y, width, prefH);
- y += prefH;
- }
- }
-
- setSize (width, y);
- repaint();
- }
-
- void PropertyHolderComponent::refreshAll() const
- {
- for (int i = getNumChildComponents(); --i >= 0;)
- {
- PropertySectionComponent* const section
- = dynamic_cast <PropertySectionComponent*> (getChildComponent (i));
-
- if (section != 0)
- section->refreshAll();
- }
- }
-
- PropertyPanel::PropertyPanel()
- {
- messageWhenEmpty = TRANS("(nothing selected)");
-
- addAndMakeVisible (viewport = new Viewport());
- viewport->setViewedComponent (propertyHolderComponent = new PropertyHolderComponent());
- viewport->setFocusContainer (true);
- }
-
- PropertyPanel::~PropertyPanel()
- {
- clear();
- deleteAllChildren();
- }
-
- void PropertyPanel::paint (Graphics& g)
- {
- if (propertyHolderComponent->getNumChildComponents() == 0)
- {
- g.setColour (Colours::black.withAlpha (0.5f));
- g.setFont (14.0f);
- g.drawText (messageWhenEmpty, 0, 0, getWidth(), 30,
- Justification::centred, true);
- }
- }
-
- void PropertyPanel::resized()
- {
- viewport->setBounds (0, 0, getWidth(), getHeight());
- updatePropHolderLayout();
- }
-
- void PropertyPanel::clear()
- {
- if (propertyHolderComponent->getNumChildComponents() > 0)
- {
- propertyHolderComponent->deleteAllChildren();
- repaint();
- }
- }
-
- void PropertyPanel::addProperties (const Array <PropertyComponent*>& newProperties)
- {
- if (propertyHolderComponent->getNumChildComponents() == 0)
- repaint();
-
- propertyHolderComponent->addAndMakeVisible (new PropertySectionComponent (String::empty,
- newProperties,
- true), 0);
- updatePropHolderLayout();
- }
-
- void PropertyPanel::addSection (const String& sectionTitle,
- const Array <PropertyComponent*>& newProperties,
- const bool shouldBeOpen)
- {
- jassert (sectionTitle.isNotEmpty());
-
- if (propertyHolderComponent->getNumChildComponents() == 0)
- repaint();
-
- propertyHolderComponent->addAndMakeVisible (new PropertySectionComponent (sectionTitle,
- newProperties,
- shouldBeOpen), 0);
-
- updatePropHolderLayout();
- }
-
- void PropertyPanel::updatePropHolderLayout() const
- {
- const int maxWidth = viewport->getMaximumVisibleWidth();
- ((PropertyHolderComponent*) propertyHolderComponent)->updateLayout (maxWidth);
-
- const int newMaxWidth = viewport->getMaximumVisibleWidth();
- if (maxWidth != newMaxWidth)
- {
- // need to do this twice because of scrollbars changing the size, etc.
- ((PropertyHolderComponent*) propertyHolderComponent)->updateLayout (newMaxWidth);
- }
- }
-
- void PropertyPanel::refreshAll() const
- {
- ((PropertyHolderComponent*) propertyHolderComponent)->refreshAll();
- }
-
- const StringArray PropertyPanel::getSectionNames() const
- {
- StringArray s;
-
- for (int i = 0; i < propertyHolderComponent->getNumChildComponents(); ++i)
- {
- PropertySectionComponent* const section = dynamic_cast <PropertySectionComponent*> (propertyHolderComponent->getChildComponent (i));
-
- if (section != 0 && section->getName().isNotEmpty())
- s.add (section->getName());
- }
-
- return s;
- }
-
- bool PropertyPanel::isSectionOpen (const int sectionIndex) const
- {
- int index = 0;
-
- for (int i = 0; i < propertyHolderComponent->getNumChildComponents(); ++i)
- {
- PropertySectionComponent* const section = dynamic_cast <PropertySectionComponent*> (propertyHolderComponent->getChildComponent (i));
-
- if (section != 0 && section->getName().isNotEmpty())
- {
- if (index == sectionIndex)
- return section->isOpen();
-
- ++index;
- }
- }
-
- return false;
- }
-
- void PropertyPanel::setSectionOpen (const int sectionIndex, const bool shouldBeOpen)
- {
- int index = 0;
-
- for (int i = 0; i < propertyHolderComponent->getNumChildComponents(); ++i)
- {
- PropertySectionComponent* const section = dynamic_cast <PropertySectionComponent*> (propertyHolderComponent->getChildComponent (i));
-
- if (section != 0 && section->getName().isNotEmpty())
- {
- if (index == sectionIndex)
- {
- section->setOpen (shouldBeOpen);
- break;
- }
-
- ++index;
- }
- }
- }
-
- XmlElement* PropertyPanel::getOpennessState() const
- {
- XmlElement* const xml = new XmlElement (T("PROPERTYPANELSTATE"));
-
- const StringArray sections (getSectionNames());
-
- for (int i = 0; i < sections.size(); ++i)
- {
- if (sections[i].isNotEmpty())
- {
- XmlElement* const e = new XmlElement (T("SECTION"));
- e->setAttribute (T("name"), sections[i]);
- e->setAttribute (T("open"), isSectionOpen (i) ? 1 : 0);
- xml->addChildElement (e);
- }
- }
-
- return xml;
- }
-
- void PropertyPanel::restoreOpennessState (const XmlElement& xml)
- {
- if (xml.hasTagName (T("PROPERTYPANELSTATE")))
- {
- const StringArray sections (getSectionNames());
-
- forEachXmlChildElementWithTagName (xml, e, T("SECTION"))
- {
- setSectionOpen (sections.indexOf (e->getStringAttribute (T("name"))),
- e->getBoolAttribute (T("open")));
- }
- }
- }
-
- void PropertyPanel::setMessageWhenEmpty (const String& newMessage)
- {
- if (messageWhenEmpty != newMessage)
- {
- messageWhenEmpty = newMessage;
- repaint();
- }
- }
-
- const String& PropertyPanel::getMessageWhenEmpty() const throw()
- {
- return messageWhenEmpty;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_PropertyPanel.cpp *********/
-
- /********* Start of inlined file: juce_SliderPropertyComponent.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- SliderPropertyComponent::SliderPropertyComponent (const String& name,
- const double rangeMin,
- const double rangeMax,
- const double interval,
- const double skewFactor)
- : PropertyComponent (name)
- {
- addAndMakeVisible (slider = new Slider (name));
-
- slider->setRange (rangeMin, rangeMax, interval);
- slider->setSkewFactor (skewFactor);
- slider->setSliderStyle (Slider::LinearBar);
-
- slider->addListener (this);
- }
-
- SliderPropertyComponent::~SliderPropertyComponent()
- {
- deleteAllChildren();
- }
-
- void SliderPropertyComponent::refresh()
- {
- slider->setValue (getValue(), false);
- }
-
- void SliderPropertyComponent::sliderValueChanged (Slider*)
- {
- if (getValue() != slider->getValue())
- setValue (slider->getValue());
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_SliderPropertyComponent.cpp *********/
-
- /********* Start of inlined file: juce_TextPropertyComponent.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- class TextPropLabel : public Label
- {
- TextPropertyComponent& owner;
- int maxChars;
- bool isMultiline;
-
- public:
- TextPropLabel (TextPropertyComponent& owner_,
- const int maxChars_, const bool isMultiline_)
- : Label (String::empty, String::empty),
- owner (owner_),
- maxChars (maxChars_),
- isMultiline (isMultiline_)
- {
- setEditable (true, true, false);
-
- setColour (backgroundColourId, Colours::white);
- setColour (outlineColourId, findColour (ComboBox::outlineColourId));
- }
-
- ~TextPropLabel()
- {
- }
-
- TextEditor* createEditorComponent()
- {
- TextEditor* const textEditor = Label::createEditorComponent();
-
- textEditor->setInputRestrictions (maxChars);
-
- if (isMultiline)
- {
- textEditor->setMultiLine (true, true);
- textEditor->setReturnKeyStartsNewLine (true);
- }
-
- return textEditor;
- }
-
- void textWasEdited()
- {
- owner.textWasEdited();
- }
- };
-
- TextPropertyComponent::TextPropertyComponent (const String& name,
- const int maxNumChars,
- const bool isMultiLine)
- : PropertyComponent (name)
- {
- addAndMakeVisible (textEditor = new TextPropLabel (*this, maxNumChars, isMultiLine));
-
- if (isMultiLine)
- {
- textEditor->setJustificationType (Justification::topLeft);
- preferredHeight = 120;
- }
- }
-
- TextPropertyComponent::~TextPropertyComponent()
- {
- deleteAllChildren();
- }
-
- void TextPropertyComponent::refresh()
- {
- textEditor->setText (getText(), false);
- }
-
- void TextPropertyComponent::textWasEdited()
- {
- const String newText (textEditor->getText());
-
- if (getText() != newText)
- setText (newText);
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_TextPropertyComponent.cpp *********/
-
- /********* Start of inlined file: juce_AudioDeviceSelectorComponent.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- class SimpleDeviceManagerInputLevelMeter : public Component,
- public Timer
- {
- public:
- SimpleDeviceManagerInputLevelMeter (AudioDeviceManager* const manager_)
- : manager (manager_),
- level (0)
- {
- startTimer (50);
- manager->enableInputLevelMeasurement (true);
- }
-
- ~SimpleDeviceManagerInputLevelMeter()
- {
- manager->enableInputLevelMeasurement (false);
- }
-
- void timerCallback()
- {
- const float newLevel = (float) manager->getCurrentInputLevel();
-
- if (fabsf (level - newLevel) > 0.005f)
- {
- level = newLevel;
- repaint();
- }
- }
-
- void paint (Graphics& g)
- {
- getLookAndFeel().drawLevelMeter (g, getWidth(), getHeight(), level);
- }
-
- private:
- AudioDeviceManager* const manager;
- float level;
- };
-
- class MidiInputSelectorComponentListBox : public ListBox,
- public ListBoxModel
- {
- public:
-
- MidiInputSelectorComponentListBox (AudioDeviceManager& deviceManager_,
- const String& noItemsMessage_,
- const int minNumber_,
- const int maxNumber_)
- : ListBox (String::empty, 0),
- deviceManager (deviceManager_),
- noItemsMessage (noItemsMessage_),
- minNumber (minNumber_),
- maxNumber (maxNumber_)
- {
- items = MidiInput::getDevices();
-
- setModel (this);
- setOutlineThickness (1);
- }
-
- ~MidiInputSelectorComponentListBox()
- {
- }
-
- int getNumRows()
- {
- return items.size();
- }
-
- void paintListBoxItem (int row,
- Graphics& g,
- int width, int height,
- bool rowIsSelected)
- {
- if (((unsigned int) row) < (unsigned int) items.size())
- {
- if (rowIsSelected)
- g.fillAll (findColour (TextEditor::highlightColourId)
- .withMultipliedAlpha (0.3f));
-
- const String item (items [row]);
- bool enabled = deviceManager.isMidiInputEnabled (item);
-
- const int x = getTickX();
- const int tickW = height - height / 4;
-
- getLookAndFeel().drawTickBox (g, *this, x - tickW, (height - tickW) / 2, tickW, tickW,
- enabled, true, true, false);
-
- g.setFont (height * 0.6f);
- g.setColour (findColour (ListBox::textColourId, true).withMultipliedAlpha (enabled ? 1.0f : 0.6f));
- g.drawText (item, x, 0, width - x - 2, height, Justification::centredLeft, true);
- }
- }
-
- void listBoxItemClicked (int row, const MouseEvent& e)
- {
- selectRow (row);
-
- if (e.x < getTickX())
- flipEnablement (row);
- }
-
- void listBoxItemDoubleClicked (int row, const MouseEvent&)
- {
- flipEnablement (row);
- }
-
- void returnKeyPressed (int row)
- {
- flipEnablement (row);
- }
-
- void paint (Graphics& g)
- {
- ListBox::paint (g);
-
- if (items.size() == 0)
- {
- g.setColour (Colours::grey);
- g.setFont (13.0f);
- g.drawText (noItemsMessage,
- 0, 0, getWidth(), getHeight() / 2,
- Justification::centred, true);
- }
- }
-
- int getBestHeight (const int preferredHeight)
- {
- const int extra = getOutlineThickness() * 2;
-
- return jmax (getRowHeight() * 2 + extra,
- jmin (getRowHeight() * getNumRows() + extra,
- preferredHeight));
- }
-
- juce_UseDebuggingNewOperator
-
- private:
- AudioDeviceManager& deviceManager;
- const String noItemsMessage;
- StringArray items;
- int minNumber, maxNumber;
-
- void flipEnablement (const int row)
- {
- if (((unsigned int) row) < (unsigned int) items.size())
- {
- const String item (items [row]);
- deviceManager.setMidiInputEnabled (item, ! deviceManager.isMidiInputEnabled (item));
- }
- }
-
- int getTickX() const throw()
- {
- return getRowHeight() + 5;
- }
-
- MidiInputSelectorComponentListBox (const MidiInputSelectorComponentListBox&);
- const MidiInputSelectorComponentListBox& operator= (const MidiInputSelectorComponentListBox&);
- };
-
- class AudioDeviceSettingsPanel : public Component,
- public ComboBoxListener,
- public ChangeListener,
- public ButtonListener
- {
- public:
- AudioDeviceSettingsPanel (AudioIODeviceType* type_,
- AudioIODeviceType::DeviceSetupDetails& setup_,
- const bool hideAdvancedOptionsWithButton)
- : type (type_),
- setup (setup_)
- {
- sampleRateDropDown = 0;
- sampleRateLabel = 0;
- bufferSizeDropDown = 0;
- bufferSizeLabel = 0;
- outputDeviceDropDown = 0;
- outputDeviceLabel = 0;
- inputDeviceDropDown = 0;
- inputDeviceLabel = 0;
- testButton = 0;
- inputLevelMeter = 0;
- showUIButton = 0;
- inputChanList = 0;
- outputChanList = 0;
- inputChanLabel = 0;
- outputChanLabel = 0;
- showAdvancedSettingsButton = 0;
-
- if (hideAdvancedOptionsWithButton)
- {
- addAndMakeVisible (showAdvancedSettingsButton = new TextButton (TRANS("Show advanced settings...")));
- showAdvancedSettingsButton->addButtonListener (this);
- }
-
- type->scanForDevices();
-
- setup.manager->addChangeListener (this);
- changeListenerCallback (0);
- }
-
- ~AudioDeviceSettingsPanel()
- {
- setup.manager->removeChangeListener (this);
-
- deleteAndZero (outputDeviceLabel);
- deleteAndZero (inputDeviceLabel);
- deleteAndZero (sampleRateLabel);
- deleteAndZero (bufferSizeLabel);
- deleteAndZero (showUIButton);
- deleteAndZero (inputChanLabel);
- deleteAndZero (outputChanLabel);
- deleteAndZero (showAdvancedSettingsButton);
-
- deleteAllChildren();
- }
-
- void resized()
- {
- const int lx = proportionOfWidth (0.35f);
- const int w = proportionOfWidth (0.4f);
- const int h = 24;
- const int space = 6;
- const int dh = h + space;
- int y = 0;
-
- if (outputDeviceDropDown != 0)
- {
- outputDeviceDropDown->setBounds (lx, y, w, h);
- testButton->setBounds (proportionOfWidth (0.77f),
- outputDeviceDropDown->getY(),
- proportionOfWidth (0.18f),
- h);
- y += dh;
- }
-
- if (inputDeviceDropDown != 0)
- {
- inputDeviceDropDown->setBounds (lx, y, w, h);
-
- inputLevelMeter->setBounds (proportionOfWidth (0.77f),
- inputDeviceDropDown->getY(),
- proportionOfWidth (0.18f),
- h);
- y += dh;
- }
-
- const int maxBoxHeight = 100;//(getHeight() - y - dh * 2) / numBoxes;
-
- if (outputChanList != 0)
- {
- const int bh = outputChanList->getBestHeight (maxBoxHeight);
- outputChanList->setBounds (lx, y, proportionOfWidth (0.55f), bh);
- y += bh + space;
- }
-
- if (inputChanList != 0)
- {
- const int bh = inputChanList->getBestHeight (maxBoxHeight);
- inputChanList->setBounds (lx, y, proportionOfWidth (0.55f), bh);
- y += bh + space;
- }
-
- y += space * 2;
-
- if (showAdvancedSettingsButton != 0)
- {
- showAdvancedSettingsButton->changeWidthToFitText (h);
- showAdvancedSettingsButton->setTopLeftPosition (lx, y);
- }
-
- if (sampleRateDropDown != 0)
- {
- sampleRateDropDown->setVisible (showAdvancedSettingsButton == 0
- || ! showAdvancedSettingsButton->isVisible());
-
- sampleRateDropDown->setBounds (lx, y, w, h);
- y += dh;
- }
-
- if (bufferSizeDropDown != 0)
- {
- bufferSizeDropDown->setVisible (showAdvancedSettingsButton == 0
- || ! showAdvancedSettingsButton->isVisible());
- bufferSizeDropDown->setBounds (lx, y, w, h);
- y += dh;
- }
-
- if (showUIButton != 0)
- {
- showUIButton->setVisible (showAdvancedSettingsButton == 0
- || ! showAdvancedSettingsButton->isVisible());
- showUIButton->changeWidthToFitText (h);
- showUIButton->setTopLeftPosition (lx, y);
- }
- }
-
- void comboBoxChanged (ComboBox* comboBoxThatHasChanged)
- {
- if (comboBoxThatHasChanged == 0)
- return;
-
- AudioDeviceManager::AudioDeviceSetup config;
- setup.manager->getAudioDeviceSetup (config);
- String error;
-
- if (comboBoxThatHasChanged == outputDeviceDropDown
- || comboBoxThatHasChanged == inputDeviceDropDown)
- {
- if (outputDeviceDropDown != 0)
- config.outputDeviceName = outputDeviceDropDown->getSelectedId() < 0 ? String::empty
- : outputDeviceDropDown->getText();
-
- if (inputDeviceDropDown != 0)
- config.inputDeviceName = inputDeviceDropDown->getSelectedId() < 0 ? String::empty
- : inputDeviceDropDown->getText();
-
- if (! type->hasSeparateInputsAndOutputs())
- config.inputDeviceName = config.outputDeviceName;
-
- if (comboBoxThatHasChanged == inputDeviceDropDown)
- config.useDefaultInputChannels = true;
- else
- config.useDefaultOutputChannels = true;
-
- error = setup.manager->setAudioDeviceSetup (config, true);
-
- showCorrectDeviceName (inputDeviceDropDown, true);
- showCorrectDeviceName (outputDeviceDropDown, false);
-
- updateControlPanelButton();
- resized();
- }
- else if (comboBoxThatHasChanged == sampleRateDropDown)
- {
- if (sampleRateDropDown->getSelectedId() > 0)
- {
- config.sampleRate = sampleRateDropDown->getSelectedId();
- error = setup.manager->setAudioDeviceSetup (config, true);
- }
- }
- else if (comboBoxThatHasChanged == bufferSizeDropDown)
- {
- if (bufferSizeDropDown->getSelectedId() > 0)
- {
- config.bufferSize = bufferSizeDropDown->getSelectedId();
- error = setup.manager->setAudioDeviceSetup (config, true);
- }
- }
-
- if (error.isNotEmpty())
- {
- AlertWindow::showMessageBox (AlertWindow::WarningIcon,
- T("Error when trying to open audio device!"),
- error);
- }
- }
-
- void buttonClicked (Button* button)
- {
- if (button == showAdvancedSettingsButton)
- {
- showAdvancedSettingsButton->setVisible (false);
- resized();
- }
- else if (button == showUIButton)
- {
- AudioIODevice* const device = setup.manager->getCurrentAudioDevice();
-
- if (device != 0 && device->showControlPanel())
- {
- setup.manager->closeAudioDevice();
- setup.manager->restartLastAudioDevice();
- getTopLevelComponent()->toFront (true);
- }
- }
- else if (button == testButton)
- {
- setup.manager->playTestSound();
- }
- }
-
- void updateControlPanelButton()
- {
- AudioIODevice* const currentDevice = setup.manager->getCurrentAudioDevice();
-
- deleteAndZero (showUIButton);
-
- if (currentDevice != 0 && currentDevice->hasControlPanel())
- {
- addAndMakeVisible (showUIButton = new TextButton (TRANS ("show this device's control panel"),
- TRANS ("opens the device's own control panel")));
- showUIButton->addButtonListener (this);
- }
-
- resized();
- }
-
- void changeListenerCallback (void*)
- {
- AudioIODevice* const currentDevice = setup.manager->getCurrentAudioDevice();
-
- if (setup.maxNumOutputChannels > 0 || ! type->hasSeparateInputsAndOutputs())
- {
- if (outputDeviceDropDown == 0)
- {
- outputDeviceDropDown = new ComboBox (String::empty);
- outputDeviceDropDown->addListener (this);
- addAndMakeVisible (outputDeviceDropDown);
-
- outputDeviceLabel = new Label (String::empty,
- type->hasSeparateInputsAndOutputs() ? TRANS ("output:")
- : TRANS ("device:"));
- outputDeviceLabel->attachToComponent (outputDeviceDropDown, true);
-
- addAndMakeVisible (testButton = new TextButton (TRANS ("Test")));
- testButton->addButtonListener (this);
- }
-
- addNamesToDeviceBox (*outputDeviceDropDown, false);
- }
-
- if (setup.maxNumInputChannels > 0 && type->hasSeparateInputsAndOutputs())
- {
- if (inputDeviceDropDown == 0)
- {
- inputDeviceDropDown = new ComboBox (String::empty);
- inputDeviceDropDown->addListener (this);
- addAndMakeVisible (inputDeviceDropDown);
-
- inputDeviceLabel = new Label (String::empty, TRANS ("input:"));
- inputDeviceLabel->attachToComponent (inputDeviceDropDown, true);
-
- addAndMakeVisible (inputLevelMeter
- = new SimpleDeviceManagerInputLevelMeter (setup.manager));
- }
-
- addNamesToDeviceBox (*inputDeviceDropDown, true);
- }
-
- updateControlPanelButton();
- showCorrectDeviceName (inputDeviceDropDown, true);
- showCorrectDeviceName (outputDeviceDropDown, false);
-
- if (currentDevice != 0)
- {
- if (setup.maxNumOutputChannels > 0
- && setup.minNumOutputChannels < setup.manager->getCurrentAudioDevice()->getOutputChannelNames().size())
- {
- if (outputChanList == 0)
- {
- addAndMakeVisible (outputChanList
- = new ChannelSelectorListBox (setup, ChannelSelectorListBox::audioOutputType,
- TRANS ("(no audio output channels found)")));
- outputChanLabel = new Label (String::empty, TRANS ("active output channels:"));
- outputChanLabel->attachToComponent (outputChanList, true);
- }
-
- outputChanList->refresh();
- }
- else
- {
- deleteAndZero (outputChanLabel);
- deleteAndZero (outputChanList);
- }
-
- if (setup.maxNumInputChannels > 0
- && setup.minNumInputChannels < setup.manager->getCurrentAudioDevice()->getInputChannelNames().size())
- {
- if (inputChanList == 0)
- {
- addAndMakeVisible (inputChanList
- = new ChannelSelectorListBox (setup, ChannelSelectorListBox::audioInputType,
- TRANS ("(no audio input channels found)")));
- inputChanLabel = new Label (String::empty, TRANS ("active input channels:"));
- inputChanLabel->attachToComponent (inputChanList, true);
- }
-
- inputChanList->refresh();
- }
- else
- {
- deleteAndZero (inputChanLabel);
- deleteAndZero (inputChanList);
- }
-
- // sample rate..
- {
- if (sampleRateDropDown == 0)
- {
- addAndMakeVisible (sampleRateDropDown = new ComboBox (String::empty));
- sampleRateDropDown->addListener (this);
-
- delete sampleRateLabel;
- sampleRateLabel = new Label (String::empty, TRANS ("sample rate:"));
- sampleRateLabel->attachToComponent (sampleRateDropDown, true);
- }
- else
- {
- sampleRateDropDown->clear();
- sampleRateDropDown->removeListener (this);
- }
-
- const int numRates = currentDevice->getNumSampleRates();
-
- for (int i = 0; i < numRates; ++i)
- {
- const int rate = roundDoubleToInt (currentDevice->getSampleRate (i));
- sampleRateDropDown->addItem (String (rate) + T(" Hz"), rate);
- }
-
- sampleRateDropDown->setSelectedId (roundDoubleToInt (currentDevice->getCurrentSampleRate()), true);
- sampleRateDropDown->addListener (this);
- }
-
- // buffer size
- {
- if (bufferSizeDropDown == 0)
- {
- addAndMakeVisible (bufferSizeDropDown = new ComboBox (String::empty));
- bufferSizeDropDown->addListener (this);
-
- delete bufferSizeLabel;
- bufferSizeLabel = new Label (String::empty, TRANS ("audio buffer size:"));
- bufferSizeLabel->attachToComponent (bufferSizeDropDown, true);
- }
- else
- {
- bufferSizeDropDown->clear();
- }
-
- const int numBufferSizes = currentDevice->getNumBufferSizesAvailable();
- double currentRate = currentDevice->getCurrentSampleRate();
- if (currentRate == 0)
- currentRate = 48000.0;
-
- for (int i = 0; i < numBufferSizes; ++i)
- {
- const int bs = currentDevice->getBufferSizeSamples (i);
- bufferSizeDropDown->addItem (String (bs)
- + T(" samples (")
- + String (bs * 1000.0 / currentRate, 1)
- + T(" ms)"),
- bs);
- }
-
- bufferSizeDropDown->setSelectedId (currentDevice->getCurrentBufferSizeSamples(), true);
- }
- }
- else
- {
- jassert (setup.manager->getCurrentAudioDevice() == 0); // not the correct device type!
-
- deleteAndZero (sampleRateLabel);
- deleteAndZero (bufferSizeLabel);
- deleteAndZero (sampleRateDropDown);
- deleteAndZero (bufferSizeDropDown);
-
- if (outputDeviceDropDown != 0)
- outputDeviceDropDown->setSelectedId (-1, true);
-
- if (inputDeviceDropDown != 0)
- inputDeviceDropDown->setSelectedId (-1, true);
- }
-
- resized();
- setSize (getWidth(), getLowestY() + 4);
- }
-
- private:
- AudioIODeviceType* const type;
- const AudioIODeviceType::DeviceSetupDetails setup;
-
- ComboBox* outputDeviceDropDown;
- ComboBox* inputDeviceDropDown;
- ComboBox* sampleRateDropDown;
- ComboBox* bufferSizeDropDown;
- Label* outputDeviceLabel;
- Label* inputDeviceLabel;
- Label* sampleRateLabel;
- Label* bufferSizeLabel;
- Label* inputChanLabel;
- Label* outputChanLabel;
- TextButton* testButton;
- Component* inputLevelMeter;
- TextButton* showUIButton;
- TextButton* showAdvancedSettingsButton;
-
- void showCorrectDeviceName (ComboBox* const box, const bool isInput)
- {
- if (box != 0)
- {
- AudioIODevice* const currentDevice = dynamic_cast <AudioIODevice*> (setup.manager->getCurrentAudioDevice());
-
- const int index = type->getIndexOfDevice (currentDevice, isInput);
-
- box->setSelectedId (index + 1, true);
-
- if (! isInput)
- testButton->setEnabled (index >= 0);
- }
- }
-
- void addNamesToDeviceBox (ComboBox& combo, bool isInputs)
- {
- const StringArray devs (type->getDeviceNames (isInputs));
-
- combo.clear (true);
-
- for (int i = 0; i < devs.size(); ++i)
- combo.addItem (devs[i], i + 1);
-
- combo.addItem (TRANS("<< none >>"), -1);
- combo.setSelectedId (-1, true);
- }
-
- int getLowestY() const
- {
- int y = 0;
-
- for (int i = getNumChildComponents(); --i >= 0;)
- y = jmax (y, getChildComponent (i)->getBottom());
-
- return y;
- }
-
- class ChannelSelectorListBox : public ListBox,
- public ListBoxModel
- {
- public:
- enum BoxType
- {
- audioInputType,
- audioOutputType
- };
-
- ChannelSelectorListBox (const AudioIODeviceType::DeviceSetupDetails& setup_,
- const BoxType type_,
- const String& noItemsMessage_)
- : ListBox (String::empty, 0),
- setup (setup_),
- type (type_),
- noItemsMessage (noItemsMessage_)
- {
- refresh();
- setModel (this);
- setOutlineThickness (1);
- }
-
- ~ChannelSelectorListBox()
- {
- }
-
- void refresh()
- {
- items.clear();
-
- AudioIODevice* const currentDevice = setup.manager->getCurrentAudioDevice();
-
- if (currentDevice != 0)
- {
- if (type == audioInputType)
- items = currentDevice->getInputChannelNames();
- else if (type == audioOutputType)
- items = currentDevice->getOutputChannelNames();
-
- if (setup.useStereoPairs)
- {
- StringArray pairs;
-
- for (int i = 0; i < items.size(); i += 2)
- {
- String name (items[i]);
- String name2 (items[i + 1]);
-
- String commonBit;
-
- for (int j = 0; j < name.length(); ++j)
- if (name.substring (0, j).equalsIgnoreCase (name2.substring (0, j)))
- commonBit = name.substring (0, j);
-
- pairs.add (name.trim()
- + " + "
- + name2.substring (commonBit.length()).trim());
- }
-
- items = pairs;
- }
- }
-
- updateContent();
- repaint();
- }
-
- int getNumRows()
- {
- return items.size();
- }
-
- void paintListBoxItem (int row,
- Graphics& g,
- int width, int height,
- bool rowIsSelected)
- {
- if (((unsigned int) row) < (unsigned int) items.size())
- {
- if (rowIsSelected)
- g.fillAll (findColour (TextEditor::highlightColourId)
- .withMultipliedAlpha (0.3f));
-
- const String item (items [row]);
- bool enabled = false;
-
- AudioDeviceManager::AudioDeviceSetup config;
- setup.manager->getAudioDeviceSetup (config);
-
- if (setup.useStereoPairs)
- {
- if (type == audioInputType)
- enabled = config.inputChannels [row * 2] || config.inputChannels [row * 2 + 1];
- else if (type == audioOutputType)
- enabled = config.outputChannels [row * 2] || config.outputChannels [row * 2 + 1];
- }
- else
- {
- if (type == audioInputType)
- enabled = config.inputChannels [row];
- else if (type == audioOutputType)
- enabled = config.outputChannels [row];
- }
-
- const int x = getTickX();
- const int tickW = height - height / 4;
-
- getLookAndFeel().drawTickBox (g, *this, x - tickW, (height - tickW) / 2, tickW, tickW,
- enabled, true, true, false);
-
- g.setFont (height * 0.6f);
- g.setColour (findColour (ListBox::textColourId, true).withMultipliedAlpha (enabled ? 1.0f : 0.6f));
- g.drawText (item, x, 0, width - x - 2, height, Justification::centredLeft, true);
- }
- }
-
- void listBoxItemClicked (int row, const MouseEvent& e)
- {
- selectRow (row);
-
- if (e.x < getTickX())
- flipEnablement (row);
- }
-
- void listBoxItemDoubleClicked (int row, const MouseEvent&)
- {
- flipEnablement (row);
- }
-
- void returnKeyPressed (int row)
- {
- flipEnablement (row);
- }
-
- void paint (Graphics& g)
- {
- ListBox::paint (g);
-
- if (items.size() == 0)
- {
- g.setColour (Colours::grey);
- g.setFont (13.0f);
- g.drawText (noItemsMessage,
- 0, 0, getWidth(), getHeight() / 2,
- Justification::centred, true);
- }
- }
-
- int getBestHeight (int maxHeight)
- {
- return getRowHeight() * jlimit (2, jmax (2, maxHeight / getRowHeight()),
- getNumRows())
- + getOutlineThickness() * 2;
- }
-
- juce_UseDebuggingNewOperator
-
- private:
- const AudioIODeviceType::DeviceSetupDetails setup;
- const BoxType type;
- const String noItemsMessage;
- StringArray items;
-
- void flipEnablement (const int row)
- {
- jassert (type == audioInputType || type == audioOutputType);
-
- if (((unsigned int) row) < (unsigned int) items.size())
- {
- AudioDeviceManager::AudioDeviceSetup config;
- setup.manager->getAudioDeviceSetup (config);
-
- if (setup.useStereoPairs)
- {
- BitArray bits;
- BitArray& original = (type == audioInputType ? config.inputChannels
- : config.outputChannels);
-
- int i;
- for (i = 0; i < 256; i += 2)
- bits.setBit (i / 2, original [i] || original [i + 1]);
-
- if (type == audioInputType)
- {
- config.useDefaultInputChannels = false;
- flipBit (bits, row, setup.minNumInputChannels / 2, setup.maxNumInputChannels / 2);
- }
- else
- {
- config.useDefaultOutputChannels = false;
- flipBit (bits, row, setup.minNumOutputChannels / 2, setup.maxNumOutputChannels / 2);
- }
-
- for (i = 0; i < 256; ++i)
- original.setBit (i, bits [i / 2]);
- }
- else
- {
- if (type == audioInputType)
- {
- config.useDefaultInputChannels = false;
- flipBit (config.inputChannels, row, setup.minNumInputChannels, setup.maxNumInputChannels);
- }
- else
- {
- config.useDefaultOutputChannels = false;
- flipBit (config.outputChannels, row, setup.minNumOutputChannels, setup.maxNumOutputChannels);
- }
- }
-
- String error (setup.manager->setAudioDeviceSetup (config, true));
-
- if (! error.isEmpty())
- {
- //xxx
- }
- }
- }
-
- static void flipBit (BitArray& chans, int index, int minNumber, int maxNumber)
- {
- const int numActive = chans.countNumberOfSetBits();
-
- if (chans [index])
- {
- if (numActive > minNumber)
- chans.setBit (index, false);
- }
- else
- {
- if (numActive >= maxNumber)
- {
- const int firstActiveChan = chans.findNextSetBit();
-
- chans.setBit (index > firstActiveChan
- ? firstActiveChan : chans.getHighestBit(),
- false);
- }
-
- chans.setBit (index, true);
- }
- }
-
- int getTickX() const throw()
- {
- return getRowHeight() + 5;
- }
-
- ChannelSelectorListBox (const ChannelSelectorListBox&);
- const ChannelSelectorListBox& operator= (const ChannelSelectorListBox&);
- };
-
- ChannelSelectorListBox* inputChanList;
- ChannelSelectorListBox* outputChanList;
-
- AudioDeviceSettingsPanel (const AudioDeviceSettingsPanel&);
- const AudioDeviceSettingsPanel& operator= (const AudioDeviceSettingsPanel&);
- };
-
- AudioDeviceSelectorComponent::AudioDeviceSelectorComponent (AudioDeviceManager& deviceManager_,
- const int minInputChannels_,
- const int maxInputChannels_,
- const int minOutputChannels_,
- const int maxOutputChannels_,
- const bool showMidiInputOptions,
- const bool showMidiOutputSelector,
- const bool showChannelsAsStereoPairs_,
- const bool hideAdvancedOptionsWithButton_)
- : deviceManager (deviceManager_),
- minOutputChannels (minOutputChannels_),
- maxOutputChannels (maxOutputChannels_),
- minInputChannels (minInputChannels_),
- maxInputChannels (maxInputChannels_),
- showChannelsAsStereoPairs (showChannelsAsStereoPairs_),
- hideAdvancedOptionsWithButton (hideAdvancedOptionsWithButton_),
- deviceTypeDropDown (0),
- deviceTypeDropDownLabel (0),
- audioDeviceSettingsComp (0)
- {
- jassert (minOutputChannels >= 0 && minOutputChannels <= maxOutputChannels);
- jassert (minInputChannels >= 0 && minInputChannels <= maxInputChannels);
-
- if (deviceManager_.getAvailableDeviceTypes().size() > 1)
- {
- deviceTypeDropDown = new ComboBox (String::empty);
-
- for (int i = 0; i < deviceManager_.getAvailableDeviceTypes().size(); ++i)
- {
- deviceTypeDropDown
- ->addItem (deviceManager_.getAvailableDeviceTypes().getUnchecked(i)->getTypeName(),
- i + 1);
- }
-
- addAndMakeVisible (deviceTypeDropDown);
- deviceTypeDropDown->addListener (this);
-
- deviceTypeDropDownLabel = new Label (String::empty, TRANS ("audio device type:"));
- deviceTypeDropDownLabel->setJustificationType (Justification::centredRight);
- deviceTypeDropDownLabel->attachToComponent (deviceTypeDropDown, true);
- }
-
- if (showMidiInputOptions)
- {
- addAndMakeVisible (midiInputsList
- = new MidiInputSelectorComponentListBox (deviceManager,
- TRANS("(no midi inputs available)"),
- 0, 0));
-
- midiInputsLabel = new Label (String::empty, TRANS ("active midi inputs:"));
- midiInputsLabel->setJustificationType (Justification::topRight);
- midiInputsLabel->attachToComponent (midiInputsList, true);
- }
- else
- {
- midiInputsList = 0;
- midiInputsLabel = 0;
- }
-
- if (showMidiOutputSelector)
- {
- addAndMakeVisible (midiOutputSelector = new ComboBox (String::empty));
- midiOutputSelector->addListener (this);
-
- midiOutputLabel = new Label ("lm", TRANS("Midi Output:"));
- midiOutputLabel->attachToComponent (midiOutputSelector, true);
- }
- else
- {
- midiOutputSelector = 0;
- midiOutputLabel = 0;
- }
-
- deviceManager_.addChangeListener (this);
- changeListenerCallback (0);
- }
-
- AudioDeviceSelectorComponent::~AudioDeviceSelectorComponent()
- {
- deviceManager.removeChangeListener (this);
- deleteAllChildren();
- }
-
- void AudioDeviceSelectorComponent::resized()
- {
- const int lx = proportionOfWidth (0.35f);
- const int w = proportionOfWidth (0.4f);
- const int h = 24;
- const int space = 6;
- const int dh = h + space;
- int y = 15;
-
- if (deviceTypeDropDown != 0)
- {
- deviceTypeDropDown->setBounds (lx, y, proportionOfWidth (0.3f), h);
- y += dh + space * 2;
- }
-
- if (audioDeviceSettingsComp != 0)
- {
- audioDeviceSettingsComp->setBounds (0, y, getWidth(), audioDeviceSettingsComp->getHeight());
- y += audioDeviceSettingsComp->getHeight() + space;
- }
-
- if (midiInputsList != 0)
- {
- const int bh = midiInputsList->getBestHeight (jmin (h * 8, getHeight() - y - space));
- midiInputsList->setBounds (lx, y, w, bh);
- y += bh + space;
- }
-
- if (midiOutputSelector != 0)
- midiOutputSelector->setBounds (lx, y, w, h);
- }
-
- void AudioDeviceSelectorComponent::buttonClicked (Button*)
- {
- AudioIODevice* const device = deviceManager.getCurrentAudioDevice();
-
- if (device != 0 && device->hasControlPanel())
- {
- if (device->showControlPanel())
- deviceManager.restartLastAudioDevice();
-
- getTopLevelComponent()->toFront (true);
- }
- }
-
- void AudioDeviceSelectorComponent::comboBoxChanged (ComboBox* comboBoxThatHasChanged)
- {
- if (comboBoxThatHasChanged == deviceTypeDropDown)
- {
- AudioIODeviceType* const type = deviceManager.getAvailableDeviceTypes() [deviceTypeDropDown->getSelectedId() - 1];
-
- if (type != 0)
- {
- deleteAndZero (audioDeviceSettingsComp);
-
- deviceManager.setCurrentAudioDeviceType (type->getTypeName(), true);
-
- changeListenerCallback (0); // needed in case the type hasn't actally changed
- }
- }
- else if (comboBoxThatHasChanged == midiOutputSelector)
- {
- deviceManager.setDefaultMidiOutput (midiOutputSelector->getText());
- }
- }
-
- void AudioDeviceSelectorComponent::changeListenerCallback (void*)
- {
- if (deviceTypeDropDown != 0)
- {
- deviceTypeDropDown->setText (deviceManager.getCurrentAudioDeviceType(), false);
- }
-
- if (audioDeviceSettingsComp == 0
- || audioDeviceSettingsCompType != deviceManager.getCurrentAudioDeviceType())
- {
- audioDeviceSettingsCompType = deviceManager.getCurrentAudioDeviceType();
-
- deleteAndZero (audioDeviceSettingsComp);
-
- AudioIODeviceType* const type
- = deviceManager.getAvailableDeviceTypes() [deviceTypeDropDown == 0
- ? 0 : deviceTypeDropDown->getSelectedId() - 1];
-
- if (type != 0)
- {
- AudioIODeviceType::DeviceSetupDetails details;
- details.manager = &deviceManager;
- details.minNumInputChannels = minInputChannels;
- details.maxNumInputChannels = maxInputChannels;
- details.minNumOutputChannels = minOutputChannels;
- details.maxNumOutputChannels = maxOutputChannels;
- details.useStereoPairs = showChannelsAsStereoPairs;
-
- audioDeviceSettingsComp = new AudioDeviceSettingsPanel (type, details, hideAdvancedOptionsWithButton);
-
- if (audioDeviceSettingsComp != 0)
- {
- addAndMakeVisible (audioDeviceSettingsComp);
- audioDeviceSettingsComp->resized();
- }
- }
- }
-
- if (midiInputsList != 0)
- {
- midiInputsList->updateContent();
- midiInputsList->repaint();
- }
-
- if (midiOutputSelector != 0)
- {
- midiOutputSelector->clear();
-
- const StringArray midiOuts (MidiOutput::getDevices());
-
- midiOutputSelector->addItem (TRANS("<< none >>"), -1);
- midiOutputSelector->addSeparator();
-
- for (int i = 0; i < midiOuts.size(); ++i)
- midiOutputSelector->addItem (midiOuts[i], i + 1);
-
- int current = -1;
-
- if (deviceManager.getDefaultMidiOutput() != 0)
- current = 1 + midiOuts.indexOf (deviceManager.getDefaultMidiOutputName());
-
- midiOutputSelector->setSelectedId (current, true);
- }
-
- resized();
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_AudioDeviceSelectorComponent.cpp *********/
-
- /********* Start of inlined file: juce_BubbleComponent.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- BubbleComponent::BubbleComponent()
- : side (0),
- allowablePlacements (above | below | left | right),
- arrowTipX (0.0f),
- arrowTipY (0.0f)
- {
- setInterceptsMouseClicks (false, false);
-
- shadow.setShadowProperties (5.0f, 0.35f, 0, 0);
- setComponentEffect (&shadow);
- }
-
- BubbleComponent::~BubbleComponent()
- {
- }
-
- void BubbleComponent::paint (Graphics& g)
- {
- int x = content.getX();
- int y = content.getY();
- int w = content.getWidth();
- int h = content.getHeight();
-
- int cw, ch;
- getContentSize (cw, ch);
-
- if (side == 3)
- x += w - cw;
- else if (side != 1)
- x += (w - cw) / 2;
-
- w = cw;
-
- if (side == 2)
- y += h - ch;
- else if (side != 0)
- y += (h - ch) / 2;
-
- h = ch;
-
- getLookAndFeel().drawBubble (g, arrowTipX, arrowTipY,
- (float) x, (float) y,
- (float) w, (float) h);
-
- const int cx = x + (w - cw) / 2;
- const int cy = y + (h - ch) / 2;
-
- const int indent = 3;
-
- g.setOrigin (cx + indent, cy + indent);
- g.reduceClipRegion (0, 0, cw - indent * 2, ch - indent * 2);
-
- paintContent (g, cw - indent * 2, ch - indent * 2);
- }
-
- void BubbleComponent::setAllowedPlacement (const int newPlacement)
- {
- allowablePlacements = newPlacement;
- }
-
- void BubbleComponent::setPosition (Component* componentToPointTo)
- {
- jassert (componentToPointTo->isValidComponent());
-
- int tx = 0;
- int ty = 0;
-
- if (getParentComponent() != 0)
- componentToPointTo->relativePositionToOtherComponent (getParentComponent(), tx, ty);
- else
- componentToPointTo->relativePositionToGlobal (tx, ty);
-
- setPosition (Rectangle (tx, ty, componentToPointTo->getWidth(), componentToPointTo->getHeight()));
- }
-
- void BubbleComponent::setPosition (const int arrowTipX,
- const int arrowTipY)
- {
- setPosition (Rectangle (arrowTipX, arrowTipY, 1, 1));
- }
-
- void BubbleComponent::setPosition (const Rectangle& rectangleToPointTo)
- {
- Rectangle availableSpace;
-
- if (getParentComponent() != 0)
- {
- availableSpace.setSize (getParentComponent()->getWidth(),
- getParentComponent()->getHeight());
- }
- else
- {
- availableSpace = getParentMonitorArea();
- }
-
- int x = 0;
- int y = 0;
- int w = 150;
- int h = 30;
-
- getContentSize (w, h);
- w += 30;
- h += 30;
-
- const float edgeIndent = 2.0f;
- const int arrowLength = jmin (10, h / 3, w / 3);
-
- int spaceAbove = ((allowablePlacements & above) != 0) ? jmax (0, rectangleToPointTo.getY() - availableSpace.getY()) : -1;
- int spaceBelow = ((allowablePlacements & below) != 0) ? jmax (0, availableSpace.getBottom() - rectangleToPointTo.getBottom()) : -1;
- int spaceLeft = ((allowablePlacements & left) != 0) ? jmax (0, rectangleToPointTo.getX() - availableSpace.getX()) : -1;
- int spaceRight = ((allowablePlacements & right) != 0) ? jmax (0, availableSpace.getRight() - rectangleToPointTo.getRight()) : -1;
-
- // look at whether the component is elongated, and if so, try to position next to its longer dimension.
- if (rectangleToPointTo.getWidth() > rectangleToPointTo.getHeight() * 2
- && (spaceAbove > h + 20 || spaceBelow > h + 20))
- {
- spaceLeft = spaceRight = 0;
- }
- else if (rectangleToPointTo.getWidth() < rectangleToPointTo.getHeight() / 2
- && (spaceLeft > w + 20 || spaceRight > w + 20))
- {
- spaceAbove = spaceBelow = 0;
- }
-
- if (jmax (spaceAbove, spaceBelow) >= jmax (spaceLeft, spaceRight))
- {
- x = rectangleToPointTo.getX() + (rectangleToPointTo.getWidth() - w) / 2;
- arrowTipX = w * 0.5f;
- content.setSize (w, h - arrowLength);
-
- if (spaceAbove >= spaceBelow)
- {
- // above
- y = rectangleToPointTo.getY() - h;
- content.setPosition (0, 0);
- arrowTipY = h - edgeIndent;
- side = 2;
- }
- else
- {
- // below
- y = rectangleToPointTo.getBottom();
- content.setPosition (0, arrowLength);
- arrowTipY = edgeIndent;
- side = 0;
- }
- }
- else
- {
- y = rectangleToPointTo.getY() + (rectangleToPointTo.getHeight() - h) / 2;
- arrowTipY = h * 0.5f;
- content.setSize (w - arrowLength, h);
-
- if (spaceLeft > spaceRight)
- {
- // on the left
- x = rectangleToPointTo.getX() - w;
- content.setPosition (0, 0);
- arrowTipX = w - edgeIndent;
- side = 3;
- }
- else
- {
- // on the right
- x = rectangleToPointTo.getRight();
- content.setPosition (arrowLength, 0);
- arrowTipX = edgeIndent;
- side = 1;
- }
- }
-
- setBounds (x, y, w, h);
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_BubbleComponent.cpp *********/
-
- /********* Start of inlined file: juce_BubbleMessageComponent.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- BubbleMessageComponent::BubbleMessageComponent (int fadeOutLengthMs)
- : fadeOutLength (fadeOutLengthMs),
- deleteAfterUse (false)
- {
- }
-
- BubbleMessageComponent::~BubbleMessageComponent()
- {
- fadeOutComponent (fadeOutLength);
- }
-
- void BubbleMessageComponent::showAt (int x, int y,
- const String& text,
- const int numMillisecondsBeforeRemoving,
- const bool removeWhenMouseClicked,
- const bool deleteSelfAfterUse)
- {
- textLayout.clear();
- textLayout.setText (text, Font (14.0f));
- textLayout.layout (256, Justification::centredLeft, true);
-
- setPosition (x, y);
-
- init (numMillisecondsBeforeRemoving, removeWhenMouseClicked, deleteSelfAfterUse);
- }
-
- void BubbleMessageComponent::showAt (Component* const component,
- const String& text,
- const int numMillisecondsBeforeRemoving,
- const bool removeWhenMouseClicked,
- const bool deleteSelfAfterUse)
- {
- textLayout.clear();
- textLayout.setText (text, Font (14.0f));
- textLayout.layout (256, Justification::centredLeft, true);
-
- setPosition (component);
-
- init (numMillisecondsBeforeRemoving, removeWhenMouseClicked, deleteSelfAfterUse);
- }
-
- void BubbleMessageComponent::init (const int numMillisecondsBeforeRemoving,
- const bool removeWhenMouseClicked,
- const bool deleteSelfAfterUse)
- {
- setVisible (true);
-
- deleteAfterUse = deleteSelfAfterUse;
-
- if (numMillisecondsBeforeRemoving > 0)
- expiryTime = Time::getMillisecondCounter() + numMillisecondsBeforeRemoving;
- else
- expiryTime = 0;
-
- startTimer (77);
-
- mouseClickCounter = Desktop::getInstance().getMouseButtonClickCounter();
-
- if (! (removeWhenMouseClicked && isShowing()))
- mouseClickCounter += 0xfffff;
-
- repaint();
- }
-
- void BubbleMessageComponent::getContentSize (int& w, int& h)
- {
- w = textLayout.getWidth() + 16;
- h = textLayout.getHeight() + 16;
- }
-
- void BubbleMessageComponent::paintContent (Graphics& g, int w, int h)
- {
- g.setColour (findColour (TooltipWindow::textColourId));
-
- textLayout.drawWithin (g, 0, 0, w, h, Justification::centred);
- }
-
- void BubbleMessageComponent::timerCallback()
- {
- if (Desktop::getInstance().getMouseButtonClickCounter() > mouseClickCounter)
- {
- stopTimer();
- setVisible (false);
-
- if (deleteAfterUse)
- delete this;
- }
- else if (expiryTime != 0 && Time::getMillisecondCounter() > expiryTime)
- {
- stopTimer();
- fadeOutComponent (fadeOutLength);
-
- if (deleteAfterUse)
- delete this;
- }
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_BubbleMessageComponent.cpp *********/
-
- /********* Start of inlined file: juce_ColourSelector.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- static const int swatchesPerRow = 8;
- static const int swatchHeight = 22;
-
- class ColourComponentSlider : public Slider
- {
- public:
- ColourComponentSlider (const String& name)
- : Slider (name)
- {
- setRange (0.0, 255.0, 1.0);
- }
-
- ~ColourComponentSlider()
- {
- }
-
- const String getTextFromValue (double currentValue)
- {
- return String::formatted (T("%02X"), (int)currentValue);
- }
-
- double getValueFromText (const String& text)
- {
- return (double) text.getHexValue32();
- }
-
- private:
- ColourComponentSlider (const ColourComponentSlider&);
- const ColourComponentSlider& operator= (const ColourComponentSlider&);
- };
-
- class ColourSpaceMarker : public Component
- {
- public:
- ColourSpaceMarker()
- {
- setInterceptsMouseClicks (false, false);
- }
-
- ~ColourSpaceMarker()
- {
- }
-
- void paint (Graphics& g)
- {
- g.setColour (Colour::greyLevel (0.1f));
- g.drawEllipse (1.0f, 1.0f, getWidth() - 2.0f, getHeight() - 2.0f, 1.0f);
- g.setColour (Colour::greyLevel (0.9f));
- g.drawEllipse (2.0f, 2.0f, getWidth() - 4.0f, getHeight() - 4.0f, 1.0f);
- }
-
- private:
- ColourSpaceMarker (const ColourSpaceMarker&);
- const ColourSpaceMarker& operator= (const ColourSpaceMarker&);
- };
-
- class ColourSpaceView : public Component
- {
- ColourSelector* const owner;
- float& h;
- float& s;
- float& v;
- float lastHue;
- ColourSpaceMarker* marker;
- const int edge;
-
- public:
- ColourSpaceView (ColourSelector* owner_,
- float& h_, float& s_, float& v_,
- const int edgeSize)
- : owner (owner_),
- h (h_), s (s_), v (v_),
- lastHue (0.0f),
- edge (edgeSize)
- {
- addAndMakeVisible (marker = new ColourSpaceMarker());
- setMouseCursor (MouseCursor::CrosshairCursor);
- }
-
- ~ColourSpaceView()
- {
- deleteAllChildren();
- }
-
- void paint (Graphics& g)
- {
- const float hue = h;
-
- const float xScale = 1.0f / (getWidth() - edge * 2);
- const float yScale = 1.0f / (getHeight() - edge * 2);
-
- const Rectangle clip (g.getClipBounds());
- const int x1 = jmax (clip.getX(), edge) & ~1;
- const int x2 = jmin (clip.getRight(), getWidth() - edge) | 1;
- const int y1 = jmax (clip.getY(), edge) & ~1;
- const int y2 = jmin (clip.getBottom(), getHeight() - edge) | 1;
-
- for (int y = y1; y < y2; y += 2)
- {
- const float v = jlimit (0.0f, 1.0f, 1.0f - (y - edge) * yScale);
-
- for (int x = x1; x < x2; x += 2)
- {
- const float s = jlimit (0.0f, 1.0f, (x - edge) * xScale);
- g.setColour (Colour (hue, s, v, 1.0f));
- g.fillRect (x, y, 2, 2);
- }
- }
- }
-
- void mouseDown (const MouseEvent& e)
- {
- mouseDrag (e);
- }
-
- void mouseDrag (const MouseEvent& e)
- {
- const float s = (e.x - edge) / (float) (getWidth() - edge * 2);
- const float v = 1.0f - (e.y - edge) / (float) (getHeight() - edge * 2);
-
- owner->setSV (s, v);
- }
-
- void updateIfNeeded()
- {
- if (lastHue != h)
- {
- lastHue = h;
- repaint();
- }
-
- resized();
- }
-
- void resized()
- {
- marker->setBounds (roundFloatToInt ((getWidth() - edge * 2) * s),
- roundFloatToInt ((getHeight() - edge * 2) * (1.0f - v)),
- edge * 2, edge * 2);
- }
-
- private:
- ColourSpaceView (const ColourSpaceView&);
- const ColourSpaceView& operator= (const ColourSpaceView&);
- };
-
- class HueSelectorMarker : public Component
- {
- public:
- HueSelectorMarker()
- {
- setInterceptsMouseClicks (false, false);
- }
-
- ~HueSelectorMarker()
- {
- }
-
- void paint (Graphics& g)
- {
- Path p;
- p.addTriangle (1.0f, 1.0f,
- getWidth() * 0.3f, getHeight() * 0.5f,
- 1.0f, getHeight() - 1.0f);
-
- p.addTriangle (getWidth() - 1.0f, 1.0f,
- getWidth() * 0.7f, getHeight() * 0.5f,
- getWidth() - 1.0f, getHeight() - 1.0f);
-
- g.setColour (Colours::white.withAlpha (0.75f));
- g.fillPath (p);
-
- g.setColour (Colours::black.withAlpha (0.75f));
- g.strokePath (p, PathStrokeType (1.2f));
- }
-
- private:
- HueSelectorMarker (const HueSelectorMarker&);
- const HueSelectorMarker& operator= (const HueSelectorMarker&);
- };
-
- class HueSelectorComp : public Component
- {
- public:
- HueSelectorComp (ColourSelector* owner_,
- float& h_, float& s_, float& v_,
- const int edgeSize)
- : owner (owner_),
- h (h_), s (s_), v (v_),
- lastHue (0.0f),
- edge (edgeSize)
- {
- addAndMakeVisible (marker = new HueSelectorMarker());
- }
-
- ~HueSelectorComp()
- {
- deleteAllChildren();
- }
-
- void paint (Graphics& g)
- {
- const float yScale = 1.0f / (getHeight() - edge * 2);
-
- const Rectangle clip (g.getClipBounds());
-
- for (int y = jmin (clip.getBottom(), getHeight() - edge); --y >= jmax (edge, clip.getY());)
- {
- g.setColour (Colour ((y - edge) * yScale, 1.0f, 1.0f, 1.0f));
- g.fillRect (edge, y, getWidth() - edge * 2, 1);
- }
- }
-
- void resized()
- {
- marker->setBounds (0, roundFloatToInt ((getHeight() - edge * 2) * h),
- getWidth(), edge * 2);
- }
-
- void mouseDown (const MouseEvent& e)
- {
- mouseDrag (e);
- }
-
- void mouseDrag (const MouseEvent& e)
- {
- const float hue = (e.y - edge) / (float) (getHeight() - edge * 2);
-
- owner->setHue (hue);
- }
-
- void updateIfNeeded()
- {
- resized();
- }
-
- private:
- ColourSelector* const owner;
- float& h;
- float& s;
- float& v;
- float lastHue;
- HueSelectorMarker* marker;
- const int edge;
-
- HueSelectorComp (const HueSelectorComp&);
- const HueSelectorComp& operator= (const HueSelectorComp&);
- };
-
- class SwatchComponent : public Component
- {
- public:
- SwatchComponent (ColourSelector* owner_, int index_)
- : owner (owner_),
- index (index_)
- {
- }
-
- ~SwatchComponent()
- {
- }
-
- void paint (Graphics& g)
- {
- const Colour colour (owner->getSwatchColour (index));
-
- g.fillCheckerBoard (0, 0, getWidth(), getHeight(),
- 6, 6,
- Colour (0xffdddddd).overlaidWith (colour),
- Colour (0xffffffff).overlaidWith (colour));
- }
-
- void mouseDown (const MouseEvent&)
- {
- PopupMenu m;
- m.addItem (1, TRANS("Use this swatch as the current colour"));
- m.addSeparator();
- m.addItem (2, TRANS("Set this swatch to the current colour"));
-
- const int r = m.showAt (this);
-
- if (r == 1)
- {
- owner->setCurrentColour (owner->getSwatchColour (index));
- }
- else if (r == 2)
- {
- if (owner->getSwatchColour (index) != owner->getCurrentColour())
- {
- owner->setSwatchColour (index, owner->getCurrentColour());
- repaint();
- }
- }
- }
-
- private:
- ColourSelector* const owner;
- const int index;
-
- SwatchComponent (const SwatchComponent&);
- const SwatchComponent& operator= (const SwatchComponent&);
- };
-
- ColourSelector::ColourSelector (const int flags_,
- const int edgeGap_,
- const int gapAroundColourSpaceComponent)
- : colour (Colours::white),
- flags (flags_),
- topSpace (0),
- edgeGap (edgeGap_)
- {
- // not much point having a selector with no components in it!
- jassert ((flags_ & (showColourAtTop | showSliders | showColourspace)) != 0);
-
- updateHSV();
-
- if ((flags & showSliders) != 0)
- {
- addAndMakeVisible (sliders[0] = new ColourComponentSlider (TRANS ("red")));
- addAndMakeVisible (sliders[1] = new ColourComponentSlider (TRANS ("green")));
- addAndMakeVisible (sliders[2] = new ColourComponentSlider (TRANS ("blue")));
- addChildComponent (sliders[3] = new ColourComponentSlider (TRANS ("alpha")));
-
- sliders[3]->setVisible ((flags & showAlphaChannel) != 0);
-
- for (int i = 4; --i >= 0;)
- sliders[i]->addListener (this);
- }
- else
- {
- zeromem (sliders, sizeof (sliders));
- }
-
- if ((flags & showColourspace) != 0)
- {
- addAndMakeVisible (colourSpace = new ColourSpaceView (this, h, s, v, gapAroundColourSpaceComponent));
- addAndMakeVisible (hueSelector = new HueSelectorComp (this, h, s, v, gapAroundColourSpaceComponent));
- }
- else
- {
- colourSpace = 0;
- hueSelector = 0;
- }
-
- update();
- }
-
- ColourSelector::~ColourSelector()
- {
- dispatchPendingMessages();
- deleteAllChildren();
- }
-
- const Colour ColourSelector::getCurrentColour() const
- {
- return ((flags & showAlphaChannel) != 0) ? colour
- : colour.withAlpha ((uint8) 0xff);
- }
-
- void ColourSelector::setCurrentColour (const Colour& c)
- {
- if (c != colour)
- {
- colour = ((flags & showAlphaChannel) != 0) ? c : c.withAlpha ((uint8) 0xff);
-
- updateHSV();
- update();
- }
- }
-
- void ColourSelector::setHue (float newH)
- {
- newH = jlimit (0.0f, 1.0f, newH);
-
- if (h != newH)
- {
- h = newH;
- colour = Colour (h, s, v, colour.getFloatAlpha());
- update();
- }
- }
-
- void ColourSelector::setSV (float newS, float newV)
- {
- newS = jlimit (0.0f, 1.0f, newS);
- newV = jlimit (0.0f, 1.0f, newV);
-
- if (s != newS || v != newV)
- {
- s = newS;
- v = newV;
- colour = Colour (h, s, v, colour.getFloatAlpha());
- update();
- }
- }
-
- void ColourSelector::updateHSV()
- {
- colour.getHSB (h, s, v);
- }
-
- void ColourSelector::update()
- {
- if (sliders[0] != 0)
- {
- sliders[0]->setValue ((int) colour.getRed());
- sliders[1]->setValue ((int) colour.getGreen());
- sliders[2]->setValue ((int) colour.getBlue());
- sliders[3]->setValue ((int) colour.getAlpha());
- }
-
- if (colourSpace != 0)
- {
- ((ColourSpaceView*) colourSpace)->updateIfNeeded();
- ((HueSelectorComp*) hueSelector)->updateIfNeeded();
- }
-
- if ((flags & showColourAtTop) != 0)
- repaint (0, edgeGap, getWidth(), topSpace - edgeGap);
-
- sendChangeMessage (this);
- }
-
- void ColourSelector::paint (Graphics& g)
- {
- g.fillAll (findColour (backgroundColourId));
-
- if ((flags & showColourAtTop) != 0)
- {
- const Colour colour (getCurrentColour());
-
- g.fillCheckerBoard (edgeGap, edgeGap, getWidth() - edgeGap - edgeGap, topSpace - edgeGap - edgeGap,
- 10, 10,
- Colour (0xffdddddd).overlaidWith (colour),
- Colour (0xffffffff).overlaidWith (colour));
-
- g.setColour (Colours::white.overlaidWith (colour).contrasting());
- g.setFont (14.0f, true);
- g.drawText (((flags & showAlphaChannel) != 0)
- ? String::formatted (T("#%02X%02X%02X%02X"),
- (int) colour.getAlpha(),
- (int) colour.getRed(),
- (int) colour.getGreen(),
- (int) colour.getBlue())
- : String::formatted (T("#%02X%02X%02X"),
- (int) colour.getRed(),
- (int) colour.getGreen(),
- (int) colour.getBlue()),
- 0, edgeGap, getWidth(), topSpace - edgeGap * 2,
- Justification::centred, false);
- }
-
- if ((flags & showSliders) != 0)
- {
- g.setColour (findColour (labelTextColourId));
- g.setFont (11.0f);
-
- for (int i = 4; --i >= 0;)
- {
- if (sliders[i]->isVisible())
- g.drawText (sliders[i]->getName() + T(":"),
- 0, sliders[i]->getY(),
- sliders[i]->getX() - 8, sliders[i]->getHeight(),
- Justification::centredRight, false);
- }
- }
- }
-
- void ColourSelector::resized()
- {
- const int numSliders = ((flags & showAlphaChannel) != 0) ? 4 : 3;
- const int numSwatches = getNumSwatches();
-
- const int swatchSpace = numSwatches > 0 ? edgeGap + swatchHeight * ((numSwatches + 7) / swatchesPerRow) : 0;
- const int sliderSpace = ((flags & showSliders) != 0) ? jmin (22 * numSliders + edgeGap, proportionOfHeight (0.3f)) : 0;
- topSpace = ((flags & showColourAtTop) != 0) ? jmin (30 + edgeGap * 2, proportionOfHeight (0.2f)) : edgeGap;
-
- int y = topSpace;
-
- if ((flags & showColourspace) != 0)
- {
- const int hueWidth = jmin (50, proportionOfWidth (0.15f));
-
- colourSpace->setBounds (edgeGap, y,
- getWidth() - hueWidth - edgeGap - 4,
- getHeight() - topSpace - sliderSpace - swatchSpace - edgeGap);
-
- hueSelector->setBounds (colourSpace->getRight() + 4, y,
- getWidth() - edgeGap - (colourSpace->getRight() + 4),
- colourSpace->getHeight());
-
- y = getHeight() - sliderSpace - swatchSpace - edgeGap;
- }
-
- if ((flags & showSliders) != 0)
- {
- const int sliderHeight = jmax (4, sliderSpace / numSliders);
-
- for (int i = 0; i < numSliders; ++i)
- {
- sliders[i]->setBounds (proportionOfWidth (0.2f), y,
- proportionOfWidth (0.72f), sliderHeight - 2);
-
- y += sliderHeight;
- }
- }
-
- if (numSwatches > 0)
- {
- const int startX = 8;
- const int xGap = 4;
- const int yGap = 4;
- const int swatchWidth = (getWidth() - startX * 2) / swatchesPerRow;
- y += edgeGap;
-
- if (swatchComponents.size() != numSwatches)
- {
- int i;
- for (i = swatchComponents.size(); --i >= 0;)
- {
- SwatchComponent* const sc = (SwatchComponent*) swatchComponents.getUnchecked(i);
- delete sc;
- }
-
- for (i = 0; i < numSwatches; ++i)
- {
- SwatchComponent* const sc = new SwatchComponent (this, i);
- swatchComponents.add (sc);
- addAndMakeVisible (sc);
- }
- }
-
- int x = startX;
-
- for (int i = 0; i < swatchComponents.size(); ++i)
- {
- SwatchComponent* const sc = (SwatchComponent*) swatchComponents.getUnchecked(i);
-
- sc->setBounds (x + xGap / 2,
- y + yGap / 2,
- swatchWidth - xGap,
- swatchHeight - yGap);
-
- if (((i + 1) % swatchesPerRow) == 0)
- {
- x = startX;
- y += swatchHeight;
- }
- else
- {
- x += swatchWidth;
- }
- }
- }
- }
-
- void ColourSelector::sliderValueChanged (Slider*)
- {
- if (sliders[0] != 0)
- setCurrentColour (Colour ((uint8) sliders[0]->getValue(),
- (uint8) sliders[1]->getValue(),
- (uint8) sliders[2]->getValue(),
- (uint8) sliders[3]->getValue()));
- }
-
- int ColourSelector::getNumSwatches() const
- {
- return 0;
- }
-
- const Colour ColourSelector::getSwatchColour (const int) const
- {
- jassertfalse // if you've overridden getNumSwatches(), you also need to implement this method
- return Colours::black;
- }
-
- void ColourSelector::setSwatchColour (const int, const Colour&) const
- {
- jassertfalse // if you've overridden getNumSwatches(), you also need to implement this method
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_ColourSelector.cpp *********/
-
- /********* Start of inlined file: juce_DropShadower.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- class ShadowWindow : public Component
- {
- Component* owner;
- Image** shadowImageSections;
- const int type; // 0 = left, 1 = right, 2 = top, 3 = bottom. left + right are full-height
-
- public:
- ShadowWindow (Component* const owner_,
- const int type_,
- Image** const shadowImageSections_)
- : owner (owner_),
- shadowImageSections (shadowImageSections_),
- type (type_)
- {
- setInterceptsMouseClicks (false, false);
-
- if (owner_->isOnDesktop())
- {
- setSize (1, 1); // to keep the OS happy by not having zero-size windows
- addToDesktop (ComponentPeer::windowIgnoresMouseClicks
- | ComponentPeer::windowIsTemporary);
- }
- else if (owner_->getParentComponent() != 0)
- {
- owner_->getParentComponent()->addChildComponent (this);
- }
- }
-
- ~ShadowWindow()
- {
- }
-
- void paint (Graphics& g)
- {
- Image* const topLeft = shadowImageSections [type * 3];
- Image* const bottomRight = shadowImageSections [type * 3 + 1];
- Image* const filler = shadowImageSections [type * 3 + 2];
- ImageBrush fillBrush (filler, 0, 0, 1.0f);
-
- g.setOpacity (1.0f);
-
- if (type < 2)
- {
- int imH = jmin (topLeft->getHeight(), getHeight() / 2);
- g.drawImage (topLeft,
- 0, 0, topLeft->getWidth(), imH,
- 0, 0, topLeft->getWidth(), imH);
-
- imH = jmin (bottomRight->getHeight(), getHeight() - getHeight() / 2);
- g.drawImage (bottomRight,
- 0, getHeight() - imH, bottomRight->getWidth(), imH,
- 0, bottomRight->getHeight() - imH, bottomRight->getWidth(), imH);
-
- g.setBrush (&fillBrush);
- g.fillRect (0, topLeft->getHeight(), getWidth(), getHeight() - (topLeft->getHeight() + bottomRight->getHeight()));
- }
- else
- {
- int imW = jmin (topLeft->getWidth(), getWidth() / 2);
- g.drawImage (topLeft,
- 0, 0, imW, topLeft->getHeight(),
- 0, 0, imW, topLeft->getHeight());
-
- imW = jmin (bottomRight->getWidth(), getWidth() - getWidth() / 2);
- g.drawImage (bottomRight,
- getWidth() - imW, 0, imW, bottomRight->getHeight(),
- bottomRight->getWidth() - imW, 0, imW, bottomRight->getHeight());
-
- g.setBrush (&fillBrush);
- g.fillRect (topLeft->getWidth(), 0, getWidth() - (topLeft->getWidth() + bottomRight->getWidth()), getHeight());
- }
- }
-
- void resized()
- {
- repaint(); // (needed for correct repainting)
- }
-
- private:
- ShadowWindow (const ShadowWindow&);
- const ShadowWindow& operator= (const ShadowWindow&);
- };
-
- DropShadower::DropShadower (const float alpha_,
- const int xOffset_,
- const int yOffset_,
- const float blurRadius_)
- : owner (0),
- numShadows (0),
- shadowEdge (jmax (xOffset_, yOffset_) + (int) blurRadius_),
- xOffset (xOffset_),
- yOffset (yOffset_),
- alpha (alpha_),
- blurRadius (blurRadius_),
- inDestructor (false),
- reentrant (false)
- {
- }
-
- DropShadower::~DropShadower()
- {
- if (owner != 0)
- owner->removeComponentListener (this);
-
- inDestructor = true;
-
- deleteShadowWindows();
- }
-
- void DropShadower::deleteShadowWindows()
- {
- if (numShadows > 0)
- {
- int i;
- for (i = numShadows; --i >= 0;)
- delete shadowWindows[i];
-
- for (i = 12; --i >= 0;)
- delete shadowImageSections[i];
-
- numShadows = 0;
- }
- }
-
- void DropShadower::setOwner (Component* componentToFollow)
- {
- if (componentToFollow != owner)
- {
- if (owner != 0)
- owner->removeComponentListener (this);
-
- // (the component can't be null)
- jassert (componentToFollow != 0);
-
- owner = componentToFollow;
-
- jassert (owner != 0);
- jassert (owner->isOpaque()); // doesn't work properly for semi-transparent comps!
-
- owner->addComponentListener (this);
-
- updateShadows();
- }
- }
-
- void DropShadower::componentMovedOrResized (Component&, bool /*wasMoved*/, bool /*wasResized*/)
- {
- updateShadows();
- }
-
- void DropShadower::componentBroughtToFront (Component&)
- {
- bringShadowWindowsToFront();
- }
-
- void DropShadower::componentChildrenChanged (Component&)
- {
- }
-
- void DropShadower::componentParentHierarchyChanged (Component&)
- {
- deleteShadowWindows();
- updateShadows();
- }
-
- void DropShadower::componentVisibilityChanged (Component&)
- {
- updateShadows();
- }
-
- void DropShadower::updateShadows()
- {
- if (reentrant || inDestructor || (owner == 0))
- return;
-
- reentrant = true;
-
- ComponentPeer* const nw = owner->getPeer();
-
- const bool isOwnerVisible = owner->isVisible()
- && (nw == 0 || ! nw->isMinimised());
-
- const bool createShadowWindows = numShadows == 0
- && owner->getWidth() > 0
- && owner->getHeight() > 0
- && isOwnerVisible
- && (Desktop::canUseSemiTransparentWindows()
- || owner->getParentComponent() != 0);
-
- if (createShadowWindows)
- {
- // keep a cached version of the image to save doing the gaussian too often
- String imageId;
- imageId << shadowEdge << T(',')
- << xOffset << T(',')
- << yOffset << T(',')
- << alpha;
-
- const int hash = imageId.hashCode();
-
- Image* bigIm = ImageCache::getFromHashCode (hash);
-
- if (bigIm == 0)
- {
- bigIm = new Image (Image::ARGB, shadowEdge * 5, shadowEdge * 5, true);
-
- Graphics bigG (*bigIm);
- bigG.setColour (Colours::black.withAlpha (alpha));
- bigG.fillRect (shadowEdge + xOffset,
- shadowEdge + yOffset,
- bigIm->getWidth() - (shadowEdge * 2),
- bigIm->getHeight() - (shadowEdge * 2));
-
- ImageConvolutionKernel blurKernel (roundFloatToInt (blurRadius * 2.0f));
- blurKernel.createGaussianBlur (blurRadius);
-
- blurKernel.applyToImage (*bigIm, 0,
- xOffset,
- yOffset,
- bigIm->getWidth(),
- bigIm->getHeight());
-
- ImageCache::addImageToCache (bigIm, hash);
- }
-
- const int iw = bigIm->getWidth();
- const int ih = bigIm->getHeight();
- const int shadowEdge2 = shadowEdge * 2;
-
- setShadowImage (bigIm, 0, shadowEdge, shadowEdge2, 0, 0);
- setShadowImage (bigIm, 1, shadowEdge, shadowEdge2, 0, ih - shadowEdge2);
- setShadowImage (bigIm, 2, shadowEdge, shadowEdge, 0, shadowEdge2);
- setShadowImage (bigIm, 3, shadowEdge, shadowEdge2, iw - shadowEdge, 0);
- setShadowImage (bigIm, 4, shadowEdge, shadowEdge2, iw - shadowEdge, ih - shadowEdge2);
- setShadowImage (bigIm, 5, shadowEdge, shadowEdge, iw - shadowEdge, shadowEdge2);
- setShadowImage (bigIm, 6, shadowEdge, shadowEdge, shadowEdge, 0);
- setShadowImage (bigIm, 7, shadowEdge, shadowEdge, iw - shadowEdge2, 0);
- setShadowImage (bigIm, 8, shadowEdge, shadowEdge, shadowEdge2, 0);
- setShadowImage (bigIm, 9, shadowEdge, shadowEdge, shadowEdge, ih - shadowEdge);
- setShadowImage (bigIm, 10, shadowEdge, shadowEdge, iw - shadowEdge2, ih - shadowEdge);
- setShadowImage (bigIm, 11, shadowEdge, shadowEdge, shadowEdge2, ih - shadowEdge);
-
- ImageCache::release (bigIm);
-
- for (int i = 0; i < 4; ++i)
- {
- shadowWindows[numShadows] = new ShadowWindow (owner, i, shadowImageSections);
- ++numShadows;
- }
- }
-
- if (numShadows > 0)
- {
- for (int i = numShadows; --i >= 0;)
- {
- shadowWindows[i]->setAlwaysOnTop (owner->isAlwaysOnTop());
- shadowWindows[i]->setVisible (isOwnerVisible);
- }
-
- const int x = owner->getX();
- const int y = owner->getY() - shadowEdge;
- const int w = owner->getWidth();
- const int h = owner->getHeight() + shadowEdge + shadowEdge;
-
- shadowWindows[0]->setBounds (x - shadowEdge,
- y,
- shadowEdge,
- h);
-
- shadowWindows[1]->setBounds (x + w,
- y,
- shadowEdge,
- h);
-
- shadowWindows[2]->setBounds (x,
- y,
- w,
- shadowEdge);
-
- shadowWindows[3]->setBounds (x,
- owner->getBottom(),
- w,
- shadowEdge);
- }
-
- reentrant = false;
-
- if (createShadowWindows)
- bringShadowWindowsToFront();
- }
-
- void DropShadower::setShadowImage (Image* const src,
- const int num,
- const int w,
- const int h,
- const int sx,
- const int sy) throw()
- {
- shadowImageSections[num] = new Image (Image::ARGB, w, h, true);
-
- Graphics g (*shadowImageSections[num]);
- g.drawImage (src, 0, 0, w, h, sx, sy, w, h);
- }
-
- void DropShadower::bringShadowWindowsToFront()
- {
- if (! (inDestructor || reentrant))
- {
- updateShadows();
-
- reentrant = true;
-
- for (int i = numShadows; --i >= 0;)
- shadowWindows[i]->toBehind (owner);
-
- reentrant = false;
- }
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_DropShadower.cpp *********/
-
- /********* Start of inlined file: juce_MagnifierComponent.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- class MagnifyingPeer : public ComponentPeer
- {
- public:
-
- MagnifyingPeer (Component* const component,
- MagnifierComponent* const magnifierComp_)
- : ComponentPeer (component, 0),
- magnifierComp (magnifierComp_)
- {
- }
-
- ~MagnifyingPeer()
- {
- }
-
- void* getNativeHandle() const { return 0; }
- void setVisible (bool) {}
- void setTitle (const String&) {}
- void setPosition (int, int) {}
- void setSize (int, int) {}
- void setBounds (int, int, int, int, const bool) {}
- void setMinimised (bool) {}
- bool isMinimised() const { return false; }
- void setFullScreen (bool) {}
- bool isFullScreen() const { return false; }
- const BorderSize getFrameSize() const { return BorderSize (0); }
- bool setAlwaysOnTop (bool) { return true; }
- void toFront (bool) {}
- void toBehind (ComponentPeer*) {}
- void setIcon (const Image&) {}
-
- bool isFocused() const
- {
- return magnifierComp->hasKeyboardFocus (true);
- }
-
- void grabFocus()
- {
- ComponentPeer* peer = magnifierComp->getPeer();
- if (peer != 0)
- peer->grabFocus();
- }
-
- void textInputRequired (int x, int y)
- {
- ComponentPeer* peer = magnifierComp->getPeer();
- if (peer != 0)
- peer->textInputRequired (x, y);
- }
-
- void getBounds (int& x, int& y, int& w, int& h) const
- {
- x = magnifierComp->getScreenX();
- y = magnifierComp->getScreenY();
- w = component->getWidth();
- h = component->getHeight();
- }
-
- int getScreenX() const { return magnifierComp->getScreenX(); }
- int getScreenY() const { return magnifierComp->getScreenY(); }
-
- void relativePositionToGlobal (int& x, int& y)
- {
- const double zoom = magnifierComp->getScaleFactor();
- x = roundDoubleToInt (x * zoom);
- y = roundDoubleToInt (y * zoom);
-
- magnifierComp->relativePositionToGlobal (x, y);
- }
-
- void globalPositionToRelative (int& x, int& y)
- {
- magnifierComp->globalPositionToRelative (x, y);
-
- const double zoom = magnifierComp->getScaleFactor();
- x = roundDoubleToInt (x / zoom);
- y = roundDoubleToInt (y / zoom);
- }
-
- bool contains (int x, int y, bool) const
- {
- return ((unsigned int) x) < (unsigned int) magnifierComp->getWidth()
- && ((unsigned int) y) < (unsigned int) magnifierComp->getHeight();
- }
-
- void repaint (int x, int y, int w, int h)
- {
- const double zoom = magnifierComp->getScaleFactor();
-
- magnifierComp->repaint ((int) (x * zoom),
- (int) (y * zoom),
- roundDoubleToInt (w * zoom) + 1,
- roundDoubleToInt (h * zoom) + 1);
- }
-
- void performAnyPendingRepaintsNow()
- {
- }
-
- juce_UseDebuggingNewOperator
-
- private:
- MagnifierComponent* const magnifierComp;
-
- MagnifyingPeer (const MagnifyingPeer&);
- const MagnifyingPeer& operator= (const MagnifyingPeer&);
- };
-
- class PeerHolderComp : public Component
- {
- public:
- PeerHolderComp (MagnifierComponent* const magnifierComp_)
- : magnifierComp (magnifierComp_)
- {
- setVisible (true);
- }
-
- ~PeerHolderComp()
- {
- }
-
- ComponentPeer* createNewPeer (int, void*)
- {
- return new MagnifyingPeer (this, magnifierComp);
- }
-
- void childBoundsChanged (Component* c)
- {
- if (c != 0)
- {
- setSize (c->getWidth(), c->getHeight());
- magnifierComp->childBoundsChanged (this);
- }
- }
-
- void mouseWheelMove (const MouseEvent& e, float ix, float iy)
- {
- // unhandled mouse wheel moves can be referred upwards to the parent comp..
- Component* const p = magnifierComp->getParentComponent();
-
- if (p != 0)
- p->mouseWheelMove (e.getEventRelativeTo (p), ix, iy);
- }
-
- private:
- MagnifierComponent* const magnifierComp;
-
- PeerHolderComp (const PeerHolderComp&);
- const PeerHolderComp& operator= (const PeerHolderComp&);
- };
-
- MagnifierComponent::MagnifierComponent (Component* const content_,
- const bool deleteContentCompWhenNoLongerNeeded)
- : content (content_),
- scaleFactor (0.0),
- peer (0),
- deleteContent (deleteContentCompWhenNoLongerNeeded)
- {
- holderComp = new PeerHolderComp (this);
- setScaleFactor (1.0);
- }
-
- MagnifierComponent::~MagnifierComponent()
- {
- delete holderComp;
-
- if (deleteContent)
- delete content;
- }
-
- void MagnifierComponent::setScaleFactor (double newScaleFactor)
- {
- jassert (newScaleFactor > 0.0); // hmm - unlikely to work well with a negative scale factor
-
- newScaleFactor = jlimit (1.0 / 8.0, 1000.0, newScaleFactor);
-
- if (scaleFactor != newScaleFactor)
- {
- scaleFactor = newScaleFactor;
-
- if (scaleFactor == 1.0)
- {
- holderComp->removeFromDesktop();
- peer = 0;
- addChildComponent (content);
- childBoundsChanged (content);
- }
- else
- {
- holderComp->addAndMakeVisible (content);
- holderComp->childBoundsChanged (content);
- childBoundsChanged (holderComp);
- holderComp->addToDesktop (0);
- peer = holderComp->getPeer();
- }
-
- repaint();
- }
- }
-
- void MagnifierComponent::paint (Graphics& g)
- {
- const int w = holderComp->getWidth();
- const int h = holderComp->getHeight();
-
- if (w == 0 || h == 0)
- return;
-
- const Rectangle r (g.getClipBounds());
-
- const int srcX = (int) (r.getX() / scaleFactor);
- const int srcY = (int) (r.getY() / scaleFactor);
- int srcW = roundDoubleToInt (r.getRight() / scaleFactor) - srcX;
- int srcH = roundDoubleToInt (r.getBottom() / scaleFactor) - srcY;
-
- if (scaleFactor >= 1.0)
- {
- ++srcW;
- ++srcH;
- }
-
- Image temp (Image::ARGB, jmax (w, srcX + srcW), jmax (h, srcY + srcH), false);
- temp.clear (srcX, srcY, srcW, srcH);
-
- Graphics g2 (temp);
- g2.reduceClipRegion (srcX, srcY, srcW, srcH);
- holderComp->paintEntireComponent (g2);
-
- g.setImageResamplingQuality (Graphics::lowResamplingQuality);
- g.drawImage (&temp,
- 0, 0, (int) (w * scaleFactor), (int) (h * scaleFactor),
- 0, 0, w, h,
- false);
- }
-
- void MagnifierComponent::childBoundsChanged (Component* c)
- {
- if (c != 0)
- setSize (roundDoubleToInt (c->getWidth() * scaleFactor),
- roundDoubleToInt (c->getHeight() * scaleFactor));
- }
-
- void MagnifierComponent::mouseDown (const MouseEvent& e)
- {
- if (peer != 0)
- peer->handleMouseDown (scaleInt (e.x), scaleInt (e.y), e.eventTime.toMilliseconds());
- }
-
- void MagnifierComponent::mouseUp (const MouseEvent& e)
- {
- if (peer != 0)
- peer->handleMouseUp (e.mods.getRawFlags(), scaleInt (e.x), scaleInt (e.y), e.eventTime.toMilliseconds());
- }
-
- void MagnifierComponent::mouseDrag (const MouseEvent& e)
- {
- if (peer != 0)
- peer->handleMouseDrag (scaleInt (e.x), scaleInt (e.y), e.eventTime.toMilliseconds());
- }
-
- void MagnifierComponent::mouseMove (const MouseEvent& e)
- {
- if (peer != 0)
- peer->handleMouseMove (scaleInt (e.x), scaleInt (e.y), e.eventTime.toMilliseconds());
- }
-
- void MagnifierComponent::mouseEnter (const MouseEvent& e)
- {
- if (peer != 0)
- peer->handleMouseEnter (scaleInt (e.x), scaleInt (e.y), e.eventTime.toMilliseconds());
- }
-
- void MagnifierComponent::mouseExit (const MouseEvent& e)
- {
- if (peer != 0)
- peer->handleMouseExit (scaleInt (e.x), scaleInt (e.y), e.eventTime.toMilliseconds());
- }
-
- void MagnifierComponent::mouseWheelMove (const MouseEvent& e, float ix, float iy)
- {
- if (peer != 0)
- peer->handleMouseWheel (roundFloatToInt (ix * 256.0f),
- roundFloatToInt (iy * 256.0f),
- e.eventTime.toMilliseconds());
- else
- Component::mouseWheelMove (e, ix, iy);
- }
-
- int MagnifierComponent::scaleInt (const int n) const throw()
- {
- return roundDoubleToInt (n / scaleFactor);
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_MagnifierComponent.cpp *********/
-
- /********* Start of inlined file: juce_MidiKeyboardComponent.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- class MidiKeyboardUpDownButton : public Button
- {
- public:
- MidiKeyboardUpDownButton (MidiKeyboardComponent* const owner_,
- const int delta_)
- : Button (String::empty),
- owner (owner_),
- delta (delta_)
- {
- setOpaque (true);
- }
-
- ~MidiKeyboardUpDownButton()
- {
- }
-
- void clicked()
- {
- int note = owner->getLowestVisibleKey();
-
- if (delta < 0)
- note = (note - 1) / 12;
- else
- note = note / 12 + 1;
-
- owner->setLowestVisibleKey (note * 12);
- }
-
- void paintButton (Graphics& g,
- bool isMouseOverButton,
- bool isButtonDown)
- {
- owner->drawUpDownButton (g, getWidth(), getHeight(),
- isMouseOverButton, isButtonDown,
- delta > 0);
- }
-
- private:
- MidiKeyboardComponent* const owner;
- const int delta;
-
- MidiKeyboardUpDownButton (const MidiKeyboardUpDownButton&);
- const MidiKeyboardUpDownButton& operator= (const MidiKeyboardUpDownButton&);
- };
-
- MidiKeyboardComponent::MidiKeyboardComponent (MidiKeyboardState& state_,
- const Orientation orientation_)
- : state (state_),
- xOffset (0),
- blackNoteLength (1),
- keyWidth (16.0f),
- orientation (orientation_),
- midiChannel (1),
- midiInChannelMask (0xffff),
- velocity (1.0f),
- noteUnderMouse (-1),
- mouseDownNote (-1),
- rangeStart (0),
- rangeEnd (127),
- firstKey (12 * 4),
- canScroll (true),
- mouseDragging (false),
- keyPresses (4),
- keyPressNotes (16),
- keyMappingOctave (6),
- octaveNumForMiddleC (3)
- {
- addChildComponent (scrollDown = new MidiKeyboardUpDownButton (this, -1));
- addChildComponent (scrollUp = new MidiKeyboardUpDownButton (this, 1));
-
- // initialise with a default set of querty key-mappings..
- const char* const keymap = "awsedftgyhujkolp;";
-
- for (int i = String (keymap).length(); --i >= 0;)
- setKeyPressForNote (KeyPress (keymap[i], 0, 0), i);
-
- setOpaque (true);
- setWantsKeyboardFocus (true);
-
- state.addListener (this);
- }
-
- MidiKeyboardComponent::~MidiKeyboardComponent()
- {
- state.removeListener (this);
- jassert (mouseDownNote < 0 && keysPressed.countNumberOfSetBits() == 0); // leaving stuck notes!
-
- deleteAllChildren();
- }
-
- void MidiKeyboardComponent::setKeyWidth (const float widthInPixels)
- {
- keyWidth = widthInPixels;
- resized();
- }
-
- void MidiKeyboardComponent::setOrientation (const Orientation newOrientation)
- {
- if (orientation != newOrientation)
- {
- orientation = newOrientation;
- resized();
- }
- }
-
- void MidiKeyboardComponent::setAvailableRange (const int lowestNote,
- const int highestNote)
- {
- jassert (lowestNote >= 0 && lowestNote <= 127);
- jassert (highestNote >= 0 && highestNote <= 127);
- jassert (lowestNote <= highestNote);
-
- if (rangeStart != lowestNote || rangeEnd != highestNote)
- {
- rangeStart = jlimit (0, 127, lowestNote);
- rangeEnd = jlimit (0, 127, highestNote);
- firstKey = jlimit (rangeStart, rangeEnd, firstKey);
- resized();
- }
- }
-
- void MidiKeyboardComponent::setLowestVisibleKey (int noteNumber)
- {
- noteNumber = jlimit (rangeStart, rangeEnd, noteNumber);
-
- if (noteNumber != firstKey)
- {
- firstKey = noteNumber;
- sendChangeMessage (this);
- resized();
- }
- }
-
- void MidiKeyboardComponent::setScrollButtonsVisible (const bool canScroll_)
- {
- if (canScroll != canScroll_)
- {
- canScroll = canScroll_;
- resized();
- }
- }
-
- void MidiKeyboardComponent::colourChanged()
- {
- repaint();
- }
-
- void MidiKeyboardComponent::setMidiChannel (const int midiChannelNumber)
- {
- jassert (midiChannelNumber > 0 && midiChannelNumber <= 16);
-
- if (midiChannel != midiChannelNumber)
- {
- resetAnyKeysInUse();
- midiChannel = jlimit (1, 16, midiChannelNumber);
- }
- }
-
- void MidiKeyboardComponent::setMidiChannelsToDisplay (const int midiChannelMask)
- {
- midiInChannelMask = midiChannelMask;
- triggerAsyncUpdate();
- }
-
- void MidiKeyboardComponent::setVelocity (const float velocity_)
- {
- velocity = jlimit (0.0f, 1.0f, velocity_);
- }
-
- void MidiKeyboardComponent::getKeyPosition (int midiNoteNumber, const float keyWidth, int& x, int& w) const
- {
- jassert (midiNoteNumber >= 0 && midiNoteNumber < 128);
-
- static const float blackNoteWidth = 0.7f;
-
- static const float notePos[] = { 0.0f, 1 - blackNoteWidth * 0.6f,
- 1.0f, 2 - blackNoteWidth * 0.4f,
- 2.0f, 3.0f, 4 - blackNoteWidth * 0.7f,
- 4.0f, 5 - blackNoteWidth * 0.5f,
- 5.0f, 6 - blackNoteWidth * 0.3f,
- 6.0f };
-
- static const float widths[] = { 1.0f, blackNoteWidth,
- 1.0f, blackNoteWidth,
- 1.0f, 1.0f, blackNoteWidth,
- 1.0f, blackNoteWidth,
- 1.0f, blackNoteWidth,
- 1.0f };
-
- const int octave = midiNoteNumber / 12;
- const int note = midiNoteNumber % 12;
-
- x = roundFloatToInt (octave * 7.0f * keyWidth + notePos [note] * keyWidth);
- w = roundFloatToInt (widths [note] * keyWidth);
- }
-
- void MidiKeyboardComponent::getKeyPos (int midiNoteNumber, int& x, int& w) const
- {
- getKeyPosition (midiNoteNumber, keyWidth, x, w);
-
- int rx, rw;
- getKeyPosition (rangeStart, keyWidth, rx, rw);
-
- x -= xOffset + rx;
- }
-
- int MidiKeyboardComponent::getKeyStartPosition (const int midiNoteNumber) const
- {
- int x, y;
- getKeyPos (midiNoteNumber, x, y);
- return x;
- }
-
- static const uint8 whiteNotes[] = { 0, 2, 4, 5, 7, 9, 11 };
- static const uint8 blackNotes[] = { 1, 3, 6, 8, 10 };
-
- int MidiKeyboardComponent::xyToNote (int x, int y)
- {
- if (! reallyContains (x, y, false))
- return -1;
-
- if (orientation != horizontalKeyboard)
- {
- swapVariables (x, y);
-
- if (orientation == verticalKeyboardFacingLeft)
- y = getWidth() - y;
- else
- x = getHeight() - x;
- }
-
- return remappedXYToNote (x + xOffset, y);
- }
-
- int MidiKeyboardComponent::remappedXYToNote (int x, int y) const
- {
- if (y < blackNoteLength)
- {
- for (int octaveStart = 12 * (rangeStart / 12); octaveStart < rangeEnd; octaveStart += 12)
- {
- for (int i = 0; i < 5; ++i)
- {
- const int note = octaveStart + blackNotes [i];
-
- if (note >= rangeStart && note <= rangeEnd)
- {
- int kx, kw;
- getKeyPos (note, kx, kw);
- kx += xOffset;
-
- if (x >= kx && x < kx + kw)
- return note;
- }
- }
- }
- }
-
- for (int octaveStart = 12 * (rangeStart / 12); octaveStart < rangeEnd; octaveStart += 12)
- {
- for (int i = 0; i < 7; ++i)
- {
- const int note = octaveStart + whiteNotes [i];
-
- if (note >= rangeStart && note <= rangeEnd)
- {
- int kx, kw;
- getKeyPos (note, kx, kw);
- kx += xOffset;
-
- if (x >= kx && x < kx + kw)
- return note;
- }
- }
- }
-
- return -1;
- }
-
- void MidiKeyboardComponent::repaintNote (const int noteNum)
- {
- if (noteNum >= rangeStart && noteNum <= rangeEnd)
- {
- int x, w;
- getKeyPos (noteNum, x, w);
-
- if (orientation == horizontalKeyboard)
- repaint (x, 0, w, getHeight());
- else if (orientation == verticalKeyboardFacingLeft)
- repaint (0, x, getWidth(), w);
- else if (orientation == verticalKeyboardFacingRight)
- repaint (0, getHeight() - x - w, getWidth(), w);
- }
- }
-
- void MidiKeyboardComponent::paint (Graphics& g)
- {
- g.fillAll (Colours::white.overlaidWith (findColour (whiteNoteColourId)));
-
- const Colour lineColour (findColour (keySeparatorLineColourId));
- const Colour textColour (findColour (textLabelColourId));
-
- int x, w, octave;
-
- for (octave = 0; octave < 128; octave += 12)
- {
- for (int white = 0; white < 7; ++white)
- {
- const int noteNum = octave + whiteNotes [white];
-
- if (noteNum >= rangeStart && noteNum <= rangeEnd)
- {
- getKeyPos (noteNum, x, w);
-
- if (orientation == horizontalKeyboard)
- drawWhiteNote (noteNum, g, x, 0, w, getHeight(),
- state.isNoteOnForChannels (midiInChannelMask, noteNum),
- noteUnderMouse == noteNum,
- lineColour, textColour);
- else if (orientation == verticalKeyboardFacingLeft)
- drawWhiteNote (noteNum, g, 0, x, getWidth(), w,
- state.isNoteOnForChannels (midiInChannelMask, noteNum),
- noteUnderMouse == noteNum,
- lineColour, textColour);
- else if (orientation == verticalKeyboardFacingRight)
- drawWhiteNote (noteNum, g, 0, getHeight() - x - w, getWidth(), w,
- state.isNoteOnForChannels (midiInChannelMask, noteNum),
- noteUnderMouse == noteNum,
- lineColour, textColour);
- }
- }
- }
-
- float x1 = 0.0f, y1 = 0.0f, x2 = 0.0f, y2 = 0.0f;
-
- if (orientation == verticalKeyboardFacingLeft)
- {
- x1 = getWidth() - 1.0f;
- x2 = getWidth() - 5.0f;
- }
- else if (orientation == verticalKeyboardFacingRight)
- x2 = 5.0f;
- else
- y2 = 5.0f;
-
- GradientBrush gb (Colours::black.withAlpha (0.3f), x1, y1,
- Colours::transparentBlack, x2, y2, false);
- g.setBrush (&gb);
-
- getKeyPos (rangeEnd, x, w);
- x += w;
-
- if (orientation == verticalKeyboardFacingLeft)
- g.fillRect (getWidth() - 5, 0, 5, x);
- else if (orientation == verticalKeyboardFacingRight)
- g.fillRect (0, 0, 5, x);
- else
- g.fillRect (0, 0, x, 5);
-
- g.setColour (lineColour);
-
- if (orientation == verticalKeyboardFacingLeft)
- g.fillRect (0, 0, 1, x);
- else if (orientation == verticalKeyboardFacingRight)
- g.fillRect (getWidth() - 1, 0, 1, x);
- else
- g.fillRect (0, getHeight() - 1, x, 1);
-
- const Colour blackNoteColour (findColour (blackNoteColourId));
-
- for (octave = 0; octave < 128; octave += 12)
- {
- for (int black = 0; black < 5; ++black)
- {
- const int noteNum = octave + blackNotes [black];
-
- if (noteNum >= rangeStart && noteNum <= rangeEnd)
- {
- getKeyPos (noteNum, x, w);
-
- if (orientation == horizontalKeyboard)
- drawBlackNote (noteNum, g, x, 0, w, blackNoteLength,
- state.isNoteOnForChannels (midiInChannelMask, noteNum),
- noteUnderMouse == noteNum,
- blackNoteColour);
- else if (orientation == verticalKeyboardFacingLeft)
- drawBlackNote (noteNum, g, getWidth() - blackNoteLength, x, blackNoteLength, w,
- state.isNoteOnForChannels (midiInChannelMask, noteNum),
- noteUnderMouse == noteNum,
- blackNoteColour);
- else if (orientation == verticalKeyboardFacingRight)
- drawBlackNote (noteNum, g, 0, getHeight() - x - w, blackNoteLength, w,
- state.isNoteOnForChannels (midiInChannelMask, noteNum),
- noteUnderMouse == noteNum,
- blackNoteColour);
- }
- }
- }
- }
-
- void MidiKeyboardComponent::drawWhiteNote (int midiNoteNumber,
- Graphics& g, int x, int y, int w, int h,
- bool isDown, bool isOver,
- const Colour& lineColour,
- const Colour& textColour)
- {
- Colour c (Colours::transparentWhite);
-
- if (isDown)
- c = findColour (keyDownOverlayColourId);
-
- if (isOver)
- c = c.overlaidWith (findColour (mouseOverKeyOverlayColourId));
-
- g.setColour (c);
- g.fillRect (x, y, w, h);
-
- const String text (getWhiteNoteText (midiNoteNumber));
-
- if (! text.isEmpty())
- {
- g.setColour (textColour);
-
- Font f (jmin (12.0f, keyWidth * 0.9f));
- f.setHorizontalScale (0.8f);
- g.setFont (f);
- Justification justification (Justification::centredBottom);
-
- if (orientation == verticalKeyboardFacingLeft)
- justification = Justification::centredLeft;
- else if (orientation == verticalKeyboardFacingRight)
- justification = Justification::centredRight;
-
- g.drawFittedText (text, x + 2, y + 2, w - 4, h - 4, justification, 1);
- }
-
- g.setColour (lineColour);
-
- if (orientation == horizontalKeyboard)
- g.fillRect (x, y, 1, h);
- else if (orientation == verticalKeyboardFacingLeft)
- g.fillRect (x, y, w, 1);
- else if (orientation == verticalKeyboardFacingRight)
- g.fillRect (x, y + h - 1, w, 1);
-
- if (midiNoteNumber == rangeEnd)
- {
- if (orientation == horizontalKeyboard)
- g.fillRect (x + w, y, 1, h);
- else if (orientation == verticalKeyboardFacingLeft)
- g.fillRect (x, y + h, w, 1);
- else if (orientation == verticalKeyboardFacingRight)
- g.fillRect (x, y - 1, w, 1);
- }
- }
-
- void MidiKeyboardComponent::drawBlackNote (int /*midiNoteNumber*/,
- Graphics& g, int x, int y, int w, int h,
- bool isDown, bool isOver,
- const Colour& noteFillColour)
- {
- Colour c (noteFillColour);
-
- if (isDown)
- c = c.overlaidWith (findColour (keyDownOverlayColourId));
-
- if (isOver)
- c = c.overlaidWith (findColour (mouseOverKeyOverlayColourId));
-
- g.setColour (c);
- g.fillRect (x, y, w, h);
-
- if (isDown)
- {
- g.setColour (noteFillColour);
- g.drawRect (x, y, w, h);
- }
- else
- {
- const int xIndent = jmax (1, jmin (w, h) / 8);
-
- g.setColour (c.brighter());
-
- if (orientation == horizontalKeyboard)
- g.fillRect (x + xIndent, y, w - xIndent * 2, 7 * h / 8);
- else if (orientation == verticalKeyboardFacingLeft)
- g.fillRect (x + w / 8, y + xIndent, w - w / 8, h - xIndent * 2);
- else if (orientation == verticalKeyboardFacingRight)
- g.fillRect (x, y + xIndent, 7 * w / 8, h - xIndent * 2);
- }
- }
-
- void MidiKeyboardComponent::setOctaveForMiddleC (const int octaveNumForMiddleC_) throw()
- {
- octaveNumForMiddleC = octaveNumForMiddleC_;
- repaint();
- }
-
- const String MidiKeyboardComponent::getWhiteNoteText (const int midiNoteNumber)
- {
- if (keyWidth > 14.0f && midiNoteNumber % 12 == 0)
- return MidiMessage::getMidiNoteName (midiNoteNumber, true, true, octaveNumForMiddleC);
-
- return String::empty;
- }
-
- void MidiKeyboardComponent::drawUpDownButton (Graphics& g, int w, int h,
- const bool isMouseOver,
- const bool isButtonDown,
- const bool movesOctavesUp)
- {
- g.fillAll (findColour (upDownButtonBackgroundColourId));
-
- float angle;
-
- if (orientation == MidiKeyboardComponent::horizontalKeyboard)
- angle = movesOctavesUp ? 0.0f : 0.5f;
- else if (orientation == MidiKeyboardComponent::verticalKeyboardFacingLeft)
- angle = movesOctavesUp ? 0.25f : 0.75f;
- else
- angle = movesOctavesUp ? 0.75f : 0.25f;
-
- Path path;
- path.lineTo (0.0f, 1.0f);
- path.lineTo (1.0f, 0.5f);
- path.closeSubPath();
-
- path.applyTransform (AffineTransform::rotation (float_Pi * 2.0f * angle, 0.5f, 0.5f));
-
- g.setColour (findColour (upDownButtonArrowColourId)
- .withAlpha (isButtonDown ? 1.0f : (isMouseOver ? 0.6f : 0.4f)));
-
- g.fillPath (path, path.getTransformToScaleToFit (1.0f, 1.0f,
- w - 2.0f,
- h - 2.0f,
- true));
- }
-
- void MidiKeyboardComponent::resized()
- {
- int w = getWidth();
- int h = getHeight();
-
- if (w > 0 && h > 0)
- {
- if (orientation != horizontalKeyboard)
- swapVariables (w, h);
-
- blackNoteLength = roundFloatToInt (h * 0.7f);
-
- int kx2, kw2;
- getKeyPos (rangeEnd, kx2, kw2);
-
- kx2 += kw2;
-
- if (firstKey != rangeStart)
- {
- int kx1, kw1;
- getKeyPos (rangeStart, kx1, kw1);
-
- if (kx2 - kx1 <= w)
- {
- firstKey = rangeStart;
- sendChangeMessage (this);
- repaint();
- }
- }
-
- const bool showScrollButtons = canScroll && (firstKey > rangeStart || kx2 > w + xOffset * 2);
-
- scrollDown->setVisible (showScrollButtons);
- scrollUp->setVisible (showScrollButtons);
-
- xOffset = 0;
-
- if (showScrollButtons)
- {
- const int scrollButtonW = jmin (12, w / 2);
-
- if (orientation == horizontalKeyboard)
- {
- scrollDown->setBounds (0, 0, scrollButtonW, getHeight());
- scrollUp->setBounds (getWidth() - scrollButtonW, 0, scrollButtonW, getHeight());
- }
- else if (orientation == verticalKeyboardFacingLeft)
- {
- scrollDown->setBounds (0, 0, getWidth(), scrollButtonW);
- scrollUp->setBounds (0, getHeight() - scrollButtonW, getWidth(), scrollButtonW);
- }
- else if (orientation == verticalKeyboardFacingRight)
- {
- scrollDown->setBounds (0, getHeight() - scrollButtonW, getWidth(), scrollButtonW);
- scrollUp->setBounds (0, 0, getWidth(), scrollButtonW);
- }
-
- int endOfLastKey, kw;
- getKeyPos (rangeEnd, endOfLastKey, kw);
- endOfLastKey += kw;
-
- const int spaceAvailable = w - scrollButtonW * 2;
- const int lastStartKey = remappedXYToNote (endOfLastKey - spaceAvailable, 0) + 1;
-
- if (lastStartKey >= 0 && firstKey > lastStartKey)
- {
- firstKey = jlimit (rangeStart, rangeEnd, lastStartKey);
- sendChangeMessage (this);
- }
-
- int newOffset = 0;
- getKeyPos (firstKey, newOffset, kw);
- xOffset = newOffset - scrollButtonW;
- }
- else
- {
- firstKey = rangeStart;
- }
-
- timerCallback();
- repaint();
- }
- }
-
- void MidiKeyboardComponent::handleNoteOn (MidiKeyboardState*, int /*midiChannel*/, int /*midiNoteNumber*/, float /*velocity*/)
- {
- triggerAsyncUpdate();
- }
-
- void MidiKeyboardComponent::handleNoteOff (MidiKeyboardState*, int /*midiChannel*/, int /*midiNoteNumber*/)
- {
- triggerAsyncUpdate();
- }
-
- void MidiKeyboardComponent::handleAsyncUpdate()
- {
- for (int i = rangeStart; i <= rangeEnd; ++i)
- {
- if (keysCurrentlyDrawnDown[i] != state.isNoteOnForChannels (midiInChannelMask, i))
- {
- keysCurrentlyDrawnDown.setBit (i, state.isNoteOnForChannels (midiInChannelMask, i));
- repaintNote (i);
- }
- }
- }
-
- void MidiKeyboardComponent::resetAnyKeysInUse()
- {
- if (keysPressed.countNumberOfSetBits() > 0 || mouseDownNote > 0)
- {
- state.allNotesOff (midiChannel);
- keysPressed.clear();
- mouseDownNote = -1;
- }
- }
-
- void MidiKeyboardComponent::updateNoteUnderMouse (int x, int y)
- {
- const int newNote = (mouseDragging || isMouseOver())
- ? xyToNote (x, y) : -1;
-
- if (noteUnderMouse != newNote)
- {
- if (mouseDownNote >= 0)
- {
- state.noteOff (midiChannel, mouseDownNote);
- mouseDownNote = -1;
- }
-
- if (mouseDragging && newNote >= 0)
- {
- state.noteOn (midiChannel, newNote, velocity);
- mouseDownNote = newNote;
- }
-
- repaintNote (noteUnderMouse);
- noteUnderMouse = newNote;
- repaintNote (noteUnderMouse);
- }
- else if (mouseDownNote >= 0 && ! mouseDragging)
- {
- state.noteOff (midiChannel, mouseDownNote);
- mouseDownNote = -1;
- }
- }
-
- void MidiKeyboardComponent::mouseMove (const MouseEvent& e)
- {
- updateNoteUnderMouse (e.x, e.y);
- stopTimer();
- }
-
- void MidiKeyboardComponent::mouseDrag (const MouseEvent& e)
- {
- const int newNote = xyToNote (e.x, e.y);
-
- if (newNote >= 0)
- mouseDraggedToKey (newNote, e);
-
- updateNoteUnderMouse (e.x, e.y);
- }
-
- bool MidiKeyboardComponent::mouseDownOnKey (int /*midiNoteNumber*/, const MouseEvent&)
- {
- return true;
- }
-
- void MidiKeyboardComponent::mouseDraggedToKey (int /*midiNoteNumber*/, const MouseEvent&)
- {
- }
-
- void MidiKeyboardComponent::mouseDown (const MouseEvent& e)
- {
- const int newNote = xyToNote (e.x, e.y);
- mouseDragging = false;
-
- if (newNote >= 0 && mouseDownOnKey (newNote, e))
- {
- repaintNote (noteUnderMouse);
- noteUnderMouse = -1;
- mouseDragging = true;
-
- updateNoteUnderMouse (e.x, e.y);
- startTimer (500);
- }
- }
-
- void MidiKeyboardComponent::mouseUp (const MouseEvent& e)
- {
- mouseDragging = false;
- updateNoteUnderMouse (e.x, e.y);
-
- stopTimer();
- }
-
- void MidiKeyboardComponent::mouseEnter (const MouseEvent& e)
- {
- updateNoteUnderMouse (e.x, e.y);
- }
-
- void MidiKeyboardComponent::mouseExit (const MouseEvent& e)
- {
- updateNoteUnderMouse (e.x, e.y);
- }
-
- void MidiKeyboardComponent::mouseWheelMove (const MouseEvent&, float ix, float iy)
- {
- setLowestVisibleKey (getLowestVisibleKey() + roundFloatToInt ((ix != 0 ? ix : iy) * 5.0f));
- }
-
- void MidiKeyboardComponent::timerCallback()
- {
- int mx, my;
- getMouseXYRelative (mx, my);
-
- updateNoteUnderMouse (mx, my);
- }
-
- void MidiKeyboardComponent::clearKeyMappings()
- {
- resetAnyKeysInUse();
- keyPressNotes.clear();
- keyPresses.clear();
- }
-
- void MidiKeyboardComponent::setKeyPressForNote (const KeyPress& key,
- const int midiNoteOffsetFromC)
- {
- removeKeyPressForNote (midiNoteOffsetFromC);
-
- keyPressNotes.add (midiNoteOffsetFromC);
- keyPresses.add (key);
- }
-
- void MidiKeyboardComponent::removeKeyPressForNote (const int midiNoteOffsetFromC)
- {
- for (int i = keyPressNotes.size(); --i >= 0;)
- {
- if (keyPressNotes.getUnchecked (i) == midiNoteOffsetFromC)
- {
- keyPressNotes.remove (i);
- keyPresses.remove (i);
- }
- }
- }
-
- void MidiKeyboardComponent::setKeyPressBaseOctave (const int newOctaveNumber)
- {
- jassert (newOctaveNumber >= 0 && newOctaveNumber <= 10);
-
- keyMappingOctave = newOctaveNumber;
- }
-
- bool MidiKeyboardComponent::keyStateChanged()
- {
- bool keyPressUsed = false;
-
- for (int i = keyPresses.size(); --i >= 0;)
- {
- const int note = 12 * keyMappingOctave + keyPressNotes.getUnchecked (i);
-
- if (keyPresses.getReference(i).isCurrentlyDown())
- {
- if (! keysPressed [note])
- {
- keysPressed.setBit (note);
- state.noteOn (midiChannel, note, velocity);
- keyPressUsed = true;
- }
- }
- else
- {
- if (keysPressed [note])
- {
- keysPressed.clearBit (note);
- state.noteOff (midiChannel, note);
- keyPressUsed = true;
- }
- }
- }
-
- return keyPressUsed;
- }
-
- void MidiKeyboardComponent::focusLost (FocusChangeType)
- {
- resetAnyKeysInUse();
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_MidiKeyboardComponent.cpp *********/
-
- /********* Start of inlined file: juce_OpenGLComponent.cpp *********/
-
- #if JUCE_OPENGL
-
- BEGIN_JUCE_NAMESPACE
-
- extern void juce_glViewport (const int w, const int h);
-
- OpenGLPixelFormat::OpenGLPixelFormat (const int bitsPerRGBComponent,
- const int alphaBits_,
- const int depthBufferBits_,
- const int stencilBufferBits_) throw()
- : redBits (bitsPerRGBComponent),
- greenBits (bitsPerRGBComponent),
- blueBits (bitsPerRGBComponent),
- alphaBits (alphaBits_),
- depthBufferBits (depthBufferBits_),
- stencilBufferBits (stencilBufferBits_),
- accumulationBufferRedBits (0),
- accumulationBufferGreenBits (0),
- accumulationBufferBlueBits (0),
- accumulationBufferAlphaBits (0),
- fullSceneAntiAliasingNumSamples (0)
- {
- }
-
- bool OpenGLPixelFormat::operator== (const OpenGLPixelFormat& other) const throw()
- {
- return memcmp (this, &other, sizeof (other)) == 0;
- }
-
- static VoidArray knownContexts;
-
- OpenGLContext::OpenGLContext() throw()
- {
- knownContexts.add (this);
- }
-
- OpenGLContext::~OpenGLContext()
- {
- knownContexts.removeValue (this);
- }
-
- OpenGLContext* OpenGLContext::getCurrentContext()
- {
- for (int i = knownContexts.size(); --i >= 0;)
- {
- OpenGLContext* const oglc = (OpenGLContext*) knownContexts.getUnchecked(i);
-
- if (oglc->isActive())
- return oglc;
- }
-
- return 0;
- }
-
- class OpenGLComponentWatcher : public ComponentMovementWatcher
- {
- public:
-
- OpenGLComponentWatcher (OpenGLComponent* const owner_)
- : ComponentMovementWatcher (owner_),
- owner (owner_),
- wasShowing (false)
- {
- }
-
- ~OpenGLComponentWatcher() {}
-
- void componentMovedOrResized (bool /*wasMoved*/, bool /*wasResized*/)
- {
- owner->updateContextPosition();
- }
-
- void componentPeerChanged()
- {
- const ScopedLock sl (owner->getContextLock());
- owner->deleteContext();
- }
-
- void componentVisibilityChanged (Component&)
- {
- const bool isShowingNow = owner->isShowing();
-
- if (wasShowing != isShowingNow)
- {
- wasShowing = isShowingNow;
- owner->updateContextPosition();
- }
- }
-
- juce_UseDebuggingNewOperator
-
- private:
- OpenGLComponent* const owner;
- bool wasShowing;
- };
-
- OpenGLComponent::OpenGLComponent()
- : context (0),
- contextToShareListsWith (0),
- needToUpdateViewport (true)
- {
- setOpaque (true);
- componentWatcher = new OpenGLComponentWatcher (this);
- }
-
- OpenGLComponent::~OpenGLComponent()
- {
- deleteContext();
- delete componentWatcher;
- }
-
- void OpenGLComponent::deleteContext()
- {
- const ScopedLock sl (contextLock);
- deleteAndZero (context);
- }
-
- void OpenGLComponent::updateContextPosition()
- {
- needToUpdateViewport = true;
-
- if (getWidth() > 0 && getHeight() > 0)
- {
- Component* const topComp = getTopLevelComponent();
-
- if (topComp->getPeer() != 0)
- {
- const ScopedLock sl (contextLock);
-
- if (context != 0)
- context->updateWindowPosition (getScreenX() - topComp->getScreenX(),
- getScreenY() - topComp->getScreenY(),
- getWidth(),
- getHeight(),
- topComp->getHeight());
- }
- }
- }
-
- const OpenGLPixelFormat OpenGLComponent::getPixelFormat() const
- {
- OpenGLPixelFormat pf;
-
- const ScopedLock sl (contextLock);
- if (context != 0)
- pf = context->getPixelFormat();
-
- return pf;
- }
-
- void OpenGLComponent::setPixelFormat (const OpenGLPixelFormat& formatToUse)
- {
- if (! (preferredPixelFormat == formatToUse))
- {
- const ScopedLock sl (contextLock);
- deleteContext();
- preferredPixelFormat = formatToUse;
- }
- }
-
- void OpenGLComponent::shareWith (OpenGLContext* context)
- {
- if (contextToShareListsWith != context)
- {
- const ScopedLock sl (contextLock);
- deleteContext();
- contextToShareListsWith = context;
- }
- }
-
- bool OpenGLComponent::makeCurrentContextActive()
- {
- if (context == 0)
- {
- const ScopedLock sl (contextLock);
-
- if (isShowing() && getTopLevelComponent()->getPeer() != 0)
- {
- context = OpenGLContext::createContextForWindow (this,
- preferredPixelFormat,
- contextToShareListsWith);
-
- if (context != 0)
- {
- updateContextPosition();
-
- if (context->makeActive())
- newOpenGLContextCreated();
- }
- }
- }
-
- return context != 0 && context->makeActive();
- }
-
- void OpenGLComponent::makeCurrentContextInactive()
- {
- if (context != 0)
- context->makeInactive();
- }
-
- bool OpenGLComponent::isActiveContext() const throw()
- {
- return context != 0 && context->isActive();
- }
-
- void OpenGLComponent::swapBuffers()
- {
- if (context != 0)
- context->swapBuffers();
- }
-
- void OpenGLComponent::paint (Graphics&)
- {
- if (renderAndSwapBuffers())
- {
- ComponentPeer* const peer = getPeer();
-
- if (peer != 0)
- {
- peer->addMaskedRegion (getScreenX() - peer->getScreenX(),
- getScreenY() - peer->getScreenY(),
- getWidth(), getHeight());
- }
- }
- }
-
- bool OpenGLComponent::renderAndSwapBuffers()
- {
- const ScopedLock sl (contextLock);
-
- if (! makeCurrentContextActive())
- return false;
-
- if (needToUpdateViewport)
- {
- needToUpdateViewport = false;
- juce_glViewport (getWidth(), getHeight());
- }
-
- renderOpenGL();
- swapBuffers();
-
- return true;
- }
-
- void OpenGLComponent::internalRepaint (int x, int y, int w, int h)
- {
- Component::internalRepaint (x, y, w, h);
-
- if (context != 0)
- context->repaint();
- }
-
- END_JUCE_NAMESPACE
-
- #endif
- /********* End of inlined file: juce_OpenGLComponent.cpp *********/
-
- /********* Start of inlined file: juce_PreferencesPanel.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- PreferencesPanel::PreferencesPanel()
- : currentPage (0),
- buttonSize (70)
- {
- }
-
- PreferencesPanel::~PreferencesPanel()
- {
- deleteAllChildren();
- }
-
- void PreferencesPanel::addSettingsPage (const String& title,
- const Drawable* icon,
- const Drawable* overIcon,
- const Drawable* downIcon)
- {
- DrawableButton* button = new DrawableButton (title, DrawableButton::ImageAboveTextLabel);
- button->setImages (icon, overIcon, downIcon);
- button->setRadioGroupId (1);
- button->addButtonListener (this);
- button->setClickingTogglesState (true);
- button->setWantsKeyboardFocus (false);
- addAndMakeVisible (button);
-
- resized();
- }
-
- void PreferencesPanel::addSettingsPage (const String& title,
- const char* imageData,
- const int imageDataSize)
- {
- DrawableImage icon, iconOver, iconDown;
- icon.setImage (ImageCache::getFromMemory (imageData, imageDataSize), true);
-
- iconOver.setImage (ImageCache::getFromMemory (imageData, imageDataSize), true);
- iconOver.setOverlayColour (Colours::black.withAlpha (0.12f));
-
- iconDown.setImage (ImageCache::getFromMemory (imageData, imageDataSize), true);
- iconDown.setOverlayColour (Colours::black.withAlpha (0.25f));
-
- addSettingsPage (title, &icon, &iconOver, &iconDown);
-
- if (currentPage == 0)
- setCurrentPage (title);
- }
-
- class PrefsDialogWindow : public DialogWindow
- {
- public:
- PrefsDialogWindow (const String& dialogtitle,
- const Colour& backgroundColour)
- : DialogWindow (dialogtitle, backgroundColour, true)
- {
- }
-
- ~PrefsDialogWindow()
- {
- }
-
- void closeButtonPressed()
- {
- exitModalState (0);
- }
-
- private:
- PrefsDialogWindow (const PrefsDialogWindow&);
- const PrefsDialogWindow& operator= (const PrefsDialogWindow&);
- };
-
- void PreferencesPanel::showInDialogBox (const String& dialogtitle,
- int dialogWidth,
- int dialogHeight,
- const Colour& backgroundColour)
- {
- setSize (dialogWidth, dialogHeight);
-
- PrefsDialogWindow dw (dialogtitle, backgroundColour);
-
- dw.setContentComponent (this, true, true);
- dw.centreAroundComponent (0, dw.getWidth(), dw.getHeight());
- dw.runModalLoop();
- }
-
- void PreferencesPanel::resized()
- {
- int x = 0;
-
- for (int i = 0; i < getNumChildComponents(); ++i)
- {
- Component* c = getChildComponent (i);
-
- if (dynamic_cast <DrawableButton*> (c) == 0)
- {
- c->setBounds (0, buttonSize + 5, getWidth(), getHeight() - buttonSize - 5);
- }
- else
- {
- c->setBounds (x, 0, buttonSize, buttonSize);
- x += buttonSize;
- }
- }
- }
-
- void PreferencesPanel::paint (Graphics& g)
- {
- g.setColour (Colours::grey);
- g.fillRect (0, buttonSize + 2, getWidth(), 1);
- }
-
- void PreferencesPanel::setCurrentPage (const String& pageName)
- {
- if (currentPageName != pageName)
- {
- currentPageName = pageName;
-
- deleteAndZero (currentPage);
- currentPage = createComponentForPage (pageName);
-
- if (currentPage != 0)
- {
- addAndMakeVisible (currentPage);
- currentPage->toBack();
- resized();
- }
-
- for (int i = 0; i < getNumChildComponents(); ++i)
- {
- DrawableButton* db = dynamic_cast <DrawableButton*> (getChildComponent (i));
-
- if (db != 0 && db->getName() == pageName)
- {
- db->setToggleState (true, false);
- break;
- }
- }
- }
- }
-
- void PreferencesPanel::buttonClicked (Button*)
- {
- for (int i = 0; i < getNumChildComponents(); ++i)
- {
- DrawableButton* db = dynamic_cast <DrawableButton*> (getChildComponent (i));
-
- if (db != 0 && db->getToggleState())
- {
- setCurrentPage (db->getName());
- break;
- }
- }
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_PreferencesPanel.cpp *********/
-
- /********* Start of inlined file: juce_QuickTimeMovieComponent.cpp *********/
-
- #if JUCE_QUICKTIME
-
- #ifdef _MSC_VER
- #pragma warning (disable: 4514)
- #endif
-
- #ifdef _WIN32
- #include <windows.h>
-
- #ifdef _MSC_VER
- #pragma warning (push)
- #pragma warning (disable : 4100)
- #endif
-
- /* If you've got an include error here, you probably need to install the QuickTime SDK and
- add its header directory to your include path.
-
- Alternatively, if you don't need any QuickTime services, just turn off the JUC_QUICKTIME
- flag in juce_Config.h
- */
- #include <Movies.h>
- #include <QTML.h>
- #include <QuickTimeComponents.h>
- #include <MediaHandlers.h>
- #include <ImageCodec.h>
-
- #ifdef _MSC_VER
- #pragma warning (pop)
- #endif
-
- // If you've got QuickTime 7 installed, then these COM objects should be found in
- // the "\Program Files\Quicktime" directory. You'll need to add this directory to
- // your include search path to make these import statements work.
- #import <QTOLibrary.dll>
- #import <QTOControl.dll>
-
- using namespace QTOLibrary;
- using namespace QTOControlLib;
- #else
- #include <Carbon/Carbon.h>
- #include <QuickTime/Movies.h>
- #include <QuickTime/QuickTimeComponents.h>
- #include <QuickTime/MediaHandlers.h>
- #endif
-
- BEGIN_JUCE_NAMESPACE
-
- bool juce_OpenQuickTimeMovieFromStream (InputStream* input, Movie& movie, Handle& dataHandle);
-
- static bool hasLoadedQT = false;
- static bool isQTAvailable = false;
-
- struct QTMovieCompInternal
- {
- QTMovieCompInternal()
- : dataHandle (0)
- {
- #if JUCE_MAC
- movie = 0;
- controller = 0;
- #endif
- }
-
- ~QTMovieCompInternal()
- {
- clearHandle();
- }
-
- #if JUCE_MAC
- Movie movie;
- MovieController controller;
- #else
- IQTControlPtr qtControlInternal;
- IQTMoviePtr qtMovieInternal;
- #endif
-
- Handle dataHandle;
-
- void clearHandle()
- {
- if (dataHandle != 0)
- {
- DisposeHandle (dataHandle);
- dataHandle = 0;
- }
- }
- };
-
- #if JUCE_WIN32
-
- #define qtControl (((QTMovieCompInternal*) internal)->qtControlInternal)
- #define qtMovie (((QTMovieCompInternal*) internal)->qtMovieInternal)
-
- QuickTimeMovieComponent::QuickTimeMovieComponent()
- : movieLoaded (false),
- controllerVisible (true)
- {
- internal = new QTMovieCompInternal();
- setMouseEventsAllowed (false);
- }
-
- QuickTimeMovieComponent::~QuickTimeMovieComponent()
- {
- closeMovie();
- qtControl = 0;
-
- deleteControl();
-
- delete internal;
- internal = 0;
- }
-
- bool QuickTimeMovieComponent::isQuickTimeAvailable() throw()
- {
- if (! hasLoadedQT)
- {
- hasLoadedQT = true;
-
- isQTAvailable = (InitializeQTML (0) == noErr)
- && (EnterMovies() == noErr);
- }
-
- return isQTAvailable;
- }
-
- void QuickTimeMovieComponent::createControlIfNeeded()
- {
- if (isShowing() && ! isControlCreated())
- {
- const IID qtIID = __uuidof (QTControl);
-
- if (createControl (&qtIID))
- {
- const IID qtInterfaceIID = __uuidof (IQTControl);
- qtControl = (IQTControl*) queryInterface (&qtInterfaceIID);
-
- if (qtControl != 0)
- {
- qtControl->Release(); // it has one ref too many at this point
-
- qtControl->QuickTimeInitialize();
- qtControl->PutSizing (qtMovieFitsControl);
-
- if (movieFile != File::nonexistent)
- loadMovie (movieFile, controllerVisible);
- }
- }
- }
- }
-
- bool QuickTimeMovieComponent::isControlCreated() const
- {
- return isControlOpen();
- }
-
- bool QuickTimeMovieComponent::loadMovie (InputStream* movieStream,
- const bool isControllerVisible)
- {
- movieFile = File::nonexistent;
- movieLoaded = false;
- qtMovie = 0;
- controllerVisible = isControllerVisible;
- createControlIfNeeded();
-
- if (isControlCreated())
- {
- if (qtControl != 0)
- {
- qtControl->Put_MovieHandle (0);
- ((QTMovieCompInternal*) internal)->clearHandle();
-
- Movie movie;
- if (juce_OpenQuickTimeMovieFromStream (movieStream, movie, ((QTMovieCompInternal*) internal)->dataHandle))
- {
- qtControl->Put_MovieHandle ((long) (pointer_sized_int) movie);
-
- qtMovie = qtControl->GetMovie();
-
- if (qtMovie != 0)
- qtMovie->PutMovieControllerType (isControllerVisible ? qtMovieControllerTypeStandard
- : qtMovieControllerTypeNone);
- }
-
- if (movie == 0)
- ((QTMovieCompInternal*) internal)->clearHandle();
- }
-
- movieLoaded = (qtMovie != 0);
- }
- else
- {
- // You're trying to open a movie when the control hasn't yet been created, probably because
- // you've not yet added this component to a Window and made the whole component hierarchy visible.
- jassertfalse
- }
-
- delete movieStream;
- return movieLoaded;
- }
-
- void QuickTimeMovieComponent::closeMovie()
- {
- stop();
- movieFile = File::nonexistent;
- movieLoaded = false;
- qtMovie = 0;
-
- if (qtControl != 0)
- qtControl->Put_MovieHandle (0);
-
- ((QTMovieCompInternal*) internal)->clearHandle();
- }
-
- const File QuickTimeMovieComponent::getCurrentMovieFile() const
- {
- return movieFile;
- }
-
- bool QuickTimeMovieComponent::isMovieOpen() const
- {
- return movieLoaded;
- }
-
- double QuickTimeMovieComponent::getMovieDuration() const
- {
- if (qtMovie != 0)
- return qtMovie->GetDuration() / (double) qtMovie->GetTimeScale();
-
- return 0.0;
- }
-
- void QuickTimeMovieComponent::getMovieNormalSize (int& width, int& height) const
- {
- if (qtMovie != 0)
- {
- struct QTRECT r = qtMovie->GetNaturalRect();
-
- width = r.right - r.left;
- height = r.bottom - r.top;
- }
- else
- {
- width = height = 0;
- }
- }
-
- void QuickTimeMovieComponent::play()
- {
- if (qtMovie != 0)
- qtMovie->Play();
- }
-
- void QuickTimeMovieComponent::stop()
- {
- if (qtMovie != 0)
- qtMovie->Stop();
- }
-
- bool QuickTimeMovieComponent::isPlaying() const
- {
- return qtMovie != 0 && qtMovie->GetRate() != 0.0f;
- }
-
- void QuickTimeMovieComponent::setPosition (const double seconds)
- {
- if (qtMovie != 0)
- qtMovie->PutTime ((long) (seconds * qtMovie->GetTimeScale()));
- }
-
- double QuickTimeMovieComponent::getPosition() const
- {
- if (qtMovie != 0)
- return qtMovie->GetTime() / (double) qtMovie->GetTimeScale();
-
- return 0.0;
- }
-
- void QuickTimeMovieComponent::setSpeed (const float newSpeed)
- {
- if (qtMovie != 0)
- qtMovie->PutRate (newSpeed);
- }
-
- void QuickTimeMovieComponent::setMovieVolume (const float newVolume)
- {
- if (qtMovie != 0)
- {
- qtMovie->PutAudioVolume (newVolume);
- qtMovie->PutAudioMute (newVolume <= 0);
- }
- }
-
- float QuickTimeMovieComponent::getMovieVolume() const
- {
- if (qtMovie != 0)
- return qtMovie->GetAudioVolume();
-
- return 0.0f;
- }
-
- void QuickTimeMovieComponent::setLooping (const bool shouldLoop)
- {
- if (qtMovie != 0)
- qtMovie->PutLoop (shouldLoop);
- }
-
- bool QuickTimeMovieComponent::isLooping() const
- {
- return qtMovie != 0 && qtMovie->GetLoop();
- }
-
- bool QuickTimeMovieComponent::isControllerVisible() const
- {
- return controllerVisible;
- }
-
- void QuickTimeMovieComponent::parentHierarchyChanged()
- {
- createControlIfNeeded();
- QTWinBaseClass::parentHierarchyChanged();
- }
-
- void QuickTimeMovieComponent::visibilityChanged()
- {
- createControlIfNeeded();
- QTWinBaseClass::visibilityChanged();
- }
-
- void QuickTimeMovieComponent::paint (Graphics& g)
- {
- if (! isControlCreated())
- g.fillAll (Colours::black);
- }
-
- #endif
-
- #if JUCE_MAC
-
- static VoidArray activeQTWindows (2);
-
- struct MacClickEventData
- {
- ::Point where;
- long when;
- long modifiers;
- };
-
- void OfferMouseClickToQuickTime (WindowRef window,
- ::Point where, long when, long modifiers,
- Component* topLevelComp)
- {
- if (hasLoadedQT)
- {
- for (int i = activeQTWindows.size(); --i >= 0;)
- {
- QuickTimeMovieComponent* const qtw = (QuickTimeMovieComponent*) activeQTWindows[i];
-
- if (qtw->isVisible() && topLevelComp->isParentOf (qtw))
- {
- MacClickEventData data;
- data.where = where;
- data.when = when;
- data.modifiers = modifiers;
-
- qtw->handleMCEvent (&data);
- }
- }
- }
- }
-
- QuickTimeMovieComponent::QuickTimeMovieComponent()
- : internal (new QTMovieCompInternal()),
- associatedWindow (0),
- controllerVisible (false),
- controllerAssignedToWindow (false),
- reentrant (false)
- {
- if (! hasLoadedQT)
- {
- hasLoadedQT = true;
- isQTAvailable = EnterMovies() == noErr;
- }
-
- setOpaque (true);
- setVisible (true);
-
- activeQTWindows.add (this);
- }
-
- QuickTimeMovieComponent::~QuickTimeMovieComponent()
- {
- closeMovie();
-
- activeQTWindows.removeValue ((void*) this);
-
- QTMovieCompInternal* const i = (QTMovieCompInternal*) internal;
- delete i;
-
- if (activeQTWindows.size() == 0 && isQTAvailable)
- {
- isQTAvailable = false;
- hasLoadedQT = false;
-
- ExitMovies();
- }
- }
-
- bool QuickTimeMovieComponent::isQuickTimeAvailable() throw()
- {
- if (! hasLoadedQT)
- {
- hasLoadedQT = true;
- isQTAvailable = EnterMovies() == noErr;
- }
-
- return isQTAvailable;
- }
-
- bool QuickTimeMovieComponent::loadMovie (InputStream* movieStream,
- const bool controllerVisible_)
- {
- if (! isQTAvailable)
- return false;
-
- closeMovie();
- movieFile = File::nonexistent;
-
- if (getPeer() == 0)
- {
- // To open a movie, this component must be visible inside a functioning window, so that
- // the QT control can be assigned to the window.
- jassertfalse
- return false;
- }
-
- controllerVisible = controllerVisible_;
-
- QTMovieCompInternal* const qmci = (QTMovieCompInternal*) internal;
-
- GrafPtr savedPort;
- GetPort (&savedPort);
- bool result = false;
-
- if (juce_OpenQuickTimeMovieFromStream (movieStream, qmci->movie, qmci->dataHandle))
- {
- qmci->controller = 0;
-
- void* window = getWindowHandle();
-
- if (window != associatedWindow && window != 0)
- associatedWindow = window;
-
- assignMovieToWindow();
-
- SetMovieActive (qmci->movie, true);
- SetMovieProgressProc (qmci->movie, (MovieProgressUPP) -1, 0);
-
- startTimer (1000 / 50); // this needs to be quite a high frequency for smooth playback
- result = true;
-
- repaint();
- }
-
- MacSetPort (savedPort);
-
- return result;
- }
-
- void QuickTimeMovieComponent::closeMovie()
- {
- stop();
-
- QTMovieCompInternal* const qmci = (QTMovieCompInternal*) internal;
-
- if (qmci->controller != 0)
- {
- DisposeMovieController (qmci->controller);
- qmci->controller = 0;
- }
-
- if (qmci->movie != 0)
- {
- DisposeMovie (qmci->movie);
- qmci->movie = 0;
- }
-
- qmci->clearHandle();
-
- stopTimer();
- movieFile = File::nonexistent;
- }
-
- bool QuickTimeMovieComponent::isMovieOpen() const
- {
- QTMovieCompInternal* const qmci = (QTMovieCompInternal*) internal;
- return qmci->movie != 0 && qmci->controller != 0;
- }
-
- const File QuickTimeMovieComponent::getCurrentMovieFile() const
- {
- return movieFile;
- }
-
- static GrafPtr getPortForWindow (void* window)
- {
- if (window == 0)
- return 0;
-
- return (GrafPtr) GetWindowPort ((WindowRef) window);
- }
-
- void QuickTimeMovieComponent::assignMovieToWindow()
- {
- if (reentrant)
- return;
-
- reentrant = true;
-
- QTMovieCompInternal* const qmci = (QTMovieCompInternal*) internal;
- if (qmci->controller != 0)
- {
- DisposeMovieController (qmci->controller);
- qmci->controller = 0;
- }
-
- controllerAssignedToWindow = false;
-
- void* window = getWindowHandle();
- GrafPtr port = getPortForWindow (window);
-
- if (port != 0)
- {
- GrafPtr savedPort;
- GetPort (&savedPort);
-
- SetMovieGWorld (qmci->movie, (CGrafPtr) port, 0);
- MacSetPort (port);
-
- Rect r;
- r.top = 0;
- r.left = 0;
- r.right = (short) jmax (1, getWidth());
- r.bottom = (short) jmax (1, getHeight());
- SetMovieBox (qmci->movie, &r);
-
- // create the movie controller
- qmci->controller = NewMovieController (qmci->movie, &r,
- controllerVisible ? mcTopLeftMovie
- : mcNotVisible);
-
- if (qmci->controller != 0)
- {
- MCEnableEditing (qmci->controller, true);
-
- MCDoAction (qmci->controller, mcActionSetUseBadge, (void*) false);
- MCDoAction (qmci->controller, mcActionSetLoopIsPalindrome, (void*) false);
- setLooping (looping);
-
- MCDoAction (qmci->controller, mcActionSetFlags,
- (void*) (pointer_sized_int) (mcFlagSuppressMovieFrame | (controllerVisible ? 0 : (mcFlagSuppressStepButtons | mcFlagSuppressSpeakerButton))));
-
- MCSetControllerBoundsRect (qmci->controller, &r);
-
- controllerAssignedToWindow = true;
-
- resized();
- }
-
- MacSetPort (savedPort);
- }
- else
- {
- SetMovieGWorld (qmci->movie, 0, 0);
- }
-
- reentrant = false;
- }
-
- void QuickTimeMovieComponent::play()
- {
- QTMovieCompInternal* const qmci = (QTMovieCompInternal*) internal;
-
- if (qmci->movie != 0)
- StartMovie (qmci->movie);
- }
-
- void QuickTimeMovieComponent::stop()
- {
- QTMovieCompInternal* const qmci = (QTMovieCompInternal*) internal;
-
- if (qmci->movie != 0)
- StopMovie (qmci->movie);
- }
-
- bool QuickTimeMovieComponent::isPlaying() const
- {
- QTMovieCompInternal* const qmci = (QTMovieCompInternal*) internal;
-
- return qmci->movie != 0 && GetMovieRate (qmci->movie) != 0;
- }
-
- void QuickTimeMovieComponent::setPosition (const double seconds)
- {
- QTMovieCompInternal* const qmci = (QTMovieCompInternal*) internal;
-
- if (qmci->controller != 0)
- {
- TimeRecord time;
- time.base = GetMovieTimeBase (qmci->movie);
- time.scale = 100000;
- const uint64 t = (uint64) (100000.0 * seconds);
- time.value.lo = (UInt32) (t & 0xffffffff);
- time.value.hi = (UInt32) (t >> 32);
-
- SetMovieTime (qmci->movie, &time);
- timerCallback(); // to call MCIdle
- }
- else
- {
- jassertfalse // no movie is open, so can't set the position.
- }
- }
-
- double QuickTimeMovieComponent::getPosition() const
- {
- QTMovieCompInternal* const qmci = (QTMovieCompInternal*) internal;
-
- if (qmci->movie != 0)
- {
- TimeRecord time;
- GetMovieTime (qmci->movie, &time);
-
- return ((int64) (((uint64) time.value.hi << 32) | (uint64) time.value.lo))
- / (double) time.scale;
- }
-
- return 0.0;
- }
-
- void QuickTimeMovieComponent::setSpeed (const float newSpeed)
- {
- QTMovieCompInternal* const qmci = (QTMovieCompInternal*) internal;
-
- if (qmci->movie != 0)
- SetMovieRate (qmci->movie, (Fixed) (newSpeed * (Fixed) 0x00010000L));
- }
-
- double QuickTimeMovieComponent::getMovieDuration() const
- {
- QTMovieCompInternal* const qmci = (QTMovieCompInternal*) internal;
-
- if (qmci->movie != 0)
- return GetMovieDuration (qmci->movie) / (double) GetMovieTimeScale (qmci->movie);
-
- return 0.0;
- }
-
- void QuickTimeMovieComponent::setLooping (const bool shouldLoop)
- {
- QTMovieCompInternal* const qmci = (QTMovieCompInternal*) internal;
- looping = shouldLoop;
-
- if (qmci->controller != 0)
- MCDoAction (qmci->controller, mcActionSetLooping, (void*) shouldLoop);
- }
-
- bool QuickTimeMovieComponent::isLooping() const
- {
- return looping;
- }
-
- void QuickTimeMovieComponent::setMovieVolume (const float newVolume)
- {
- QTMovieCompInternal* const qmci = (QTMovieCompInternal*) internal;
-
- if (qmci->movie != 0)
- SetMovieVolume (qmci->movie, jlimit ((short) 0, (short) 0x100, (short) (newVolume * 0x0100)));
- }
-
- float QuickTimeMovieComponent::getMovieVolume() const
- {
- QTMovieCompInternal* const qmci = (QTMovieCompInternal*) internal;
-
- if (qmci->movie != 0)
- return jmax (0.0f, GetMovieVolume (qmci->movie) / (float) 0x0100);
-
- return 0.0f;
- }
-
- void QuickTimeMovieComponent::getMovieNormalSize (int& width, int& height) const
- {
- width = 0;
- height = 0;
-
- QTMovieCompInternal* const qmci = (QTMovieCompInternal*) internal;
-
- if (qmci->movie != 0)
- {
- Rect r;
- GetMovieNaturalBoundsRect (qmci->movie, &r);
- width = r.right - r.left;
- height = r.bottom - r.top;
- }
- }
-
- void QuickTimeMovieComponent::paint (Graphics& g)
- {
- QTMovieCompInternal* const qmci = (QTMovieCompInternal*) internal;
-
- if (qmci->movie == 0 || qmci->controller == 0)
- {
- g.fillAll (Colours::black);
- return;
- }
-
- GrafPtr savedPort;
- GetPort (&savedPort);
-
- MacSetPort (getPortForWindow (getWindowHandle()));
- MCDraw (qmci->controller, (WindowRef) getWindowHandle());
-
- MacSetPort (savedPort);
-
- ComponentPeer* const peer = getPeer();
-
- if (peer != 0)
- {
- peer->addMaskedRegion (getScreenX() - peer->getScreenX(),
- getScreenY() - peer->getScreenY(),
- getWidth(), getHeight());
- }
-
- timerCallback();
- }
-
- static const Rectangle getMoviePos (Component* const c)
- {
- return Rectangle (c->getScreenX() - c->getTopLevelComponent()->getScreenX(),
- c->getScreenY() - c->getTopLevelComponent()->getScreenY(),
- jmax (1, c->getWidth()),
- jmax (1, c->getHeight()));
- }
-
- void QuickTimeMovieComponent::moved()
- {
- resized();
- }
-
- void QuickTimeMovieComponent::resized()
- {
- QTMovieCompInternal* const qmci = (QTMovieCompInternal*) internal;
-
- if (qmci->controller != 0 && isShowing())
- {
- checkWindowAssociation();
-
- GrafPtr port = getPortForWindow (getWindowHandle());
-
- if (port != 0)
- {
- GrafPtr savedPort;
- GetPort (&savedPort);
-
- SetMovieGWorld (qmci->movie, (CGrafPtr) port, 0);
- MacSetPort (port);
-
- lastPositionApplied = getMoviePos (this);
-
- Rect r;
- r.left = (short) lastPositionApplied.getX();
- r.top = (short) lastPositionApplied.getY();
- r.right = (short) lastPositionApplied.getRight();
- r.bottom = (short) lastPositionApplied.getBottom();
-
- if (MCGetVisible (qmci->controller))
- MCSetControllerBoundsRect (qmci->controller, &r);
- else
- SetMovieBox (qmci->movie, &r);
-
- if (! isPlaying())
- timerCallback();
-
- MacSetPort (savedPort);
-
- repaint();
- }
- }
- }
-
- void QuickTimeMovieComponent::visibilityChanged()
- {
- checkWindowAssociation();
- QTWinBaseClass::visibilityChanged();
- }
-
- void QuickTimeMovieComponent::timerCallback()
- {
- QTMovieCompInternal* const qmci = (QTMovieCompInternal*) internal;
-
- if (qmci->controller != 0)
- {
- if (isTimerRunning())
- startTimer (getTimerInterval());
-
- MCIdle (qmci->controller);
-
- if (lastPositionApplied != getMoviePos (this))
- resized();
- }
- }
-
- void QuickTimeMovieComponent::checkWindowAssociation()
- {
- void* const window = getWindowHandle();
-
- if (window != associatedWindow
- || (window != 0 && ! controllerAssignedToWindow))
- {
- associatedWindow = window;
- assignMovieToWindow();
- }
- }
-
- void QuickTimeMovieComponent::parentHierarchyChanged()
- {
- checkWindowAssociation();
- }
-
- void QuickTimeMovieComponent::handleMCEvent (void* ev)
- {
- QTMovieCompInternal* const qmci = (QTMovieCompInternal*) internal;
-
- if (qmci->controller != 0 && isShowing())
- {
- MacClickEventData* data = (MacClickEventData*) ev;
-
- data->where.h -= getTopLevelComponent()->getScreenX();
- data->where.v -= getTopLevelComponent()->getScreenY();
-
- Boolean b = false;
- MCPtInController (qmci->controller, data->where, &b);
-
- if (b)
- {
- const int oldTimeBeforeWaitCursor = MessageManager::getInstance()->getTimeBeforeShowingWaitCursor();
- MessageManager::getInstance()->setTimeBeforeShowingWaitCursor (0);
-
- MCClick (qmci->controller,
- (WindowRef) getWindowHandle(),
- data->where,
- data->when,
- data->modifiers);
-
- MessageManager::getInstance()->setTimeBeforeShowingWaitCursor (oldTimeBeforeWaitCursor);
- }
- }
- }
-
- #endif
-
- // (methods common to both platforms..)
-
- static Handle createHandleDataRef (Handle dataHandle, const char* fileName)
- {
- Handle dataRef = 0;
- OSStatus err = PtrToHand (&dataHandle, &dataRef, sizeof (Handle));
- if (err == noErr)
- {
- Str255 suffix;
-
- CharacterFunctions::copy ((char*) suffix, fileName, 128);
-
- StringPtr name = suffix;
- err = PtrAndHand (name, dataRef, name[0] + 1);
-
- if (err == noErr)
- {
- long atoms[3];
- atoms[0] = EndianU32_NtoB (3 * sizeof (long));
- atoms[1] = EndianU32_NtoB (kDataRefExtensionMacOSFileType);
- atoms[2] = EndianU32_NtoB (MovieFileType);
-
- err = PtrAndHand (atoms, dataRef, 3 * sizeof (long));
-
- if (err == noErr)
- return dataRef;
- }
-
- DisposeHandle (dataRef);
- }
-
- return 0;
- }
-
- static CFStringRef juceStringToCFString (const String& s)
- {
- const int len = s.length();
- const juce_wchar* const t = (const juce_wchar*) s;
-
- UniChar* temp = (UniChar*) juce_malloc (sizeof (UniChar) * len + 4);
-
- for (int i = 0; i <= len; ++i)
- temp[i] = t[i];
-
- CFStringRef result = CFStringCreateWithCharacters (kCFAllocatorDefault, temp, len);
- juce_free (temp);
-
- return result;
- }
-
- static bool openMovie (QTNewMoviePropertyElement* props, int prop, Movie& movie)
- {
- Boolean trueBool = true;
- props[prop].propClass = kQTPropertyClass_MovieInstantiation;
- props[prop].propID = kQTMovieInstantiationPropertyID_DontResolveDataRefs;
- props[prop].propValueSize = sizeof (trueBool);
- props[prop].propValueAddress = &trueBool;
- ++prop;
-
- props[prop].propClass = kQTPropertyClass_MovieInstantiation;
- props[prop].propID = kQTMovieInstantiationPropertyID_AsyncOK;
- props[prop].propValueSize = sizeof (trueBool);
- props[prop].propValueAddress = &trueBool;
- ++prop;
-
- Boolean isActive = true;
- props[prop].propClass = kQTPropertyClass_NewMovieProperty;
- props[prop].propID = kQTNewMoviePropertyID_Active;
- props[prop].propValueSize = sizeof (isActive);
- props[prop].propValueAddress = &isActive;
- ++prop;
-
- #if JUCE_MAC
- SetPort (0);
- #else
- MacSetPort (0);
- #endif
-
- jassert (prop <= 5);
- OSStatus err = NewMovieFromProperties (prop, props, 0, 0, &movie);
-
- return err == noErr;
- }
-
- bool juce_OpenQuickTimeMovieFromStream (InputStream* input, Movie& movie, Handle& dataHandle)
- {
- if (input == 0)
- return false;
-
- dataHandle = 0;
- bool ok = false;
-
- QTNewMoviePropertyElement props[5];
- zeromem (props, sizeof (props));
- int prop = 0;
-
- DataReferenceRecord dr;
- props[prop].propClass = kQTPropertyClass_DataLocation;
- props[prop].propID = kQTDataLocationPropertyID_DataReference;
- props[prop].propValueSize = sizeof (dr);
- props[prop].propValueAddress = (void*) &dr;
- ++prop;
-
- FileInputStream* const fin = dynamic_cast <FileInputStream*> (input);
-
- if (fin != 0)
- {
- CFStringRef filePath = juceStringToCFString (fin->getFile().getFullPathName());
-
- QTNewDataReferenceFromFullPathCFString (filePath, (QTPathStyle) kQTNativeDefaultPathStyle, 0,
- &dr.dataRef, &dr.dataRefType);
-
- ok = openMovie (props, prop, movie);
-
- DisposeHandle (dr.dataRef);
- CFRelease (filePath);
- }
- else
- {
- // sanity-check because this currently needs to load the whole stream into memory..
- jassert (input->getTotalLength() < 50 * 1024 * 1024);
-
- dataHandle = NewHandle ((Size) input->getTotalLength());
- HLock (dataHandle);
- // read the entire stream into memory - this is a pain, but can't get it to work
- // properly using a custom callback to supply the data.
- input->read (*dataHandle, (int) input->getTotalLength());
- HUnlock (dataHandle);
-
- // different types to get QT to try. (We should really be a bit smarter here by
- // working out in advance which one the stream contains, rather than just trying
- // each one)
- const char* const suffixesToTry[] = { "\04.mov", "\04.mp3",
- "\04.avi", "\04.m4a" };
-
- for (int i = 0; i < numElementsInArray (suffixesToTry) && ! ok; ++i)
- {
- /* // this fails for some bizarre reason - it can be bodged to work with
- // movies, but can't seem to do it for other file types..
- QTNewMovieUserProcRecord procInfo;
- procInfo.getMovieUserProc = NewGetMovieUPP (readMovieStreamProc);
- procInfo.getMovieUserProcRefcon = this;
- procInfo.defaultDataRef.dataRef = dataRef;
- procInfo.defaultDataRef.dataRefType = HandleDataHandlerSubType;
-
- props[prop].propClass = kQTPropertyClass_DataLocation;
- props[prop].propID = kQTDataLocationPropertyID_MovieUserProc;
- props[prop].propValueSize = sizeof (procInfo);
- props[prop].propValueAddress = (void*) &procInfo;
- ++prop; */
-
- dr.dataRef = createHandleDataRef (dataHandle, suffixesToTry [i]);
- dr.dataRefType = HandleDataHandlerSubType;
- ok = openMovie (props, prop, movie);
-
- DisposeHandle (dr.dataRef);
- }
- }
-
- return ok;
- }
-
- bool QuickTimeMovieComponent::loadMovie (const File& movieFile_,
- const bool isControllerVisible)
- {
- const bool ok = loadMovie ((InputStream*) movieFile_.createInputStream(), isControllerVisible);
- movieFile = movieFile_;
- return ok;
- }
-
- void QuickTimeMovieComponent::goToStart()
- {
- setPosition (0.0);
- }
-
- void QuickTimeMovieComponent::setBoundsWithCorrectAspectRatio (const Rectangle& spaceToFitWithin,
- const RectanglePlacement& placement)
- {
- int normalWidth, normalHeight;
- getMovieNormalSize (normalWidth, normalHeight);
-
- if (normalWidth > 0 && normalHeight > 0 && ! spaceToFitWithin.isEmpty())
- {
- double x = 0.0, y = 0.0, w = normalWidth, h = normalHeight;
-
- placement.applyTo (x, y, w, h,
- spaceToFitWithin.getX(), spaceToFitWithin.getY(),
- spaceToFitWithin.getWidth(), spaceToFitWithin.getHeight());
-
- if (w > 0 && h > 0)
- {
- setBounds (roundDoubleToInt (x), roundDoubleToInt (y),
- roundDoubleToInt (w), roundDoubleToInt (h));
- }
- }
- else
- {
- setBounds (spaceToFitWithin);
- }
- }
-
- END_JUCE_NAMESPACE
-
- #endif
- /********* End of inlined file: juce_QuickTimeMovieComponent.cpp *********/
-
- /********* Start of inlined file: juce_SystemTrayIconComponent.cpp *********/
-
- #if JUCE_WIN32 || JUCE_LINUX
-
- BEGIN_JUCE_NAMESPACE
-
- SystemTrayIconComponent::SystemTrayIconComponent()
- {
- addToDesktop (0);
- }
-
- SystemTrayIconComponent::~SystemTrayIconComponent()
- {
- }
-
- END_JUCE_NAMESPACE
-
- #endif
- /********* End of inlined file: juce_SystemTrayIconComponent.cpp *********/
-
- /********* Start of inlined file: juce_AlertWindow.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- static const int titleH = 24;
- static const int iconWidth = 80;
-
- class AlertWindowTextEditor : public TextEditor
- {
- public:
- #if JUCE_LINUX
- #define PASSWORD_CHAR 0x2022
- #else
- #define PASSWORD_CHAR 0x25cf
- #endif
-
- AlertWindowTextEditor (const String& name,
- const bool isPasswordBox)
- : TextEditor (name,
- isPasswordBox ? (const tchar) PASSWORD_CHAR
- : (const tchar) 0)
- {
- setSelectAllWhenFocused (true);
- }
-
- ~AlertWindowTextEditor()
- {
- }
-
- void returnPressed()
- {
- // pass these up the component hierarchy to be trigger the buttons
- getParentComponent()->keyPressed (KeyPress (KeyPress::returnKey, 0, T('\n')));
- }
-
- void escapePressed()
- {
- // pass these up the component hierarchy to be trigger the buttons
- getParentComponent()->keyPressed (KeyPress (KeyPress::escapeKey, 0, 0));
- }
-
- private:
- AlertWindowTextEditor (const AlertWindowTextEditor&);
- const AlertWindowTextEditor& operator= (const AlertWindowTextEditor&);
- };
-
- AlertWindow::AlertWindow (const String& title,
- const String& message,
- AlertIconType iconType)
- : TopLevelWindow (title, true),
- alertIconType (iconType)
- {
- if (message.isEmpty())
- text = T(" "); // to force an update if the message is empty
-
- setMessage (message);
-
- #if JUCE_MAC
- setAlwaysOnTop (true);
- #else
- for (int i = Desktop::getInstance().getNumComponents(); --i >= 0;)
- {
- Component* const c = Desktop::getInstance().getComponent (i);
-
- if (c != 0 && c->isAlwaysOnTop() && c->isShowing())
- {
- setAlwaysOnTop (true);
- break;
- }
- }
- #endif
-
- lookAndFeelChanged();
-
- constrainer.setMinimumOnscreenAmounts (0x10000, 0x10000, 0x10000, 0x10000);
- }
-
- AlertWindow::~AlertWindow()
- {
- for (int i = customComps.size(); --i >= 0;)
- removeChildComponent ((Component*) customComps[i]);
-
- deleteAllChildren();
- }
-
- void AlertWindow::setMessage (const String& message)
- {
- const String newMessage (message.substring (0, 2048));
-
- if (text != newMessage)
- {
- text = newMessage;
-
- font.setHeight (15.0f);
-
- Font titleFont (font.getHeight() * 1.1f, Font::bold);
- textLayout.setText (getName() + T("\n\n"), titleFont);
-
- textLayout.appendText (text, font);
-
- updateLayout (true);
- repaint();
- }
- }
-
- void AlertWindow::buttonClicked (Button* button)
- {
- for (int i = 0; i < buttons.size(); i++)
- {
- TextButton* const c = (TextButton*) buttons[i];
-
- if (button->getName() == c->getName())
- {
- if (c->getParentComponent() != 0)
- c->getParentComponent()->exitModalState (c->getCommandID());
-
- break;
- }
- }
- }
-
- void AlertWindow::addButton (const String& name,
- const int returnValue,
- const KeyPress& shortcutKey1,
- const KeyPress& shortcutKey2)
- {
- TextButton* const b = new TextButton (name, String::empty);
-
- b->setWantsKeyboardFocus (true);
- b->setMouseClickGrabsKeyboardFocus (false);
- b->setCommandToTrigger (0, returnValue, false);
- b->addShortcut (shortcutKey1);
- b->addShortcut (shortcutKey2);
- b->addButtonListener (this);
- b->changeWidthToFitText (28);
-
- addAndMakeVisible (b, 0);
- buttons.add (b);
-
- updateLayout (false);
- }
-
- int AlertWindow::getNumButtons() const
- {
- return buttons.size();
- }
-
- void AlertWindow::addTextEditor (const String& name,
- const String& initialContents,
- const String& onScreenLabel,
- const bool isPasswordBox)
- {
- AlertWindowTextEditor* const tc = new AlertWindowTextEditor (name, isPasswordBox);
-
- tc->setColour (TextEditor::outlineColourId, findColour (ComboBox::outlineColourId));
- tc->setFont (font);
- tc->setText (initialContents);
- tc->setCaretPosition (initialContents.length());
- addAndMakeVisible (tc);
- textBoxes.add (tc);
- allComps.add (tc);
- textboxNames.add (onScreenLabel);
-
- updateLayout (false);
- }
-
- const String AlertWindow::getTextEditorContents (const String& nameOfTextEditor) const
- {
- for (int i = textBoxes.size(); --i >= 0;)
- if (((TextEditor*)textBoxes[i])->getName() == nameOfTextEditor)
- return ((TextEditor*)textBoxes[i])->getText();
-
- return String::empty;
- }
-
- void AlertWindow::addComboBox (const String& name,
- const StringArray& items,
- const String& onScreenLabel)
- {
- ComboBox* const cb = new ComboBox (name);
-
- for (int i = 0; i < items.size(); ++i)
- cb->addItem (items[i], i + 1);
-
- addAndMakeVisible (cb);
- cb->setSelectedItemIndex (0);
-
- comboBoxes.add (cb);
- allComps.add (cb);
-
- comboBoxNames.add (onScreenLabel);
-
- updateLayout (false);
- }
-
- ComboBox* AlertWindow::getComboBoxComponent (const String& nameOfList) const
- {
- for (int i = comboBoxes.size(); --i >= 0;)
- if (((ComboBox*) comboBoxes[i])->getName() == nameOfList)
- return (ComboBox*) comboBoxes[i];
-
- return 0;
- }
-
- class AlertTextComp : public TextEditor
- {
- AlertTextComp (const AlertTextComp&);
- const AlertTextComp& operator= (const AlertTextComp&);
-
- int bestWidth;
-
- public:
- AlertTextComp (const String& message,
- const Font& font)
- {
- setReadOnly (true);
- setMultiLine (true, true);
- setCaretVisible (false);
- setScrollbarsShown (true);
- lookAndFeelChanged();
- setWantsKeyboardFocus (false);
-
- setFont (font);
- setText (message, false);
-
- bestWidth = 2 * (int) sqrt (font.getHeight() * font.getStringWidth (message));
-
- setColour (TextEditor::backgroundColourId, Colours::transparentBlack);
- setColour (TextEditor::outlineColourId, Colours::transparentBlack);
- setColour (TextEditor::shadowColourId, Colours::transparentBlack);
- }
-
- ~AlertTextComp()
- {
- }
-
- int getPreferredWidth() const throw() { return bestWidth; }
-
- void updateLayout (const int width)
- {
- TextLayout text;
- text.appendText (getText(), getFont());
- text.layout (width - 8, Justification::topLeft, true);
- setSize (width, jmin (width, text.getHeight() + (int) getFont().getHeight()));
- }
- };
-
- void AlertWindow::addTextBlock (const String& text)
- {
- AlertTextComp* const c = new AlertTextComp (text, font);
-
- textBlocks.add (c);
- allComps.add (c);
-
- addAndMakeVisible (c);
-
- updateLayout (false);
- }
-
- void AlertWindow::addProgressBarComponent (double& progressValue)
- {
- ProgressBar* const pb = new ProgressBar (progressValue);
-
- progressBars.add (pb);
- allComps.add (pb);
-
- addAndMakeVisible (pb);
-
- updateLayout (false);
- }
-
- void AlertWindow::addCustomComponent (Component* const component)
- {
- customComps.add (component);
- allComps.add (component);
-
- addAndMakeVisible (component);
-
- updateLayout (false);
- }
-
- int AlertWindow::getNumCustomComponents() const
- {
- return customComps.size();
- }
-
- Component* AlertWindow::getCustomComponent (const int index) const
- {
- return (Component*) customComps [index];
- }
-
- Component* AlertWindow::removeCustomComponent (const int index)
- {
- Component* const c = getCustomComponent (index);
-
- if (c != 0)
- {
- customComps.removeValue (c);
- allComps.removeValue (c);
- removeChildComponent (c);
-
- updateLayout (false);
- }
-
- return c;
- }
-
- void AlertWindow::paint (Graphics& g)
- {
- getLookAndFeel().drawAlertBox (g, *this, textArea, textLayout);
-
- g.setColour (Colours::black);
- g.setFont (12.0f);
-
- int i;
- for (i = textBoxes.size(); --i >= 0;)
- {
- if (textboxNames[i].isNotEmpty())
- {
- const TextEditor* const te = (TextEditor*) textBoxes[i];
-
- g.drawFittedText (textboxNames[i],
- te->getX(), te->getY() - 14,
- te->getWidth(), 14,
- Justification::centredLeft, 1);
- }
- }
-
- for (i = comboBoxNames.size(); --i >= 0;)
- {
- if (comboBoxNames[i].isNotEmpty())
- {
- const ComboBox* const cb = (ComboBox*) comboBoxes[i];
-
- g.drawFittedText (comboBoxNames[i],
- cb->getX(), cb->getY() - 14,
- cb->getWidth(), 14,
- Justification::centredLeft, 1);
- }
- }
- }
-
- void AlertWindow::updateLayout (const bool onlyIncreaseSize)
- {
- const int wid = jmax (font.getStringWidth (text),
- font.getStringWidth (getName()));
-
- const int sw = (int) sqrt (font.getHeight() * wid);
- int w = jmin (300 + sw * 2, (int) (getParentWidth() * 0.7f));
- const int edgeGap = 10;
- int iconSpace;
-
- if (alertIconType == NoIcon)
- {
- textLayout.layout (w, Justification::horizontallyCentred, true);
- iconSpace = 0;
- }
- else
- {
- textLayout.layout (w, Justification::left, true);
- iconSpace = iconWidth;
- }
-
- w = jmax (350, textLayout.getWidth() + iconSpace + edgeGap * 4);
- w = jmin (w, (int) (getParentWidth() * 0.7f));
-
- const int textLayoutH = textLayout.getHeight();
- const int textBottom = 16 + titleH + textLayoutH;
- int h = textBottom;
-
- int buttonW = 40;
- int i;
- for (i = 0; i < buttons.size(); ++i)
- buttonW += 16 + ((const TextButton*) buttons[i])->getWidth();
-
- w = jmax (buttonW, w);
-
- h += (textBoxes.size() + comboBoxes.size() + progressBars.size()) * 50;
-
- if (buttons.size() > 0)
- h += 20 + ((TextButton*) buttons[0])->getHeight();
-
- for (i = customComps.size(); --i >= 0;)
- {
- w = jmax (w, ((Component*) customComps[i])->getWidth() + 40);
- h += 10 + ((Component*) customComps[i])->getHeight();
- }
-
- for (i = textBlocks.size(); --i >= 0;)
- {
- const AlertTextComp* const ac = (AlertTextComp*) textBlocks[i];
- w = jmax (w, ac->getPreferredWidth());
- }
-
- w = jmin (w, (int) (getParentWidth() * 0.7f));
-
- for (i = textBlocks.size(); --i >= 0;)
- {
- AlertTextComp* const ac = (AlertTextComp*) textBlocks[i];
- ac->updateLayout ((int) (w * 0.8f));
- h += ac->getHeight() + 10;
- }
-
- h = jmin (getParentHeight() - 50, h);
-
- if (onlyIncreaseSize)
- {
- w = jmax (w, getWidth());
- h = jmax (h, getHeight());
- }
-
- if (! isVisible())
- {
- centreAroundComponent (0, w, h);
- }
- else
- {
- const int cx = getX() + getWidth() / 2;
- const int cy = getY() + getHeight() / 2;
-
- setBounds (cx - w / 2,
- cy - h / 2,
- w, h);
- }
-
- textArea.setBounds (edgeGap, edgeGap, w - (edgeGap * 2), h - edgeGap);
-
- const int spacer = 16;
- int totalWidth = -spacer;
-
- for (i = buttons.size(); --i >= 0;)
- totalWidth += ((TextButton*) buttons[i])->getWidth() + spacer;
-
- int x = (w - totalWidth) / 2;
- int y = (int) (getHeight() * 0.95f);
-
- for (i = 0; i < buttons.size(); ++i)
- {
- TextButton* const c = (TextButton*) buttons[i];
- int ny = proportionOfHeight (0.95f) - c->getHeight();
- c->setTopLeftPosition (x, ny);
- if (ny < y)
- y = ny;
-
- x += c->getWidth() + spacer;
-
- c->toFront (false);
- }
-
- y = textBottom;
-
- for (i = 0; i < allComps.size(); ++i)
- {
- Component* const c = (Component*) allComps[i];
-
- const int h = 22;
-
- const int comboIndex = comboBoxes.indexOf (c);
- if (comboIndex >= 0 && comboBoxNames [comboIndex].isNotEmpty())
- y += 18;
-
- const int tbIndex = textBoxes.indexOf (c);
- if (tbIndex >= 0 && textboxNames[tbIndex].isNotEmpty())
- y += 18;
-
- if (customComps.contains (c) || textBlocks.contains (c))
- {
- c->setTopLeftPosition ((getWidth() - c->getWidth()) / 2, y);
- y += c->getHeight() + 10;
- }
- else
- {
- c->setBounds (proportionOfWidth (0.1f), y, proportionOfWidth (0.8f), h);
- y += h + 10;
- }
- }
-
- setWantsKeyboardFocus (getNumChildComponents() == 0);
- }
-
- bool AlertWindow::containsAnyExtraComponents() const
- {
- return textBoxes.size()
- + comboBoxes.size()
- + progressBars.size()
- + customComps.size() > 0;
- }
-
- void AlertWindow::mouseDown (const MouseEvent&)
- {
- dragger.startDraggingComponent (this, &constrainer);
- }
-
- void AlertWindow::mouseDrag (const MouseEvent& e)
- {
- dragger.dragComponent (this, e);
- }
-
- bool AlertWindow::keyPressed (const KeyPress& key)
- {
- for (int i = buttons.size(); --i >= 0;)
- {
- TextButton* const b = (TextButton*) buttons[i];
-
- if (b->isRegisteredForShortcut (key))
- {
- b->triggerClick();
- return true;
- }
- }
-
- if (key.isKeyCode (KeyPress::escapeKey) && buttons.size() == 0)
- {
- exitModalState (0);
- return true;
- }
- else if (key.isKeyCode (KeyPress::returnKey) && buttons.size() == 1)
- {
- ((TextButton*) buttons.getFirst())->triggerClick();
- return true;
- }
-
- return false;
- }
-
- void AlertWindow::lookAndFeelChanged()
- {
- const int flags = getLookAndFeel().getAlertBoxWindowFlags();
-
- setUsingNativeTitleBar ((flags & ComponentPeer::windowHasTitleBar) != 0);
- setDropShadowEnabled ((flags & ComponentPeer::windowHasDropShadow) != 0);
- }
-
- struct AlertWindowInfo
- {
- String title, message, button1, button2, button3;
- AlertWindow::AlertIconType iconType;
- int numButtons;
-
- int run() const
- {
- return (int) (pointer_sized_int)
- MessageManager::getInstance()->callFunctionOnMessageThread (showCallback, (void*) this);
- }
-
- private:
- int show() const
- {
- AlertWindow aw (title, message, iconType);
-
- if (numButtons == 1)
- {
- aw.addButton (button1, 0,
- KeyPress (KeyPress::escapeKey, 0, 0),
- KeyPress (KeyPress::returnKey, 0, 0));
- }
- else
- {
- const KeyPress button1ShortCut (CharacterFunctions::toLowerCase (button1[0]), 0, 0);
- KeyPress button2ShortCut (CharacterFunctions::toLowerCase (button2[0]), 0, 0);
- if (button1ShortCut == button2ShortCut)
- button2ShortCut = KeyPress();
-
- if (numButtons == 2)
- {
- aw.addButton (button1, 1, KeyPress (KeyPress::returnKey, 0, 0), button1ShortCut);
- aw.addButton (button2, 0, KeyPress (KeyPress::escapeKey, 0, 0), button2ShortCut);
- }
- else
- {
- jassert (numButtons == 3);
-
- aw.addButton (button1, 1, button1ShortCut);
- aw.addButton (button2, 2, button2ShortCut);
- aw.addButton (button3, 0, KeyPress (KeyPress::escapeKey, 0, 0));
- }
- }
-
- return aw.runModalLoop();
- }
-
- static void* showCallback (void* userData)
- {
- return (void*) (pointer_sized_int) ((const AlertWindowInfo*) userData)->show();
- }
- };
-
- void AlertWindow::showMessageBox (AlertIconType iconType,
- const String& title,
- const String& message,
- const String& buttonText)
- {
- AlertWindowInfo info;
- info.title = title;
- info.message = message;
- info.button1 = buttonText.isEmpty() ? TRANS("ok") : buttonText;
- info.iconType = iconType;
- info.numButtons = 1;
-
- info.run();
- }
-
- bool AlertWindow::showOkCancelBox (AlertIconType iconType,
- const String& title,
- const String& message,
- const String& button1Text,
- const String& button2Text)
- {
- AlertWindowInfo info;
- info.title = title;
- info.message = message;
- info.button1 = button1Text.isEmpty() ? TRANS("ok") : button1Text;
- info.button2 = button2Text.isEmpty() ? TRANS("cancel") : button2Text;
- info.iconType = iconType;
- info.numButtons = 2;
-
- return info.run() != 0;
- }
-
- int AlertWindow::showYesNoCancelBox (AlertIconType iconType,
- const String& title,
- const String& message,
- const String& button1Text,
- const String& button2Text,
- const String& button3Text)
- {
- AlertWindowInfo info;
- info.title = title;
- info.message = message;
- info.button1 = button1Text.isEmpty() ? TRANS("yes") : button1Text;
- info.button2 = button2Text.isEmpty() ? TRANS("no") : button2Text;
- info.button3 = button3Text.isEmpty() ? TRANS("cancel") : button3Text;
- info.iconType = iconType;
- info.numButtons = 3;
-
- return info.run();
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_AlertWindow.cpp *********/
-
- /********* Start of inlined file: juce_ComponentPeer.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- //#define JUCE_ENABLE_REPAINT_DEBUGGING 1
-
- // these are over in juce_component.cpp
- extern int64 juce_recentMouseDownTimes[4];
- extern int juce_recentMouseDownX [4];
- extern int juce_recentMouseDownY [4];
- extern Component* juce_recentMouseDownComponent [4];
- extern int juce_LastMousePosX;
- extern int juce_LastMousePosY;
- extern int juce_MouseClickCounter;
- extern bool juce_MouseHasMovedSignificantlySincePressed;
-
- static const int fakeMouseMoveMessage = 0x7fff00ff;
-
- static VoidArray heavyweightPeers (4);
-
- ComponentPeer::ComponentPeer (Component* const component_,
- const int styleFlags_) throw()
- : component (component_),
- styleFlags (styleFlags_),
- lastPaintTime (0),
- constrainer (0),
- lastFocusedComponent (0),
- dragAndDropTargetComponent (0),
- lastDragAndDropCompUnderMouse (0),
- fakeMouseMessageSent (false),
- isWindowMinimised (false)
- {
- heavyweightPeers.add (this);
- }
-
- ComponentPeer::~ComponentPeer()
- {
- heavyweightPeers.removeValue (this);
- delete dragAndDropTargetComponent;
- }
-
- int ComponentPeer::getNumPeers() throw()
- {
- return heavyweightPeers.size();
- }
-
- ComponentPeer* ComponentPeer::getPeer (const int index) throw()
- {
- return (ComponentPeer*) heavyweightPeers [index];
- }
-
- ComponentPeer* ComponentPeer::getPeerFor (const Component* const component) throw()
- {
- for (int i = heavyweightPeers.size(); --i >= 0;)
- {
- ComponentPeer* const peer = (ComponentPeer*) heavyweightPeers.getUnchecked(i);
-
- if (peer->getComponent() == component)
- return peer;
- }
-
- return 0;
- }
-
- bool ComponentPeer::isValidPeer (const ComponentPeer* const peer) throw()
- {
- return heavyweightPeers.contains (const_cast <ComponentPeer*> (peer));
- }
-
- void ComponentPeer::updateCurrentModifiers() throw()
- {
- ModifierKeys::updateCurrentModifiers();
- }
-
- void ComponentPeer::handleMouseEnter (int x, int y, const int64 time)
- {
- jassert (component->isValidComponent());
- updateCurrentModifiers();
-
- Component* c = component->getComponentAt (x, y);
- const ComponentDeletionWatcher deletionChecker (component);
-
- if (c != Component::componentUnderMouse && Component::componentUnderMouse != 0)
- {
- jassert (Component::componentUnderMouse->isValidComponent());
-
- const int oldX = x;
- const int oldY = y;
- component->relativePositionToOtherComponent (Component::componentUnderMouse, x, y);
- Component::componentUnderMouse->internalMouseExit (x, y, time);
- Component::componentUnderMouse = 0;
-
- if (deletionChecker.hasBeenDeleted())
- return;
-
- c = component->getComponentAt (oldX, oldY);
- }
-
- Component::componentUnderMouse = c;
-
- if (Component::componentUnderMouse != 0)
- {
- component->relativePositionToOtherComponent (Component::componentUnderMouse, x, y);
- Component::componentUnderMouse->internalMouseEnter (x, y, time);
- }
- }
-
- void ComponentPeer::handleMouseMove (int x, int y, const int64 time)
- {
- jassert (component->isValidComponent());
- updateCurrentModifiers();
-
- fakeMouseMessageSent = false;
-
- const ComponentDeletionWatcher deletionChecker (component);
- Component* c = component->getComponentAt (x, y);
-
- if (c != Component::componentUnderMouse)
- {
- const int oldX = x;
- const int oldY = y;
-
- if (Component::componentUnderMouse != 0)
- {
- component->relativePositionToOtherComponent (Component::componentUnderMouse, x, y);
- Component::componentUnderMouse->internalMouseExit (x, y, time);
- x = oldX;
- y = oldY;
-
- Component::componentUnderMouse = 0;
-
- if (deletionChecker.hasBeenDeleted())
- return; // if this window has just been deleted..
-
- c = component->getComponentAt (x, y);
- }
-
- Component::componentUnderMouse = c;
-
- if (c != 0)
- {
- component->relativePositionToOtherComponent (c, x, y);
- c->internalMouseEnter (x, y, time);
- x = oldX;
- y = oldY;
-
- if (deletionChecker.hasBeenDeleted())
- return; // if this window has just been deleted..
- }
- }
-
- if (Component::componentUnderMouse != 0)
- {
- component->relativePositionToOtherComponent (Component::componentUnderMouse, x, y);
- Component::componentUnderMouse->internalMouseMove (x, y, time);
- }
- }
-
- void ComponentPeer::handleMouseDown (int x, int y, const int64 time)
- {
- ++juce_MouseClickCounter;
-
- updateCurrentModifiers();
-
- int numMouseButtonsDown = 0;
-
- if (ModifierKeys::getCurrentModifiers().isLeftButtonDown())
- ++numMouseButtonsDown;
-
- if (ModifierKeys::getCurrentModifiers().isRightButtonDown())
- ++numMouseButtonsDown;
-
- if (ModifierKeys::getCurrentModifiers().isMiddleButtonDown())
- ++numMouseButtonsDown;
-
- if (numMouseButtonsDown == 1)
- {
- Component::componentUnderMouse = component->getComponentAt (x, y);
-
- if (Component::componentUnderMouse != 0)
- {
- // can't set these in the mouseDownInt() method, because it's re-entrant, so do it here..
-
- for (int i = numElementsInArray (juce_recentMouseDownTimes); --i > 0;)
- {
- juce_recentMouseDownTimes [i] = juce_recentMouseDownTimes [i - 1];
- juce_recentMouseDownX [i] = juce_recentMouseDownX [i - 1];
- juce_recentMouseDownY [i] = juce_recentMouseDownY [i - 1];
- juce_recentMouseDownComponent [i] = juce_recentMouseDownComponent [i - 1];
- }
-
- juce_recentMouseDownTimes[0] = time;
- juce_recentMouseDownX[0] = x;
- juce_recentMouseDownY[0] = y;
- juce_recentMouseDownComponent[0] = Component::componentUnderMouse;
- relativePositionToGlobal (juce_recentMouseDownX[0], juce_recentMouseDownY[0]);
- juce_MouseHasMovedSignificantlySincePressed = false;
-
- component->relativePositionToOtherComponent (Component::componentUnderMouse, x, y);
- Component::componentUnderMouse->internalMouseDown (x, y);
- }
- }
- }
-
- void ComponentPeer::handleMouseDrag (int x, int y, const int64 time)
- {
- updateCurrentModifiers();
-
- if (Component::componentUnderMouse != 0)
- {
- component->relativePositionToOtherComponent (Component::componentUnderMouse, x, y);
-
- Component::componentUnderMouse->internalMouseDrag (x, y, time);
- }
- }
-
- void ComponentPeer::handleMouseUp (const int oldModifiers, int x, int y, const int64 time)
- {
- updateCurrentModifiers();
-
- int numMouseButtonsDown = 0;
-
- if ((oldModifiers & ModifierKeys::leftButtonModifier) != 0)
- ++numMouseButtonsDown;
-
- if ((oldModifiers & ModifierKeys::rightButtonModifier) != 0)
- ++numMouseButtonsDown;
-
- if ((oldModifiers & ModifierKeys::middleButtonModifier) != 0)
- ++numMouseButtonsDown;
-
- if (numMouseButtonsDown == 1)
- {
- const ComponentDeletionWatcher deletionChecker (component);
- Component* c = component->getComponentAt (x, y);
-
- if (c != Component::componentUnderMouse)
- {
- const int oldX = x;
- const int oldY = y;
-
- if (Component::componentUnderMouse != 0)
- {
- component->relativePositionToOtherComponent (Component::componentUnderMouse, x, y);
- Component::componentUnderMouse->internalMouseUp (oldModifiers, x, y, time);
- x = oldX;
- y = oldY;
-
- if (Component::componentUnderMouse != 0)
- Component::componentUnderMouse->internalMouseExit (x, y, time);
-
- if (deletionChecker.hasBeenDeleted())
- return;
-
- c = component->getComponentAt (oldX, oldY);
- }
-
- Component::componentUnderMouse = c;
-
- if (Component::componentUnderMouse != 0)
- {
- component->relativePositionToOtherComponent (Component::componentUnderMouse, x, y);
- Component::componentUnderMouse->internalMouseEnter (x, y, time);
- }
- }
- else
- {
- if (Component::componentUnderMouse != 0)
- {
- component->relativePositionToOtherComponent (Component::componentUnderMouse, x, y);
- Component::componentUnderMouse->internalMouseUp (oldModifiers, x, y, time);
- }
- }
- }
- }
-
- void ComponentPeer::handleMouseExit (int x, int y, const int64 time)
- {
- jassert (component->isValidComponent());
- updateCurrentModifiers();
-
- if (Component::componentUnderMouse != 0)
- {
- component->relativePositionToOtherComponent (Component::componentUnderMouse, x, y);
-
- Component::componentUnderMouse->internalMouseExit (x, y, time);
- Component::componentUnderMouse = 0;
- }
- }
-
- void ComponentPeer::handleMouseWheel (const int amountX, const int amountY, const int64 time)
- {
- updateCurrentModifiers();
-
- if (Component::componentUnderMouse != 0)
- Component::componentUnderMouse->internalMouseWheel (amountX, amountY, time);
- }
-
- void ComponentPeer::sendFakeMouseMove() throw()
- {
- if ((! fakeMouseMessageSent)
- && component->flags.hasHeavyweightPeerFlag
- && ! ModifierKeys::getCurrentModifiers().isAnyMouseButtonDown())
- {
- if (! isMinimised())
- {
- int realX, realY, realW, realH;
- getBounds (realX, realY, realW, realH);
-
- component->bounds_.setBounds (realX, realY, realW, realH);
- }
-
- int x, y;
- component->getMouseXYRelative (x, y);
-
- if (((unsigned int) x) < (unsigned int) component->getWidth()
- && ((unsigned int) y) < (unsigned int) component->getHeight()
- && contains (x, y, false))
- {
- postMessage (new Message (fakeMouseMoveMessage, x, y, 0));
- }
-
- fakeMouseMessageSent = true;
- }
- }
-
- void ComponentPeer::handleMessage (const Message& message)
- {
- if (message.intParameter1 == fakeMouseMoveMessage)
- {
- handleMouseMove (message.intParameter2,
- message.intParameter3,
- Time::currentTimeMillis());
- }
- }
-
- void ComponentPeer::handlePaint (LowLevelGraphicsContext& contextToPaintTo)
- {
- Graphics g (&contextToPaintTo);
-
- #if JUCE_ENABLE_REPAINT_DEBUGGING
- g.saveState();
- #endif
-
- JUCE_TRY
- {
- component->paintEntireComponent (g);
- }
- JUCE_CATCH_EXCEPTION
-
- #if JUCE_ENABLE_REPAINT_DEBUGGING
- // enabling this code will fill all areas that get repainted with a colour overlay, to show
- // clearly when things are being repainted.
- {
- g.restoreState();
-
- g.fillAll (Colour ((uint8) Random::getSystemRandom().nextInt (255),
- (uint8) Random::getSystemRandom().nextInt (255),
- (uint8) Random::getSystemRandom().nextInt (255),
- (uint8) 0x50));
- }
- #endif
- }
-
- bool ComponentPeer::handleKeyPress (const int keyCode,
- const juce_wchar textCharacter)
- {
- updateCurrentModifiers();
-
- Component* target = Component::currentlyFocusedComponent->isValidComponent()
- ? Component::currentlyFocusedComponent
- : component;
-
- if (target->isCurrentlyBlockedByAnotherModalComponent())
- {
- Component* const currentModalComp = Component::getCurrentlyModalComponent();
-
- if (currentModalComp != 0)
- target = currentModalComp;
- }
-
- const KeyPress keyInfo (keyCode,
- ModifierKeys::getCurrentModifiers().getRawFlags()
- & ModifierKeys::allKeyboardModifiers,
- textCharacter);
-
- bool keyWasUsed = false;
-
- while (target != 0)
- {
- const ComponentDeletionWatcher deletionChecker (target);
-
- if (target->keyListeners_ != 0)
- {
- for (int i = target->keyListeners_->size(); --i >= 0;)
- {
- keyWasUsed = ((KeyListener*) target->keyListeners_->getUnchecked(i))->keyPressed (keyInfo, target);
-
- if (keyWasUsed || deletionChecker.hasBeenDeleted())
- return keyWasUsed;
-
- i = jmin (i, target->keyListeners_->size());
- }
- }
-
- keyWasUsed = target->keyPressed (keyInfo);
-
- if (keyWasUsed || deletionChecker.hasBeenDeleted())
- break;
-
- if (keyInfo.isKeyCode (KeyPress::tabKey) && Component::getCurrentlyFocusedComponent() != 0)
- {
- Component::getCurrentlyFocusedComponent()
- ->moveKeyboardFocusToSibling (! keyInfo.getModifiers().isShiftDown());
-
- keyWasUsed = true;
- break;
- }
-
- target = target->parentComponent_;
- }
-
- return keyWasUsed;
- }
-
- bool ComponentPeer::handleKeyUpOrDown()
- {
- updateCurrentModifiers();
-
- Component* target = Component::currentlyFocusedComponent->isValidComponent()
- ? Component::currentlyFocusedComponent
- : component;
-
- if (target->isCurrentlyBlockedByAnotherModalComponent())
- {
- Component* const currentModalComp = Component::getCurrentlyModalComponent();
-
- if (currentModalComp != 0)
- target = currentModalComp;
- }
-
- bool keyWasUsed = false;
-
- while (target != 0)
- {
- const ComponentDeletionWatcher deletionChecker (target);
-
- keyWasUsed = target->keyStateChanged();
-
- if (keyWasUsed || deletionChecker.hasBeenDeleted())
- break;
-
- if (target->keyListeners_ != 0)
- {
- for (int i = target->keyListeners_->size(); --i >= 0;)
- {
- keyWasUsed = ((KeyListener*) target->keyListeners_->getUnchecked(i))->keyStateChanged (target);
-
- if (keyWasUsed || deletionChecker.hasBeenDeleted())
- return keyWasUsed;
-
- i = jmin (i, target->keyListeners_->size());
- }
- }
-
- target = target->parentComponent_;
- }
-
- return keyWasUsed;
- }
-
- void ComponentPeer::handleModifierKeysChange()
- {
- updateCurrentModifiers();
-
- Component* target = Component::getComponentUnderMouse();
-
- if (target == 0)
- target = Component::getCurrentlyFocusedComponent();
-
- if (target == 0)
- target = component;
-
- if (target->isValidComponent())
- target->internalModifierKeysChanged();
- }
-
- void ComponentPeer::handleBroughtToFront()
- {
- updateCurrentModifiers();
-
- if (component != 0)
- component->internalBroughtToFront();
- }
-
- void ComponentPeer::setConstrainer (ComponentBoundsConstrainer* const newConstrainer) throw()
- {
- constrainer = newConstrainer;
- }
-
- void ComponentPeer::handleMovedOrResized()
- {
- jassert (component->isValidComponent());
- updateCurrentModifiers();
-
- const bool nowMinimised = isMinimised();
-
- if (component->flags.hasHeavyweightPeerFlag && ! nowMinimised)
- {
- const ComponentDeletionWatcher deletionChecker (component);
-
- int realX, realY, realW, realH;
- getBounds (realX, realY, realW, realH);
-
- const bool wasMoved = (component->getX() != realX || component->getY() != realY);
- const bool wasResized = (component->getWidth() != realW || component->getHeight() != realH);
-
- if (wasMoved || wasResized)
- {
- component->bounds_.setBounds (realX, realY, realW, realH);
-
- if (wasResized)
- component->repaint();
-
- component->sendMovedResizedMessages (wasMoved, wasResized);
-
- if (deletionChecker.hasBeenDeleted())
- return;
- }
- }
-
- if (isWindowMinimised != nowMinimised)
- {
- isWindowMinimised = nowMinimised;
- component->minimisationStateChanged (nowMinimised);
- component->sendVisibilityChangeMessage();
- }
-
- if (! isFullScreen())
- lastNonFullscreenBounds = component->getBounds();
- }
-
- void ComponentPeer::handleFocusGain()
- {
- updateCurrentModifiers();
-
- if (component->isParentOf (lastFocusedComponent))
- {
- Component::currentlyFocusedComponent = lastFocusedComponent;
- Desktop::getInstance().triggerFocusCallback();
- lastFocusedComponent->internalFocusGain (Component::focusChangedDirectly);
- }
- else
- {
- if (! component->isCurrentlyBlockedByAnotherModalComponent())
- {
- component->grabKeyboardFocus();
- }
- else
- {
- Component* const currentModalComp = Component::getCurrentlyModalComponent();
-
- if (currentModalComp != 0)
- currentModalComp->toFront (! currentModalComp->hasKeyboardFocus (true));
- }
- }
- }
-
- void ComponentPeer::handleFocusLoss()
- {
- updateCurrentModifiers();
-
- if (component->hasKeyboardFocus (true))
- {
- lastFocusedComponent = Component::currentlyFocusedComponent;
-
- if (lastFocusedComponent != 0)
- {
- Component::currentlyFocusedComponent = 0;
- Desktop::getInstance().triggerFocusCallback();
- lastFocusedComponent->internalFocusLoss (Component::focusChangedByMouseClick);
- }
- }
- }
-
- Component* ComponentPeer::getLastFocusedSubcomponent() const throw()
- {
- return (component->isParentOf (lastFocusedComponent) && lastFocusedComponent->isShowing())
- ? lastFocusedComponent
- : component;
- }
-
- void ComponentPeer::handleScreenSizeChange()
- {
- updateCurrentModifiers();
-
- component->parentSizeChanged();
- handleMovedOrResized();
- }
-
- void ComponentPeer::setNonFullScreenBounds (const Rectangle& newBounds) throw()
- {
- lastNonFullscreenBounds = newBounds;
- }
-
- const Rectangle& ComponentPeer::getNonFullScreenBounds() const throw()
- {
- return lastNonFullscreenBounds;
- }
-
- static FileDragAndDropTarget* findDragAndDropTarget (Component* c,
- const StringArray& files,
- FileDragAndDropTarget* const lastOne)
- {
- while (c != 0)
- {
- FileDragAndDropTarget* const t = dynamic_cast <FileDragAndDropTarget*> (c);
-
- if (t != 0 && (t == lastOne || t->isInterestedInFileDrag (files)))
- return t;
-
- c = c->getParentComponent();
- }
-
- return 0;
- }
-
- void ComponentPeer::handleFileDragMove (const StringArray& files, int x, int y)
- {
- updateCurrentModifiers();
-
- FileDragAndDropTarget* lastTarget = 0;
-
- if (dragAndDropTargetComponent != 0 && ! dragAndDropTargetComponent->hasBeenDeleted())
- lastTarget = const_cast <FileDragAndDropTarget*> (dynamic_cast <const FileDragAndDropTarget*> (dragAndDropTargetComponent->getComponent()));
-
- FileDragAndDropTarget* newTarget = 0;
-
- Component* const compUnderMouse = component->getComponentAt (x, y);
-
- if (compUnderMouse != lastDragAndDropCompUnderMouse)
- {
- lastDragAndDropCompUnderMouse = compUnderMouse;
- newTarget = findDragAndDropTarget (compUnderMouse, files, lastTarget);
-
- if (newTarget != lastTarget)
- {
- if (lastTarget != 0)
- lastTarget->fileDragExit (files);
-
- deleteAndZero (dragAndDropTargetComponent);
-
- if (newTarget != 0)
- {
- Component* const targetComp = dynamic_cast <Component*> (newTarget);
- int mx = x, my = y;
- component->relativePositionToOtherComponent (targetComp, mx, my);
-
- dragAndDropTargetComponent = new ComponentDeletionWatcher (dynamic_cast <Component*> (newTarget));
- newTarget->fileDragEnter (files, mx, my);
- }
- }
- }
- else
- {
- newTarget = lastTarget;
- }
-
- if (newTarget != 0)
- {
- Component* const targetComp = dynamic_cast <Component*> (newTarget);
- component->relativePositionToOtherComponent (targetComp, x, y);
-
- newTarget->fileDragMove (files, x, y);
- }
- }
-
- void ComponentPeer::handleFileDragExit (const StringArray& files)
- {
- handleFileDragMove (files, -1, -1);
-
- jassert (dragAndDropTargetComponent == 0);
- lastDragAndDropCompUnderMouse = 0;
- }
-
- void ComponentPeer::handleFileDragDrop (const StringArray& files, int x, int y)
- {
- handleFileDragMove (files, x, y);
-
- if (dragAndDropTargetComponent != 0 && ! dragAndDropTargetComponent->hasBeenDeleted())
- {
- FileDragAndDropTarget* const target = const_cast <FileDragAndDropTarget*> (dynamic_cast <const FileDragAndDropTarget*> (dragAndDropTargetComponent->getComponent()));
-
- deleteAndZero (dragAndDropTargetComponent);
- lastDragAndDropCompUnderMouse = 0;
-
- if (target != 0)
- {
- Component* const targetComp = dynamic_cast <Component*> (target);
-
- if (targetComp->isCurrentlyBlockedByAnotherModalComponent())
- {
- targetComp->internalModalInputAttempt();
-
- if (targetComp->isCurrentlyBlockedByAnotherModalComponent())
- return;
- }
-
- component->relativePositionToOtherComponent (targetComp, x, y);
- target->filesDropped (files, x, y);
- }
- }
- }
-
- void ComponentPeer::handleUserClosingWindow()
- {
- updateCurrentModifiers();
-
- component->userTriedToCloseWindow();
- }
-
- void ComponentPeer::clearMaskedRegion() throw()
- {
- maskedRegion.clear();
- }
-
- void ComponentPeer::addMaskedRegion (int x, int y, int w, int h) throw()
- {
- maskedRegion.add (x, y, w, h);
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_ComponentPeer.cpp *********/
-
- /********* Start of inlined file: juce_DialogWindow.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- DialogWindow::DialogWindow (const String& name,
- const Colour& backgroundColour_,
- const bool escapeKeyTriggersCloseButton_,
- const bool addToDesktop_)
- : DocumentWindow (name, backgroundColour_, DocumentWindow::closeButton, addToDesktop_),
- escapeKeyTriggersCloseButton (escapeKeyTriggersCloseButton_)
- {
- }
-
- DialogWindow::~DialogWindow()
- {
- }
-
- void DialogWindow::resized()
- {
- DocumentWindow::resized();
-
- const KeyPress esc (KeyPress::escapeKey, 0, 0);
-
- if (escapeKeyTriggersCloseButton
- && getCloseButton() != 0
- && ! getCloseButton()->isRegisteredForShortcut (esc))
- {
- getCloseButton()->addShortcut (esc);
- }
- }
-
- class TempDialogWindow : public DialogWindow
- {
- public:
- TempDialogWindow (const String& title, const Colour& colour, const bool escapeCloses)
- : DialogWindow (title, colour, escapeCloses, true)
- {
- }
-
- ~TempDialogWindow()
- {
- }
-
- void closeButtonPressed()
- {
- setVisible (false);
- }
-
- private:
- TempDialogWindow (const TempDialogWindow&);
- const TempDialogWindow& operator= (const TempDialogWindow&);
-
- };
-
- int DialogWindow::showModalDialog (const String& dialogTitle,
- Component* contentComponent,
- Component* componentToCentreAround,
- const Colour& colour,
- const bool escapeKeyTriggersCloseButton,
- const bool shouldBeResizable,
- const bool useBottomRightCornerResizer)
- {
- TempDialogWindow dw (dialogTitle, colour, escapeKeyTriggersCloseButton);
-
- dw.setContentComponent (contentComponent, true, true);
- dw.centreAroundComponent (componentToCentreAround, dw.getWidth(), dw.getHeight());
- dw.setResizable (shouldBeResizable, useBottomRightCornerResizer);
- const int result = dw.runModalLoop();
- dw.setContentComponent (0, false);
- return result;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_DialogWindow.cpp *********/
-
- /********* Start of inlined file: juce_DocumentWindow.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- DocumentWindow::DocumentWindow (const String& title,
- const Colour& backgroundColour,
- const int requiredButtons_,
- const bool addToDesktop_)
- : ResizableWindow (title, backgroundColour, addToDesktop_),
- titleBarHeight (26),
- menuBarHeight (24),
- requiredButtons (requiredButtons_),
- #if JUCE_MAC
- positionTitleBarButtonsOnLeft (true),
- #else
- positionTitleBarButtonsOnLeft (false),
- #endif
- drawTitleTextCentred (true),
- titleBarIcon (0),
- menuBar (0),
- menuBarModel (0)
- {
- zeromem (titleBarButtons, sizeof (titleBarButtons));
-
- setResizeLimits (128, 128, 32768, 32768);
-
- lookAndFeelChanged();
- }
-
- DocumentWindow::~DocumentWindow()
- {
- for (int i = 0; i < 3; ++i)
- delete titleBarButtons[i];
-
- delete titleBarIcon;
- delete menuBar;
- }
-
- void DocumentWindow::repaintTitleBar()
- {
- const int border = getBorderSize();
- repaint (border, border, getWidth() - border * 2, getTitleBarHeight());
- }
-
- void DocumentWindow::setName (const String& newName)
- {
- if (newName != getName())
- {
- Component::setName (newName);
- repaintTitleBar();
- }
- }
-
- void DocumentWindow::setIcon (const Image* imageToUse)
- {
- deleteAndZero (titleBarIcon);
-
- if (imageToUse != 0)
- titleBarIcon = imageToUse->createCopy();
-
- repaintTitleBar();
- }
-
- void DocumentWindow::setTitleBarHeight (const int newHeight)
- {
- titleBarHeight = newHeight;
- resized();
- repaintTitleBar();
- }
-
- void DocumentWindow::setTitleBarButtonsRequired (const int requiredButtons_,
- const bool positionTitleBarButtonsOnLeft_)
- {
- requiredButtons = requiredButtons_;
- positionTitleBarButtonsOnLeft = positionTitleBarButtonsOnLeft_;
- lookAndFeelChanged();
- }
-
- void DocumentWindow::setTitleBarTextCentred (const bool textShouldBeCentred)
- {
- drawTitleTextCentred = textShouldBeCentred;
- repaintTitleBar();
- }
-
- void DocumentWindow::setMenuBar (MenuBarModel* menuBarModel_,
- const int menuBarHeight_)
- {
- if (menuBarModel != menuBarModel_)
- {
- delete menuBar;
- menuBar = 0;
-
- menuBarModel = menuBarModel_;
- menuBarHeight = (menuBarHeight_ > 0) ? menuBarHeight_
- : getLookAndFeel().getDefaultMenuBarHeight();
-
- if (menuBarModel != 0)
- {
- // (call the Component method directly to avoid the assertion in ResizableWindow)
- Component::addAndMakeVisible (menuBar = new MenuBarComponent (menuBarModel));
- menuBar->setEnabled (isActiveWindow());
- }
-
- resized();
- }
- }
-
- void DocumentWindow::closeButtonPressed()
- {
- /* If you've got a close button, you have to override this method to get
- rid of your window!
-
- If the window is just a pop-up, you should override this method and make
- it delete the window in whatever way is appropriate for your app. E.g. you
- might just want to call "delete this".
-
- If your app is centred around this window such that the whole app should quit when
- the window is closed, then you will probably want to use this method as an opportunity
- to call JUCEApplication::quit(), and leave the window to be deleted later by your
- JUCEApplication::shutdown() method. (Doing it this way means that your window will
- still get cleaned-up if the app is quit by some other means (e.g. a cmd-Q on the mac
- or closing it via the taskbar icon on Windows).
- */
- jassertfalse
- }
-
- void DocumentWindow::minimiseButtonPressed()
- {
- setMinimised (true);
- }
-
- void DocumentWindow::maximiseButtonPressed()
- {
- setFullScreen (! isFullScreen());
- }
-
- void DocumentWindow::paint (Graphics& g)
- {
- ResizableWindow::paint (g);
-
- if (resizableBorder == 0 && getBorderSize() == 1)
- {
- g.setColour (getBackgroundColour().overlaidWith (Colour (0x80000000)));
- g.drawRect (0, 0, getWidth(), getHeight());
- }
-
- const int border = getBorderSize();
-
- g.setOrigin (border, border);
- g.reduceClipRegion (0, 0, getWidth() - border * 2, getTitleBarHeight());
-
- int titleSpaceX1 = 6;
- int titleSpaceX2 = getWidth() - 6;
-
- for (int i = 0; i < 3; ++i)
- {
- if (titleBarButtons[i] != 0)
- {
- if (positionTitleBarButtonsOnLeft)
- titleSpaceX1 = jmax (titleSpaceX1, titleBarButtons[i]->getRight() + (getWidth() - titleBarButtons[i]->getRight()) / 8);
- else
- titleSpaceX2 = jmin (titleSpaceX2, titleBarButtons[i]->getX() - (titleBarButtons[i]->getX() / 8));
- }
- }
-
- getLookAndFeel()
- .drawDocumentWindowTitleBar (*this, g,
- getWidth() - border * 2,
- getTitleBarHeight(),
- titleSpaceX1, jmax (1, titleSpaceX2 - titleSpaceX1),
- titleBarIcon, ! drawTitleTextCentred);
- }
-
- void DocumentWindow::resized()
- {
- ResizableWindow::resized();
-
- if (titleBarButtons[1] != 0)
- titleBarButtons[1]->setToggleState (isFullScreen(), false);
-
- const int border = getBorderSize();
- getLookAndFeel()
- .positionDocumentWindowButtons (*this,
- border, border,
- getWidth() - border * 2, getTitleBarHeight(),
- titleBarButtons[0],
- titleBarButtons[1],
- titleBarButtons[2],
- positionTitleBarButtonsOnLeft);
-
- if (menuBar != 0)
- menuBar->setBounds (border, border + getTitleBarHeight(),
- getWidth() - border * 2, menuBarHeight);
- }
-
- Button* DocumentWindow::getCloseButton() const throw()
- {
- return titleBarButtons[2];
- }
-
- Button* DocumentWindow::getMinimiseButton() const throw()
- {
- return titleBarButtons[0];
- }
-
- Button* DocumentWindow::getMaximiseButton() const throw()
- {
- return titleBarButtons[1];
- }
-
- int DocumentWindow::getDesktopWindowStyleFlags() const
- {
- int flags = ResizableWindow::getDesktopWindowStyleFlags();
-
- if ((requiredButtons & minimiseButton) != 0)
- flags |= ComponentPeer::windowHasMinimiseButton;
-
- if ((requiredButtons & maximiseButton) != 0)
- flags |= ComponentPeer::windowHasMaximiseButton;
-
- if ((requiredButtons & closeButton) != 0)
- flags |= ComponentPeer::windowHasCloseButton;
-
- return flags;
- }
-
- void DocumentWindow::lookAndFeelChanged()
- {
- int i;
- for (i = 0; i < 3; ++i)
- deleteAndZero (titleBarButtons[i]);
-
- if (! isUsingNativeTitleBar())
- {
- titleBarButtons[0] = ((requiredButtons & minimiseButton) != 0)
- ? getLookAndFeel().createDocumentWindowButton (minimiseButton) : 0;
-
- titleBarButtons[1] = ((requiredButtons & maximiseButton) != 0)
- ? getLookAndFeel().createDocumentWindowButton (maximiseButton) : 0;
-
- titleBarButtons[2] = ((requiredButtons & closeButton) != 0)
- ? getLookAndFeel().createDocumentWindowButton (closeButton) : 0;
-
- for (i = 0; i < 3; ++i)
- {
- if (titleBarButtons[i] != 0)
- {
- buttonListener.owner = this;
- titleBarButtons[i]->addButtonListener (&buttonListener);
- titleBarButtons[i]->setWantsKeyboardFocus (false);
-
- // (call the Component method directly to avoid the assertion in ResizableWindow)
- Component::addAndMakeVisible (titleBarButtons[i]);
- }
- }
-
- if (getCloseButton() != 0)
- {
- #if JUCE_MAC
- getCloseButton()->addShortcut (KeyPress (T('w'), ModifierKeys::commandModifier, 0));
- #else
- getCloseButton()->addShortcut (KeyPress (KeyPress::F4Key, ModifierKeys::altModifier, 0));
- #endif
- }
- }
-
- activeWindowStatusChanged();
-
- ResizableWindow::lookAndFeelChanged();
- }
-
- void DocumentWindow::parentHierarchyChanged()
- {
- lookAndFeelChanged();
- }
-
- void DocumentWindow::activeWindowStatusChanged()
- {
- ResizableWindow::activeWindowStatusChanged();
-
- for (int i = 0; i < 3; ++i)
- if (titleBarButtons[i] != 0)
- titleBarButtons[i]->setEnabled (isActiveWindow());
-
- if (menuBar != 0)
- menuBar->setEnabled (isActiveWindow());
- }
-
- const BorderSize DocumentWindow::getBorderThickness()
- {
- return BorderSize (getBorderSize());
- }
-
- const BorderSize DocumentWindow::getContentComponentBorder()
- {
- const int size = getBorderSize();
-
- return BorderSize (size
- + (isUsingNativeTitleBar() ? 0 : titleBarHeight)
- + (menuBar != 0 ? menuBarHeight : 0),
- size, size, size);
- }
-
- void DocumentWindow::mouseDoubleClick (const MouseEvent& e)
- {
- const int border = getBorderSize();
-
- if (e.x >= border
- && e.y >= border
- && e.x < getWidth() - border
- && e.y < border + getTitleBarHeight()
- && getMaximiseButton() != 0)
- {
- getMaximiseButton()->triggerClick();
- }
- }
-
- void DocumentWindow::userTriedToCloseWindow()
- {
- closeButtonPressed();
- }
-
- int DocumentWindow::getTitleBarHeight() const
- {
- return isUsingNativeTitleBar() ? 0 : jmin (titleBarHeight, getHeight() - 4);
- }
-
- int DocumentWindow::getBorderSize() const
- {
- return (isFullScreen() || isUsingNativeTitleBar()) ? 0 : (resizableBorder != 0 ? 4 : 1);
- }
-
- DocumentWindow::ButtonListenerProxy::ButtonListenerProxy()
- {
- }
-
- void DocumentWindow::ButtonListenerProxy::buttonClicked (Button* button)
- {
- if (button == owner->getMinimiseButton())
- {
- owner->minimiseButtonPressed();
- }
- else if (button == owner->getMaximiseButton())
- {
- owner->maximiseButtonPressed();
- }
- else if (button == owner->getCloseButton())
- {
- owner->closeButtonPressed();
- }
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_DocumentWindow.cpp *********/
-
- /********* Start of inlined file: juce_ResizableWindow.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- ResizableWindow::ResizableWindow (const String& name,
- const Colour& backgroundColour_,
- const bool addToDesktop_)
- : TopLevelWindow (name, addToDesktop_),
- resizableCorner (0),
- resizableBorder (0),
- contentComponent (0),
- resizeToFitContent (false),
- fullscreen (false),
- constrainer (0)
- #ifdef JUCE_DEBUG
- , hasBeenResized (false)
- #endif
- {
- setBackgroundColour (backgroundColour_);
-
- defaultConstrainer.setMinimumOnscreenAmounts (0x10000, 16, 24, 16);
-
- lastNonFullScreenPos.setBounds (50, 50, 256, 256);
-
- if (addToDesktop_)
- Component::addToDesktop (getDesktopWindowStyleFlags());
- }
-
- ResizableWindow::~ResizableWindow()
- {
- deleteAndZero (resizableCorner);
- deleteAndZero (resizableBorder);
- deleteAndZero (contentComponent);
-
- // have you been adding your own components directly to this window..? tut tut tut.
- // Read the instructions for using a ResizableWindow!
- jassert (getNumChildComponents() == 0);
- }
-
- int ResizableWindow::getDesktopWindowStyleFlags() const
- {
- int flags = TopLevelWindow::getDesktopWindowStyleFlags();
-
- if (isResizable() && (flags & ComponentPeer::windowHasTitleBar) != 0)
- flags |= ComponentPeer::windowIsResizable;
-
- return flags;
- }
-
- void ResizableWindow::setContentComponent (Component* const newContentComponent,
- const bool deleteOldOne,
- const bool resizeToFit)
- {
- resizeToFitContent = resizeToFit;
-
- if (contentComponent != newContentComponent)
- {
- if (deleteOldOne)
- delete contentComponent;
- else
- removeChildComponent (contentComponent);
-
- contentComponent = newContentComponent;
-
- Component::addAndMakeVisible (contentComponent);
- }
-
- if (resizeToFit)
- childBoundsChanged (contentComponent);
-
- resized(); // must always be called to position the new content comp
- }
-
- void ResizableWindow::setContentComponentSize (int width, int height)
- {
- jassert (width > 0 && height > 0); // not a great idea to give it a zero size..
-
- const BorderSize border (getContentComponentBorder());
-
- setSize (width + border.getLeftAndRight(),
- height + border.getTopAndBottom());
- }
-
- const BorderSize ResizableWindow::getBorderThickness()
- {
- return BorderSize (isUsingNativeTitleBar() ? 0 : ((resizableBorder != 0 && ! isFullScreen()) ? 5 : 3));
- }
-
- const BorderSize ResizableWindow::getContentComponentBorder()
- {
- return getBorderThickness();
- }
-
- void ResizableWindow::moved()
- {
- updateLastPos();
- }
-
- void ResizableWindow::visibilityChanged()
- {
- TopLevelWindow::visibilityChanged();
-
- updateLastPos();
- }
-
- void ResizableWindow::resized()
- {
- if (resizableBorder != 0)
- {
- resizableBorder->setVisible (! isFullScreen());
- resizableBorder->setBorderThickness (getBorderThickness());
-
- resizableBorder->setSize (getWidth(), getHeight());
- resizableBorder->toBack();
- }
-
- if (resizableCorner != 0)
- {
- resizableCorner->setVisible (! isFullScreen());
-
- const int resizerSize = 18;
- resizableCorner->setBounds (getWidth() - resizerSize,
- getHeight() - resizerSize,
- resizerSize, resizerSize);
- }
-
- if (contentComponent != 0)
- contentComponent->setBoundsInset (getContentComponentBorder());
-
- updateLastPos();
-
- #ifdef JUCE_DEBUG
- hasBeenResized = true;
- #endif
- }
-
- void ResizableWindow::childBoundsChanged (Component* child)
- {
- if ((child == contentComponent) && (child != 0) && resizeToFitContent)
- {
- // not going to look very good if this component has a zero size..
- jassert (child->getWidth() > 0);
- jassert (child->getHeight() > 0);
-
- const BorderSize borders (getContentComponentBorder());
-
- setSize (child->getWidth() + borders.getLeftAndRight(),
- child->getHeight() + borders.getTopAndBottom());
- }
- }
-
- void ResizableWindow::activeWindowStatusChanged()
- {
- const BorderSize borders (getContentComponentBorder());
-
- repaint (0, 0, getWidth(), borders.getTop());
- repaint (0, borders.getTop(), borders.getLeft(), getHeight() - borders.getBottom() - borders.getTop());
- repaint (0, getHeight() - borders.getBottom(), getWidth(), borders.getBottom());
- repaint (getWidth() - borders.getRight(), borders.getTop(), borders.getRight(), getHeight() - borders.getBottom() - borders.getTop());
- }
-
- void ResizableWindow::setResizable (const bool shouldBeResizable,
- const bool useBottomRightCornerResizer)
- {
- if (shouldBeResizable)
- {
- if (useBottomRightCornerResizer)
- {
- deleteAndZero (resizableBorder);
-
- if (resizableCorner == 0)
- {
- Component::addChildComponent (resizableCorner = new ResizableCornerComponent (this, constrainer));
- resizableCorner->setAlwaysOnTop (true);
- }
- }
- else
- {
- deleteAndZero (resizableCorner);
-
- if (resizableBorder == 0)
- Component::addChildComponent (resizableBorder = new ResizableBorderComponent (this, constrainer));
- }
- }
- else
- {
- deleteAndZero (resizableCorner);
- deleteAndZero (resizableBorder);
- }
-
- if (isUsingNativeTitleBar())
- recreateDesktopWindow();
-
- childBoundsChanged (contentComponent);
- resized();
- }
-
- bool ResizableWindow::isResizable() const throw()
- {
- return resizableCorner != 0
- || resizableBorder != 0;
- }
-
- void ResizableWindow::setResizeLimits (const int newMinimumWidth,
- const int newMinimumHeight,
- const int newMaximumWidth,
- const int newMaximumHeight) throw()
- {
- // if you've set up a custom constrainer then these settings won't have any effect..
- jassert (constrainer == &defaultConstrainer || constrainer == 0);
-
- if (constrainer == 0)
- setConstrainer (&defaultConstrainer);
-
- defaultConstrainer.setSizeLimits (newMinimumWidth, newMinimumHeight,
- newMaximumWidth, newMaximumHeight);
-
- setBoundsConstrained (getX(), getY(), getWidth(), getHeight());
- }
-
- void ResizableWindow::setConstrainer (ComponentBoundsConstrainer* newConstrainer)
- {
- if (constrainer != newConstrainer)
- {
- constrainer = newConstrainer;
-
- const bool useBottomRightCornerResizer = resizableCorner != 0;
- const bool shouldBeResizable = useBottomRightCornerResizer || resizableBorder != 0;
-
- deleteAndZero (resizableCorner);
- deleteAndZero (resizableBorder);
-
- setResizable (shouldBeResizable, useBottomRightCornerResizer);
-
- ComponentPeer* const peer = getPeer();
- if (peer != 0)
- peer->setConstrainer (newConstrainer);
- }
- }
-
- void ResizableWindow::setBoundsConstrained (int x, int y, int w, int h)
- {
- if (constrainer != 0)
- constrainer->setBoundsForComponent (this, x, y, w, h, false, false, false, false);
- else
- setBounds (x, y, w, h);
- }
-
- void ResizableWindow::paint (Graphics& g)
- {
- g.fillAll (backgroundColour);
-
- if (! isFullScreen())
- {
- getLookAndFeel().drawResizableWindowBorder (g, getWidth(), getHeight(),
- getBorderThickness(), *this);
- }
-
- #ifdef JUCE_DEBUG
- /* If this fails, then you've probably written a subclass with a resized()
- callback but forgotten to make it call its parent class's resized() method.
-
- It's important when you override methods like resized(), moved(),
- etc., that you make sure the base class methods also get called.
-
- Of course you shouldn't really be overriding ResizableWindow::resized() anyway,
- because your content should all be inside the content component - and it's the
- content component's resized() method that you should be using to do your
- layout.
- */
- jassert (hasBeenResized || (getWidth() == 0 && getHeight() == 0));
- #endif
- }
-
- void ResizableWindow::lookAndFeelChanged()
- {
- resized();
-
- if (isOnDesktop())
- {
- Component::addToDesktop (getDesktopWindowStyleFlags());
-
- ComponentPeer* const peer = getPeer();
- if (peer != 0)
- peer->setConstrainer (constrainer);
- }
- }
-
- void ResizableWindow::setBackgroundColour (const Colour& newColour)
- {
- if (Desktop::canUseSemiTransparentWindows())
- backgroundColour = newColour;
- else
- backgroundColour = newColour.withAlpha (1.0f);
-
- setOpaque (backgroundColour.isOpaque());
- repaint();
- }
-
- bool ResizableWindow::isFullScreen() const
- {
- if (isOnDesktop())
- {
- ComponentPeer* const peer = getPeer();
- return peer != 0 && peer->isFullScreen();
- }
-
- return fullscreen;
- }
-
- void ResizableWindow::setFullScreen (const bool shouldBeFullScreen)
- {
- if (shouldBeFullScreen != isFullScreen())
- {
- updateLastPos();
- fullscreen = shouldBeFullScreen;
-
- if (isOnDesktop())
- {
- ComponentPeer* const peer = getPeer();
-
- if (peer != 0)
- {
- // keep a copy of this intact in case the real one gets messed-up while we're un-maximising
- const Rectangle lastPos (lastNonFullScreenPos);
-
- peer->setFullScreen (shouldBeFullScreen);
-
- if (! shouldBeFullScreen)
- setBounds (lastPos);
- }
- else
- {
- jassertfalse
- }
- }
- else
- {
- if (shouldBeFullScreen)
- setBounds (0, 0, getParentWidth(), getParentHeight());
- else
- setBounds (lastNonFullScreenPos);
- }
-
- resized();
- }
- }
-
- bool ResizableWindow::isMinimised() const
- {
- ComponentPeer* const peer = getPeer();
-
- return (peer != 0) && peer->isMinimised();
- }
-
- void ResizableWindow::setMinimised (const bool shouldMinimise)
- {
- if (shouldMinimise != isMinimised())
- {
- ComponentPeer* const peer = getPeer();
-
- if (peer != 0)
- {
- updateLastPos();
- peer->setMinimised (shouldMinimise);
- }
- else
- {
- jassertfalse
- }
- }
- }
-
- void ResizableWindow::updateLastPos()
- {
- if (isShowing() && ! (isFullScreen() || isMinimised()))
- {
- lastNonFullScreenPos = getBounds();
- }
- }
-
- void ResizableWindow::parentSizeChanged()
- {
- if (isFullScreen() && getParentComponent() != 0)
- {
- setBounds (0, 0, getParentWidth(), getParentHeight());
- }
- }
-
- const String ResizableWindow::getWindowStateAsString()
- {
- updateLastPos();
-
- String s;
-
- if (isFullScreen())
- s << "fs ";
-
- s << lastNonFullScreenPos.getX() << T(' ')
- << lastNonFullScreenPos.getY() << T(' ')
- << lastNonFullScreenPos.getWidth() << T(' ')
- << lastNonFullScreenPos.getHeight();
-
- return s;
- }
-
- bool ResizableWindow::restoreWindowStateFromString (const String& s)
- {
- StringArray tokens;
- tokens.addTokens (s, false);
- tokens.removeEmptyStrings();
- tokens.trim();
-
- const bool fs = tokens[0].startsWithIgnoreCase (T("fs"));
- const int n = fs ? 1 : 0;
-
- if (tokens.size() != 4 + n)
- return false;
-
- Rectangle r (tokens[n].getIntValue(),
- tokens[n + 1].getIntValue(),
- tokens[n + 2].getIntValue(),
- tokens[n + 3].getIntValue());
-
- if (r.isEmpty())
- return false;
-
- const Rectangle screen (Desktop::getInstance().getMonitorAreaContaining (r.getX(), r.getY()));
-
- r = r.getIntersection (screen);
-
- lastNonFullScreenPos = r;
-
- if (isOnDesktop())
- {
- ComponentPeer* const peer = getPeer();
-
- if (peer != 0)
- peer->setNonFullScreenBounds (r);
- }
-
- setFullScreen (fs);
-
- if (! fs)
- setBoundsConstrained (r.getX(),
- r.getY(),
- r.getWidth(),
- r.getHeight());
-
- return true;
- }
-
- void ResizableWindow::mouseDown (const MouseEvent&)
- {
- if (! isFullScreen())
- dragger.startDraggingComponent (this, constrainer);
- }
-
- void ResizableWindow::mouseDrag (const MouseEvent& e)
- {
- if (! isFullScreen())
- dragger.dragComponent (this, e);
- }
-
- #ifdef JUCE_DEBUG
- void ResizableWindow::addChildComponent (Component* const child, int zOrder)
- {
- /* Agh! You shouldn't add components directly to a ResizableWindow - this class
- manages its child components automatically, and if you add your own it'll cause
- trouble. Instead, use setContentComponent() to give it a component which
- will be automatically resized and kept in the right place - then you can add
- subcomponents to the content comp. See the notes for the ResizableWindow class
- for more info.
-
- If you really know what you're doing and want to avoid this assertion, just call
- Component::addChildComponent directly.
- */
- jassertfalse
-
- Component::addChildComponent (child, zOrder);
- }
-
- void ResizableWindow::addAndMakeVisible (Component* const child, int zOrder)
- {
- /* Agh! You shouldn't add components directly to a ResizableWindow - this class
- manages its child components automatically, and if you add your own it'll cause
- trouble. Instead, use setContentComponent() to give it a component which
- will be automatically resized and kept in the right place - then you can add
- subcomponents to the content comp. See the notes for the ResizableWindow class
- for more info.
-
- If you really know what you're doing and want to avoid this assertion, just call
- Component::addAndMakeVisible directly.
- */
- jassertfalse
-
- Component::addAndMakeVisible (child, zOrder);
- }
- #endif
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_ResizableWindow.cpp *********/
-
- /********* Start of inlined file: juce_SplashScreen.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- SplashScreen::SplashScreen()
- : backgroundImage (0),
- isImageInCache (false)
- {
- setOpaque (true);
- }
-
- SplashScreen::~SplashScreen()
- {
- if (isImageInCache)
- ImageCache::release (backgroundImage);
- else
- delete backgroundImage;
- }
-
- void SplashScreen::show (const String& title,
- Image* const backgroundImage_,
- const int minimumTimeToDisplayFor,
- const bool useDropShadow,
- const bool removeOnMouseClick)
- {
- backgroundImage = backgroundImage_;
-
- jassert (backgroundImage_ != 0);
-
- if (backgroundImage_ != 0)
- {
- isImageInCache = ImageCache::isImageInCache (backgroundImage_);
-
- setOpaque (! backgroundImage_->hasAlphaChannel());
-
- show (title,
- backgroundImage_->getWidth(),
- backgroundImage_->getHeight(),
- minimumTimeToDisplayFor,
- useDropShadow,
- removeOnMouseClick);
- }
- }
-
- void SplashScreen::show (const String& title,
- const int width,
- const int height,
- const int minimumTimeToDisplayFor,
- const bool useDropShadow,
- const bool removeOnMouseClick)
- {
- setName (title);
- setAlwaysOnTop (true);
- setVisible (true);
- centreWithSize (width, height);
-
- addToDesktop (useDropShadow ? ComponentPeer::windowHasDropShadow : 0);
- toFront (false);
-
- MessageManager::getInstance()->dispatchPendingMessages();
-
- repaint();
-
- originalClickCounter = removeOnMouseClick
- ? Desktop::getMouseButtonClickCounter()
- : INT_MAX;
-
- earliestTimeToDelete = Time::getCurrentTime() + RelativeTime::milliseconds (minimumTimeToDisplayFor);
-
- startTimer (50);
- }
-
- void SplashScreen::paint (Graphics& g)
- {
- if (backgroundImage != 0)
- {
- g.setOpacity (1.0f);
-
- g.drawImage (backgroundImage,
- 0, 0, getWidth(), getHeight(),
- 0, 0, backgroundImage->getWidth(), backgroundImage->getHeight());
- }
- }
-
- void SplashScreen::timerCallback()
- {
- if (Time::getCurrentTime() > earliestTimeToDelete
- || Desktop::getMouseButtonClickCounter() > originalClickCounter)
- {
- delete this;
- }
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_SplashScreen.cpp *********/
-
- /********* Start of inlined file: juce_ThreadWithProgressWindow.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- ThreadWithProgressWindow::ThreadWithProgressWindow (const String& title,
- const bool hasProgressBar,
- const bool hasCancelButton,
- const int timeOutMsWhenCancelling_,
- const String& cancelButtonText)
- : Thread ("Juce Progress Window"),
- progress (0.0),
- alertWindow (title, String::empty, AlertWindow::NoIcon),
- timeOutMsWhenCancelling (timeOutMsWhenCancelling_)
- {
- if (hasProgressBar)
- alertWindow.addProgressBarComponent (progress);
-
- if (hasCancelButton)
- alertWindow.addButton (cancelButtonText, 1);
- }
-
- ThreadWithProgressWindow::~ThreadWithProgressWindow()
- {
- stopThread (timeOutMsWhenCancelling);
- }
-
- bool ThreadWithProgressWindow::runThread (const int priority)
- {
- startThread (priority);
- startTimer (100);
-
- {
- const ScopedLock sl (messageLock);
- alertWindow.setMessage (message);
- }
-
- const bool wasCancelled = alertWindow.runModalLoop() != 0;
-
- stopThread (timeOutMsWhenCancelling);
-
- alertWindow.setVisible (false);
-
- return ! wasCancelled;
- }
-
- void ThreadWithProgressWindow::setProgress (const double newProgress)
- {
- progress = newProgress;
- }
-
- void ThreadWithProgressWindow::setStatusMessage (const String& newStatusMessage)
- {
- const ScopedLock sl (messageLock);
- message = newStatusMessage;
- }
-
- void ThreadWithProgressWindow::timerCallback()
- {
- if (! isThreadRunning())
- {
- // thread has finished normally..
- alertWindow.exitModalState (0);
- alertWindow.setVisible (false);
- }
- else
- {
- const ScopedLock sl (messageLock);
- alertWindow.setMessage (message);
- }
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_ThreadWithProgressWindow.cpp *********/
-
- /********* Start of inlined file: juce_TooltipWindow.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- TooltipWindow::TooltipWindow (Component* const parentComponent,
- const int millisecondsBeforeTipAppears_)
- : Component ("tooltip"),
- millisecondsBeforeTipAppears (millisecondsBeforeTipAppears_),
- mouseX (0),
- mouseY (0),
- lastMouseMoveTime (0),
- lastHideTime (0),
- lastComponentUnderMouse (0),
- changedCompsSinceShown (true)
- {
- startTimer (123);
-
- setAlwaysOnTop (true);
- setOpaque (true);
-
- if (parentComponent != 0)
- {
- parentComponent->addChildComponent (this);
- }
- else
- {
- setSize (1, 1); // to keep the OS happy by not having zero-size windows
- addToDesktop (ComponentPeer::windowHasDropShadow
- | ComponentPeer::windowIsTemporary);
- }
- }
-
- TooltipWindow::~TooltipWindow()
- {
- }
-
- void TooltipWindow::paint (Graphics& g)
- {
- getLookAndFeel().drawTooltip (g, tip, getWidth(), getHeight());
- }
-
- void TooltipWindow::mouseEnter (const MouseEvent&)
- {
- setVisible (false);
- }
-
- void TooltipWindow::showFor (Component* const c)
- {
- TooltipClient* const ttc = dynamic_cast <TooltipClient*> (c);
-
- if (ttc != 0 && ! c->isCurrentlyBlockedByAnotherModalComponent())
- tip = ttc->getTooltip();
- else
- tip = String::empty;
-
- if (tip.isEmpty())
- {
- setVisible (false);
- }
- else
- {
- int mx, my;
- Desktop::getMousePosition (mx, my);
-
- if (getParentComponent() != 0)
- getParentComponent()->globalPositionToRelative (mx, my);
-
- int x, y, w, h;
- getLookAndFeel().getTooltipSize (tip, w, h);
-
- if (mx > getParentWidth() / 2)
- x = mx - (w + 12);
- else
- x = mx + 24;
-
- if (my > getParentHeight() / 2)
- y = my - (h + 6);
- else
- y = my + 6;
-
- setBounds (x, y, w, h);
- setVisible (true);
- toFront (false);
- }
- }
-
- void TooltipWindow::timerCallback()
- {
- int mx, my;
- Desktop::getMousePosition (mx, my);
-
- const unsigned int now = Time::getApproximateMillisecondCounter();
- Component* const underMouse = Component::getComponentUnderMouse();
- const bool changedComp = (underMouse != lastComponentUnderMouse);
- lastComponentUnderMouse = underMouse;
-
- if (changedComp
- || abs (mx - mouseX) > 4
- || abs (my - mouseY) > 4
- || Desktop::getInstance().getMouseButtonClickCounter() > mouseClicks)
- {
- lastMouseMoveTime = now;
-
- if (isVisible())
- {
- lastHideTime = now;
- setVisible (false);
- }
-
- changedCompsSinceShown = changedCompsSinceShown || changedComp;
-
- tip = String::empty;
-
- mouseX = mx;
- mouseY = my;
- }
-
- if (changedCompsSinceShown)
- {
- if ((now > lastMouseMoveTime + millisecondsBeforeTipAppears
- || now < lastHideTime + 500)
- && ! isVisible())
- {
- if (underMouse->isValidComponent())
- showFor (underMouse);
-
- changedCompsSinceShown = false;
- }
- }
-
- mouseClicks = Desktop::getInstance().getMouseButtonClickCounter();
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_TooltipWindow.cpp *********/
-
- /********* Start of inlined file: juce_TopLevelWindow.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- /** Keeps track of the active top level window.
- */
- class TopLevelWindowManager : public Timer,
- public DeletedAtShutdown
- {
- public:
-
- TopLevelWindowManager()
- : windows (8),
- currentActive (0)
- {
- }
-
- ~TopLevelWindowManager()
- {
- clearSingletonInstance();
- }
-
- juce_DeclareSingleton_SingleThreaded_Minimal (TopLevelWindowManager)
-
- void timerCallback()
- {
- startTimer (1731);
- TopLevelWindow* active = 0;
-
- if (Process::isForegroundProcess())
- {
- active = currentActive;
-
- Component* const c = Component::getCurrentlyFocusedComponent();
-
- TopLevelWindow* tlw = dynamic_cast <TopLevelWindow*> (c);
-
- if (tlw == 0 && c != 0)
- // (unable to use the syntax findParentComponentOfClass <TopLevelWindow> () because of a VC6 compiler bug)
- tlw = c->findParentComponentOfClass ((TopLevelWindow*) 0);
-
- if (tlw != 0)
- active = tlw;
- }
-
- if (active != currentActive)
- {
- currentActive = active;
-
- for (int i = windows.size(); --i >= 0;)
- {
- TopLevelWindow* const tlw = (TopLevelWindow*) windows.getUnchecked (i);
- tlw->setWindowActive (isWindowActive (tlw));
-
- i = jmin (i, windows.size() - 1);
- }
-
- Desktop::getInstance().triggerFocusCallback();
- }
- }
-
- bool addWindow (TopLevelWindow* const w) throw()
- {
- windows.add (w);
- startTimer (10);
-
- return isWindowActive (w);
- }
-
- void removeWindow (TopLevelWindow* const w) throw()
- {
- startTimer (10);
-
- if (currentActive == w)
- currentActive = 0;
-
- windows.removeValue (w);
-
- if (windows.size() == 0)
- deleteInstance();
- }
-
- VoidArray windows;
-
- private:
- TopLevelWindow* currentActive;
-
- bool isWindowActive (TopLevelWindow* const tlw) const throw()
- {
- return (tlw == currentActive
- || tlw->isParentOf (currentActive)
- || tlw->hasKeyboardFocus (true))
- && tlw->isShowing();
- }
-
- TopLevelWindowManager (const TopLevelWindowManager&);
- const TopLevelWindowManager& operator= (const TopLevelWindowManager&);
- };
-
- juce_ImplementSingleton_SingleThreaded (TopLevelWindowManager)
-
- void juce_CheckCurrentlyFocusedTopLevelWindow() throw()
- {
- if (TopLevelWindowManager::getInstanceWithoutCreating() != 0)
- TopLevelWindowManager::getInstanceWithoutCreating()->startTimer (20);
- }
-
- TopLevelWindow::TopLevelWindow (const String& name,
- const bool addToDesktop_)
- : Component (name),
- useDropShadow (true),
- useNativeTitleBar (false),
- windowIsActive_ (false),
- shadower (0)
- {
- setOpaque (true);
-
- if (addToDesktop_)
- Component::addToDesktop (getDesktopWindowStyleFlags());
- else
- setDropShadowEnabled (true);
-
- setWantsKeyboardFocus (true);
- setBroughtToFrontOnMouseClick (true);
- windowIsActive_ = TopLevelWindowManager::getInstance()->addWindow (this);
- }
-
- TopLevelWindow::~TopLevelWindow()
- {
- deleteAndZero (shadower);
- TopLevelWindowManager::getInstance()->removeWindow (this);
- }
-
- void TopLevelWindow::focusOfChildComponentChanged (FocusChangeType)
- {
- if (hasKeyboardFocus (true))
- TopLevelWindowManager::getInstance()->timerCallback();
- else
- TopLevelWindowManager::getInstance()->startTimer (10);
- }
-
- void TopLevelWindow::setWindowActive (const bool isNowActive) throw()
- {
- if (windowIsActive_ != isNowActive)
- {
- windowIsActive_ = isNowActive;
- activeWindowStatusChanged();
- }
- }
-
- void TopLevelWindow::activeWindowStatusChanged()
- {
- }
-
- void TopLevelWindow::parentHierarchyChanged()
- {
- setDropShadowEnabled (useDropShadow);
- }
-
- void TopLevelWindow::visibilityChanged()
- {
- if (isShowing())
- toFront (true);
- }
-
- int TopLevelWindow::getDesktopWindowStyleFlags() const
- {
- int flags = ComponentPeer::windowAppearsOnTaskbar;
-
- if (useDropShadow)
- flags |= ComponentPeer::windowHasDropShadow;
-
- if (useNativeTitleBar)
- flags |= ComponentPeer::windowHasTitleBar;
-
- return flags;
- }
-
- void TopLevelWindow::setDropShadowEnabled (const bool useShadow)
- {
- useDropShadow = useShadow;
-
- if (isOnDesktop())
- {
- deleteAndZero (shadower);
- Component::addToDesktop (getDesktopWindowStyleFlags());
- }
- else
- {
- if (useShadow && isOpaque())
- {
- if (shadower == 0)
- {
- shadower = getLookAndFeel().createDropShadowerForComponent (this);
-
- if (shadower != 0)
- shadower->setOwner (this);
- }
- }
- else
- {
- deleteAndZero (shadower);
- }
- }
- }
-
- void TopLevelWindow::setUsingNativeTitleBar (const bool useNativeTitleBar_)
- {
- if (useNativeTitleBar != useNativeTitleBar_)
- {
- useNativeTitleBar = useNativeTitleBar_;
- recreateDesktopWindow();
- sendLookAndFeelChange();
- }
- }
-
- void TopLevelWindow::recreateDesktopWindow()
- {
- if (isOnDesktop())
- {
- Component::addToDesktop (getDesktopWindowStyleFlags());
- toFront (true);
- }
- }
-
- void TopLevelWindow::addToDesktop (int windowStyleFlags, void* nativeWindowToAttachTo)
- {
- /* It's not recommended to change the desktop window flags directly for a TopLevelWindow,
- because this class needs to make sure its layout corresponds with settings like whether
- it's got a native title bar or not.
-
- If you need custom flags for your window, you can override the getDesktopWindowStyleFlags()
- method. If you do this, it's best to call the base class's getDesktopWindowStyleFlags()
- method, then add or remove whatever flags are necessary from this value before returning it.
- */
-
- jassert ((windowStyleFlags & ~ComponentPeer::windowIsSemiTransparent)
- == (getDesktopWindowStyleFlags() & ~ComponentPeer::windowIsSemiTransparent));
-
- Component::addToDesktop (windowStyleFlags, nativeWindowToAttachTo);
-
- if (windowStyleFlags != getDesktopWindowStyleFlags())
- sendLookAndFeelChange();
- }
-
- void TopLevelWindow::centreAroundComponent (Component* c, const int width, const int height)
- {
- if (c == 0)
- c = TopLevelWindow::getActiveTopLevelWindow();
-
- if (c == 0)
- {
- centreWithSize (width, height);
- }
- else
- {
- int x = (c->getWidth() - width) / 2;
- int y = (c->getHeight() - height) / 2;
- c->relativePositionToGlobal (x, y);
-
- Rectangle parentArea (c->getParentMonitorArea());
-
- if (getParentComponent() != 0)
- {
- getParentComponent()->globalPositionToRelative (x, y);
- parentArea.setBounds (0, 0, getParentWidth(), getParentHeight());
- }
-
- parentArea.reduce (12, 12);
-
- setBounds (jlimit (parentArea.getX(), jmax (parentArea.getX(), parentArea.getRight() - width), x),
- jlimit (parentArea.getY(), jmax (parentArea.getY(), parentArea.getBottom() - height), y),
- width, height);
- }
- }
-
- int TopLevelWindow::getNumTopLevelWindows() throw()
- {
- return TopLevelWindowManager::getInstance()->windows.size();
- }
-
- TopLevelWindow* TopLevelWindow::getTopLevelWindow (const int index) throw()
- {
- return (TopLevelWindow*) TopLevelWindowManager::getInstance()->windows [index];
- }
-
- TopLevelWindow* TopLevelWindow::getActiveTopLevelWindow() throw()
- {
- TopLevelWindow* best = 0;
- int bestNumTWLParents = -1;
-
- for (int i = TopLevelWindow::getNumTopLevelWindows(); --i >= 0;)
- {
- TopLevelWindow* const tlw = TopLevelWindow::getTopLevelWindow (i);
-
- if (tlw->isActiveWindow())
- {
- int numTWLParents = 0;
-
- const Component* c = tlw->getParentComponent();
-
- while (c != 0)
- {
- if (dynamic_cast <const TopLevelWindow*> (c) != 0)
- ++numTWLParents;
-
- c = c->getParentComponent();
- }
-
- if (bestNumTWLParents < numTWLParents)
- {
- best = tlw;
- bestNumTWLParents = numTWLParents;
- }
- }
- }
-
- return best;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_TopLevelWindow.cpp *********/
-
- /********* Start of inlined file: juce_Brush.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- Brush::Brush() throw()
- {
- }
-
- Brush::~Brush() throw()
- {
- }
-
- void Brush::paintVerticalLine (LowLevelGraphicsContext& context,
- int x, float y1, float y2) throw()
- {
- Path p;
- p.addRectangle ((float) x, y1, 1.0f, y2 - y1);
- paintPath (context, p, AffineTransform::identity);
- }
-
- void Brush::paintHorizontalLine (LowLevelGraphicsContext& context,
- int y, float x1, float x2) throw()
- {
- Path p;
- p.addRectangle (x1, (float) y, x2 - x1, 1.0f);
- paintPath (context, p, AffineTransform::identity);
- }
-
- void Brush::paintLine (LowLevelGraphicsContext& context,
- float x1, float y1, float x2, float y2) throw()
- {
- Path p;
- p.addLineSegment (x1, y1, x2, y2, 1.0f);
- paintPath (context, p, AffineTransform::identity);
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_Brush.cpp *********/
-
- /********* Start of inlined file: juce_GradientBrush.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- GradientBrush::GradientBrush (const Colour& colour1,
- const float x1,
- const float y1,
- const Colour& colour2,
- const float x2,
- const float y2,
- const bool isRadial) throw()
- : gradient (colour1, x1, y1,
- colour2, x2, y2,
- isRadial)
- {
- }
-
- GradientBrush::GradientBrush (const ColourGradient& gradient_) throw()
- : gradient (gradient_)
- {
- }
-
- GradientBrush::~GradientBrush() throw()
- {
- }
-
- Brush* GradientBrush::createCopy() const throw()
- {
- return new GradientBrush (gradient);
- }
-
- void GradientBrush::applyTransform (const AffineTransform& transform) throw()
- {
- gradient.transform = gradient.transform.followedBy (transform);
- }
-
- void GradientBrush::multiplyOpacity (const float multiple) throw()
- {
- gradient.multiplyOpacity (multiple);
- }
-
- bool GradientBrush::isInvisible() const throw()
- {
- return gradient.isInvisible();
- }
-
- void GradientBrush::paintPath (LowLevelGraphicsContext& context,
- const Path& path, const AffineTransform& transform) throw()
- {
- context.fillPathWithGradient (path, transform, gradient, EdgeTable::Oversampling_4times);
- }
-
- void GradientBrush::paintRectangle (LowLevelGraphicsContext& context,
- int x, int y, int w, int h) throw()
- {
- context.fillRectWithGradient (x, y, w, h, gradient);
- }
-
- void GradientBrush::paintAlphaChannel (LowLevelGraphicsContext& context,
- const Image& alphaChannelImage, int imageX, int imageY,
- int x, int y, int w, int h) throw()
- {
- context.saveState();
-
- if (context.reduceClipRegion (x, y, w, h))
- context.fillAlphaChannelWithGradient (alphaChannelImage, imageX, imageY, gradient);
-
- context.restoreState();
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_GradientBrush.cpp *********/
-
- /********* Start of inlined file: juce_ImageBrush.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- ImageBrush::ImageBrush (Image* const image_,
- const int anchorX_,
- const int anchorY_,
- const float opacity_) throw()
- : image (image_),
- anchorX (anchorX_),
- anchorY (anchorY_),
- opacity (opacity_)
- {
- jassert (image != 0); // not much point creating a brush without an image, is there?
-
- if (image != 0)
- {
- if (image->getWidth() == 0 || image->getHeight() == 0)
- {
- jassertfalse // you've passed in an empty image - not exactly brilliant for tiling.
- image = 0;
- }
- }
- }
-
- ImageBrush::~ImageBrush() throw()
- {
- }
-
- Brush* ImageBrush::createCopy() const throw()
- {
- return new ImageBrush (image, anchorX, anchorY, opacity);
- }
-
- void ImageBrush::multiplyOpacity (const float multiple) throw()
- {
- opacity *= multiple;
- }
-
- bool ImageBrush::isInvisible() const throw()
- {
- return opacity == 0.0f;
- }
-
- void ImageBrush::applyTransform (const AffineTransform& /*transform*/) throw()
- {
- //xxx should probably be smarter and warp the image
- }
-
- void ImageBrush::getStartXY (int& x, int& y) const throw()
- {
- x -= anchorX;
- y -= anchorY;
-
- const int iw = image->getWidth();
- const int ih = image->getHeight();
-
- if (x < 0)
- x = ((x / iw) - 1) * iw;
- else
- x = (x / iw) * iw;
-
- if (y < 0)
- y = ((y / ih) - 1) * ih;
- else
- y = (y / ih) * ih;
-
- x += anchorX;
- y += anchorY;
- }
-
- void ImageBrush::paintRectangle (LowLevelGraphicsContext& context,
- int x, int y, int w, int h) throw()
- {
- context.saveState();
-
- if (image != 0 && context.reduceClipRegion (x, y, w, h))
- {
- const int right = x + w;
- const int bottom = y + h;
-
- const int iw = image->getWidth();
- const int ih = image->getHeight();
-
- int startX = x;
- getStartXY (startX, y);
-
- while (y < bottom)
- {
- x = startX;
-
- while (x < right)
- {
- context.blendImage (*image, x, y, iw, ih, 0, 0, opacity);
- x += iw;
- }
-
- y += ih;
- }
- }
-
- context.restoreState();
- }
-
- void ImageBrush::paintPath (LowLevelGraphicsContext& context,
- const Path& path, const AffineTransform& transform) throw()
- {
- if (image != 0)
- {
- Rectangle clip (context.getClipBounds());
-
- {
- float x, y, w, h;
- path.getBoundsTransformed (transform, x, y, w, h);
-
- clip = clip.getIntersection (Rectangle ((int) floorf (x),
- (int) floorf (y),
- 2 + (int) floorf (w),
- 2 + (int) floorf (h)));
- }
-
- int x = clip.getX();
- int y = clip.getY();
- const int right = clip.getRight();
- const int bottom = clip.getBottom();
-
- const int iw = image->getWidth();
- const int ih = image->getHeight();
-
- int startX = x;
- getStartXY (startX, y);
-
- while (y < bottom)
- {
- x = startX;
-
- while (x < right)
- {
- context.fillPathWithImage (path, transform, *image, x, y, opacity, EdgeTable::Oversampling_4times);
- x += iw;
- }
-
- y += ih;
- }
- }
- }
-
- void ImageBrush::paintAlphaChannel (LowLevelGraphicsContext& context,
- const Image& alphaChannelImage, int imageX, int imageY,
- int x, int y, int w, int h) throw()
- {
- context.saveState();
-
- if (image != 0 && context.reduceClipRegion (x, y, w, h))
- {
- const Rectangle clip (context.getClipBounds());
- x = clip.getX();
- y = clip.getY();
- const int right = clip.getRight();
- const int bottom = clip.getBottom();
-
- const int iw = image->getWidth();
- const int ih = image->getHeight();
-
- int startX = x;
- getStartXY (startX, y);
-
- while (y < bottom)
- {
- x = startX;
-
- while (x < right)
- {
- context.fillAlphaChannelWithImage (alphaChannelImage,
- imageX, imageY, *image,
- x, y, opacity);
- x += iw;
- }
-
- y += ih;
- }
- }
-
- context.restoreState();
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_ImageBrush.cpp *********/
-
- /********* Start of inlined file: juce_SolidColourBrush.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- SolidColourBrush::SolidColourBrush() throw()
- : colour (0xff000000)
- {
- }
-
- SolidColourBrush::SolidColourBrush (const Colour& colour_) throw()
- : colour (colour_)
- {
- }
-
- SolidColourBrush::~SolidColourBrush() throw()
- {
- }
-
- Brush* SolidColourBrush::createCopy() const throw()
- {
- return new SolidColourBrush (colour);
- }
-
- void SolidColourBrush::applyTransform (const AffineTransform& /*transform*/) throw()
- {
- }
-
- void SolidColourBrush::multiplyOpacity (const float multiple) throw()
- {
- colour = colour.withMultipliedAlpha (multiple);
- }
-
- bool SolidColourBrush::isInvisible() const throw()
- {
- return colour.isTransparent();
- }
-
- void SolidColourBrush::paintPath (LowLevelGraphicsContext& context,
- const Path& path, const AffineTransform& transform) throw()
- {
- if (! colour.isTransparent())
- context.fillPathWithColour (path, transform, colour, EdgeTable::Oversampling_4times);
- }
-
- void SolidColourBrush::paintRectangle (LowLevelGraphicsContext& context,
- int x, int y, int w, int h) throw()
- {
- if (! colour.isTransparent())
- context.fillRectWithColour (x, y, w, h, colour, false);
- }
-
- void SolidColourBrush::paintAlphaChannel (LowLevelGraphicsContext& context,
- const Image& alphaChannelImage, int imageX, int imageY,
- int x, int y, int w, int h) throw()
- {
- if (! colour.isTransparent())
- {
- context.saveState();
-
- if (context.reduceClipRegion (x, y, w, h))
- context.fillAlphaChannelWithColour (alphaChannelImage, imageX, imageY, colour);
-
- context.restoreState();
- }
- }
-
- void SolidColourBrush::paintVerticalLine (LowLevelGraphicsContext& context,
- int x, float y1, float y2) throw()
- {
- context.drawVerticalLine (x, y1, y2, colour);
- }
-
- void SolidColourBrush::paintHorizontalLine (LowLevelGraphicsContext& context,
- int y, float x1, float x2) throw()
- {
- context.drawHorizontalLine (y, x1, x2, colour);
- }
-
- void SolidColourBrush::paintLine (LowLevelGraphicsContext& context,
- float x1, float y1, float x2, float y2) throw()
- {
- context.drawLine (x1, y1, x2, y2, colour);
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_SolidColourBrush.cpp *********/
-
- /********* Start of inlined file: juce_Colour.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- static forcedinline uint8 floatAlphaToInt (const float alpha)
- {
- return (uint8) jlimit (0, 0xff, roundFloatToInt (alpha * 255.0f));
- }
-
- static const float oneOver255 = 1.0f / 255.0f;
-
- Colour::Colour() throw()
- : argb (0)
- {
- }
-
- Colour::Colour (const Colour& other) throw()
- : argb (other.argb)
- {
- }
-
- const Colour& Colour::operator= (const Colour& other) throw()
- {
- argb = other.argb;
- return *this;
- }
-
- bool Colour::operator== (const Colour& other) const throw()
- {
- return argb.getARGB() == other.argb.getARGB();
- }
-
- bool Colour::operator!= (const Colour& other) const throw()
- {
- return argb.getARGB() != other.argb.getARGB();
- }
-
- Colour::Colour (const uint32 argb_) throw()
- : argb (argb_)
- {
- }
-
- Colour::Colour (const uint8 red,
- const uint8 green,
- const uint8 blue) throw()
- {
- argb.setARGB (0xff, red, green, blue);
- }
-
- const Colour Colour::fromRGB (const uint8 red,
- const uint8 green,
- const uint8 blue) throw()
- {
- return Colour (red, green, blue);
- }
-
- Colour::Colour (const uint8 red,
- const uint8 green,
- const uint8 blue,
- const uint8 alpha) throw()
- {
- argb.setARGB (alpha, red, green, blue);
- }
-
- const Colour Colour::fromRGBA (const uint8 red,
- const uint8 green,
- const uint8 blue,
- const uint8 alpha) throw()
- {
- return Colour (red, green, blue, alpha);
- }
-
- Colour::Colour (const uint8 red,
- const uint8 green,
- const uint8 blue,
- const float alpha) throw()
- {
- argb.setARGB (floatAlphaToInt (alpha), red, green, blue);
- }
-
- const Colour Colour::fromRGBAFloat (const uint8 red,
- const uint8 green,
- const uint8 blue,
- const float alpha) throw()
- {
- return Colour (red, green, blue, alpha);
- }
-
- static void convertHSBtoRGB (float h, const float s, float v,
- uint8& r, uint8& g, uint8& b) throw()
- {
- v *= 255.0f;
- const uint8 intV = (uint8) roundFloatToInt (v);
-
- if (s == 0)
- {
- r = intV;
- g = intV;
- b = intV;
- }
- else
- {
- h = (h - floorf (h)) * 6.0f + 0.00001f; // need a small adjustment to compensate for rounding errors
- const float f = h - floorf (h);
-
- const uint8 x = (uint8) roundFloatToInt (v * (1.0f - s));
- const float y = v * (1.0f - s * f);
- const float z = v * (1.0f - (s * (1.0f - f)));
-
- if (h < 1.0f)
- {
- r = intV;
- g = (uint8) roundFloatToInt (z);
- b = x;
- }
- else if (h < 2.0f)
- {
- r = (uint8) roundFloatToInt (y);
- g = intV;
- b = x;
- }
- else if (h < 3.0f)
- {
- r = x;
- g = intV;
- b = (uint8) roundFloatToInt (z);
- }
- else if (h < 4.0f)
- {
- r = x;
- g = (uint8) roundFloatToInt (y);
- b = intV;
- }
- else if (h < 5.0f)
- {
- r = (uint8) roundFloatToInt (z);
- g = x;
- b = intV;
- }
- else if (h < 6.0f)
- {
- r = intV;
- g = x;
- b = (uint8) roundFloatToInt (y);
- }
- else
- {
- r = 0;
- g = 0;
- b = 0;
- }
- }
- }
-
- Colour::Colour (const float hue,
- const float saturation,
- const float brightness,
- const float alpha) throw()
- {
- uint8 r = getRed(), g = getGreen(), b = getBlue();
- convertHSBtoRGB (hue, saturation, brightness, r, g, b);
-
- argb.setARGB (floatAlphaToInt (alpha), r, g, b);
- }
-
- const Colour Colour::fromHSV (const float hue,
- const float saturation,
- const float brightness,
- const float alpha) throw()
- {
- return Colour (hue, saturation, brightness, alpha);
- }
-
- Colour::Colour (const float hue,
- const float saturation,
- const float brightness,
- const uint8 alpha) throw()
- {
- uint8 r = getRed(), g = getGreen(), b = getBlue();
- convertHSBtoRGB (hue, saturation, brightness, r, g, b);
-
- argb.setARGB (alpha, r, g, b);
- }
-
- Colour::~Colour() throw()
- {
- }
-
- const PixelARGB Colour::getPixelARGB() const throw()
- {
- PixelARGB p (argb);
- p.premultiply();
- return p;
- }
-
- uint32 Colour::getARGB() const throw()
- {
- return argb.getARGB();
- }
-
- bool Colour::isTransparent() const throw()
- {
- return getAlpha() == 0;
- }
-
- bool Colour::isOpaque() const throw()
- {
- return getAlpha() == 0xff;
- }
-
- const Colour Colour::withAlpha (const uint8 newAlpha) const throw()
- {
- PixelARGB newCol (argb);
- newCol.setAlpha (newAlpha);
- return Colour (newCol.getARGB());
- }
-
- const Colour Colour::withAlpha (const float newAlpha) const throw()
- {
- jassert (newAlpha >= 0 && newAlpha <= 1.0f);
-
- PixelARGB newCol (argb);
- newCol.setAlpha (floatAlphaToInt (newAlpha));
- return Colour (newCol.getARGB());
- }
-
- const Colour Colour::withMultipliedAlpha (const float alphaMultiplier) const throw()
- {
- jassert (alphaMultiplier >= 0);
-
- PixelARGB newCol (argb);
- newCol.setAlpha ((uint8) jmin (0xff, roundFloatToInt (alphaMultiplier * newCol.getAlpha())));
- return Colour (newCol.getARGB());
- }
-
- const Colour Colour::overlaidWith (const Colour& src) const throw()
- {
- const int destAlpha = getAlpha();
-
- if (destAlpha > 0)
- {
- const int invA = 0xff - (int) src.getAlpha();
- const int resA = 0xff - (((0xff - destAlpha) * invA) >> 8);
-
- if (resA > 0)
- {
- const int da = (invA * destAlpha) / resA;
-
- return Colour ((uint8) (src.getRed() + ((((int) getRed() - src.getRed()) * da) >> 8)),
- (uint8) (src.getGreen() + ((((int) getGreen() - src.getGreen()) * da) >> 8)),
- (uint8) (src.getBlue() + ((((int) getBlue() - src.getBlue()) * da) >> 8)),
- (uint8) resA);
- }
-
- return *this;
- }
- else
- {
- return src;
- }
- }
-
- float Colour::getFloatRed() const throw()
- {
- return getRed() * oneOver255;
- }
-
- float Colour::getFloatGreen() const throw()
- {
- return getGreen() * oneOver255;
- }
-
- float Colour::getFloatBlue() const throw()
- {
- return getBlue() * oneOver255;
- }
-
- float Colour::getFloatAlpha() const throw()
- {
- return getAlpha() * oneOver255;
- }
-
- void Colour::getHSB (float& h, float& s, float& v) const throw()
- {
- const int r = getRed();
- const int g = getGreen();
- const int b = getBlue();
-
- const int hi = jmax (r, g, b);
- const int lo = jmin (r, g, b);
-
- if (hi != 0)
- {
- s = (hi - lo) / (float) hi;
-
- if (s != 0)
- {
- const float invDiff = 1.0f / (hi - lo);
-
- const float red = (hi - r) * invDiff;
- const float green = (hi - g) * invDiff;
- const float blue = (hi - b) * invDiff;
-
- if (r == hi)
- h = blue - green;
- else if (g == hi)
- h = 2.0f + red - blue;
- else
- h = 4.0f + green - red;
-
- h *= 1.0f / 6.0f;
-
- if (h < 0)
- ++h;
- }
- else
- {
- h = 0;
- }
- }
- else
- {
- s = 0;
- h = 0;
- }
-
- v = hi * oneOver255;
- }
-
- float Colour::getHue() const throw()
- {
- float h, s, b;
- getHSB (h, s, b);
- return h;
- }
-
- const Colour Colour::withHue (const float hue) const throw()
- {
- float h, s, b;
- getHSB (h, s, b);
-
- return Colour (hue, s, b, getAlpha());
- }
-
- const Colour Colour::withRotatedHue (const float amountToRotate) const throw()
- {
- float h, s, b;
- getHSB (h, s, b);
-
- h += amountToRotate;
- h -= floorf (h);
-
- return Colour (h, s, b, getAlpha());
- }
-
- float Colour::getSaturation() const throw()
- {
- float h, s, b;
- getHSB (h, s, b);
- return s;
- }
-
- const Colour Colour::withSaturation (const float saturation) const throw()
- {
- float h, s, b;
- getHSB (h, s, b);
-
- return Colour (h, saturation, b, getAlpha());
- }
-
- const Colour Colour::withMultipliedSaturation (const float amount) const throw()
- {
- float h, s, b;
- getHSB (h, s, b);
-
- return Colour (h, jmin (1.0f, s * amount), b, getAlpha());
- }
-
- float Colour::getBrightness() const throw()
- {
- float h, s, b;
- getHSB (h, s, b);
- return b;
- }
-
- const Colour Colour::withBrightness (const float brightness) const throw()
- {
- float h, s, b;
- getHSB (h, s, b);
-
- return Colour (h, s, brightness, getAlpha());
- }
-
- const Colour Colour::withMultipliedBrightness (const float amount) const throw()
- {
- float h, s, b;
- getHSB (h, s, b);
-
- b *= amount;
-
- if (b > 1.0f)
- b = 1.0f;
-
- return Colour (h, s, b, getAlpha());
- }
-
- const Colour Colour::brighter (float amount) const throw()
- {
- amount = 1.0f / (1.0f + amount);
-
- return Colour ((uint8) (255 - (amount * (255 - getRed()))),
- (uint8) (255 - (amount * (255 - getGreen()))),
- (uint8) (255 - (amount * (255 - getBlue()))),
- getAlpha());
- }
-
- const Colour Colour::darker (float amount) const throw()
- {
- amount = 1.0f / (1.0f + amount);
-
- return Colour ((uint8) (amount * getRed()),
- (uint8) (amount * getGreen()),
- (uint8) (amount * getBlue()),
- getAlpha());
- }
-
- const Colour Colour::greyLevel (const float brightness) throw()
- {
- const uint8 level
- = (uint8) jlimit (0x00, 0xff, roundFloatToInt (brightness * 255.0f));
-
- return Colour (level, level, level);
- }
-
- const Colour Colour::contrasting (const float amount) const throw()
- {
- return overlaidWith ((((int) getRed() + (int) getGreen() + (int) getBlue() >= 3 * 128)
- ? Colours::black
- : Colours::white).withAlpha (amount));
- }
-
- const Colour Colour::contrasting (const Colour& colour1,
- const Colour& colour2) throw()
- {
- const float b1 = colour1.getBrightness();
- const float b2 = colour2.getBrightness();
- float best = 0.0f;
- float bestDist = 0.0f;
-
- for (float i = 0.0f; i < 1.0f; i += 0.02f)
- {
- const float d1 = fabsf (i - b1);
- const float d2 = fabsf (i - b2);
- const float dist = jmin (d1, d2, 1.0f - d1, 1.0f - d2);
-
- if (dist > bestDist)
- {
- best = i;
- bestDist = dist;
- }
- }
-
- return colour1.overlaidWith (colour2.withMultipliedAlpha (0.5f))
- .withBrightness (best);
- }
-
- const String Colour::toString() const throw()
- {
- return String::toHexString ((int) argb.getARGB());
- }
-
- const Colour Colour::fromString (const String& encodedColourString)
- {
- return Colour ((uint32) encodedColourString.getHexValue32());
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_Colour.cpp *********/
-
- /********* Start of inlined file: juce_ColourGradient.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- ColourGradient::ColourGradient() throw()
- : colours (4)
- {
- #ifdef JUCE_DEBUG
- x1 = 987654.0f;
- #endif
- }
-
- ColourGradient::ColourGradient (const Colour& colour1,
- const float x1_,
- const float y1_,
- const Colour& colour2,
- const float x2_,
- const float y2_,
- const bool isRadial_) throw()
- : x1 (x1_),
- y1 (y1_),
- x2 (x2_),
- y2 (y2_),
- isRadial (isRadial_),
- colours (4)
- {
- colours.add (0);
- colours.add (colour1.getPixelARGB().getARGB());
-
- colours.add (1 << 16);
- colours.add (colour2.getPixelARGB().getARGB());
- }
-
- ColourGradient::~ColourGradient() throw()
- {
- }
-
- void ColourGradient::clearColours() throw()
- {
- colours.clear();
- }
-
- void ColourGradient::addColour (const double proportionAlongGradient,
- const Colour& colour) throw()
- {
- // must be within the two end-points
- jassert (proportionAlongGradient >= 0 && proportionAlongGradient <= 1.0);
-
- const uint32 pos = jlimit (0, 65535, roundDoubleToInt (proportionAlongGradient * 65536.0));
-
- int i;
- for (i = 0; i < colours.size(); i += 2)
- if (colours.getUnchecked(i) > pos)
- break;
-
- colours.insert (i, pos);
- colours.insert (i + 1, colour.getPixelARGB().getARGB());
- }
-
- void ColourGradient::multiplyOpacity (const float multiplier) throw()
- {
- for (int i = 1; i < colours.size(); i += 2)
- {
- PixelARGB pix (colours.getUnchecked(i));
- pix.multiplyAlpha (multiplier);
- colours.set (i, pix.getARGB());
- }
- }
-
- int ColourGradient::getNumColours() const throw()
- {
- return colours.size() >> 1;
- }
-
- double ColourGradient::getColourPosition (const int index) const throw()
- {
- return colours [index << 1];
- }
-
- const Colour ColourGradient::getColour (const int index) const throw()
- {
- PixelARGB pix (colours [(index << 1) + 1]);
- pix.unpremultiply();
- return Colour (pix.getARGB());
- }
-
- PixelARGB* ColourGradient::createLookupTable (int& numEntries) const throw()
- {
- #ifdef JUCE_DEBUG
- // trying to use the object without setting its co-ordinates? Have a careful read of
- // the comments for the constructors.
- jassert (x1 != 987654.0f);
- #endif
-
- const int numColours = colours.size() >> 1;
-
- float tx1 = x1, ty1 = y1, tx2 = x2, ty2 = y2;
- transform.transformPoint (tx1, ty1);
- transform.transformPoint (tx2, ty2);
- const double distance = juce_hypot (tx1 - tx2, ty1 - ty2);
-
- numEntries = jlimit (1, (numColours - 1) << 8, 3 * (int) distance);
-
- PixelARGB* const lookupTable = (PixelARGB*) juce_calloc (numEntries * sizeof (PixelARGB));
-
- if (numColours >= 2)
- {
- jassert (colours.getUnchecked (0) == 0); // the first colour specified has to go at position 0
-
- PixelARGB pix1 (colours.getUnchecked (1));
- int index = 0;
-
- for (int j = 2; j < colours.size(); j += 2)
- {
- const int numToDo = ((colours.getUnchecked (j) * numEntries) >> 16) - index;
- const PixelARGB pix2 (colours.getUnchecked (j + 1));
-
- for (int i = 0; i < numToDo; ++i)
- {
- jassert (index >= 0 && index < numEntries);
-
- lookupTable[index] = pix1;
- lookupTable[index].tween (pix2, (i << 8) / numToDo);
- ++index;
- }
-
- pix1 = pix2;
- }
-
- while (index < numEntries)
- lookupTable [index++] = pix1;
- }
- else
- {
- jassertfalse // no colours specified!
- }
-
- return lookupTable;
- }
-
- bool ColourGradient::isOpaque() const throw()
- {
- for (int i = 1; i < colours.size(); i += 2)
- if (PixelARGB (colours.getUnchecked(i)).getAlpha() < 0xff)
- return false;
-
- return true;
- }
-
- bool ColourGradient::isInvisible() const throw()
- {
- for (int i = 1; i < colours.size(); i += 2)
- if (PixelARGB (colours.getUnchecked(i)).getAlpha() > 0)
- return false;
-
- return true;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_ColourGradient.cpp *********/
-
- /********* Start of inlined file: juce_Colours.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- const Colour Colours::transparentBlack (0);
- const Colour Colours::transparentWhite (0x00ffffff);
-
- const Colour Colours::aliceblue (0xfff0f8ff);
- const Colour Colours::antiquewhite (0xfffaebd7);
- const Colour Colours::aqua (0xff00ffff);
- const Colour Colours::aquamarine (0xff7fffd4);
- const Colour Colours::azure (0xfff0ffff);
- const Colour Colours::beige (0xfff5f5dc);
- const Colour Colours::bisque (0xffffe4c4);
- const Colour Colours::black (0xff000000);
- const Colour Colours::blanchedalmond (0xffffebcd);
- const Colour Colours::blue (0xff0000ff);
- const Colour Colours::blueviolet (0xff8a2be2);
- const Colour Colours::brown (0xffa52a2a);
- const Colour Colours::burlywood (0xffdeb887);
- const Colour Colours::cadetblue (0xff5f9ea0);
- const Colour Colours::chartreuse (0xff7fff00);
- const Colour Colours::chocolate (0xffd2691e);
- const Colour Colours::coral (0xffff7f50);
- const Colour Colours::cornflowerblue (0xff6495ed);
- const Colour Colours::cornsilk (0xfffff8dc);
- const Colour Colours::crimson (0xffdc143c);
- const Colour Colours::cyan (0xff00ffff);
- const Colour Colours::darkblue (0xff00008b);
- const Colour Colours::darkcyan (0xff008b8b);
- const Colour Colours::darkgoldenrod (0xffb8860b);
- const Colour Colours::darkgrey (0xff555555);
- const Colour Colours::darkgreen (0xff006400);
- const Colour Colours::darkkhaki (0xffbdb76b);
- const Colour Colours::darkmagenta (0xff8b008b);
- const Colour Colours::darkolivegreen (0xff556b2f);
- const Colour Colours::darkorange (0xffff8c00);
- const Colour Colours::darkorchid (0xff9932cc);
- const Colour Colours::darkred (0xff8b0000);
- const Colour Colours::darksalmon (0xffe9967a);
- const Colour Colours::darkseagreen (0xff8fbc8f);
- const Colour Colours::darkslateblue (0xff483d8b);
- const Colour Colours::darkslategrey (0xff2f4f4f);
- const Colour Colours::darkturquoise (0xff00ced1);
- const Colour Colours::darkviolet (0xff9400d3);
- const Colour Colours::deeppink (0xffff1493);
- const Colour Colours::deepskyblue (0xff00bfff);
- const Colour Colours::dimgrey (0xff696969);
- const Colour Colours::dodgerblue (0xff1e90ff);
- const Colour Colours::firebrick (0xffb22222);
- const Colour Colours::floralwhite (0xfffffaf0);
- const Colour Colours::forestgreen (0xff228b22);
- const Colour Colours::fuchsia (0xffff00ff);
- const Colour Colours::gainsboro (0xffdcdcdc);
- const Colour Colours::gold (0xffffd700);
- const Colour Colours::goldenrod (0xffdaa520);
- const Colour Colours::grey (0xff808080);
- const Colour Colours::green (0xff008000);
- const Colour Colours::greenyellow (0xffadff2f);
- const Colour Colours::honeydew (0xfff0fff0);
- const Colour Colours::hotpink (0xffff69b4);
- const Colour Colours::indianred (0xffcd5c5c);
- const Colour Colours::indigo (0xff4b0082);
- const Colour Colours::ivory (0xfffffff0);
- const Colour Colours::khaki (0xfff0e68c);
- const Colour Colours::lavender (0xffe6e6fa);
- const Colour Colours::lavenderblush (0xfffff0f5);
- const Colour Colours::lemonchiffon (0xfffffacd);
- const Colour Colours::lightblue (0xffadd8e6);
- const Colour Colours::lightcoral (0xfff08080);
- const Colour Colours::lightcyan (0xffe0ffff);
- const Colour Colours::lightgoldenrodyellow (0xfffafad2);
- const Colour Colours::lightgreen (0xff90ee90);
- const Colour Colours::lightgrey (0xffd3d3d3);
- const Colour Colours::lightpink (0xffffb6c1);
- const Colour Colours::lightsalmon (0xffffa07a);
- const Colour Colours::lightseagreen (0xff20b2aa);
- const Colour Colours::lightskyblue (0xff87cefa);
- const Colour Colours::lightslategrey (0xff778899);
- const Colour Colours::lightsteelblue (0xffb0c4de);
- const Colour Colours::lightyellow (0xffffffe0);
- const Colour Colours::lime (0xff00ff00);
- const Colour Colours::limegreen (0xff32cd32);
- const Colour Colours::linen (0xfffaf0e6);
- const Colour Colours::magenta (0xffff00ff);
- const Colour Colours::maroon (0xff800000);
- const Colour Colours::mediumaquamarine (0xff66cdaa);
- const Colour Colours::mediumblue (0xff0000cd);
- const Colour Colours::mediumorchid (0xffba55d3);
- const Colour Colours::mediumpurple (0xff9370db);
- const Colour Colours::mediumseagreen (0xff3cb371);
- const Colour Colours::mediumslateblue (0xff7b68ee);
- const Colour Colours::mediumspringgreen (0xff00fa9a);
- const Colour Colours::mediumturquoise (0xff48d1cc);
- const Colour Colours::mediumvioletred (0xffc71585);
- const Colour Colours::midnightblue (0xff191970);
- const Colour Colours::mintcream (0xfff5fffa);
- const Colour Colours::mistyrose (0xffffe4e1);
- const Colour Colours::navajowhite (0xffffdead);
- const Colour Colours::navy (0xff000080);
- const Colour Colours::oldlace (0xfffdf5e6);
- const Colour Colours::olive (0xff808000);
- const Colour Colours::olivedrab (0xff6b8e23);
- const Colour Colours::orange (0xffffa500);
- const Colour Colours::orangered (0xffff4500);
- const Colour Colours::orchid (0xffda70d6);
- const Colour Colours::palegoldenrod (0xffeee8aa);
- const Colour Colours::palegreen (0xff98fb98);
- const Colour Colours::paleturquoise (0xffafeeee);
- const Colour Colours::palevioletred (0xffdb7093);
- const Colour Colours::papayawhip (0xffffefd5);
- const Colour Colours::peachpuff (0xffffdab9);
- const Colour Colours::peru (0xffcd853f);
- const Colour Colours::pink (0xffffc0cb);
- const Colour Colours::plum (0xffdda0dd);
- const Colour Colours::powderblue (0xffb0e0e6);
- const Colour Colours::purple (0xff800080);
- const Colour Colours::red (0xffff0000);
- const Colour Colours::rosybrown (0xffbc8f8f);
- const Colour Colours::royalblue (0xff4169e1);
- const Colour Colours::saddlebrown (0xff8b4513);
- const Colour Colours::salmon (0xfffa8072);
- const Colour Colours::sandybrown (0xfff4a460);
- const Colour Colours::seagreen (0xff2e8b57);
- const Colour Colours::seashell (0xfffff5ee);
- const Colour Colours::sienna (0xffa0522d);
- const Colour Colours::silver (0xffc0c0c0);
- const Colour Colours::skyblue (0xff87ceeb);
- const Colour Colours::slateblue (0xff6a5acd);
- const Colour Colours::slategrey (0xff708090);
- const Colour Colours::snow (0xfffffafa);
- const Colour Colours::springgreen (0xff00ff7f);
- const Colour Colours::steelblue (0xff4682b4);
- const Colour Colours::tan (0xffd2b48c);
- const Colour Colours::teal (0xff008080);
- const Colour Colours::thistle (0xffd8bfd8);
- const Colour Colours::tomato (0xffff6347);
- const Colour Colours::turquoise (0xff40e0d0);
- const Colour Colours::violet (0xffee82ee);
- const Colour Colours::wheat (0xfff5deb3);
- const Colour Colours::white (0xffffffff);
- const Colour Colours::whitesmoke (0xfff5f5f5);
- const Colour Colours::yellow (0xffffff00);
- const Colour Colours::yellowgreen (0xff9acd32);
-
- const Colour Colours::findColourForName (const String& colourName,
- const Colour& defaultColour)
- {
- static const int presets[] =
- {
- // (first value is the string's hashcode, second is ARGB)
-
- 0x05978fff, 0xff000000, /* black */
- 0x06bdcc29, 0xffffffff, /* white */
- 0x002e305a, 0xff0000ff, /* blue */
- 0x00308adf, 0xff808080, /* grey */
- 0x05e0cf03, 0xff008000, /* green */
- 0x0001b891, 0xffff0000, /* red */
- 0xd43c6474, 0xffffff00, /* yellow */
- 0x620886da, 0xfff0f8ff, /* aliceblue */
- 0x20a2676a, 0xfffaebd7, /* antiquewhite */
- 0x002dcebc, 0xff00ffff, /* aqua */
- 0x46bb5f7e, 0xff7fffd4, /* aquamarine */
- 0x0590228f, 0xfff0ffff, /* azure */
- 0x05947fe4, 0xfff5f5dc, /* beige */
- 0xad388e35, 0xffffe4c4, /* bisque */
- 0x00674f7e, 0xffffebcd, /* blanchedalmond */
- 0x39129959, 0xff8a2be2, /* blueviolet */
- 0x059a8136, 0xffa52a2a, /* brown */
- 0x89cea8f9, 0xffdeb887, /* burlywood */
- 0x0fa260cf, 0xff5f9ea0, /* cadetblue */
- 0x6b748956, 0xff7fff00, /* chartreuse */
- 0x2903623c, 0xffd2691e, /* chocolate */
- 0x05a74431, 0xffff7f50, /* coral */
- 0x618d42dd, 0xff6495ed, /* cornflowerblue */
- 0xe4b479fd, 0xfffff8dc, /* cornsilk */
- 0x3d8c4edf, 0xffdc143c, /* crimson */
- 0x002ed323, 0xff00ffff, /* cyan */
- 0x67cc74d0, 0xff00008b, /* darkblue */
- 0x67cd1799, 0xff008b8b, /* darkcyan */
- 0x31bbd168, 0xffb8860b, /* darkgoldenrod */
- 0x67cecf55, 0xff555555, /* darkgrey */
- 0x920b194d, 0xff006400, /* darkgreen */
- 0x923edd4c, 0xffbdb76b, /* darkkhaki */
- 0x5c293873, 0xff8b008b, /* darkmagenta */
- 0x6b6671fe, 0xff556b2f, /* darkolivegreen */
- 0xbcfd2524, 0xffff8c00, /* darkorange */
- 0xbcfdf799, 0xff9932cc, /* darkorchid */
- 0x55ee0d5b, 0xff8b0000, /* darkred */
- 0xc2e5f564, 0xffe9967a, /* darksalmon */
- 0x61be858a, 0xff8fbc8f, /* darkseagreen */
- 0xc2b0f2bd, 0xff483d8b, /* darkslateblue */
- 0xc2b34d42, 0xff2f4f4f, /* darkslategrey */
- 0x7cf2b06b, 0xff00ced1, /* darkturquoise */
- 0xc8769375, 0xff9400d3, /* darkviolet */
- 0x25832862, 0xffff1493, /* deeppink */
- 0xfcad568f, 0xff00bfff, /* deepskyblue */
- 0x634c8b67, 0xff696969, /* dimgrey */
- 0x45c1ce55, 0xff1e90ff, /* dodgerblue */
- 0xef19e3cb, 0xffb22222, /* firebrick */
- 0xb852b195, 0xfffffaf0, /* floralwhite */
- 0xd086fd06, 0xff228b22, /* forestgreen */
- 0xe106b6d7, 0xffff00ff, /* fuchsia */
- 0x7880d61e, 0xffdcdcdc, /* gainsboro */
- 0x00308060, 0xffffd700, /* gold */
- 0xb3b3bc1e, 0xffdaa520, /* goldenrod */
- 0xbab8a537, 0xffadff2f, /* greenyellow */
- 0xe4cacafb, 0xfff0fff0, /* honeydew */
- 0x41892743, 0xffff69b4, /* hotpink */
- 0xd5796f1a, 0xffcd5c5c, /* indianred */
- 0xb969fed2, 0xff4b0082, /* indigo */
- 0x05fef6a9, 0xfffffff0, /* ivory */
- 0x06149302, 0xfff0e68c, /* khaki */
- 0xad5a05c7, 0xffe6e6fa, /* lavender */
- 0x7c4d5b99, 0xfffff0f5, /* lavenderblush */
- 0x195756f0, 0xfffffacd, /* lemonchiffon */
- 0x28e4ea70, 0xffadd8e6, /* lightblue */
- 0xf3c7ccdb, 0xfff08080, /* lightcoral */
- 0x28e58d39, 0xffe0ffff, /* lightcyan */
- 0x21234e3c, 0xfffafad2, /* lightgoldenrodyellow */
- 0xf40157ad, 0xff90ee90, /* lightgreen */
- 0x28e744f5, 0xffd3d3d3, /* lightgrey */
- 0x28eb3b8c, 0xffffb6c1, /* lightpink */
- 0x9fb78304, 0xffffa07a, /* lightsalmon */
- 0x50632b2a, 0xff20b2aa, /* lightseagreen */
- 0x68fb7b25, 0xff87cefa, /* lightskyblue */
- 0xa8a35ba2, 0xff778899, /* lightslategrey */
- 0xa20d484f, 0xffb0c4de, /* lightsteelblue */
- 0xaa2cf10a, 0xffffffe0, /* lightyellow */
- 0x0032afd5, 0xff00ff00, /* lime */
- 0x607bbc4e, 0xff32cd32, /* limegreen */
- 0x06234efa, 0xfffaf0e6, /* linen */
- 0x316858a9, 0xffff00ff, /* magenta */
- 0xbf8ca470, 0xff800000, /* maroon */
- 0xbd58e0b3, 0xff66cdaa, /* mediumaquamarine */
- 0x967dfd4f, 0xff0000cd, /* mediumblue */
- 0x056f5c58, 0xffba55d3, /* mediumorchid */
- 0x07556b71, 0xff9370db, /* mediumpurple */
- 0x5369b689, 0xff3cb371, /* mediumseagreen */
- 0x066be19e, 0xff7b68ee, /* mediumslateblue */
- 0x3256b281, 0xff00fa9a, /* mediumspringgreen */
- 0xc0ad9f4c, 0xff48d1cc, /* mediumturquoise */
- 0x628e63dd, 0xffc71585, /* mediumvioletred */
- 0x168eb32a, 0xff191970, /* midnightblue */
- 0x4306b960, 0xfff5fffa, /* mintcream */
- 0x4cbc0e6b, 0xffffe4e1, /* mistyrose */
- 0xe97218a6, 0xffffdead, /* navajowhite */
- 0x00337bb6, 0xff000080, /* navy */
- 0xadd2d33e, 0xfffdf5e6, /* oldlace */
- 0x064ee1db, 0xff808000, /* olive */
- 0x9e33a98a, 0xff6b8e23, /* olivedrab */
- 0xc3de262e, 0xffffa500, /* orange */
- 0x58bebba3, 0xffff4500, /* orangered */
- 0xc3def8a3, 0xffda70d6, /* orchid */
- 0x28cb4834, 0xffeee8aa, /* palegoldenrod */
- 0x3d9dd619, 0xff98fb98, /* palegreen */
- 0x74022737, 0xffafeeee, /* paleturquoise */
- 0x15e2ebc8, 0xffdb7093, /* palevioletred */
- 0x5fd898e2, 0xffffefd5, /* papayawhip */
- 0x93e1b776, 0xffffdab9, /* peachpuff */
- 0x003472f8, 0xffcd853f, /* peru */
- 0x00348176, 0xffffc0cb, /* pink */
- 0x00348d94, 0xffdda0dd, /* plum */
- 0xd036be93, 0xffb0e0e6, /* powderblue */
- 0xc5c507bc, 0xff800080, /* purple */
- 0xa89d65b3, 0xffbc8f8f, /* rosybrown */
- 0xbd9413e1, 0xff4169e1, /* royalblue */
- 0xf456044f, 0xff8b4513, /* saddlebrown */
- 0xc9c6f66e, 0xfffa8072, /* salmon */
- 0x0bb131e1, 0xfff4a460, /* sandybrown */
- 0x34636c14, 0xff2e8b57, /* seagreen */
- 0x3507fb41, 0xfffff5ee, /* seashell */
- 0xca348772, 0xffa0522d, /* sienna */
- 0xca37d30d, 0xffc0c0c0, /* silver */
- 0x80da74fb, 0xff87ceeb, /* skyblue */
- 0x44a8dd73, 0xff6a5acd, /* slateblue */
- 0x44ab37f8, 0xff708090, /* slategrey */
- 0x0035f183, 0xfffffafa, /* snow */
- 0xd5440d16, 0xff00ff7f, /* springgreen */
- 0x3e1524a5, 0xff4682b4, /* steelblue */
- 0x0001bfa1, 0xffd2b48c, /* tan */
- 0x0036425c, 0xff008080, /* teal */
- 0xafc8858f, 0xffd8bfd8, /* thistle */
- 0xcc41600a, 0xffff6347, /* tomato */
- 0xfeea9b21, 0xff40e0d0, /* turquoise */
- 0xcf57947f, 0xffee82ee, /* violet */
- 0x06bdbae7, 0xfff5deb3, /* wheat */
- 0x10802ee6, 0xfff5f5f5, /* whitesmoke */
- 0xe1b5130f, 0xff9acd32 /* yellowgreen */
- };
-
- const int hash = colourName.trim().toLowerCase().hashCode();
-
- for (int i = 0; i < numElementsInArray (presets); i += 2)
- if (presets [i] == hash)
- return Colour (presets [i + 1]);
-
- return defaultColour;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_Colours.cpp *********/
-
- /********* Start of inlined file: juce_EdgeTable.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- EdgeTable::EdgeTable (const int top_,
- const int height_,
- const OversamplingLevel oversampling_,
- const int expectedEdgesPerLine) throw()
- : top (top_),
- height (height_),
- maxEdgesPerLine (expectedEdgesPerLine),
- lineStrideElements ((expectedEdgesPerLine << 1) + 1),
- oversampling (oversampling_)
- {
- table = (int*) juce_calloc ((height << (int)oversampling_)
- * lineStrideElements * sizeof (int));
- }
-
- EdgeTable::EdgeTable (const EdgeTable& other) throw()
- : table (0)
- {
- operator= (other);
- }
-
- const EdgeTable& EdgeTable::operator= (const EdgeTable& other) throw()
- {
- juce_free (table);
-
- top = other.top;
- height = other.height;
- maxEdgesPerLine = other.maxEdgesPerLine;
- lineStrideElements = other.lineStrideElements;
- oversampling = other.oversampling;
-
- const int tableSize = (height << (int)oversampling)
- * lineStrideElements * sizeof (int);
-
- table = (int*) juce_malloc (tableSize);
- memcpy (table, other.table, tableSize);
-
- return *this;
- }
-
- EdgeTable::~EdgeTable() throw()
- {
- juce_free (table);
- }
-
- void EdgeTable::remapTableForNumEdges (const int newNumEdgesPerLine) throw()
- {
- if (newNumEdgesPerLine != maxEdgesPerLine)
- {
- maxEdgesPerLine = newNumEdgesPerLine;
-
- const int newLineStrideElements = maxEdgesPerLine * 2 + 1;
- int* const newTable = (int*) juce_malloc ((height << (int) oversampling)
- * newLineStrideElements * sizeof (int));
-
- for (int i = 0; i < (height << (int) oversampling); ++i)
- {
- const int* srcLine = table + lineStrideElements * i;
- int* dstLine = newTable + newLineStrideElements * i;
-
- int num = *srcLine++;
- *dstLine++ = num;
-
- num <<= 1;
- while (--num >= 0)
- *dstLine++ = *srcLine++;
- }
-
- juce_free (table);
- table = newTable;
- lineStrideElements = newLineStrideElements;
- }
- }
-
- void EdgeTable::optimiseTable() throw()
- {
- int maxLineElements = 0;
-
- for (int i = height; --i >= 0;)
- maxLineElements = jmax (maxLineElements,
- table [i * lineStrideElements]);
-
- remapTableForNumEdges (maxLineElements);
- }
-
- void EdgeTable::addEdgePoint (const int x, const int y, const int winding) throw()
- {
- jassert (y >= 0 && y < (height << oversampling))
-
- int* lineStart = table + lineStrideElements * y;
- int n = lineStart[0];
-
- if (n >= maxEdgesPerLine)
- {
- remapTableForNumEdges (maxEdgesPerLine + juce_edgeTableDefaultEdgesPerLine);
- lineStart = table + lineStrideElements * y;
- }
-
- n <<= 1;
-
- int* const line = lineStart + 1;
-
- while (n > 0)
- {
- const int cx = line [n - 2];
-
- if (cx <= x)
- break;
-
- line [n] = cx;
- line [n + 1] = line [n - 1];
- n -= 2;
- }
-
- line [n] = x;
- line [n + 1] = winding;
-
- lineStart[0]++;
- }
-
- void EdgeTable::addPath (const Path& path,
- const AffineTransform& transform) throw()
- {
- const int windingAmount = 256 / (1 << (int) oversampling);
- const float timesOversampling = (float) (1 << (int) oversampling);
-
- const int bottomLimit = (height << (int) oversampling);
-
- PathFlatteningIterator iter (path, transform);
-
- while (iter.next())
- {
- int y1 = roundFloatToInt (iter.y1 * timesOversampling) - (top << (int) oversampling);
- int y2 = roundFloatToInt (iter.y2 * timesOversampling) - (top << (int) oversampling);
-
- if (y1 != y2)
- {
- const double x1 = 256.0 * iter.x1;
- const double x2 = 256.0 * iter.x2;
-
- const double multiplier = (x2 - x1) / (y2 - y1);
-
- const int oldY1 = y1;
- int winding;
-
- if (y1 > y2)
- {
- swapVariables (y1, y2);
- winding = windingAmount;
- }
- else
- {
- winding = -windingAmount;
- }
-
- jassert (y1 < y2);
-
- if (y1 < 0)
- y1 = 0;
-
- if (y2 > bottomLimit)
- y2 = bottomLimit;
-
- while (y1 < y2)
- {
- addEdgePoint (roundDoubleToInt (x1 + multiplier * (y1 - oldY1)),
- y1,
- winding);
-
- ++y1;
- }
- }
- }
-
- if (! path.isUsingNonZeroWinding())
- {
- // if it's an alternate-winding path, we need to go through and
- // make sure all the windings are alternating.
-
- int* lineStart = table;
-
- for (int i = height << (int) oversampling; --i >= 0;)
- {
- int* line = lineStart;
- lineStart += lineStrideElements;
-
- int num = *line;
-
- while (--num >= 0)
- {
- line += 2;
- *line = abs (*line);
-
- if (--num >= 0)
- {
- line += 2;
- *line = -abs (*line);
- }
- }
- }
- }
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_EdgeTable.cpp *********/
-
- /********* Start of inlined file: juce_Graphics.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- static const Graphics::ResamplingQuality defaultQuality = Graphics::mediumResamplingQuality;
-
- #define MINIMUM_COORD -0x3fffffff
- #define MAXIMUM_COORD 0x3fffffff
-
- #undef ASSERT_COORDS_ARE_SENSIBLE_NUMBERS
- #define ASSERT_COORDS_ARE_SENSIBLE_NUMBERS(x, y, w, h) \
- jassert ((int) x >= MINIMUM_COORD \
- && (int) x <= MAXIMUM_COORD \
- && (int) y >= MINIMUM_COORD \
- && (int) y <= MAXIMUM_COORD \
- && (int) w >= MINIMUM_COORD \
- && (int) w <= MAXIMUM_COORD \
- && (int) h >= MINIMUM_COORD \
- && (int) h <= MAXIMUM_COORD);
-
- LowLevelGraphicsContext::LowLevelGraphicsContext()
- {
- }
-
- LowLevelGraphicsContext::~LowLevelGraphicsContext()
- {
- }
-
- Graphics::Graphics (Image& imageToDrawOnto) throw()
- : context (imageToDrawOnto.createLowLevelContext()),
- ownsContext (true),
- state (new GraphicsState()),
- saveStatePending (false)
- {
- }
-
- Graphics::Graphics (LowLevelGraphicsContext* const internalContext) throw()
- : context (internalContext),
- ownsContext (false),
- state (new GraphicsState()),
- saveStatePending (false)
- {
- }
-
- Graphics::~Graphics() throw()
- {
- delete state;
-
- if (ownsContext)
- delete context;
- }
-
- void Graphics::resetToDefaultState() throw()
- {
- setColour (Colours::black);
- state->font.resetToDefaultState();
- state->quality = defaultQuality;
- }
-
- bool Graphics::isVectorDevice() const throw()
- {
- return context->isVectorDevice();
- }
-
- bool Graphics::reduceClipRegion (const int x, const int y,
- const int w, const int h) throw()
- {
- saveStateIfPending();
- return context->reduceClipRegion (x, y, w, h);
- }
-
- bool Graphics::reduceClipRegion (const RectangleList& clipRegion) throw()
- {
- saveStateIfPending();
- return context->reduceClipRegion (clipRegion);
- }
-
- void Graphics::excludeClipRegion (const int x, const int y,
- const int w, const int h) throw()
- {
- saveStateIfPending();
- context->excludeClipRegion (x, y, w, h);
- }
-
- bool Graphics::isClipEmpty() const throw()
- {
- return context->isClipEmpty();
- }
-
- const Rectangle Graphics::getClipBounds() const throw()
- {
- return context->getClipBounds();
- }
-
- void Graphics::saveState() throw()
- {
- saveStateIfPending();
- saveStatePending = true;
- }
-
- void Graphics::restoreState() throw()
- {
- if (saveStatePending)
- {
- saveStatePending = false;
- }
- else
- {
- const int stackSize = stateStack.size();
-
- if (stackSize > 0)
- {
- context->restoreState();
-
- delete state;
- state = stateStack.getUnchecked (stackSize - 1);
-
- stateStack.removeLast (1, false);
- }
- else
- {
- // Trying to call restoreState() more times than you've called saveState() !
- // Be careful to correctly match each saveState() with exactly one call to restoreState().
- jassertfalse
- }
- }
- }
-
- void Graphics::saveStateIfPending() throw()
- {
- if (saveStatePending)
- {
- saveStatePending = false;
-
- context->saveState();
- stateStack.add (new GraphicsState (*state));
- }
- }
-
- void Graphics::setOrigin (const int newOriginX,
- const int newOriginY) throw()
- {
- saveStateIfPending();
- context->setOrigin (newOriginX, newOriginY);
- }
-
- bool Graphics::clipRegionIntersects (const int x, const int y,
- const int w, const int h) const throw()
- {
- return context->clipRegionIntersects (x, y, w, h);
- }
-
- void Graphics::setColour (const Colour& newColour) throw()
- {
- saveStateIfPending();
- state->colour = newColour;
- deleteAndZero (state->brush);
- }
-
- const Colour& Graphics::getCurrentColour() const throw()
- {
- return state->colour;
- }
-
- void Graphics::setOpacity (const float newOpacity) throw()
- {
- saveStateIfPending();
- state->colour = state->colour.withAlpha (newOpacity);
- }
-
- void Graphics::setBrush (const Brush* const newBrush) throw()
- {
- saveStateIfPending();
- delete state->brush;
-
- if (newBrush != 0)
- state->brush = newBrush->createCopy();
- else
- state->brush = 0;
- }
-
- Graphics::GraphicsState::GraphicsState() throw()
- : colour (Colours::black),
- brush (0),
- quality (defaultQuality)
- {
- }
-
- Graphics::GraphicsState::GraphicsState (const GraphicsState& other) throw()
- : colour (other.colour),
- brush (other.brush != 0 ? other.brush->createCopy() : 0),
- font (other.font),
- quality (other.quality)
- {
- }
-
- Graphics::GraphicsState::~GraphicsState() throw()
- {
- delete brush;
- }
-
- void Graphics::setFont (const Font& newFont) throw()
- {
- saveStateIfPending();
- state->font = newFont;
- }
-
- void Graphics::setFont (const float newFontHeight,
- const int newFontStyleFlags) throw()
- {
- saveStateIfPending();
- state->font.setSizeAndStyle (newFontHeight, newFontStyleFlags, 1.0f, 0.0f);
- }
-
- const Font& Graphics::getCurrentFont() const throw()
- {
- return state->font;
- }
-
- void Graphics::drawSingleLineText (const String& text,
- const int startX,
- const int baselineY) const throw()
- {
- if (text.isNotEmpty()
- && startX < context->getClipBounds().getRight())
- {
- GlyphArrangement arr;
- arr.addLineOfText (state->font, text, (float) startX, (float) baselineY);
- arr.draw (*this);
- }
- }
-
- void Graphics::drawTextAsPath (const String& text,
- const AffineTransform& transform) const throw()
- {
- if (text.isNotEmpty())
- {
- GlyphArrangement arr;
- arr.addLineOfText (state->font, text, 0.0f, 0.0f);
- arr.draw (*this, transform);
- }
- }
-
- void Graphics::drawMultiLineText (const String& text,
- const int startX,
- const int baselineY,
- const int maximumLineWidth) const throw()
- {
- if (text.isNotEmpty()
- && startX < context->getClipBounds().getRight())
- {
- GlyphArrangement arr;
- arr.addJustifiedText (state->font, text,
- (float) startX, (float) baselineY, (float) maximumLineWidth,
- Justification::left);
- arr.draw (*this);
- }
- }
-
- void Graphics::drawText (const String& text,
- const int x,
- const int y,
- const int width,
- const int height,
- const Justification& justificationType,
- const bool useEllipsesIfTooBig) const throw()
- {
- if (text.isNotEmpty() && context->clipRegionIntersects (x, y, width, height))
- {
- GlyphArrangement arr;
-
- arr.addCurtailedLineOfText (state->font, text,
- 0.0f, 0.0f, (float)width,
- useEllipsesIfTooBig);
-
- arr.justifyGlyphs (0, arr.getNumGlyphs(),
- (float) x, (float) y,
- (float) width, (float) height,
- justificationType);
- arr.draw (*this);
- }
- }
-
- void Graphics::drawFittedText (const String& text,
- const int x,
- const int y,
- const int width,
- const int height,
- const Justification& justification,
- const int maximumNumberOfLines,
- const float minimumHorizontalScale) const throw()
- {
- if (text.isNotEmpty()
- && width > 0 && height > 0
- && context->clipRegionIntersects (x, y, width, height))
- {
- GlyphArrangement arr;
-
- arr.addFittedText (state->font, text,
- (float) x, (float) y,
- (float) width, (float) height,
- justification,
- maximumNumberOfLines,
- minimumHorizontalScale);
-
- arr.draw (*this);
- }
- }
-
- void Graphics::fillRect (int x,
- int y,
- int width,
- int height) const throw()
- {
- // passing in a silly number can cause maths problems in rendering!
- ASSERT_COORDS_ARE_SENSIBLE_NUMBERS (x, y, width, height);
-
- SolidColourBrush colourBrush (state->colour);
- (state->brush != 0 ? *(state->brush) : (Brush&) colourBrush).paintRectangle (*context, x, y, width, height);
- }
-
- void Graphics::fillRect (const Rectangle& r) const throw()
- {
- fillRect (r.getX(),
- r.getY(),
- r.getWidth(),
- r.getHeight());
- }
-
- void Graphics::fillRect (const float x,
- const float y,
- const float width,
- const float height) const throw()
- {
- // passing in a silly number can cause maths problems in rendering!
- ASSERT_COORDS_ARE_SENSIBLE_NUMBERS (x, y, width, height);
-
- Path p;
- p.addRectangle (x, y, width, height);
- fillPath (p);
- }
-
- void Graphics::setPixel (int x, int y) const throw()
- {
- if (context->clipRegionIntersects (x, y, 1, 1))
- {
- SolidColourBrush colourBrush (state->colour);
- (state->brush != 0 ? *(state->brush) : (Brush&) colourBrush).paintRectangle (*context, x, y, 1, 1);
- }
- }
-
- void Graphics::fillAll() const throw()
- {
- fillRect (context->getClipBounds());
- }
-
- void Graphics::fillAll (const Colour& colourToUse) const throw()
- {
- if (! colourToUse.isTransparent())
- {
- const Rectangle clip (context->getClipBounds());
-
- context->fillRectWithColour (clip.getX(), clip.getY(), clip.getWidth(), clip.getHeight(),
- colourToUse, false);
- }
- }
-
- void Graphics::fillPath (const Path& path,
- const AffineTransform& transform) const throw()
- {
- if ((! context->isClipEmpty()) && ! path.isEmpty())
- {
- SolidColourBrush colourBrush (state->colour);
- (state->brush != 0 ? *(state->brush) : (Brush&) colourBrush).paintPath (*context, path, transform);
- }
- }
-
- void Graphics::strokePath (const Path& path,
- const PathStrokeType& strokeType,
- const AffineTransform& transform) const throw()
- {
- if (! state->colour.isTransparent())
- {
- Path stroke;
- strokeType.createStrokedPath (stroke, path, transform);
- fillPath (stroke);
- }
- }
-
- void Graphics::drawRect (const int x,
- const int y,
- const int width,
- const int height,
- const int lineThickness) const throw()
- {
- // passing in a silly number can cause maths problems in rendering!
- ASSERT_COORDS_ARE_SENSIBLE_NUMBERS (x, y, width, height);
-
- SolidColourBrush colourBrush (state->colour);
- Brush& b = (state->brush != 0 ? *(state->brush) : (Brush&) colourBrush);
-
- b.paintRectangle (*context, x, y, width, lineThickness);
- b.paintRectangle (*context, x, y + lineThickness, lineThickness, height - lineThickness * 2);
- b.paintRectangle (*context, x + width - lineThickness, y + lineThickness, lineThickness, height - lineThickness * 2);
- b.paintRectangle (*context, x, y + height - lineThickness, width, lineThickness);
- }
-
- void Graphics::drawRect (const float x,
- const float y,
- const float width,
- const float height,
- const float lineThickness) const throw()
- {
- // passing in a silly number can cause maths problems in rendering!
- ASSERT_COORDS_ARE_SENSIBLE_NUMBERS (x, y, width, height);
-
- Path p;
- p.addRectangle (x, y, width, lineThickness);
- p.addRectangle (x, y + lineThickness, lineThickness, height - lineThickness * 2.0f);
- p.addRectangle (x + width - lineThickness, y + lineThickness, lineThickness, height - lineThickness * 2.0f);
- p.addRectangle (x, y + height - lineThickness, width, lineThickness);
- fillPath (p);
- }
-
- void Graphics::drawRect (const Rectangle& r,
- const int lineThickness) const throw()
- {
- drawRect (r.getX(), r.getY(),
- r.getWidth(), r.getHeight(),
- lineThickness);
- }
-
- void Graphics::drawBevel (const int x,
- const int y,
- const int width,
- const int height,
- const int bevelThickness,
- const Colour& topLeftColour,
- const Colour& bottomRightColour,
- const bool useGradient) const throw()
- {
- // passing in a silly number can cause maths problems in rendering!
- ASSERT_COORDS_ARE_SENSIBLE_NUMBERS (x, y, width, height);
-
- if (clipRegionIntersects (x, y, width, height))
- {
- const float oldOpacity = state->colour.getFloatAlpha();
- const float ramp = oldOpacity / bevelThickness;
-
- for (int i = bevelThickness; --i >= 0;)
- {
- const float op = useGradient ? ramp * (bevelThickness - i)
- : oldOpacity;
-
- context->fillRectWithColour (x + i, y + i, width - i * 2, 1, topLeftColour.withMultipliedAlpha (op), false);
- context->fillRectWithColour (x + i, y + i + 1, 1, height - i * 2 - 2, topLeftColour.withMultipliedAlpha (op * 0.75f), false);
- context->fillRectWithColour (x + i, y + height - i - 1, width - i * 2, 1, bottomRightColour.withMultipliedAlpha (op), false);
- context->fillRectWithColour (x + width - i - 1, y + i + 1, 1, height - i * 2 - 2, bottomRightColour.withMultipliedAlpha (op * 0.75f), false);
- }
- }
- }
-
- void Graphics::fillEllipse (const float x,
- const float y,
- const float width,
- const float height) const throw()
- {
- // passing in a silly number can cause maths problems in rendering!
- ASSERT_COORDS_ARE_SENSIBLE_NUMBERS (x, y, width, height);
-
- Path p;
- p.addEllipse (x, y, width, height);
- fillPath (p);
- }
-
- void Graphics::drawEllipse (const float x,
- const float y,
- const float width,
- const float height,
- const float lineThickness) const throw()
- {
- // passing in a silly number can cause maths problems in rendering!
- ASSERT_COORDS_ARE_SENSIBLE_NUMBERS (x, y, width, height);
-
- Path p;
- p.addEllipse (x, y, width, height);
- strokePath (p, PathStrokeType (lineThickness));
- }
-
- void Graphics::fillRoundedRectangle (const float x,
- const float y,
- const float width,
- const float height,
- const float cornerSize) const throw()
- {
- // passing in a silly number can cause maths problems in rendering!
- ASSERT_COORDS_ARE_SENSIBLE_NUMBERS (x, y, width, height);
-
- Path p;
- p.addRoundedRectangle (x, y, width, height, cornerSize);
- fillPath (p);
- }
-
- void Graphics::fillRoundedRectangle (const Rectangle& r,
- const float cornerSize) const throw()
- {
- fillRoundedRectangle ((float) r.getX(),
- (float) r.getY(),
- (float) r.getWidth(),
- (float) r.getHeight(),
- cornerSize);
- }
-
- void Graphics::drawRoundedRectangle (const float x,
- const float y,
- const float width,
- const float height,
- const float cornerSize,
- const float lineThickness) const throw()
- {
- // passing in a silly number can cause maths problems in rendering!
- ASSERT_COORDS_ARE_SENSIBLE_NUMBERS (x, y, width, height);
-
- Path p;
- p.addRoundedRectangle (x, y, width, height, cornerSize);
- strokePath (p, PathStrokeType (lineThickness));
- }
-
- void Graphics::drawRoundedRectangle (const Rectangle& r,
- const float cornerSize,
- const float lineThickness) const throw()
- {
- drawRoundedRectangle ((float) r.getX(),
- (float) r.getY(),
- (float) r.getWidth(),
- (float) r.getHeight(),
- cornerSize, lineThickness);
- }
-
- void Graphics::drawArrow (const float startX,
- const float startY,
- const float endX,
- const float endY,
- const float lineThickness,
- const float arrowheadWidth,
- const float arrowheadLength) const throw()
- {
- Path p;
- p.addArrow (startX, startY, endX, endY,
- lineThickness, arrowheadWidth, arrowheadLength);
- fillPath (p);
- }
-
- void Graphics::fillCheckerBoard (int x, int y,
- int width, int height,
- const int checkWidth,
- const int checkHeight,
- const Colour& colour1,
- const Colour& colour2) const throw()
- {
- jassert (checkWidth > 0 && checkHeight > 0); // can't be zero or less!
-
- if (checkWidth > 0 && checkHeight > 0)
- {
- if (colour1 == colour2)
- {
- context->fillRectWithColour (x, y, width, height, colour1, false);
- }
- else
- {
- const Rectangle clip (context->getClipBounds());
-
- const int right = jmin (x + width, clip.getRight());
- const int bottom = jmin (y + height, clip.getBottom());
-
- int cy = 0;
- while (y < bottom)
- {
- int cx = cy;
-
- for (int xx = x; xx < right; xx += checkWidth)
- context->fillRectWithColour (xx, y,
- jmin (checkWidth, right - xx),
- jmin (checkHeight, bottom - y),
- ((cx++ & 1) == 0) ? colour1 : colour2,
- false);
-
- ++cy;
- y += checkHeight;
- }
- }
- }
- }
-
- void Graphics::drawVerticalLine (const int x, float top, float bottom) const throw()
- {
- SolidColourBrush colourBrush (state->colour);
- (state->brush != 0 ? *(state->brush) : (Brush&) colourBrush).paintVerticalLine (*context, x, top, bottom);
- }
-
- void Graphics::drawHorizontalLine (const int y, float left, float right) const throw()
- {
- SolidColourBrush colourBrush (state->colour);
- (state->brush != 0 ? *(state->brush) : (Brush&) colourBrush).paintHorizontalLine (*context, y, left, right);
- }
-
- void Graphics::drawLine (float x1, float y1,
- float x2, float y2) const throw()
- {
- if (! context->isClipEmpty())
- {
- SolidColourBrush colourBrush (state->colour);
- (state->brush != 0 ? *(state->brush) : (Brush&) colourBrush).paintLine (*context, x1, y1, x2, y2);
- }
- }
-
- void Graphics::drawLine (const float startX,
- const float startY,
- const float endX,
- const float endY,
- const float lineThickness) const throw()
- {
- Path p;
- p.addLineSegment (startX, startY, endX, endY, lineThickness);
- fillPath (p);
- }
-
- void Graphics::drawLine (const Line& line) const throw()
- {
- drawLine (line.getStartX(), line.getStartY(), line.getEndX(), line.getEndY());
- }
-
- void Graphics::drawLine (const Line& line,
- const float lineThickness) const throw()
- {
- drawLine (line.getStartX(), line.getStartY(), line.getEndX(), line.getEndY(), lineThickness);
- }
-
- void Graphics::drawDashedLine (const float startX,
- const float startY,
- const float endX,
- const float endY,
- const float* const dashLengths,
- const int numDashLengths,
- const float lineThickness) const throw()
- {
- const double dx = endX - startX;
- const double dy = endY - startY;
- const double totalLen = juce_hypot (dx, dy);
-
- if (totalLen >= 0.5)
- {
- const double onePixAlpha = 1.0 / totalLen;
-
- double alpha = 0.0;
- float x = startX;
- float y = startY;
- int n = 0;
-
- while (alpha < 1.0f)
- {
- alpha = jmin (1.0, alpha + dashLengths[n++] * onePixAlpha);
- n = n % numDashLengths;
-
- const float oldX = x;
- const float oldY = y;
-
- x = (float) (startX + dx * alpha);
- y = (float) (startY + dy * alpha);
-
- if ((n & 1) != 0)
- {
- if (lineThickness != 1.0f)
- drawLine (oldX, oldY, x, y, lineThickness);
- else
- drawLine (oldX, oldY, x, y);
- }
- }
- }
- }
-
- void Graphics::setImageResamplingQuality (const Graphics::ResamplingQuality newQuality) throw()
- {
- saveStateIfPending();
- state->quality = newQuality;
- }
-
- void Graphics::drawImageAt (const Image* const imageToDraw,
- const int topLeftX,
- const int topLeftY,
- const bool fillAlphaChannelWithCurrentBrush) const throw()
- {
- if (imageToDraw != 0)
- {
- const int imageW = imageToDraw->getWidth();
- const int imageH = imageToDraw->getHeight();
-
- drawImage (imageToDraw,
- topLeftX, topLeftY, imageW, imageH,
- 0, 0, imageW, imageH,
- fillAlphaChannelWithCurrentBrush);
- }
- }
-
- void Graphics::drawImageWithin (const Image* const imageToDraw,
- const int destX,
- const int destY,
- const int destW,
- const int destH,
- const RectanglePlacement& placementWithinTarget,
- const bool fillAlphaChannelWithCurrentBrush) const throw()
- {
- // passing in a silly number can cause maths problems in rendering!
- ASSERT_COORDS_ARE_SENSIBLE_NUMBERS (destX, destY, destW, destH);
-
- if (imageToDraw != 0)
- {
- const int imageW = imageToDraw->getWidth();
- const int imageH = imageToDraw->getHeight();
-
- if (imageW > 0 && imageH > 0)
- {
- double newX = 0.0, newY = 0.0;
- double newW = imageW;
- double newH = imageH;
-
- placementWithinTarget.applyTo (newX, newY, newW, newH,
- destX, destY, destW, destH);
-
- if (newW > 0 && newH > 0)
- {
- drawImage (imageToDraw,
- roundDoubleToInt (newX), roundDoubleToInt (newY),
- roundDoubleToInt (newW), roundDoubleToInt (newH),
- 0, 0, imageW, imageH,
- fillAlphaChannelWithCurrentBrush);
- }
- }
- }
- }
-
- void Graphics::drawImage (const Image* const imageToDraw,
- int dx, int dy, int dw, int dh,
- int sx, int sy, int sw, int sh,
- const bool fillAlphaChannelWithCurrentBrush) const throw()
- {
- // passing in a silly number can cause maths problems in rendering!
- ASSERT_COORDS_ARE_SENSIBLE_NUMBERS (dx, dy, dw, dh);
- ASSERT_COORDS_ARE_SENSIBLE_NUMBERS (sx, sy, sw, sh);
-
- if (imageToDraw == 0 || ! context->clipRegionIntersects (dx, dy, dw, dh))
- return;
-
- if (sw == dw && sh == dh)
- {
- if (sx < 0)
- {
- dx -= sx;
- dw += sx;
- sw += sx;
- sx = 0;
- }
-
- if (sx + sw > imageToDraw->getWidth())
- {
- const int amount = sx + sw - imageToDraw->getWidth();
- dw -= amount;
- sw -= amount;
- }
-
- if (sy < 0)
- {
- dy -= sy;
- dh += sy;
- sh += sy;
- sy = 0;
- }
-
- if (sy + sh > imageToDraw->getHeight())
- {
- const int amount = sy + sh - imageToDraw->getHeight();
- dh -= amount;
- sh -= amount;
- }
-
- if (dw <= 0 || dh <= 0 || sw <= 0 || sh <= 0)
- return;
-
- if (fillAlphaChannelWithCurrentBrush)
- {
- SolidColourBrush colourBrush (state->colour);
- (state->brush != 0 ? *(state->brush) : (Brush&) colourBrush)
- .paintAlphaChannel (*context, *imageToDraw,
- dx - sx, dy - sy,
- dx, dy,
- dw, dh);
- }
- else
- {
- context->blendImage (*imageToDraw,
- dx, dy, dw, dh, sx, sy,
- state->colour.getFloatAlpha());
- }
- }
- else
- {
- if (dw <= 0 || dh <= 0 || sw <= 0 || sh <= 0)
- return;
-
- if (fillAlphaChannelWithCurrentBrush)
- {
- if (imageToDraw->isRGB())
- {
- fillRect (dx, dy, dw, dh);
- }
- else
- {
- int tx = dx;
- int ty = dy;
- int tw = dw;
- int th = dh;
-
- if (context->getClipBounds().intersectRectangle (tx, ty, tw, th))
- {
- Image temp (imageToDraw->getFormat(), tw, th, true);
- Graphics g (temp);
- g.setImageResamplingQuality (state->quality);
- g.setOrigin (dx - tx, dy - ty);
-
- g.drawImage (imageToDraw,
- 0, 0, dw, dh,
- sx, sy, sw, sh,
- false);
-
- SolidColourBrush colourBrush (state->colour);
- (state->brush != 0 ? *(state->brush) : (Brush&) colourBrush)
- .paintAlphaChannel (*context, temp, tx, ty, tx, ty, tw, th);
- }
- }
- }
- else
- {
- context->blendImageRescaling (*imageToDraw,
- dx, dy, dw, dh,
- sx, sy, sw, sh,
- state->colour.getFloatAlpha(),
- state->quality);
- }
- }
- }
-
- void Graphics::drawImageTransformed (const Image* const imageToDraw,
- int sourceClipX,
- int sourceClipY,
- int sourceClipWidth,
- int sourceClipHeight,
- const AffineTransform& transform,
- const bool fillAlphaChannelWithCurrentBrush) const throw()
- {
- if (imageToDraw != 0
- && (! context->isClipEmpty())
- && ! transform.isSingularity())
- {
- if (fillAlphaChannelWithCurrentBrush)
- {
- Path p;
- p.addRectangle ((float) sourceClipX, (float) sourceClipY,
- (float) sourceClipWidth, (float) sourceClipHeight);
-
- p.applyTransform (transform);
-
- float dx, dy, dw, dh;
- p.getBounds (dx, dy, dw, dh);
- int tx = (int) dx;
- int ty = (int) dy;
- int tw = roundFloatToInt (dw) + 2;
- int th = roundFloatToInt (dh) + 2;
-
- if (context->getClipBounds().intersectRectangle (tx, ty, tw, th))
- {
- Image temp (imageToDraw->getFormat(), tw, th, true);
- Graphics g (temp);
- g.setImageResamplingQuality (state->quality);
-
- g.drawImageTransformed (imageToDraw,
- sourceClipX,
- sourceClipY,
- sourceClipWidth,
- sourceClipHeight,
- transform.translated ((float) -tx, (float) -ty),
- false);
-
- SolidColourBrush colourBrush (state->colour);
- (state->brush != 0 ? *(state->brush) : (Brush&) colourBrush).paintAlphaChannel (*context, temp, tx, ty, tx, ty, tw, th);
- }
- }
- else
- {
- context->blendImageWarping (*imageToDraw,
- sourceClipX,
- sourceClipY,
- sourceClipWidth,
- sourceClipHeight,
- transform,
- state->colour.getFloatAlpha(),
- state->quality);
- }
- }
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_Graphics.cpp *********/
-
- /********* Start of inlined file: juce_Justification.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- Justification::Justification (const Justification& other) throw()
- : flags (other.flags)
- {
- }
-
- const Justification& Justification::operator= (const Justification& other) throw()
- {
- flags = other.flags;
- return *this;
- }
-
- int Justification::getOnlyVerticalFlags() const throw()
- {
- return flags & (top | bottom | verticallyCentred);
- }
-
- int Justification::getOnlyHorizontalFlags() const throw()
- {
- return flags & (left | right | horizontallyCentred | horizontallyJustified);
- }
-
- void Justification::applyToRectangle (int& x, int& y,
- const int w, const int h,
- const int spaceX, const int spaceY,
- const int spaceW, const int spaceH) const throw()
- {
- if ((flags & horizontallyCentred) != 0)
- {
- x = spaceX + ((spaceW - w) >> 1);
- }
- else if ((flags & right) != 0)
- {
- x = spaceX + spaceW - w;
- }
- else
- {
- x = spaceX;
- }
-
- if ((flags & verticallyCentred) != 0)
- {
- y = spaceY + ((spaceH - h) >> 1);
- }
- else if ((flags & bottom) != 0)
- {
- y = spaceY + spaceH - h;
- }
- else
- {
- y = spaceY;
- }
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_Justification.cpp *********/
-
- /********* Start of inlined file: juce_LowLevelGraphicsPostScriptRenderer.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- #if JUCE_MSVC
- #pragma warning (disable: 4996) // deprecated sprintf warning
- #endif
-
- // this will throw an assertion if you try to draw something that's not
- // possible in postscript
- #define WARN_ABOUT_NON_POSTSCRIPT_OPERATIONS 0
-
- #if defined (JUCE_DEBUG) && WARN_ABOUT_NON_POSTSCRIPT_OPERATIONS
- #define notPossibleInPostscriptAssert jassertfalse
- #else
- #define notPossibleInPostscriptAssert
- #endif
-
- LowLevelGraphicsPostScriptRenderer::LowLevelGraphicsPostScriptRenderer (OutputStream& resultingPostScript,
- const String& documentTitle,
- const int totalWidth_,
- const int totalHeight_)
- : out (resultingPostScript),
- totalWidth (totalWidth_),
- totalHeight (totalHeight_),
- xOffset (0),
- yOffset (0),
- needToClip (true)
- {
- clip = new RectangleList (Rectangle (0, 0, totalWidth_, totalHeight_));
-
- const float scale = jmin ((520.0f / totalWidth_), (750.0f / totalHeight));
-
- out << "%!PS-Adobe-3.0 EPSF-3.0"
- "\n%%BoundingBox: 0 0 600 824"
- "\n%%Pages: 0"
- "\n%%Creator: Raw Material Software JUCE"
- "\n%%Title: " << documentTitle <<
- "\n%%CreationDate: none"
- "\n%%LanguageLevel: 2"
- "\n%%EndComments"
- "\n%%BeginProlog"
- "\n%%BeginResource: JRes"
- "\n/bd {bind def} bind def"
- "\n/c {setrgbcolor} bd"
- "\n/m {moveto} bd"
- "\n/l {lineto} bd"
- "\n/rl {rlineto} bd"
- "\n/ct {curveto} bd"
- "\n/cp {closepath} bd"
- "\n/pr {3 index 3 index moveto 1 index 0 rlineto 0 1 index rlineto pop neg 0 rlineto pop pop closepath} bd"
- "\n/doclip {initclip newpath} bd"
- "\n/endclip {clip newpath} bd"
- "\n%%EndResource"
- "\n%%EndProlog"
- "\n%%BeginSetup"
- "\n%%EndSetup"
- "\n%%Page: 1 1"
- "\n%%BeginPageSetup"
- "\n%%EndPageSetup\n\n"
- << "40 800 translate\n"
- << scale << ' ' << scale << " scale\n\n";
- }
-
- LowLevelGraphicsPostScriptRenderer::~LowLevelGraphicsPostScriptRenderer()
- {
- delete clip;
- }
-
- bool LowLevelGraphicsPostScriptRenderer::isVectorDevice() const
- {
- return true;
- }
-
- void LowLevelGraphicsPostScriptRenderer::setOrigin (int x, int y)
- {
- if (x != 0 || y != 0)
- {
- xOffset += x;
- yOffset += y;
- needToClip = true;
- }
- }
-
- bool LowLevelGraphicsPostScriptRenderer::reduceClipRegion (int x, int y, int w, int h)
- {
- needToClip = true;
- return clip->clipTo (Rectangle (x + xOffset, y + yOffset, w, h));
- }
-
- bool LowLevelGraphicsPostScriptRenderer::reduceClipRegion (const RectangleList& clipRegion)
- {
- needToClip = true;
- return clip->clipTo (clipRegion);
- }
-
- void LowLevelGraphicsPostScriptRenderer::excludeClipRegion (int x, int y, int w, int h)
- {
- needToClip = true;
- clip->subtract (Rectangle (x + xOffset, y + yOffset, w, h));
- }
-
- bool LowLevelGraphicsPostScriptRenderer::clipRegionIntersects (int x, int y, int w, int h)
- {
- return clip->intersectsRectangle (Rectangle (x + xOffset, y + yOffset, w, h));
- }
-
- const Rectangle LowLevelGraphicsPostScriptRenderer::getClipBounds() const
- {
- return clip->getBounds().translated (-xOffset, -yOffset);
- }
-
- bool LowLevelGraphicsPostScriptRenderer::isClipEmpty() const
- {
- return clip->isEmpty();
- }
-
- LowLevelGraphicsPostScriptRenderer::SavedState::SavedState (RectangleList* const clip_,
- const int xOffset_, const int yOffset_)
- : clip (clip_),
- xOffset (xOffset_),
- yOffset (yOffset_)
- {
- }
-
- LowLevelGraphicsPostScriptRenderer::SavedState::~SavedState()
- {
- delete clip;
- }
-
- void LowLevelGraphicsPostScriptRenderer::saveState()
- {
- stateStack.add (new SavedState (new RectangleList (*clip), xOffset, yOffset));
- }
-
- void LowLevelGraphicsPostScriptRenderer::restoreState()
- {
- SavedState* const top = stateStack.getLast();
-
- if (top != 0)
- {
- clip->swapWith (*top->clip);
-
- xOffset = top->xOffset;
- yOffset = top->yOffset;
-
- stateStack.removeLast();
-
- needToClip = true;
- }
- else
- {
- jassertfalse // trying to pop with an empty stack!
- }
- }
-
- void LowLevelGraphicsPostScriptRenderer::writeClip()
- {
- if (needToClip)
- {
- needToClip = false;
-
- out << "doclip ";
-
- int itemsOnLine = 0;
-
- for (RectangleList::Iterator i (*clip); i.next();)
- {
- if (++itemsOnLine == 6)
- {
- itemsOnLine = 0;
- out << '\n';
- }
-
- const Rectangle& r = *i.getRectangle();
-
- out << r.getX() << ' ' << -r.getY() << ' '
- << r.getWidth() << ' ' << -r.getHeight() << " pr ";
- }
-
- out << "endclip\n";
- }
- }
-
- void LowLevelGraphicsPostScriptRenderer::writeColour (const Colour& colour)
- {
- Colour c (Colours::white.overlaidWith (colour));
-
- if (lastColour != c)
- {
- lastColour = c;
-
- out << String (c.getFloatRed(), 3) << ' '
- << String (c.getFloatGreen(), 3) << ' '
- << String (c.getFloatBlue(), 3) << " c\n";
- }
- }
-
- void LowLevelGraphicsPostScriptRenderer::writeXY (const float x, const float y) const
- {
- out << String (x, 2) << ' '
- << String (-y, 2) << ' ';
- }
-
- void LowLevelGraphicsPostScriptRenderer::writePath (const Path& path) const
- {
- out << "newpath ";
-
- float lastX = 0.0f;
- float lastY = 0.0f;
- int itemsOnLine = 0;
-
- Path::Iterator i (path);
-
- while (i.next())
- {
- if (++itemsOnLine == 4)
- {
- itemsOnLine = 0;
- out << '\n';
- }
-
- switch (i.elementType)
- {
- case Path::Iterator::startNewSubPath:
- writeXY (i.x1, i.y1);
- lastX = i.x1;
- lastY = i.y1;
- out << "m ";
- break;
-
- case Path::Iterator::lineTo:
- writeXY (i.x1, i.y1);
- lastX = i.x1;
- lastY = i.y1;
- out << "l ";
- break;
-
- case Path::Iterator::quadraticTo:
- {
- const float cp1x = lastX + (i.x1 - lastX) * 2.0f / 3.0f;
- const float cp1y = lastY + (i.y1 - lastY) * 2.0f / 3.0f;
- const float cp2x = cp1x + (i.x2 - lastX) / 3.0f;
- const float cp2y = cp1y + (i.y2 - lastY) / 3.0f;
-
- writeXY (cp1x, cp1y);
- writeXY (cp2x, cp2y);
- writeXY (i.x2, i.y2);
- out << "ct ";
- lastX = i.x2;
- lastY = i.y2;
- }
- break;
-
- case Path::Iterator::cubicTo:
- writeXY (i.x1, i.y1);
- writeXY (i.x2, i.y2);
- writeXY (i.x3, i.y3);
- out << "ct ";
- lastX = i.x3;
- lastY = i.y3;
- break;
-
- case Path::Iterator::closePath:
- out << "cp ";
- break;
-
- default:
- jassertfalse
- break;
- }
- }
-
- out << '\n';
- }
-
- void LowLevelGraphicsPostScriptRenderer::writeTransform (const AffineTransform& trans) const
- {
- out << "[ "
- << trans.mat00 << ' '
- << trans.mat10 << ' '
- << trans.mat01 << ' '
- << trans.mat11 << ' '
- << trans.mat02 << ' '
- << trans.mat12 << " ] concat ";
- }
-
- void LowLevelGraphicsPostScriptRenderer::fillRectWithColour (int x, int y, int w, int h, const Colour& colour, const bool /*replaceExistingContents*/)
- {
- writeClip();
- writeColour (colour);
-
- x += xOffset;
- y += yOffset;
-
- out << x << ' ' << -(y + h) << ' ' << w << ' ' << h << " rectfill\n";
- }
-
- void LowLevelGraphicsPostScriptRenderer::fillRectWithGradient (int x, int y, int w, int h, const ColourGradient& gradient)
- {
- Path p;
- p.addRectangle ((float) x, (float) y, (float) w, (float) h);
-
- fillPathWithGradient (p, AffineTransform::identity, gradient, EdgeTable::Oversampling_256times);
- }
-
- void LowLevelGraphicsPostScriptRenderer::fillPathWithColour (const Path& path, const AffineTransform& t,
- const Colour& colour, EdgeTable::OversamplingLevel /*quality*/)
- {
- writeClip();
-
- Path p (path);
- p.applyTransform (t.translated ((float) xOffset, (float) yOffset));
- writePath (p);
-
- writeColour (colour);
-
- out << "fill\n";
- }
-
- void LowLevelGraphicsPostScriptRenderer::fillPathWithGradient (const Path& path, const AffineTransform& t, const ColourGradient& gradient, EdgeTable::OversamplingLevel /*quality*/)
- {
- // this doesn't work correctly yet - it could be improved to handle solid gradients, but
- // postscript can't do semi-transparent ones.
- notPossibleInPostscriptAssert // you can disable this warning by setting the WARN_ABOUT_NON_POSTSCRIPT_OPERATIONS flag at the top of this file
-
- writeClip();
- out << "gsave ";
-
- {
- Path p (path);
- p.applyTransform (t.translated ((float) xOffset, (float) yOffset));
- writePath (p);
- out << "clip\n";
- }
-
- int numColours = 256;
- PixelARGB* const colours = gradient.createLookupTable (numColours);
-
- for (int i = numColours; --i >= 0;)
- colours[i].unpremultiply();
-
- const Rectangle bounds (clip->getBounds());
-
- // ideally this would draw lots of lines or ellipses to approximate the gradient, but for the
- // time-being, this just fills it with the average colour..
- writeColour (Colour (colours [numColours / 2].getARGB()));
- out << bounds.getX() << ' ' << -bounds.getBottom() << ' ' << bounds.getWidth() << ' ' << bounds.getHeight() << " rectfill\n";
-
- juce_free (colours);
- out << "grestore\n";
- }
-
- void LowLevelGraphicsPostScriptRenderer::fillPathWithImage (const Path& path, const AffineTransform& transform,
- const Image& sourceImage,
- int imageX, int imageY,
- float opacity, EdgeTable::OversamplingLevel /*quality*/)
- {
- writeClip();
-
- out << "gsave ";
- Path p (path);
- p.applyTransform (transform.translated ((float) xOffset, (float) yOffset));
- writePath (p);
- out << "clip\n";
-
- blendImage (sourceImage, imageX, imageY, sourceImage.getWidth(), sourceImage.getHeight(), 0, 0, opacity);
-
- out << "grestore\n";
- }
-
- void LowLevelGraphicsPostScriptRenderer::fillAlphaChannelWithColour (const Image& /*clipImage*/, int x, int y, const Colour& colour)
- {
- x += xOffset;
- y += yOffset;
-
- writeClip();
- writeColour (colour);
-
- notPossibleInPostscriptAssert // you can disable this warning by setting the WARN_ABOUT_NON_POSTSCRIPT_OPERATIONS flag at the top of this file
- }
-
- void LowLevelGraphicsPostScriptRenderer::fillAlphaChannelWithGradient (const Image& /*alphaChannelImage*/, int imageX, int imageY, const ColourGradient& /*gradient*/)
- {
- imageX += xOffset;
- imageY += yOffset;
-
- writeClip();
-
- notPossibleInPostscriptAssert // you can disable this warning by setting the WARN_ABOUT_NON_POSTSCRIPT_OPERATIONS flag at the top of this file
- }
-
- void LowLevelGraphicsPostScriptRenderer::fillAlphaChannelWithImage (const Image& /*alphaImage*/, int alphaImageX, int alphaImageY,
- const Image& /*fillerImage*/, int fillerImageX, int fillerImageY, float /*opacity*/)
- {
- alphaImageX += xOffset;
- alphaImageY += yOffset;
-
- fillerImageX += xOffset;
- fillerImageY += yOffset;
-
- writeClip();
-
- notPossibleInPostscriptAssert // you can disable this warning by setting the WARN_ABOUT_NON_POSTSCRIPT_OPERATIONS flag at the top of this file
- }
-
- void LowLevelGraphicsPostScriptRenderer::blendImageRescaling (const Image& sourceImage,
- int dx, int dy, int dw, int dh,
- int sx, int sy, int sw, int sh,
- float alpha,
- const Graphics::ResamplingQuality quality)
- {
- if (sw > 0 && sh > 0)
- {
- jassert (sx >= 0 && sx + sw <= sourceImage.getWidth());
- jassert (sy >= 0 && sy + sh <= sourceImage.getHeight());
-
- if (sw == dw && sh == dh)
- {
- blendImage (sourceImage,
- dx, dy, dw, dh,
- sx, sy, alpha);
- }
- else
- {
- blendImageWarping (sourceImage,
- sx, sy, sw, sh,
- AffineTransform::scale (dw / (float) sw,
- dh / (float) sh)
- .translated ((float) (dx - sx),
- (float) (dy - sy)),
- alpha,
- quality);
- }
- }
- }
-
- void LowLevelGraphicsPostScriptRenderer::blendImage (const Image& sourceImage, int dx, int dy, int dw, int dh, int sx, int sy, float opacity)
- {
- blendImageWarping (sourceImage,
- sx, sy, dw, dh,
- AffineTransform::translation ((float) dx, (float) dy),
- opacity, Graphics::highResamplingQuality);
- }
-
- void LowLevelGraphicsPostScriptRenderer::writeImage (const Image& im,
- const int sx, const int sy,
- const int maxW, const int maxH) const
- {
- out << "{<\n";
-
- const int w = jmin (maxW, im.getWidth());
- const int h = jmin (maxH, im.getHeight());
-
- int charsOnLine = 0;
- int lineStride, pixelStride;
- const uint8* data = im.lockPixelDataReadOnly (0, 0, w, h, lineStride, pixelStride);
-
- Colour pixel;
-
- for (int y = h; --y >= 0;)
- {
- for (int x = 0; x < w; ++x)
- {
- const uint8* pixelData = data + lineStride * y + pixelStride * x;
-
- if (x >= sx && y >= sy)
- {
- if (im.isARGB())
- {
- PixelARGB p (*(const PixelARGB*) pixelData);
- p.unpremultiply();
- pixel = Colours::white.overlaidWith (Colour (p.getARGB()));
- }
- else if (im.isRGB())
- {
- pixel = Colour (((const PixelRGB*) pixelData)->getARGB());
- }
- else
- {
- pixel = Colour ((uint8) 0, (uint8) 0, (uint8) 0, *pixelData);
- }
- }
- else
- {
- pixel = Colours::transparentWhite;
- }
-
- char colourString [16];
- sprintf (colourString, "%x%x%x", pixel.getRed(), pixel.getGreen(), pixel.getBlue());
-
- out << (const char*) colourString;
- charsOnLine += 3;
-
- if (charsOnLine > 100)
- {
- out << '\n';
- charsOnLine = 0;
- }
- }
- }
-
- im.releasePixelDataReadOnly (data);
-
- out << "\n>}\n";
- }
-
- void LowLevelGraphicsPostScriptRenderer::blendImageWarping (const Image& sourceImage,
- int srcClipX, int srcClipY,
- int srcClipW, int srcClipH,
- const AffineTransform& t,
- float /*opacity*/,
- const Graphics::ResamplingQuality /*quality*/)
- {
- const int w = jmin (sourceImage.getWidth(), srcClipX + srcClipW);
- const int h = jmin (sourceImage.getHeight(), srcClipY + srcClipH);
-
- writeClip();
-
- out << "gsave ";
- writeTransform (t.translated ((float) xOffset, (float) yOffset)
- .scaled (1.0f, -1.0f));
-
- RectangleList imageClip;
- sourceImage.createSolidAreaMask (imageClip, 0.5f);
- imageClip.clipTo (Rectangle (srcClipX, srcClipY, srcClipW, srcClipH));
-
- out << "newpath ";
- int itemsOnLine = 0;
-
- for (RectangleList::Iterator i (imageClip); i.next();)
- {
- if (++itemsOnLine == 6)
- {
- out << '\n';
- itemsOnLine = 0;
- }
-
- const Rectangle& r = *i.getRectangle();
-
- out << r.getX() << ' ' << r.getY() << ' ' << r.getWidth() << ' ' << r.getHeight() << " pr ";
- }
-
- out << " clip newpath\n";
-
- out << w << ' ' << h << " scale\n";
- out << w << ' ' << h << " 8 [" << w << " 0 0 -" << h << ' ' << (int) 0 << ' ' << h << " ]\n";
-
- writeImage (sourceImage, srcClipX, srcClipY, srcClipW, srcClipH);
-
- out << "false 3 colorimage grestore\n";
- needToClip = true;
- }
-
- void LowLevelGraphicsPostScriptRenderer::drawLine (double x1, double y1, double x2, double y2, const Colour& colour)
- {
- Path p;
- p.addLineSegment ((float) x1, (float) y1, (float) x2, (float) y2, 1.0f);
-
- fillPathWithColour (p, AffineTransform::identity, colour, EdgeTable::Oversampling_256times);
- }
-
- void LowLevelGraphicsPostScriptRenderer::drawVerticalLine (const int x, double top, double bottom, const Colour& col)
- {
- drawLine (x, top, x, bottom, col);
- }
-
- void LowLevelGraphicsPostScriptRenderer::drawHorizontalLine (const int y, double left, double right, const Colour& col)
- {
- drawLine (left, y, right, y, col);
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_LowLevelGraphicsPostScriptRenderer.cpp *********/
-
- /********* Start of inlined file: juce_LowLevelGraphicsSoftwareRenderer.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- #if ! (defined (JUCE_MAC) || (defined (JUCE_WIN32) && defined (JUCE_64BIT)))
- #define JUCE_USE_SSE_INSTRUCTIONS 1
- #endif
-
- #if defined (JUCE_DEBUG) && JUCE_MSVC
- #pragma warning (disable: 4714)
- #endif
-
- #define MINIMUM_COORD -0x3fffffff
- #define MAXIMUM_COORD 0x3fffffff
-
- #undef ASSERT_COORDS_ARE_SENSIBLE_NUMBERS
- #define ASSERT_COORDS_ARE_SENSIBLE_NUMBERS(x, y, w, h) \
- jassert ((int) x >= MINIMUM_COORD \
- && (int) x <= MAXIMUM_COORD \
- && (int) y >= MINIMUM_COORD \
- && (int) y <= MAXIMUM_COORD \
- && (int) w >= 0 \
- && (int) w < MAXIMUM_COORD \
- && (int) h >= 0 \
- && (int) h < MAXIMUM_COORD);
-
- static void replaceRectRGB (uint8* pixels, const int w, int h, const int stride, const Colour& colour) throw()
- {
- const PixelARGB blendColour (colour.getPixelARGB());
-
- if (w < 32)
- {
- while (--h >= 0)
- {
- PixelRGB* dest = (PixelRGB*) pixels;
-
- for (int i = w; --i >= 0;)
- (dest++)->set (blendColour);
-
- pixels += stride;
- }
- }
- else
- {
- // for wider fills, it's worth using some optimisations..
-
- const uint8 r = blendColour.getRed();
- const uint8 g = blendColour.getGreen();
- const uint8 b = blendColour.getBlue();
-
- if (r == g && r == b) // if all the component values are the same, we can cheat..
- {
- while (--h >= 0)
- {
- memset (pixels, r, w * 3);
- pixels += stride;
- }
- }
- else
- {
- PixelRGB filler [4];
- filler[0].set (blendColour);
- filler[1].set (blendColour);
- filler[2].set (blendColour);
- filler[3].set (blendColour);
- const int* const intFiller = (const int*) filler;
-
- while (--h >= 0)
- {
- uint8* dest = (uint8*) pixels;
-
- int i = w;
-
- while ((i > 8) && (((pointer_sized_int) dest & 7) != 0))
- {
- ((PixelRGB*) dest)->set (blendColour);
- dest += 3;
- --i;
- }
-
- while (i >= 4)
- {
- ((int*) dest) [0] = intFiller[0];
- ((int*) dest) [1] = intFiller[1];
- ((int*) dest) [2] = intFiller[2];
-
- dest += 12;
- i -= 4;
- }
-
- while (--i >= 0)
- {
- ((PixelRGB*) dest)->set (blendColour);
- dest += 3;
- }
-
- pixels += stride;
- }
- }
- }
- }
-
- static void replaceRectARGB (uint8* pixels, const int w, int h, const int stride, const Colour& colour) throw()
- {
- const PixelARGB blendColour (colour.getPixelARGB());
-
- while (--h >= 0)
- {
- PixelARGB* const dest = (PixelARGB*) pixels;
-
- for (int i = 0; i < w; ++i)
- dest[i] = blendColour;
-
- pixels += stride;
- }
- }
-
- static void blendRectRGB (uint8* pixels, const int w, int h, const int stride, const Colour& colour) throw()
- {
- if (colour.isOpaque())
- {
- replaceRectRGB (pixels, w, h, stride, colour);
- }
- else
- {
- const PixelARGB blendColour (colour.getPixelARGB());
- const int alpha = blendColour.getAlpha();
-
- if (alpha <= 0)
- return;
-
- #if defined (JUCE_USE_SSE_INSTRUCTIONS) && ! JUCE_64BIT
- if (SystemStats::hasSSE())
- {
- int64 rgb0 = (((int64) blendColour.getRed()) << 32)
- | (int64) ((blendColour.getGreen() << 16)
- | blendColour.getBlue());
-
- const int invAlpha = 0xff - alpha;
- int64 aaaa = (invAlpha << 16) | invAlpha;
- aaaa = (aaaa << 16) | aaaa;
-
- #ifndef JUCE_GCC
- __asm
- {
- movq mm1, aaaa
- movq mm2, rgb0
- pxor mm7, mm7
- }
-
- while (--h >= 0)
- {
- __asm
- {
- mov edx, pixels
- mov ebx, w
-
- pixloop:
- prefetchnta [edx]
- mov ax, [edx + 1]
- shl eax, 8
- mov al, [edx]
- movd mm0, eax
-
- punpcklbw mm0, mm7
- pmullw mm0, mm1
- psrlw mm0, 8
- paddw mm0, mm2
- packuswb mm0, mm7
-
- movd eax, mm0
- mov [edx], al
- inc edx
- shr eax, 8
- mov [edx], ax
- add edx, 2
-
- dec ebx
- jg pixloop
- }
-
- pixels += stride;
- }
-
- __asm emms
- #else
- __asm__ __volatile__ (
- "movq %[aaaa], %%mm1 \n"
- "\tmovq %[rgb0], %%mm2 \n"
- "\tpxor %%mm7, %%mm7 \n"
- ".lineLoop2: \n"
- "\tmovl %%esi,%%edx \n"
- "\tmovl %[w], %%ebx \n"
- ".pixLoop2: \n"
- "\tprefetchnta (%%edx) \n"
- "\tmov (%%edx), %%ax \n"
- "\tshl $8, %%eax \n"
- "\tmov 2(%%edx), %%al \n"
- "\tmovd %%eax, %%mm0 \n"
- "\tpunpcklbw %%mm7, %%mm0 \n"
- "\tpmullw %%mm1, %%mm0 \n"
- "\tpsrlw $8, %%mm0 \n"
- "\tpaddw %%mm2, %%mm0 \n"
- "\tpackuswb %%mm7, %%mm0 \n"
- "\tmovd %%mm0, %%eax \n"
- "\tmovb %%al, (%%edx) \n"
- "\tinc %%edx \n"
- "\tshr $8, %%eax \n"
- "\tmovw %%ax, (%%edx) \n"
- "\tadd $2, %%edx \n"
- "\tdec %%ebx \n"
- "\tjg .pixLoop2 \n"
- "\tadd %%edi, %%esi \n"
- "\tdec %%ecx \n"
- "\tjg .lineLoop2 \n"
- "\temms \n"
- : /* No output registers */
- : [aaaa] "m" (aaaa), /* Input registers */
- [rgb0] "m" (rgb0),
- [w] "m" (w),
- "c" (h),
- [stride] "D" (stride),
- [pixels] "S" (pixels)
- : "cc", "eax", "edx", "memory" /* Clobber list */
- );
- #endif
- }
- else
- #endif
- {
- while (--h >= 0)
- {
- PixelRGB* dest = (PixelRGB*) pixels;
-
- for (int i = w; --i >= 0;)
- (dest++)->blend (blendColour);
-
- pixels += stride;
- }
- }
- }
- }
-
- static void blendRectARGB (uint8* pixels, const int w, int h, const int stride, const Colour& colour) throw()
- {
- if (colour.isOpaque())
- {
- replaceRectARGB (pixels, w, h, stride, colour);
- }
- else
- {
- const PixelARGB blendColour (colour.getPixelARGB());
- const int alpha = blendColour.getAlpha();
-
- if (alpha <= 0)
- return;
-
- while (--h >= 0)
- {
- PixelARGB* dest = (PixelARGB*) pixels;
-
- for (int i = w; --i >= 0;)
- (dest++)->blend (blendColour);
-
- pixels += stride;
- }
- }
- }
-
- static void blendAlphaMapARGB (uint8* destPixel, const int imageStride,
- const uint8* alphaValues, const int w, int h,
- const int pixelStride, const int lineStride,
- const Colour& colour) throw()
- {
- const PixelARGB srcPix (colour.getPixelARGB());
-
- while (--h >= 0)
- {
- PixelARGB* dest = (PixelARGB*) destPixel;
- const uint8* src = alphaValues;
-
- int i = w;
- while (--i >= 0)
- {
- unsigned int srcAlpha = *src;
- src += pixelStride;
-
- if (srcAlpha > 0)
- dest->blend (srcPix, srcAlpha);
-
- ++dest;
- }
-
- alphaValues += lineStride;
- destPixel += imageStride;
- }
- }
-
- static void blendAlphaMapRGB (uint8* destPixel, const int imageStride,
- const uint8* alphaValues, int const width, int height,
- const int pixelStride, const int lineStride,
- const Colour& colour) throw()
- {
- const PixelARGB srcPix (colour.getPixelARGB());
-
- while (--height >= 0)
- {
- PixelRGB* dest = (PixelRGB*) destPixel;
- const uint8* src = alphaValues;
-
- int i = width;
- while (--i >= 0)
- {
- unsigned int srcAlpha = *src;
- src += pixelStride;
-
- if (srcAlpha > 0)
- dest->blend (srcPix, srcAlpha);
-
- ++dest;
- }
-
- alphaValues += lineStride;
- destPixel += imageStride;
- }
- }
-
- template <class PixelType>
- class SolidColourEdgeTableRenderer
- {
- uint8* const data;
- const int stride;
- PixelType* linePixels;
- PixelARGB sourceColour;
-
- SolidColourEdgeTableRenderer (const SolidColourEdgeTableRenderer&);
- const SolidColourEdgeTableRenderer& operator= (const SolidColourEdgeTableRenderer&);
-
- public:
- SolidColourEdgeTableRenderer (uint8* const data_,
- const int stride_,
- const Colour& colour) throw()
- : data (data_),
- stride (stride_),
- sourceColour (colour.getPixelARGB())
- {
- }
-
- forcedinline void setEdgeTableYPos (const int y) throw()
- {
- linePixels = (PixelType*) (data + stride * y);
- }
-
- forcedinline void handleEdgeTablePixel (const int x, const int alphaLevel) const throw()
- {
- linePixels[x].blend (sourceColour, alphaLevel);
- }
-
- forcedinline void handleEdgeTableLine (const int x, int width, const int alphaLevel) const throw()
- {
- PixelARGB p (sourceColour);
- p.multiplyAlpha (alphaLevel);
-
- PixelType* dest = linePixels + x;
-
- if (p.getAlpha() < 0xff)
- {
- do
- {
- dest->blend (p);
- ++dest;
-
- } while (--width > 0);
- }
- else
- {
- do
- {
- dest->set (p);
- ++dest;
-
- } while (--width > 0);
- }
- }
- };
-
- class AlphaBitmapRenderer
- {
- uint8* data;
- int stride;
- uint8* lineStart;
-
- AlphaBitmapRenderer (const AlphaBitmapRenderer&);
- const AlphaBitmapRenderer& operator= (const AlphaBitmapRenderer&);
-
- public:
- AlphaBitmapRenderer (uint8* const data_,
- const int stride_) throw()
- : data (data_),
- stride (stride_)
- {
- }
-
- forcedinline void setEdgeTableYPos (const int y) throw()
- {
- lineStart = data + (stride * y);
- }
-
- forcedinline void handleEdgeTablePixel (const int x, const int alphaLevel) const throw()
- {
- lineStart [x] = (uint8) alphaLevel;
- }
-
- forcedinline void handleEdgeTableLine (const int x, int width, const int alphaLevel) const throw()
- {
- uint8* d = lineStart + x;
-
- while (--width >= 0)
- *d++ = (uint8) alphaLevel;
- }
- };
-
- static const int numScaleBits = 12;
-
- class LinearGradientPixelGenerator
- {
- const PixelARGB* const lookupTable;
- const int numEntries;
- PixelARGB linePix;
- int start, scale;
- double grad, yTerm;
- bool vertical, horizontal;
-
- LinearGradientPixelGenerator (const LinearGradientPixelGenerator&);
- const LinearGradientPixelGenerator& operator= (const LinearGradientPixelGenerator&);
-
- public:
- LinearGradientPixelGenerator (const ColourGradient& gradient,
- const PixelARGB* const lookupTable_, const int numEntries_)
- : lookupTable (lookupTable_),
- numEntries (numEntries_)
- {
- jassert (numEntries_ >= 0);
- float x1 = gradient.x1;
- float y1 = gradient.y1;
- float x2 = gradient.x2;
- float y2 = gradient.y2;
-
- if (! gradient.transform.isIdentity())
- {
- Line l (x2, y2, x1, y1);
- const Point p3 = l.getPointAlongLine (0.0, 100.0f);
- float x3 = p3.getX();
- float y3 = p3.getY();
-
- gradient.transform.transformPoint (x1, y1);
- gradient.transform.transformPoint (x2, y2);
- gradient.transform.transformPoint (x3, y3);
-
- Line l2 (x2, y2, x3, y3);
- float prop = l2.findNearestPointTo (x1, y1);
- const Point newP2 (l2.getPointAlongLineProportionally (prop));
-
- x2 = newP2.getX();
- y2 = newP2.getY();
- }
-
- vertical = fabs (x1 - x2) < 0.001f;
- horizontal = fabs (y1 - y2) < 0.001f;
-
- if (vertical)
- {
- scale = roundDoubleToInt ((numEntries << numScaleBits) / (double) (y2 - y1));
- start = roundDoubleToInt (y1 * scale);
- }
- else if (horizontal)
- {
- scale = roundDoubleToInt ((numEntries << numScaleBits) / (double) (x2 - x1));
- start = roundDoubleToInt (x1 * scale);
- }
- else
- {
- grad = (y2 - y1) / (double) (x1 - x2);
- yTerm = y1 - x1 / grad;
- scale = roundDoubleToInt ((numEntries << numScaleBits) / (yTerm * grad - (y2 * grad - x2)));
- grad *= scale;
- }
- }
-
- forcedinline void setY (const int y) throw()
- {
- if (vertical)
- linePix = lookupTable [jlimit (0, numEntries, (y * scale - start) >> numScaleBits)];
- else if (! horizontal)
- start = roundDoubleToInt ((y - yTerm) * grad);
- }
-
- forcedinline const PixelARGB getPixel (const int x) const throw()
- {
- if (vertical)
- return linePix;
-
- return lookupTable [jlimit (0, numEntries, (x * scale - start) >> numScaleBits)];
- }
- };
-
- class RadialGradientPixelGenerator
- {
- protected:
- const PixelARGB* const lookupTable;
- const int numEntries;
- const double gx1, gy1;
- double maxDist, invScale;
- double dy;
-
- RadialGradientPixelGenerator (const RadialGradientPixelGenerator&);
- const RadialGradientPixelGenerator& operator= (const RadialGradientPixelGenerator&);
-
- public:
- RadialGradientPixelGenerator (const ColourGradient& gradient,
- const PixelARGB* const lookupTable_, const int numEntries_) throw()
- : lookupTable (lookupTable_),
- numEntries (numEntries_),
- gx1 (gradient.x1),
- gy1 (gradient.y1)
- {
- jassert (numEntries_ >= 0);
- const float dx = gradient.x1 - gradient.x2;
- const float dy = gradient.y1 - gradient.y2;
- maxDist = dx * dx + dy * dy;
- invScale = (numEntries + 1) / sqrt (maxDist);
- }
-
- forcedinline void setY (const int y) throw()
- {
- dy = y - gy1;
- dy *= dy;
- }
-
- forcedinline const PixelARGB getPixel (const int px) const throw()
- {
- double x = px - gx1;
- x *= x;
- x += dy;
-
- if (x >= maxDist)
- return lookupTable [numEntries];
- else
- return lookupTable [jmin (numEntries, roundDoubleToInt (sqrt (x) * invScale))];
- }
- };
-
- class TransformedRadialGradientPixelGenerator : public RadialGradientPixelGenerator
- {
- double tM10, tM00, lineYM01, lineYM11;
- AffineTransform inverseTransform;
-
- TransformedRadialGradientPixelGenerator (const TransformedRadialGradientPixelGenerator&);
- const TransformedRadialGradientPixelGenerator& operator= (const TransformedRadialGradientPixelGenerator&);
-
- public:
- TransformedRadialGradientPixelGenerator (const ColourGradient& gradient,
- const PixelARGB* const lookupTable_, const int numEntries_) throw()
- : RadialGradientPixelGenerator (gradient, lookupTable_, numEntries_),
- inverseTransform (gradient.transform.inverted())
- {
- tM10 = inverseTransform.mat10;
- tM00 = inverseTransform.mat00;
- }
-
- forcedinline void setY (const int y) throw()
- {
- lineYM01 = inverseTransform.mat01 * y + inverseTransform.mat02 - gx1;
- lineYM11 = inverseTransform.mat11 * y + inverseTransform.mat12 - gy1;
- }
-
- forcedinline const PixelARGB getPixel (const int px) const throw()
- {
- double x = px;
- const double y = tM10 * x + lineYM11;
- x = tM00 * x + lineYM01;
- x *= x;
- x += y * y;
-
- if (x >= maxDist)
- return lookupTable [numEntries];
- else
- return lookupTable [jmin (numEntries, roundDoubleToInt (sqrt (x) * invScale))];
- }
- };
-
- template <class PixelType, class GradientType>
- class GradientEdgeTableRenderer : public GradientType
- {
- uint8* const data;
- const int stride;
- PixelType* linePixels;
-
- GradientEdgeTableRenderer (const GradientEdgeTableRenderer&);
- const GradientEdgeTableRenderer& operator= (const GradientEdgeTableRenderer&);
-
- public:
- GradientEdgeTableRenderer (uint8* const data_,
- const int stride_,
- const ColourGradient& gradient,
- const PixelARGB* const lookupTable, const int numEntries) throw()
- : GradientType (gradient, lookupTable, numEntries - 1),
- data (data_),
- stride (stride_)
- {
- }
-
- forcedinline void setEdgeTableYPos (const int y) throw()
- {
- linePixels = (PixelType*) (data + stride * y);
- GradientType::setY (y);
- }
-
- forcedinline void handleEdgeTablePixel (const int x, const int alphaLevel) const throw()
- {
- linePixels[x].blend (GradientType::getPixel (x), alphaLevel);
- }
-
- forcedinline void handleEdgeTableLine (int x, int width, const int alphaLevel) const throw()
- {
- PixelType* dest = linePixels + x;
-
- if (alphaLevel < 0xff)
- {
- do
- {
- (dest++)->blend (GradientType::getPixel (x++), alphaLevel);
-
- } while (--width > 0);
- }
- else
- {
- do
- {
- (dest++)->blend (GradientType::getPixel (x++));
-
- } while (--width > 0);
- }
- }
- };
-
- template <class DestPixelType, class SrcPixelType>
- class ImageFillEdgeTableRenderer
- {
- uint8* const destImageData;
- const uint8* srcImageData;
- int stride, srcStride, extraAlpha;
-
- DestPixelType* linePixels;
- SrcPixelType* sourceLineStart;
-
- ImageFillEdgeTableRenderer (const ImageFillEdgeTableRenderer&);
- const ImageFillEdgeTableRenderer& operator= (const ImageFillEdgeTableRenderer&);
-
- public:
- ImageFillEdgeTableRenderer (uint8* const destImageData_,
- const int stride_,
- const uint8* srcImageData_,
- const int srcStride_,
- int extraAlpha_,
- SrcPixelType*) throw() // dummy param to avoid compiler error
- : destImageData (destImageData_),
- srcImageData (srcImageData_),
- stride (stride_),
- srcStride (srcStride_),
- extraAlpha (extraAlpha_)
- {
- }
-
- forcedinline void setEdgeTableYPos (int y) throw()
- {
- linePixels = (DestPixelType*) (destImageData + stride * y);
- sourceLineStart = (SrcPixelType*) (srcImageData + srcStride * y);
- }
-
- forcedinline void handleEdgeTablePixel (const int x, int alphaLevel) const throw()
- {
- alphaLevel = (alphaLevel * extraAlpha) >> 8;
-
- linePixels[x].blend (sourceLineStart [x], alphaLevel);
- }
-
- forcedinline void handleEdgeTableLine (int x, int width, int alphaLevel) const throw()
- {
- DestPixelType* dest = linePixels + x;
- alphaLevel = (alphaLevel * extraAlpha) >> 8;
-
- if (alphaLevel < 0xfe)
- {
- do
- {
- dest++ ->blend (sourceLineStart [x++], alphaLevel);
-
- } while (--width > 0);
- }
- else
- {
- do
- {
- dest++ ->blend (sourceLineStart [x++]);
-
- } while (--width > 0);
- }
- }
- };
-
- static void blendRowOfPixels (PixelARGB* dst,
- const PixelRGB* src,
- int width) throw()
- {
- while (--width >= 0)
- (dst++)->set (*src++);
- }
-
- static void blendRowOfPixels (PixelRGB* dst,
- const PixelRGB* src,
- int width) throw()
- {
- memcpy (dst, src, 3 * width);
- }
-
- static void blendRowOfPixels (PixelRGB* dst,
- const PixelARGB* src,
- int width) throw()
- {
- while (--width >= 0)
- (dst++)->blend (*src++);
- }
-
- static void blendRowOfPixels (PixelARGB* dst,
- const PixelARGB* src,
- int width) throw()
- {
- while (--width >= 0)
- (dst++)->blend (*src++);
- }
-
- static void blendRowOfPixels (PixelARGB* dst,
- const PixelRGB* src,
- int width,
- const uint8 alpha) throw()
- {
- while (--width >= 0)
- (dst++)->blend (*src++, alpha);
- }
-
- static void blendRowOfPixels (PixelRGB* dst,
- const PixelRGB* src,
- int width,
- const uint8 alpha) throw()
- {
- uint8* d = (uint8*) dst;
- const uint8* s = (const uint8*) src;
- const int inverseAlpha = 0xff - alpha;
-
- while (--width >= 0)
- {
- d[0] = (uint8) (s[0] + (((d[0] - s[0]) * inverseAlpha) >> 8));
- d[1] = (uint8) (s[1] + (((d[1] - s[1]) * inverseAlpha) >> 8));
- d[2] = (uint8) (s[2] + (((d[2] - s[2]) * inverseAlpha) >> 8));
-
- d += 3;
- s += 3;
- }
- }
-
- static void blendRowOfPixels (PixelRGB* dst,
- const PixelARGB* src,
- int width,
- const uint8 alpha) throw()
- {
- while (--width >= 0)
- (dst++)->blend (*src++, alpha);
- }
-
- static void blendRowOfPixels (PixelARGB* dst,
- const PixelARGB* src,
- int width,
- const uint8 alpha) throw()
- {
- while (--width >= 0)
- (dst++)->blend (*src++, alpha);
- }
-
- template <class DestPixelType, class SrcPixelType>
- static void overlayImage (DestPixelType* dest,
- const int destStride,
- const SrcPixelType* src,
- const int srcStride,
- const int width,
- int height,
- const uint8 alpha) throw()
- {
- if (alpha < 0xff)
- {
- while (--height >= 0)
- {
- blendRowOfPixels (dest, src, width, alpha);
-
- dest = (DestPixelType*) (((uint8*) dest) + destStride);
- src = (const SrcPixelType*) (((const uint8*) src) + srcStride);
- }
- }
- else
- {
- while (--height >= 0)
- {
- blendRowOfPixels (dest, src, width);
-
- dest = (DestPixelType*) (((uint8*) dest) + destStride);
- src = (const SrcPixelType*) (((const uint8*) src) + srcStride);
- }
- }
- }
-
- template <class DestPixelType, class SrcPixelType>
- static void transformedImageRender (Image& destImage,
- const Image& sourceImage,
- const int destClipX, const int destClipY,
- const int destClipW, const int destClipH,
- const int srcClipX, const int srcClipY,
- const int srcClipWidth, const int srcClipHeight,
- double srcX, double srcY,
- const double lineDX, const double lineDY,
- const double pixelDX, const double pixelDY,
- const uint8 alpha,
- const Graphics::ResamplingQuality quality,
- DestPixelType*,
- SrcPixelType*) throw() // forced by a compiler bug to include dummy
- // parameters of the templated classes to
- // make it use the correct instance of this function..
- {
- int destStride, destPixelStride;
- uint8* const destPixels = destImage.lockPixelDataReadWrite (destClipX, destClipY, destClipW, destClipH, destStride, destPixelStride);
-
- int srcStride, srcPixelStride;
- const uint8* const srcPixels = sourceImage.lockPixelDataReadOnly (srcClipX, srcClipY, srcClipWidth, srcClipHeight, srcStride, srcPixelStride);
-
- if (quality == Graphics::lowResamplingQuality) // nearest-neighbour..
- {
- for (int y = 0; y < destClipH; ++y)
- {
- double sx = srcX;
- double sy = srcY;
-
- DestPixelType* dest = (DestPixelType*) (destPixels + destStride * y);
-
- for (int x = 0; x < destClipW; ++x)
- {
- const int ix = roundDoubleToInt (floor (sx)) - srcClipX;
-
- if (((unsigned int) ix) < (unsigned int) srcClipWidth)
- {
- const int iy = roundDoubleToInt (floor (sy)) - srcClipY;
-
- if (((unsigned int) iy) < (unsigned int) srcClipHeight)
- {
- const SrcPixelType* const src = (const SrcPixelType*) (srcPixels + srcStride * iy + srcPixelStride * ix);
-
- dest->blend (*src, alpha);
- }
- }
-
- ++dest;
- sx += pixelDX;
- sy += pixelDY;
- }
-
- srcX += lineDX;
- srcY += lineDY;
- }
- }
- else
- {
- jassert (quality == Graphics::mediumResamplingQuality); // (only bilinear is implemented, so that's what you'll get here..)
-
- for (int y = 0; y < destClipH; ++y)
- {
- double sx = srcX;
- double sy = srcY;
- DestPixelType* dest = (DestPixelType*) (destPixels + destStride * y);
-
- for (int x = 0; x < destClipW; ++x)
- {
- const double fx = floor (sx);
- const double fy = floor (sy);
- const int ix = roundDoubleToInt (fx) - srcClipX;
- const int iy = roundDoubleToInt (fy) - srcClipY;
-
- if (ix < srcClipWidth && iy < srcClipHeight)
- {
- PixelARGB p1 (0), p2 (0), p3 (0), p4 (0);
-
- const SrcPixelType* src = (const SrcPixelType*) (srcPixels + srcStride * iy + srcPixelStride * ix);
-
- if (iy >= 0)
- {
- if (ix >= 0)
- p1.set (src[0]);
-
- if (((unsigned int) (ix + 1)) < (unsigned int) srcClipWidth)
- p2.set (src[1]);
- }
-
- if (((unsigned int) (iy + 1)) < (unsigned int) srcClipHeight)
- {
- src = (const SrcPixelType*) (((const uint8*) src) + srcStride);
-
- if (ix >= 0)
- p3.set (src[0]);
-
- if (((unsigned int) (ix + 1)) < (unsigned int) srcClipWidth)
- p4.set (src[1]);
- }
-
- const int dx = roundDoubleToInt ((sx - fx) * 255.0);
- p1.tween (p2, dx);
- p3.tween (p4, dx);
- p1.tween (p3, roundDoubleToInt ((sy - fy) * 255.0));
-
- if (p1.getAlpha() > 0)
- dest->blend (p1, alpha);
- }
-
- ++dest;
- sx += pixelDX;
- sy += pixelDY;
- }
-
- srcX += lineDX;
- srcY += lineDY;
- }
- }
-
- destImage.releasePixelDataReadWrite (destPixels);
- sourceImage.releasePixelDataReadOnly (srcPixels);
- }
-
- template <class SrcPixelType, class DestPixelType>
- static void renderAlphaMap (DestPixelType* destPixels,
- int destStride,
- SrcPixelType* srcPixels,
- int srcStride,
- const uint8* alphaValues,
- const int lineStride, const int pixelStride,
- int width, int height,
- const int extraAlpha) throw()
- {
- while (--height >= 0)
- {
- SrcPixelType* srcPix = srcPixels;
- srcPixels = (SrcPixelType*) (((const uint8*) srcPixels) + srcStride);
-
- DestPixelType* destPix = destPixels;
- destPixels = (DestPixelType*) (((uint8*) destPixels) + destStride);
-
- const uint8* alpha = alphaValues;
- alphaValues += lineStride;
-
- if (extraAlpha < 0x100)
- {
- for (int i = width; --i >= 0;)
- {
- destPix++ ->blend (*srcPix++, (extraAlpha * *alpha) >> 8);
- alpha += pixelStride;
- }
- }
- else
- {
- for (int i = width; --i >= 0;)
- {
- destPix++ ->blend (*srcPix++, *alpha);
- alpha += pixelStride;
- }
- }
- }
- }
-
- LowLevelGraphicsSoftwareRenderer::LowLevelGraphicsSoftwareRenderer (Image& image_)
- : image (image_),
- xOffset (0),
- yOffset (0),
- stateStack (20)
- {
- clip = new RectangleList (Rectangle (0, 0, image_.getWidth(), image_.getHeight()));
- }
-
- LowLevelGraphicsSoftwareRenderer::~LowLevelGraphicsSoftwareRenderer()
- {
- delete clip;
- }
-
- bool LowLevelGraphicsSoftwareRenderer::isVectorDevice() const
- {
- return false;
- }
-
- void LowLevelGraphicsSoftwareRenderer::setOrigin (int x, int y)
- {
- xOffset += x;
- yOffset += y;
- }
-
- bool LowLevelGraphicsSoftwareRenderer::reduceClipRegion (int x, int y, int w, int h)
- {
- return clip->clipTo (Rectangle (x + xOffset, y + yOffset, w, h));
- }
-
- bool LowLevelGraphicsSoftwareRenderer::reduceClipRegion (const RectangleList& clipRegion)
- {
- RectangleList temp (clipRegion);
- temp.offsetAll (xOffset, yOffset);
-
- return clip->clipTo (temp);
- }
-
- void LowLevelGraphicsSoftwareRenderer::excludeClipRegion (int x, int y, int w, int h)
- {
- clip->subtract (Rectangle (x + xOffset, y + yOffset, w, h));
- }
-
- bool LowLevelGraphicsSoftwareRenderer::clipRegionIntersects (int x, int y, int w, int h)
- {
- return clip->intersectsRectangle (Rectangle (x + xOffset, y + yOffset, w, h));
- }
-
- const Rectangle LowLevelGraphicsSoftwareRenderer::getClipBounds() const
- {
- return clip->getBounds().translated (-xOffset, -yOffset);
- }
-
- bool LowLevelGraphicsSoftwareRenderer::isClipEmpty() const
- {
- return clip->isEmpty();
- }
-
- LowLevelGraphicsSoftwareRenderer::SavedState::SavedState (RectangleList* const clip_,
- const int xOffset_, const int yOffset_)
- : clip (clip_),
- xOffset (xOffset_),
- yOffset (yOffset_)
- {
- }
-
- LowLevelGraphicsSoftwareRenderer::SavedState::~SavedState()
- {
- delete clip;
- }
-
- void LowLevelGraphicsSoftwareRenderer::saveState()
- {
- stateStack.add (new SavedState (new RectangleList (*clip), xOffset, yOffset));
- }
-
- void LowLevelGraphicsSoftwareRenderer::restoreState()
- {
- SavedState* const top = stateStack.getLast();
-
- if (top != 0)
- {
- clip->swapWith (*top->clip);
-
- xOffset = top->xOffset;
- yOffset = top->yOffset;
-
- stateStack.removeLast();
- }
- else
- {
- jassertfalse // trying to pop with an empty stack!
- }
- }
-
- void LowLevelGraphicsSoftwareRenderer::fillRectWithColour (int x, int y, int w, int h, const Colour& colour, const bool replaceExistingContents)
- {
- x += xOffset;
- y += yOffset;
-
- for (RectangleList::Iterator i (*clip); i.next();)
- {
- clippedFillRectWithColour (*i.getRectangle(), x, y, w, h, colour, replaceExistingContents);
- }
- }
-
- void LowLevelGraphicsSoftwareRenderer::clippedFillRectWithColour (const Rectangle& clipRect,
- int x, int y, int w, int h, const Colour& colour, const bool replaceExistingContents)
- {
- if (clipRect.intersectRectangle (x, y, w, h))
- {
- int stride, pixelStride;
- uint8* const pixels = (uint8*) image.lockPixelDataReadWrite (x, y, w, h, stride, pixelStride);
-
- if (image.getFormat() == Image::RGB)
- {
- if (replaceExistingContents)
- replaceRectRGB (pixels, w, h, stride, colour);
- else
- blendRectRGB (pixels, w, h, stride, colour);
- }
- else if (image.getFormat() == Image::ARGB)
- {
- if (replaceExistingContents)
- replaceRectARGB (pixels, w, h, stride, colour);
- else
- blendRectARGB (pixels, w, h, stride, colour);
- }
- else
- {
- jassertfalse // not done!
- }
-
- image.releasePixelDataReadWrite (pixels);
- }
- }
-
- void LowLevelGraphicsSoftwareRenderer::fillRectWithGradient (int x, int y, int w, int h, const ColourGradient& gradient)
- {
- Path p;
- p.addRectangle ((float) x, (float) y, (float) w, (float) h);
- fillPathWithGradient (p, AffineTransform::identity, gradient, EdgeTable::Oversampling_none);
- }
-
- bool LowLevelGraphicsSoftwareRenderer::getPathBounds (int clipX, int clipY, int clipW, int clipH,
- const Path& path, const AffineTransform& transform,
- int& x, int& y, int& w, int& h) const
- {
- float tx, ty, tw, th;
- path.getBoundsTransformed (transform, tx, ty, tw, th);
-
- x = roundDoubleToInt (tx) - 1;
- y = roundDoubleToInt (ty) - 1;
- w = roundDoubleToInt (tw) + 2;
- h = roundDoubleToInt (th) + 2;
-
- // seems like this operation is using some crazy out-of-range numbers..
- ASSERT_COORDS_ARE_SENSIBLE_NUMBERS (x, y, w, h);
-
- return Rectangle::intersectRectangles (x, y, w, h, clipX, clipY, clipW, clipH);
- }
-
- void LowLevelGraphicsSoftwareRenderer::fillPathWithColour (const Path& path, const AffineTransform& t,
- const Colour& colour, EdgeTable::OversamplingLevel quality)
- {
- for (RectangleList::Iterator i (*clip); i.next();)
- {
- const Rectangle& r = *i.getRectangle();
-
- clippedFillPathWithColour (r.getX(), r.getY(), r.getWidth(), r.getHeight(), path, t, colour, quality);
- }
- }
-
- void LowLevelGraphicsSoftwareRenderer::clippedFillPathWithColour (int clipX, int clipY, int clipW, int clipH, const Path& path, const AffineTransform& t,
- const Colour& colour, EdgeTable::OversamplingLevel quality)
- {
- const AffineTransform transform (t.translated ((float) xOffset, (float) yOffset));
- int cx, cy, cw, ch;
-
- if (getPathBounds (clipX, clipY, clipW, clipH, path, transform, cx, cy, cw, ch))
- {
- EdgeTable edgeTable (0, ch, quality);
-
- edgeTable.addPath (path, transform.translated ((float) -cx, (float) -cy));
-
- int stride, pixelStride;
- uint8* const pixels = (uint8*) image.lockPixelDataReadWrite (cx, cy, cw, ch, stride, pixelStride);
-
- if (image.getFormat() == Image::RGB)
- {
- jassert (pixelStride == 3);
- SolidColourEdgeTableRenderer <PixelRGB> renderer (pixels, stride, colour);
- edgeTable.iterate (renderer, 0, 0, cw, ch, 0);
- }
- else if (image.getFormat() == Image::ARGB)
- {
- jassert (pixelStride == 4);
- SolidColourEdgeTableRenderer <PixelARGB> renderer (pixels, stride, colour);
- edgeTable.iterate (renderer, 0, 0, cw, ch, 0);
- }
- else if (image.getFormat() == Image::SingleChannel)
- {
- jassert (pixelStride == 1);
- AlphaBitmapRenderer renderer (pixels, stride);
- edgeTable.iterate (renderer, 0, 0, cw, ch, 0);
- }
-
- image.releasePixelDataReadWrite (pixels);
- }
- }
-
- void LowLevelGraphicsSoftwareRenderer::fillPathWithGradient (const Path& path, const AffineTransform& t, const ColourGradient& gradient, EdgeTable::OversamplingLevel quality)
- {
- for (RectangleList::Iterator i (*clip); i.next();)
- {
- const Rectangle& r = *i.getRectangle();
-
- clippedFillPathWithGradient (r.getX(), r.getY(), r.getWidth(), r.getHeight(),
- path, t, gradient, quality);
- }
- }
-
- void LowLevelGraphicsSoftwareRenderer::clippedFillPathWithGradient (int clipX, int clipY, int clipW, int clipH, const Path& path, const AffineTransform& t,
- const ColourGradient& gradient, EdgeTable::OversamplingLevel quality)
- {
- const AffineTransform transform (t.translated ((float) xOffset, (float) yOffset));
- int cx, cy, cw, ch;
-
- if (getPathBounds (clipX, clipY, clipW, clipH, path, transform, cx, cy, cw, ch))
- {
- int stride, pixelStride;
- uint8* const pixels = (uint8*) image.lockPixelDataReadWrite (cx, cy, cw, ch, stride, pixelStride);
-
- ColourGradient g2 (gradient);
-
- const bool isIdentity = g2.transform.isIdentity();
- if (isIdentity)
- {
- g2.x1 += xOffset - cx;
- g2.x2 += xOffset - cx;
- g2.y1 += yOffset - cy;
- g2.y2 += yOffset - cy;
- }
- else
- {
- g2.transform = g2.transform.translated ((float) (xOffset - cx),
- (float) (yOffset - cy));
- }
-
- int numLookupEntries;
- PixelARGB* const lookupTable = g2.createLookupTable (numLookupEntries);
- jassert (numLookupEntries > 0);
-
- EdgeTable edgeTable (0, ch, quality);
-
- edgeTable.addPath (path, transform.translated ((float) -cx, (float) -cy));
-
- if (image.getFormat() == Image::RGB)
- {
- jassert (pixelStride == 3);
-
- if (g2.isRadial)
- {
- if (isIdentity)
- {
- GradientEdgeTableRenderer <PixelRGB, RadialGradientPixelGenerator> renderer (pixels, stride, g2, lookupTable, numLookupEntries);
- edgeTable.iterate (renderer, 0, 0, cw, ch, 0);
- }
- else
- {
- GradientEdgeTableRenderer <PixelRGB, TransformedRadialGradientPixelGenerator> renderer (pixels, stride, g2, lookupTable, numLookupEntries);
- edgeTable.iterate (renderer, 0, 0, cw, ch, 0);
- }
- }
- else
- {
- GradientEdgeTableRenderer <PixelRGB, LinearGradientPixelGenerator> renderer (pixels, stride, g2, lookupTable, numLookupEntries);
- edgeTable.iterate (renderer, 0, 0, cw, ch, 0);
- }
- }
- else if (image.getFormat() == Image::ARGB)
- {
- jassert (pixelStride == 4);
-
- if (g2.isRadial)
- {
- if (isIdentity)
- {
- GradientEdgeTableRenderer <PixelARGB, RadialGradientPixelGenerator> renderer (pixels, stride, g2, lookupTable, numLookupEntries);
- edgeTable.iterate (renderer, 0, 0, cw, ch, 0);
- }
- else
- {
- GradientEdgeTableRenderer <PixelARGB, TransformedRadialGradientPixelGenerator> renderer (pixels, stride, g2, lookupTable, numLookupEntries);
- edgeTable.iterate (renderer, 0, 0, cw, ch, 0);
- }
- }
- else
- {
- GradientEdgeTableRenderer <PixelARGB, LinearGradientPixelGenerator> renderer (pixels, stride, g2, lookupTable, numLookupEntries);
- edgeTable.iterate (renderer, 0, 0, cw, ch, 0);
- }
- }
- else if (image.getFormat() == Image::SingleChannel)
- {
- jassertfalse // not done!
- }
-
- juce_free (lookupTable);
- image.releasePixelDataReadWrite (pixels);
- }
- }
-
- void LowLevelGraphicsSoftwareRenderer::fillPathWithImage (const Path& path, const AffineTransform& transform,
- const Image& sourceImage, int imageX, int imageY, float opacity, EdgeTable::OversamplingLevel quality)
- {
- imageX += xOffset;
- imageY += yOffset;
-
- for (RectangleList::Iterator i (*clip); i.next();)
- {
- const Rectangle& r = *i.getRectangle();
-
- clippedFillPathWithImage (r.getX(), r.getY(), r.getWidth(), r.getHeight(),
- path, transform, sourceImage, imageX, imageY, opacity, quality);
- }
- }
-
- void LowLevelGraphicsSoftwareRenderer::clippedFillPathWithImage (int x, int y, int w, int h, const Path& path, const AffineTransform& transform,
- const Image& sourceImage, int imageX, int imageY, float opacity, EdgeTable::OversamplingLevel quality)
- {
- if (Rectangle::intersectRectangles (x, y, w, h, imageX, imageY, sourceImage.getWidth(), sourceImage.getHeight()))
- {
- EdgeTable edgeTable (0, h, quality);
- edgeTable.addPath (path, transform.translated ((float) (xOffset - x), (float) (yOffset - y)));
-
- int stride, pixelStride;
- uint8* const pixels = (uint8*) image.lockPixelDataReadWrite (x, y, w, h, stride, pixelStride);
-
- int srcStride, srcPixelStride;
- const uint8* const srcPix = (const uint8*) sourceImage.lockPixelDataReadOnly (x - imageX, y - imageY, w, h, srcStride, srcPixelStride);
-
- const int alpha = jlimit (0, 255, roundDoubleToInt (opacity * 255.0f));
-
- if (image.getFormat() == Image::RGB)
- {
- if (sourceImage.getFormat() == Image::RGB)
- {
- ImageFillEdgeTableRenderer <PixelRGB, PixelRGB> renderer (pixels, stride,
- srcPix, srcStride,
- alpha, (PixelRGB*) 0);
- edgeTable.iterate (renderer, 0, 0, w, h, 0);
- }
- else if (sourceImage.getFormat() == Image::ARGB)
- {
- ImageFillEdgeTableRenderer <PixelRGB, PixelARGB> renderer (pixels, stride,
- srcPix, srcStride,
- alpha, (PixelARGB*) 0);
- edgeTable.iterate (renderer, 0, 0, w, h, 0);
- }
- else
- {
- jassertfalse // not done!
- }
- }
- else if (image.getFormat() == Image::ARGB)
- {
- if (sourceImage.getFormat() == Image::RGB)
- {
- ImageFillEdgeTableRenderer <PixelARGB, PixelRGB> renderer (pixels, stride,
- srcPix, srcStride,
- alpha, (PixelRGB*) 0);
- edgeTable.iterate (renderer, 0, 0, w, h, 0);
- }
- else if (sourceImage.getFormat() == Image::ARGB)
- {
- ImageFillEdgeTableRenderer <PixelARGB, PixelARGB> renderer (pixels, stride,
- srcPix, srcStride,
- alpha, (PixelARGB*) 0);
- edgeTable.iterate (renderer, 0, 0, w, h, 0);
- }
- else
- {
- jassertfalse // not done!
- }
- }
- else
- {
- jassertfalse // not done!
- }
-
- sourceImage.releasePixelDataReadOnly (srcPix);
- image.releasePixelDataReadWrite (pixels);
- }
- }
-
- void LowLevelGraphicsSoftwareRenderer::fillAlphaChannelWithColour (const Image& clipImage, int x, int y, const Colour& colour)
- {
- x += xOffset;
- y += yOffset;
-
- for (RectangleList::Iterator i (*clip); i.next();)
- {
- const Rectangle& r = *i.getRectangle();
-
- clippedFillAlphaChannelWithColour (r.getX(), r.getY(), r.getWidth(), r.getHeight(),
- clipImage, x, y, colour);
- }
- }
-
- void LowLevelGraphicsSoftwareRenderer::clippedFillAlphaChannelWithColour (int clipX, int clipY, int clipW, int clipH, const Image& clipImage, int x, int y, const Colour& colour)
- {
- int w = clipImage.getWidth();
- int h = clipImage.getHeight();
- int sx = 0;
- int sy = 0;
-
- if (x < clipX)
- {
- sx = clipX - x;
- w -= clipX - x;
- x = clipX;
- }
-
- if (y < clipY)
- {
- sy = clipY - y;
- h -= clipY - y;
- y = clipY;
- }
-
- if (x + w > clipX + clipW)
- w = clipX + clipW - x;
-
- if (y + h > clipY + clipH)
- h = clipY + clipH - y;
-
- if (w > 0 && h > 0)
- {
- int stride, alphaStride, pixelStride;
- uint8* const pixels = (uint8*) image.lockPixelDataReadWrite (x, y, w, h, stride, pixelStride);
-
- const uint8* const alphaValues
- = clipImage.lockPixelDataReadOnly (sx, sy, w, h, alphaStride, pixelStride);
-
- #if JUCE_MAC
- const uint8* const alphas = alphaValues;
- #else
- const uint8* const alphas = alphaValues + (clipImage.getFormat() == Image::ARGB ? 3 : 0);
- #endif
-
- if (image.getFormat() == Image::RGB)
- {
- blendAlphaMapRGB (pixels, stride,
- alphas, w, h,
- pixelStride, alphaStride,
- colour);
- }
- else if (image.getFormat() == Image::ARGB)
- {
- blendAlphaMapARGB (pixels, stride,
- alphas, w, h,
- pixelStride, alphaStride,
- colour);
- }
- else
- {
- jassertfalse // not done!
- }
-
- clipImage.releasePixelDataReadOnly (alphaValues);
- image.releasePixelDataReadWrite (pixels);
- }
- }
-
- void LowLevelGraphicsSoftwareRenderer::fillAlphaChannelWithGradient (const Image& alphaChannelImage, int imageX, int imageY, const ColourGradient& gradient)
- {
- imageX += xOffset;
- imageY += yOffset;
-
- for (RectangleList::Iterator i (*clip); i.next();)
- {
- const Rectangle& r = *i.getRectangle();
-
- clippedFillAlphaChannelWithGradient (r.getX(), r.getY(), r.getWidth(), r.getHeight(),
- alphaChannelImage, imageX, imageY, gradient);
- }
- }
-
- void LowLevelGraphicsSoftwareRenderer::clippedFillAlphaChannelWithGradient (int x, int y, int w, int h,
- const Image& alphaChannelImage,
- int imageX, int imageY, const ColourGradient& gradient)
- {
- if (Rectangle::intersectRectangles (x, y, w, h, imageX, imageY, alphaChannelImage.getWidth(), alphaChannelImage.getHeight()))
- {
- ColourGradient g2 (gradient);
- g2.x1 += xOffset - x;
- g2.x2 += xOffset - x;
- g2.y1 += yOffset - y;
- g2.y2 += yOffset - y;
-
- Image temp (g2.isOpaque() ? Image::RGB : Image::ARGB, w, h, true);
- LowLevelGraphicsSoftwareRenderer tempG (temp);
- tempG.fillRectWithGradient (0, 0, w, h, g2);
-
- clippedFillAlphaChannelWithImage (x, y, w, h,
- alphaChannelImage, imageX, imageY,
- temp, x, y, 1.0f);
- }
- }
-
- void LowLevelGraphicsSoftwareRenderer::fillAlphaChannelWithImage (const Image& alphaImage, int alphaImageX, int alphaImageY,
- const Image& fillerImage, int fillerImageX, int fillerImageY, float opacity)
- {
- alphaImageX += xOffset;
- alphaImageY += yOffset;
-
- fillerImageX += xOffset;
- fillerImageY += yOffset;
-
- for (RectangleList::Iterator i (*clip); i.next();)
- {
- const Rectangle& r = *i.getRectangle();
-
- clippedFillAlphaChannelWithImage (r.getX(), r.getY(), r.getWidth(), r.getHeight(),
- alphaImage, alphaImageX, alphaImageY,
- fillerImage, fillerImageX, fillerImageY, opacity);
- }
- }
-
- void LowLevelGraphicsSoftwareRenderer::clippedFillAlphaChannelWithImage (int x, int y, int w, int h, const Image& alphaImage, int alphaImageX, int alphaImageY,
- const Image& fillerImage, int fillerImageX, int fillerImageY, float opacity)
- {
- if (Rectangle::intersectRectangles (x, y, w, h, alphaImageX, alphaImageY, alphaImage.getWidth(), alphaImage.getHeight())
- && Rectangle::intersectRectangles (x, y, w, h, fillerImageX, fillerImageY, fillerImage.getWidth(), fillerImage.getHeight()))
- {
- int dstStride, dstPixStride;
- uint8* const dstPix = image.lockPixelDataReadWrite (x, y, w, h, dstStride, dstPixStride);
-
- int srcStride, srcPixStride;
- const uint8* const srcPix = fillerImage.lockPixelDataReadOnly (x - fillerImageX, y - fillerImageY, w, h, srcStride, srcPixStride);
-
- int maskStride, maskPixStride;
- const uint8* const alpha
- = alphaImage.lockPixelDataReadOnly (x - alphaImageX, y - alphaImageY, w, h, maskStride, maskPixStride);
-
- #if JUCE_MAC
- const uint8* const alphaValues = alpha;
- #else
- const uint8* const alphaValues = alpha + (alphaImage.getFormat() == Image::ARGB ? 3 : 0);
- #endif
-
- const int extraAlpha = jlimit (0, 0x100, roundDoubleToInt (opacity * 256.0f));
-
- if (image.getFormat() == Image::RGB)
- {
- if (fillerImage.getFormat() == Image::RGB)
- {
- renderAlphaMap ((PixelRGB*) dstPix, dstStride, (const PixelRGB*) srcPix, srcStride, alphaValues, maskStride, maskPixStride, w, h, extraAlpha);
- }
- else if (fillerImage.getFormat() == Image::ARGB)
- {
- renderAlphaMap ((PixelRGB*) dstPix, dstStride, (const PixelARGB*) srcPix, srcStride, alphaValues, maskStride, maskPixStride, w, h, extraAlpha);
- }
- else
- {
- jassertfalse // not done!
- }
- }
- else if (image.getFormat() == Image::ARGB)
- {
- if (fillerImage.getFormat() == Image::RGB)
- {
- renderAlphaMap ((PixelARGB*) dstPix, dstStride, (const PixelRGB*) srcPix, srcStride, alphaValues, maskStride, maskPixStride, w, h, extraAlpha);
- }
- else if (fillerImage.getFormat() == Image::ARGB)
- {
- renderAlphaMap ((PixelARGB*) dstPix, dstStride, (const PixelARGB*) srcPix, srcStride, alphaValues, maskStride, maskPixStride, w, h, extraAlpha);
- }
- else
- {
- jassertfalse // not done!
- }
- }
- else
- {
- jassertfalse // not done!
- }
-
- alphaImage.releasePixelDataReadOnly (alphaValues);
- fillerImage.releasePixelDataReadOnly (srcPix);
- image.releasePixelDataReadWrite (dstPix);
- }
- }
-
- void LowLevelGraphicsSoftwareRenderer::blendImage (const Image& sourceImage, int dx, int dy, int dw, int dh, int sx, int sy, float opacity)
- {
- dx += xOffset;
- dy += yOffset;
-
- for (RectangleList::Iterator i (*clip); i.next();)
- {
- const Rectangle& r = *i.getRectangle();
-
- clippedBlendImage (r.getX(), r.getY(), r.getWidth(), r.getHeight(),
- sourceImage, dx, dy, dw, dh, sx, sy, opacity);
- }
- }
-
- void LowLevelGraphicsSoftwareRenderer::clippedBlendImage (int clipX, int clipY, int clipW, int clipH,
- const Image& sourceImage, int dx, int dy, int dw, int dh, int sx, int sy, float opacity)
- {
- if (dx < clipX)
- {
- sx += clipX - dx;
- dw -= clipX - dx;
- dx = clipX;
- }
-
- if (dy < clipY)
- {
- sy += clipY - dy;
- dh -= clipY - dy;
- dy = clipY;
- }
-
- if (dx + dw > clipX + clipW)
- dw = clipX + clipW - dx;
-
- if (dy + dh > clipY + clipH)
- dh = clipY + clipH - dy;
-
- if (dw <= 0 || dh <= 0)
- return;
-
- const uint8 alpha = (uint8) jlimit (0, 0xff, roundDoubleToInt (opacity * 256.0f));
-
- if (alpha == 0)
- return;
-
- int dstStride, dstPixelStride;
- uint8* const dstPixels = image.lockPixelDataReadWrite (dx, dy, dw, dh, dstStride, dstPixelStride);
-
- int srcStride, srcPixelStride;
- const uint8* const srcPixels = sourceImage.lockPixelDataReadOnly (sx, sy, dw, dh, srcStride, srcPixelStride);
-
- if (image.getFormat() == Image::ARGB)
- {
- if (sourceImage.getFormat() == Image::ARGB)
- {
- overlayImage ((PixelARGB*) dstPixels, dstStride,
- (PixelARGB*) srcPixels, srcStride,
- dw, dh, alpha);
- }
- else if (sourceImage.getFormat() == Image::RGB)
- {
- overlayImage ((PixelARGB*) dstPixels, dstStride,
- (PixelRGB*) srcPixels, srcStride,
- dw, dh, alpha);
- }
- else
- {
- jassertfalse
- }
- }
- else if (image.getFormat() == Image::RGB)
- {
- if (sourceImage.getFormat() == Image::ARGB)
- {
- overlayImage ((PixelRGB*) dstPixels, dstStride,
- (PixelARGB*) srcPixels, srcStride,
- dw, dh, alpha);
- }
- else if (sourceImage.getFormat() == Image::RGB)
- {
- overlayImage ((PixelRGB*) dstPixels, dstStride,
- (PixelRGB*) srcPixels, srcStride,
- dw, dh, alpha);
- }
- else
- {
- jassertfalse
- }
- }
- else
- {
- jassertfalse
- }
-
- image.releasePixelDataReadWrite (dstPixels);
- sourceImage.releasePixelDataReadOnly (srcPixels);
- }
-
- void LowLevelGraphicsSoftwareRenderer::blendImageRescaling (const Image& sourceImage,
- int dx, int dy, int dw, int dh,
- int sx, int sy, int sw, int sh,
- float alpha,
- const Graphics::ResamplingQuality quality)
- {
- if (sw > 0 && sh > 0)
- {
- if (sw == dw && sh == dh)
- {
- blendImage (sourceImage,
- dx, dy, dw, dh,
- sx, sy, alpha);
- }
- else
- {
- blendImageWarping (sourceImage,
- sx, sy, sw, sh,
- AffineTransform::translation ((float) -sx,
- (float) -sy)
- .scaled (dw / (float) sw,
- dh / (float) sh)
- .translated ((float) dx,
- (float) dy),
- alpha,
- quality);
- }
- }
- }
-
- void LowLevelGraphicsSoftwareRenderer::blendImageWarping (const Image& sourceImage,
- int srcClipX, int srcClipY, int srcClipW, int srcClipH,
- const AffineTransform& t,
- float opacity,
- const Graphics::ResamplingQuality quality)
- {
- const AffineTransform transform (t.translated ((float) xOffset, (float) yOffset));
-
- for (RectangleList::Iterator i (*clip); i.next();)
- {
- const Rectangle& r = *i.getRectangle();
-
- clippedBlendImageWarping (r.getX(), r.getY(), r.getWidth(), r.getHeight(),
- sourceImage, srcClipX, srcClipY, srcClipW, srcClipH,
- transform, opacity, quality);
- }
- }
-
- void LowLevelGraphicsSoftwareRenderer::clippedBlendImageWarping (int destClipX, int destClipY, int destClipW, int destClipH,
- const Image& sourceImage,
- int srcClipX, int srcClipY, int srcClipW, int srcClipH,
- const AffineTransform& transform,
- float opacity,
- const Graphics::ResamplingQuality quality)
- {
- if (opacity > 0 && destClipW > 0 && destClipH > 0 && ! transform.isSingularity())
- {
- Rectangle::intersectRectangles (srcClipX, srcClipY, srcClipW, srcClipH,
- 0, 0, sourceImage.getWidth(), sourceImage.getHeight());
-
- if (srcClipW <= 0 || srcClipH <= 0)
- return;
-
- jassert (srcClipX >= 0 && srcClipY >= 0);
-
- Path imageBounds;
- imageBounds.addRectangle ((float) srcClipX, (float) srcClipY, (float) srcClipW, (float) srcClipH);
- imageBounds.applyTransform (transform);
- float imX, imY, imW, imH;
- imageBounds.getBounds (imX, imY, imW, imH);
-
- if (Rectangle::intersectRectangles (destClipX, destClipY, destClipW, destClipH,
- (int) floorf (imX),
- (int) floorf (imY),
- 1 + roundDoubleToInt (imW),
- 1 + roundDoubleToInt (imH)))
- {
- const uint8 alpha = (uint8) jlimit (0, 0xff, roundDoubleToInt (opacity * 256.0f));
-
- float srcX1 = (float) destClipX;
- float srcY1 = (float) destClipY;
- float srcX2 = (float) (destClipX + destClipW);
- float srcY2 = srcY1;
- float srcX3 = srcX1;
- float srcY3 = (float) (destClipY + destClipH);
-
- AffineTransform inverse (transform.inverted());
- inverse.transformPoint (srcX1, srcY1);
- inverse.transformPoint (srcX2, srcY2);
- inverse.transformPoint (srcX3, srcY3);
-
- const double lineDX = (double) (srcX3 - srcX1) / destClipH;
- const double lineDY = (double) (srcY3 - srcY1) / destClipH;
- const double pixelDX = (double) (srcX2 - srcX1) / destClipW;
- const double pixelDY = (double) (srcY2 - srcY1) / destClipW;
-
- if (image.getFormat() == Image::ARGB)
- {
- if (sourceImage.getFormat() == Image::ARGB)
- {
- transformedImageRender (image, sourceImage,
- destClipX, destClipY, destClipW, destClipH,
- srcClipX, srcClipY, srcClipW, srcClipH,
- srcX1, srcY1, lineDX, lineDY, pixelDX, pixelDY,
- alpha, quality, (PixelARGB*)0, (PixelARGB*)0);
- }
- else if (sourceImage.getFormat() == Image::RGB)
- {
- transformedImageRender (image, sourceImage,
- destClipX, destClipY, destClipW, destClipH,
- srcClipX, srcClipY, srcClipW, srcClipH,
- srcX1, srcY1, lineDX, lineDY, pixelDX, pixelDY,
- alpha, quality, (PixelARGB*)0, (PixelRGB*)0);
- }
- else
- {
- jassertfalse
- }
- }
- else if (image.getFormat() == Image::RGB)
- {
- if (sourceImage.getFormat() == Image::ARGB)
- {
- transformedImageRender (image, sourceImage,
- destClipX, destClipY, destClipW, destClipH,
- srcClipX, srcClipY, srcClipW, srcClipH,
- srcX1, srcY1, lineDX, lineDY, pixelDX, pixelDY,
- alpha, quality, (PixelRGB*)0, (PixelARGB*)0);
- }
- else if (sourceImage.getFormat() == Image::RGB)
- {
- transformedImageRender (image, sourceImage,
- destClipX, destClipY, destClipW, destClipH,
- srcClipX, srcClipY, srcClipW, srcClipH,
- srcX1, srcY1, lineDX, lineDY, pixelDX, pixelDY,
- alpha, quality, (PixelRGB*)0, (PixelRGB*)0);
- }
- else
- {
- jassertfalse
- }
- }
- else
- {
- jassertfalse
- }
- }
- }
- }
-
- void LowLevelGraphicsSoftwareRenderer::drawLine (double x1, double y1, double x2, double y2, const Colour& colour)
- {
- x1 += xOffset;
- y1 += yOffset;
- x2 += xOffset;
- y2 += yOffset;
-
- for (RectangleList::Iterator i (*clip); i.next();)
- {
- const Rectangle& r = *i.getRectangle();
-
- clippedDrawLine (r.getX(), r.getY(), r.getWidth(), r.getHeight(),
- x1, y1, x2, y2, colour);
- }
- }
-
- void LowLevelGraphicsSoftwareRenderer::clippedDrawLine (int clipX, int clipY, int clipW, int clipH, double x1, double y1, double x2, double y2, const Colour& colour)
- {
- if (clipW > 0 && clipH > 0)
- {
- if (x1 == x2)
- {
- if (y2 < y1)
- swapVariables (y1, y2);
-
- clippedDrawVerticalLine (clipX, clipY, clipW, clipH, roundDoubleToInt (x1), y1, y2, colour);
- }
- else if (y1 == y2)
- {
- if (x2 < x1)
- swapVariables (x1, x2);
-
- clippedDrawHorizontalLine (clipX, clipY, clipW, clipH, roundDoubleToInt (y1), x1, x2, colour);
- }
- else
- {
- double gradient = (y2 - y1) / (x2 - x1);
-
- if (fabs (gradient) > 1.0)
- {
- gradient = 1.0 / gradient;
-
- int y = roundDoubleToInt (y1);
- const int startY = y;
- int endY = roundDoubleToInt (y2);
-
- if (y > endY)
- swapVariables (y, endY);
-
- while (y < endY)
- {
- const double x = x1 + gradient * (y - startY);
- clippedDrawHorizontalLine (clipX, clipY, clipW, clipH, y, x, x + 1.0, colour);
- ++y;
- }
- }
- else
- {
- int x = roundDoubleToInt (x1);
- const int startX = x;
- int endX = roundDoubleToInt (x2);
-
- if (x > endX)
- swapVariables (x, endX);
-
- while (x < endX)
- {
- const double y = y1 + gradient * (x - startX);
- clippedDrawVerticalLine (clipX, clipY, clipW, clipH, x, y, y + 1.0, colour);
- ++x;
- }
- }
- }
- }
- }
-
- void LowLevelGraphicsSoftwareRenderer::drawVerticalLine (const int x, double top, double bottom, const Colour& col)
- {
- for (RectangleList::Iterator i (*clip); i.next();)
- {
- const Rectangle& r = *i.getRectangle();
-
- clippedDrawVerticalLine (r.getX(), r.getY(), r.getWidth(), r.getHeight(),
- x + xOffset, top + yOffset, bottom + yOffset, col);
- }
- }
-
- void LowLevelGraphicsSoftwareRenderer::clippedDrawVerticalLine (int clipX, int clipY, int clipW, int clipH,
- const int x, double top, double bottom, const Colour& col)
- {
- jassert (top <= bottom);
-
- if (((unsigned int) (x - clipX)) < (unsigned int) clipW
- && top < clipY + clipH
- && bottom > clipY
- && clipW > 0)
- {
- if (top < clipY)
- top = clipY;
-
- if (bottom > clipY + clipH)
- bottom = clipY + clipH;
-
- if (bottom > top)
- drawVertical (x, top, bottom, col);
- }
- }
-
- void LowLevelGraphicsSoftwareRenderer::drawHorizontalLine (const int y, double left, double right, const Colour& col)
- {
- for (RectangleList::Iterator i (*clip); i.next();)
- {
- const Rectangle& r = *i.getRectangle();
-
- clippedDrawHorizontalLine (r.getX(), r.getY(), r.getWidth(), r.getHeight(),
- y + yOffset, left + xOffset, right + xOffset, col);
- }
- }
-
- void LowLevelGraphicsSoftwareRenderer::clippedDrawHorizontalLine (int clipX, int clipY, int clipW, int clipH,
- const int y, double left, double right, const Colour& col)
- {
- jassert (left <= right);
-
- if (((unsigned int) (y - clipY)) < (unsigned int) clipH
- && left < clipX + clipW
- && right > clipX
- && clipW > 0)
- {
- if (left < clipX)
- left = clipX;
-
- if (right > clipX + clipW)
- right = clipX + clipW;
-
- if (right > left)
- drawHorizontal (y, left, right, col);
- }
- }
-
- void LowLevelGraphicsSoftwareRenderer::drawVertical (const int x,
- const double top,
- const double bottom,
- const Colour& col)
- {
- int wholeStart = (int) top;
- const int wholeEnd = (int) bottom;
-
- const int lastAlpha = roundDoubleToInt (255.0 * (bottom - wholeEnd));
- const int totalPixels = (wholeEnd - wholeStart) + (lastAlpha > 0 ? 1 : 0);
-
- if (totalPixels <= 0)
- return;
-
- int lineStride, dstPixelStride;
- uint8* const dstPixels = image.lockPixelDataReadWrite (x, wholeStart, 1, totalPixels, lineStride, dstPixelStride);
- uint8* dest = dstPixels;
-
- PixelARGB colour (col.getPixelARGB());
-
- if (wholeEnd == wholeStart)
- {
- if (image.getFormat() == Image::ARGB)
- ((PixelARGB*) dest)->blend (colour, roundDoubleToInt (255.0 * (bottom - top)));
- else if (image.getFormat() == Image::RGB)
- ((PixelRGB*) dest)->blend (colour, roundDoubleToInt (255.0 * (bottom - top)));
- else
- {
- jassertfalse
- }
- }
- else
- {
- if (image.getFormat() == Image::ARGB)
- {
- ((PixelARGB*) dest)->blend (colour, roundDoubleToInt (255.0 * (1.0 - (top - wholeStart))));
- ++wholeStart;
- dest += lineStride;
-
- if (colour.getAlpha() == 0xff)
- {
- while (wholeEnd > wholeStart)
- {
- ((PixelARGB*) dest)->set (colour);
- ++wholeStart;
- dest += lineStride;
- }
- }
- else
- {
- while (wholeEnd > wholeStart)
- {
- ((PixelARGB*) dest)->blend (colour);
- ++wholeStart;
- dest += lineStride;
- }
- }
-
- if (lastAlpha > 0)
- {
- ((PixelARGB*) dest)->blend (colour, lastAlpha);
- }
- }
- else if (image.getFormat() == Image::RGB)
- {
- ((PixelRGB*) dest)->blend (colour, roundDoubleToInt (255.0 * (1.0 - (top - wholeStart))));
- ++wholeStart;
- dest += lineStride;
-
- if (colour.getAlpha() == 0xff)
- {
- while (wholeEnd > wholeStart)
- {
- ((PixelRGB*) dest)->set (colour);
- ++wholeStart;
- dest += lineStride;
- }
- }
- else
- {
- while (wholeEnd > wholeStart)
- {
- ((PixelRGB*) dest)->blend (colour);
- ++wholeStart;
- dest += lineStride;
- }
- }
-
- if (lastAlpha > 0)
- {
- ((PixelRGB*) dest)->blend (colour, lastAlpha);
- }
- }
- else
- {
- jassertfalse
- }
- }
-
- image.releasePixelDataReadWrite (dstPixels);
- }
-
- void LowLevelGraphicsSoftwareRenderer::drawHorizontal (const int y,
- const double top,
- const double bottom,
- const Colour& col)
- {
- int wholeStart = (int) top;
- const int wholeEnd = (int) bottom;
-
- const int lastAlpha = roundDoubleToInt (255.0 * (bottom - wholeEnd));
- const int totalPixels = (wholeEnd - wholeStart) + (lastAlpha > 0 ? 1 : 0);
-
- if (totalPixels <= 0)
- return;
-
- int lineStride, dstPixelStride;
- uint8* const dstPixels = image.lockPixelDataReadWrite (wholeStart, y, totalPixels, 1, lineStride, dstPixelStride);
- uint8* dest = dstPixels;
-
- PixelARGB colour (col.getPixelARGB());
-
- if (wholeEnd == wholeStart)
- {
- if (image.getFormat() == Image::ARGB)
- ((PixelARGB*) dest)->blend (colour, roundDoubleToInt (255.0 * (bottom - top)));
- else if (image.getFormat() == Image::RGB)
- ((PixelRGB*) dest)->blend (colour, roundDoubleToInt (255.0 * (bottom - top)));
- else
- {
- jassertfalse
- }
- }
- else
- {
- if (image.getFormat() == Image::ARGB)
- {
- ((PixelARGB*) dest)->blend (colour, roundDoubleToInt (255.0 * (1.0 - (top - wholeStart))));
- dest += dstPixelStride;
- ++wholeStart;
-
- if (colour.getAlpha() == 0xff)
- {
- while (wholeEnd > wholeStart)
- {
- ((PixelARGB*) dest)->set (colour);
- dest += dstPixelStride;
- ++wholeStart;
- }
- }
- else
- {
- while (wholeEnd > wholeStart)
- {
- ((PixelARGB*) dest)->blend (colour);
- dest += dstPixelStride;
- ++wholeStart;
- }
- }
-
- if (lastAlpha > 0)
- {
- ((PixelARGB*) dest)->blend (colour, lastAlpha);
- }
- }
- else if (image.getFormat() == Image::RGB)
- {
- ((PixelRGB*) dest)->blend (colour, roundDoubleToInt (255.0 * (1.0 - (top - wholeStart))));
- dest += dstPixelStride;
- ++wholeStart;
-
- if (colour.getAlpha() == 0xff)
- {
- while (wholeEnd > wholeStart)
- {
- ((PixelRGB*) dest)->set (colour);
- dest += dstPixelStride;
- ++wholeStart;
- }
- }
- else
- {
- while (wholeEnd > wholeStart)
- {
- ((PixelRGB*) dest)->blend (colour);
- dest += dstPixelStride;
- ++wholeStart;
- }
- }
-
- if (lastAlpha > 0)
- {
- ((PixelRGB*) dest)->blend (colour, lastAlpha);
- }
- }
- else
- {
- jassertfalse
- }
- }
-
- image.releasePixelDataReadWrite (dstPixels);
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_LowLevelGraphicsSoftwareRenderer.cpp *********/
-
- /********* Start of inlined file: juce_RectanglePlacement.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- RectanglePlacement::RectanglePlacement (const RectanglePlacement& other) throw()
- : flags (other.flags)
- {
- }
-
- const RectanglePlacement& RectanglePlacement::operator= (const RectanglePlacement& other) throw()
- {
- flags = other.flags;
- return *this;
- }
-
- void RectanglePlacement::applyTo (double& x, double& y,
- double& w, double& h,
- const double dx, const double dy,
- const double dw, const double dh) const throw()
- {
- if (w == 0 || h == 0)
- return;
-
- if ((flags & stretchToFit) != 0)
- {
- x = dx;
- y = dy;
- w = dw;
- h = dh;
- }
- else
- {
- double scale = (flags & fillDestination) != 0 ? jmax (dw / w, dh / h)
- : jmin (dw / w, dh / h);
-
- if ((flags & onlyReduceInSize) != 0)
- scale = jmin (scale, 1.0);
-
- if ((flags & onlyIncreaseInSize) != 0)
- scale = jmax (scale, 1.0);
-
- w *= scale;
- h *= scale;
-
- if ((flags & xLeft) != 0)
- x = dx;
- else if ((flags & xRight) != 0)
- x = dx + dw - w;
- else
- x = dx + (dw - w) * 0.5;
-
- if ((flags & yTop) != 0)
- y = dy;
- else if ((flags & yBottom) != 0)
- y = dy + dh - h;
- else
- y = dy + (dh - h) * 0.5;
- }
- }
-
- const AffineTransform RectanglePlacement::getTransformToFit (float x, float y,
- float w, float h,
- const float dx, const float dy,
- const float dw, const float dh) const throw()
- {
- if (w == 0 || h == 0)
- return AffineTransform::identity;
-
- const float scaleX = dw / w;
- const float scaleY = dh / h;
-
- if ((flags & stretchToFit) != 0)
- {
- return AffineTransform::translation (-x, -y)
- .scaled (scaleX, scaleY)
- .translated (dx - x, dy - y);
- }
-
- float scale = (flags & fillDestination) != 0 ? jmax (scaleX, scaleY)
- : jmin (scaleX, scaleY);
-
- if ((flags & onlyReduceInSize) != 0)
- scale = jmin (scale, 1.0f);
-
- if ((flags & onlyIncreaseInSize) != 0)
- scale = jmax (scale, 1.0f);
-
- w *= scale;
- h *= scale;
-
- float newX = dx;
-
- if ((flags & xRight) != 0)
- newX += dw - w; // right
- else if ((flags & xLeft) == 0)
- newX += (dw - w) / 2.0f; // centre
-
- float newY = dy;
-
- if ((flags & yBottom) != 0)
- newY += dh - h; // bottom
- else if ((flags & yTop) == 0)
- newY += (dh - h) / 2.0f; // centre
-
- return AffineTransform::translation (-x, -y)
- .scaled (scale, scale)
- .translated (newX, newY);
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_RectanglePlacement.cpp *********/
-
- /********* Start of inlined file: juce_Drawable.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- Drawable::Drawable()
- {
- }
-
- Drawable::~Drawable()
- {
- }
-
- void Drawable::drawAt (Graphics& g, const float x, const float y) const
- {
- draw (g, AffineTransform::translation (x, y));
- }
-
- void Drawable::drawWithin (Graphics& g,
- const int destX,
- const int destY,
- const int destW,
- const int destH,
- const RectanglePlacement& placement) const
- {
- if (destW > 0 && destH > 0)
- {
- float x, y, w, h;
- getBounds (x, y, w, h);
-
- draw (g, placement.getTransformToFit (x, y, w, h,
- (float) destX, (float) destY,
- (float) destW, (float) destH));
- }
- }
-
- Drawable* Drawable::createFromImageData (const void* data, const int numBytes)
- {
- Drawable* result = 0;
-
- Image* const image = ImageFileFormat::loadFrom (data, numBytes);
-
- if (image != 0)
- {
- DrawableImage* const di = new DrawableImage();
- di->setImage (image, true);
- result = di;
- }
- else
- {
- const String asString (String::createStringFromData (data, numBytes));
-
- XmlDocument doc (asString);
- XmlElement* const outer = doc.getDocumentElement (true);
-
- if (outer != 0 && outer->hasTagName (T("svg")))
- {
- XmlElement* const svg = doc.getDocumentElement();
-
- if (svg != 0)
- {
- result = Drawable::createFromSVG (*svg);
- delete svg;
- }
- }
-
- delete outer;
- }
-
- return result;
- }
-
- Drawable* Drawable::createFromImageDataStream (InputStream& dataSource)
- {
- MemoryBlock mb;
- dataSource.readIntoMemoryBlock (mb);
-
- return createFromImageData (mb.getData(), mb.getSize());
- }
-
- Drawable* Drawable::createFromImageFile (const File& file)
- {
- FileInputStream* fin = file.createInputStream();
-
- if (fin == 0)
- return 0;
-
- Drawable* d = createFromImageDataStream (*fin);
- delete fin;
-
- return d;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_Drawable.cpp *********/
-
- /********* Start of inlined file: juce_DrawableComposite.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- DrawableComposite::DrawableComposite()
- {
- }
-
- DrawableComposite::~DrawableComposite()
- {
- }
-
- void DrawableComposite::insertDrawable (Drawable* drawable,
- const AffineTransform& transform,
- const int index)
- {
- if (drawable != 0)
- {
- if (! drawables.contains (drawable))
- {
- drawables.insert (index, drawable);
-
- if (transform.isIdentity())
- transforms.insert (index, 0);
- else
- transforms.insert (index, new AffineTransform (transform));
- }
- else
- {
- jassertfalse // trying to add a drawable that's already in here!
- }
- }
- }
-
- void DrawableComposite::insertDrawable (const Drawable& drawable,
- const AffineTransform& transform,
- const int index)
- {
- insertDrawable (drawable.createCopy(), transform, index);
- }
-
- void DrawableComposite::removeDrawable (const int index)
- {
- drawables.remove (index);
- transforms.remove (index);
- }
-
- void DrawableComposite::bringToFront (const int index)
- {
- if (index >= 0 && index < drawables.size() - 1)
- {
- drawables.move (index, -1);
- transforms.move (index, -1);
- }
- }
-
- void DrawableComposite::draw (Graphics& g, const AffineTransform& transform) const
- {
- for (int i = 0; i < drawables.size(); ++i)
- {
- const AffineTransform* const t = transforms.getUnchecked(i);
-
- drawables.getUnchecked(i)->draw (g, t == 0 ? transform
- : t->followedBy (transform));
- }
- }
-
- void DrawableComposite::getBounds (float& x, float& y, float& width, float& height) const
- {
- Path totalPath;
-
- for (int i = 0; i < drawables.size(); ++i)
- {
- drawables.getUnchecked(i)->getBounds (x, y, width, height);
-
- if (width > 0.0f && height > 0.0f)
- {
- Path outline;
- outline.addRectangle (x, y, width, height);
-
- const AffineTransform* const t = transforms.getUnchecked(i);
-
- if (t == 0)
- totalPath.addPath (outline);
- else
- totalPath.addPath (outline, *t);
- }
- }
-
- totalPath.getBounds (x, y, width, height);
- }
-
- bool DrawableComposite::hitTest (float x, float y) const
- {
- for (int i = 0; i < drawables.size(); ++i)
- {
- float tx = x;
- float ty = y;
-
- const AffineTransform* const t = transforms.getUnchecked(i);
-
- if (t != 0)
- t->inverted().transformPoint (tx, ty);
-
- if (drawables.getUnchecked(i)->hitTest (tx, ty))
- return true;
- }
-
- return false;
- }
-
- Drawable* DrawableComposite::createCopy() const
- {
- DrawableComposite* const dc = new DrawableComposite();
-
- for (int i = 0; i < drawables.size(); ++i)
- {
- dc->drawables.add (drawables.getUnchecked(i)->createCopy());
-
- const AffineTransform* const t = transforms.getUnchecked(i);
- dc->transforms.add (t != 0 ? new AffineTransform (*t) : 0);
- }
-
- return dc;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_DrawableComposite.cpp *********/
-
- /********* Start of inlined file: juce_DrawableImage.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- DrawableImage::DrawableImage()
- : image (0),
- canDeleteImage (false),
- opacity (1.0f),
- overlayColour (0x00000000)
- {
- }
-
- DrawableImage::~DrawableImage()
- {
- clearImage();
- }
-
- void DrawableImage::clearImage()
- {
- if (canDeleteImage && image != 0)
- {
- if (ImageCache::isImageInCache (image))
- ImageCache::release (image);
- else
- delete image;
- }
-
- image = 0;
- }
-
- void DrawableImage::setImage (const Image& imageToCopy)
- {
- clearImage();
- image = new Image (imageToCopy);
- canDeleteImage = true;
- }
-
- void DrawableImage::setImage (Image* imageToUse,
- const bool releaseWhenNotNeeded)
- {
- clearImage();
- image = imageToUse;
- canDeleteImage = releaseWhenNotNeeded;
- }
-
- void DrawableImage::setOpacity (const float newOpacity)
- {
- opacity = newOpacity;
- }
-
- void DrawableImage::setOverlayColour (const Colour& newOverlayColour)
- {
- overlayColour = newOverlayColour;
- }
-
- void DrawableImage::draw (Graphics& g, const AffineTransform& transform) const
- {
- if (image != 0)
- {
- const Colour oldColour (g.getCurrentColour()); // save this so we can restore it later
-
- if (opacity > 0.0f && ! overlayColour.isOpaque())
- {
- g.setColour (oldColour.withMultipliedAlpha (opacity));
-
- g.drawImageTransformed (image,
- 0, 0, image->getWidth(), image->getHeight(),
- transform, false);
- }
-
- if (! overlayColour.isTransparent())
- {
- g.setColour (overlayColour.withMultipliedAlpha (oldColour.getFloatAlpha()));
-
- g.drawImageTransformed (image,
- 0, 0, image->getWidth(), image->getHeight(),
- transform, true);
- }
-
- g.setColour (oldColour);
- }
- }
-
- void DrawableImage::getBounds (float& x, float& y, float& width, float& height) const
- {
- x = 0.0f;
- y = 0.0f;
- width = 0.0f;
- height = 0.0f;
-
- if (image != 0)
- {
- width = (float) image->getWidth();
- height = (float) image->getHeight();
- }
- }
-
- bool DrawableImage::hitTest (float x, float y) const
- {
- return image != 0
- && x >= 0.0f
- && y >= 0.0f
- && x < image->getWidth()
- && y < image->getHeight()
- && image->getPixelAt (roundFloatToInt (x), roundFloatToInt (y)).getAlpha() >= 127;
- }
-
- Drawable* DrawableImage::createCopy() const
- {
- DrawableImage* const di = new DrawableImage();
-
- di->opacity = opacity;
- di->overlayColour = overlayColour;
-
- if (image != 0)
- {
- if ((! canDeleteImage) || ! ImageCache::isImageInCache (image))
- {
- di->setImage (*image);
- }
- else
- {
- ImageCache::incReferenceCount (image);
- di->setImage (image, true);
- }
- }
-
- return di;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_DrawableImage.cpp *********/
-
- /********* Start of inlined file: juce_DrawablePath.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- DrawablePath::DrawablePath()
- : fillBrush (new SolidColourBrush (Colours::black)),
- strokeBrush (0),
- strokeType (0.0f)
- {
- }
-
- DrawablePath::~DrawablePath()
- {
- delete fillBrush;
- delete strokeBrush;
- }
-
- void DrawablePath::setPath (const Path& newPath)
- {
- path = newPath;
- updateOutline();
- }
-
- void DrawablePath::setSolidFill (const Colour& newColour)
- {
- delete fillBrush;
- fillBrush = new SolidColourBrush (newColour);
- }
-
- void DrawablePath::setFillBrush (const Brush& newBrush)
- {
- delete fillBrush;
- fillBrush = newBrush.createCopy();
- }
-
- void DrawablePath::setOutline (const float thickness, const Colour& colour)
- {
- strokeType = PathStrokeType (thickness);
- delete strokeBrush;
- strokeBrush = new SolidColourBrush (colour);
- updateOutline();
- }
-
- void DrawablePath::setOutline (const PathStrokeType& strokeType_, const Brush& newStrokeBrush)
- {
- strokeType = strokeType_;
- delete strokeBrush;
- strokeBrush = newStrokeBrush.createCopy();
- updateOutline();
- }
-
- void DrawablePath::draw (Graphics& g, const AffineTransform& transform) const
- {
- const Colour oldColour (g.getCurrentColour()); // save this so we can restore it later
- const float currentOpacity = oldColour.getFloatAlpha();
-
- {
- Brush* const tempBrush = fillBrush->createCopy();
- tempBrush->applyTransform (transform);
- tempBrush->multiplyOpacity (currentOpacity);
-
- g.setBrush (tempBrush);
- g.fillPath (path, transform);
-
- delete tempBrush;
- }
-
- if (strokeBrush != 0 && strokeType.getStrokeThickness() > 0.0f)
- {
- Brush* const tempBrush = strokeBrush->createCopy();
- tempBrush->applyTransform (transform);
- tempBrush->multiplyOpacity (currentOpacity);
-
- g.setBrush (tempBrush);
- g.fillPath (outline, transform);
-
- delete tempBrush;
- }
-
- g.setColour (oldColour);
- }
-
- void DrawablePath::updateOutline()
- {
- outline.clear();
- strokeType.createStrokedPath (outline, path, AffineTransform::identity, 4.0f);
- }
-
- void DrawablePath::getBounds (float& x, float& y, float& width, float& height) const
- {
- if (strokeType.getStrokeThickness() > 0.0f)
- outline.getBounds (x, y, width, height);
- else
- path.getBounds (x, y, width, height);
- }
-
- bool DrawablePath::hitTest (float x, float y) const
- {
- return path.contains (x, y)
- || outline.contains (x, y);
- }
-
- Drawable* DrawablePath::createCopy() const
- {
- DrawablePath* const dp = new DrawablePath();
-
- dp->path = path;
- dp->setFillBrush (*fillBrush);
-
- if (strokeBrush != 0)
- dp->setOutline (strokeType, *strokeBrush);
-
- return dp;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_DrawablePath.cpp *********/
-
- /********* Start of inlined file: juce_DrawableText.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- DrawableText::DrawableText()
- : colour (Colours::white)
- {
- }
-
- DrawableText::~DrawableText()
- {
- }
-
- void DrawableText::setText (const GlyphArrangement& newText)
- {
- text = newText;
- }
-
- void DrawableText::setText (const String& newText, const Font& fontToUse)
- {
- text.clear();
- text.addLineOfText (fontToUse, newText, 0.0f, 0.0f);
- }
-
- void DrawableText::setColour (const Colour& newColour)
- {
- colour = newColour;
- }
-
- void DrawableText::draw (Graphics& g, const AffineTransform& transform) const
- {
- const Colour oldColour (g.getCurrentColour()); // save this so we can restore it later
-
- g.setColour (colour.withMultipliedAlpha (oldColour.getFloatAlpha()));
- text.draw (g, transform);
-
- g.setColour (oldColour);
- }
-
- void DrawableText::getBounds (float& x, float& y, float& width, float& height) const
- {
- text.getBoundingBox (0, -1, x, y, width, height, false); // (really returns top, left, bottom, right)
- width -= x;
- height -= y;
- }
-
- bool DrawableText::hitTest (float x, float y) const
- {
- return text.findGlyphIndexAt (x, y) >= 0;
- }
-
- Drawable* DrawableText::createCopy() const
- {
- DrawableText* const dt = new DrawableText();
-
- dt->text = text;
- dt->colour = colour;
-
- return dt;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_DrawableText.cpp *********/
-
- /********* Start of inlined file: juce_SVGParser.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- class SVGState
- {
- public:
-
- SVGState (const XmlElement* const topLevel)
- : topLevelXml (topLevel),
- x (0), y (0),
- width (512), height (512),
- viewBoxW (0), viewBoxH (0)
- {
- }
-
- ~SVGState()
- {
- }
-
- Drawable* parseSVGElement (const XmlElement& xml)
- {
- if (! xml.hasTagName (T("svg")))
- return 0;
-
- DrawableComposite* const drawable = new DrawableComposite();
-
- drawable->setName (xml.getStringAttribute (T("id")));
-
- SVGState newState (*this);
-
- if (xml.hasAttribute (T("transform")))
- newState.addTransform (xml);
-
- newState.x = getCoordLength (xml.getStringAttribute (T("x"), String (newState.x)), viewBoxW);
- newState.y = getCoordLength (xml.getStringAttribute (T("y"), String (newState.y)), viewBoxH);
- newState.width = getCoordLength (xml.getStringAttribute (T("width"), String (newState.width)), viewBoxW);
- newState.height = getCoordLength (xml.getStringAttribute (T("height"), String (newState.height)), viewBoxH);
-
- if (xml.hasAttribute (T("viewBox")))
- {
- const String viewParams (xml.getStringAttribute (T("viewBox")));
- int i = 0;
- float vx, vy, vw, vh;
-
- if (parseCoords (viewParams, vx, vy, i, true)
- && parseCoords (viewParams, vw, vh, i, true)
- && vw > 0
- && vh > 0)
- {
- newState.viewBoxW = vw;
- newState.viewBoxH = vh;
-
- int placementFlags = 0;
-
- const String aspect (xml.getStringAttribute (T("preserveAspectRatio")));
-
- if (aspect.containsIgnoreCase (T("none")))
- {
- placementFlags = RectanglePlacement::stretchToFit;
- }
- else
- {
- if (aspect.containsIgnoreCase (T("slice")))
- placementFlags |= RectanglePlacement::fillDestination;
-
- if (aspect.containsIgnoreCase (T("xMin")))
- placementFlags |= RectanglePlacement::xLeft;
- else if (aspect.containsIgnoreCase (T("xMax")))
- placementFlags |= RectanglePlacement::xRight;
- else
- placementFlags |= RectanglePlacement::xMid;
-
- if (aspect.containsIgnoreCase (T("yMin")))
- placementFlags |= RectanglePlacement::yTop;
- else if (aspect.containsIgnoreCase (T("yMax")))
- placementFlags |= RectanglePlacement::yBottom;
- else
- placementFlags |= RectanglePlacement::yMid;
- }
-
- const RectanglePlacement placement (placementFlags);
-
- newState.transform
- = placement.getTransformToFit (vx, vy, vw, vh,
- 0.0f, 0.0f, newState.width, newState.height)
- .followedBy (newState.transform);
- }
- }
- else
- {
- if (viewBoxW == 0)
- newState.viewBoxW = newState.width;
-
- if (viewBoxH == 0)
- newState.viewBoxH = newState.height;
- }
-
- newState.parseSubElements (xml, drawable);
-
- return drawable;
- }
-
- private:
-
- const XmlElement* const topLevelXml;
- float x, y, width, height, viewBoxW, viewBoxH;
- AffineTransform transform;
- String cssStyleText;
-
- void parseSubElements (const XmlElement& xml, DrawableComposite* const parentDrawable)
- {
- forEachXmlChildElement (xml, e)
- {
- Drawable* d = 0;
-
- if (e->hasTagName (T("g")))
- d = parseGroupElement (*e);
- else if (e->hasTagName (T("svg")))
- d = parseSVGElement (*e);
- else if (e->hasTagName (T("path")))
- d = parsePath (*e);
- else if (e->hasTagName (T("rect")))
- d = parseRect (*e);
- else if (e->hasTagName (T("circle")))
- d = parseCircle (*e);
- else if (e->hasTagName (T("ellipse")))
- d = parseEllipse (*e);
- else if (e->hasTagName (T("line")))
- d = parseLine (*e);
- else if (e->hasTagName (T("polyline")))
- d = parsePolygon (*e, true);
- else if (e->hasTagName (T("polygon")))
- d = parsePolygon (*e, false);
- else if (e->hasTagName (T("text")))
- d = parseText (*e);
- else if (e->hasTagName (T("switch")))
- d = parseSwitch (*e);
- else if (e->hasTagName (T("style")))
- parseCSSStyle (*e);
-
- parentDrawable->insertDrawable (d);
- }
- }
-
- DrawableComposite* parseSwitch (const XmlElement& xml)
- {
- const XmlElement* const group = xml.getChildByName (T("g"));
-
- if (group != 0)
- return parseGroupElement (*group);
-
- return 0;
- }
-
- DrawableComposite* parseGroupElement (const XmlElement& xml)
- {
- DrawableComposite* const drawable = new DrawableComposite();
-
- drawable->setName (xml.getStringAttribute (T("id")));
-
- if (xml.hasAttribute (T("transform")))
- {
- SVGState newState (*this);
- newState.addTransform (xml);
-
- newState.parseSubElements (xml, drawable);
- }
- else
- {
- parseSubElements (xml, drawable);
- }
-
- return drawable;
- }
-
- Drawable* parsePath (const XmlElement& xml) const
- {
- const String d (xml.getStringAttribute (T("d")).trimStart());
- Path path;
-
- if (getStyleAttribute (&xml, T("fill-rule")).trim().equalsIgnoreCase (T("evenodd")))
- path.setUsingNonZeroWinding (false);
-
- int index = 0;
- float lastX = 0, lastY = 0;
- float lastX2 = 0, lastY2 = 0;
- tchar lastCommandChar = 0;
- bool carryOn = true;
-
- const String validCommandChars (T("MmLlHhVvCcSsQqTtAaZz"));
-
- for (;;)
- {
- float x, y, x2, y2, x3, y3;
- const bool isRelative = (d[index] >= 'a' && d[index] <= 'z');
-
- if (validCommandChars.containsChar (d[index]))
- lastCommandChar = d [index++];
-
- switch (lastCommandChar)
- {
- case T('M'):
- case T('m'):
- case T('L'):
- case T('l'):
- if (parseCoords (d, x, y, index, false))
- {
- if (isRelative)
- {
- x += lastX;
- y += lastY;
- }
-
- if (lastCommandChar == T('M') || lastCommandChar == T('m'))
- path.startNewSubPath (x, y);
- else
- path.lineTo (x, y);
-
- lastX2 = lastX;
- lastY2 = lastY;
- lastX = x;
- lastY = y;
- }
- else
- {
- ++index;
- }
-
- break;
-
- case T('H'):
- case T('h'):
- if (parseCoord (d, x, index, false, true))
- {
- if (isRelative)
- x += lastX;
-
- path.lineTo (x, lastY);
-
- lastX2 = lastX;
- lastX = x;
- }
- else
- {
- ++index;
- }
- break;
-
- case T('V'):
- case T('v'):
- if (parseCoord (d, y, index, false, false))
- {
- if (isRelative)
- y += lastY;
-
- path.lineTo (lastX, y);
-
- lastY2 = lastY;
- lastY = y;
- }
- else
- {
- ++index;
- }
- break;
-
- case T('C'):
- case T('c'):
- if (parseCoords (d, x, y, index, false)
- && parseCoords (d, x2, y2, index, false)
- && parseCoords (d, x3, y3, index, false))
- {
- if (isRelative)
- {
- x += lastX;
- y += lastY;
- x2 += lastX;
- y2 += lastY;
- x3 += lastX;
- y3 += lastY;
- }
-
- path.cubicTo (x, y, x2, y2, x3, y3);
-
- lastX2 = x2;
- lastY2 = y2;
- lastX = x3;
- lastY = y3;
- }
- else
- {
- ++index;
- }
- break;
-
- case T('S'):
- case T('s'):
- if (parseCoords (d, x, y, index, false)
- && parseCoords (d, x3, y3, index, false))
- {
- if (isRelative)
- {
- x += lastX;
- y += lastY;
- x3 += lastX;
- y3 += lastY;
- }
-
- x2 = lastX + (lastX - lastX2);
- y2 = lastY + (lastY - lastY2);
- path.cubicTo (x2, y2, x, y, x3, y3);
-
- lastX2 = x2;
- lastY2 = y2;
- lastX = x3;
- lastY = y3;
- }
- else
- {
- ++index;
- }
- break;
-
- case T('Q'):
- case T('q'):
- if (parseCoords (d, x, y, index, false)
- && parseCoords (d, x2, y2, index, false))
- {
- if (isRelative)
- {
- x += lastX;
- y += lastY;
- x2 += lastX;
- y2 += lastY;
- }
-
- path.quadraticTo (x, y, x2, y2);
-
- lastX2 = x;
- lastY2 = y;
- lastX = x2;
- lastY = y2;
- }
- else
- {
- ++index;
- }
- break;
-
- case T('T'):
- case T('t'):
- if (parseCoords (d, x, y, index, false))
- {
- if (isRelative)
- {
- x += lastX;
- y += lastY;
- }
-
- x2 = lastX + (lastX - lastX2);
- y2 = lastY + (lastY - lastY2);
- path.quadraticTo (x2, y2, x, y);
-
- lastX2 = x2;
- lastY2 = y2;
- lastX = x;
- lastY = y;
- }
- else
- {
- ++index;
- }
- break;
-
- case T('A'):
- case T('a'):
- if (parseCoords (d, x, y, index, false))
- {
- String num;
-
- if (parseNextNumber (d, num, index, false))
- {
- const float angle = num.getFloatValue() * (180.0f / float_Pi);
-
- if (parseNextNumber (d, num, index, false))
- {
- const bool largeArc = num.getIntValue() != 0;
-
- if (parseNextNumber (d, num, index, false))
- {
- const bool sweep = num.getIntValue() != 0;
-
- if (parseCoords (d, x2, y2, index, false))
- {
- if (isRelative)
- {
- x2 += lastX;
- y2 += lastY;
- }
-
- if (lastX != x2 || lastY != y2)
- {
- double centreX, centreY, startAngle, deltaAngle;
- double rx = x, ry = y;
-
- endpointToCentreParameters (lastX, lastY, x2, y2,
- angle, largeArc, sweep,
- rx, ry, centreX, centreY,
- startAngle, deltaAngle);
-
- path.addCentredArc ((float) centreX, (float) centreY,
- (float) rx, (float) ry,
- angle, (float) startAngle, (float) (startAngle + deltaAngle),
- false);
-
- path.lineTo (x2, y2);
- }
-
- lastX2 = lastX;
- lastY2 = lastY;
- lastX = x2;
- lastY = y2;
- }
- }
- }
- }
- }
- else
- {
- ++index;
- }
-
- break;
-
- case T('Z'):
- case T('z'):
- path.closeSubPath();
- while (CharacterFunctions::isWhitespace (d [index]))
- ++index;
-
- break;
-
- default:
- carryOn = false;
- break;
- }
-
- if (! carryOn)
- break;
- }
-
- return parseShape (xml, path);
- }
-
- Drawable* parseRect (const XmlElement& xml) const
- {
- Path rect;
-
- const bool hasRX = xml.hasAttribute (T("rx"));
- const bool hasRY = xml.hasAttribute (T("ry"));
-
- if (hasRX || hasRY)
- {
- float rx = getCoordLength (xml.getStringAttribute (T("rx")), viewBoxW);
- float ry = getCoordLength (xml.getStringAttribute (T("ry")), viewBoxH);
-
- if (! hasRX)
- rx = ry;
- else if (! hasRY)
- ry = rx;
-
- rect.addRoundedRectangle (getCoordLength (xml.getStringAttribute (T("x")), viewBoxW),
- getCoordLength (xml.getStringAttribute (T("y")), viewBoxH),
- getCoordLength (xml.getStringAttribute (T("width")), viewBoxW),
- getCoordLength (xml.getStringAttribute (T("height")), viewBoxH),
- rx, ry);
- }
- else
- {
- rect.addRectangle (getCoordLength (xml.getStringAttribute (T("x")), viewBoxW),
- getCoordLength (xml.getStringAttribute (T("y")), viewBoxH),
- getCoordLength (xml.getStringAttribute (T("width")), viewBoxW),
- getCoordLength (xml.getStringAttribute (T("height")), viewBoxH));
- }
-
- return parseShape (xml, rect);
- }
-
- Drawable* parseCircle (const XmlElement& xml) const
- {
- Path circle;
-
- const float cx = getCoordLength (xml.getStringAttribute (T("cx")), viewBoxW);
- const float cy = getCoordLength (xml.getStringAttribute (T("cy")), viewBoxH);
- const float radius = getCoordLength (xml.getStringAttribute (T("r")), viewBoxW);
-
- circle.addEllipse (cx - radius, cy - radius, radius * 2.0f, radius * 2.0f);
-
- return parseShape (xml, circle);
- }
-
- Drawable* parseEllipse (const XmlElement& xml) const
- {
- Path ellipse;
-
- const float cx = getCoordLength (xml.getStringAttribute (T("cx")), viewBoxW);
- const float cy = getCoordLength (xml.getStringAttribute (T("cy")), viewBoxH);
- const float radiusX = getCoordLength (xml.getStringAttribute (T("rx")), viewBoxW);
- const float radiusY = getCoordLength (xml.getStringAttribute (T("ry")), viewBoxH);
-
- ellipse.addEllipse (cx - radiusX, cy - radiusY, radiusX * 2.0f, radiusY * 2.0f);
-
- return parseShape (xml, ellipse);
- }
-
- Drawable* parseLine (const XmlElement& xml) const
- {
- Path line;
-
- const float x1 = getCoordLength (xml.getStringAttribute (T("x1")), viewBoxW);
- const float y1 = getCoordLength (xml.getStringAttribute (T("y1")), viewBoxH);
- const float x2 = getCoordLength (xml.getStringAttribute (T("x2")), viewBoxW);
- const float y2 = getCoordLength (xml.getStringAttribute (T("y2")), viewBoxH);
-
- line.startNewSubPath (x1, y1);
- line.lineTo (x2, y2);
-
- return parseShape (xml, line);
- }
-
- Drawable* parsePolygon (const XmlElement& xml, const bool isPolyline) const
- {
- const String points (xml.getStringAttribute (T("points")));
- Path path;
-
- int index = 0;
- float x, y;
-
- if (parseCoords (points, x, y, index, true))
- {
- float firstX = x;
- float firstY = y;
- float lastX = 0, lastY = 0;
-
- path.startNewSubPath (x, y);
-
- while (parseCoords (points, x, y, index, true))
- {
- lastX = x;
- lastY = y;
- path.lineTo (x, y);
- }
-
- if ((! isPolyline) || (firstX == lastX && firstY == lastY))
- path.closeSubPath();
- }
-
- return parseShape (xml, path);
- }
-
- Drawable* parseShape (const XmlElement& xml, Path& path,
- const bool parseTransform = true) const
- {
- if (parseTransform && xml.hasAttribute (T("transform")))
- {
- SVGState newState (*this);
- newState.addTransform (xml);
-
- return newState.parseShape (xml, path, false);
- }
-
- DrawablePath* dp = new DrawablePath();
- dp->setSolidFill (Colours::transparentBlack);
-
- path.applyTransform (transform);
- dp->setPath (path);
-
- Path::Iterator iter (path);
-
- bool containsClosedSubPath = false;
- while (iter.next())
- {
- if (iter.elementType == Path::Iterator::closePath)
- {
- containsClosedSubPath = true;
- break;
- }
- }
-
- Brush* const fillBrush
- = getBrushForFill (path,
- getStyleAttribute (&xml, T("fill")),
- getStyleAttribute (&xml, T("fill-opacity")),
- getStyleAttribute (&xml, T("opacity")),
- containsClosedSubPath ? Colours::black
- : Colours::transparentBlack);
-
- if (fillBrush != 0)
- {
- if (! fillBrush->isInvisible())
- {
- fillBrush->applyTransform (transform);
- dp->setFillBrush (*fillBrush);
- }
-
- delete fillBrush;
- }
-
- const String strokeType (getStyleAttribute (&xml, T("stroke")));
-
- if (strokeType.isNotEmpty() && ! strokeType.equalsIgnoreCase (T("none")))
- {
- Brush* const strokeBrush
- = getBrushForFill (path, strokeType,
- getStyleAttribute (&xml, T("stroke-opacity")),
- getStyleAttribute (&xml, T("opacity")),
- Colours::transparentBlack);
-
- if (strokeBrush != 0)
- {
- const PathStrokeType stroke (getStrokeFor (&xml));
-
- if (! strokeBrush->isInvisible())
- {
- strokeBrush->applyTransform (transform);
- dp->setOutline (stroke, *strokeBrush);
- }
-
- delete strokeBrush;
- }
- }
-
- return dp;
- }
-
- const XmlElement* findLinkedElement (const XmlElement* e) const
- {
- const String id (e->getStringAttribute (T("xlink:href")));
-
- if (! id.startsWithChar (T('#')))
- return 0;
-
- return findElementForId (topLevelXml, id.substring (1));
- }
-
- void addGradientStopsIn (ColourGradient& cg, const XmlElement* const fillXml) const
- {
- if (fillXml == 0)
- return;
-
- forEachXmlChildElementWithTagName (*fillXml, e, T("stop"))
- {
- int index = 0;
- Colour col (parseColour (getStyleAttribute (e, T("stop-color")), index, Colours::black));
-
- const String opacity (getStyleAttribute (e, T("stop-opacity"), T("1")));
- col = col.withMultipliedAlpha (jlimit (0.0f, 1.0f, opacity.getFloatValue()));
-
- double offset = e->getDoubleAttribute (T("offset"));
-
- if (e->getStringAttribute (T("offset")).containsChar (T('%')))
- offset *= 0.01;
-
- cg.addColour (jlimit (0.0, 1.0, offset), col);
- }
- }
-
- Brush* getBrushForFill (const Path& path,
- const String& fill,
- const String& fillOpacity,
- const String& overallOpacity,
- const Colour& defaultColour) const
- {
- float opacity = 1.0f;
-
- if (overallOpacity.isNotEmpty())
- opacity = jlimit (0.0f, 1.0f, overallOpacity.getFloatValue());
-
- if (fillOpacity.isNotEmpty())
- opacity *= (jlimit (0.0f, 1.0f, fillOpacity.getFloatValue()));
-
- if (fill.startsWithIgnoreCase (T("url")))
- {
- const String id (fill.fromFirstOccurrenceOf (T("#"), false, false)
- .upToLastOccurrenceOf (T(")"), false, false).trim());
-
- const XmlElement* const fillXml = findElementForId (topLevelXml, id);
-
- if (fillXml != 0
- && (fillXml->hasTagName (T("linearGradient"))
- || fillXml->hasTagName (T("radialGradient"))))
- {
- const XmlElement* inheritedFrom = findLinkedElement (fillXml);
-
- ColourGradient cg;
-
- addGradientStopsIn (cg, inheritedFrom);
- addGradientStopsIn (cg, fillXml);
-
- if (cg.getNumColours() > 0)
- {
- cg.addColour (0.0, cg.getColour (0));
- cg.addColour (1.0, cg.getColour (cg.getNumColours() - 1));
- }
- else
- {
- cg.addColour (0.0, Colours::black);
- cg.addColour (1.0, Colours::black);
- }
-
- if (overallOpacity.isNotEmpty())
- cg.multiplyOpacity (overallOpacity.getFloatValue());
-
- jassert (cg.getNumColours() > 0);
-
- cg.isRadial = fillXml->hasTagName (T("radialGradient"));
- cg.transform = parseTransform (fillXml->getStringAttribute (T("gradientTransform")));
-
- float width = viewBoxW;
- float height = viewBoxH;
- float dx = 0.0;
- float dy = 0.0;
-
- const bool userSpace = fillXml->getStringAttribute (T("gradientUnits")).equalsIgnoreCase (T("userSpaceOnUse"));
-
- if (! userSpace)
- path.getBounds (dx, dy, width, height);
-
- if (cg.isRadial)
- {
- cg.x1 = dx + getCoordLength (fillXml->getStringAttribute (T("cx"), T("50%")), width);
- cg.y1 = dy + getCoordLength (fillXml->getStringAttribute (T("cy"), T("50%")), height);
-
- const float radius = getCoordLength (fillXml->getStringAttribute (T("r"), T("50%")), width);
-
- cg.x2 = cg.x1 + radius;
- cg.y2 = cg.y1;
-
- //xxx (the fx, fy focal point isn't handled properly here..)
- }
- else
- {
- cg.x1 = dx + getCoordLength (fillXml->getStringAttribute (T("x1"), T("0%")), width);
- cg.y1 = dy + getCoordLength (fillXml->getStringAttribute (T("y1"), T("0%")), height);
-
- cg.x2 = dx + getCoordLength (fillXml->getStringAttribute (T("x2"), T("100%")), width);
- cg.y2 = dy + getCoordLength (fillXml->getStringAttribute (T("y2"), T("0%")), height);
-
- if (cg.x1 == cg.x2 && cg.y1 == cg.y2)
- return new SolidColourBrush (cg.getColour (cg.getNumColours() - 1));
- }
-
- return new GradientBrush (cg);
- }
- }
-
- if (fill.equalsIgnoreCase (T("none")))
- return new SolidColourBrush (Colours::transparentBlack);
-
- int i = 0;
- Colour colour (parseColour (fill, i, defaultColour));
- colour = colour.withMultipliedAlpha (opacity);
-
- return new SolidColourBrush (colour);
- }
-
- const PathStrokeType getStrokeFor (const XmlElement* const xml) const
- {
- const String width (getStyleAttribute (xml, T("stroke-width")));
- const String cap (getStyleAttribute (xml, T("stroke-linecap")));
- const String join (getStyleAttribute (xml, T("stroke-linejoin")));
-
- //const String mitreLimit (getStyleAttribute (xml, T("stroke-miterlimit")));
- //const String dashArray (getStyleAttribute (xml, T("stroke-dasharray")));
- //const String dashOffset (getStyleAttribute (xml, T("stroke-dashoffset")));
-
- PathStrokeType::JointStyle joinStyle = PathStrokeType::mitered;
- PathStrokeType::EndCapStyle capStyle = PathStrokeType::butt;
-
- if (join.equalsIgnoreCase (T("round")))
- joinStyle = PathStrokeType::curved;
- else if (join.equalsIgnoreCase (T("bevel")))
- joinStyle = PathStrokeType::beveled;
-
- if (cap.equalsIgnoreCase (T("round")))
- capStyle = PathStrokeType::rounded;
- else if (cap.equalsIgnoreCase (T("square")))
- capStyle = PathStrokeType::square;
-
- float ox = 0.0f, oy = 0.0f;
- transform.transformPoint (ox, oy);
- float x = getCoordLength (width, viewBoxW), y = 0.0f;
- transform.transformPoint (x, y);
-
- return PathStrokeType (width.isNotEmpty() ? juce_hypotf (x - ox, y - oy) : 1.0f,
- joinStyle, capStyle);
- }
-
- Drawable* parseText (const XmlElement& xml)
- {
- Array <float> xCoords, yCoords, dxCoords, dyCoords;
-
- getCoordList (xCoords, getInheritedAttribute (&xml, T("x")), true, true);
- getCoordList (yCoords, getInheritedAttribute (&xml, T("y")), true, false);
- getCoordList (dxCoords, getInheritedAttribute (&xml, T("dx")), true, true);
- getCoordList (dyCoords, getInheritedAttribute (&xml, T("dy")), true, false);
-
- //xxx not done text yet!
-
- forEachXmlChildElement (xml, e)
- {
- if (e->isTextElement())
- {
- const String text (e->getText());
-
- Path path;
- Drawable* s = parseShape (*e, path);
- delete s;
- }
- else if (e->hasTagName (T("tspan")))
- {
- Drawable* s = parseText (*e);
- delete s;
- }
- }
-
- return 0;
- }
-
- void addTransform (const XmlElement& xml)
- {
- transform = parseTransform (xml.getStringAttribute (T("transform")))
- .followedBy (transform);
- }
-
- bool parseCoord (const String& s, float& value, int& index,
- const bool allowUnits, const bool isX) const
- {
- String number;
-
- if (! parseNextNumber (s, number, index, allowUnits))
- {
- value = 0;
- return false;
- }
-
- value = getCoordLength (number, isX ? viewBoxW : viewBoxH);
- return true;
- }
-
- bool parseCoords (const String& s, float& x, float& y,
- int& index, const bool allowUnits) const
- {
- return parseCoord (s, x, index, allowUnits, true)
- && parseCoord (s, y, index, allowUnits, false);
- }
-
- float getCoordLength (const String& s, const float sizeForProportions) const
- {
- float n = s.getFloatValue();
- const int len = s.length();
-
- if (len > 2)
- {
- const float dpi = 96.0f;
-
- const tchar n1 = s [len - 2];
- const tchar n2 = s [len - 1];
-
- if (n1 == T('i') && n2 == T('n'))
- n *= dpi;
- else if (n1 == T('m') && n2 == T('m'))
- n *= dpi / 25.4f;
- else if (n1 == T('c') && n2 == T('m'))
- n *= dpi / 2.54f;
- else if (n1 == T('p') && n2 == T('c'))
- n *= 15.0f;
- else if (n2 == T('%'))
- n *= 0.01f * sizeForProportions;
- }
-
- return n;
- }
-
- void getCoordList (Array <float>& coords, const String& list,
- const bool allowUnits, const bool isX) const
- {
- int index = 0;
- float value;
-
- while (parseCoord (list, value, index, allowUnits, isX))
- coords.add (value);
- }
-
- void parseCSSStyle (const XmlElement& xml)
- {
- cssStyleText = xml.getAllSubText() + T("\n") + cssStyleText;
- }
-
- const String getStyleAttribute (const XmlElement* xml, const String& attributeName,
- const String& defaultValue = String::empty) const
- {
- if (xml->hasAttribute (attributeName))
- return xml->getStringAttribute (attributeName, defaultValue);
-
- const String styleAtt (xml->getStringAttribute (T("style")));
-
- if (styleAtt.isNotEmpty())
- {
- const String value (getAttributeFromStyleList (styleAtt, attributeName, String::empty));
-
- if (value.isNotEmpty())
- return value;
- }
- else if (xml->hasAttribute (T("class")))
- {
- const String className (T(".") + xml->getStringAttribute (T("class")));
-
- int index = cssStyleText.indexOfIgnoreCase (className + T(" "));
-
- if (index < 0)
- index = cssStyleText.indexOfIgnoreCase (className + T("{"));
-
- if (index >= 0)
- {
- const int openBracket = cssStyleText.indexOfChar (index, T('{'));
-
- if (openBracket > index)
- {
- const int closeBracket = cssStyleText.indexOfChar (openBracket, T('}'));
-
- if (closeBracket > openBracket)
- {
- const String value (getAttributeFromStyleList (cssStyleText.substring (openBracket + 1, closeBracket), attributeName, defaultValue));
-
- if (value.isNotEmpty())
- return value;
- }
- }
- }
- }
-
- xml = const_cast <XmlElement*> (topLevelXml)->findParentElementOf (xml);
-
- if (xml != 0)
- return getStyleAttribute (xml, attributeName, defaultValue);
-
- return defaultValue;
- }
-
- const String getInheritedAttribute (const XmlElement* xml, const String& attributeName) const
- {
- if (xml->hasAttribute (attributeName))
- return xml->getStringAttribute (attributeName);
-
- xml = const_cast <XmlElement*> (topLevelXml)->findParentElementOf (xml);
-
- if (xml != 0)
- return getInheritedAttribute (xml, attributeName);
-
- return String::empty;
- }
-
- static bool isIdentifierChar (const tchar c)
- {
- return CharacterFunctions::isLetter (c) || c == T('-');
- }
-
- static const String getAttributeFromStyleList (const String& list, const String& attributeName, const String& defaultValue)
- {
- int i = 0;
-
- for (;;)
- {
- i = list.indexOf (i, attributeName);
-
- if (i < 0)
- break;
-
- if ((i == 0 || (i > 0 && ! isIdentifierChar (list [i - 1])))
- && ! isIdentifierChar (list [i + attributeName.length()]))
- {
- i = list.indexOfChar (i, T(':'));
-
- if (i < 0)
- break;
-
- int end = list.indexOfChar (i, T(';'));
-
- if (end < 0)
- end = 0x7ffff;
-
- return list.substring (i + 1, end).trim();
- }
-
- ++i;
- }
-
- return defaultValue;
- }
-
- static bool parseNextNumber (const String& source, String& value, int& index, const bool allowUnits)
- {
- const tchar* const s = (const tchar*) source;
-
- while (CharacterFunctions::isWhitespace (s[index]) || s[index] == T(','))
- ++index;
-
- int start = index;
-
- if (CharacterFunctions::isDigit (s[index]) || s[index] == T('.') || s[index] == T('-'))
- ++index;
-
- while (CharacterFunctions::isDigit (s[index]) || s[index] == T('.'))
- ++index;
-
- if ((s[index] == T('e') || s[index] == T('E'))
- && (CharacterFunctions::isDigit (s[index + 1])
- || s[index + 1] == T('-')
- || s[index + 1] == T('+')))
- {
- index += 2;
-
- while (CharacterFunctions::isDigit (s[index]))
- ++index;
- }
-
- if (allowUnits)
- {
- while (CharacterFunctions::isLetter (s[index]))
- ++index;
- }
-
- if (index == start)
- return false;
-
- value = String (s + start, index - start);
-
- while (CharacterFunctions::isWhitespace (s[index]) || s[index] == T(','))
- ++index;
-
- return true;
- }
-
- static const Colour parseColour (const String& s, int& index, const Colour& defaultColour)
- {
- if (s [index] == T('#'))
- {
- uint32 hex [6];
- zeromem (hex, sizeof (hex));
- int numChars = 0;
-
- for (int i = 6; --i >= 0;)
- {
- const int hexValue = CharacterFunctions::getHexDigitValue (s [++index]);
-
- if (hexValue >= 0)
- hex [numChars++] = hexValue;
- else
- break;
- }
-
- if (numChars <= 3)
- return Colour ((uint8) (hex [0] * 0x11),
- (uint8) (hex [1] * 0x11),
- (uint8) (hex [2] * 0x11));
- else
- return Colour ((uint8) ((hex [0] << 4) + hex [1]),
- (uint8) ((hex [2] << 4) + hex [3]),
- (uint8) ((hex [4] << 4) + hex [5]));
- }
- else if (s [index] == T('r')
- && s [index + 1] == T('g')
- && s [index + 2] == T('b'))
- {
- const int openBracket = s.indexOfChar (index, T('('));
- const int closeBracket = s.indexOfChar (openBracket, T(')'));
-
- if (openBracket >= 3 && closeBracket > openBracket)
- {
- index = closeBracket;
-
- StringArray tokens;
- tokens.addTokens (s.substring (openBracket + 1, closeBracket), T(","), T(""));
- tokens.trim();
- tokens.removeEmptyStrings();
-
- if (tokens[0].containsChar T('%'))
- return Colour ((uint8) roundDoubleToInt (2.55 * tokens[0].getDoubleValue()),
- (uint8) roundDoubleToInt (2.55 * tokens[1].getDoubleValue()),
- (uint8) roundDoubleToInt (2.55 * tokens[2].getDoubleValue()));
- else
- return Colour ((uint8) tokens[0].getIntValue(),
- (uint8) tokens[1].getIntValue(),
- (uint8) tokens[2].getIntValue());
- }
- }
-
- return Colours::findColourForName (s, defaultColour);
- }
-
- static const AffineTransform parseTransform (String t)
- {
- AffineTransform result;
-
- while (t.isNotEmpty())
- {
- StringArray tokens;
- tokens.addTokens (t.fromFirstOccurrenceOf (T("("), false, false)
- .upToFirstOccurrenceOf (T(")"), false, false),
- T(", "), 0);
-
- tokens.removeEmptyStrings (true);
-
- float numbers [6];
-
- for (int i = 0; i < 6; ++i)
- numbers[i] = tokens[i].getFloatValue();
-
- AffineTransform trans;
-
- if (t.startsWithIgnoreCase (T("matrix")))
- {
- trans = AffineTransform (numbers[0], numbers[2], numbers[4],
- numbers[1], numbers[3], numbers[5]);
- }
- else if (t.startsWithIgnoreCase (T("translate")))
- {
- trans = trans.translated (numbers[0], numbers[1]);
- }
- else if (t.startsWithIgnoreCase (T("scale")))
- {
- if (tokens.size() == 1)
- trans = trans.scaled (numbers[0], numbers[0]);
- else
- trans = trans.scaled (numbers[0], numbers[1]);
- }
- else if (t.startsWithIgnoreCase (T("rotate")))
- {
- if (tokens.size() != 3)
- trans = trans.rotated (numbers[0] / (180.0f / float_Pi));
- else
- trans = trans.rotated (numbers[0] / (180.0f / float_Pi),
- numbers[1], numbers[2]);
- }
- else if (t.startsWithIgnoreCase (T("skewX")))
- {
- trans = AffineTransform (1.0f, tanf (numbers[0] * (float_Pi / 180.0f)), 0.0f,
- 0.0f, 1.0f, 0.0f);
- }
- else if (t.startsWithIgnoreCase (T("skewY")))
- {
- trans = AffineTransform (1.0f, 0.0f, 0.0f,
- tanf (numbers[0] * (float_Pi / 180.0f)), 1.0f, 0.0f);
- }
-
- result = trans.followedBy (result);
- t = t.fromFirstOccurrenceOf (T(")"), false, false).trimStart();
- }
-
- return result;
- }
-
- static void endpointToCentreParameters (const double x1, const double y1,
- const double x2, const double y2,
- const double angle,
- const bool largeArc, const bool sweep,
- double& rx, double& ry,
- double& centreX, double& centreY,
- double& startAngle, double& deltaAngle)
- {
- const double midX = (x1 - x2) * 0.5;
- const double midY = (y1 - y2) * 0.5;
-
- const double cosAngle = cos (angle);
- const double sinAngle = sin (angle);
- const double xp = cosAngle * midX + sinAngle * midY;
- const double yp = cosAngle * midY - sinAngle * midX;
- const double xp2 = xp * xp;
- const double yp2 = yp * yp;
-
- double rx2 = rx * rx;
- double ry2 = ry * ry;
-
- const double s = (xp2 / rx2) + (yp2 / ry2);
- double c;
-
- if (s <= 1.0)
- {
- c = sqrt (jmax (0.0, ((rx2 * ry2) - (rx2 * yp2) - (ry2 * xp2))
- / (( rx2 * yp2) + (ry2 * xp2))));
-
- if (largeArc == sweep)
- c = -c;
- }
- else
- {
- const double s2 = sqrt (s);
- rx *= s2;
- ry *= s2;
- rx2 = rx * rx;
- ry2 = ry * ry;
- c = 0;
- }
-
- const double cpx = ((rx * yp) / ry) * c;
- const double cpy = ((-ry * xp) / rx) * c;
-
- centreX = ((x1 + x2) * 0.5) + (cosAngle * cpx) - (sinAngle * cpy);
- centreY = ((y1 + y2) * 0.5) + (sinAngle * cpx) + (cosAngle * cpy);
-
- const double ux = (xp - cpx) / rx;
- const double uy = (yp - cpy) / ry;
- const double vx = (-xp - cpx) / rx;
- const double vy = (-yp - cpy) / ry;
-
- const double length = juce_hypot (ux, uy);
-
- startAngle = acos (jlimit (-1.0, 1.0, ux / length));
-
- if (uy < 0)
- startAngle = -startAngle;
-
- startAngle += double_Pi * 0.5;
-
- deltaAngle = acos (jlimit (-1.0, 1.0, ((ux * vx) + (uy * vy))
- / (length * juce_hypot (vx, vy))));
-
- if ((ux * vy) - (uy * vx) < 0)
- deltaAngle = -deltaAngle;
-
- if (sweep)
- {
- if (deltaAngle < 0)
- deltaAngle += double_Pi * 2.0;
- }
- else
- {
- if (deltaAngle > 0)
- deltaAngle -= double_Pi * 2.0;
- }
-
- deltaAngle = fmod (deltaAngle, double_Pi * 2.0);
- }
-
- static const XmlElement* findElementForId (const XmlElement* const parent, const String& id)
- {
- forEachXmlChildElement (*parent, e)
- {
- if (e->compareAttribute (T("id"), id))
- return e;
-
- const XmlElement* const found = findElementForId (e, id);
-
- if (found != 0)
- return found;
- }
-
- return 0;
- }
-
- const SVGState& operator= (const SVGState&);
- };
-
- Drawable* Drawable::createFromSVG (const XmlElement& svgDocument)
- {
- SVGState state (&svgDocument);
- return state.parseSVGElement (svgDocument);
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_SVGParser.cpp *********/
-
- /********* Start of inlined file: juce_DropShadowEffect.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- #if JUCE_MSVC
- #pragma optimize ("t", on) // try to avoid slowing everything down in debug builds
- #endif
-
- DropShadowEffect::DropShadowEffect()
- : offsetX (0),
- offsetY (0),
- radius (4),
- opacity (0.6f)
- {
- }
-
- DropShadowEffect::~DropShadowEffect()
- {
- }
-
- void DropShadowEffect::setShadowProperties (const float newRadius,
- const float newOpacity,
- const int newShadowOffsetX,
- const int newShadowOffsetY)
- {
- radius = jmax (1.1f, newRadius);
- offsetX = newShadowOffsetX;
- offsetY = newShadowOffsetY;
- opacity = newOpacity;
- }
-
- void DropShadowEffect::applyEffect (Image& image, Graphics& g)
- {
- const int w = image.getWidth();
- const int h = image.getHeight();
-
- int lineStride, pixelStride;
- const PixelARGB* srcPixels = (const PixelARGB*) image.lockPixelDataReadOnly (0, 0, image.getWidth(), image.getHeight(), lineStride, pixelStride);
-
- Image shadowImage (Image::SingleChannel, w, h, false);
- int destStride, destPixelStride;
- uint8* const shadowChannel = (uint8*) shadowImage.lockPixelDataReadWrite (0, 0, w, h, destStride, destPixelStride);
-
- const int filter = roundFloatToInt (63.0f / radius);
- const int radiusMinus1 = roundFloatToInt ((radius - 1.0f) * 63.0f);
-
- for (int x = w; --x >= 0;)
- {
- int shadowAlpha = 0;
-
- const PixelARGB* src = srcPixels + x;
- uint8* shadowPix = shadowChannel + x;
-
- for (int y = h; --y >= 0;)
- {
- shadowAlpha = ((shadowAlpha * radiusMinus1 + (src->getAlpha() << 6)) * filter) >> 12;
-
- *shadowPix = (uint8) shadowAlpha;
- src = (const PixelARGB*) (((const uint8*) src) + lineStride);
- shadowPix += destStride;
- }
- }
-
- for (int y = h; --y >= 0;)
- {
- int shadowAlpha = 0;
- uint8* shadowPix = shadowChannel + y * destStride;
-
- for (int x = w; --x >= 0;)
- {
- shadowAlpha = ((shadowAlpha * radiusMinus1 + (*shadowPix << 6)) * filter) >> 12;
- *shadowPix++ = (uint8) shadowAlpha;
- }
- }
-
- image.releasePixelDataReadOnly (srcPixels);
- shadowImage.releasePixelDataReadWrite (shadowChannel);
-
- g.setColour (Colours::black.withAlpha (opacity));
- g.drawImageAt (&shadowImage, offsetX, offsetY, true);
-
- g.setOpacity (1.0f);
- g.drawImageAt (&image, 0, 0);
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_DropShadowEffect.cpp *********/
-
- /********* Start of inlined file: juce_GlowEffect.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- GlowEffect::GlowEffect()
- : radius (2.0f),
- colour (Colours::white)
- {
- }
-
- GlowEffect::~GlowEffect()
- {
- }
-
- void GlowEffect::setGlowProperties (const float newRadius,
- const Colour& newColour)
- {
- radius = newRadius;
- colour = newColour;
- }
-
- void GlowEffect::applyEffect (Image& image, Graphics& g)
- {
- const int w = image.getWidth();
- const int h = image.getHeight();
-
- Image temp (image.getFormat(), w, h, true);
-
- ImageConvolutionKernel blurKernel (roundFloatToInt (radius * 2.0f));
-
- blurKernel.createGaussianBlur (radius);
- blurKernel.rescaleAllValues (radius);
-
- blurKernel.applyToImage (temp, &image, 0, 0, w, h);
-
- g.setColour (colour);
- g.drawImageAt (&temp, 0, 0, true);
-
- g.setOpacity (1.0f);
- g.drawImageAt (&image, 0, 0, false);
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_GlowEffect.cpp *********/
-
- /********* Start of inlined file: juce_ReduceOpacityEffect.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- ReduceOpacityEffect::ReduceOpacityEffect (const float opacity_)
- : opacity (opacity_)
- {
- }
-
- ReduceOpacityEffect::~ReduceOpacityEffect()
- {
- }
-
- void ReduceOpacityEffect::setOpacity (const float newOpacity)
- {
- opacity = jlimit (0.0f, 1.0f, newOpacity);
- }
-
- void ReduceOpacityEffect::applyEffect (Image& image, Graphics& g)
- {
- g.setOpacity (opacity);
- g.drawImageAt (&image, 0, 0);
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_ReduceOpacityEffect.cpp *********/
-
- /********* Start of inlined file: juce_Font.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- static const float minFontHeight = 0.1f;
- static const float maxFontHeight = 10000.0f;
- static const float defaultFontHeight = 14.0f;
-
- static String defaultSans, defaultSerif, defaultFixed, fallbackFont;
-
- Font::Font() throw()
- : typefaceName (defaultSans),
- height (defaultFontHeight),
- horizontalScale (1.0f),
- kerning (0),
- ascent (0),
- styleFlags (Font::plain)
- {
- }
-
- void Font::resetToDefaultState() throw()
- {
- typefaceName = defaultSans;
- height = defaultFontHeight;
- horizontalScale = 1.0f;
- kerning = 0;
- ascent = 0;
- styleFlags = Font::plain;
- typeface = 0;
- }
-
- Font::Font (const float fontHeight,
- const int styleFlags_) throw()
- : typefaceName (defaultSans),
- height (jlimit (minFontHeight, maxFontHeight, fontHeight)),
- horizontalScale (1.0f),
- kerning (0),
- ascent (0),
- styleFlags (styleFlags_)
- {
- }
-
- Font::Font (const String& typefaceName_,
- const float fontHeight,
- const int styleFlags_) throw()
- : typefaceName (typefaceName_),
- height (jlimit (minFontHeight, maxFontHeight, fontHeight)),
- horizontalScale (1.0f),
- kerning (0),
- ascent (0),
- styleFlags (styleFlags_)
- {
- }
-
- Font::Font (const Font& other) throw()
- : typefaceName (other.typefaceName),
- height (other.height),
- horizontalScale (other.horizontalScale),
- kerning (other.kerning),
- ascent (other.ascent),
- styleFlags (other.styleFlags),
- typeface (other.typeface)
- {
- }
-
- const Font& Font::operator= (const Font& other) throw()
- {
- if (this != &other)
- {
- typefaceName = other.typefaceName;
- height = other.height;
- styleFlags = other.styleFlags;
- horizontalScale = other.horizontalScale;
- kerning = other.kerning;
- ascent = other.ascent;
- typeface = other.typeface;
- }
-
- return *this;
- }
-
- Font::~Font() throw()
- {
- }
-
- Font::Font (const Typeface& face) throw()
- : height (11.0f),
- horizontalScale (1.0f),
- kerning (0),
- ascent (0),
- styleFlags (plain)
- {
- typefaceName = face.getName();
- setBold (face.isBold());
- setItalic (face.isItalic());
- typeface = new Typeface (face);
- }
-
- bool Font::operator== (const Font& other) const throw()
- {
- return height == other.height
- && horizontalScale == other.horizontalScale
- && kerning == other.kerning
- && styleFlags == other.styleFlags
- && typefaceName == other.typefaceName;
- }
-
- bool Font::operator!= (const Font& other) const throw()
- {
- return ! operator== (other);
- }
-
- void Font::setTypefaceName (const String& faceName) throw()
- {
- typefaceName = faceName;
- typeface = 0;
- ascent = 0;
- }
-
- void Font::initialiseDefaultFontNames() throw()
- {
- Font::getDefaultFontNames (defaultSans,
- defaultSerif,
- defaultFixed);
- }
-
- void clearUpDefaultFontNames() throw() // called at shutdown by code in Typface
- {
- defaultSans = String::empty;
- defaultSerif = String::empty;
- defaultFixed = String::empty;
- fallbackFont = String::empty;
- }
-
- const String Font::getDefaultSansSerifFontName() throw()
- {
- return defaultSans;
- }
-
- const String Font::getDefaultSerifFontName() throw()
- {
- return defaultSerif;
- }
-
- const String Font::getDefaultMonospacedFontName() throw()
- {
- return defaultFixed;
- }
-
- void Font::setDefaultSansSerifFontName (const String& name) throw()
- {
- defaultSans = name;
- }
-
- const String Font::getFallbackFontName() throw()
- {
- return fallbackFont;
- }
-
- void Font::setFallbackFontName (const String& name) throw()
- {
- fallbackFont = name;
- }
-
- void Font::setHeight (float newHeight) throw()
- {
- height = jlimit (minFontHeight, maxFontHeight, newHeight);
- }
-
- void Font::setHeightWithoutChangingWidth (float newHeight) throw()
- {
- newHeight = jlimit (minFontHeight, maxFontHeight, newHeight);
- horizontalScale *= (height / newHeight);
- height = newHeight;
- }
-
- void Font::setStyleFlags (const int newFlags) throw()
- {
- if (styleFlags != newFlags)
- {
- styleFlags = newFlags;
- typeface = 0;
- ascent = 0;
- }
- }
-
- void Font::setSizeAndStyle (const float newHeight,
- const int newStyleFlags,
- const float newHorizontalScale,
- const float newKerningAmount) throw()
- {
- height = jlimit (minFontHeight, maxFontHeight, newHeight);
- horizontalScale = newHorizontalScale;
- kerning = newKerningAmount;
-
- setStyleFlags (newStyleFlags);
- }
-
- void Font::setHorizontalScale (const float scaleFactor) throw()
- {
- horizontalScale = scaleFactor;
- }
-
- void Font::setExtraKerningFactor (const float extraKerning) throw()
- {
- kerning = extraKerning;
- }
-
- void Font::setBold (const bool shouldBeBold) throw()
- {
- setStyleFlags (shouldBeBold ? (styleFlags | bold)
- : (styleFlags & ~bold));
- }
-
- bool Font::isBold() const throw()
- {
- return (styleFlags & bold) != 0;
- }
-
- void Font::setItalic (const bool shouldBeItalic) throw()
- {
- setStyleFlags (shouldBeItalic ? (styleFlags | italic)
- : (styleFlags & ~italic));
- }
-
- bool Font::isItalic() const throw()
- {
- return (styleFlags & italic) != 0;
- }
-
- void Font::setUnderline (const bool shouldBeUnderlined) throw()
- {
- setStyleFlags (shouldBeUnderlined ? (styleFlags | underlined)
- : (styleFlags & ~underlined));
- }
-
- bool Font::isUnderlined() const throw()
- {
- return (styleFlags & underlined) != 0;
- }
-
- float Font::getAscent() const throw()
- {
- if (ascent == 0)
- ascent = getTypeface()->getAscent();
-
- return height * ascent;
- }
-
- float Font::getDescent() const throw()
- {
- return height - getAscent();
- }
-
- int Font::getStringWidth (const String& text) const throw()
- {
- return roundFloatToInt (getStringWidthFloat (text));
- }
-
- float Font::getStringWidthFloat (const String& text) const throw()
- {
- float x = 0.0f;
-
- if (text.isNotEmpty())
- {
- Typeface* const typeface = getTypeface();
- const juce_wchar* t = (const juce_wchar*) text;
-
- do
- {
- const TypefaceGlyphInfo* const glyph = typeface->getGlyph (*t++);
-
- if (glyph != 0)
- x += kerning + glyph->getHorizontalSpacing (*t);
- }
- while (*t != 0);
-
- x *= height;
- x *= horizontalScale;
- }
-
- return x;
- }
-
- Typeface* Font::getTypeface() const throw()
- {
- if (typeface == 0)
- typeface = Typeface::getTypefaceFor (*this);
-
- return typeface;
- }
-
- void Font::findFonts (OwnedArray<Font>& destArray) throw()
- {
- const StringArray names (findAllTypefaceNames());
-
- for (int i = 0; i < names.size(); ++i)
- destArray.add (new Font (names[i], defaultFontHeight, Font::plain));
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_Font.cpp *********/
-
- /********* Start of inlined file: juce_GlyphArrangement.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- #define SHOULD_WRAP(x, wrapwidth) (((x) - 0.0001f) >= (wrapwidth))
-
- class FontGlyphAlphaMap
- {
- public:
-
- bool draw (const Graphics& g, float x, const float y) const throw()
- {
- if (bitmap1 == 0)
- return false;
-
- x += xOrigin;
- const float xFloor = floorf (x);
- const int intX = (int) xFloor;
-
- g.drawImageAt (((x - xFloor) >= 0.5f && bitmap2 != 0) ? bitmap2 : bitmap1,
- intX, (int) floorf (y + yOrigin), true);
-
- return true;
- }
-
- juce_UseDebuggingNewOperator
-
- private:
-
- Image* bitmap1;
- Image* bitmap2;
- float xOrigin, yOrigin;
- int lastAccessCount;
- Typeface::Ptr typeface;
- float height, horizontalScale;
- juce_wchar character;
-
- friend class GlyphCache;
-
- FontGlyphAlphaMap() throw()
- : bitmap1 (0),
- bitmap2 (0),
- lastAccessCount (0),
- height (0),
- horizontalScale (0),
- character (0)
- {
- }
-
- ~FontGlyphAlphaMap() throw()
- {
- delete bitmap1;
- delete bitmap2;
- }
-
- class AlphaBitmapRenderer
- {
- uint8* const data;
- const int stride;
- uint8* lineStart;
-
- AlphaBitmapRenderer (const AlphaBitmapRenderer&);
- const AlphaBitmapRenderer& operator= (const AlphaBitmapRenderer&);
-
- public:
- AlphaBitmapRenderer (uint8* const data_,
- const int stride_) throw()
- : data (data_),
- stride (stride_)
- {
- }
-
- forcedinline void setEdgeTableYPos (const int y) throw()
- {
- lineStart = data + (stride * y);
- }
-
- forcedinline void handleEdgeTablePixel (const int x, const int alphaLevel) const throw()
- {
- lineStart [x] = (uint8) alphaLevel;
- }
-
- forcedinline void handleEdgeTableLine (const int x, int width, const int alphaLevel) const throw()
- {
- uint8* d = lineStart + x;
-
- while (--width >= 0)
- *d++ = (uint8) alphaLevel;
- }
- };
-
- Image* createAlphaMapFromPath (const Path& path,
- float& topLeftX, float& topLeftY,
- float xScale, float yScale,
- const float subPixelOffsetX) throw()
- {
- Image* im = 0;
-
- float px, py, pw, ph;
- path.getBounds (px, py, pw, ph);
-
- topLeftX = floorf (px * xScale);
- topLeftY = floorf (py * yScale);
-
- int bitmapWidth = roundFloatToInt (pw * xScale) + 2;
- int bitmapHeight = roundFloatToInt (ph * yScale) + 2;
-
- im = new Image (Image::SingleChannel, bitmapWidth, bitmapHeight, true);
-
- EdgeTable edgeTable (0, bitmapHeight, EdgeTable::Oversampling_16times);
-
- edgeTable.addPath (path, AffineTransform::scale (xScale, yScale)
- .translated (subPixelOffsetX - topLeftX, -topLeftY));
-
- int stride, pixelStride;
- uint8* const pixels = (uint8*) im->lockPixelDataReadWrite (0, 0, bitmapWidth, bitmapHeight, stride, pixelStride);
-
- jassert (pixelStride == 1);
- AlphaBitmapRenderer renderer (pixels, stride);
- edgeTable.iterate (renderer, 0, 0, bitmapWidth, bitmapHeight, 0);
-
- im->releasePixelDataReadWrite (pixels);
-
- return im;
- }
-
- void generate (Typeface* const face,
- const juce_wchar character_,
- const float fontHeight,
- const float fontHorizontalScale) throw()
- {
- character = character_;
- typeface = face;
- height = fontHeight;
- horizontalScale = fontHorizontalScale;
-
- const Path* const glyphPath = face->getOutlineForGlyph (character_);
-
- deleteAndZero (bitmap1);
- deleteAndZero (bitmap2);
-
- const float fontHScale = fontHeight * fontHorizontalScale;
-
- if (glyphPath != 0 && ! glyphPath->isEmpty())
- {
- bitmap1 = createAlphaMapFromPath (*glyphPath, xOrigin, yOrigin, fontHScale, fontHeight, 0.0f);
-
- if (fontHScale < 24.0f)
- bitmap2 = createAlphaMapFromPath (*glyphPath, xOrigin, yOrigin, fontHScale, fontHeight, 0.5f);
- }
- else
- {
- xOrigin = yOrigin = 0;
- }
- }
- };
-
- static const int defaultNumGlyphsToCache = 120;
- class GlyphCache;
- static GlyphCache* cacheInstance = 0;
-
- class GlyphCache : private DeletedAtShutdown
- {
- public:
-
- static GlyphCache* getInstance() throw()
- {
- if (cacheInstance == 0)
- cacheInstance = new GlyphCache();
-
- return cacheInstance;
- }
-
- const FontGlyphAlphaMap& getGlyphFor (Typeface* const typeface,
- const float fontHeight,
- const float fontHorizontalScale,
- const juce_wchar character) throw()
- {
- ++accessCounter;
-
- int oldestCounter = INT_MAX;
- int oldestIndex = 0;
-
- for (int i = numGlyphs; --i >= 0;)
- {
- FontGlyphAlphaMap& g = glyphs[i];
-
- if (g.character == character
- && g.height == fontHeight
- && g.typeface->hashCode() == typeface->hashCode()
- && g.horizontalScale == fontHorizontalScale)
- {
- g.lastAccessCount = accessCounter;
- ++hits;
- return g;
- }
-
- if (oldestCounter > g.lastAccessCount)
- {
- oldestCounter = g.lastAccessCount;
- oldestIndex = i;
- }
- }
-
- ++misses;
-
- if (hits + misses > (numGlyphs << 4))
- {
- if (misses * 2 > hits)
- setCacheSize (numGlyphs + 32);
-
- hits = 0;
- misses = 0;
- oldestIndex = 0;
- }
-
- FontGlyphAlphaMap& oldest = glyphs [oldestIndex];
- oldest.lastAccessCount = accessCounter;
-
- oldest.generate (typeface,
- character,
- fontHeight,
- fontHorizontalScale);
-
- return oldest;
- }
-
- void setCacheSize (const int num) throw()
- {
- if (numGlyphs != num)
- {
- numGlyphs = num;
-
- if (glyphs != 0)
- delete[] glyphs;
-
- glyphs = new FontGlyphAlphaMap [numGlyphs];
-
- hits = 0;
- misses = 0;
- }
- }
-
- juce_UseDebuggingNewOperator
-
- private:
- FontGlyphAlphaMap* glyphs;
- int numGlyphs, accessCounter;
- int hits, misses;
-
- GlyphCache() throw()
- : glyphs (0),
- numGlyphs (0),
- accessCounter (0)
- {
- setCacheSize (defaultNumGlyphsToCache);
- }
-
- ~GlyphCache() throw()
- {
- delete[] glyphs;
-
- jassert (cacheInstance == this);
- cacheInstance = 0;
- }
-
- GlyphCache (const GlyphCache&);
- const GlyphCache& operator= (const GlyphCache&);
- };
-
- PositionedGlyph::PositionedGlyph() throw()
- {
- }
-
- void PositionedGlyph::draw (const Graphics& g) const throw()
- {
- if (! glyphInfo->isWhitespace())
- {
- if (fontHeight < 100.0f && fontHeight > 0.1f && ! g.isVectorDevice())
- {
- const FontGlyphAlphaMap& alphaMap
- = GlyphCache::getInstance()->getGlyphFor (glyphInfo->getTypeface(),
- fontHeight,
- fontHorizontalScale,
- getCharacter());
-
- alphaMap.draw (g, x, y);
- }
- else
- {
- // that's a bit of a dodgy size, isn't it??
- jassert (fontHeight > 0.0f && fontHeight < 4000.0f);
-
- draw (g, AffineTransform::identity);
- }
- }
- }
-
- void PositionedGlyph::draw (const Graphics& g,
- const AffineTransform& transform) const throw()
- {
- if (! glyphInfo->isWhitespace())
- {
- g.fillPath (glyphInfo->getPath(),
- AffineTransform::scale (fontHeight * fontHorizontalScale, fontHeight)
- .translated (x, y)
- .followedBy (transform));
- }
- }
-
- void PositionedGlyph::createPath (Path& path) const throw()
- {
- if (! glyphInfo->isWhitespace())
- {
- path.addPath (glyphInfo->getPath(),
- AffineTransform::scale (fontHeight * fontHorizontalScale, fontHeight)
- .translated (x, y));
- }
- }
-
- bool PositionedGlyph::hitTest (float px, float py) const throw()
- {
- if (px >= getLeft() && px < getRight()
- && py >= getTop() && py < getBottom()
- && fontHeight > 0.0f
- && ! glyphInfo->isWhitespace())
- {
- AffineTransform::translation (-x, -y)
- .scaled (1.0f / (fontHeight * fontHorizontalScale), 1.0f / fontHeight)
- .transformPoint (px, py);
-
- return glyphInfo->getPath().contains (px, py);
- }
-
- return false;
- }
-
- void PositionedGlyph::moveBy (const float deltaX,
- const float deltaY) throw()
- {
- x += deltaX;
- y += deltaY;
- }
-
- GlyphArrangement::GlyphArrangement() throw()
- : numGlyphs (0),
- numAllocated (0),
- glyphs (0)
- {
- }
-
- GlyphArrangement::GlyphArrangement (const GlyphArrangement& other) throw()
- : numGlyphs (0),
- numAllocated (0),
- glyphs (0)
- {
- addGlyphArrangement (other);
- }
-
- const GlyphArrangement& GlyphArrangement::operator= (const GlyphArrangement& other) throw()
- {
- if (this != &other)
- {
- clear();
- addGlyphArrangement (other);
- }
-
- return *this;
- }
-
- GlyphArrangement::~GlyphArrangement() throw()
- {
- clear();
- juce_free (glyphs);
- }
-
- void GlyphArrangement::ensureNumGlyphsAllocated (const int minGlyphs) throw()
- {
- if (numAllocated <= minGlyphs)
- {
- numAllocated = minGlyphs + 2;
-
- if (glyphs == 0)
- glyphs = (PositionedGlyph*) juce_malloc (numAllocated * sizeof (PositionedGlyph));
- else
- glyphs = (PositionedGlyph*) juce_realloc (glyphs, numAllocated * sizeof (PositionedGlyph));
- }
- }
-
- void GlyphArrangement::incGlyphRefCount (const int i) const throw()
- {
- jassert (((unsigned int) i) < (unsigned int) numGlyphs);
-
- if (glyphs[i].glyphInfo != 0 && glyphs[i].glyphInfo->getTypeface() != 0)
- glyphs[i].glyphInfo->getTypeface()->incReferenceCount();
- }
-
- void GlyphArrangement::decGlyphRefCount (const int i) const throw()
- {
- if (glyphs[i].glyphInfo != 0 && glyphs[i].glyphInfo->getTypeface() != 0)
- glyphs[i].glyphInfo->getTypeface()->decReferenceCount();
- }
-
- void GlyphArrangement::clear() throw()
- {
- for (int i = numGlyphs; --i >= 0;)
- decGlyphRefCount (i);
-
- numGlyphs = 0;
- }
-
- PositionedGlyph& GlyphArrangement::getGlyph (const int index) const throw()
- {
- jassert (((unsigned int) index) < (unsigned int) numGlyphs);
-
- return glyphs [index];
- }
-
- void GlyphArrangement::addGlyphArrangement (const GlyphArrangement& other) throw()
- {
- ensureNumGlyphsAllocated (numGlyphs + other.numGlyphs);
-
- memcpy (glyphs + numGlyphs, other.glyphs,
- other.numGlyphs * sizeof (PositionedGlyph));
-
- for (int i = other.numGlyphs; --i >= 0;)
- incGlyphRefCount (numGlyphs++);
- }
-
- void GlyphArrangement::removeLast() throw()
- {
- if (numGlyphs > 0)
- decGlyphRefCount (--numGlyphs);
- }
-
- void GlyphArrangement::removeRangeOfGlyphs (int startIndex, const int num) throw()
- {
- jassert (startIndex >= 0);
-
- if (startIndex < 0)
- startIndex = 0;
-
- if (num < 0 || startIndex + num >= numGlyphs)
- {
- while (numGlyphs > startIndex)
- removeLast();
- }
- else if (num > 0)
- {
- int i;
- for (i = startIndex; i < startIndex + num; ++i)
- decGlyphRefCount (i);
-
- for (i = numGlyphs - (startIndex + num); --i >= 0;)
- {
- glyphs [startIndex] = glyphs [startIndex + num];
- ++startIndex;
- }
-
- numGlyphs -= num;
- }
- }
-
- void GlyphArrangement::addLineOfText (const Font& font,
- const String& text,
- const float xOffset,
- const float yOffset) throw()
- {
- addCurtailedLineOfText (font, text,
- xOffset, yOffset,
- 1.0e10f, false);
- }
-
- void GlyphArrangement::addCurtailedLineOfText (const Font& font,
- const String& text,
- float xOffset,
- const float yOffset,
- const float maxWidthPixels,
- const bool useEllipsis) throw()
- {
- const int textLen = text.length();
-
- if (textLen > 0)
- {
- ensureNumGlyphsAllocated (numGlyphs + textLen + 3); // extra chars for ellipsis
-
- Typeface* const typeface = font.getTypeface();
- const float fontHeight = font.getHeight();
- const float ascent = font.getAscent();
- const float fontHorizontalScale = font.getHorizontalScale();
- const float heightTimesScale = fontHorizontalScale * fontHeight;
- const float kerningFactor = font.getExtraKerningFactor();
- const float startX = xOffset;
-
- const juce_wchar* const unicodeText = (const juce_wchar*) text;
-
- for (int i = 0; i < textLen; ++i)
- {
- const TypefaceGlyphInfo* const glyph = typeface->getGlyph (unicodeText[i]);
-
- if (glyph != 0)
- {
- jassert (numAllocated > numGlyphs);
-
- ensureNumGlyphsAllocated (numGlyphs);
- PositionedGlyph& pg = glyphs [numGlyphs];
- pg.glyphInfo = glyph;
- pg.x = xOffset;
- pg.y = yOffset;
- pg.w = heightTimesScale * glyph->getHorizontalSpacing (0);
- pg.fontHeight = fontHeight;
- pg.fontAscent = ascent;
- pg.fontHorizontalScale = fontHorizontalScale;
- pg.isUnderlined = font.isUnderlined();
-
- xOffset += heightTimesScale * (kerningFactor + glyph->getHorizontalSpacing (unicodeText [i + 1]));
-
- if (xOffset - startX > maxWidthPixels + 1.0f)
- {
- // curtail the string if it's too wide..
-
- if (useEllipsis && textLen > 3 && numGlyphs >= 3)
- appendEllipsis (font, startX + maxWidthPixels);
-
- break;
- }
- else
- {
- if (glyph->getTypeface() != 0)
- glyph->getTypeface()->incReferenceCount();
-
- ++numGlyphs;
- }
- }
- }
- }
- }
-
- void GlyphArrangement::appendEllipsis (const Font& font, const float maxXPixels) throw()
- {
- const TypefaceGlyphInfo* const dotGlyph = font.getTypeface()->getGlyph (T('.'));
-
- if (dotGlyph != 0)
- {
- if (numGlyphs > 0)
- {
- PositionedGlyph& glyph = glyphs [numGlyphs - 1];
- const float fontHeight = glyph.fontHeight;
- const float fontHorizontalScale = glyph.fontHorizontalScale;
- const float fontAscent = glyph.fontAscent;
-
- const float dx = fontHeight * fontHorizontalScale
- * (font.getExtraKerningFactor() + dotGlyph->getHorizontalSpacing (T('.')));
-
- float xOffset = 0.0f, yOffset = 0.0f;
-
- for (int dotPos = 3; --dotPos >= 0 && numGlyphs > 0;)
- {
- removeLast();
-
- jassert (numAllocated > numGlyphs);
- PositionedGlyph& pg = glyphs [numGlyphs];
- xOffset = pg.x;
- yOffset = pg.y;
-
- if (numGlyphs == 0 || xOffset + dx * 3 <= maxXPixels)
- break;
- }
-
- for (int i = 3; --i >= 0;)
- {
- jassert (numAllocated > numGlyphs);
-
- ensureNumGlyphsAllocated (numGlyphs);
- PositionedGlyph& pg = glyphs [numGlyphs];
- pg.glyphInfo = dotGlyph;
- pg.x = xOffset;
- pg.y = yOffset;
- pg.w = dx;
- pg.fontHeight = fontHeight;
- pg.fontAscent = fontAscent;
- pg.fontHorizontalScale = fontHorizontalScale;
- pg.isUnderlined = font.isUnderlined();
-
- xOffset += dx;
-
- if (dotGlyph->getTypeface() != 0)
- dotGlyph->getTypeface()->incReferenceCount();
-
- ++numGlyphs;
- }
- }
- }
- }
-
- void GlyphArrangement::addJustifiedText (const Font& font,
- const String& text,
- float x, float y,
- const float maxLineWidth,
- const Justification& horizontalLayout) throw()
- {
- int lineStartIndex = numGlyphs;
- addLineOfText (font, text, x, y);
-
- const float originalY = y;
-
- while (lineStartIndex < numGlyphs)
- {
- int i = lineStartIndex;
-
- if (glyphs[i].getCharacter() != T('\n') && glyphs[i].getCharacter() != T('\r'))
- ++i;
-
- const float lineMaxX = glyphs [lineStartIndex].getLeft() + maxLineWidth;
- int lastWordBreakIndex = -1;
-
- while (i < numGlyphs)
- {
- PositionedGlyph& pg = glyphs[i];
- const juce_wchar c = pg.getCharacter();
-
- if (c == T('\r') || c == T('\n'))
- {
- ++i;
-
- if (c == T('\r') && i < numGlyphs && glyphs [i].getCharacter() == T('\n'))
- ++i;
-
- break;
- }
- else if (pg.isWhitespace())
- {
- lastWordBreakIndex = i + 1;
- }
- else if (SHOULD_WRAP (pg.getRight(), lineMaxX))
- {
- if (lastWordBreakIndex >= 0)
- i = lastWordBreakIndex;
-
- break;
- }
-
- ++i;
- }
-
- const float currentLineStartX = glyphs [lineStartIndex].getLeft();
- float currentLineEndX = currentLineStartX;
-
- for (int j = i; --j >= lineStartIndex;)
- {
- if (! glyphs[j].isWhitespace())
- {
- currentLineEndX = glyphs[j].getRight();
- break;
- }
- }
-
- float deltaX = 0.0f;
-
- if (horizontalLayout.testFlags (Justification::horizontallyJustified))
- spreadOutLine (lineStartIndex, i - lineStartIndex, maxLineWidth);
- else if (horizontalLayout.testFlags (Justification::horizontallyCentred))
- deltaX = (maxLineWidth - (currentLineEndX - currentLineStartX)) * 0.5f;
- else if (horizontalLayout.testFlags (Justification::right))
- deltaX = maxLineWidth - (currentLineEndX - currentLineStartX);
-
- moveRangeOfGlyphs (lineStartIndex, i - lineStartIndex,
- x + deltaX - currentLineStartX, y - originalY);
-
- lineStartIndex = i;
-
- y += font.getHeight();
- }
- }
-
- void GlyphArrangement::addFittedText (const Font& f,
- const String& text,
- float x, float y,
- float width, float height,
- const Justification& layout,
- int maximumLines,
- const float minimumHorizontalScale) throw()
- {
- // doesn't make much sense if this is outside a sensible range of 0.5 to 1.0
- jassert (minimumHorizontalScale > 0 && minimumHorizontalScale <= 1.0f);
-
- if (text.containsAnyOf (T("\r\n")))
- {
- GlyphArrangement ga;
- ga.addJustifiedText (f, text, x, y, width, layout);
-
- float l, t, r, b;
- ga.getBoundingBox (0, -1, l, t, r, b, false);
-
- float dy = y - t;
-
- if (layout.testFlags (Justification::verticallyCentred))
- dy += (height - (b - t)) * 0.5f;
- else if (layout.testFlags (Justification::bottom))
- dy += height - (b - t);
-
- ga.moveRangeOfGlyphs (0, -1, 0.0f, dy);
-
- addGlyphArrangement (ga);
-
- return;
- }
-
- int startIndex = numGlyphs;
- addLineOfText (f, text.trim(), x, y);
-
- if (numGlyphs > startIndex)
- {
- float lineWidth = glyphs[numGlyphs - 1].getRight() - glyphs[startIndex].getLeft();
-
- if (lineWidth <= 0)
- return;
-
- if (lineWidth * minimumHorizontalScale < width)
- {
- if (lineWidth > width)
- {
- stretchRangeOfGlyphs (startIndex, numGlyphs - startIndex,
- width / lineWidth);
-
- }
-
- justifyGlyphs (startIndex, numGlyphs - startIndex,
- x, y, width, height, layout);
- }
- else if (maximumLines <= 1)
- {
- const float ratio = jmax (minimumHorizontalScale, width / lineWidth);
-
- stretchRangeOfGlyphs (startIndex, numGlyphs - startIndex, ratio);
-
- while (numGlyphs > 0 && glyphs [numGlyphs - 1].x + glyphs [numGlyphs - 1].w >= x + width)
- removeLast();
-
- appendEllipsis (f, x + width);
-
- justifyGlyphs (startIndex, numGlyphs - startIndex,
- x, y, width, height, layout);
- }
- else
- {
- Font font (f);
-
- String txt (text.trim());
- const int length = txt.length();
- int numLines = 1;
- const int originalStartIndex = startIndex;
-
- if (length <= 12 && ! txt.containsAnyOf (T(" -\t\r\n")))
- maximumLines = 1;
-
- maximumLines = jmin (maximumLines, length);
-
- while (numLines < maximumLines)
- {
- ++numLines;
-
- const float newFontHeight = height / (float)numLines;
-
- if (newFontHeight < 8.0f)
- break;
-
- if (newFontHeight < font.getHeight())
- {
- font.setHeight (newFontHeight);
-
- while (numGlyphs > startIndex)
- removeLast();
-
- addLineOfText (font, txt, x, y);
-
- lineWidth = glyphs[numGlyphs - 1].getRight() - glyphs[startIndex].getLeft();
- }
-
- if (numLines > lineWidth / width)
- break;
- }
-
- if (numLines < 1)
- numLines = 1;
-
- float lineY = y;
- float widthPerLine = lineWidth / numLines;
- int lastLineStartIndex = 0;
-
- for (int line = 0; line < numLines; ++line)
- {
- int i = startIndex;
- lastLineStartIndex = i;
- float lineStartX = glyphs[startIndex].getLeft();
-
- while (i < numGlyphs)
- {
- lineWidth = (glyphs[i].getRight() - lineStartX);
-
- if (lineWidth > widthPerLine)
- {
- // got to a point where the line's too long, so skip forward to find a
- // good place to break it..
- const int searchStartIndex = i;
-
- while (i < numGlyphs)
- {
- if ((glyphs[i].getRight() - lineStartX) * minimumHorizontalScale < width)
- {
- if (glyphs[i].isWhitespace()
- || glyphs[i].getCharacter() == T('-'))
- {
- ++i;
- break;
- }
- }
- else
- {
- // can't find a suitable break, so try looking backwards..
- i = searchStartIndex;
-
- for (int back = 1; back < jmin (5, i - startIndex - 1); ++back)
- {
- if (glyphs[i - back].isWhitespace()
- || glyphs[i - back].getCharacter() == T('-'))
- {
- i -= back - 1;
- break;
- }
- }
-
- break;
- }
-
- ++i;
- }
-
- break;
- }
-
- ++i;
- }
-
- int wsStart = i;
- while (wsStart > 0 && glyphs[wsStart - 1].isWhitespace())
- --wsStart;
-
- int wsEnd = i;
-
- while (wsEnd < numGlyphs && glyphs[wsEnd].isWhitespace())
- ++wsEnd;
-
- removeRangeOfGlyphs (wsStart, wsEnd - wsStart);
- i = jmax (wsStart, startIndex + 1);
-
- lineWidth = glyphs[i - 1].getRight() - lineStartX;
-
- if (lineWidth > width)
- {
- stretchRangeOfGlyphs (startIndex, i - startIndex,
- width / lineWidth);
- }
-
- justifyGlyphs (startIndex, i - startIndex,
- x, lineY, width, font.getHeight(),
- layout.getOnlyHorizontalFlags() | Justification::verticallyCentred);
-
- startIndex = i;
- lineY += font.getHeight();
-
- if (startIndex >= numGlyphs)
- break;
- }
-
- if (startIndex < numGlyphs)
- {
- while (numGlyphs > startIndex)
- removeLast();
-
- if (startIndex - originalStartIndex > 4)
- {
- const float lineStartX = glyphs[lastLineStartIndex].getLeft();
- appendEllipsis (font, lineStartX + width);
-
- lineWidth = glyphs[startIndex - 1].getRight() - lineStartX;
-
- if (lineWidth > width)
- {
- stretchRangeOfGlyphs (lastLineStartIndex, startIndex - lastLineStartIndex,
- width / lineWidth);
- }
-
- justifyGlyphs (lastLineStartIndex, startIndex - lastLineStartIndex,
- x, lineY - font.getHeight(), width, font.getHeight(),
- layout.getOnlyHorizontalFlags() | Justification::verticallyCentred);
- }
-
- startIndex = numGlyphs;
- }
-
- justifyGlyphs (originalStartIndex, startIndex - originalStartIndex,
- x, y, width, height, layout.getFlags() & ~Justification::horizontallyJustified);
- }
- }
- }
-
- void GlyphArrangement::moveRangeOfGlyphs (int startIndex, int num,
- const float dx, const float dy) throw()
- {
- jassert (startIndex >= 0);
-
- if (dx != 0.0f || dy != 0.0f)
- {
- if (num < 0 || startIndex + num > numGlyphs)
- num = numGlyphs - startIndex;
-
- while (--num >= 0)
- {
- jassert (((unsigned int) startIndex) <= (unsigned int) numGlyphs);
- glyphs [startIndex++].moveBy (dx, dy);
- }
- }
- }
-
- void GlyphArrangement::stretchRangeOfGlyphs (int startIndex, int num,
- const float horizontalScaleFactor) throw()
- {
- jassert (startIndex >= 0);
-
- if (num < 0 || startIndex + num > numGlyphs)
- num = numGlyphs - startIndex;
-
- if (num > 0)
- {
- const float xAnchor = glyphs[startIndex].getLeft();
-
- while (--num >= 0)
- {
- jassert (((unsigned int) startIndex) <= (unsigned int) numGlyphs);
- PositionedGlyph& pg = glyphs[startIndex++];
-
- pg.x = xAnchor + (pg.x - xAnchor) * horizontalScaleFactor;
- pg.fontHorizontalScale *= horizontalScaleFactor;
- pg.w *= horizontalScaleFactor;
- }
- }
- }
-
- void GlyphArrangement::getBoundingBox (int startIndex, int num,
- float& left,
- float& top,
- float& right,
- float& bottom,
- const bool includeWhitespace) const throw()
- {
- jassert (startIndex >= 0);
-
- if (num < 0 || startIndex + num > numGlyphs)
- num = numGlyphs - startIndex;
-
- left = 0.0f;
- top = 0.0f;
- right = 0.0f;
- bottom = 0.0f;
- bool isFirst = true;
-
- while (--num >= 0)
- {
- const PositionedGlyph& pg = glyphs [startIndex++];
-
- if (includeWhitespace || ! pg.isWhitespace())
- {
- if (isFirst)
- {
- isFirst = false;
- left = pg.getLeft();
- top = pg.getTop();
- right = pg.getRight();
- bottom = pg.getBottom();
- }
- else
- {
- left = jmin (left, pg.getLeft());
- top = jmin (top, pg.getTop());
- right = jmax (right, pg.getRight());
- bottom = jmax (bottom, pg.getBottom());
- }
- }
- }
- }
-
- void GlyphArrangement::justifyGlyphs (const int startIndex,
- const int num,
- const float x, const float y,
- const float width, const float height,
- const Justification& justification) throw()
- {
- jassert (num >= 0 && startIndex >= 0);
-
- if (numGlyphs > 0 && num > 0)
- {
- float left, top, right, bottom;
- getBoundingBox (startIndex, num, left, top, right, bottom,
- ! justification.testFlags (Justification::horizontallyJustified
- | Justification::horizontallyCentred));
-
- float deltaX = 0.0f;
-
- if (justification.testFlags (Justification::horizontallyJustified))
- deltaX = x - left;
- else if (justification.testFlags (Justification::horizontallyCentred))
- deltaX = x + (width - (right - left)) * 0.5f - left;
- else if (justification.testFlags (Justification::right))
- deltaX = (x + width) - right;
- else
- deltaX = x - left;
-
- float deltaY = 0.0f;
-
- if (justification.testFlags (Justification::top))
- deltaY = y - top;
- else if (justification.testFlags (Justification::bottom))
- deltaY = (y + height) - bottom;
- else
- deltaY = y + (height - (bottom - top)) * 0.5f - top;
-
- moveRangeOfGlyphs (startIndex, num, deltaX, deltaY);
-
- if (justification.testFlags (Justification::horizontallyJustified))
- {
- int lineStart = 0;
- float baseY = glyphs [startIndex].getBaselineY();
-
- int i;
- for (i = 0; i < num; ++i)
- {
- const float glyphY = glyphs [startIndex + i].getBaselineY();
-
- if (glyphY != baseY)
- {
- spreadOutLine (startIndex + lineStart, i - lineStart, width);
-
- lineStart = i;
- baseY = glyphY;
- }
- }
-
- if (i > lineStart)
- spreadOutLine (startIndex + lineStart, i - lineStart, width);
- }
- }
- }
-
- void GlyphArrangement::spreadOutLine (const int start, const int num, const float targetWidth) throw()
- {
- if (start + num < numGlyphs
- && glyphs [start + num - 1].getCharacter() != T('\r')
- && glyphs [start + num - 1].getCharacter() != T('\n'))
- {
- int numSpaces = 0;
- int spacesAtEnd = 0;
-
- for (int i = 0; i < num; ++i)
- {
- if (glyphs [start + i].isWhitespace())
- {
- ++spacesAtEnd;
- ++numSpaces;
- }
- else
- {
- spacesAtEnd = 0;
- }
- }
-
- numSpaces -= spacesAtEnd;
-
- if (numSpaces > 0)
- {
- const float startX = glyphs [start].getLeft();
- const float endX = glyphs [start + num - 1 - spacesAtEnd].getRight();
-
- const float extraPaddingBetweenWords
- = (targetWidth - (endX - startX)) / (float) numSpaces;
-
- float deltaX = 0.0f;
-
- for (int i = 0; i < num; ++i)
- {
- glyphs [start + i].moveBy (deltaX, 0.0);
-
- if (glyphs [start + i].isWhitespace())
- deltaX += extraPaddingBetweenWords;
- }
- }
- }
- }
-
- void GlyphArrangement::draw (const Graphics& g) const throw()
- {
- for (int i = 0; i < numGlyphs; ++i)
- {
- glyphs[i].draw (g);
-
- if (glyphs[i].isUnderlined)
- {
- const float lineThickness = (glyphs[i].fontHeight - glyphs[i].fontAscent) * 0.3f;
-
- juce_wchar nextChar = 0;
-
- if (i < numGlyphs - 1
- && glyphs[i + 1].y == glyphs[i].y)
- {
- nextChar = glyphs[i + 1].glyphInfo->getCharacter();
- }
-
- g.fillRect (glyphs[i].x,
- glyphs[i].y + lineThickness * 2.0f,
- glyphs[i].fontHeight
- * glyphs[i].fontHorizontalScale
- * glyphs[i].glyphInfo->getHorizontalSpacing (nextChar),
- lineThickness);
- }
- }
- }
-
- void GlyphArrangement::draw (const Graphics& g, const AffineTransform& transform) const throw()
- {
- for (int i = 0; i < numGlyphs; ++i)
- {
- glyphs[i].draw (g, transform);
-
- if (glyphs[i].isUnderlined)
- {
- const float lineThickness = (glyphs[i].fontHeight - glyphs[i].fontAscent) * 0.3f;
-
- juce_wchar nextChar = 0;
-
- if (i < numGlyphs - 1
- && glyphs[i + 1].y == glyphs[i].y)
- {
- nextChar = glyphs[i + 1].glyphInfo->getCharacter();
- }
-
- Path p;
- p.addLineSegment (glyphs[i].x,
- glyphs[i].y + lineThickness * 2.5f,
- glyphs[i].x + glyphs[i].fontHeight
- * glyphs[i].fontHorizontalScale
- * glyphs[i].glyphInfo->getHorizontalSpacing (nextChar),
- glyphs[i].y + lineThickness * 2.5f,
- lineThickness);
-
- g.fillPath (p, transform);
- }
- }
- }
-
- void GlyphArrangement::createPath (Path& path) const throw()
- {
- for (int i = 0; i < numGlyphs; ++i)
- glyphs[i].createPath (path);
- }
-
- int GlyphArrangement::findGlyphIndexAt (float x, float y) const throw()
- {
- for (int i = 0; i < numGlyphs; ++i)
- if (glyphs[i].hitTest (x, y))
- return i;
-
- return -1;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_GlyphArrangement.cpp *********/
-
- /********* Start of inlined file: juce_TextLayout.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- class TextLayoutToken
- {
- public:
- String text;
- Font font;
- int x, y, w, h;
- int line, lineHeight;
- bool isWhitespace, isNewLine;
-
- TextLayoutToken (const String& t,
- const Font& f,
- const bool isWhitespace_) throw()
- : text (t),
- font (f),
- x(0),
- y(0),
- isWhitespace (isWhitespace_)
- {
- w = font.getStringWidth (t);
- h = roundFloatToInt (f.getHeight());
- isNewLine = t.containsAnyOf (T("\r\n"));
- }
-
- TextLayoutToken (const TextLayoutToken& other) throw()
- : text (other.text),
- font (other.font),
- x (other.x),
- y (other.y),
- w (other.w),
- h (other.h),
- line (other.line),
- lineHeight (other.lineHeight),
- isWhitespace (other.isWhitespace),
- isNewLine (other.isNewLine)
- {
- }
-
- ~TextLayoutToken() throw()
- {
- }
-
- void draw (Graphics& g,
- const int xOffset,
- const int yOffset) throw()
- {
- if (! isWhitespace)
- {
- g.setFont (font);
- g.drawSingleLineText (text.trimEnd(),
- xOffset + x,
- yOffset + y + (lineHeight - h)
- + roundFloatToInt (font.getAscent()));
- }
- }
-
- juce_UseDebuggingNewOperator
- };
-
- TextLayout::TextLayout() throw()
- : tokens (64),
- totalLines (0)
- {
- }
-
- TextLayout::TextLayout (const String& text,
- const Font& font) throw()
- : tokens (64),
- totalLines (0)
- {
- appendText (text, font);
- }
-
- TextLayout::TextLayout (const TextLayout& other) throw()
- : tokens (64),
- totalLines (0)
- {
- *this = other;
- }
-
- const TextLayout& TextLayout::operator= (const TextLayout& other) throw()
- {
- if (this != &other)
- {
- clear();
-
- totalLines = other.totalLines;
-
- for (int i = 0; i < other.tokens.size(); ++i)
- tokens.add (new TextLayoutToken (*(const TextLayoutToken*)(other.tokens.getUnchecked(i))));
- }
-
- return *this;
- }
-
- TextLayout::~TextLayout() throw()
- {
- clear();
- }
-
- void TextLayout::clear() throw()
- {
- for (int i = tokens.size(); --i >= 0;)
- {
- TextLayoutToken* const t = (TextLayoutToken*)tokens.getUnchecked(i);
- delete t;
- }
-
- tokens.clear();
- totalLines = 0;
- }
-
- void TextLayout::appendText (const String& text,
- const Font& font) throw()
- {
- const tchar* t = text;
- String currentString;
- int lastCharType = 0;
-
- for (;;)
- {
- const tchar c = *t++;
- if (c == 0)
- break;
-
- int charType;
- if (c == T('\r') || c == T('\n'))
- {
- charType = 0;
- }
- else if (CharacterFunctions::isWhitespace (c))
- {
- charType = 2;
- }
- else
- {
- charType = 1;
- }
-
- if (charType == 0 || charType != lastCharType)
- {
- if (currentString.isNotEmpty())
- {
- tokens.add (new TextLayoutToken (currentString, font,
- lastCharType == 2 || lastCharType == 0));
- }
-
- currentString = String::charToString (c);
-
- if (c == T('\r') && *t == T('\n'))
- currentString += *t++;
- }
- else
- {
- currentString += c;
- }
-
- lastCharType = charType;
- }
-
- if (currentString.isNotEmpty())
- tokens.add (new TextLayoutToken (currentString,
- font,
- lastCharType == 2));
- }
-
- void TextLayout::setText (const String& text, const Font& font) throw()
- {
- clear();
- appendText (text, font);
- }
-
- void TextLayout::layout (int maxWidth,
- const Justification& justification,
- const bool attemptToBalanceLineLengths) throw()
- {
- if (attemptToBalanceLineLengths)
- {
- const int originalW = maxWidth;
- int bestWidth = maxWidth;
- float bestLineProportion = 0.0f;
-
- while (maxWidth > originalW / 2)
- {
- layout (maxWidth, justification, false);
-
- if (getNumLines() <= 1)
- return;
-
- const int lastLineW = getLineWidth (getNumLines() - 1);
- const int lastButOneLineW = getLineWidth (getNumLines() - 2);
-
- const float prop = lastLineW / (float) lastButOneLineW;
-
- if (prop > 0.9f)
- return;
-
- if (prop > bestLineProportion)
- {
- bestLineProportion = prop;
- bestWidth = maxWidth;
- }
-
- maxWidth -= 10;
- }
-
- layout (bestWidth, justification, false);
- }
- else
- {
- int x = 0;
- int y = 0;
- int h = 0;
- totalLines = 0;
- int i;
-
- for (i = 0; i < tokens.size(); ++i)
- {
- TextLayoutToken* const t = (TextLayoutToken*)tokens.getUnchecked(i);
- t->x = x;
- t->y = y;
- t->line = totalLines;
- x += t->w;
- h = jmax (h, t->h);
-
- const TextLayoutToken* nextTok = (TextLayoutToken*) tokens [i + 1];
-
- if (nextTok == 0)
- break;
-
- if (t->isNewLine || ((! nextTok->isWhitespace) && x + nextTok->w > maxWidth))
- {
- // finished a line, so go back and update the heights of the things on it
- for (int j = i; j >= 0; --j)
- {
- TextLayoutToken* const tok = (TextLayoutToken*)tokens.getUnchecked(j);
-
- if (tok->line == totalLines)
- tok->lineHeight = h;
- else
- break;
- }
-
- x = 0;
- y += h;
- h = 0;
- ++totalLines;
- }
- }
-
- // finished a line, so go back and update the heights of the things on it
- for (int j = jmin (i, tokens.size() - 1); j >= 0; --j)
- {
- TextLayoutToken* const t = (TextLayoutToken*) tokens.getUnchecked(j);
-
- if (t->line == totalLines)
- t->lineHeight = h;
- else
- break;
- }
-
- ++totalLines;
-
- if (! justification.testFlags (Justification::left))
- {
- int totalW = getWidth();
-
- for (i = totalLines; --i >= 0;)
- {
- const int lineW = getLineWidth (i);
-
- int dx = 0;
- if (justification.testFlags (Justification::horizontallyCentred))
- dx = (totalW - lineW) / 2;
- else if (justification.testFlags (Justification::right))
- dx = totalW - lineW;
-
- for (int j = tokens.size(); --j >= 0;)
- {
- TextLayoutToken* const t = (TextLayoutToken*)tokens.getUnchecked(j);
-
- if (t->line == i)
- t->x += dx;
- }
- }
- }
- }
- }
-
- int TextLayout::getLineWidth (const int lineNumber) const throw()
- {
- int maxW = 0;
-
- for (int i = tokens.size(); --i >= 0;)
- {
- const TextLayoutToken* const t = (TextLayoutToken*) tokens.getUnchecked(i);
-
- if (t->line == lineNumber && ! t->isWhitespace)
- maxW = jmax (maxW, t->x + t->w);
- }
-
- return maxW;
- }
-
- int TextLayout::getWidth() const throw()
- {
- int maxW = 0;
-
- for (int i = tokens.size(); --i >= 0;)
- {
- const TextLayoutToken* const t = (TextLayoutToken*) tokens.getUnchecked(i);
- if (! t->isWhitespace)
- maxW = jmax (maxW, t->x + t->w);
- }
-
- return maxW;
- }
-
- int TextLayout::getHeight() const throw()
- {
- int maxH = 0;
-
- for (int i = tokens.size(); --i >= 0;)
- {
- const TextLayoutToken* const t = (TextLayoutToken*) tokens.getUnchecked(i);
-
- if (! t->isWhitespace)
- maxH = jmax (maxH, t->y + t->h);
- }
-
- return maxH;
- }
-
- void TextLayout::draw (Graphics& g,
- const int xOffset,
- const int yOffset) const throw()
- {
- for (int i = tokens.size(); --i >= 0;)
- ((TextLayoutToken*) tokens.getUnchecked(i))->draw (g, xOffset, yOffset);
- }
-
- void TextLayout::drawWithin (Graphics& g,
- int x, int y, int w, int h,
- const Justification& justification) const throw()
- {
- justification.applyToRectangle (x, y, getWidth(), getHeight(),
- x, y, w, h);
-
- draw (g, x, y);
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_TextLayout.cpp *********/
-
- /********* Start of inlined file: juce_Typeface.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- TypefaceGlyphInfo::TypefaceGlyphInfo (const juce_wchar character_,
- const Path& shape,
- const float horizontalSeparation,
- Typeface* const typeface_) throw()
- : character (character_),
- path (shape),
- width (horizontalSeparation),
- typeface (typeface_)
- {
- }
-
- TypefaceGlyphInfo::~TypefaceGlyphInfo() throw()
- {
- }
-
- float TypefaceGlyphInfo::getHorizontalSpacing (const juce_wchar subsequentCharacter) const throw()
- {
- if (subsequentCharacter != 0)
- {
- const KerningPair* const pairs = (const KerningPair*) kerningPairs.getData();
- const int numPairs = getNumKerningPairs();
-
- for (int i = 0; i < numPairs; ++i)
- if (pairs [i].character2 == subsequentCharacter)
- return width + pairs [i].kerningAmount;
- }
-
- return width;
- }
-
- void TypefaceGlyphInfo::addKerningPair (const juce_wchar subsequentCharacter,
- const float extraKerningAmount) throw()
- {
- const int numPairs = getNumKerningPairs();
- kerningPairs.setSize ((numPairs + 1) * sizeof (KerningPair));
-
- KerningPair& p = getKerningPair (numPairs);
- p.character2 = subsequentCharacter;
- p.kerningAmount = extraKerningAmount;
- }
-
- TypefaceGlyphInfo::KerningPair& TypefaceGlyphInfo::getKerningPair (const int index) const throw()
- {
- return ((KerningPair*) kerningPairs.getData()) [index];
- }
-
- int TypefaceGlyphInfo::getNumKerningPairs() const throw()
- {
- return kerningPairs.getSize() / sizeof (KerningPair);
- }
-
- Typeface::Typeface() throw()
- : hash (0),
- isFullyPopulated (false)
- {
- zeromem (lookupTable, sizeof (lookupTable));
- }
-
- Typeface::Typeface (const Typeface& other)
- : typefaceName (other.typefaceName),
- ascent (other.ascent),
- bold (other.bold),
- italic (other.italic),
- isFullyPopulated (other.isFullyPopulated),
- defaultCharacter (other.defaultCharacter)
- {
- zeromem (lookupTable, sizeof (lookupTable));
-
- for (int i = 0; i < other.glyphs.size(); ++i)
- addGlyphCopy ((const TypefaceGlyphInfo*) other.glyphs.getUnchecked(i));
-
- updateHashCode();
- }
-
- Typeface::Typeface (const String& faceName,
- const bool bold,
- const bool italic)
- : isFullyPopulated (false)
- {
- zeromem (lookupTable, sizeof (lookupTable));
-
- initialiseTypefaceCharacteristics (faceName, bold, italic, false);
-
- updateHashCode();
- }
-
- Typeface::~Typeface()
- {
- clear();
- }
-
- const Typeface& Typeface::operator= (const Typeface& other) throw()
- {
- if (this != &other)
- {
- clear();
-
- typefaceName = other.typefaceName;
- ascent = other.ascent;
- bold = other.bold;
- italic = other.italic;
- isFullyPopulated = other.isFullyPopulated;
- defaultCharacter = other.defaultCharacter;
-
- for (int i = 0; i < other.glyphs.size(); ++i)
- addGlyphCopy ((const TypefaceGlyphInfo*) other.glyphs.getUnchecked(i));
-
- updateHashCode();
- }
-
- return *this;
- }
-
- void Typeface::updateHashCode() throw()
- {
- hash = typefaceName.hashCode();
-
- if (bold)
- hash ^= 0xffff;
-
- if (italic)
- hash ^= 0xffff0000;
- }
-
- void Typeface::clear() throw()
- {
- zeromem (lookupTable, sizeof (lookupTable));
- typefaceName = String::empty;
- bold = false;
- italic = false;
-
- for (int i = glyphs.size(); --i >= 0;)
- {
- TypefaceGlyphInfo* const g = (TypefaceGlyphInfo*) (glyphs.getUnchecked(i));
- delete g;
- }
-
- glyphs.clear();
- updateHashCode();
- }
-
- Typeface::Typeface (InputStream& serialisedTypefaceStream)
- {
- zeromem (lookupTable, sizeof (lookupTable));
- isFullyPopulated = true;
-
- GZIPDecompressorInputStream gzin (&serialisedTypefaceStream, false);
- BufferedInputStream in (&gzin, 32768, false);
-
- typefaceName = in.readString();
- bold = in.readBool();
- italic = in.readBool();
- ascent = in.readFloat();
- defaultCharacter = (juce_wchar) in.readShort();
-
- int i, numChars = in.readInt();
-
- for (i = 0; i < numChars; ++i)
- {
- const juce_wchar c = (juce_wchar) in.readShort();
- const float width = in.readFloat();
-
- Path p;
- p.loadPathFromStream (in);
- addGlyph (c, p, width);
- }
-
- const int numKerningPairs = in.readInt();
-
- for (i = 0; i < numKerningPairs; ++i)
- {
- const juce_wchar char1 = (juce_wchar) in.readShort();
- const juce_wchar char2 = (juce_wchar) in.readShort();
-
- addKerningPair (char1, char2, in.readFloat());
- }
-
- updateHashCode();
- }
-
- void Typeface::serialise (OutputStream& outputStream)
- {
- GZIPCompressorOutputStream out (&outputStream);
-
- out.writeString (typefaceName);
- out.writeBool (bold);
- out.writeBool (italic);
- out.writeFloat (ascent);
- out.writeShort ((short) (unsigned short) defaultCharacter);
- out.writeInt (glyphs.size());
-
- int i, numKerningPairs = 0;
-
- for (i = 0; i < glyphs.size(); ++i)
- {
- const TypefaceGlyphInfo& g = *(const TypefaceGlyphInfo*)(glyphs.getUnchecked (i));
- out.writeShort ((short) (unsigned short) g.character);
- out.writeFloat (g.width);
- g.path.writePathToStream (out);
-
- numKerningPairs += g.getNumKerningPairs();
- }
-
- out.writeInt (numKerningPairs);
-
- for (i = 0; i < glyphs.size(); ++i)
- {
- const TypefaceGlyphInfo& g = *(const TypefaceGlyphInfo*)(glyphs.getUnchecked (i));
-
- for (int j = 0; j < g.getNumKerningPairs(); ++j)
- {
- const TypefaceGlyphInfo::KerningPair& p = g.getKerningPair (j);
- out.writeShort ((short) (unsigned short) g.character);
- out.writeShort ((short) (unsigned short) p.character2);
- out.writeFloat (p.kerningAmount);
- }
- }
- }
-
- const Path* Typeface::getOutlineForGlyph (const juce_wchar character) throw()
- {
- const TypefaceGlyphInfo* const g = (const TypefaceGlyphInfo*) getGlyph (character);
-
- if (g != 0)
- return &(g->path);
- else
- return 0;
- }
-
- const TypefaceGlyphInfo* Typeface::getGlyph (const juce_wchar character) throw()
- {
- if (((unsigned int) character) < 128 && lookupTable [character] > 0)
- return (const TypefaceGlyphInfo*) glyphs [(int) lookupTable [character]];
-
- for (int i = 0; i < glyphs.size(); ++i)
- {
- const TypefaceGlyphInfo* const g = (const TypefaceGlyphInfo*) glyphs.getUnchecked(i);
-
- if (g->character == character)
- return g;
- }
-
- if ((! isFullyPopulated)
- && findAndAddSystemGlyph (character))
- {
- for (int i = 0; i < glyphs.size(); ++i)
- {
- const TypefaceGlyphInfo* const g = (const TypefaceGlyphInfo*) glyphs.getUnchecked(i);
-
- if (g->character == character)
- return g;
- }
- }
-
- if (CharacterFunctions::isWhitespace (character) && character != L' ')
- {
- const TypefaceGlyphInfo* spaceGlyph = getGlyph (L' ');
-
- if (spaceGlyph != 0)
- {
- // Add a copy of the empty glyph, mapped onto this character
- addGlyph (character, spaceGlyph->getPath(), spaceGlyph->getHorizontalSpacing (0));
- spaceGlyph = (const TypefaceGlyphInfo*) glyphs [(int) lookupTable [character]];
- }
-
- return spaceGlyph;
- }
- else if (character != defaultCharacter)
- {
- const Font fallbackFont (Font::getFallbackFontName(), 10, 0);
- Typeface* const fallbackTypeface = fallbackFont.getTypeface();
-
- if (fallbackTypeface != 0 && fallbackTypeface != this)
- return fallbackTypeface->getGlyph (character);
-
- return getGlyph (defaultCharacter);
- }
-
- return 0;
- }
-
- void Typeface::addGlyph (const juce_wchar character,
- const Path& path,
- const float horizontalSpacing) throw()
- {
- #ifdef JUCE_DEBUG
- for (int i = 0; i < glyphs.size(); ++i)
- {
- const TypefaceGlyphInfo* const g = (const TypefaceGlyphInfo*) glyphs.getUnchecked(i);
-
- if (g->character == character)
- jassertfalse;
- }
- #endif
-
- if (((unsigned int) character) < 128)
- lookupTable [character] = (short) glyphs.size();
-
- glyphs.add (new TypefaceGlyphInfo (character,
- path,
- horizontalSpacing,
- this));
- }
-
- void Typeface::addGlyphCopy (const TypefaceGlyphInfo* const glyphInfoToCopy) throw()
- {
- if (glyphInfoToCopy != 0)
- {
- if (glyphInfoToCopy->character > 0 && glyphInfoToCopy->character < 128)
- lookupTable [glyphInfoToCopy->character] = (short) glyphs.size();
-
- TypefaceGlyphInfo* const newOne
- = new TypefaceGlyphInfo (glyphInfoToCopy->character,
- glyphInfoToCopy->path,
- glyphInfoToCopy->width,
- this);
-
- newOne->kerningPairs = glyphInfoToCopy->kerningPairs;
- glyphs.add (newOne);
- }
- }
-
- void Typeface::addKerningPair (const juce_wchar char1,
- const juce_wchar char2,
- const float extraAmount) throw()
- {
- TypefaceGlyphInfo* const g = (TypefaceGlyphInfo*) getGlyph (char1);
-
- if (g != 0)
- g->addKerningPair (char2, extraAmount);
- }
-
- void Typeface::setName (const String& name) throw()
- {
- typefaceName = name;
- updateHashCode();
- }
-
- void Typeface::setAscent (const float newAscent) throw()
- {
- ascent = newAscent;
- }
-
- void Typeface::setDefaultCharacter (const juce_wchar newDefaultCharacter) throw()
- {
- defaultCharacter = newDefaultCharacter;
- }
-
- void Typeface::setBold (const bool shouldBeBold) throw()
- {
- bold = shouldBeBold;
- updateHashCode();
- }
-
- void Typeface::setItalic (const bool shouldBeItalic) throw()
- {
- italic = shouldBeItalic;
- updateHashCode();
- }
-
- class TypefaceCache;
- static TypefaceCache* typefaceCacheInstance = 0;
-
- void clearUpDefaultFontNames() throw(); // in juce_Font.cpp
-
- class TypefaceCache : private DeletedAtShutdown
- {
- private:
-
- struct CachedFace
- {
- CachedFace() throw()
- : lastUsageCount (0),
- flags (0)
- {
- }
-
- String typefaceName;
- int lastUsageCount;
- int flags;
- Typeface::Ptr typeFace;
- };
-
- int counter;
- OwnedArray <CachedFace> faces;
-
- TypefaceCache (const TypefaceCache&);
- const TypefaceCache& operator= (const TypefaceCache&);
-
- public:
-
- TypefaceCache (int numToCache = 10)
- : counter (1),
- faces (2)
- {
- while (--numToCache >= 0)
- {
- CachedFace* const face = new CachedFace();
- face->typeFace = new Typeface();
- faces.add (face);
- }
- }
-
- ~TypefaceCache()
- {
- faces.clear();
- jassert (typefaceCacheInstance == this);
- typefaceCacheInstance = 0;
-
- // just a courtesy call to get avoid leaking these strings at shutdown
- clearUpDefaultFontNames();
- }
-
- static TypefaceCache* getInstance() throw()
- {
- if (typefaceCacheInstance == 0)
- typefaceCacheInstance = new TypefaceCache();
-
- return typefaceCacheInstance;
- }
-
- const Typeface::Ptr findTypefaceFor (const Font& font) throw()
- {
- const int flags = font.getStyleFlags() & (Font::bold | Font::italic);
-
- int i;
- for (i = faces.size(); --i >= 0;)
- {
- CachedFace* const face = faces.getUnchecked(i);
-
- if (face->flags == flags
- && face->typefaceName == font.getTypefaceName())
- {
- face->lastUsageCount = ++counter;
- return face->typeFace;
- }
- }
-
- int replaceIndex = 0;
- int bestLastUsageCount = INT_MAX;
-
- for (i = faces.size(); --i >= 0;)
- {
- const int lu = faces.getUnchecked(i)->lastUsageCount;
-
- if (bestLastUsageCount > lu)
- {
- bestLastUsageCount = lu;
- replaceIndex = i;
- }
- }
-
- CachedFace* const face = faces.getUnchecked (replaceIndex);
-
- face->typefaceName = font.getTypefaceName();
- face->flags = flags;
- face->lastUsageCount = ++counter;
- face->typeFace = new Typeface (font.getTypefaceName(),
- font.isBold(),
- font.isItalic());
-
- return face->typeFace;
- }
- };
-
- const Typeface::Ptr Typeface::getTypefaceFor (const Font& font) throw()
- {
- return TypefaceCache::getInstance()->findTypefaceFor (font);
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_Typeface.cpp *********/
-
- /********* Start of inlined file: juce_AffineTransform.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- AffineTransform::AffineTransform() throw()
- : mat00 (1.0f),
- mat01 (0),
- mat02 (0),
- mat10 (0),
- mat11 (1.0f),
- mat12 (0)
- {
- }
-
- AffineTransform::AffineTransform (const AffineTransform& other) throw()
- : mat00 (other.mat00),
- mat01 (other.mat01),
- mat02 (other.mat02),
- mat10 (other.mat10),
- mat11 (other.mat11),
- mat12 (other.mat12)
- {
- }
-
- AffineTransform::AffineTransform (const float mat00_,
- const float mat01_,
- const float mat02_,
- const float mat10_,
- const float mat11_,
- const float mat12_) throw()
- : mat00 (mat00_),
- mat01 (mat01_),
- mat02 (mat02_),
- mat10 (mat10_),
- mat11 (mat11_),
- mat12 (mat12_)
- {
- }
-
- const AffineTransform& AffineTransform::operator= (const AffineTransform& other) throw()
- {
- mat00 = other.mat00;
- mat01 = other.mat01;
- mat02 = other.mat02;
- mat10 = other.mat10;
- mat11 = other.mat11;
- mat12 = other.mat12;
-
- return *this;
- }
-
- bool AffineTransform::operator== (const AffineTransform& other) const throw()
- {
- return mat00 == other.mat00
- && mat01 == other.mat01
- && mat02 == other.mat02
- && mat10 == other.mat10
- && mat11 == other.mat11
- && mat12 == other.mat12;
- }
-
- bool AffineTransform::operator!= (const AffineTransform& other) const throw()
- {
- return ! operator== (other);
- }
-
- bool AffineTransform::isIdentity() const throw()
- {
- return (mat01 == 0)
- && (mat02 == 0)
- && (mat10 == 0)
- && (mat12 == 0)
- && (mat00 == 1.0f)
- && (mat11 == 1.0f);
- }
-
- const AffineTransform AffineTransform::identity;
-
- const AffineTransform AffineTransform::followedBy (const AffineTransform& other) const throw()
- {
- return AffineTransform (other.mat00 * mat00 + other.mat01 * mat10,
- other.mat00 * mat01 + other.mat01 * mat11,
- other.mat00 * mat02 + other.mat01 * mat12 + other.mat02,
- other.mat10 * mat00 + other.mat11 * mat10,
- other.mat10 * mat01 + other.mat11 * mat11,
- other.mat10 * mat02 + other.mat11 * mat12 + other.mat12);
- }
-
- const AffineTransform AffineTransform::followedBy (const float omat00,
- const float omat01,
- const float omat02,
- const float omat10,
- const float omat11,
- const float omat12) const throw()
- {
- return AffineTransform (omat00 * mat00 + omat01 * mat10,
- omat00 * mat01 + omat01 * mat11,
- omat00 * mat02 + omat01 * mat12 + omat02,
- omat10 * mat00 + omat11 * mat10,
- omat10 * mat01 + omat11 * mat11,
- omat10 * mat02 + omat11 * mat12 + omat12);
- }
-
- const AffineTransform AffineTransform::translated (const float dx,
- const float dy) const throw()
- {
- return followedBy (1.0f, 0, dx,
- 0, 1.0f, dy);
- }
-
- const AffineTransform AffineTransform::translation (const float dx,
- const float dy) throw()
- {
- return AffineTransform (1.0f, 0, dx,
- 0, 1.0f, dy);
- }
-
- const AffineTransform AffineTransform::rotated (const float rad) const throw()
- {
- const float cosRad = cosf (rad);
- const float sinRad = sinf (rad);
-
- return followedBy (cosRad, -sinRad, 0,
- sinRad, cosRad, 0);
- }
-
- const AffineTransform AffineTransform::rotation (const float rad) throw()
- {
- const float cosRad = cosf (rad);
- const float sinRad = sinf (rad);
-
- return AffineTransform (cosRad, -sinRad, 0,
- sinRad, cosRad, 0);
- }
-
- const AffineTransform AffineTransform::rotated (const float angle,
- const float pivotX,
- const float pivotY) const throw()
- {
- return translated (-pivotX, -pivotY)
- .rotated (angle)
- .translated (pivotX, pivotY);
- }
-
- const AffineTransform AffineTransform::rotation (const float angle,
- const float pivotX,
- const float pivotY) throw()
- {
- return translation (-pivotX, -pivotY)
- .rotated (angle)
- .translated (pivotX, pivotY);
- }
-
- const AffineTransform AffineTransform::scaled (const float factorX,
- const float factorY) const throw()
- {
- return followedBy (factorX, 0, 0,
- 0, factorY, 0);
- }
-
- const AffineTransform AffineTransform::scale (const float factorX,
- const float factorY) throw()
- {
- return AffineTransform (factorX, 0, 0,
- 0, factorY, 0);
- }
-
- const AffineTransform AffineTransform::sheared (const float shearX,
- const float shearY) const throw()
- {
- return followedBy (1.0f, shearX, 0,
- shearY, 1.0f, 0);
- }
-
- const AffineTransform AffineTransform::inverted() const throw()
- {
- double determinant = (mat00 * mat11 - mat10 * mat01);
-
- if (determinant != 0.0)
- {
- determinant = 1.0 / determinant;
-
- const float dst00 = (float) (mat11 * determinant);
- const float dst10 = (float) (-mat10 * determinant);
- const float dst01 = (float) (-mat01 * determinant);
- const float dst11 = (float) (mat00 * determinant);
-
- return AffineTransform (dst00, dst01, -mat02 * dst00 - mat12 * dst01,
- dst10, dst11, -mat02 * dst10 - mat12 * dst11);
- }
- else
- {
- // singularity..
- return *this;
- }
- }
-
- bool AffineTransform::isSingularity() const throw()
- {
- return (mat00 * mat11 - mat10 * mat01) == 0.0;
- }
-
- void AffineTransform::transformPoint (float& x,
- float& y) const throw()
- {
- const float oldX = x;
- x = mat00 * oldX + mat01 * y + mat02;
- y = mat10 * oldX + mat11 * y + mat12;
- }
-
- void AffineTransform::transformPoint (double& x,
- double& y) const throw()
- {
- const double oldX = x;
- x = mat00 * oldX + mat01 * y + mat02;
- y = mat10 * oldX + mat11 * y + mat12;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_AffineTransform.cpp *********/
-
- /********* Start of inlined file: juce_BorderSize.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- BorderSize::BorderSize() throw()
- : top (0),
- left (0),
- bottom (0),
- right (0)
- {
- }
-
- BorderSize::BorderSize (const BorderSize& other) throw()
- : top (other.top),
- left (other.left),
- bottom (other.bottom),
- right (other.right)
- {
- }
-
- BorderSize::BorderSize (const int topGap,
- const int leftGap,
- const int bottomGap,
- const int rightGap) throw()
- : top (topGap),
- left (leftGap),
- bottom (bottomGap),
- right (rightGap)
- {
- }
-
- BorderSize::BorderSize (const int allGaps) throw()
- : top (allGaps),
- left (allGaps),
- bottom (allGaps),
- right (allGaps)
- {
- }
-
- BorderSize::~BorderSize() throw()
- {
- }
-
- void BorderSize::setTop (const int newTopGap) throw()
- {
- top = newTopGap;
- }
-
- void BorderSize::setLeft (const int newLeftGap) throw()
- {
- left = newLeftGap;
- }
-
- void BorderSize::setBottom (const int newBottomGap) throw()
- {
- bottom = newBottomGap;
- }
-
- void BorderSize::setRight (const int newRightGap) throw()
- {
- right = newRightGap;
- }
-
- const Rectangle BorderSize::subtractedFrom (const Rectangle& r) const throw()
- {
- return Rectangle (r.getX() + left,
- r.getY() + top,
- r.getWidth() - (left + right),
- r.getHeight() - (top + bottom));
- }
-
- void BorderSize::subtractFrom (Rectangle& r) const throw()
- {
- r.setBounds (r.getX() + left,
- r.getY() + top,
- r.getWidth() - (left + right),
- r.getHeight() - (top + bottom));
- }
-
- const Rectangle BorderSize::addedTo (const Rectangle& r) const throw()
- {
- return Rectangle (r.getX() - left,
- r.getY() - top,
- r.getWidth() + (left + right),
- r.getHeight() + (top + bottom));
- }
-
- void BorderSize::addTo (Rectangle& r) const throw()
- {
- r.setBounds (r.getX() - left,
- r.getY() - top,
- r.getWidth() + (left + right),
- r.getHeight() + (top + bottom));
- }
-
- bool BorderSize::operator== (const BorderSize& other) const throw()
- {
- return top == other.top
- && left == other.left
- && bottom == other.bottom
- && right == other.right;
- }
-
- bool BorderSize::operator!= (const BorderSize& other) const throw()
- {
- return ! operator== (other);
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_BorderSize.cpp *********/
-
- /********* Start of inlined file: juce_Line.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- static bool juce_lineIntersection (const float x1, const float y1,
- const float x2, const float y2,
- const float x3, const float y3,
- const float x4, const float y4,
- float& intersectionX,
- float& intersectionY) throw()
- {
- if (x2 != x3 || y2 != y3)
- {
- const float dx1 = x2 - x1;
- const float dy1 = y2 - y1;
- const float dx2 = x4 - x3;
- const float dy2 = y4 - y3;
- const float divisor = dx1 * dy2 - dx2 * dy1;
-
- if (divisor == 0)
- {
- if (! ((dx1 == 0 && dy1 == 0) || (dx2 == 0 && dy2 == 0)))
- {
- if (dy1 == 0 && dy2 != 0)
- {
- const float along = (y1 - y3) / dy2;
- intersectionX = x3 + along * dx2;
- intersectionY = y1;
-
- return along >= 0 && along <= 1.0f;
- }
- else if (dy2 == 0 && dy1 != 0)
- {
- const float along = (y3 - y1) / dy1;
- intersectionX = x1 + along * dx1;
- intersectionY = y3;
-
- return along >= 0 && along <= 1.0f;
- }
- else if (dx1 == 0 && dx2 != 0)
- {
- const float along = (x1 - x3) / dx2;
- intersectionX = x1;
- intersectionY = y3 + along * dy2;
-
- return along >= 0 && along <= 1.0f;
- }
- else if (dx2 == 0 && dx1 != 0)
- {
- const float along = (x3 - x1) / dx1;
- intersectionX = x3;
- intersectionY = y1 + along * dy1;
-
- return along >= 0 && along <= 1.0f;
- }
- }
-
- intersectionX = 0.5f * (x2 + x3);
- intersectionY = 0.5f * (y2 + y3);
-
- return false;
- }
-
- const float along1 = ((y1 - y3) * dx2 - (x1 - x3) * dy2) / divisor;
-
- intersectionX = x1 + along1 * dx1;
- intersectionY = y1 + along1 * dy1;
-
- if (along1 < 0 || along1 > 1.0f)
- return false;
-
- const float along2 = ((y1 - y3) * dx1 - (x1 - x3) * dy1) / divisor;
-
- return along2 >= 0 && along2 <= 1.0f;
- }
-
- intersectionX = x2;
- intersectionY = y2;
- return true;
- }
-
- Line::Line() throw()
- : startX (0.0f),
- startY (0.0f),
- endX (0.0f),
- endY (0.0f)
- {
- }
-
- Line::Line (const Line& other) throw()
- : startX (other.startX),
- startY (other.startY),
- endX (other.endX),
- endY (other.endY)
- {
- }
-
- Line::Line (const float startX_, const float startY_,
- const float endX_, const float endY_) throw()
- : startX (startX_),
- startY (startY_),
- endX (endX_),
- endY (endY_)
- {
- }
-
- Line::Line (const Point& start,
- const Point& end) throw()
- : startX (start.getX()),
- startY (start.getY()),
- endX (end.getX()),
- endY (end.getY())
- {
- }
-
- const Line& Line::operator= (const Line& other) throw()
- {
- startX = other.startX;
- startY = other.startY;
- endX = other.endX;
- endY = other.endY;
-
- return *this;
- }
-
- Line::~Line() throw()
- {
- }
-
- const Point Line::getStart() const throw()
- {
- return Point (startX, startY);
- }
-
- const Point Line::getEnd() const throw()
- {
- return Point (endX, endY);
- }
-
- void Line::setStart (const float newStartX,
- const float newStartY) throw()
- {
- startX = newStartX;
- startY = newStartY;
- }
-
- void Line::setStart (const Point& newStart) throw()
- {
- startX = newStart.getX();
- startY = newStart.getY();
- }
-
- void Line::setEnd (const float newEndX,
- const float newEndY) throw()
- {
- endX = newEndX;
- endY = newEndY;
- }
-
- void Line::setEnd (const Point& newEnd) throw()
- {
- endX = newEnd.getX();
- endY = newEnd.getY();
- }
-
- bool Line::operator== (const Line& other) const throw()
- {
- return startX == other.startX
- && startY == other.startY
- && endX == other.endX
- && endY == other.endY;
- }
-
- bool Line::operator!= (const Line& other) const throw()
- {
- return startX != other.startX
- || startY != other.startY
- || endX != other.endX
- || endY != other.endY;
- }
-
- void Line::applyTransform (const AffineTransform& transform) throw()
- {
- transform.transformPoint (startX, startY);
- transform.transformPoint (endX, endY);
- }
-
- float Line::getLength() const throw()
- {
- return (float) juce_hypot (startX - endX,
- startY - endY);
- }
-
- float Line::getAngle() const throw()
- {
- return atan2f (endX - startX,
- endY - startY);
- }
-
- const Point Line::getPointAlongLine (const float distanceFromStart) const throw()
- {
- const float alpha = distanceFromStart / getLength();
-
- return Point (startX + (endX - startX) * alpha,
- startY + (endY - startY) * alpha);
- }
-
- const Point Line::getPointAlongLine (const float offsetX,
- const float offsetY) const throw()
- {
- const float dx = endX - startX;
- const float dy = endY - startY;
- const double length = juce_hypot (dx, dy);
-
- if (length == 0)
- return Point (startX, startY);
- else
- return Point (startX + (float) (((dx * offsetX) - (dy * offsetY)) / length),
- startY + (float) (((dy * offsetX) + (dx * offsetY)) / length));
- }
-
- const Point Line::getPointAlongLineProportionally (const float alpha) const throw()
- {
- return Point (startX + (endX - startX) * alpha,
- startY + (endY - startY) * alpha);
- }
-
- float Line::getDistanceFromLine (const float x,
- const float y) const throw()
- {
- const double dx = endX - startX;
- const double dy = endY - startY;
- const double length = dx * dx + dy * dy;
-
- if (length > 0)
- {
- const double prop = ((x - startX) * dx + (y - startY) * dy) / length;
-
- if (prop >= 0.0f && prop < 1.0f)
- {
- return (float) juce_hypot (x - (startX + prop * dx),
- y - (startY + prop * dy));
- }
- }
-
- return (float) jmin (juce_hypot (x - startX, y - startY),
- juce_hypot (x - endX, y - endY));
- }
-
- float Line::findNearestPointTo (const float x,
- const float y) const throw()
- {
- const double dx = endX - startX;
- const double dy = endY - startY;
- const double length = dx * dx + dy * dy;
-
- if (length <= 0.0)
- return 0.0f;
-
- return jlimit (0.0f, 1.0f,
- (float) (((x - startX) * dx + (y - startY) * dy) / length));
- }
-
- const Line Line::withShortenedStart (const float distanceToShortenBy) const throw()
- {
- const float length = getLength();
-
- return Line (getPointAlongLine (jmin (distanceToShortenBy, length)),
- getEnd());
- }
-
- const Line Line::withShortenedEnd (const float distanceToShortenBy) const throw()
- {
- const float length = getLength();
-
- return Line (getStart(),
- getPointAlongLine (length - jmin (distanceToShortenBy, length)));
- }
-
- bool Line::clipToPath (const Path& path,
- const bool keepSectionOutsidePath) throw()
- {
- const bool startInside = path.contains (startX, startY);
- const bool endInside = path.contains (endX, endY);
-
- if (startInside == endInside)
- {
- if (keepSectionOutsidePath != startInside)
- {
- // entirely outside the path
- return false;
- }
- else
- {
- // entirely inside the path
- startX = 0.0f;
- startY = 0.0f;
- endX = 0.0f;
- endY = 0.0f;
-
- return true;
- }
- }
- else
- {
- bool changed = false;
- PathFlatteningIterator iter (path, AffineTransform::identity);
-
- while (iter.next())
- {
- float ix, iy;
-
- if (intersects (Line (iter.x1, iter.y1,
- iter.x2, iter.y2),
- ix, iy))
- {
- if ((startInside && keepSectionOutsidePath)
- || (endInside && ! keepSectionOutsidePath))
- {
- setStart (ix, iy);
- }
- else
- {
- setEnd (ix, iy);
- }
-
- changed = true;
- }
- }
-
- return changed;
- }
- }
-
- bool Line::intersects (const Line& line,
- float& intersectionX,
- float& intersectionY) const throw()
- {
- return juce_lineIntersection (startX, startY,
- endX, endY,
- line.startX, line.startY,
- line.endX, line.endY,
- intersectionX,
- intersectionY);
- }
-
- bool Line::isVertical() const throw()
- {
- return startX == endX;
- }
-
- bool Line::isHorizontal() const throw()
- {
- return startY == endY;
- }
-
- bool Line::isPointAbove (const float x, const float y) const throw()
- {
- return startX != endX
- && y < ((endY - startY) * (x - startX)) / (endX - startX) + startY;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_Line.cpp *********/
-
- /********* Start of inlined file: juce_Path.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- // tests that some co-ords aren't NaNs
- #define CHECK_COORDS_ARE_VALID(x, y) \
- jassert (x == x && y == y);
-
- const float Path::lineMarker = 100001.0f;
- const float Path::moveMarker = 100002.0f;
- const float Path::quadMarker = 100003.0f;
- const float Path::cubicMarker = 100004.0f;
- const float Path::closeSubPathMarker = 100005.0f;
-
- static const int defaultGranularity = 32;
-
- Path::Path() throw()
- : ArrayAllocationBase <float> (defaultGranularity),
- numElements (0),
- pathXMin (0),
- pathXMax (0),
- pathYMin (0),
- pathYMax (0),
- useNonZeroWinding (true)
- {
- }
-
- Path::~Path() throw()
- {
- }
-
- Path::Path (const Path& other) throw()
- : ArrayAllocationBase <float> (defaultGranularity),
- numElements (other.numElements),
- pathXMin (other.pathXMin),
- pathXMax (other.pathXMax),
- pathYMin (other.pathYMin),
- pathYMax (other.pathYMax),
- useNonZeroWinding (other.useNonZeroWinding)
- {
- if (numElements > 0)
- {
- setAllocatedSize (numElements);
- memcpy (elements, other.elements, numElements * sizeof (float));
- }
- }
-
- const Path& Path::operator= (const Path& other) throw()
- {
- if (this != &other)
- {
- ensureAllocatedSize (other.numElements);
-
- numElements = other.numElements;
- pathXMin = other.pathXMin;
- pathXMax = other.pathXMax;
- pathYMin = other.pathYMin;
- pathYMax = other.pathYMax;
- useNonZeroWinding = other.useNonZeroWinding;
-
- if (numElements > 0)
- memcpy (elements, other.elements, numElements * sizeof (float));
- }
-
- return *this;
- }
-
- void Path::clear() throw()
- {
- numElements = 0;
- pathXMin = 0;
- pathYMin = 0;
- pathYMax = 0;
- pathXMax = 0;
- }
-
- void Path::swapWithPath (Path& other)
- {
- swapVariables <int> (this->numAllocated, other.numAllocated);
- swapVariables <float*> (this->elements, other.elements);
- swapVariables <int> (this->numElements, other.numElements);
- swapVariables <float> (this->pathXMin, other.pathXMin);
- swapVariables <float> (this->pathXMax, other.pathXMax);
- swapVariables <float> (this->pathYMin, other.pathYMin);
- swapVariables <float> (this->pathYMax, other.pathYMax);
- swapVariables <bool> (this->useNonZeroWinding, other.useNonZeroWinding);
- }
-
- void Path::setUsingNonZeroWinding (const bool isNonZero) throw()
- {
- useNonZeroWinding = isNonZero;
- }
-
- void Path::scaleToFit (const float x, const float y, const float w, const float h,
- const bool preserveProportions) throw()
- {
- applyTransform (getTransformToScaleToFit (x, y, w, h, preserveProportions));
- }
-
- bool Path::isEmpty() const throw()
- {
- int i = 0;
-
- while (i < numElements)
- {
- const float type = elements [i++];
-
- if (type == moveMarker)
- {
- i += 2;
- }
- else if (type == lineMarker
- || type == quadMarker
- || type == cubicMarker)
- {
- return false;
- }
- }
-
- return true;
- }
-
- void Path::getBounds (float& x, float& y,
- float& w, float& h) const throw()
- {
- x = pathXMin;
- y = pathYMin;
- w = pathXMax - pathXMin;
- h = pathYMax - pathYMin;
- }
-
- void Path::getBoundsTransformed (const AffineTransform& transform,
- float& x, float& y,
- float& w, float& h) const throw()
- {
- float x1 = pathXMin;
- float y1 = pathYMin;
- transform.transformPoint (x1, y1);
-
- float x2 = pathXMax;
- float y2 = pathYMin;
- transform.transformPoint (x2, y2);
-
- float x3 = pathXMin;
- float y3 = pathYMax;
- transform.transformPoint (x3, y3);
-
- float x4 = pathXMax;
- float y4 = pathYMax;
- transform.transformPoint (x4, y4);
-
- x = jmin (x1, x2, x3, x4);
- y = jmin (y1, y2, y3, y4);
- w = jmax (x1, x2, x3, x4) - x;
- h = jmax (y1, y2, y3, y4) - y;
- }
-
- void Path::startNewSubPath (const float x,
- const float y) throw()
- {
- CHECK_COORDS_ARE_VALID (x, y);
-
- if (numElements == 0)
- {
- pathXMin = pathXMax = x;
- pathYMin = pathYMax = y;
- }
- else
- {
- pathXMin = jmin (pathXMin, x);
- pathXMax = jmax (pathXMax, x);
- pathYMin = jmin (pathYMin, y);
- pathYMax = jmax (pathYMax, y);
- }
-
- ensureAllocatedSize (numElements + 3);
-
- elements [numElements++] = moveMarker;
- elements [numElements++] = x;
- elements [numElements++] = y;
- }
-
- void Path::lineTo (const float x, const float y) throw()
- {
- CHECK_COORDS_ARE_VALID (x, y);
-
- if (numElements == 0)
- startNewSubPath (0, 0);
-
- ensureAllocatedSize (numElements + 3);
-
- elements [numElements++] = lineMarker;
- elements [numElements++] = x;
- elements [numElements++] = y;
-
- pathXMin = jmin (pathXMin, x);
- pathXMax = jmax (pathXMax, x);
- pathYMin = jmin (pathYMin, y);
- pathYMax = jmax (pathYMax, y);
- }
-
- void Path::quadraticTo (const float x1, const float y1,
- const float x2, const float y2) throw()
- {
- CHECK_COORDS_ARE_VALID (x1, y1);
- CHECK_COORDS_ARE_VALID (x2, y2);
-
- if (numElements == 0)
- startNewSubPath (0, 0);
-
- ensureAllocatedSize (numElements + 5);
-
- elements [numElements++] = quadMarker;
- elements [numElements++] = x1;
- elements [numElements++] = y1;
- elements [numElements++] = x2;
- elements [numElements++] = y2;
-
- pathXMin = jmin (pathXMin, x1, x2);
- pathXMax = jmax (pathXMax, x1, x2);
- pathYMin = jmin (pathYMin, y1, y2);
- pathYMax = jmax (pathYMax, y1, y2);
- }
-
- void Path::cubicTo (const float x1, const float y1,
- const float x2, const float y2,
- const float x3, const float y3) throw()
- {
- CHECK_COORDS_ARE_VALID (x1, y1);
- CHECK_COORDS_ARE_VALID (x2, y2);
- CHECK_COORDS_ARE_VALID (x3, y3);
-
- if (numElements == 0)
- startNewSubPath (0, 0);
-
- ensureAllocatedSize (numElements + 7);
-
- elements [numElements++] = cubicMarker;
- elements [numElements++] = x1;
- elements [numElements++] = y1;
- elements [numElements++] = x2;
- elements [numElements++] = y2;
- elements [numElements++] = x3;
- elements [numElements++] = y3;
-
- pathXMin = jmin (pathXMin, x1, x2, x3);
- pathXMax = jmax (pathXMax, x1, x2, x3);
- pathYMin = jmin (pathYMin, y1, y2, y3);
- pathYMax = jmax (pathYMax, y1, y2, y3);
- }
-
- void Path::closeSubPath() throw()
- {
- if (numElements > 0
- && elements [numElements - 1] != closeSubPathMarker)
- {
- ensureAllocatedSize (numElements + 1);
- elements [numElements++] = closeSubPathMarker;
- }
- }
-
- const Point Path::getCurrentPosition() const
- {
- int i = numElements - 1;
-
- if (i > 0 && elements[i] == closeSubPathMarker)
- {
- while (i >= 0)
- {
- if (elements[i] == moveMarker)
- {
- i += 2;
- break;
- }
-
- --i;
- }
- }
-
- if (i > 0)
- return Point (elements [i - 1], elements [i]);
-
- return Point (0.0f, 0.0f);
- }
-
- void Path::addRectangle (const float x, const float y,
- const float w, const float h) throw()
- {
- startNewSubPath (x, y + h);
- lineTo (x, y);
- lineTo (x + w, y);
- lineTo (x + w, y + h);
- closeSubPath();
- }
-
- void Path::addRoundedRectangle (const float x, const float y,
- const float w, const float h,
- float csx,
- float csy) throw()
- {
- csx = jmin (csx, w * 0.5f);
- csy = jmin (csy, h * 0.5f);
- const float cs45x = csx * 0.45f;
- const float cs45y = csy * 0.45f;
- const float x2 = x + w;
- const float y2 = y + h;
-
- startNewSubPath (x + csx, y);
- lineTo (x2 - csx, y);
- cubicTo (x2 - cs45x, y, x2, y + cs45y, x2, y + csy);
- lineTo (x2, y2 - csy);
- cubicTo (x2, y2 - cs45y, x2 - cs45x, y2, x2 - csx, y2);
- lineTo (x + csx, y2);
- cubicTo (x + cs45x, y2, x, y2 - cs45y, x, y2 - csy);
- lineTo (x, y + csy);
- cubicTo (x, y + cs45y, x + cs45x, y, x + csx, y);
- closeSubPath();
- }
-
- void Path::addRoundedRectangle (const float x, const float y,
- const float w, const float h,
- float cs) throw()
- {
- addRoundedRectangle (x, y, w, h, cs, cs);
- }
-
- void Path::addTriangle (const float x1, const float y1,
- const float x2, const float y2,
- const float x3, const float y3) throw()
- {
- startNewSubPath (x1, y1);
- lineTo (x2, y2);
- lineTo (x3, y3);
- closeSubPath();
- }
-
- void Path::addQuadrilateral (const float x1, const float y1,
- const float x2, const float y2,
- const float x3, const float y3,
- const float x4, const float y4) throw()
- {
- startNewSubPath (x1, y1);
- lineTo (x2, y2);
- lineTo (x3, y3);
- lineTo (x4, y4);
- closeSubPath();
- }
-
- void Path::addEllipse (const float x, const float y,
- const float w, const float h) throw()
- {
- const float hw = w * 0.5f;
- const float hw55 = hw * 0.55f;
- const float hh = h * 0.5f;
- const float hh45 = hh * 0.55f;
- const float cx = x + hw;
- const float cy = y + hh;
-
- startNewSubPath (cx, cy - hh);
- cubicTo (cx + hw55, cy - hh, cx + hw, cy - hh45, cx + hw, cy);
- cubicTo (cx + hw, cy + hh45, cx + hw55, cy + hh, cx, cy + hh);
- cubicTo (cx - hw55, cy + hh, cx - hw, cy + hh45, cx - hw, cy);
- cubicTo (cx - hw, cy - hh45, cx - hw55, cy - hh, cx, cy - hh);
- closeSubPath();
- }
-
- void Path::addArc (const float x, const float y,
- const float w, const float h,
- const float fromRadians,
- const float toRadians,
- const bool startAsNewSubPath) throw()
- {
- const float radiusX = w / 2.0f;
- const float radiusY = h / 2.0f;
-
- addCentredArc (x + radiusX,
- y + radiusY,
- radiusX, radiusY,
- 0.0f,
- fromRadians, toRadians,
- startAsNewSubPath);
- }
-
- static const float ellipseAngularIncrement = 0.05f;
-
- void Path::addCentredArc (const float centreX, const float centreY,
- const float radiusX, const float radiusY,
- const float rotationOfEllipse,
- const float fromRadians,
- const float toRadians,
- const bool startAsNewSubPath) throw()
- {
- if (radiusX > 0.0f && radiusY > 0.0f)
- {
- const AffineTransform rotation (AffineTransform::rotation (rotationOfEllipse, centreX, centreY));
- float angle = fromRadians;
-
- if (startAsNewSubPath)
- {
- float x = centreX + radiusX * sinf (angle);
- float y = centreY - radiusY * cosf (angle);
-
- if (rotationOfEllipse != 0)
- rotation.transformPoint (x, y);
-
- startNewSubPath (x, y);
- }
-
- if (fromRadians < toRadians)
- {
- if (startAsNewSubPath)
- angle += ellipseAngularIncrement;
-
- while (angle < toRadians)
- {
- float x = centreX + radiusX * sinf (angle);
- float y = centreY - radiusY * cosf (angle);
-
- if (rotationOfEllipse != 0)
- rotation.transformPoint (x, y);
-
- lineTo (x, y);
-
- angle += ellipseAngularIncrement;
- }
- }
- else
- {
- if (startAsNewSubPath)
- angle -= ellipseAngularIncrement;
-
- while (angle > toRadians)
- {
- float x = centreX + radiusX * sinf (angle);
- float y = centreY - radiusY * cosf (angle);
-
- if (rotationOfEllipse != 0)
- rotation.transformPoint (x, y);
-
- lineTo (x, y);
-
- angle -= ellipseAngularIncrement;
- }
- }
-
- float x = centreX + radiusX * sinf (toRadians);
- float y = centreY - radiusY * cosf (toRadians);
-
- if (rotationOfEllipse != 0)
- rotation.transformPoint (x, y);
-
- lineTo (x, y);
- }
- }
-
- void Path::addPieSegment (const float x, const float y,
- const float width, const float height,
- const float fromRadians,
- const float toRadians,
- const float innerCircleProportionalSize)
- {
- float hw = width * 0.5f;
- float hh = height * 0.5f;
- const float centreX = x + hw;
- const float centreY = y + hh;
-
- startNewSubPath (centreX + hw * sinf (fromRadians),
- centreY - hh * cosf (fromRadians));
-
- addArc (x, y, width, height, fromRadians, toRadians);
-
- if (fabs (fromRadians - toRadians) > float_Pi * 1.999f)
- {
- closeSubPath();
-
- if (innerCircleProportionalSize > 0)
- {
- hw *= innerCircleProportionalSize;
- hh *= innerCircleProportionalSize;
-
- startNewSubPath (centreX + hw * sinf (toRadians),
- centreY - hh * cosf (toRadians));
-
- addArc (centreX - hw, centreY - hh, hw * 2.0f, hh * 2.0f,
- toRadians, fromRadians);
- }
- }
- else
- {
- if (innerCircleProportionalSize > 0)
- {
- hw *= innerCircleProportionalSize;
- hh *= innerCircleProportionalSize;
-
- addArc (centreX - hw, centreY - hh, hw * 2.0f, hh * 2.0f,
- toRadians, fromRadians);
- }
- else
- {
- lineTo (centreX, centreY);
- }
- }
-
- closeSubPath();
- }
-
- static void perpendicularOffset (const float x1, const float y1,
- const float x2, const float y2,
- const float offsetX, const float offsetY,
- float& resultX, float& resultY) throw()
- {
- const float dx = x2 - x1;
- const float dy = y2 - y1;
- const float len = juce_hypotf (dx, dy);
-
- if (len == 0)
- {
- resultX = x1;
- resultY = y1;
- }
- else
- {
- resultX = x1 + ((dx * offsetX) - (dy * offsetY)) / len;
- resultY = y1 + ((dy * offsetX) + (dx * offsetY)) / len;
- }
- }
-
- void Path::addLineSegment (const float startX, const float startY,
- const float endX, const float endY,
- float lineThickness) throw()
- {
- lineThickness *= 0.5f;
-
- float x, y;
-
- perpendicularOffset (startX, startY, endX, endY,
- 0, lineThickness, x, y);
- startNewSubPath (x, y);
-
- perpendicularOffset (startX, startY, endX, endY,
- 0, -lineThickness, x, y);
- lineTo (x, y);
-
- perpendicularOffset (endX, endY, startX, startY,
- 0, lineThickness, x, y);
- lineTo (x, y);
-
- perpendicularOffset (endX, endY, startX, startY,
- 0, -lineThickness, x, y);
- lineTo (x, y);
-
- closeSubPath();
- }
-
- void Path::addArrow (const float startX, const float startY,
- const float endX, const float endY,
- float lineThickness,
- float arrowheadWidth,
- float arrowheadLength) throw()
- {
- lineThickness *= 0.5f;
- arrowheadWidth *= 0.5f;
- arrowheadLength = jmin (arrowheadLength, 0.8f * juce_hypotf (startX - endX,
- startY - endY));
-
- float x, y;
-
- perpendicularOffset (startX, startY, endX, endY,
- 0, lineThickness, x, y);
- startNewSubPath (x, y);
-
- perpendicularOffset (startX, startY, endX, endY,
- 0, -lineThickness, x, y);
- lineTo (x, y);
-
- perpendicularOffset (endX, endY, startX, startY,
- arrowheadLength, lineThickness, x, y);
- lineTo (x, y);
-
- perpendicularOffset (endX, endY, startX, startY,
- arrowheadLength, arrowheadWidth, x, y);
- lineTo (x, y);
-
- perpendicularOffset (endX, endY, startX, startY,
- 0, 0, x, y);
- lineTo (x, y);
-
- perpendicularOffset (endX, endY, startX, startY,
- arrowheadLength, -arrowheadWidth, x, y);
- lineTo (x, y);
-
- perpendicularOffset (endX, endY, startX, startY,
- arrowheadLength, -lineThickness, x, y);
- lineTo (x, y);
-
- closeSubPath();
- }
-
- void Path::addStar (const float centreX,
- const float centreY,
- const int numberOfPoints,
- const float innerRadius,
- const float outerRadius,
- const float startAngle)
- {
- jassert (numberOfPoints > 1); // this would be silly.
-
- if (numberOfPoints > 1)
- {
- const float angleBetweenPoints = float_Pi * 2.0f / numberOfPoints;
-
- for (int i = 0; i < numberOfPoints; ++i)
- {
- float angle = startAngle + i * angleBetweenPoints;
-
- const float x = centreX + outerRadius * sinf (angle);
- const float y = centreY - outerRadius * cosf (angle);
-
- if (i == 0)
- startNewSubPath (x, y);
- else
- lineTo (x, y);
-
- angle += angleBetweenPoints * 0.5f;
-
- lineTo (centreX + innerRadius * sinf (angle),
- centreY - innerRadius * cosf (angle));
- }
-
- closeSubPath();
- }
- }
-
- void Path::addBubble (float x, float y,
- float w, float h,
- float cs,
- float tipX,
- float tipY,
- int whichSide,
- float arrowPos,
- float arrowWidth)
- {
- if (w > 1.0f && h > 1.0f)
- {
- cs = jmin (cs, w * 0.5f, h * 0.5f);
- const float cs2 = 2.0f * cs;
-
- startNewSubPath (x + cs, y);
-
- if (whichSide == 0)
- {
- const float halfArrowW = jmin (arrowWidth, w - cs2) * 0.5f;
- const float arrowX1 = x + cs + jmax (0.0f, (w - cs2) * arrowPos - halfArrowW);
- lineTo (arrowX1, y);
- lineTo (tipX, tipY);
- lineTo (arrowX1 + halfArrowW * 2.0f, y);
- }
-
- lineTo (x + w - cs, y);
-
- if (cs > 0.0f)
- addArc (x + w - cs2, y, cs2, cs2, 0, float_Pi * 0.5f);
-
- if (whichSide == 3)
- {
- const float halfArrowH = jmin (arrowWidth, h - cs2) * 0.5f;
- const float arrowY1 = y + cs + jmax (0.0f, (h - cs2) * arrowPos - halfArrowH);
- lineTo (x + w, arrowY1);
- lineTo (tipX, tipY);
- lineTo (x + w, arrowY1 + halfArrowH * 2.0f);
- }
-
- lineTo (x + w, y + h - cs);
-
- if (cs > 0.0f)
- addArc (x + w - cs2, y + h - cs2, cs2, cs2, float_Pi * 0.5f, float_Pi);
-
- if (whichSide == 2)
- {
- const float halfArrowW = jmin (arrowWidth, w - cs2) * 0.5f;
- const float arrowX1 = x + cs + jmax (0.0f, (w - cs2) * arrowPos - halfArrowW);
- lineTo (arrowX1 + halfArrowW * 2.0f, y + h);
- lineTo (tipX, tipY);
- lineTo (arrowX1, y + h);
- }
-
- lineTo (x + cs, y + h);
-
- if (cs > 0.0f)
- addArc (x, y + h - cs2, cs2, cs2, float_Pi, float_Pi * 1.5f);
-
- if (whichSide == 1)
- {
- const float halfArrowH = jmin (arrowWidth, h - cs2) * 0.5f;
- const float arrowY1 = y + cs + jmax (0.0f, (h - cs2) * arrowPos - halfArrowH);
- lineTo (x, arrowY1 + halfArrowH * 2.0f);
- lineTo (tipX, tipY);
- lineTo (x, arrowY1);
- }
-
- lineTo (x, y + cs);
-
- if (cs > 0.0f)
- addArc (x, y, cs2, cs2, float_Pi * 1.5f, float_Pi * 2.0f - ellipseAngularIncrement);
-
- closeSubPath();
- }
- }
-
- void Path::addPath (const Path& other) throw()
- {
- int i = 0;
-
- while (i < other.numElements)
- {
- const float type = other.elements [i++];
-
- if (type == moveMarker)
- {
- startNewSubPath (other.elements [i],
- other.elements [i + 1]);
-
- i += 2;
- }
- else if (type == lineMarker)
- {
- lineTo (other.elements [i],
- other.elements [i + 1]);
-
- i += 2;
- }
- else if (type == quadMarker)
- {
- quadraticTo (other.elements [i],
- other.elements [i + 1],
- other.elements [i + 2],
- other.elements [i + 3]);
- i += 4;
- }
- else if (type == cubicMarker)
- {
- cubicTo (other.elements [i],
- other.elements [i + 1],
- other.elements [i + 2],
- other.elements [i + 3],
- other.elements [i + 4],
- other.elements [i + 5]);
-
- i += 6;
- }
- else if (type == closeSubPathMarker)
- {
- closeSubPath();
- }
- else
- {
- // something's gone wrong with the element list!
- jassertfalse
- }
- }
- }
-
- void Path::addPath (const Path& other,
- const AffineTransform& transformToApply) throw()
- {
- int i = 0;
-
- while (i < other.numElements)
- {
- const float type = other.elements [i++];
-
- if (type == closeSubPathMarker)
- {
- closeSubPath();
- }
- else
- {
- float x = other.elements [i++];
- float y = other.elements [i++];
- transformToApply.transformPoint (x, y);
-
- if (type == moveMarker)
- {
- startNewSubPath (x, y);
- }
- else if (type == lineMarker)
- {
- lineTo (x, y);
- }
- else if (type == quadMarker)
- {
- float x2 = other.elements [i++];
- float y2 = other.elements [i++];
- transformToApply.transformPoint (x2, y2);
-
- quadraticTo (x, y, x2, y2);
- }
- else if (type == cubicMarker)
- {
- float x2 = other.elements [i++];
- float y2 = other.elements [i++];
- float x3 = other.elements [i++];
- float y3 = other.elements [i++];
- transformToApply.transformPoint (x2, y2);
- transformToApply.transformPoint (x3, y3);
-
- cubicTo (x, y, x2, y2, x3, y3);
- }
- else
- {
- // something's gone wrong with the element list!
- jassertfalse
- }
- }
- }
- }
-
- void Path::applyTransform (const AffineTransform& transform) throw()
- {
- int i = 0;
- pathYMin = pathXMin = 0;
- pathYMax = pathXMax = 0;
- bool setMaxMin = false;
-
- while (i < numElements)
- {
- const float type = elements [i++];
-
- if (type == moveMarker)
- {
- transform.transformPoint (elements [i],
- elements [i + 1]);
-
- if (setMaxMin)
- {
- pathXMin = jmin (pathXMin, elements [i]);
- pathXMax = jmax (pathXMax, elements [i]);
- pathYMin = jmin (pathYMin, elements [i + 1]);
- pathYMax = jmax (pathYMax, elements [i + 1]);
- }
- else
- {
- pathXMin = pathXMax = elements [i];
- pathYMin = pathYMax = elements [i + 1];
- setMaxMin = true;
- }
-
- i += 2;
- }
- else if (type == lineMarker)
- {
- transform.transformPoint (elements [i],
- elements [i + 1]);
-
- pathXMin = jmin (pathXMin, elements [i]);
- pathXMax = jmax (pathXMax, elements [i]);
- pathYMin = jmin (pathYMin, elements [i + 1]);
- pathYMax = jmax (pathYMax, elements [i + 1]);
-
- i += 2;
- }
- else if (type == quadMarker)
- {
- transform.transformPoint (elements [i],
- elements [i + 1]);
-
- transform.transformPoint (elements [i + 2],
- elements [i + 3]);
-
- pathXMin = jmin (pathXMin, elements [i], elements [i + 2]);
- pathXMax = jmax (pathXMax, elements [i], elements [i + 2]);
- pathYMin = jmin (pathYMin, elements [i + 1], elements [i + 3]);
- pathYMax = jmax (pathYMax, elements [i + 1], elements [i + 3]);
-
- i += 4;
- }
- else if (type == cubicMarker)
- {
- transform.transformPoint (elements [i],
- elements [i + 1]);
-
- transform.transformPoint (elements [i + 2],
- elements [i + 3]);
-
- transform.transformPoint (elements [i + 4],
- elements [i + 5]);
-
- pathXMin = jmin (pathXMin, elements [i], elements [i + 2], elements [i + 4]);
- pathXMax = jmax (pathXMax, elements [i], elements [i + 2], elements [i + 4]);
- pathYMin = jmin (pathYMin, elements [i + 1], elements [i + 3], elements [i + 5]);
- pathYMax = jmax (pathYMax, elements [i + 1], elements [i + 3], elements [i + 5]);
-
- i += 6;
- }
- }
- }
-
- const AffineTransform Path::getTransformToScaleToFit (const float x, const float y,
- const float w, const float h,
- const bool preserveProportions,
- const Justification& justification) const throw()
- {
- float sx, sy, sw, sh;
- getBounds (sx, sy, sw, sh);
-
- if (preserveProportions)
- {
- if (w <= 0 || h <= 0 || sw <= 0 || sh <= 0)
- return AffineTransform::identity;
-
- float newW, newH;
- const float srcRatio = sh / sw;
-
- if (srcRatio > h / w)
- {
- newW = h / srcRatio;
- newH = h;
- }
- else
- {
- newW = w;
- newH = w * srcRatio;
- }
-
- float newXCentre = x;
- float newYCentre = y;
-
- if (justification.testFlags (Justification::left))
- newXCentre += newW * 0.5f;
- else if (justification.testFlags (Justification::right))
- newXCentre += w - newW * 0.5f;
- else
- newXCentre += w * 0.5f;
-
- if (justification.testFlags (Justification::top))
- newYCentre += newH * 0.5f;
- else if (justification.testFlags (Justification::bottom))
- newYCentre += h - newH * 0.5f;
- else
- newYCentre += h * 0.5f;
-
- return AffineTransform::translation (sw * -0.5f - sx, sh * -0.5f - sy)
- .scaled (newW / sw, newH / sh)
- .translated (newXCentre, newYCentre);
- }
- else
- {
- return AffineTransform::translation (-sx, -sy)
- .scaled (w / sw, h / sh)
- .translated (x, y);
- }
- }
-
- static const float collisionDetectionTolerence = 20.0f;
-
- bool Path::contains (const float x, const float y) const throw()
- {
- if (x <= pathXMin || x >= pathXMax
- || y <= pathYMin || y >= pathYMax)
- return false;
-
- PathFlatteningIterator i (*this, AffineTransform::identity, collisionDetectionTolerence);
-
- int positiveCrossings = 0;
- int negativeCrossings = 0;
-
- while (i.next())
- {
- if ((i.y1 <= y && i.y2 > y)
- || (i.y2 <= y && i.y1 > y))
- {
- const float intersectX = i.x1 + (i.x2 - i.x1) * (y - i.y1) / (i.y2 - i.y1);
-
- if (intersectX <= x)
- {
- if (i.y1 < i.y2)
- ++positiveCrossings;
- else
- ++negativeCrossings;
- }
- }
- }
-
- return (useNonZeroWinding) ? (negativeCrossings != positiveCrossings)
- : ((negativeCrossings + positiveCrossings) & 1) != 0;
- }
-
- bool Path::intersectsLine (const float x1, const float y1,
- const float x2, const float y2) throw()
- {
- PathFlatteningIterator i (*this, AffineTransform::identity, collisionDetectionTolerence);
-
- const Line line1 (x1, y1, x2, y2);
-
- while (i.next())
- {
- const Line line2 (i.x1, i.y1, i.x2, i.y2);
-
- float ix, iy;
- if (line1.intersects (line2, ix, iy))
- return true;
- }
-
- return false;
- }
-
- const Path Path::createPathWithRoundedCorners (const float cornerRadius) const throw()
- {
- if (cornerRadius <= 0.01f)
- return *this;
-
- int indexOfPathStart = 0, indexOfPathStartThis = 0;
- int n = 0;
- bool lastWasLine = false, firstWasLine = false;
- Path p;
-
- while (n < numElements)
- {
- const float type = elements [n++];
-
- if (type == moveMarker)
- {
- indexOfPathStart = p.numElements;
- indexOfPathStartThis = n - 1;
- const float x = elements [n++];
- const float y = elements [n++];
- p.startNewSubPath (x, y);
- lastWasLine = false;
- firstWasLine = (elements [n] == lineMarker);
- }
- else if (type == lineMarker || type == closeSubPathMarker)
- {
- float startX = 0, startY = 0, joinX = 0, joinY = 0, endX, endY;
-
- if (type == lineMarker)
- {
- endX = elements [n++];
- endY = elements [n++];
-
- if (n > 8)
- {
- startX = elements [n - 8];
- startY = elements [n - 7];
- joinX = elements [n - 5];
- joinY = elements [n - 4];
- }
- }
- else
- {
- endX = elements [indexOfPathStartThis + 1];
- endY = elements [indexOfPathStartThis + 2];
-
- if (n > 6)
- {
- startX = elements [n - 6];
- startY = elements [n - 5];
- joinX = elements [n - 3];
- joinY = elements [n - 2];
- }
- }
-
- if (lastWasLine)
- {
- const double len1 = juce_hypot (startX - joinX,
- startY - joinY);
-
- if (len1 > 0)
- {
- const double propNeeded = jmin (0.5, cornerRadius / len1);
-
- p.elements [p.numElements - 2] = (float) (joinX - (joinX - startX) * propNeeded);
- p.elements [p.numElements - 1] = (float) (joinY - (joinY - startY) * propNeeded);
- }
-
- const double len2 = juce_hypot (endX - joinX,
- endY - joinY);
-
- if (len2 > 0)
- {
- const double propNeeded = jmin (0.5, cornerRadius / len2);
-
- p.quadraticTo (joinX, joinY,
- (float) (joinX + (endX - joinX) * propNeeded),
- (float) (joinY + (endY - joinY) * propNeeded));
- }
-
- p.lineTo (endX, endY);
- }
- else if (type == lineMarker)
- {
- p.lineTo (endX, endY);
- lastWasLine = true;
- }
-
- if (type == closeSubPathMarker)
- {
- if (firstWasLine)
- {
- startX = elements [n - 3];
- startY = elements [n - 2];
- joinX = endX;
- joinY = endY;
- endX = elements [indexOfPathStartThis + 4];
- endY = elements [indexOfPathStartThis + 5];
-
- const double len1 = juce_hypot (startX - joinX,
- startY - joinY);
-
- if (len1 > 0)
- {
- const double propNeeded = jmin (0.5, cornerRadius / len1);
-
- p.elements [p.numElements - 2] = (float) (joinX - (joinX - startX) * propNeeded);
- p.elements [p.numElements - 1] = (float) (joinY - (joinY - startY) * propNeeded);
- }
-
- const double len2 = juce_hypot (endX - joinX,
- endY - joinY);
-
- if (len2 > 0)
- {
- const double propNeeded = jmin (0.5, cornerRadius / len2);
-
- endX = (float) (joinX + (endX - joinX) * propNeeded);
- endY = (float) (joinY + (endY - joinY) * propNeeded);
-
- p.quadraticTo (joinX, joinY, endX, endY);
-
- p.elements [indexOfPathStart + 1] = endX;
- p.elements [indexOfPathStart + 2] = endY;
- }
- }
-
- p.closeSubPath();
- }
- }
- else if (type == quadMarker)
- {
- lastWasLine = false;
- const float x1 = elements [n++];
- const float y1 = elements [n++];
- const float x2 = elements [n++];
- const float y2 = elements [n++];
- p.quadraticTo (x1, y1, x2, y2);
- }
- else if (type == cubicMarker)
- {
- lastWasLine = false;
- const float x1 = elements [n++];
- const float y1 = elements [n++];
- const float x2 = elements [n++];
- const float y2 = elements [n++];
- const float x3 = elements [n++];
- const float y3 = elements [n++];
- p.cubicTo (x1, y1, x2, y2, x3, y3);
- }
- }
-
- return p;
- }
-
- void Path::loadPathFromStream (InputStream& source)
- {
- while (! source.isExhausted())
- {
- switch (source.readByte())
- {
- case 'm':
- {
- const float x = source.readFloat();
- const float y = source.readFloat();
- startNewSubPath (x, y);
- break;
- }
-
- case 'l':
- {
- const float x = source.readFloat();
- const float y = source.readFloat();
- lineTo (x, y);
- break;
- }
-
- case 'q':
- {
- const float x1 = source.readFloat();
- const float y1 = source.readFloat();
- const float x2 = source.readFloat();
- const float y2 = source.readFloat();
- quadraticTo (x1, y1, x2, y2);
- break;
- }
-
- case 'b':
- {
- const float x1 = source.readFloat();
- const float y1 = source.readFloat();
- const float x2 = source.readFloat();
- const float y2 = source.readFloat();
- const float x3 = source.readFloat();
- const float y3 = source.readFloat();
- cubicTo (x1, y1, x2, y2, x3, y3);
- break;
- }
-
- case 'c':
- closeSubPath();
- break;
-
- case 'n':
- useNonZeroWinding = true;
- break;
-
- case 'z':
- useNonZeroWinding = false;
- break;
-
- case 'e':
- return; // end of path marker
-
- default:
- jassertfalse // illegal char in the stream
- break;
- }
- }
- }
-
- void Path::loadPathFromData (const unsigned char* const data,
- const int numberOfBytes) throw()
- {
- MemoryInputStream in ((const char*) data, numberOfBytes, false);
- loadPathFromStream (in);
- }
-
- void Path::writePathToStream (OutputStream& dest) const
- {
- dest.writeByte ((useNonZeroWinding) ? 'n' : 'z');
-
- int i = 0;
- while (i < numElements)
- {
- const float type = elements [i++];
-
- if (type == moveMarker)
- {
- dest.writeByte ('m');
- dest.writeFloat (elements [i++]);
- dest.writeFloat (elements [i++]);
- }
- else if (type == lineMarker)
- {
- dest.writeByte ('l');
- dest.writeFloat (elements [i++]);
- dest.writeFloat (elements [i++]);
- }
- else if (type == quadMarker)
- {
- dest.writeByte ('q');
- dest.writeFloat (elements [i++]);
- dest.writeFloat (elements [i++]);
- dest.writeFloat (elements [i++]);
- dest.writeFloat (elements [i++]);
- }
- else if (type == cubicMarker)
- {
- dest.writeByte ('b');
- dest.writeFloat (elements [i++]);
- dest.writeFloat (elements [i++]);
- dest.writeFloat (elements [i++]);
- dest.writeFloat (elements [i++]);
- dest.writeFloat (elements [i++]);
- dest.writeFloat (elements [i++]);
- }
- else if (type == closeSubPathMarker)
- {
- dest.writeByte ('c');
- }
- }
-
- dest.writeByte ('e'); // marks the end-of-path
- }
-
- const String Path::toString() const
- {
- String s;
- s.preallocateStorage (numElements * 4);
- if (! useNonZeroWinding)
- s << T("a ");
-
- int i = 0;
- float lastMarker = 0.0f;
-
- while (i < numElements)
- {
- const float marker = elements [i++];
- tchar markerChar = 0;
- int numCoords = 0;
-
- if (marker == moveMarker)
- {
- markerChar = T('m');
- numCoords = 2;
- }
- else if (marker == lineMarker)
- {
- markerChar = T('l');
- numCoords = 2;
- }
- else if (marker == quadMarker)
- {
- markerChar = T('q');
- numCoords = 4;
- }
- else if (marker == cubicMarker)
- {
- markerChar = T('c');
- numCoords = 6;
- }
- else
- {
- jassert (marker == closeSubPathMarker);
- markerChar = T('z');
- }
-
- if (marker != lastMarker)
- {
- s << markerChar << T(' ');
- lastMarker = marker;
- }
-
- while (--numCoords >= 0 && i < numElements)
- {
- String n (elements [i++], 3);
-
- while (n.endsWithChar (T('0')))
- n = n.dropLastCharacters (1);
-
- if (n.endsWithChar (T('.')))
- n = n.dropLastCharacters (1);
-
- s << n << T(' ');
- }
- }
-
- return s.trimEnd();
- }
-
- static const String nextToken (const tchar*& t)
- {
- while (*t == T(' '))
- ++t;
-
- const tchar* const start = t;
-
- while (*t != 0 && *t != T(' '))
- ++t;
-
- const int length = (int) (t - start);
-
- while (*t == T(' '))
- ++t;
-
- return String (start, length);
- }
-
- void Path::restoreFromString (const String& stringVersion)
- {
- clear();
- setUsingNonZeroWinding (true);
-
- const tchar* t = stringVersion;
- tchar marker = T('m');
- int numValues = 2;
- float values [6];
-
- while (*t != 0)
- {
- const String token (nextToken (t));
- const tchar firstChar = token[0];
- int startNum = 0;
-
- if (firstChar == T('m') || firstChar == T('l'))
- {
- marker = firstChar;
- numValues = 2;
- }
- else if (firstChar == T('q'))
- {
- marker = firstChar;
- numValues = 4;
- }
- else if (firstChar == T('c'))
- {
- marker = firstChar;
- numValues = 6;
- }
- else if (firstChar == T('z'))
- {
- marker = firstChar;
- numValues = 0;
- }
- else if (firstChar == T('a'))
- {
- setUsingNonZeroWinding (false);
- continue;
- }
- else
- {
- ++startNum;
- values [0] = token.getFloatValue();
- }
-
- for (int i = startNum; i < numValues; ++i)
- values [i] = nextToken (t).getFloatValue();
-
- switch (marker)
- {
- case T('m'):
- startNewSubPath (values[0], values[1]);
- break;
-
- case T('l'):
- lineTo (values[0], values[1]);
- break;
-
- case T('q'):
- quadraticTo (values[0], values[1],
- values[2], values[3]);
- break;
-
- case T('c'):
- cubicTo (values[0], values[1],
- values[2], values[3],
- values[4], values[5]);
- break;
-
- case T('z'):
- closeSubPath();
- break;
-
- default:
- jassertfalse // illegal string format?
- break;
- }
- }
- }
-
- Path::Iterator::Iterator (const Path& path_)
- : path (path_),
- index (0)
- {
- }
-
- Path::Iterator::~Iterator()
- {
- }
-
- bool Path::Iterator::next()
- {
- const float* const elements = path.elements;
-
- if (index < path.numElements)
- {
- const float type = elements [index++];
-
- if (type == moveMarker)
- {
- elementType = startNewSubPath;
- x1 = elements [index++];
- y1 = elements [index++];
- }
- else if (type == lineMarker)
- {
- elementType = lineTo;
- x1 = elements [index++];
- y1 = elements [index++];
- }
- else if (type == quadMarker)
- {
- elementType = quadraticTo;
- x1 = elements [index++];
- y1 = elements [index++];
- x2 = elements [index++];
- y2 = elements [index++];
- }
- else if (type == cubicMarker)
- {
- elementType = cubicTo;
- x1 = elements [index++];
- y1 = elements [index++];
- x2 = elements [index++];
- y2 = elements [index++];
- x3 = elements [index++];
- y3 = elements [index++];
- }
- else if (type == closeSubPathMarker)
- {
- elementType = closePath;
- }
-
- return true;
- }
-
- return false;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_Path.cpp *********/
-
- /********* Start of inlined file: juce_PathIterator.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- #if JUCE_MSVC
- #pragma optimize ("t", on)
- #endif
-
- PathFlatteningIterator::PathFlatteningIterator (const Path& path_,
- const AffineTransform& transform_,
- float tolerence_) throw()
- : x2 (0),
- y2 (0),
- closesSubPath (false),
- subPathIndex (-1),
- path (path_),
- transform (transform_),
- points (path_.elements),
- tolerence (tolerence_ * tolerence_),
- subPathCloseX (0),
- subPathCloseY (0),
- index (0),
- stackSize (32)
- {
- stackBase = (float*) juce_malloc (stackSize * sizeof (float));
- isIdentityTransform = transform.isIdentity();
- stackPos = stackBase;
- }
-
- PathFlatteningIterator::~PathFlatteningIterator() throw()
- {
- juce_free (stackBase);
- }
-
- bool PathFlatteningIterator::next() throw()
- {
- x1 = x2;
- y1 = y2;
-
- float x3 = 0;
- float y3 = 0;
- float x4 = 0;
- float y4 = 0;
- float type;
-
- for (;;)
- {
- if (stackPos == stackBase)
- {
- if (index >= path.numElements)
- {
- return false;
- }
- else
- {
- type = points [index++];
-
- if (type != Path::closeSubPathMarker)
- {
- x2 = points [index++];
- y2 = points [index++];
-
- if (! isIdentityTransform)
- transform.transformPoint (x2, y2);
-
- if (type == Path::quadMarker)
- {
- x3 = points [index++];
- y3 = points [index++];
-
- if (! isIdentityTransform)
- transform.transformPoint (x3, y3);
- }
- else if (type == Path::cubicMarker)
- {
- x3 = points [index++];
- y3 = points [index++];
- x4 = points [index++];
- y4 = points [index++];
-
- if (! isIdentityTransform)
- {
- transform.transformPoint (x3, y3);
- transform.transformPoint (x4, y4);
- }
- }
- }
- }
- }
- else
- {
- type = *--stackPos;
-
- if (type != Path::closeSubPathMarker)
- {
- x2 = *--stackPos;
- y2 = *--stackPos;
-
- if (type == Path::quadMarker)
- {
- x3 = *--stackPos;
- y3 = *--stackPos;
- }
- else if (type == Path::cubicMarker)
- {
- x3 = *--stackPos;
- y3 = *--stackPos;
- x4 = *--stackPos;
- y4 = *--stackPos;
- }
- }
- }
-
- if (type == Path::lineMarker)
- {
- ++subPathIndex;
-
- closesSubPath = (stackPos == stackBase)
- && (index < path.numElements)
- && (points [index] == Path::closeSubPathMarker)
- && x2 == subPathCloseX
- && y2 == subPathCloseY;
-
- return true;
- }
- else if (type == Path::quadMarker)
- {
- const int offset = (int) (stackPos - stackBase);
-
- if (offset >= stackSize - 10)
- {
- stackSize <<= 1;
- stackBase = (float*) juce_realloc (stackBase, stackSize * sizeof (float));
- stackPos = stackBase + offset;
- }
-
- const float dx1 = x1 - x2;
- const float dy1 = y1 - y2;
- const float dx2 = x2 - x3;
- const float dy2 = y2 - y3;
-
- const float m1x = (x1 + x2) * 0.5f;
- const float m1y = (y1 + y2) * 0.5f;
- const float m2x = (x2 + x3) * 0.5f;
- const float m2y = (y2 + y3) * 0.5f;
- const float m3x = (m1x + m2x) * 0.5f;
- const float m3y = (m1y + m2y) * 0.5f;
-
- if (dx1*dx1 + dy1*dy1 + dx2*dx2 + dy2*dy2 > tolerence)
- {
- *stackPos++ = y3;
- *stackPos++ = x3;
- *stackPos++ = m2y;
- *stackPos++ = m2x;
- *stackPos++ = Path::quadMarker;
-
- *stackPos++ = m3y;
- *stackPos++ = m3x;
- *stackPos++ = m1y;
- *stackPos++ = m1x;
- *stackPos++ = Path::quadMarker;
- }
- else
- {
- *stackPos++ = y3;
- *stackPos++ = x3;
- *stackPos++ = Path::lineMarker;
-
- *stackPos++ = m3y;
- *stackPos++ = m3x;
- *stackPos++ = Path::lineMarker;
- }
-
- jassert (stackPos < stackBase + stackSize);
- }
- else if (type == Path::cubicMarker)
- {
- const int offset = (int) (stackPos - stackBase);
-
- if (offset >= stackSize - 16)
- {
- stackSize <<= 1;
- stackBase = (float*) juce_realloc (stackBase, stackSize * sizeof (float));
- stackPos = stackBase + offset;
- }
-
- const float dx1 = x1 - x2;
- const float dy1 = y1 - y2;
- const float dx2 = x2 - x3;
- const float dy2 = y2 - y3;
- const float dx3 = x3 - x4;
- const float dy3 = y3 - y4;
-
- const float m1x = (x1 + x2) * 0.5f;
- const float m1y = (y1 + y2) * 0.5f;
- const float m2x = (x3 + x2) * 0.5f;
- const float m2y = (y3 + y2) * 0.5f;
- const float m3x = (x3 + x4) * 0.5f;
- const float m3y = (y3 + y4) * 0.5f;
- const float m4x = (m1x + m2x) * 0.5f;
- const float m4y = (m1y + m2y) * 0.5f;
- const float m5x = (m3x + m2x) * 0.5f;
- const float m5y = (m3y + m2y) * 0.5f;
-
- if (dx1*dx1 + dy1*dy1 + dx2*dx2
- + dy2*dy2 + dx3*dx3 + dy3*dy3 > tolerence)
- {
- *stackPos++ = y4;
- *stackPos++ = x4;
- *stackPos++ = m3y;
- *stackPos++ = m3x;
- *stackPos++ = m5y;
- *stackPos++ = m5x;
- *stackPos++ = Path::cubicMarker;
-
- *stackPos++ = (m4y + m5y) * 0.5f;
- *stackPos++ = (m4x + m5x) * 0.5f;
- *stackPos++ = m4y;
- *stackPos++ = m4x;
- *stackPos++ = m1y;
- *stackPos++ = m1x;
- *stackPos++ = Path::cubicMarker;
- }
- else
- {
- *stackPos++ = y4;
- *stackPos++ = x4;
- *stackPos++ = Path::lineMarker;
-
- *stackPos++ = m5y;
- *stackPos++ = m5x;
- *stackPos++ = Path::lineMarker;
-
- *stackPos++ = m4y;
- *stackPos++ = m4x;
- *stackPos++ = Path::lineMarker;
- }
- }
- else if (type == Path::closeSubPathMarker)
- {
- if (x2 != subPathCloseX || y2 != subPathCloseY)
- {
- x1 = x2;
- y1 = y2;
- x2 = subPathCloseX;
- y2 = subPathCloseY;
- closesSubPath = true;
-
- return true;
- }
- }
- else
- {
- subPathIndex = -1;
- subPathCloseX = x1 = x2;
- subPathCloseY = y1 = y2;
- }
- }
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_PathIterator.cpp *********/
-
- /********* Start of inlined file: juce_PathStrokeType.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- PathStrokeType::PathStrokeType (const float strokeThickness,
- const JointStyle jointStyle_,
- const EndCapStyle endStyle_) throw()
- : thickness (strokeThickness),
- jointStyle (jointStyle_),
- endStyle (endStyle_)
- {
- }
-
- PathStrokeType::PathStrokeType (const PathStrokeType& other) throw()
- : thickness (other.thickness),
- jointStyle (other.jointStyle),
- endStyle (other.endStyle)
- {
- }
-
- const PathStrokeType& PathStrokeType::operator= (const PathStrokeType& other) throw()
- {
- thickness = other.thickness;
- jointStyle = other.jointStyle;
- endStyle = other.endStyle;
- return *this;
- }
-
- PathStrokeType::~PathStrokeType() throw()
- {
- }
-
- bool PathStrokeType::operator== (const PathStrokeType& other) const throw()
- {
- return thickness == other.thickness
- && jointStyle == other.jointStyle
- && endStyle == other.endStyle;
- }
-
- bool PathStrokeType::operator!= (const PathStrokeType& other) const throw()
- {
- return ! operator== (other);
- }
-
- static bool lineIntersection (const float x1, const float y1,
- const float x2, const float y2,
- const float x3, const float y3,
- const float x4, const float y4,
- float& intersectionX,
- float& intersectionY,
- float& distanceBeyondLine1EndSquared) throw()
- {
- if (x2 != x3 || y2 != y3)
- {
- const float dx1 = x2 - x1;
- const float dy1 = y2 - y1;
- const float dx2 = x4 - x3;
- const float dy2 = y4 - y3;
- const float divisor = dx1 * dy2 - dx2 * dy1;
-
- if (divisor == 0)
- {
- if (! ((dx1 == 0 && dy1 == 0) || (dx2 == 0 && dy2 == 0)))
- {
- if (dy1 == 0 && dy2 != 0)
- {
- const float along = (y1 - y3) / dy2;
- intersectionX = x3 + along * dx2;
- intersectionY = y1;
-
- distanceBeyondLine1EndSquared = intersectionX - x2;
- distanceBeyondLine1EndSquared *= distanceBeyondLine1EndSquared;
- if ((x2 > x1) == (intersectionX < x2))
- distanceBeyondLine1EndSquared = -distanceBeyondLine1EndSquared;
-
- return along >= 0 && along <= 1.0f;
- }
- else if (dy2 == 0 && dy1 != 0)
- {
- const float along = (y3 - y1) / dy1;
- intersectionX = x1 + along * dx1;
- intersectionY = y3;
-
- distanceBeyondLine1EndSquared = (along - 1.0f) * dx1;
- distanceBeyondLine1EndSquared *= distanceBeyondLine1EndSquared;
- if (along < 1.0f)
- distanceBeyondLine1EndSquared = -distanceBeyondLine1EndSquared;
-
- return along >= 0 && along <= 1.0f;
- }
- else if (dx1 == 0 && dx2 != 0)
- {
- const float along = (x1 - x3) / dx2;
- intersectionX = x1;
- intersectionY = y3 + along * dy2;
-
- distanceBeyondLine1EndSquared = intersectionY - y2;
- distanceBeyondLine1EndSquared *= distanceBeyondLine1EndSquared;
-
- if ((y2 > y1) == (intersectionY < y2))
- distanceBeyondLine1EndSquared = -distanceBeyondLine1EndSquared;
-
- return along >= 0 && along <= 1.0f;
- }
- else if (dx2 == 0 && dx1 != 0)
- {
- const float along = (x3 - x1) / dx1;
- intersectionX = x3;
- intersectionY = y1 + along * dy1;
-
- distanceBeyondLine1EndSquared = (along - 1.0f) * dy1;
- distanceBeyondLine1EndSquared *= distanceBeyondLine1EndSquared;
- if (along < 1.0f)
- distanceBeyondLine1EndSquared = -distanceBeyondLine1EndSquared;
-
- return along >= 0 && along <= 1.0f;
- }
- }
-
- intersectionX = 0.5f * (x2 + x3);
- intersectionY = 0.5f * (y2 + y3);
-
- distanceBeyondLine1EndSquared = 0.0f;
- return false;
- }
- else
- {
- const float along1 = ((y1 - y3) * dx2 - (x1 - x3) * dy2) / divisor;
-
- intersectionX = x1 + along1 * dx1;
- intersectionY = y1 + along1 * dy1;
-
- if (along1 >= 0 && along1 <= 1.0f)
- {
- const float along2 = ((y1 - y3) * dx1 - (x1 - x3) * dy1);
-
- if (along2 >= 0 && along2 <= divisor)
- {
- distanceBeyondLine1EndSquared = 0.0f;
- return true;
- }
- }
-
- distanceBeyondLine1EndSquared = along1 - 1.0f;
- distanceBeyondLine1EndSquared *= distanceBeyondLine1EndSquared;
- distanceBeyondLine1EndSquared *= (dx1 * dx1 + dy1 * dy1);
-
- if (along1 < 1.0f)
- distanceBeyondLine1EndSquared = -distanceBeyondLine1EndSquared;
-
- return false;
- }
- }
-
- intersectionX = x2;
- intersectionY = y2;
-
- distanceBeyondLine1EndSquared = 0.0f;
- return true;
- }
-
- // part of stroke drawing stuff
- static void addEdgeAndJoint (Path& destPath,
- const PathStrokeType::JointStyle style,
- const float maxMiterExtensionSquared, const float width,
- const float x1, const float y1,
- const float x2, const float y2,
- const float x3, const float y3,
- const float x4, const float y4,
- const float midX, const float midY) throw()
- {
- if (style == PathStrokeType::beveled
- || (x3 == x4 && y3 == y4)
- || (x1 == x2 && y1 == y2))
- {
- destPath.lineTo (x2, y2);
- destPath.lineTo (x3, y3);
- }
- else
- {
- float jx, jy, distanceBeyondLine1EndSquared;
-
- // if they intersect, use this point..
- if (lineIntersection (x1, y1, x2, y2,
- x3, y3, x4, y4,
- jx, jy, distanceBeyondLine1EndSquared))
- {
- destPath.lineTo (jx, jy);
- }
- else
- {
- if (style == PathStrokeType::mitered)
- {
- if (distanceBeyondLine1EndSquared < maxMiterExtensionSquared
- && distanceBeyondLine1EndSquared > 0.0f)
- {
- destPath.lineTo (jx, jy);
- }
- else
- {
- // the end sticks out too far, so just use a blunt joint
- destPath.lineTo (x2, y2);
- destPath.lineTo (x3, y3);
- }
- }
- else
- {
- // curved joints
- float angle = atan2f (x2 - midX, y2 - midY);
- float angle2 = atan2f (x3 - midX, y3 - midY);
-
- while (angle < angle2 - 0.01f)
- angle2 -= float_Pi * 2.0f;
-
- destPath.lineTo (x2, y2);
-
- while (angle > angle2)
- {
- destPath.lineTo (midX + width * sinf (angle),
- midY + width * cosf (angle));
-
- angle -= 0.1f;
- }
-
- destPath.lineTo (x3, y3);
- }
- }
- }
- }
-
- static inline void addLineEnd (Path& destPath,
- const PathStrokeType::EndCapStyle style,
- const float x1, const float y1,
- const float x2, const float y2,
- const float width) throw()
- {
- if (style == PathStrokeType::butt)
- {
- destPath.lineTo (x2, y2);
- }
- else
- {
- float offx1, offy1, offx2, offy2;
-
- float dx = x2 - x1;
- float dy = y2 - y1;
- const float len = juce_hypotf (dx, dy);
-
- if (len == 0)
- {
- offx1 = offx2 = x1;
- offy1 = offy2 = y1;
- }
- else
- {
- const float offset = width / len;
- dx *= offset;
- dy *= offset;
-
- offx1 = x1 + dy;
- offy1 = y1 - dx;
- offx2 = x2 + dy;
- offy2 = y2 - dx;
- }
-
- if (style == PathStrokeType::square)
- {
- // sqaure ends
- destPath.lineTo (offx1, offy1);
- destPath.lineTo (offx2, offy2);
- destPath.lineTo (x2, y2);
- }
- else
- {
- // rounded ends
- const float midx = (offx1 + offx2) * 0.5f;
- const float midy = (offy1 + offy2) * 0.5f;
-
- destPath.cubicTo (x1 + (offx1 - x1) * 0.55f, y1 + (offy1 - y1) * 0.55f,
- offx1 + (midx - offx1) * 0.45f, offy1 + (midy - offy1) * 0.45f,
- midx, midy);
-
- destPath.cubicTo (midx + (offx2 - midx) * 0.55f, midy + (offy2 - midy) * 0.55f,
- offx2 + (x2 - offx2) * 0.45f, offy2 + (y2 - offy2) * 0.45f,
- x2, y2);
- }
- }
- }
-
- struct LineSection
- {
- LineSection() throw() {}
- LineSection (int) throw() {}
-
- float x1, y1, x2, y2; // original line
- float lx1, ly1, lx2, ly2; // the left-hand stroke
- float rx1, ry1, rx2, ry2; // the right-hand stroke
- };
-
- static void addSubPath (Path& destPath, const Array <LineSection>& subPath,
- const bool isClosed,
- const float width, const float maxMiterExtensionSquared,
- const PathStrokeType::JointStyle jointStyle, const PathStrokeType::EndCapStyle endStyle) throw()
- {
- jassert (subPath.size() > 0);
-
- const LineSection& firstLine = subPath.getReference (0);
-
- float lastX1 = firstLine.lx1;
- float lastY1 = firstLine.ly1;
- float lastX2 = firstLine.lx2;
- float lastY2 = firstLine.ly2;
-
- if (isClosed)
- {
- destPath.startNewSubPath (lastX1, lastY1);
- }
- else
- {
- destPath.startNewSubPath (firstLine.rx2, firstLine.ry2);
-
- addLineEnd (destPath, endStyle,
- firstLine.rx2, firstLine.ry2,
- lastX1, lastY1,
- width);
- }
-
- int i;
- for (i = 1; i < subPath.size(); ++i)
- {
- const LineSection& l = subPath.getReference (i);
-
- addEdgeAndJoint (destPath, jointStyle,
- maxMiterExtensionSquared, width,
- lastX1, lastY1, lastX2, lastY2,
- l.lx1, l.ly1, l.lx2, l.ly2,
- l.x1, l.y1);
-
- lastX1 = l.lx1;
- lastY1 = l.ly1;
- lastX2 = l.lx2;
- lastY2 = l.ly2;
- }
-
- const LineSection& lastLine = subPath.getReference (subPath.size() - 1);
-
- if (isClosed)
- {
- const LineSection& l = subPath.getReference (0);
-
- addEdgeAndJoint (destPath, jointStyle,
- maxMiterExtensionSquared, width,
- lastX1, lastY1, lastX2, lastY2,
- l.lx1, l.ly1, l.lx2, l.ly2,
- l.x1, l.y1);
-
- destPath.closeSubPath();
- destPath.startNewSubPath (lastLine.rx1, lastLine.ry1);
- }
- else
- {
- destPath.lineTo (lastX2, lastY2);
-
- addLineEnd (destPath, endStyle,
- lastX2, lastY2,
- lastLine.rx1, lastLine.ry1,
- width);
- }
-
- lastX1 = lastLine.rx1;
- lastY1 = lastLine.ry1;
- lastX2 = lastLine.rx2;
- lastY2 = lastLine.ry2;
-
- for (i = subPath.size() - 1; --i >= 0;)
- {
- const LineSection& l = subPath.getReference (i);
-
- addEdgeAndJoint (destPath, jointStyle,
- maxMiterExtensionSquared, width,
- lastX1, lastY1, lastX2, lastY2,
- l.rx1, l.ry1, l.rx2, l.ry2,
- l.x2, l.y2);
-
- lastX1 = l.rx1;
- lastY1 = l.ry1;
- lastX2 = l.rx2;
- lastY2 = l.ry2;
- }
-
- if (isClosed)
- {
- addEdgeAndJoint (destPath, jointStyle,
- maxMiterExtensionSquared, width,
- lastX1, lastY1, lastX2, lastY2,
- lastLine.rx1, lastLine.ry1, lastLine.rx2, lastLine.ry2,
- lastLine.x2, lastLine.y2);
- }
- else
- {
- // do the last line
- destPath.lineTo (lastX2, lastY2);
- }
-
- destPath.closeSubPath();
- }
-
- void PathStrokeType::createStrokedPath (Path& destPath,
- const Path& source,
- const AffineTransform& transform,
- const float extraAccuracy) const throw()
- {
- if (thickness <= 0)
- {
- destPath.clear();
- return;
- }
-
- const Path* sourcePath = &source;
- Path temp;
-
- if (sourcePath == &destPath)
- {
- destPath.swapWithPath (temp);
- sourcePath = &temp;
- }
- else
- {
- destPath.clear();
- }
-
- destPath.setUsingNonZeroWinding (true);
-
- const float maxMiterExtensionSquared = 9.0f * thickness * thickness;
- const float width = 0.5f * thickness;
-
- // Iterate the path, creating a list of the
- // left/right-hand lines along either side of it...
- PathFlatteningIterator it (*sourcePath, transform, 9.0f / extraAccuracy);
-
- Array <LineSection> subPath;
- LineSection l;
- l.x1 = 0;
- l.y1 = 0;
-
- const float minSegmentLength = 2.0f / (extraAccuracy * extraAccuracy);
-
- while (it.next())
- {
- if (it.subPathIndex == 0)
- {
- if (subPath.size() > 0)
- {
- addSubPath (destPath, subPath, false, width, maxMiterExtensionSquared, jointStyle, endStyle);
- subPath.clearQuick();
- }
-
- l.x1 = it.x1;
- l.y1 = it.y1;
- }
-
- l.x2 = it.x2;
- l.y2 = it.y2;
-
- float dx = l.x2 - l.x1;
- float dy = l.y2 - l.y1;
-
- const float hypotSquared = dx*dx + dy*dy;
-
- if (it.closesSubPath || hypotSquared > minSegmentLength || it.isLastInSubpath())
- {
- const float len = sqrtf (hypotSquared);
-
- if (len == 0)
- {
- l.rx1 = l.rx2 = l.lx1 = l.lx2 = l.x1;
- l.ry1 = l.ry2 = l.ly1 = l.ly2 = l.y1;
- }
- else
- {
- const float offset = width / len;
- dx *= offset;
- dy *= offset;
-
- l.rx2 = l.x1 - dy;
- l.ry2 = l.y1 + dx;
- l.lx1 = l.x1 + dy;
- l.ly1 = l.y1 - dx;
-
- l.lx2 = l.x2 + dy;
- l.ly2 = l.y2 - dx;
- l.rx1 = l.x2 - dy;
- l.ry1 = l.y2 + dx;
- }
-
- subPath.add (l);
-
- if (it.closesSubPath)
- {
- addSubPath (destPath, subPath, true, width, maxMiterExtensionSquared, jointStyle, endStyle);
- subPath.clearQuick();
- }
- else
- {
- l.x1 = it.x2;
- l.y1 = it.y2;
- }
- }
- }
-
- if (subPath.size() > 0)
- addSubPath (destPath, subPath, false, width, maxMiterExtensionSquared, jointStyle, endStyle);
- }
-
- void PathStrokeType::createDashedStroke (Path& destPath,
- const Path& sourcePath,
- const float* dashLengths,
- int numDashLengths,
- const AffineTransform& transform,
- const float extraAccuracy) const throw()
- {
- if (thickness <= 0)
- return;
-
- // this should really be an even number..
- jassert ((numDashLengths & 1) == 0);
-
- Path newDestPath;
- PathFlatteningIterator it (sourcePath, transform, 9.0f / extraAccuracy);
-
- bool first = true;
- int dashNum = 0;
- float pos = 0.0f, lineLen = 0.0f, lineEndPos = 0.0f;
- float dx = 0.0f, dy = 0.0f;
-
- for (;;)
- {
- const bool isSolid = ((dashNum & 1) == 0);
-
- const float dashLen = dashLengths [dashNum++ % numDashLengths];
- jassert (dashLen > 0); // must be a positive increment!
- if (dashLen <= 0)
- break;
-
- pos += dashLen;
-
- while (pos > lineEndPos)
- {
- if (! it.next())
- {
- if (isSolid && ! first)
- newDestPath.lineTo (it.x2, it.y2);
-
- createStrokedPath (destPath, newDestPath, AffineTransform::identity, extraAccuracy);
- return;
- }
-
- if (isSolid && ! first)
- {
- newDestPath.lineTo (it.x1, it.y1);
- }
- else
- {
- newDestPath.startNewSubPath (it.x1, it.y1);
- first = false;
- }
-
- dx = it.x2 - it.x1;
- dy = it.y2 - it.y1;
- lineLen = juce_hypotf (dx, dy);
- lineEndPos += lineLen;
- }
-
- const float alpha = (pos - (lineEndPos - lineLen)) / lineLen;
-
- if (isSolid)
- newDestPath.lineTo (it.x1 + dx * alpha,
- it.y1 + dy * alpha);
- else
- newDestPath.startNewSubPath (it.x1 + dx * alpha,
- it.y1 + dy * alpha);
- }
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_PathStrokeType.cpp *********/
-
- /********* Start of inlined file: juce_Point.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- Point::Point() throw()
- : x (0.0f),
- y (0.0f)
- {
- }
-
- Point::Point (const Point& other) throw()
- : x (other.x),
- y (other.y)
- {
- }
-
- const Point& Point::operator= (const Point& other) throw()
- {
- x = other.x;
- y = other.y;
-
- return *this;
- }
-
- Point::Point (const float x_,
- const float y_) throw()
- : x (x_),
- y (y_)
- {
- }
-
- Point::~Point() throw()
- {
- }
-
- void Point::setXY (const float x_,
- const float y_) throw()
- {
- x = x_;
- y = y_;
- }
-
- void Point::applyTransform (const AffineTransform& transform) throw()
- {
- transform.transformPoint (x, y);
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_Point.cpp *********/
-
- /********* Start of inlined file: juce_PositionedRectangle.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- PositionedRectangle::PositionedRectangle() throw()
- : x (0.0),
- y (0.0),
- w (0.0),
- h (0.0),
- xMode (anchorAtLeftOrTop | absoluteFromParentTopLeft),
- yMode (anchorAtLeftOrTop | absoluteFromParentTopLeft),
- wMode (absoluteSize),
- hMode (absoluteSize)
- {
- }
-
- PositionedRectangle::PositionedRectangle (const PositionedRectangle& other) throw()
- : x (other.x),
- y (other.y),
- w (other.w),
- h (other.h),
- xMode (other.xMode),
- yMode (other.yMode),
- wMode (other.wMode),
- hMode (other.hMode)
- {
- }
-
- const PositionedRectangle& PositionedRectangle::operator= (const PositionedRectangle& other) throw()
- {
- if (this != &other)
- {
- x = other.x;
- y = other.y;
- w = other.w;
- h = other.h;
- xMode = other.xMode;
- yMode = other.yMode;
- wMode = other.wMode;
- hMode = other.hMode;
- }
-
- return *this;
- }
-
- PositionedRectangle::~PositionedRectangle() throw()
- {
- }
-
- const bool PositionedRectangle::operator== (const PositionedRectangle& other) const throw()
- {
- return x == other.x
- && y == other.y
- && w == other.w
- && h == other.h
- && xMode == other.xMode
- && yMode == other.yMode
- && wMode == other.wMode
- && hMode == other.hMode;
- }
-
- const bool PositionedRectangle::operator!= (const PositionedRectangle& other) const throw()
- {
- return ! operator== (other);
- }
-
- PositionedRectangle::PositionedRectangle (const String& stringVersion) throw()
- {
- StringArray tokens;
- tokens.addTokens (stringVersion, false);
-
- decodePosString (tokens [0], xMode, x);
- decodePosString (tokens [1], yMode, y);
- decodeSizeString (tokens [2], wMode, w);
- decodeSizeString (tokens [3], hMode, h);
- }
-
- const String PositionedRectangle::toString() const throw()
- {
- String s;
- s.preallocateStorage (12);
-
- addPosDescription (s, xMode, x);
- s << T(' ');
- addPosDescription (s, yMode, y);
- s << T(' ');
- addSizeDescription (s, wMode, w);
- s << T(' ');
- addSizeDescription (s, hMode, h);
-
- return s;
- }
-
- const Rectangle PositionedRectangle::getRectangle (const Rectangle& target) const throw()
- {
- jassert (! target.isEmpty());
-
- double x_, y_, w_, h_;
- applyPosAndSize (x_, w_, x, w, xMode, wMode, target.getX(), target.getWidth());
- applyPosAndSize (y_, h_, y, h, yMode, hMode, target.getY(), target.getHeight());
-
- return Rectangle (roundDoubleToInt (x_), roundDoubleToInt (y_),
- roundDoubleToInt (w_), roundDoubleToInt (h_));
- }
-
- void PositionedRectangle::getRectangleDouble (const Rectangle& target,
- double& x_, double& y_,
- double& w_, double& h_) const throw()
- {
- jassert (! target.isEmpty());
-
- applyPosAndSize (x_, w_, x, w, xMode, wMode, target.getX(), target.getWidth());
- applyPosAndSize (y_, h_, y, h, yMode, hMode, target.getY(), target.getHeight());
- }
-
- void PositionedRectangle::applyToComponent (Component& comp) const throw()
- {
- comp.setBounds (getRectangle (Rectangle (0, 0, comp.getParentWidth(), comp.getParentHeight())));
- }
-
- void PositionedRectangle::updateFrom (const Rectangle& rectangle,
- const Rectangle& target) throw()
- {
- updatePosAndSize (x, w, rectangle.getX(), rectangle.getWidth(), xMode, wMode, target.getX(), target.getWidth());
- updatePosAndSize (y, h, rectangle.getY(), rectangle.getHeight(), yMode, hMode, target.getY(), target.getHeight());
- }
-
- void PositionedRectangle::updateFromDouble (const double newX, const double newY,
- const double newW, const double newH,
- const Rectangle& target) throw()
- {
- updatePosAndSize (x, w, newX, newW, xMode, wMode, target.getX(), target.getWidth());
- updatePosAndSize (y, h, newY, newH, yMode, hMode, target.getY(), target.getHeight());
- }
-
- void PositionedRectangle::updateFromComponent (const Component& comp) throw()
- {
- if (comp.getParentComponent() == 0 && ! comp.isOnDesktop())
- updateFrom (comp.getBounds(), Rectangle());
- else
- updateFrom (comp.getBounds(), Rectangle (0, 0, comp.getParentWidth(), comp.getParentHeight()));
- }
-
- PositionedRectangle::AnchorPoint PositionedRectangle::getAnchorPointX() const throw()
- {
- return (AnchorPoint) (xMode & (anchorAtLeftOrTop | anchorAtRightOrBottom | anchorAtCentre));
- }
-
- PositionedRectangle::PositionMode PositionedRectangle::getPositionModeX() const throw()
- {
- return (PositionMode) (xMode & (absoluteFromParentTopLeft
- | absoluteFromParentBottomRight
- | absoluteFromParentCentre
- | proportionOfParentSize));
- }
-
- PositionedRectangle::AnchorPoint PositionedRectangle::getAnchorPointY() const throw()
- {
- return (AnchorPoint) (yMode & (anchorAtLeftOrTop | anchorAtRightOrBottom | anchorAtCentre));
- }
-
- PositionedRectangle::PositionMode PositionedRectangle::getPositionModeY() const throw()
- {
- return (PositionMode) (yMode & (absoluteFromParentTopLeft
- | absoluteFromParentBottomRight
- | absoluteFromParentCentre
- | proportionOfParentSize));
- }
-
- PositionedRectangle::SizeMode PositionedRectangle::getWidthMode() const throw()
- {
- return (SizeMode) wMode;
- }
-
- PositionedRectangle::SizeMode PositionedRectangle::getHeightMode() const throw()
- {
- return (SizeMode) hMode;
- }
-
- void PositionedRectangle::setModes (const AnchorPoint xAnchor,
- const PositionMode xMode_,
- const AnchorPoint yAnchor,
- const PositionMode yMode_,
- const SizeMode widthMode,
- const SizeMode heightMode,
- const Rectangle& target) throw()
- {
- if (xMode != (xAnchor | xMode_) || wMode != widthMode)
- {
- double tx, tw;
- applyPosAndSize (tx, tw, x, w, xMode, wMode, target.getX(), target.getWidth());
-
- xMode = (uint8) (xAnchor | xMode_);
- wMode = (uint8) widthMode;
-
- updatePosAndSize (x, w, tx, tw, xMode, wMode, target.getX(), target.getWidth());
- }
-
- if (yMode != (yAnchor | yMode_) || hMode != heightMode)
- {
- double ty, th;
- applyPosAndSize (ty, th, y, h, yMode, hMode, target.getY(), target.getHeight());
-
- yMode = (uint8) (yAnchor | yMode_);
- hMode = (uint8) heightMode;
-
- updatePosAndSize (y, h, ty, th, yMode, hMode, target.getY(), target.getHeight());
- }
- }
-
- bool PositionedRectangle::isPositionAbsolute() const throw()
- {
- return xMode == absoluteFromParentTopLeft
- && yMode == absoluteFromParentTopLeft
- && wMode == absoluteSize
- && hMode == absoluteSize;
- }
-
- void PositionedRectangle::addPosDescription (String& s, const uint8 mode, const double value) const throw()
- {
- if ((mode & proportionOfParentSize) != 0)
- {
- s << (roundDoubleToInt (value * 100000.0) / 1000.0) << T('%');
- }
- else
- {
- s << (roundDoubleToInt (value * 100.0) / 100.0);
-
- if ((mode & absoluteFromParentBottomRight) != 0)
- s << T('R');
- else if ((mode & absoluteFromParentCentre) != 0)
- s << T('C');
- }
-
- if ((mode & anchorAtRightOrBottom) != 0)
- s << T('r');
- else if ((mode & anchorAtCentre) != 0)
- s << T('c');
- }
-
- void PositionedRectangle::addSizeDescription (String& s, const uint8 mode, const double value) const throw()
- {
- if (mode == proportionalSize)
- s << (roundDoubleToInt (value * 100000.0) / 1000.0) << T('%');
- else if (mode == parentSizeMinusAbsolute)
- s << (roundDoubleToInt (value * 100.0) / 100.0) << T('M');
- else
- s << (roundDoubleToInt (value * 100.0) / 100.0);
- }
-
- void PositionedRectangle::decodePosString (const String& s, uint8& mode, double& value) throw()
- {
- if (s.containsChar (T('r')))
- mode = anchorAtRightOrBottom;
- else if (s.containsChar (T('c')))
- mode = anchorAtCentre;
- else
- mode = anchorAtLeftOrTop;
-
- if (s.containsChar (T('%')))
- {
- mode |= proportionOfParentSize;
- value = s.removeCharacters (T("%rcRC")).getDoubleValue() / 100.0;
- }
- else
- {
- if (s.containsChar (T('R')))
- mode |= absoluteFromParentBottomRight;
- else if (s.containsChar (T('C')))
- mode |= absoluteFromParentCentre;
- else
- mode |= absoluteFromParentTopLeft;
-
- value = s.removeCharacters (T("rcRC")).getDoubleValue();
- }
- }
-
- void PositionedRectangle::decodeSizeString (const String& s, uint8& mode, double& value) throw()
- {
- if (s.containsChar (T('%')))
- {
- mode = proportionalSize;
- value = s.upToFirstOccurrenceOf (T("%"), false, false).getDoubleValue() / 100.0;
- }
- else if (s.containsChar (T('M')))
- {
- mode = parentSizeMinusAbsolute;
- value = s.getDoubleValue();
- }
- else
- {
- mode = absoluteSize;
- value = s.getDoubleValue();
- }
- }
-
- void PositionedRectangle::applyPosAndSize (double& xOut, double& wOut,
- const double x, const double w,
- const uint8 xMode, const uint8 wMode,
- const int parentPos,
- const int parentSize) const throw()
- {
- if (wMode == proportionalSize)
- wOut = roundDoubleToInt (w * parentSize);
- else if (wMode == parentSizeMinusAbsolute)
- wOut = jmax (0, parentSize - roundDoubleToInt (w));
- else
- wOut = roundDoubleToInt (w);
-
- if ((xMode & proportionOfParentSize) != 0)
- xOut = parentPos + x * parentSize;
- else if ((xMode & absoluteFromParentBottomRight) != 0)
- xOut = (parentPos + parentSize) - x;
- else if ((xMode & absoluteFromParentCentre) != 0)
- xOut = x + (parentPos + parentSize / 2);
- else
- xOut = x + parentPos;
-
- if ((xMode & anchorAtRightOrBottom) != 0)
- xOut -= wOut;
- else if ((xMode & anchorAtCentre) != 0)
- xOut -= wOut / 2;
- }
-
- void PositionedRectangle::updatePosAndSize (double& xOut, double& wOut,
- double x, const double w,
- const uint8 xMode, const uint8 wMode,
- const int parentPos,
- const int parentSize) const throw()
- {
- if (wMode == proportionalSize)
- {
- if (parentSize > 0)
- wOut = w / parentSize;
- }
- else if (wMode == parentSizeMinusAbsolute)
- wOut = parentSize - w;
- else
- wOut = w;
-
- if ((xMode & anchorAtRightOrBottom) != 0)
- x += w;
- else if ((xMode & anchorAtCentre) != 0)
- x += w / 2;
-
- if ((xMode & proportionOfParentSize) != 0)
- {
- if (parentSize > 0)
- xOut = (x - parentPos) / parentSize;
- }
- else if ((xMode & absoluteFromParentBottomRight) != 0)
- xOut = (parentPos + parentSize) - x;
- else if ((xMode & absoluteFromParentCentre) != 0)
- xOut = x - (parentPos + parentSize / 2);
- else
- xOut = x - parentPos;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_PositionedRectangle.cpp *********/
-
- /********* Start of inlined file: juce_Rectangle.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- Rectangle::Rectangle() throw()
- : x (0),
- y (0),
- w (0),
- h (0)
- {
- }
-
- Rectangle::Rectangle (const int x_, const int y_,
- const int w_, const int h_) throw()
- : x (x_),
- y (y_),
- w (w_),
- h (h_)
- {
- }
-
- Rectangle::Rectangle (const int w_, const int h_) throw()
- : x (0),
- y (0),
- w (w_),
- h (h_)
- {
- }
-
- Rectangle::Rectangle (const Rectangle& other) throw()
- : x (other.x),
- y (other.y),
- w (other.w),
- h (other.h)
- {
- }
-
- Rectangle::~Rectangle() throw()
- {
- }
-
- bool Rectangle::isEmpty() const throw()
- {
- return w <= 0 || h <= 0;
- }
-
- void Rectangle::setBounds (const int x_,
- const int y_,
- const int w_,
- const int h_) throw()
- {
- x = x_;
- y = y_;
- w = w_;
- h = h_;
- }
-
- void Rectangle::setPosition (const int x_,
- const int y_) throw()
- {
- x = x_;
- y = y_;
- }
-
- void Rectangle::setSize (const int w_,
- const int h_) throw()
- {
- w = w_;
- h = h_;
- }
-
- void Rectangle::translate (const int dx,
- const int dy) throw()
- {
- x += dx;
- y += dy;
- }
-
- const Rectangle Rectangle::translated (const int dx,
- const int dy) const throw()
- {
- return Rectangle (x + dx, y + dy, w, h);
- }
-
- void Rectangle::expand (const int deltaX,
- const int deltaY) throw()
- {
- const int nw = jmax (0, w + deltaX + deltaX);
- const int nh = jmax (0, h + deltaY + deltaY);
-
- setBounds (x - deltaX,
- y - deltaY,
- nw, nh);
- }
-
- const Rectangle Rectangle::expanded (const int deltaX,
- const int deltaY) const throw()
- {
- const int nw = jmax (0, w + deltaX + deltaX);
- const int nh = jmax (0, h + deltaY + deltaY);
-
- return Rectangle (x - deltaX,
- y - deltaY,
- nw, nh);
- }
-
- void Rectangle::reduce (const int deltaX,
- const int deltaY) throw()
- {
- expand (-deltaX, -deltaY);
- }
-
- const Rectangle Rectangle::reduced (const int deltaX,
- const int deltaY) const throw()
- {
- return expanded (-deltaX, -deltaY);
- }
-
- bool Rectangle::operator== (const Rectangle& other) const throw()
- {
- return x == other.x
- && y == other.y
- && w == other.w
- && h == other.h;
- }
-
- bool Rectangle::operator!= (const Rectangle& other) const throw()
- {
- return x != other.x
- || y != other.y
- || w != other.w
- || h != other.h;
- }
-
- bool Rectangle::contains (const int px,
- const int py) const throw()
- {
- return px >= x
- && py >= y
- && px < x + w
- && py < y + h;
- }
-
- bool Rectangle::contains (const Rectangle& other) const throw()
- {
- return x <= other.x
- && y <= other.y
- && x + w >= other.x + other.w
- && y + h >= other.y + other.h;
- }
-
- bool Rectangle::intersects (const Rectangle& other) const throw()
- {
- return x + w > other.x
- && y + h > other.y
- && x < other.x + other.w
- && y < other.y + other.h
- && w > 0
- && h > 0;
- }
-
- const Rectangle Rectangle::getIntersection (const Rectangle& other) const throw()
- {
- const int nx = jmax (x, other.x);
- const int ny = jmax (y, other.y);
- const int nw = jmin (x + w, other.x + other.w) - nx;
- const int nh = jmin (y + h, other.y + other.h) - ny;
-
- if (nw >= 0 && nh >= 0)
- return Rectangle (nx, ny, nw, nh);
- else
- return Rectangle();
- }
-
- bool Rectangle::intersectRectangle (int& x1, int& y1, int& w1, int& h1) const throw()
- {
- const int maxX = jmax (x1, x);
- w1 = jmin (x1 + w1, x + w) - maxX;
-
- if (w1 > 0)
- {
- const int maxY = jmax (y1, y);
- h1 = jmin (y1 + h1, y + h) - maxY;
-
- if (h1 > 0)
- {
- x1 = maxX;
- y1 = maxY;
-
- return true;
- }
- }
-
- return false;
- }
-
- bool Rectangle::intersectRectangles (int& x1, int& y1, int& w1, int& h1,
- int x2, int y2, int w2, int h2) throw()
- {
- const int x = jmax (x1, x2);
- w1 = jmin (x1 + w1, x2 + w2) - x;
-
- if (w1 > 0)
- {
- const int y = jmax (y1, y2);
- h1 = jmin (y1 + h1, y2 + h2) - y;
-
- if (h1 > 0)
- {
- x1 = x;
- y1 = y;
-
- return true;
- }
- }
-
- return false;
- }
-
- const Rectangle Rectangle::getUnion (const Rectangle& other) const throw()
- {
- const int newX = jmin (x, other.x);
- const int newY = jmin (y, other.y);
-
- return Rectangle (newX, newY,
- jmax (x + w, other.x + other.w) - newX,
- jmax (y + h, other.y + other.h) - newY);
- }
-
- bool Rectangle::enlargeIfAdjacent (const Rectangle& other) throw()
- {
- if (x == other.x && getRight() == other.getRight()
- && (other.getBottom() >= y && other.y <= getBottom()))
- {
- const int newY = jmin (y, other.y);
- h = jmax (getBottom(), other.getBottom()) - newY;
- y = newY;
- return true;
- }
- else if (y == other.y && getBottom() == other.getBottom()
- && (other.getRight() >= x && other.x <= getRight()))
- {
- const int newX = jmin (x, other.x);
- w = jmax (getRight(), other.getRight()) - newX;
- x = newX;
- return true;
- }
-
- return false;
- }
-
- bool Rectangle::reduceIfPartlyContainedIn (const Rectangle& other) throw()
- {
- int inside = 0;
- const int otherR = other.getRight();
-
- if (x >= other.x && x < otherR)
- inside = 1;
-
- const int otherB = other.getBottom();
-
- if (y >= other.y && y < otherB)
- inside |= 2;
-
- const int r = x + w;
-
- if (r >= other.x && r < otherR)
- inside |= 4;
-
- const int b = y + h;
-
- if (b >= other.y && b < otherB)
- inside |= 8;
-
- switch (inside)
- {
- case 1 + 2 + 8:
- w = r - otherR;
- x = otherR;
- return true;
-
- case 1 + 2 + 4:
- h = b - otherB;
- y = otherB;
- return true;
-
- case 2 + 4 + 8:
- w = other.x - x;
- return true;
-
- case 1 + 4 + 8:
- h = other.y - y;
- return true;
- }
-
- return false;
- }
-
- const String Rectangle::toString() const throw()
- {
- String s;
- s.preallocateStorage (16);
-
- s << x << T(' ')
- << y << T(' ')
- << w << T(' ')
- << h;
-
- return s;
- }
-
- const Rectangle Rectangle::fromString (const String& stringVersion)
- {
- StringArray toks;
- toks.addTokens (stringVersion.trim(), T(",; \t\r\n"), 0);
-
- return Rectangle (toks[0].trim().getIntValue(),
- toks[1].trim().getIntValue(),
- toks[2].trim().getIntValue(),
- toks[3].trim().getIntValue());
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_Rectangle.cpp *********/
-
- /********* Start of inlined file: juce_RectangleList.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- RectangleList::RectangleList() throw()
- {
- }
-
- RectangleList::RectangleList (const Rectangle& rect) throw()
- {
- if (! rect.isEmpty())
- rects.add (rect);
- }
-
- RectangleList::RectangleList (const RectangleList& other) throw()
- : rects (other.rects)
- {
- }
-
- const RectangleList& RectangleList::operator= (const RectangleList& other) throw()
- {
- if (this != &other)
- rects = other.rects;
-
- return *this;
- }
-
- RectangleList::~RectangleList() throw()
- {
- }
-
- void RectangleList::clear() throw()
- {
- rects.clearQuick();
- }
-
- const Rectangle RectangleList::getRectangle (const int index) const throw()
- {
- if (((unsigned int) index) < (unsigned int) rects.size())
- return rects.getReference (index);
-
- return Rectangle();
- }
-
- bool RectangleList::isEmpty() const throw()
- {
- return rects.size() == 0;
- }
-
- RectangleList::Iterator::Iterator (const RectangleList& list) throw()
- : current (0),
- owner (list),
- index (list.rects.size())
- {
- }
-
- RectangleList::Iterator::~Iterator() throw()
- {
- }
-
- bool RectangleList::Iterator::next() throw()
- {
- if (--index >= 0)
- {
- current = & (owner.rects.getReference (index));
- return true;
- }
-
- return false;
- }
-
- void RectangleList::add (const Rectangle& rect) throw()
- {
- if (! rect.isEmpty())
- {
- if (rects.size() == 0)
- {
- rects.add (rect);
- }
- else
- {
- bool anyOverlaps = false;
-
- int i;
- for (i = rects.size(); --i >= 0;)
- {
- Rectangle& ourRect = rects.getReference (i);
-
- if (rect.intersects (ourRect))
- {
- if (rect.contains (ourRect))
- rects.remove (i);
- else if (! ourRect.reduceIfPartlyContainedIn (rect))
- anyOverlaps = true;
- }
- }
-
- if (anyOverlaps && rects.size() > 0)
- {
- RectangleList r (rect);
-
- for (i = rects.size(); --i >= 0;)
- {
- const Rectangle& ourRect = rects.getReference (i);
-
- if (rect.intersects (ourRect))
- {
- r.subtract (ourRect);
-
- if (r.rects.size() == 0)
- return;
- }
- }
-
- for (i = r.getNumRectangles(); --i >= 0;)
- rects.add (r.rects.getReference (i));
- }
- else
- {
- rects.add (rect);
- }
- }
- }
- }
-
- void RectangleList::addWithoutMerging (const Rectangle& rect) throw()
- {
- rects.add (rect);
- }
-
- void RectangleList::add (const int x, const int y, const int w, const int h) throw()
- {
- if (rects.size() == 0)
- {
- if (w > 0 && h > 0)
- rects.add (Rectangle (x, y, w, h));
- }
- else
- {
- add (Rectangle (x, y, w, h));
- }
- }
-
- void RectangleList::add (const RectangleList& other) throw()
- {
- for (int i = 0; i < other.rects.size(); ++i)
- add (other.rects.getReference (i));
- }
-
- void RectangleList::subtract (const Rectangle& rect) throw()
- {
- const int originalNumRects = rects.size();
-
- if (originalNumRects > 0)
- {
- const int x1 = rect.x;
- const int y1 = rect.y;
- const int x2 = x1 + rect.w;
- const int y2 = y1 + rect.h;
-
- for (int i = getNumRectangles(); --i >= 0;)
- {
- Rectangle& r = rects.getReference (i);
-
- const int rx1 = r.x;
- const int ry1 = r.y;
- const int rx2 = rx1 + r.w;
- const int ry2 = ry1 + r.h;
-
- if (! (x2 <= rx1 || x1 >= rx2 || y2 <= ry1 || y1 >= ry2))
- {
- if (x1 > rx1 && x1 < rx2)
- {
- if (y1 <= ry1 && y2 >= ry2 && x2 >= rx2)
- {
- r.w = x1 - rx1;
- }
- else
- {
- r.x = x1;
- r.w = rx2 - x1;
-
- rects.insert (i + 1, Rectangle (rx1, ry1, x1 - rx1, ry2 - ry1));
- i += 2;
- }
- }
- else if (x2 > rx1 && x2 < rx2)
- {
- r.x = x2;
- r.w = rx2 - x2;
-
- if (y1 > ry1 || y2 < ry2 || x1 > rx1)
- {
- rects.insert (i + 1, Rectangle (rx1, ry1, x2 - rx1, ry2 - ry1));
- i += 2;
- }
- }
- else if (y1 > ry1 && y1 < ry2)
- {
- if (x1 <= rx1 && x2 >= rx2 && y2 >= ry2)
- {
- r.h = y1 - ry1;
- }
- else
- {
- r.y = y1;
- r.h = ry2 - y1;
-
- rects.insert (i + 1, Rectangle (rx1, ry1, rx2 - rx1, y1 - ry1));
- i += 2;
- }
- }
- else if (y2 > ry1 && y2 < ry2)
- {
- r.y = y2;
- r.h = ry2 - y2;
-
- if (x1 > rx1 || x2 < rx2 || y1 > ry1)
- {
- rects.insert (i + 1, Rectangle (rx1, ry1, rx2 - rx1, y2 - ry1));
- i += 2;
- }
- }
- else
- {
- rects.remove (i);
- }
- }
- }
-
- if (rects.size() > originalNumRects + 10)
- consolidate();
- }
- }
-
- void RectangleList::subtract (const RectangleList& otherList) throw()
- {
- for (int i = otherList.rects.size(); --i >= 0;)
- subtract (otherList.rects.getReference (i));
- }
-
- bool RectangleList::clipTo (const Rectangle& rect) throw()
- {
- bool notEmpty = false;
-
- if (rect.isEmpty())
- {
- clear();
- }
- else
- {
- for (int i = rects.size(); --i >= 0;)
- {
- Rectangle& r = rects.getReference (i);
-
- if (! rect.intersectRectangle (r.x, r.y, r.w, r.h))
- rects.remove (i);
- else
- notEmpty = true;
- }
- }
-
- return notEmpty;
- }
-
- bool RectangleList::clipTo (const RectangleList& other) throw()
- {
- if (rects.size() == 0)
- return false;
-
- RectangleList result;
-
- for (int j = 0; j < rects.size(); ++j)
- {
- const Rectangle& rect = rects.getReference (j);
-
- for (int i = other.rects.size(); --i >= 0;)
- {
- Rectangle r (other.rects.getReference (i));
-
- if (rect.intersectRectangle (r.x, r.y, r.w, r.h))
- result.rects.add (r);
- }
- }
-
- swapWith (result);
-
- return ! isEmpty();
- }
-
- bool RectangleList::getIntersectionWith (const Rectangle& rect, RectangleList& destRegion) const throw()
- {
- destRegion.clear();
-
- if (! rect.isEmpty())
- {
- for (int i = rects.size(); --i >= 0;)
- {
- Rectangle r (rects.getReference (i));
-
- if (rect.intersectRectangle (r.x, r.y, r.w, r.h))
- destRegion.rects.add (r);
- }
- }
-
- return destRegion.rects.size() > 0;
- }
-
- void RectangleList::swapWith (RectangleList& otherList) throw()
- {
- rects.swapWithArray (otherList.rects);
- }
-
- void RectangleList::consolidate() throw()
- {
- int i;
- for (i = 0; i < getNumRectangles() - 1; ++i)
- {
- Rectangle& r = rects.getReference (i);
- const int rx1 = r.x;
- const int ry1 = r.y;
- const int rx2 = rx1 + r.w;
- const int ry2 = ry1 + r.h;
-
- for (int j = rects.size(); --j > i;)
- {
- Rectangle& r2 = rects.getReference (j);
- const int jrx1 = r2.x;
- const int jry1 = r2.y;
- const int jrx2 = jrx1 + r2.w;
- const int jry2 = jry1 + r2.h;
-
- // if the vertical edges of any blocks are touching and their horizontals don't
- // line up, split them horizontally..
- if (jrx1 == rx2 || jrx2 == rx1)
- {
- if (jry1 > ry1 && jry1 < ry2)
- {
- r.h = jry1 - ry1;
- rects.add (Rectangle (rx1, jry1, rx2 - rx1, ry2 - jry1));
- i = -1;
- break;
- }
-
- if (jry2 > ry1 && jry2 < ry2)
- {
- r.h = jry2 - ry1;
- rects.add (Rectangle (rx1, jry2, rx2 - rx1, ry2 - jry2));
- i = -1;
- break;
- }
- else if (ry1 > jry1 && ry1 < jry2)
- {
- r2.h = ry1 - jry1;
- rects.add (Rectangle (jrx1, ry1, jrx2 - jrx1, jry2 - ry1));
- i = -1;
- break;
- }
- else if (ry2 > jry1 && ry2 < jry2)
- {
- r2.h = ry2 - jry1;
- rects.add (Rectangle (jrx1, ry2, jrx2 - jrx1, jry2 - ry2));
- i = -1;
- break;
- }
- }
- }
- }
-
- for (i = 0; i < rects.size() - 1; ++i)
- {
- Rectangle& r = rects.getReference (i);
-
- for (int j = rects.size(); --j > i;)
- {
- if (r.enlargeIfAdjacent (rects.getReference (j)))
- {
- rects.remove (j);
- i = -1;
- break;
- }
- }
- }
- }
-
- bool RectangleList::containsPoint (const int x, const int y) const throw()
- {
- for (int i = getNumRectangles(); --i >= 0;)
- if (rects.getReference (i).contains (x, y))
- return true;
-
- return false;
- }
-
- bool RectangleList::containsRectangle (const Rectangle& rectangleToCheck) const throw()
- {
- if (rects.size() > 1)
- {
- RectangleList r (rectangleToCheck);
-
- for (int i = rects.size(); --i >= 0;)
- {
- r.subtract (rects.getReference (i));
-
- if (r.rects.size() == 0)
- return true;
- }
- }
- else if (rects.size() > 0)
- {
- return rects.getReference (0).contains (rectangleToCheck);
- }
-
- return false;
- }
-
- bool RectangleList::intersectsRectangle (const Rectangle& rectangleToCheck) const throw()
- {
- for (int i = rects.size(); --i >= 0;)
- if (rects.getReference (i).intersects (rectangleToCheck))
- return true;
-
- return false;
- }
-
- bool RectangleList::intersects (const RectangleList& other) const throw()
- {
- for (int i = rects.size(); --i >= 0;)
- if (other.intersectsRectangle (rects.getReference (i)))
- return true;
-
- return false;
- }
-
- const Rectangle RectangleList::getBounds() const throw()
- {
- if (rects.size() <= 1)
- {
- if (rects.size() == 0)
- return Rectangle();
- else
- return rects.getReference (0);
- }
- else
- {
- const Rectangle& r = rects.getReference (0);
-
- int minX = r.x;
- int minY = r.y;
- int maxX = minX + r.w;
- int maxY = minY + r.h;
-
- for (int i = rects.size(); --i > 0;)
- {
- const Rectangle& r2 = rects.getReference (i);
-
- minX = jmin (minX, r2.x);
- minY = jmin (minY, r2.y);
- maxX = jmax (maxX, r2.getRight());
- maxY = jmax (maxY, r2.getBottom());
- }
-
- return Rectangle (minX, minY, maxX - minX, maxY - minY);
- }
- }
-
- void RectangleList::offsetAll (const int dx, const int dy) throw()
- {
- for (int i = rects.size(); --i >= 0;)
- {
- Rectangle& r = rects.getReference (i);
-
- r.x += dx;
- r.y += dy;
- }
- }
-
- const Path RectangleList::toPath() const throw()
- {
- Path p;
-
- for (int i = rects.size(); --i >= 0;)
- {
- const Rectangle& r = rects.getReference (i);
-
- p.addRectangle ((float) r.x,
- (float) r.y,
- (float) r.w,
- (float) r.h);
- }
-
- return p;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_RectangleList.cpp *********/
-
- /********* Start of inlined file: juce_Image.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- static const int fullAlphaThreshold = 253;
-
- Image::Image (const PixelFormat format_,
- const int imageWidth_,
- const int imageHeight_)
- : format (format_),
- imageWidth (imageWidth_),
- imageHeight (imageHeight_),
- imageData (0)
- {
- jassert (format_ == RGB || format_ == ARGB || format_ == SingleChannel);
- jassert (imageWidth_ > 0 && imageHeight_ > 0); // it's illegal to create a zero-sized image - the
- // actual image will be at least 1x1.
- }
-
- Image::Image (const PixelFormat format_,
- const int imageWidth_,
- const int imageHeight_,
- const bool clearImage)
- : format (format_),
- imageWidth (imageWidth_),
- imageHeight (imageHeight_)
- {
- jassert (format_ == RGB || format_ == ARGB || format_ == SingleChannel);
- jassert (imageWidth_ > 0 && imageHeight_ > 0); // it's illegal to create a zero-sized image - the
- // actual image will be at least 1x1.
-
- pixelStride = (format == RGB) ? 3 : ((format == ARGB) ? 4 : 1);
- lineStride = (pixelStride * jmax (1, imageWidth_) + 3) & ~3;
- const int dataSize = lineStride * jmax (1, imageHeight_);
-
- imageData = (uint8*) (clearImage ? juce_calloc (dataSize)
- : juce_malloc (dataSize));
- }
-
- Image::Image (const Image& other)
- : format (other.format),
- imageWidth (other.imageWidth),
- imageHeight (other.imageHeight)
- {
- pixelStride = (format == RGB) ? 3 : ((format == ARGB) ? 4 : 1);
- lineStride = (pixelStride * jmax (1, imageWidth) + 3) & ~3;
- const int dataSize = lineStride * jmax (1, imageHeight);
-
- imageData = (uint8*) juce_malloc (dataSize);
-
- int ls, ps;
- const uint8* srcData = other.lockPixelDataReadOnly (0, 0, imageWidth, imageHeight, ls, ps);
- setPixelData (0, 0, imageWidth, imageHeight, srcData, ls);
- other.releasePixelDataReadOnly (srcData);
- }
-
- Image::~Image()
- {
- juce_free (imageData);
- }
-
- LowLevelGraphicsContext* Image::createLowLevelContext()
- {
- return new LowLevelGraphicsSoftwareRenderer (*this);
- }
-
- uint8* Image::lockPixelDataReadWrite (int x, int y, int w, int h, int& ls, int& ps)
- {
- jassert (x >= 0 && y >= 0 && w > 0 && h > 0 && x + w <= imageWidth && y + h <= imageHeight);
- w = w;
- h = h;
-
- ls = lineStride;
- ps = pixelStride;
- return imageData + x * pixelStride + y * lineStride;
- }
-
- void Image::releasePixelDataReadWrite (void*)
- {
- }
-
- const uint8* Image::lockPixelDataReadOnly (int x, int y, int w, int h, int& ls, int& ps) const
- {
- jassert (x >= 0 && y >= 0 && w > 0 && h > 0 && x + w <= imageWidth && y + h <= imageHeight);
- w = w;
- h = h;
-
- ls = lineStride;
- ps = pixelStride;
- return imageData + x * pixelStride + y * lineStride;
- }
-
- void Image::releasePixelDataReadOnly (const void*) const
- {
- }
-
- void Image::setPixelData (int x, int y, int w, int h,
- const uint8* sourcePixelData, int sourceLineStride)
- {
- jassert (x >= 0 && y >= 0 && w > 0 && h > 0 && x + w <= imageWidth && y + h <= imageHeight);
-
- if (Rectangle::intersectRectangles (x, y, w, h, 0, 0, imageWidth, imageHeight))
- {
- int ls, ps;
- uint8* dest = lockPixelDataReadWrite (x, y, w, h, ls, ps);
-
- for (int i = 0; i < h; ++i)
- {
- memcpy (dest + ls * i,
- sourcePixelData + sourceLineStride * i,
- w * pixelStride);
- }
-
- releasePixelDataReadWrite (dest);
- }
- }
-
- void Image::clear (int dx, int dy, int dw, int dh,
- const Colour& colourToClearTo)
- {
- const PixelARGB col (colourToClearTo.getPixelARGB());
-
- int ls, ps;
- uint8* dstData = lockPixelDataReadWrite (dx, dy, dw, dh, ls, ps);
- uint8* dest = dstData;
-
- while (--dh >= 0)
- {
- uint8* line = dest;
- dest += ls;
-
- if (isARGB())
- {
- for (int x = dw; --x >= 0;)
- {
- ((PixelARGB*) line)->set (col);
- line += ps;
- }
- }
- else if (isRGB())
- {
- for (int x = dw; --x >= 0;)
- {
- ((PixelRGB*) line)->set (col);
- line += ps;
- }
- }
- else
- {
- for (int x = dw; --x >= 0;)
- {
- *line = col.getAlpha();
- line += ps;
- }
- }
- }
-
- releasePixelDataReadWrite (dstData);
- }
-
- Image* Image::createCopy (int newWidth, int newHeight,
- const Graphics::ResamplingQuality quality) const
- {
- if (newWidth < 0)
- newWidth = imageWidth;
-
- if (newHeight < 0)
- newHeight = imageHeight;
-
- Image* const newImage = new Image (format, newWidth, newHeight, true);
-
- Graphics g (*newImage);
- g.setImageResamplingQuality (quality);
-
- g.drawImage (this,
- 0, 0, newWidth, newHeight,
- 0, 0, imageWidth, imageHeight,
- false);
-
- return newImage;
- }
-
- const Colour Image::getPixelAt (const int x, const int y) const
- {
- Colour c;
-
- if (((unsigned int) x) < (unsigned int) imageWidth
- && ((unsigned int) y) < (unsigned int) imageHeight)
- {
- int ls, ps;
- const uint8* const pixels = lockPixelDataReadOnly (x, y, 1, 1, ls, ps);
-
- if (isARGB())
- {
- PixelARGB p (*(const PixelARGB*) pixels);
- p.unpremultiply();
- c = Colour (p.getARGB());
- }
- else if (isRGB())
- c = Colour (((const PixelRGB*) pixels)->getARGB());
- else
- c = Colour ((uint8) 0, (uint8) 0, (uint8) 0, *pixels);
-
- releasePixelDataReadOnly (pixels);
- }
-
- return c;
- }
-
- void Image::setPixelAt (const int x, const int y,
- const Colour& colour)
- {
- if (((unsigned int) x) < (unsigned int) imageWidth
- && ((unsigned int) y) < (unsigned int) imageHeight)
- {
- int ls, ps;
- uint8* const pixels = lockPixelDataReadWrite (x, y, 1, 1, ls, ps);
- const PixelARGB col (colour.getPixelARGB());
-
- if (isARGB())
- ((PixelARGB*) pixels)->set (col);
- else if (isRGB())
- ((PixelRGB*) pixels)->set (col);
- else
- *pixels = col.getAlpha();
-
- releasePixelDataReadWrite (pixels);
- }
- }
-
- void Image::multiplyAlphaAt (const int x, const int y,
- const float multiplier)
- {
- if (((unsigned int) x) < (unsigned int) imageWidth
- && ((unsigned int) y) < (unsigned int) imageHeight
- && hasAlphaChannel())
- {
- int ls, ps;
- uint8* const pixels = lockPixelDataReadWrite (x, y, 1, 1, ls, ps);
-
- if (isARGB())
- ((PixelARGB*) pixels)->multiplyAlpha (multiplier);
- else
- *pixels = (uint8) (*pixels * multiplier);
-
- releasePixelDataReadWrite (pixels);
- }
- }
-
- void Image::multiplyAllAlphas (const float amountToMultiplyBy)
- {
- if (hasAlphaChannel())
- {
- int ls, ps;
- uint8* const pixels = lockPixelDataReadWrite (0, 0, getWidth(), getHeight(), ls, ps);
-
- if (isARGB())
- {
- for (int y = 0; y < imageHeight; ++y)
- {
- uint8* p = pixels + y * ls;
-
- for (int x = 0; x < imageWidth; ++x)
- {
- ((PixelARGB*) p)->multiplyAlpha (amountToMultiplyBy);
- p += ps;
- }
- }
- }
- else
- {
- for (int y = 0; y < imageHeight; ++y)
- {
- uint8* p = pixels + y * ls;
-
- for (int x = 0; x < imageWidth; ++x)
- {
- *p = (uint8) (*p * amountToMultiplyBy);
- p += ps;
- }
- }
- }
-
- releasePixelDataReadWrite (pixels);
- }
- else
- {
- jassertfalse // can't do this without an alpha-channel!
- }
- }
-
- void Image::desaturate()
- {
- if (isARGB() || isRGB())
- {
- int ls, ps;
- uint8* const pixels = lockPixelDataReadWrite (0, 0, getWidth(), getHeight(), ls, ps);
-
- if (isARGB())
- {
- for (int y = 0; y < imageHeight; ++y)
- {
- uint8* p = pixels + y * ls;
-
- for (int x = 0; x < imageWidth; ++x)
- {
- ((PixelARGB*) p)->desaturate();
- p += ps;
- }
- }
- }
- else
- {
- for (int y = 0; y < imageHeight; ++y)
- {
- uint8* p = pixels + y * ls;
-
- for (int x = 0; x < imageWidth; ++x)
- {
- ((PixelRGB*) p)->desaturate();
- p += ps;
- }
- }
- }
-
- releasePixelDataReadWrite (pixels);
- }
- }
-
- void Image::createSolidAreaMask (RectangleList& result, const float alphaThreshold) const
- {
- if (hasAlphaChannel())
- {
- const uint8 threshold = (uint8) jlimit (0, 255, roundFloatToInt (alphaThreshold * 255.0f));
- SparseSet <int> pixelsOnRow;
-
- int ls, ps;
- const uint8* const pixels = lockPixelDataReadOnly (0, 0, imageWidth, imageHeight, ls, ps);
-
- for (int y = 0; y < imageHeight; ++y)
- {
- pixelsOnRow.clear();
- const uint8* lineData = pixels + ls * y;
-
- if (isARGB())
- {
- for (int x = 0; x < imageWidth; ++x)
- {
- if (((const PixelARGB*) lineData)->getAlpha() >= threshold)
- pixelsOnRow.addRange (x, 1);
-
- lineData += ps;
- }
- }
- else
- {
- for (int x = 0; x < imageWidth; ++x)
- {
- if (*lineData >= threshold)
- pixelsOnRow.addRange (x, 1);
-
- lineData += ps;
- }
- }
-
- for (int i = 0; i < pixelsOnRow.getNumRanges(); ++i)
- {
- int x, w;
-
- if (pixelsOnRow.getRange (i, x, w))
- result.add (Rectangle (x, y, w, 1));
- }
-
- result.consolidate();
- }
-
- releasePixelDataReadOnly (pixels);
- }
- else
- {
- result.add (0, 0, imageWidth, imageHeight);
- }
- }
-
- void Image::moveImageSection (int dx, int dy,
- int sx, int sy,
- int w, int h)
- {
- if (dx < 0)
- {
- w += dx;
- sx -= dx;
- dx = 0;
- }
-
- if (dy < 0)
- {
- h += dy;
- sy -= dy;
- dy = 0;
- }
-
- if (sx < 0)
- {
- w += sx;
- dx -= sx;
- sx = 0;
- }
-
- if (sy < 0)
- {
- h += sy;
- dy -= sy;
- sy = 0;
- }
-
- const int minX = jmin (dx, sx);
- const int minY = jmin (dy, sy);
-
- w = jmin (w, getWidth() - jmax (sx, dx));
- h = jmin (h, getHeight() - jmax (sy, dy));
-
- if (w > 0 && h > 0)
- {
- const int maxX = jmax (dx, sx) + w;
- const int maxY = jmax (dy, sy) + h;
-
- int ls, ps;
- uint8* const pixels = lockPixelDataReadWrite (minX, minY, maxX - minX, maxY - minY, ls, ps);
-
- uint8* dst = pixels + ls * (dy - minY) + ps * (dx - minX);
- const uint8* src = pixels + ls * (sy - minY) + ps * (sx - minX);
-
- const int lineSize = ps * w;
-
- if (dy > sy)
- {
- while (--h >= 0)
- {
- const int offset = h * ls;
- memmove (dst + offset, src + offset, lineSize);
- }
- }
- else if (dst != src)
- {
- while (--h >= 0)
- {
- memmove (dst, src, lineSize);
- dst += ls;
- src += ls;
- }
- }
-
- releasePixelDataReadWrite (pixels);
- }
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_Image.cpp *********/
-
- /********* Start of inlined file: juce_ImageCache.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- struct CachedImageInfo
- {
- Image* image;
- int64 hashCode;
- int refCount;
- unsigned int releaseTime;
-
- juce_UseDebuggingNewOperator
- };
-
- static ImageCache* instance = 0;
- static int cacheTimeout = 5000;
-
- ImageCache::ImageCache() throw()
- : images (4)
- {
- }
-
- ImageCache::~ImageCache()
- {
- const ScopedLock sl (lock);
-
- for (int i = images.size(); --i >= 0;)
- {
- CachedImageInfo* const ci = (CachedImageInfo*)(images.getUnchecked(i));
- delete ci->image;
- delete ci;
- }
-
- images.clear();
-
- jassert (instance == this);
- instance = 0;
- }
-
- Image* ImageCache::getFromHashCode (const int64 hashCode)
- {
- if (instance != 0)
- {
- const ScopedLock sl (instance->lock);
-
- for (int i = instance->images.size(); --i >= 0;)
- {
- CachedImageInfo* const ci = (CachedImageInfo*) instance->images.getUnchecked(i);
-
- if (ci->hashCode == hashCode)
- {
- atomicIncrement (ci->refCount);
- return ci->image;
- }
- }
- }
-
- return 0;
- }
-
- void ImageCache::addImageToCache (Image* const image,
- const int64 hashCode)
- {
- if (image != 0)
- {
- if (instance == 0)
- instance = new ImageCache();
-
- CachedImageInfo* const newC = new CachedImageInfo();
- newC->hashCode = hashCode;
- newC->image = image;
- newC->refCount = 1;
- newC->releaseTime = 0;
-
- const ScopedLock sl (instance->lock);
- instance->images.add (newC);
- }
- }
-
- void ImageCache::release (Image* const imageToRelease)
- {
- if (imageToRelease != 0 && instance != 0)
- {
- const ScopedLock sl (instance->lock);
-
- for (int i = instance->images.size(); --i >= 0;)
- {
- CachedImageInfo* const ci = (CachedImageInfo*) instance->images.getUnchecked(i);
-
- if (ci->image == imageToRelease)
- {
- if (--(ci->refCount) == 0)
- ci->releaseTime = Time::getApproximateMillisecondCounter();
-
- if (! instance->isTimerRunning())
- instance->startTimer (999);
-
- break;
- }
- }
- }
- }
-
- bool ImageCache::isImageInCache (Image* const imageToLookFor)
- {
- if (instance != 0)
- {
- const ScopedLock sl (instance->lock);
-
- for (int i = instance->images.size(); --i >= 0;)
- if (((const CachedImageInfo*) instance->images.getUnchecked(i))->image == imageToLookFor)
- return true;
- }
-
- return false;
- }
-
- void ImageCache::incReferenceCount (Image* const image)
- {
- if (instance != 0)
- {
- const ScopedLock sl (instance->lock);
-
- for (int i = instance->images.size(); --i >= 0;)
- {
- CachedImageInfo* const ci = (CachedImageInfo*) instance->images.getUnchecked(i);
-
- if (ci->image == image)
- {
- ci->refCount++;
- return;
- }
- }
- }
-
- jassertfalse // (trying to inc the ref count of an image that's not in the cache)
- }
-
- void ImageCache::timerCallback()
- {
- int numberStillNeedingReleasing = 0;
- const unsigned int now = Time::getApproximateMillisecondCounter();
-
- const ScopedLock sl (lock);
-
- for (int i = images.size(); --i >= 0;)
- {
- CachedImageInfo* const ci = (CachedImageInfo*) images.getUnchecked(i);
-
- if (ci->refCount <= 0)
- {
- if (now > ci->releaseTime + cacheTimeout
- || now < ci->releaseTime - 1000)
- {
- images.remove (i);
- delete ci->image;
- delete ci;
- }
- else
- {
- ++numberStillNeedingReleasing;
- }
- }
- }
-
- if (numberStillNeedingReleasing == 0)
- stopTimer();
- }
-
- Image* ImageCache::getFromFile (const File& file)
- {
- const int64 hashCode = file.getFullPathName().hashCode64();
-
- Image* image = getFromHashCode (hashCode);
-
- if (image == 0)
- {
- image = ImageFileFormat::loadFrom (file);
- addImageToCache (image, hashCode);
- }
-
- return image;
- }
-
- Image* ImageCache::getFromMemory (const void* imageData,
- const int dataSize)
- {
- const int64 hashCode = (int64) (pointer_sized_int) imageData;
-
- Image* image = getFromHashCode (hashCode);
-
- if (image == 0)
- {
- image = ImageFileFormat::loadFrom (imageData, dataSize);
- addImageToCache (image, hashCode);
- }
-
- return image;
- }
-
- void ImageCache::setCacheTimeout (const int millisecs)
- {
- cacheTimeout = millisecs;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_ImageCache.cpp *********/
-
- /********* Start of inlined file: juce_ImageConvolutionKernel.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- ImageConvolutionKernel::ImageConvolutionKernel (const int size_) throw()
- : size (size_)
- {
- values = new float* [size];
-
- for (int i = size; --i >= 0;)
- values[i] = new float [size];
-
- clear();
- }
-
- ImageConvolutionKernel::~ImageConvolutionKernel() throw()
- {
- for (int i = size; --i >= 0;)
- delete[] values[i];
-
- delete[] values;
- }
-
- void ImageConvolutionKernel::setKernelValue (const int x,
- const int y,
- const float value) throw()
- {
- if (((unsigned int) x) < (unsigned int) size
- && ((unsigned int) y) < (unsigned int) size)
- {
- values[x][y] = value;
- }
- else
- {
- jassertfalse
- }
- }
-
- void ImageConvolutionKernel::clear() throw()
- {
- for (int y = size; --y >= 0;)
- for (int x = size; --x >= 0;)
- values[x][y] = 0;
- }
-
- void ImageConvolutionKernel::setOverallSum (const float desiredTotalSum) throw()
- {
- double currentTotal = 0.0;
-
- for (int y = size; --y >= 0;)
- for (int x = size; --x >= 0;)
- currentTotal += values[x][y];
-
- rescaleAllValues ((float) (desiredTotalSum / currentTotal));
- }
-
- void ImageConvolutionKernel::rescaleAllValues (const float multiplier) throw()
- {
- for (int y = size; --y >= 0;)
- for (int x = size; --x >= 0;)
- values[x][y] *= multiplier;
- }
-
- void ImageConvolutionKernel::createGaussianBlur (const float radius) throw()
- {
- const double radiusFactor = -1.0 / (radius * radius * 2);
- const int centre = size >> 1;
-
- for (int y = size; --y >= 0;)
- {
- for (int x = size; --x >= 0;)
- {
- const int cx = x - centre;
- const int cy = y - centre;
-
- values[x][y] = (float) exp (radiusFactor * (cx * cx + cy * cy));
- }
- }
-
- setOverallSum (1.0f);
- }
-
- void ImageConvolutionKernel::applyToImage (Image& destImage,
- const Image* sourceImage,
- int dx,
- int dy,
- int dw,
- int dh) const
- {
- Image* imageCreated = 0;
-
- if (sourceImage == 0)
- {
- sourceImage = imageCreated = destImage.createCopy();
- }
- else
- {
- jassert (sourceImage->getWidth() == destImage.getWidth()
- && sourceImage->getHeight() == destImage.getHeight()
- && sourceImage->getFormat() == destImage.getFormat());
-
- if (sourceImage->getWidth() != destImage.getWidth()
- || sourceImage->getHeight() != destImage.getHeight()
- || sourceImage->getFormat() != destImage.getFormat())
- return;
- }
-
- const int imageWidth = destImage.getWidth();
- const int imageHeight = destImage.getHeight();
-
- if (dx >= imageWidth || dy >= imageHeight)
- return;
-
- if (dx + dw > imageWidth)
- dw = imageWidth - dx;
-
- if (dy + dh > imageHeight)
- dh = imageHeight - dy;
-
- const int dx2 = dx + dw;
- const int dy2 = dy + dh;
-
- int lineStride, pixelStride;
- uint8* pixels = destImage.lockPixelDataReadWrite (dx, dy, dw, dh, lineStride, pixelStride);
- uint8* line = pixels;
-
- int srcLineStride, srcPixelStride;
- const uint8* srcPixels = sourceImage->lockPixelDataReadOnly (0, 0, sourceImage->getWidth(), sourceImage->getHeight(), srcLineStride, srcPixelStride);
-
- if (pixelStride == 4)
- {
- for (int y = dy; y < dy2; ++y)
- {
- uint8* dest = line;
- line += lineStride;
-
- for (int x = dx; x < dx2; ++x)
- {
- float c1 = 0;
- float c2 = 0;
- float c3 = 0;
- float c4 = 0;
-
- for (int yy = 0; yy < size; ++yy)
- {
- const int sy = y + yy - (size >> 1);
-
- if (sy >= imageHeight)
- break;
-
- if (sy >= 0)
- {
- int sx = x - (size >> 1);
- const uint8* src = srcPixels + srcLineStride * sy + srcPixelStride * sx;
-
- for (int xx = 0; xx < size; ++xx)
- {
- if (sx >= imageWidth)
- break;
-
- if (sx >= 0)
- {
- const float kernelMult = values[xx][yy];
- c1 += kernelMult * *src++;
- c2 += kernelMult * *src++;
- c3 += kernelMult * *src++;
- c4 += kernelMult * *src++;
- }
- else
- {
- src += 4;
- }
-
- ++sx;
- }
- }
- }
-
- *dest++ = (uint8) jmin (0xff, roundFloatToInt (c1));
- *dest++ = (uint8) jmin (0xff, roundFloatToInt (c2));
- *dest++ = (uint8) jmin (0xff, roundFloatToInt (c3));
- *dest++ = (uint8) jmin (0xff, roundFloatToInt (c4));
- }
- }
- }
- else if (pixelStride == 3)
- {
- for (int y = dy; y < dy2; ++y)
- {
- uint8* dest = line;
- line += lineStride;
-
- for (int x = dx; x < dx2; ++x)
- {
- float c1 = 0;
- float c2 = 0;
- float c3 = 0;
-
- for (int yy = 0; yy < size; ++yy)
- {
- const int sy = y + yy - (size >> 1);
-
- if (sy >= imageHeight)
- break;
-
- if (sy >= 0)
- {
- int sx = x - (size >> 1);
- const uint8* src = srcPixels + srcLineStride * sy + srcPixelStride * sx;
-
- for (int xx = 0; xx < size; ++xx)
- {
- if (sx >= imageWidth)
- break;
-
- if (sx >= 0)
- {
- const float kernelMult = values[xx][yy];
- c1 += kernelMult * *src++;
- c2 += kernelMult * *src++;
- c3 += kernelMult * *src++;
- }
- else
- {
- src += 3;
- }
-
- ++sx;
- }
- }
- }
-
- *dest++ = (uint8) roundFloatToInt (c1);
- *dest++ = (uint8) roundFloatToInt (c2);
- *dest++ = (uint8) roundFloatToInt (c3);
- }
- }
- }
-
- sourceImage->releasePixelDataReadOnly (srcPixels);
- destImage.releasePixelDataReadWrite (pixels);
-
- if (imageCreated != 0)
- delete imageCreated;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_ImageConvolutionKernel.cpp *********/
-
- /********* Start of inlined file: juce_ImageFileFormat.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- /********* Start of inlined file: juce_GIFLoader.h *********/
- #ifndef __JUCE_GIFLOADER_JUCEHEADER__
- #define __JUCE_GIFLOADER_JUCEHEADER__
-
- #ifndef DOXYGEN
-
- static const int maxGifCode = 1 << 12;
-
- /**
- Used internally by ImageFileFormat - don't use this class directly in your
- application.
-
- @see ImageFileFormat
- */
- class GIFLoader
- {
- public:
- GIFLoader (InputStream& in);
- ~GIFLoader() throw();
-
- Image* getImage() const throw() { return image; }
-
- private:
- Image* image;
- InputStream& input;
- uint8 buffer [300];
- uint8 palette [256][4];
- bool dataBlockIsZero, fresh, finished;
- int currentBit, lastBit, lastByteIndex;
- int codeSize, setCodeSize;
- int maxCode, maxCodeSize;
- int firstcode, oldcode;
- int clearCode, end_code;
- int table [2] [maxGifCode];
- int stack [2 * maxGifCode];
- int *sp;
-
- bool getSizeFromHeader (int& width, int& height);
- bool readPalette (const int numCols);
- int readDataBlock (unsigned char* dest);
- int processExtension (int type, int& transparent);
- int readLZWByte (bool initialise, int input_code_size);
- int getCode (int code_size, bool initialise);
- bool readImage (int width, int height,
- int interlace, int transparent);
-
- GIFLoader (const GIFLoader&);
- const GIFLoader& operator= (const GIFLoader&);
- };
-
- #endif // DOXYGEN
-
- #endif // __JUCE_GIFLOADER_JUCEHEADER__
- /********* End of inlined file: juce_GIFLoader.h *********/
-
- Image* juce_loadPNGImageFromStream (InputStream& inputStream) throw();
- bool juce_writePNGImageToStream (const Image& image, OutputStream& out) throw();
-
- PNGImageFormat::PNGImageFormat() throw() {}
- PNGImageFormat::~PNGImageFormat() throw() {}
-
- const String PNGImageFormat::getFormatName()
- {
- return T("PNG");
- }
-
- bool PNGImageFormat::canUnderstand (InputStream& in)
- {
- const int bytesNeeded = 4;
- char header [bytesNeeded];
-
- return in.read (header, bytesNeeded) == bytesNeeded
- && header[1] == 'P'
- && header[2] == 'N'
- && header[3] == 'G';
- }
-
- Image* PNGImageFormat::decodeImage (InputStream& in)
- {
- return juce_loadPNGImageFromStream (in);
- }
-
- bool PNGImageFormat::writeImageToStream (const Image& sourceImage,
- OutputStream& destStream)
- {
- return juce_writePNGImageToStream (sourceImage, destStream);
- }
-
- Image* juce_loadJPEGImageFromStream (InputStream& inputStream) throw();
- bool juce_writeJPEGImageToStream (const Image& image, OutputStream& out, float quality) throw();
-
- JPEGImageFormat::JPEGImageFormat() throw()
- : quality (-1.0f)
- {
- }
-
- JPEGImageFormat::~JPEGImageFormat() throw() {}
-
- void JPEGImageFormat::setQuality (const float newQuality)
- {
- quality = newQuality;
- }
-
- const String JPEGImageFormat::getFormatName()
- {
- return T("JPEG");
- }
-
- bool JPEGImageFormat::canUnderstand (InputStream& in)
- {
- const int bytesNeeded = 10;
- uint8 header [bytesNeeded];
-
- if (in.read (header, bytesNeeded) == bytesNeeded)
- {
- return header[0] == 0xff
- && header[1] == 0xd8
- && header[2] == 0xff
- && (header[3] == 0xe0 || header[3] == 0xe1);
- }
-
- return false;
- }
-
- Image* JPEGImageFormat::decodeImage (InputStream& in)
- {
- return juce_loadJPEGImageFromStream (in);
- }
-
- bool JPEGImageFormat::writeImageToStream (const Image& sourceImage,
- OutputStream& destStream)
- {
- return juce_writeJPEGImageToStream (sourceImage, destStream, quality);
- }
-
- class GIFImageFormat : public ImageFileFormat
- {
- public:
- GIFImageFormat() throw() {}
- ~GIFImageFormat() throw() {}
-
- const String getFormatName()
- {
- return T("GIF");
- }
-
- bool canUnderstand (InputStream& in)
- {
- const int bytesNeeded = 4;
- char header [bytesNeeded];
-
- return (in.read (header, bytesNeeded) == bytesNeeded)
- && header[0] == 'G'
- && header[1] == 'I'
- && header[2] == 'F';
- }
-
- Image* decodeImage (InputStream& in)
- {
- GIFLoader* const loader = new GIFLoader (in);
- Image* const im = loader->getImage();
- delete loader;
- return im;
- }
-
- bool writeImageToStream (const Image& /*sourceImage*/, OutputStream& /*destStream*/)
- {
- return false;
- }
- };
-
- ImageFileFormat* ImageFileFormat::findImageFormatForStream (InputStream& input)
- {
- static PNGImageFormat png;
- static JPEGImageFormat jpg;
- static GIFImageFormat gif;
-
- ImageFileFormat* formats[4];
- int numFormats = 0;
-
- formats [numFormats++] = &png;
- formats [numFormats++] = &jpg;
- formats [numFormats++] = &gif;
-
- const int64 streamPos = input.getPosition();
-
- for (int i = 0; i < numFormats; ++i)
- {
- const bool found = formats[i]->canUnderstand (input);
- input.setPosition (streamPos);
-
- if (found)
- return formats[i];
- }
-
- return 0;
- }
-
- Image* ImageFileFormat::loadFrom (InputStream& input)
- {
- ImageFileFormat* const format = findImageFormatForStream (input);
-
- if (format != 0)
- return format->decodeImage (input);
-
- return 0;
- }
-
- Image* ImageFileFormat::loadFrom (const File& file)
- {
- InputStream* const in = file.createInputStream();
-
- if (in != 0)
- {
- BufferedInputStream b (in, 8192, true);
- return loadFrom (b);
- }
-
- return 0;
- }
-
- Image* ImageFileFormat::loadFrom (const void* rawData, const int numBytes)
- {
- if (rawData != 0 && numBytes > 4)
- {
- MemoryInputStream stream (rawData, numBytes, false);
- return loadFrom (stream);
- }
-
- return 0;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_ImageFileFormat.cpp *********/
-
- /********* Start of inlined file: juce_GIFLoader.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- static inline int makeWord (const unsigned char a, const unsigned char b) throw()
- {
- return (b << 8) | a;
- }
-
- GIFLoader::GIFLoader (InputStream& in)
- : image (0),
- input (in),
- dataBlockIsZero (false),
- fresh (false),
- finished (false)
- {
- currentBit = lastBit = lastByteIndex = 0;
- maxCode = maxCodeSize = codeSize = setCodeSize = 0;
- firstcode = oldcode = 0;
- clearCode = end_code = 0;
-
- int imageWidth, imageHeight;
- int transparent = -1;
-
- if (! getSizeFromHeader (imageWidth, imageHeight))
- return;
-
- if ((imageWidth <= 0) || (imageHeight <= 0))
- return;
-
- unsigned char buf [16];
- if (in.read (buf, 3) != 3)
- return;
-
- int numColours = 2 << (buf[0] & 7);
-
- if ((buf[0] & 0x80) != 0)
- readPalette (numColours);
-
- for (;;)
- {
- if (input.read (buf, 1) != 1)
- break;
-
- if (buf[0] == ';')
- break;
-
- if (buf[0] == '!')
- {
- if (input.read (buf, 1) != 1)
- break;
-
- if (processExtension (buf[0], transparent) < 0)
- break;
-
- continue;
- }
-
- if (buf[0] != ',')
- continue;
-
- if (input.read (buf, 9) != 9)
- break;
-
- imageWidth = makeWord (buf[4], buf[5]);
- imageHeight = makeWord (buf[6], buf[7]);
-
- numColours = 2 << (buf[8] & 7);
-
- if ((buf[8] & 0x80) != 0)
- if (! readPalette (numColours))
- break;
-
- image = new Image ((transparent >= 0) ? Image::ARGB : Image::RGB,
- imageWidth, imageHeight, (transparent >= 0));
-
- readImage (imageWidth, imageHeight,
- (buf[8] & 0x40) != 0,
- transparent);
-
- break;
- }
- }
-
- GIFLoader::~GIFLoader() throw()
- {
- }
-
- bool GIFLoader::getSizeFromHeader (int& w, int& h)
- {
- unsigned char b [8];
-
- if (input.read (b, 6) == 6)
- {
- if ((strncmp ("GIF87a", (char*) b, 6) == 0)
- || (strncmp ("GIF89a", (char*) b, 6) == 0))
- {
- if (input.read (b, 4) == 4)
- {
- w = makeWord (b[0], b[1]);
- h = makeWord (b[2], b[3]);
- return true;
- }
- }
- }
-
- return false;
- }
-
- bool GIFLoader::readPalette (const int numCols)
- {
- unsigned char rgb[4];
-
- for (int i = 0; i < numCols; ++i)
- {
- input.read (rgb, 3);
-
- palette [i][0] = rgb[0];
- palette [i][1] = rgb[1];
- palette [i][2] = rgb[2];
- palette [i][3] = 0xff;
- }
-
- return true;
- }
-
- int GIFLoader::readDataBlock (unsigned char* const dest)
- {
- unsigned char n;
-
- if (input.read (&n, 1) == 1)
- {
- dataBlockIsZero = (n == 0);
-
- if (dataBlockIsZero || (input.read (dest, n) == n))
- return n;
- }
-
- return -1;
- }
-
- int GIFLoader::processExtension (const int type, int& transparent)
- {
- unsigned char b [300];
- int n = 0;
-
- if (type == 0xf9)
- {
- n = readDataBlock (b);
- if (n < 0)
- return 1;
-
- if ((b[0] & 0x1) != 0)
- transparent = b[3];
- }
-
- do
- {
- n = readDataBlock (b);
- }
- while (n > 0);
-
- return n;
- }
-
- int GIFLoader::getCode (const int codeSize, const bool initialise)
- {
- if (initialise)
- {
- currentBit = 0;
- lastBit = 0;
- finished = false;
- return 0;
- }
-
- if ((currentBit + codeSize) >= lastBit)
- {
- if (finished)
- return -1;
-
- buffer[0] = buffer [lastByteIndex - 2];
- buffer[1] = buffer [lastByteIndex - 1];
-
- const int n = readDataBlock (&buffer[2]);
-
- if (n == 0)
- finished = true;
-
- lastByteIndex = 2 + n;
- currentBit = (currentBit - lastBit) + 16;
- lastBit = (2 + n) * 8 ;
- }
-
- int result = 0;
- int i = currentBit;
-
- for (int j = 0; j < codeSize; ++j)
- {
- result |= ((buffer[i >> 3] & (1 << (i & 7))) != 0) << j;
- ++i;
- }
-
- currentBit += codeSize;
-
- return result;
- }
-
- int GIFLoader::readLZWByte (const bool initialise, const int inputCodeSize)
- {
- int code, incode, i;
-
- if (initialise)
- {
- setCodeSize = inputCodeSize;
- codeSize = setCodeSize + 1;
- clearCode = 1 << setCodeSize;
- end_code = clearCode + 1;
- maxCodeSize = 2 * clearCode;
- maxCode = clearCode + 2;
-
- getCode (0, true);
-
- fresh = true;
-
- for (i = 0; i < clearCode; ++i)
- {
- table[0][i] = 0;
- table[1][i] = i;
- }
-
- for (; i < maxGifCode; ++i)
- {
- table[0][i] = 0;
- table[1][i] = 0;
- }
-
- sp = stack;
-
- return 0;
- }
- else if (fresh)
- {
- fresh = false;
-
- do
- {
- firstcode = oldcode
- = getCode (codeSize, false);
- }
- while (firstcode == clearCode);
-
- return firstcode;
- }
-
- if (sp > stack)
- return *--sp;
-
- while ((code = getCode (codeSize, false)) >= 0)
- {
- if (code == clearCode)
- {
- for (i = 0; i < clearCode; ++i)
- {
- table[0][i] = 0;
- table[1][i] = i;
- }
-
- for (; i < maxGifCode; ++i)
- {
- table[0][i] = 0;
- table[1][i] = 0;
- }
-
- codeSize = setCodeSize + 1;
- maxCodeSize = 2 * clearCode;
- maxCode = clearCode + 2;
- sp = stack;
- firstcode = oldcode = getCode (codeSize, false);
- return firstcode;
-
- }
- else if (code == end_code)
- {
- if (dataBlockIsZero)
- return -2;
-
- unsigned char buf [260];
-
- int n;
- while ((n = readDataBlock (buf)) > 0)
- {}
-
- if (n != 0)
- return -2;
- }
-
- incode = code;
-
- if (code >= maxCode)
- {
- *sp++ = firstcode;
- code = oldcode;
- }
-
- while (code >= clearCode)
- {
- *sp++ = table[1][code];
- if (code == table[0][code])
- return -2;
-
- code = table[0][code];
- }
-
- *sp++ = firstcode = table[1][code];
-
- if ((code = maxCode) < maxGifCode)
- {
- table[0][code] = oldcode;
- table[1][code] = firstcode;
- ++maxCode;
-
- if ((maxCode >= maxCodeSize)
- && (maxCodeSize < maxGifCode))
- {
- maxCodeSize <<= 1;
- ++codeSize;
- }
- }
-
- oldcode = incode;
-
- if (sp > stack)
- return *--sp;
- }
-
- return code;
- }
-
- bool GIFLoader::readImage (const int width, const int height,
- const int interlace, const int transparent)
- {
- unsigned char c;
-
- if (input.read (&c, 1) != 1
- || readLZWByte (true, c) < 0)
- return false;
-
- if (transparent >= 0)
- {
- palette [transparent][0] = 0;
- palette [transparent][1] = 0;
- palette [transparent][2] = 0;
- palette [transparent][3] = 0;
- }
-
- int index;
- int xpos = 0, ypos = 0, pass = 0;
-
- int stride, pixelStride;
- uint8* const pixels = image->lockPixelDataReadWrite (0, 0, width, height, stride, pixelStride);
- uint8* p = pixels;
- const bool hasAlpha = image->hasAlphaChannel();
-
- while ((index = readLZWByte (false, c)) >= 0)
- {
- const uint8* const paletteEntry = palette [index];
-
- if (hasAlpha)
- {
- ((PixelARGB*) p)->setARGB (paletteEntry[3],
- paletteEntry[0],
- paletteEntry[1],
- paletteEntry[2]);
-
- ((PixelARGB*) p)->premultiply();
-
- p += pixelStride;
- }
- else
- {
- ((PixelRGB*) p)->setARGB (0,
- paletteEntry[0],
- paletteEntry[1],
- paletteEntry[2]);
-
- p += pixelStride;
- }
-
- ++xpos;
-
- if (xpos == width)
- {
- xpos = 0;
-
- if (interlace)
- {
- switch (pass)
- {
- case 0:
- case 1:
- ypos += 8;
- break;
- case 2:
- ypos += 4;
- break;
- case 3:
- ypos += 2;
- break;
- }
-
- while (ypos >= height)
- {
- ++pass;
-
- switch (pass)
- {
- case 1:
- ypos = 4;
- break;
- case 2:
- ypos = 2;
- break;
- case 3:
- ypos = 1;
- break;
- default:
- return true;
- }
- }
- }
- else
- {
- ++ypos;
- }
-
- p = pixels + xpos * pixelStride + ypos * stride;
- }
-
- if (ypos >= height)
- break;
- }
-
- image->releasePixelDataReadWrite (pixels);
- return true;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_GIFLoader.cpp *********/
-
- #endif
-
- //==============================================================================
- // some files include lots of library code, so leave them to the end to avoid cluttering
- // up the build for the clean files.
-
- /********* Start of inlined file: juce_GZIPCompressorOutputStream.cpp *********/
-
- namespace zlibNamespace
- {
- #undef OS_CODE
- #undef fdopen
-
- /********* Start of inlined file: zlib.h *********/
- #ifndef ZLIB_H
- #define ZLIB_H
-
- /********* Start of inlined file: zconf.h *********/
- /* @(#) $Id: zconf.h,v 1.1 2007/06/07 17:54:37 jules_rms Exp $ */
-
- #ifndef ZCONF_H
- #define ZCONF_H
-
- // *** Just a few hacks here to make it compile nicely with Juce..
- #define Z_PREFIX 1
- #undef __MACTYPES__
-
- #ifdef _MSC_VER
- #pragma warning (disable : 4131 4127 4244 4267)
- #endif
-
- /*
- * If you *really* need a unique prefix for all types and library functions,
- * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
- */
- #ifdef Z_PREFIX
- # define deflateInit_ z_deflateInit_
- # define deflate z_deflate
- # define deflateEnd z_deflateEnd
- # define inflateInit_ z_inflateInit_
- # define inflate z_inflate
- # define inflateEnd z_inflateEnd
- # define deflateInit2_ z_deflateInit2_
- # define deflateSetDictionary z_deflateSetDictionary
- # define deflateCopy z_deflateCopy
- # define deflateReset z_deflateReset
- # define deflateParams z_deflateParams
- # define deflateBound z_deflateBound
- # define deflatePrime z_deflatePrime
- # define inflateInit2_ z_inflateInit2_
- # define inflateSetDictionary z_inflateSetDictionary
- # define inflateSync z_inflateSync
- # define inflateSyncPoint z_inflateSyncPoint
- # define inflateCopy z_inflateCopy
- # define inflateReset z_inflateReset
- # define inflateBack z_inflateBack
- # define inflateBackEnd z_inflateBackEnd
- # define compress z_compress
- # define compress2 z_compress2
- # define compressBound z_compressBound
- # define uncompress z_uncompress
- # define adler32 z_adler32
- # define crc32 z_crc32
- # define get_crc_table z_get_crc_table
- # define zError z_zError
-
- # define alloc_func z_alloc_func
- # define free_func z_free_func
- # define in_func z_in_func
- # define out_func z_out_func
- # define Byte z_Byte
- # define uInt z_uInt
- # define uLong z_uLong
- # define Bytef z_Bytef
- # define charf z_charf
- # define intf z_intf
- # define uIntf z_uIntf
- # define uLongf z_uLongf
- # define voidpf z_voidpf
- # define voidp z_voidp
- #endif
-
- #if defined(__MSDOS__) && !defined(MSDOS)
- # define MSDOS
- #endif
- #if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
- # define OS2
- #endif
- #if defined(_WINDOWS) && !defined(WINDOWS)
- # define WINDOWS
- #endif
- #if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
- # ifndef WIN32
- # define WIN32
- # endif
- #endif
- #if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
- # if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
- # ifndef SYS16BIT
- # define SYS16BIT
- # endif
- # endif
- #endif
-
- /*
- * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
- * than 64k bytes at a time (needed on systems with 16-bit int).
- */
- #ifdef SYS16BIT
- # define MAXSEG_64K
- #endif
- #ifdef MSDOS
- # define UNALIGNED_OK
- #endif
-
- #ifdef __STDC_VERSION__
- # ifndef STDC
- # define STDC
- # endif
- # if __STDC_VERSION__ >= 199901L
- # ifndef STDC99
- # define STDC99
- # endif
- # endif
- #endif
- #if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
- # define STDC
- #endif
- #if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
- # define STDC
- #endif
- #if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
- # define STDC
- #endif
- #if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
- # define STDC
- #endif
-
- #if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */
- # define STDC
- #endif
-
- #ifndef STDC
- # ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
- # define const /* note: need a more gentle solution here */
- # endif
- #endif
-
- /* Some Mac compilers merge all .h files incorrectly: */
- #if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
- # define NO_DUMMY_DECL
- #endif
-
- /* Maximum value for memLevel in deflateInit2 */
- #ifndef MAX_MEM_LEVEL
- # ifdef MAXSEG_64K
- # define MAX_MEM_LEVEL 8
- # else
- # define MAX_MEM_LEVEL 9
- # endif
- #endif
-
- /* Maximum value for windowBits in deflateInit2 and inflateInit2.
- * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
- * created by gzip. (Files created by minigzip can still be extracted by
- * gzip.)
- */
- #ifndef MAX_WBITS
- # define MAX_WBITS 15 /* 32K LZ77 window */
- #endif
-
- /* The memory requirements for deflate are (in bytes):
- (1 << (windowBits+2)) + (1 << (memLevel+9))
- that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
- plus a few kilobytes for small objects. For example, if you want to reduce
- the default memory requirements from 256K to 128K, compile with
- make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
- Of course this will generally degrade compression (there's no free lunch).
-
- The memory requirements for inflate are (in bytes) 1 << windowBits
- that is, 32K for windowBits=15 (default value) plus a few kilobytes
- for small objects.
- */
-
- /* Type declarations */
-
- #ifndef OF /* function prototypes */
- # ifdef STDC
- # define OF(args) args
- # else
- # define OF(args) ()
- # endif
- #endif
-
- /* The following definitions for FAR are needed only for MSDOS mixed
- * model programming (small or medium model with some far allocations).
- * This was tested only with MSC; for other MSDOS compilers you may have
- * to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
- * just define FAR to be empty.
- */
- #ifdef SYS16BIT
- # if defined(M_I86SM) || defined(M_I86MM)
- /* MSC small or medium model */
- # define SMALL_MEDIUM
- # ifdef _MSC_VER
- # define FAR _far
- # else
- # define FAR far
- # endif
- # endif
- # if (defined(__SMALL__) || defined(__MEDIUM__))
- /* Turbo C small or medium model */
- # define SMALL_MEDIUM
- # ifdef __BORLANDC__
- # define FAR _far
- # else
- # define FAR far
- # endif
- # endif
- #endif
-
- #if defined(WINDOWS) || defined(WIN32)
- /* If building or using zlib as a DLL, define ZLIB_DLL.
- * This is not mandatory, but it offers a little performance increase.
- */
- # ifdef ZLIB_DLL
- # if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
- # ifdef ZLIB_INTERNAL
- # define ZEXTERN extern __declspec(dllexport)
- # else
- # define ZEXTERN extern __declspec(dllimport)
- # endif
- # endif
- # endif /* ZLIB_DLL */
- /* If building or using zlib with the WINAPI/WINAPIV calling convention,
- * define ZLIB_WINAPI.
- * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
- */
- # ifdef ZLIB_WINAPI
- # ifdef FAR
- # undef FAR
- # endif
- # include <windows.h>
- /* No need for _export, use ZLIB.DEF instead. */
- /* For complete Windows compatibility, use WINAPI, not __stdcall. */
- # define ZEXPORT WINAPI
- # ifdef WIN32
- # define ZEXPORTVA WINAPIV
- # else
- # define ZEXPORTVA FAR CDECL
- # endif
- # endif
- #endif
-
- #if defined (__BEOS__)
- # ifdef ZLIB_DLL
- # ifdef ZLIB_INTERNAL
- # define ZEXPORT __declspec(dllexport)
- # define ZEXPORTVA __declspec(dllexport)
- # else
- # define ZEXPORT __declspec(dllimport)
- # define ZEXPORTVA __declspec(dllimport)
- # endif
- # endif
- #endif
-
- #ifndef ZEXTERN
- # define ZEXTERN extern
- #endif
- #ifndef ZEXPORT
- # define ZEXPORT
- #endif
- #ifndef ZEXPORTVA
- # define ZEXPORTVA
- #endif
-
- #ifndef FAR
- # define FAR
- #endif
-
- #if !defined(__MACTYPES__)
- typedef unsigned char Byte; /* 8 bits */
- #endif
- typedef unsigned int uInt; /* 16 bits or more */
- typedef unsigned long uLong; /* 32 bits or more */
-
- #ifdef SMALL_MEDIUM
- /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
- # define Bytef Byte FAR
- #else
- typedef Byte FAR Bytef;
- #endif
- typedef char FAR charf;
- typedef int FAR intf;
- typedef uInt FAR uIntf;
- typedef uLong FAR uLongf;
-
- #ifdef STDC
- typedef void const *voidpc;
- typedef void FAR *voidpf;
- typedef void *voidp;
- #else
- typedef Byte const *voidpc;
- typedef Byte FAR *voidpf;
- typedef Byte *voidp;
- #endif
-
- #if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */
- # include <sys/types.h> /* for off_t */
- # include <unistd.h> /* for SEEK_* and off_t */
- # ifdef VMS
- # include <unixio.h> /* for off_t */
- # endif
- # define z_off_t off_t
- #endif
- #ifndef SEEK_SET
- # define SEEK_SET 0 /* Seek from beginning of file. */
- # define SEEK_CUR 1 /* Seek from current position. */
- # define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
- #endif
- #ifndef z_off_t
- # define z_off_t long
- #endif
-
- #if defined(__OS400__)
- # define NO_vsnprintf
- #endif
-
- #if defined(__MVS__)
- # define NO_vsnprintf
- # ifdef FAR
- # undef FAR
- # endif
- #endif
-
- /* MVS linker does not support external names larger than 8 bytes */
- #if defined(__MVS__)
- # pragma map(deflateInit_,"DEIN")
- # pragma map(deflateInit2_,"DEIN2")
- # pragma map(deflateEnd,"DEEND")
- # pragma map(deflateBound,"DEBND")
- # pragma map(inflateInit_,"ININ")
- # pragma map(inflateInit2_,"ININ2")
- # pragma map(inflateEnd,"INEND")
- # pragma map(inflateSync,"INSY")
- # pragma map(inflateSetDictionary,"INSEDI")
- # pragma map(compressBound,"CMBND")
- # pragma map(inflate_table,"INTABL")
- # pragma map(inflate_fast,"INFA")
- # pragma map(inflate_copyright,"INCOPY")
- #endif
-
- #endif /* ZCONF_H */
- /********* End of inlined file: zconf.h *********/
-
- #ifdef __cplusplus
- extern "C" {
- #endif
-
- #define ZLIB_VERSION "1.2.3"
- #define ZLIB_VERNUM 0x1230
-
- /*
- The 'zlib' compression library provides in-memory compression and
- decompression functions, including integrity checks of the uncompressed
- data. This version of the library supports only one compression method
- (deflation) but other algorithms will be added later and will have the same
- stream interface.
-
- Compression can be done in a single step if the buffers are large
- enough (for example if an input file is mmap'ed), or can be done by
- repeated calls of the compression function. In the latter case, the
- application must provide more input and/or consume the output
- (providing more output space) before each call.
-
- The compressed data format used by default by the in-memory functions is
- the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped
- around a deflate stream, which is itself documented in RFC 1951.
-
- The library also supports reading and writing files in gzip (.gz) format
- with an interface similar to that of stdio using the functions that start
- with "gz". The gzip format is different from the zlib format. gzip is a
- gzip wrapper, documented in RFC 1952, wrapped around a deflate stream.
-
- This library can optionally read and write gzip streams in memory as well.
-
- The zlib format was designed to be compact and fast for use in memory
- and on communications channels. The gzip format was designed for single-
- file compression on file systems, has a larger header than zlib to maintain
- directory information, and uses a different, slower check method than zlib.
-
- The library does not install any signal handler. The decoder checks
- the consistency of the compressed data, so the library should never
- crash even in case of corrupted input.
- */
-
- typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
- typedef void (*free_func) OF((voidpf opaque, voidpf address));
-
- struct internal_state;
-
- typedef struct z_stream_s {
- Bytef *next_in; /* next input byte */
- uInt avail_in; /* number of bytes available at next_in */
- uLong total_in; /* total nb of input bytes read so far */
-
- Bytef *next_out; /* next output byte should be put there */
- uInt avail_out; /* remaining free space at next_out */
- uLong total_out; /* total nb of bytes output so far */
-
- char *msg; /* last error message, NULL if no error */
- struct internal_state FAR *state; /* not visible by applications */
-
- alloc_func zalloc; /* used to allocate the internal state */
- free_func zfree; /* used to free the internal state */
- voidpf opaque; /* private data object passed to zalloc and zfree */
-
- int data_type; /* best guess about the data type: binary or text */
- uLong adler; /* adler32 value of the uncompressed data */
- uLong reserved; /* reserved for future use */
- } z_stream;
-
- typedef z_stream FAR *z_streamp;
-
- /*
- gzip header information passed to and from zlib routines. See RFC 1952
- for more details on the meanings of these fields.
- */
- typedef struct gz_header_s {
- int text; /* true if compressed data believed to be text */
- uLong time; /* modification time */
- int xflags; /* extra flags (not used when writing a gzip file) */
- int os; /* operating system */
- Bytef *extra; /* pointer to extra field or Z_NULL if none */
- uInt extra_len; /* extra field length (valid if extra != Z_NULL) */
- uInt extra_max; /* space at extra (only when reading header) */
- Bytef *name; /* pointer to zero-terminated file name or Z_NULL */
- uInt name_max; /* space at name (only when reading header) */
- Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */
- uInt comm_max; /* space at comment (only when reading header) */
- int hcrc; /* true if there was or will be a header crc */
- int done; /* true when done reading gzip header (not used
- when writing a gzip file) */
- } gz_header;
-
- typedef gz_header FAR *gz_headerp;
-
- /*
- The application must update next_in and avail_in when avail_in has
- dropped to zero. It must update next_out and avail_out when avail_out
- has dropped to zero. The application must initialize zalloc, zfree and
- opaque before calling the init function. All other fields are set by the
- compression library and must not be updated by the application.
-
- The opaque value provided by the application will be passed as the first
- parameter for calls of zalloc and zfree. This can be useful for custom
- memory management. The compression library attaches no meaning to the
- opaque value.
-
- zalloc must return Z_NULL if there is not enough memory for the object.
- If zlib is used in a multi-threaded application, zalloc and zfree must be
- thread safe.
-
- On 16-bit systems, the functions zalloc and zfree must be able to allocate
- exactly 65536 bytes, but will not be required to allocate more than this
- if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS,
- pointers returned by zalloc for objects of exactly 65536 bytes *must*
- have their offset normalized to zero. The default allocation function
- provided by this library ensures this (see zutil.c). To reduce memory
- requirements and avoid any allocation of 64K objects, at the expense of
- compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h).
-
- The fields total_in and total_out can be used for statistics or
- progress reports. After compression, total_in holds the total size of
- the uncompressed data and may be saved for use in the decompressor
- (particularly if the decompressor wants to decompress everything in
- a single step).
- */
-
- /* constants */
-
- #define Z_NO_FLUSH 0
- #define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */
- #define Z_SYNC_FLUSH 2
- #define Z_FULL_FLUSH 3
- #define Z_FINISH 4
- #define Z_BLOCK 5
- /* Allowed flush values; see deflate() and inflate() below for details */
-
- #define Z_OK 0
- #define Z_STREAM_END 1
- #define Z_NEED_DICT 2
- #define Z_ERRNO (-1)
- #define Z_STREAM_ERROR (-2)
- #define Z_DATA_ERROR (-3)
- #define Z_MEM_ERROR (-4)
- #define Z_BUF_ERROR (-5)
- #define Z_VERSION_ERROR (-6)
- /* Return codes for the compression/decompression functions. Negative
- * values are errors, positive values are used for special but normal events.
- */
-
- #define Z_NO_COMPRESSION 0
- #define Z_BEST_SPEED 1
- #define Z_BEST_COMPRESSION 9
- #define Z_DEFAULT_COMPRESSION (-1)
- /* compression levels */
-
- #define Z_FILTERED 1
- #define Z_HUFFMAN_ONLY 2
- #define Z_RLE 3
- #define Z_FIXED 4
- #define Z_DEFAULT_STRATEGY 0
- /* compression strategy; see deflateInit2() below for details */
-
- #define Z_BINARY 0
- #define Z_TEXT 1
- #define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */
- #define Z_UNKNOWN 2
- /* Possible values of the data_type field (though see inflate()) */
-
- #define Z_DEFLATED 8
- /* The deflate compression method (the only one supported in this version) */
-
- #define Z_NULL 0 /* for initializing zalloc, zfree, opaque */
-
- #define zlib_version zlibVersion()
- /* for compatibility with versions < 1.0.2 */
-
- /* basic functions */
-
- //ZEXTERN const char * ZEXPORT zlibVersion OF((void));
- /* The application can compare zlibVersion and ZLIB_VERSION for consistency.
- If the first character differs, the library code actually used is
- not compatible with the zlib.h header file used by the application.
- This check is automatically made by deflateInit and inflateInit.
- */
-
- /*
- ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
-
- Initializes the internal stream state for compression. The fields
- zalloc, zfree and opaque must be initialized before by the caller.
- If zalloc and zfree are set to Z_NULL, deflateInit updates them to
- use default allocation functions.
-
- The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
- 1 gives best speed, 9 gives best compression, 0 gives no compression at
- all (the input data is simply copied a block at a time).
- Z_DEFAULT_COMPRESSION requests a default compromise between speed and
- compression (currently equivalent to level 6).
-
- deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
- enough memory, Z_STREAM_ERROR if level is not a valid compression level,
- Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible
- with the version assumed by the caller (ZLIB_VERSION).
- msg is set to null if there is no error message. deflateInit does not
- perform any compression: this will be done by deflate().
- */
-
- ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
- /*
- deflate compresses as much data as possible, and stops when the input
- buffer becomes empty or the output buffer becomes full. It may introduce some
- output latency (reading input without producing any output) except when
- forced to flush.
-
- The detailed semantics are as follows. deflate performs one or both of the
- following actions:
-
- - Compress more input starting at next_in and update next_in and avail_in
- accordingly. If not all input can be processed (because there is not
- enough room in the output buffer), next_in and avail_in are updated and
- processing will resume at this point for the next call of deflate().
-
- - Provide more output starting at next_out and update next_out and avail_out
- accordingly. This action is forced if the parameter flush is non zero.
- Forcing flush frequently degrades the compression ratio, so this parameter
- should be set only when necessary (in interactive applications).
- Some output may be provided even if flush is not set.
-
- Before the call of deflate(), the application should ensure that at least
- one of the actions is possible, by providing more input and/or consuming
- more output, and updating avail_in or avail_out accordingly; avail_out
- should never be zero before the call. The application can consume the
- compressed output when it wants, for example when the output buffer is full
- (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK
- and with zero avail_out, it must be called again after making room in the
- output buffer because there might be more output pending.
-
- Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to
- decide how much data to accumualte before producing output, in order to
- maximize compression.
-
- If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
- flushed to the output buffer and the output is aligned on a byte boundary, so
- that the decompressor can get all input data available so far. (In particular
- avail_in is zero after the call if enough output space has been provided
- before the call.) Flushing may degrade compression for some compression
- algorithms and so it should be used only when necessary.
-
- If flush is set to Z_FULL_FLUSH, all output is flushed as with
- Z_SYNC_FLUSH, and the compression state is reset so that decompression can
- restart from this point if previous compressed data has been damaged or if
- random access is desired. Using Z_FULL_FLUSH too often can seriously degrade
- compression.
-
- If deflate returns with avail_out == 0, this function must be called again
- with the same value of the flush parameter and more output space (updated
- avail_out), until the flush is complete (deflate returns with non-zero
- avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that
- avail_out is greater than six to avoid repeated flush markers due to
- avail_out == 0 on return.
-
- If the parameter flush is set to Z_FINISH, pending input is processed,
- pending output is flushed and deflate returns with Z_STREAM_END if there
- was enough output space; if deflate returns with Z_OK, this function must be
- called again with Z_FINISH and more output space (updated avail_out) but no
- more input data, until it returns with Z_STREAM_END or an error. After
- deflate has returned Z_STREAM_END, the only possible operations on the
- stream are deflateReset or deflateEnd.
-
- Z_FINISH can be used immediately after deflateInit if all the compression
- is to be done in a single step. In this case, avail_out must be at least
- the value returned by deflateBound (see below). If deflate does not return
- Z_STREAM_END, then it must be called again as described above.
-
- deflate() sets strm->adler to the adler32 checksum of all input read
- so far (that is, total_in bytes).
-
- deflate() may update strm->data_type if it can make a good guess about
- the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered
- binary. This field is only for information purposes and does not affect
- the compression algorithm in any manner.
-
- deflate() returns Z_OK if some progress has been made (more input
- processed or more output produced), Z_STREAM_END if all input has been
- consumed and all output has been produced (only when flush is set to
- Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
- if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible
- (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not
- fatal, and deflate() can be called again with more input and more output
- space to continue compressing.
- */
-
- ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
- /*
- All dynamically allocated data structures for this stream are freed.
- This function discards any unprocessed input and does not flush any
- pending output.
-
- deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
- stream state was inconsistent, Z_DATA_ERROR if the stream was freed
- prematurely (some input or output was discarded). In the error case,
- msg may be set but then points to a static string (which must not be
- deallocated).
- */
-
- /*
- ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
-
- Initializes the internal stream state for decompression. The fields
- next_in, avail_in, zalloc, zfree and opaque must be initialized before by
- the caller. If next_in is not Z_NULL and avail_in is large enough (the exact
- value depends on the compression method), inflateInit determines the
- compression method from the zlib header and allocates all data structures
- accordingly; otherwise the allocation will be deferred to the first call of
- inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to
- use default allocation functions.
-
- inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
- memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
- version assumed by the caller. msg is set to null if there is no error
- message. inflateInit does not perform any decompression apart from reading
- the zlib header if present: this will be done by inflate(). (So next_in and
- avail_in may be modified, but next_out and avail_out are unchanged.)
- */
-
- ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
- /*
- inflate decompresses as much data as possible, and stops when the input
- buffer becomes empty or the output buffer becomes full. It may introduce
- some output latency (reading input without producing any output) except when
- forced to flush.
-
- The detailed semantics are as follows. inflate performs one or both of the
- following actions:
-
- - Decompress more input starting at next_in and update next_in and avail_in
- accordingly. If not all input can be processed (because there is not
- enough room in the output buffer), next_in is updated and processing
- will resume at this point for the next call of inflate().
-
- - Provide more output starting at next_out and update next_out and avail_out
- accordingly. inflate() provides as much output as possible, until there
- is no more input data or no more space in the output buffer (see below
- about the flush parameter).
-
- Before the call of inflate(), the application should ensure that at least
- one of the actions is possible, by providing more input and/or consuming
- more output, and updating the next_* and avail_* values accordingly.
- The application can consume the uncompressed output when it wants, for
- example when the output buffer is full (avail_out == 0), or after each
- call of inflate(). If inflate returns Z_OK and with zero avail_out, it
- must be called again after making room in the output buffer because there
- might be more output pending.
-
- The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH,
- Z_FINISH, or Z_BLOCK. Z_SYNC_FLUSH requests that inflate() flush as much
- output as possible to the output buffer. Z_BLOCK requests that inflate() stop
- if and when it gets to the next deflate block boundary. When decoding the
- zlib or gzip format, this will cause inflate() to return immediately after
- the header and before the first block. When doing a raw inflate, inflate()
- will go ahead and process the first block, and will return when it gets to
- the end of that block, or when it runs out of data.
-
- The Z_BLOCK option assists in appending to or combining deflate streams.
- Also to assist in this, on return inflate() will set strm->data_type to the
- number of unused bits in the last byte taken from strm->next_in, plus 64
- if inflate() is currently decoding the last block in the deflate stream,
- plus 128 if inflate() returned immediately after decoding an end-of-block
- code or decoding the complete header up to just before the first byte of the
- deflate stream. The end-of-block will not be indicated until all of the
- uncompressed data from that block has been written to strm->next_out. The
- number of unused bits may in general be greater than seven, except when
- bit 7 of data_type is set, in which case the number of unused bits will be
- less than eight.
-
- inflate() should normally be called until it returns Z_STREAM_END or an
- error. However if all decompression is to be performed in a single step
- (a single call of inflate), the parameter flush should be set to
- Z_FINISH. In this case all pending input is processed and all pending
- output is flushed; avail_out must be large enough to hold all the
- uncompressed data. (The size of the uncompressed data may have been saved
- by the compressor for this purpose.) The next operation on this stream must
- be inflateEnd to deallocate the decompression state. The use of Z_FINISH
- is never required, but can be used to inform inflate that a faster approach
- may be used for the single inflate() call.
-
- In this implementation, inflate() always flushes as much output as
- possible to the output buffer, and always uses the faster approach on the
- first call. So the only effect of the flush parameter in this implementation
- is on the return value of inflate(), as noted below, or when it returns early
- because Z_BLOCK is used.
-
- If a preset dictionary is needed after this call (see inflateSetDictionary
- below), inflate sets strm->adler to the adler32 checksum of the dictionary
- chosen by the compressor and returns Z_NEED_DICT; otherwise it sets
- strm->adler to the adler32 checksum of all output produced so far (that is,
- total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described
- below. At the end of the stream, inflate() checks that its computed adler32
- checksum is equal to that saved by the compressor and returns Z_STREAM_END
- only if the checksum is correct.
-
- inflate() will decompress and check either zlib-wrapped or gzip-wrapped
- deflate data. The header type is detected automatically. Any information
- contained in the gzip header is not retained, so applications that need that
- information should instead use raw inflate, see inflateInit2() below, or
- inflateBack() and perform their own processing of the gzip header and
- trailer.
-
- inflate() returns Z_OK if some progress has been made (more input processed
- or more output produced), Z_STREAM_END if the end of the compressed data has
- been reached and all uncompressed output has been produced, Z_NEED_DICT if a
- preset dictionary is needed at this point, Z_DATA_ERROR if the input data was
- corrupted (input stream not conforming to the zlib format or incorrect check
- value), Z_STREAM_ERROR if the stream structure was inconsistent (for example
- if next_in or next_out was NULL), Z_MEM_ERROR if there was not enough memory,
- Z_BUF_ERROR if no progress is possible or if there was not enough room in the
- output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and
- inflate() can be called again with more input and more output space to
- continue decompressing. If Z_DATA_ERROR is returned, the application may then
- call inflateSync() to look for a good compression block if a partial recovery
- of the data is desired.
- */
-
- ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));
- /*
- All dynamically allocated data structures for this stream are freed.
- This function discards any unprocessed input and does not flush any
- pending output.
-
- inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
- was inconsistent. In the error case, msg may be set but then points to a
- static string (which must not be deallocated).
- */
-
- /* Advanced functions */
-
- /*
- The following functions are needed only in some special applications.
- */
-
- /*
- ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
- int level,
- int method,
- int windowBits,
- int memLevel,
- int strategy));
-
- This is another version of deflateInit with more compression options. The
- fields next_in, zalloc, zfree and opaque must be initialized before by
- the caller.
-
- The method parameter is the compression method. It must be Z_DEFLATED in
- this version of the library.
-
- The windowBits parameter is the base two logarithm of the window size
- (the size of the history buffer). It should be in the range 8..15 for this
- version of the library. Larger values of this parameter result in better
- compression at the expense of memory usage. The default value is 15 if
- deflateInit is used instead.
-
- windowBits can also be -8..-15 for raw deflate. In this case, -windowBits
- determines the window size. deflate() will then generate raw deflate data
- with no zlib header or trailer, and will not compute an adler32 check value.
-
- windowBits can also be greater than 15 for optional gzip encoding. Add
- 16 to windowBits to write a simple gzip header and trailer around the
- compressed data instead of a zlib wrapper. The gzip header will have no
- file name, no extra data, no comment, no modification time (set to zero),
- no header crc, and the operating system will be set to 255 (unknown). If a
- gzip stream is being written, strm->adler is a crc32 instead of an adler32.
-
- The memLevel parameter specifies how much memory should be allocated
- for the internal compression state. memLevel=1 uses minimum memory but
- is slow and reduces compression ratio; memLevel=9 uses maximum memory
- for optimal speed. The default value is 8. See zconf.h for total memory
- usage as a function of windowBits and memLevel.
-
- The strategy parameter is used to tune the compression algorithm. Use the
- value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
- filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no
- string match), or Z_RLE to limit match distances to one (run-length
- encoding). Filtered data consists mostly of small values with a somewhat
- random distribution. In this case, the compression algorithm is tuned to
- compress them better. The effect of Z_FILTERED is to force more Huffman
- coding and less string matching; it is somewhat intermediate between
- Z_DEFAULT and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as fast as
- Z_HUFFMAN_ONLY, but give better compression for PNG image data. The strategy
- parameter only affects the compression ratio but not the correctness of the
- compressed output even if it is not set appropriately. Z_FIXED prevents the
- use of dynamic Huffman codes, allowing for a simpler decoder for special
- applications.
-
- deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
- memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid
- method). msg is set to null if there is no error message. deflateInit2 does
- not perform any compression: this will be done by deflate().
- */
-
- ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
- const Bytef *dictionary,
- uInt dictLength));
- /*
- Initializes the compression dictionary from the given byte sequence
- without producing any compressed output. This function must be called
- immediately after deflateInit, deflateInit2 or deflateReset, before any
- call of deflate. The compressor and decompressor must use exactly the same
- dictionary (see inflateSetDictionary).
-
- The dictionary should consist of strings (byte sequences) that are likely
- to be encountered later in the data to be compressed, with the most commonly
- used strings preferably put towards the end of the dictionary. Using a
- dictionary is most useful when the data to be compressed is short and can be
- predicted with good accuracy; the data can then be compressed better than
- with the default empty dictionary.
-
- Depending on the size of the compression data structures selected by
- deflateInit or deflateInit2, a part of the dictionary may in effect be
- discarded, for example if the dictionary is larger than the window size in
- deflate or deflate2. Thus the strings most likely to be useful should be
- put at the end of the dictionary, not at the front. In addition, the
- current implementation of deflate will use at most the window size minus
- 262 bytes of the provided dictionary.
-
- Upon return of this function, strm->adler is set to the adler32 value
- of the dictionary; the decompressor may later use this value to determine
- which dictionary has been used by the compressor. (The adler32 value
- applies to the whole dictionary even if only a subset of the dictionary is
- actually used by the compressor.) If a raw deflate was requested, then the
- adler32 value is not computed and strm->adler is not set.
-
- deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
- parameter is invalid (such as NULL dictionary) or the stream state is
- inconsistent (for example if deflate has already been called for this stream
- or if the compression method is bsort). deflateSetDictionary does not
- perform any compression: this will be done by deflate().
- */
-
- ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
- z_streamp source));
- /*
- Sets the destination stream as a complete copy of the source stream.
-
- This function can be useful when several compression strategies will be
- tried, for example when there are several ways of pre-processing the input
- data with a filter. The streams that will be discarded should then be freed
- by calling deflateEnd. Note that deflateCopy duplicates the internal
- compression state which can be quite large, so this strategy is slow and
- can consume lots of memory.
-
- deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
- enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
- (such as zalloc being NULL). msg is left unchanged in both source and
- destination.
- */
-
- ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm));
- /*
- This function is equivalent to deflateEnd followed by deflateInit,
- but does not free and reallocate all the internal compression state.
- The stream will keep the same compression level and any other attributes
- that may have been set by deflateInit2.
-
- deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
- stream state was inconsistent (such as zalloc or state being NULL).
- */
-
- ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
- int level,
- int strategy));
- /*
- Dynamically update the compression level and compression strategy. The
- interpretation of level and strategy is as in deflateInit2. This can be
- used to switch between compression and straight copy of the input data, or
- to switch to a different kind of input data requiring a different
- strategy. If the compression level is changed, the input available so far
- is compressed with the old level (and may be flushed); the new level will
- take effect only at the next call of deflate().
-
- Before the call of deflateParams, the stream state must be set as for
- a call of deflate(), since the currently available input may have to
- be compressed and flushed. In particular, strm->avail_out must be non-zero.
-
- deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source
- stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR
- if strm->avail_out was zero.
- */
-
- ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm,
- int good_length,
- int max_lazy,
- int nice_length,
- int max_chain));
- /*
- Fine tune deflate's internal compression parameters. This should only be
- used by someone who understands the algorithm used by zlib's deflate for
- searching for the best matching string, and even then only by the most
- fanatic optimizer trying to squeeze out the last compressed bit for their
- specific input data. Read the deflate.c source code for the meaning of the
- max_lazy, good_length, nice_length, and max_chain parameters.
-
- deflateTune() can be called after deflateInit() or deflateInit2(), and
- returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream.
- */
-
- ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm,
- uLong sourceLen));
- /*
- deflateBound() returns an upper bound on the compressed size after
- deflation of sourceLen bytes. It must be called after deflateInit()
- or deflateInit2(). This would be used to allocate an output buffer
- for deflation in a single pass, and so would be called before deflate().
- */
-
- ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm,
- int bits,
- int value));
- /*
- deflatePrime() inserts bits in the deflate output stream. The intent
- is that this function is used to start off the deflate output with the
- bits leftover from a previous deflate stream when appending to it. As such,
- this function can only be used for raw deflate, and must be used before the
- first deflate() call after a deflateInit2() or deflateReset(). bits must be
- less than or equal to 16, and that many of the least significant bits of
- value will be inserted in the output.
-
- deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
- stream state was inconsistent.
- */
-
- ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm,
- gz_headerp head));
- /*
- deflateSetHeader() provides gzip header information for when a gzip
- stream is requested by deflateInit2(). deflateSetHeader() may be called
- after deflateInit2() or deflateReset() and before the first call of
- deflate(). The text, time, os, extra field, name, and comment information
- in the provided gz_header structure are written to the gzip header (xflag is
- ignored -- the extra flags are set according to the compression level). The
- caller must assure that, if not Z_NULL, name and comment are terminated with
- a zero byte, and that if extra is not Z_NULL, that extra_len bytes are
- available there. If hcrc is true, a gzip header crc is included. Note that
- the current versions of the command-line version of gzip (up through version
- 1.3.x) do not support header crc's, and will report that it is a "multi-part
- gzip file" and give up.
-
- If deflateSetHeader is not used, the default gzip header has text false,
- the time set to zero, and os set to 255, with no extra, name, or comment
- fields. The gzip header is returned to the default state by deflateReset().
-
- deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
- stream state was inconsistent.
- */
-
- /*
- ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
- int windowBits));
-
- This is another version of inflateInit with an extra parameter. The
- fields next_in, avail_in, zalloc, zfree and opaque must be initialized
- before by the caller.
-
- The windowBits parameter is the base two logarithm of the maximum window
- size (the size of the history buffer). It should be in the range 8..15 for
- this version of the library. The default value is 15 if inflateInit is used
- instead. windowBits must be greater than or equal to the windowBits value
- provided to deflateInit2() while compressing, or it must be equal to 15 if
- deflateInit2() was not used. If a compressed stream with a larger window
- size is given as input, inflate() will return with the error code
- Z_DATA_ERROR instead of trying to allocate a larger window.
-
- windowBits can also be -8..-15 for raw inflate. In this case, -windowBits
- determines the window size. inflate() will then process raw deflate data,
- not looking for a zlib or gzip header, not generating a check value, and not
- looking for any check values for comparison at the end of the stream. This
- is for use with other formats that use the deflate compressed data format
- such as zip. Those formats provide their own check values. If a custom
- format is developed using the raw deflate format for compressed data, it is
- recommended that a check value such as an adler32 or a crc32 be applied to
- the uncompressed data as is done in the zlib, gzip, and zip formats. For
- most applications, the zlib format should be used as is. Note that comments
- above on the use in deflateInit2() applies to the magnitude of windowBits.
-
- windowBits can also be greater than 15 for optional gzip decoding. Add
- 32 to windowBits to enable zlib and gzip decoding with automatic header
- detection, or add 16 to decode only the gzip format (the zlib format will
- return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is
- a crc32 instead of an adler32.
-
- inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
- memory, Z_STREAM_ERROR if a parameter is invalid (such as a null strm). msg
- is set to null if there is no error message. inflateInit2 does not perform
- any decompression apart from reading the zlib header if present: this will
- be done by inflate(). (So next_in and avail_in may be modified, but next_out
- and avail_out are unchanged.)
- */
-
- ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
- const Bytef *dictionary,
- uInt dictLength));
- /*
- Initializes the decompression dictionary from the given uncompressed byte
- sequence. This function must be called immediately after a call of inflate,
- if that call returned Z_NEED_DICT. The dictionary chosen by the compressor
- can be determined from the adler32 value returned by that call of inflate.
- The compressor and decompressor must use exactly the same dictionary (see
- deflateSetDictionary). For raw inflate, this function can be called
- immediately after inflateInit2() or inflateReset() and before any call of
- inflate() to set the dictionary. The application must insure that the
- dictionary that was used for compression is provided.
-
- inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
- parameter is invalid (such as NULL dictionary) or the stream state is
- inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
- expected one (incorrect adler32 value). inflateSetDictionary does not
- perform any decompression: this will be done by subsequent calls of
- inflate().
- */
-
- ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
- /*
- Skips invalid compressed data until a full flush point (see above the
- description of deflate with Z_FULL_FLUSH) can be found, or until all
- available input is skipped. No output is provided.
-
- inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR
- if no more input was provided, Z_DATA_ERROR if no flush point has been found,
- or Z_STREAM_ERROR if the stream structure was inconsistent. In the success
- case, the application may save the current current value of total_in which
- indicates where valid compressed data was found. In the error case, the
- application may repeatedly call inflateSync, providing more input each time,
- until success or end of the input data.
- */
-
- ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest,
- z_streamp source));
- /*
- Sets the destination stream as a complete copy of the source stream.
-
- This function can be useful when randomly accessing a large stream. The
- first pass through the stream can periodically record the inflate state,
- allowing restarting inflate at those points when randomly accessing the
- stream.
-
- inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
- enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
- (such as zalloc being NULL). msg is left unchanged in both source and
- destination.
- */
-
- ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
- /*
- This function is equivalent to inflateEnd followed by inflateInit,
- but does not free and reallocate all the internal decompression state.
- The stream will keep attributes that may have been set by inflateInit2.
-
- inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
- stream state was inconsistent (such as zalloc or state being NULL).
- */
-
- ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm,
- int bits,
- int value));
- /*
- This function inserts bits in the inflate input stream. The intent is
- that this function is used to start inflating at a bit position in the
- middle of a byte. The provided bits will be used before any bytes are used
- from next_in. This function should only be used with raw inflate, and
- should be used before the first inflate() call after inflateInit2() or
- inflateReset(). bits must be less than or equal to 16, and that many of the
- least significant bits of value will be inserted in the input.
-
- inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
- stream state was inconsistent.
- */
-
- ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm,
- gz_headerp head));
- /*
- inflateGetHeader() requests that gzip header information be stored in the
- provided gz_header structure. inflateGetHeader() may be called after
- inflateInit2() or inflateReset(), and before the first call of inflate().
- As inflate() processes the gzip stream, head->done is zero until the header
- is completed, at which time head->done is set to one. If a zlib stream is
- being decoded, then head->done is set to -1 to indicate that there will be
- no gzip header information forthcoming. Note that Z_BLOCK can be used to
- force inflate() to return immediately after header processing is complete
- and before any actual data is decompressed.
-
- The text, time, xflags, and os fields are filled in with the gzip header
- contents. hcrc is set to true if there is a header CRC. (The header CRC
- was valid if done is set to one.) If extra is not Z_NULL, then extra_max
- contains the maximum number of bytes to write to extra. Once done is true,
- extra_len contains the actual extra field length, and extra contains the
- extra field, or that field truncated if extra_max is less than extra_len.
- If name is not Z_NULL, then up to name_max characters are written there,
- terminated with a zero unless the length is greater than name_max. If
- comment is not Z_NULL, then up to comm_max characters are written there,
- terminated with a zero unless the length is greater than comm_max. When
- any of extra, name, or comment are not Z_NULL and the respective field is
- not present in the header, then that field is set to Z_NULL to signal its
- absence. This allows the use of deflateSetHeader() with the returned
- structure to duplicate the header. However if those fields are set to
- allocated memory, then the application will need to save those pointers
- elsewhere so that they can be eventually freed.
-
- If inflateGetHeader is not used, then the header information is simply
- discarded. The header is always checked for validity, including the header
- CRC if present. inflateReset() will reset the process to discard the header
- information. The application would need to call inflateGetHeader() again to
- retrieve the header from the next gzip stream.
-
- inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
- stream state was inconsistent.
- */
-
- /*
- ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits,
- unsigned char FAR *window));
-
- Initialize the internal stream state for decompression using inflateBack()
- calls. The fields zalloc, zfree and opaque in strm must be initialized
- before the call. If zalloc and zfree are Z_NULL, then the default library-
- derived memory allocation routines are used. windowBits is the base two
- logarithm of the window size, in the range 8..15. window is a caller
- supplied buffer of that size. Except for special applications where it is
- assured that deflate was used with small window sizes, windowBits must be 15
- and a 32K byte window must be supplied to be able to decompress general
- deflate streams.
-
- See inflateBack() for the usage of these routines.
-
- inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of
- the paramaters are invalid, Z_MEM_ERROR if the internal state could not
- be allocated, or Z_VERSION_ERROR if the version of the library does not
- match the version of the header file.
- */
-
- typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *));
- typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned));
-
- ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm,
- in_func in, void FAR *in_desc,
- out_func out, void FAR *out_desc));
- /*
- inflateBack() does a raw inflate with a single call using a call-back
- interface for input and output. This is more efficient than inflate() for
- file i/o applications in that it avoids copying between the output and the
- sliding window by simply making the window itself the output buffer. This
- function trusts the application to not change the output buffer passed by
- the output function, at least until inflateBack() returns.
-
- inflateBackInit() must be called first to allocate the internal state
- and to initialize the state with the user-provided window buffer.
- inflateBack() may then be used multiple times to inflate a complete, raw
- deflate stream with each call. inflateBackEnd() is then called to free
- the allocated state.
-
- A raw deflate stream is one with no zlib or gzip header or trailer.
- This routine would normally be used in a utility that reads zip or gzip
- files and writes out uncompressed files. The utility would decode the
- header and process the trailer on its own, hence this routine expects
- only the raw deflate stream to decompress. This is different from the
- normal behavior of inflate(), which expects either a zlib or gzip header and
- trailer around the deflate stream.
-
- inflateBack() uses two subroutines supplied by the caller that are then
- called by inflateBack() for input and output. inflateBack() calls those
- routines until it reads a complete deflate stream and writes out all of the
- uncompressed data, or until it encounters an error. The function's
- parameters and return types are defined above in the in_func and out_func
- typedefs. inflateBack() will call in(in_desc, &buf) which should return the
- number of bytes of provided input, and a pointer to that input in buf. If
- there is no input available, in() must return zero--buf is ignored in that
- case--and inflateBack() will return a buffer error. inflateBack() will call
- out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out()
- should return zero on success, or non-zero on failure. If out() returns
- non-zero, inflateBack() will return with an error. Neither in() nor out()
- are permitted to change the contents of the window provided to
- inflateBackInit(), which is also the buffer that out() uses to write from.
- The length written by out() will be at most the window size. Any non-zero
- amount of input may be provided by in().
-
- For convenience, inflateBack() can be provided input on the first call by
- setting strm->next_in and strm->avail_in. If that input is exhausted, then
- in() will be called. Therefore strm->next_in must be initialized before
- calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called
- immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in
- must also be initialized, and then if strm->avail_in is not zero, input will
- initially be taken from strm->next_in[0 .. strm->avail_in - 1].
-
- The in_desc and out_desc parameters of inflateBack() is passed as the
- first parameter of in() and out() respectively when they are called. These
- descriptors can be optionally used to pass any information that the caller-
- supplied in() and out() functions need to do their job.
-
- On return, inflateBack() will set strm->next_in and strm->avail_in to
- pass back any unused input that was provided by the last in() call. The
- return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR
- if in() or out() returned an error, Z_DATA_ERROR if there was a format
- error in the deflate stream (in which case strm->msg is set to indicate the
- nature of the error), or Z_STREAM_ERROR if the stream was not properly
- initialized. In the case of Z_BUF_ERROR, an input or output error can be
- distinguished using strm->next_in which will be Z_NULL only if in() returned
- an error. If strm->next is not Z_NULL, then the Z_BUF_ERROR was due to
- out() returning non-zero. (in() will always be called before out(), so
- strm->next_in is assured to be defined if out() returns non-zero.) Note
- that inflateBack() cannot return Z_OK.
- */
-
- ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm));
- /*
- All memory allocated by inflateBackInit() is freed.
-
- inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream
- state was inconsistent.
- */
-
- //ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void));
- /* Return flags indicating compile-time options.
-
- Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other:
- 1.0: size of uInt
- 3.2: size of uLong
- 5.4: size of voidpf (pointer)
- 7.6: size of z_off_t
-
- Compiler, assembler, and debug options:
- 8: DEBUG
- 9: ASMV or ASMINF -- use ASM code
- 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention
- 11: 0 (reserved)
-
- One-time table building (smaller code, but not thread-safe if true):
- 12: BUILDFIXED -- build static block decoding tables when needed
- 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed
- 14,15: 0 (reserved)
-
- Library content (indicates missing functionality):
- 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking
- deflate code when not needed)
- 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect
- and decode gzip streams (to avoid linking crc code)
- 18-19: 0 (reserved)
-
- Operation variations (changes in library functionality):
- 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate
- 21: FASTEST -- deflate algorithm with only one, lowest compression level
- 22,23: 0 (reserved)
-
- The sprintf variant used by gzprintf (zero is best):
- 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format
- 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure!
- 26: 0 = returns value, 1 = void -- 1 means inferred string length returned
-
- Remainder:
- 27-31: 0 (reserved)
- */
-
- /* utility functions */
-
- /*
- The following utility functions are implemented on top of the
- basic stream-oriented functions. To simplify the interface, some
- default options are assumed (compression level and memory usage,
- standard memory allocation functions). The source code of these
- utility functions can easily be modified if you need special options.
- */
-
- ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen,
- const Bytef *source, uLong sourceLen));
- /*
- Compresses the source buffer into the destination buffer. sourceLen is
- the byte length of the source buffer. Upon entry, destLen is the total
- size of the destination buffer, which must be at least the value returned
- by compressBound(sourceLen). Upon exit, destLen is the actual size of the
- compressed buffer.
- This function can be used to compress a whole file at once if the
- input file is mmap'ed.
- compress returns Z_OK if success, Z_MEM_ERROR if there was not
- enough memory, Z_BUF_ERROR if there was not enough room in the output
- buffer.
- */
-
- ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen,
- const Bytef *source, uLong sourceLen,
- int level));
- /*
- Compresses the source buffer into the destination buffer. The level
- parameter has the same meaning as in deflateInit. sourceLen is the byte
- length of the source buffer. Upon entry, destLen is the total size of the
- destination buffer, which must be at least the value returned by
- compressBound(sourceLen). Upon exit, destLen is the actual size of the
- compressed buffer.
-
- compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
- memory, Z_BUF_ERROR if there was not enough room in the output buffer,
- Z_STREAM_ERROR if the level parameter is invalid.
- */
-
- ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen));
- /*
- compressBound() returns an upper bound on the compressed size after
- compress() or compress2() on sourceLen bytes. It would be used before
- a compress() or compress2() call to allocate the destination buffer.
- */
-
- ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen,
- const Bytef *source, uLong sourceLen));
- /*
- Decompresses the source buffer into the destination buffer. sourceLen is
- the byte length of the source buffer. Upon entry, destLen is the total
- size of the destination buffer, which must be large enough to hold the
- entire uncompressed data. (The size of the uncompressed data must have
- been saved previously by the compressor and transmitted to the decompressor
- by some mechanism outside the scope of this compression library.)
- Upon exit, destLen is the actual size of the compressed buffer.
- This function can be used to decompress a whole file at once if the
- input file is mmap'ed.
-
- uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
- enough memory, Z_BUF_ERROR if there was not enough room in the output
- buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete.
- */
-
- typedef voidp gzFile;
-
- ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
- /*
- Opens a gzip (.gz) file for reading or writing. The mode parameter
- is as in fopen ("rb" or "wb") but can also include a compression level
- ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for
- Huffman only compression as in "wb1h", or 'R' for run-length encoding
- as in "wb1R". (See the description of deflateInit2 for more information
- about the strategy parameter.)
-
- gzopen can be used to read a file which is not in gzip format; in this
- case gzread will directly read from the file without decompression.
-
- gzopen returns NULL if the file could not be opened or if there was
- insufficient memory to allocate the (de)compression state; errno
- can be checked to distinguish the two cases (if errno is zero, the
- zlib error is Z_MEM_ERROR). */
-
- ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode));
- /*
- gzdopen() associates a gzFile with the file descriptor fd. File
- descriptors are obtained from calls like open, dup, creat, pipe or
- fileno (in the file has been previously opened with fopen).
- The mode parameter is as in gzopen.
- The next call of gzclose on the returned gzFile will also close the
- file descriptor fd, just like fclose(fdopen(fd), mode) closes the file
- descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode).
- gzdopen returns NULL if there was insufficient memory to allocate
- the (de)compression state.
- */
-
- ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
- /*
- Dynamically update the compression level or strategy. See the description
- of deflateInit2 for the meaning of these parameters.
- gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not
- opened for writing.
- */
-
- ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
- /*
- Reads the given number of uncompressed bytes from the compressed file.
- If the input file was not in gzip format, gzread copies the given number
- of bytes into the buffer.
- gzread returns the number of uncompressed bytes actually read (0 for
- end of file, -1 for error). */
-
- ZEXTERN int ZEXPORT gzwrite OF((gzFile file,
- voidpc buf, unsigned len));
- /*
- Writes the given number of uncompressed bytes into the compressed file.
- gzwrite returns the number of uncompressed bytes actually written
- (0 in case of error).
- */
-
- ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...));
- /*
- Converts, formats, and writes the args to the compressed file under
- control of the format string, as in fprintf. gzprintf returns the number of
- uncompressed bytes actually written (0 in case of error). The number of
- uncompressed bytes written is limited to 4095. The caller should assure that
- this limit is not exceeded. If it is exceeded, then gzprintf() will return
- return an error (0) with nothing written. In this case, there may also be a
- buffer overflow with unpredictable consequences, which is possible only if
- zlib was compiled with the insecure functions sprintf() or vsprintf()
- because the secure snprintf() or vsnprintf() functions were not available.
- */
-
- ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s));
- /*
- Writes the given null-terminated string to the compressed file, excluding
- the terminating null character.
- gzputs returns the number of characters written, or -1 in case of error.
- */
-
- ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len));
- /*
- Reads bytes from the compressed file until len-1 characters are read, or
- a newline character is read and transferred to buf, or an end-of-file
- condition is encountered. The string is then terminated with a null
- character.
- gzgets returns buf, or Z_NULL in case of error.
- */
-
- ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c));
- /*
- Writes c, converted to an unsigned char, into the compressed file.
- gzputc returns the value that was written, or -1 in case of error.
- */
-
- ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
- /*
- Reads one byte from the compressed file. gzgetc returns this byte
- or -1 in case of end of file or error.
- */
-
- ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file));
- /*
- Push one character back onto the stream to be read again later.
- Only one character of push-back is allowed. gzungetc() returns the
- character pushed, or -1 on failure. gzungetc() will fail if a
- character has been pushed but not read yet, or if c is -1. The pushed
- character will be discarded if the stream is repositioned with gzseek()
- or gzrewind().
- */
-
- ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush));
- /*
- Flushes all pending output into the compressed file. The parameter
- flush is as in the deflate() function. The return value is the zlib
- error number (see function gzerror below). gzflush returns Z_OK if
- the flush parameter is Z_FINISH and all output could be flushed.
- gzflush should be called only when strictly necessary because it can
- degrade compression.
- */
-
- ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file,
- z_off_t offset, int whence));
- /*
- Sets the starting position for the next gzread or gzwrite on the
- given compressed file. The offset represents a number of bytes in the
- uncompressed data stream. The whence parameter is defined as in lseek(2);
- the value SEEK_END is not supported.
- If the file is opened for reading, this function is emulated but can be
- extremely slow. If the file is opened for writing, only forward seeks are
- supported; gzseek then compresses a sequence of zeroes up to the new
- starting position.
-
- gzseek returns the resulting offset location as measured in bytes from
- the beginning of the uncompressed stream, or -1 in case of error, in
- particular if the file is opened for writing and the new starting position
- would be before the current position.
- */
-
- ZEXTERN int ZEXPORT gzrewind OF((gzFile file));
- /*
- Rewinds the given file. This function is supported only for reading.
-
- gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET)
- */
-
- ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file));
- /*
- Returns the starting position for the next gzread or gzwrite on the
- given compressed file. This position represents a number of bytes in the
- uncompressed data stream.
-
- gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)
- */
-
- ZEXTERN int ZEXPORT gzeof OF((gzFile file));
- /*
- Returns 1 when EOF has previously been detected reading the given
- input stream, otherwise zero.
- */
-
- ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
- /*
- Returns 1 if file is being read directly without decompression, otherwise
- zero.
- */
-
- ZEXTERN int ZEXPORT gzclose OF((gzFile file));
- /*
- Flushes all pending output if necessary, closes the compressed file
- and deallocates all the (de)compression state. The return value is the zlib
- error number (see function gzerror below).
- */
-
- ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
- /*
- Returns the error message for the last error which occurred on the
- given compressed file. errnum is set to zlib error number. If an
- error occurred in the file system and not in the compression library,
- errnum is set to Z_ERRNO and the application may consult errno
- to get the exact error code.
- */
-
- ZEXTERN void ZEXPORT gzclearerr OF((gzFile file));
- /*
- Clears the error and end-of-file flags for file. This is analogous to the
- clearerr() function in stdio. This is useful for continuing to read a gzip
- file that is being written concurrently.
- */
-
- /* checksum functions */
-
- /*
- These functions are not related to compression but are exported
- anyway because they might be useful in applications using the
- compression library.
- */
-
- ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
- /*
- Update a running Adler-32 checksum with the bytes buf[0..len-1] and
- return the updated checksum. If buf is NULL, this function returns
- the required initial value for the checksum.
- An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
- much faster. Usage example:
-
- uLong adler = adler32(0L, Z_NULL, 0);
-
- while (read_buffer(buffer, length) != EOF) {
- adler = adler32(adler, buffer, length);
- }
- if (adler != original_adler) error();
- */
-
- ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2,
- z_off_t len2));
- /*
- Combine two Adler-32 checksums into one. For two sequences of bytes, seq1
- and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for
- each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of
- seq1 and seq2 concatenated, requiring only adler1, adler2, and len2.
- */
-
- ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
- /*
- Update a running CRC-32 with the bytes buf[0..len-1] and return the
- updated CRC-32. If buf is NULL, this function returns the required initial
- value for the for the crc. Pre- and post-conditioning (one's complement) is
- performed within this function so it shouldn't be done by the application.
- Usage example:
-
- uLong crc = crc32(0L, Z_NULL, 0);
-
- while (read_buffer(buffer, length) != EOF) {
- crc = crc32(crc, buffer, length);
- }
- if (crc != original_crc) error();
- */
-
- ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2));
-
- /*
- Combine two CRC-32 check values into one. For two sequences of bytes,
- seq1 and seq2 with lengths len1 and len2, CRC-32 check values were
- calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32
- check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and
- len2.
- */
-
- /* various hacks, don't look :) */
-
- /* deflateInit and inflateInit are macros to allow checking the zlib version
- * and the compiler's view of z_stream:
- */
- ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level,
- const char *version, int stream_size));
- ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm,
- const char *version, int stream_size));
- ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method,
- int windowBits, int memLevel,
- int strategy, const char *version,
- int stream_size));
- ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits,
- const char *version, int stream_size));
- ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
- unsigned char FAR *window,
- const char *version,
- int stream_size));
- #define deflateInit(strm, level) \
- deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream))
- #define inflateInit(strm) \
- inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream))
- #define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
- deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
- (strategy), ZLIB_VERSION, sizeof(z_stream))
- #define inflateInit2(strm, windowBits) \
- inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
- #define inflateBackInit(strm, windowBits, window) \
- inflateBackInit_((strm), (windowBits), (window), \
- ZLIB_VERSION, sizeof(z_stream))
-
- #if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL)
- struct internal_state {int dummy;}; /* hack for buggy compilers */
- #endif
-
- ZEXTERN const char * ZEXPORT zError OF((int));
- ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z));
- ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void));
-
- #ifdef __cplusplus
- }
- #endif
-
- #endif /* ZLIB_H */
- /********* End of inlined file: zlib.h *********/
-
- #undef OS_CODE
- }
-
- BEGIN_JUCE_NAMESPACE
-
- using namespace zlibNamespace;
-
- // internal helper object that holds the zlib structures so they don't have to be
- // included publicly.
- class GZIPCompressorHelper
- {
- private:
- z_stream* stream;
- uint8* data;
- int dataSize, compLevel, strategy;
- bool setParams;
-
- public:
- bool finished, shouldFinish;
-
- GZIPCompressorHelper (const int compressionLevel, const bool nowrap)
- : data (0),
- dataSize (0),
- compLevel (compressionLevel),
- strategy (0),
- setParams (true),
- finished (false),
- shouldFinish (false)
- {
- stream = (z_stream*) juce_calloc (sizeof (z_stream));
-
- if (deflateInit2 (stream,
- compLevel,
- Z_DEFLATED,
- nowrap ? -MAX_WBITS : MAX_WBITS,
- 8,
- strategy) != Z_OK)
- {
- juce_free (stream);
- stream = 0;
- }
- }
-
- ~GZIPCompressorHelper()
- {
- if (stream != 0)
- {
- deflateEnd (stream);
- juce_free (stream);
- }
- }
-
- bool needsInput() const throw()
- {
- return dataSize <= 0;
- }
-
- void setInput (uint8* const newData, const int size) throw()
- {
- data = newData;
- dataSize = size;
- }
-
- int doNextBlock (uint8* const dest, const int destSize) throw()
- {
- if (stream != 0)
- {
- stream->next_in = data;
- stream->next_out = dest;
- stream->avail_in = dataSize;
- stream->avail_out = destSize;
-
- const int result = setParams ? deflateParams (stream, compLevel, strategy)
- : deflate (stream, shouldFinish ? Z_FINISH : Z_NO_FLUSH);
-
- setParams = false;
-
- switch (result)
- {
- case Z_STREAM_END:
- finished = true;
-
- case Z_OK:
- data += dataSize - stream->avail_in;
- dataSize = stream->avail_in;
-
- return destSize - stream->avail_out;
-
- default:
- break;
- }
- }
-
- return 0;
- }
- };
-
- const int gzipCompBufferSize = 32768;
-
- GZIPCompressorOutputStream::GZIPCompressorOutputStream (OutputStream* const destStream_,
- int compressionLevel,
- const bool deleteDestStream_,
- const bool noWrap)
- : destStream (destStream_),
- deleteDestStream (deleteDestStream_)
- {
- if (compressionLevel < 1 || compressionLevel > 9)
- compressionLevel = -1;
-
- helper = new GZIPCompressorHelper (compressionLevel, noWrap);
-
- buffer = (uint8*) juce_malloc (gzipCompBufferSize);
- }
-
- GZIPCompressorOutputStream::~GZIPCompressorOutputStream()
- {
- flush();
-
- GZIPCompressorHelper* const h = (GZIPCompressorHelper*) helper;
- delete h;
-
- juce_free (buffer);
-
- if (deleteDestStream)
- delete destStream;
- }
-
- void GZIPCompressorOutputStream::flush()
- {
- GZIPCompressorHelper* const h = (GZIPCompressorHelper*) helper;
-
- if (! h->finished)
- {
- h->shouldFinish = true;
-
- while (! h->finished)
- doNextBlock();
- }
-
- destStream->flush();
- }
-
- bool GZIPCompressorOutputStream::write (const void* destBuffer, int howMany)
- {
- GZIPCompressorHelper* const h = (GZIPCompressorHelper*) helper;
-
- if (! h->finished)
- {
- h->setInput ((uint8*) destBuffer, howMany);
-
- while (! h->needsInput())
- {
- if (! doNextBlock())
- return false;
- }
- }
-
- return true;
- }
-
- bool GZIPCompressorOutputStream::doNextBlock()
- {
- GZIPCompressorHelper* const h = (GZIPCompressorHelper*) helper;
- const int len = h->doNextBlock (buffer, gzipCompBufferSize);
-
- if (len > 0)
- return destStream->write (buffer, len);
- else
- return true;
- }
-
- int64 GZIPCompressorOutputStream::getPosition()
- {
- return destStream->getPosition();
- }
-
- bool GZIPCompressorOutputStream::setPosition (int64 /*newPosition*/)
- {
- jassertfalse // can't do it!
- return false;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_GZIPCompressorOutputStream.cpp *********/
-
- /********* Start of inlined file: juce_GZIPDecompressorInputStream.cpp *********/
-
- #if JUCE_MSVC
- #pragma warning (push)
- #pragma warning (disable: 4309 4305)
- #endif
-
- namespace zlibNamespace
- {
- extern "C"
- {
- #undef OS_CODE
- #undef fdopen
- #define ZLIB_INTERNAL
- #define NO_DUMMY_DECL
-
- /********* Start of inlined file: adler32.c *********/
- /* @(#) $Id: adler32.c,v 1.1 2007/06/07 17:54:37 jules_rms Exp $ */
-
- #define ZLIB_INTERNAL
-
- #define BASE 65521UL /* largest prime smaller than 65536 */
- #define NMAX 5552
- /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
-
- #define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;}
- #define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
- #define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
- #define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
- #define DO16(buf) DO8(buf,0); DO8(buf,8);
-
- /* use NO_DIVIDE if your processor does not do division in hardware */
- #ifdef NO_DIVIDE
- # define MOD(a) \
- do { \
- if (a >= (BASE << 16)) a -= (BASE << 16); \
- if (a >= (BASE << 15)) a -= (BASE << 15); \
- if (a >= (BASE << 14)) a -= (BASE << 14); \
- if (a >= (BASE << 13)) a -= (BASE << 13); \
- if (a >= (BASE << 12)) a -= (BASE << 12); \
- if (a >= (BASE << 11)) a -= (BASE << 11); \
- if (a >= (BASE << 10)) a -= (BASE << 10); \
- if (a >= (BASE << 9)) a -= (BASE << 9); \
- if (a >= (BASE << 8)) a -= (BASE << 8); \
- if (a >= (BASE << 7)) a -= (BASE << 7); \
- if (a >= (BASE << 6)) a -= (BASE << 6); \
- if (a >= (BASE << 5)) a -= (BASE << 5); \
- if (a >= (BASE << 4)) a -= (BASE << 4); \
- if (a >= (BASE << 3)) a -= (BASE << 3); \
- if (a >= (BASE << 2)) a -= (BASE << 2); \
- if (a >= (BASE << 1)) a -= (BASE << 1); \
- if (a >= BASE) a -= BASE; \
- } while (0)
- # define MOD4(a) \
- do { \
- if (a >= (BASE << 4)) a -= (BASE << 4); \
- if (a >= (BASE << 3)) a -= (BASE << 3); \
- if (a >= (BASE << 2)) a -= (BASE << 2); \
- if (a >= (BASE << 1)) a -= (BASE << 1); \
- if (a >= BASE) a -= BASE; \
- } while (0)
- #else
- # define MOD(a) a %= BASE
- # define MOD4(a) a %= BASE
- #endif
-
- /* ========================================================================= */
- uLong ZEXPORT adler32(uLong adler, const Bytef *buf, uInt len)
- {
- unsigned long sum2;
- unsigned n;
-
- /* split Adler-32 into component sums */
- sum2 = (adler >> 16) & 0xffff;
- adler &= 0xffff;
-
- /* in case user likes doing a byte at a time, keep it fast */
- if (len == 1) {
- adler += buf[0];
- if (adler >= BASE)
- adler -= BASE;
- sum2 += adler;
- if (sum2 >= BASE)
- sum2 -= BASE;
- return adler | (sum2 << 16);
- }
-
- /* initial Adler-32 value (deferred check for len == 1 speed) */
- if (buf == Z_NULL)
- return 1L;
-
- /* in case short lengths are provided, keep it somewhat fast */
- if (len < 16) {
- while (len--) {
- adler += *buf++;
- sum2 += adler;
- }
- if (adler >= BASE)
- adler -= BASE;
- MOD4(sum2); /* only added so many BASE's */
- return adler | (sum2 << 16);
- }
-
- /* do length NMAX blocks -- requires just one modulo operation */
- while (len >= NMAX) {
- len -= NMAX;
- n = NMAX / 16; /* NMAX is divisible by 16 */
- do {
- DO16(buf); /* 16 sums unrolled */
- buf += 16;
- } while (--n);
- MOD(adler);
- MOD(sum2);
- }
-
- /* do remaining bytes (less than NMAX, still just one modulo) */
- if (len) { /* avoid modulos if none remaining */
- while (len >= 16) {
- len -= 16;
- DO16(buf);
- buf += 16;
- }
- while (len--) {
- adler += *buf++;
- sum2 += adler;
- }
- MOD(adler);
- MOD(sum2);
- }
-
- /* return recombined sums */
- return adler | (sum2 << 16);
- }
-
- /* ========================================================================= */
- uLong ZEXPORT adler32_combine(uLong adler1, uLong adler2, z_off_t len2)
- {
- unsigned long sum1;
- unsigned long sum2;
- unsigned rem;
-
- /* the derivation of this formula is left as an exercise for the reader */
- rem = (unsigned)(len2 % BASE);
- sum1 = adler1 & 0xffff;
- sum2 = rem * sum1;
- MOD(sum2);
- sum1 += (adler2 & 0xffff) + BASE - 1;
- sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem;
- if (sum1 > BASE) sum1 -= BASE;
- if (sum1 > BASE) sum1 -= BASE;
- if (sum2 > (BASE << 1)) sum2 -= (BASE << 1);
- if (sum2 > BASE) sum2 -= BASE;
- return sum1 | (sum2 << 16);
- }
- /********* End of inlined file: adler32.c *********/
-
- /********* Start of inlined file: compress.c *********/
- /* @(#) $Id: compress.c,v 1.1 2007/06/07 17:54:37 jules_rms Exp $ */
-
- #define ZLIB_INTERNAL
-
- /* ===========================================================================
- Compresses the source buffer into the destination buffer. The level
- parameter has the same meaning as in deflateInit. sourceLen is the byte
- length of the source buffer. Upon entry, destLen is the total size of the
- destination buffer, which must be at least 0.1% larger than sourceLen plus
- 12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
-
- compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
- memory, Z_BUF_ERROR if there was not enough room in the output buffer,
- Z_STREAM_ERROR if the level parameter is invalid.
- */
- int ZEXPORT compress2 (Bytef *dest, uLongf *destLen, const Bytef *source,
- uLong sourceLen, int level)
- {
- z_stream stream;
- int err;
-
- stream.next_in = (Bytef*)source;
- stream.avail_in = (uInt)sourceLen;
- #ifdef MAXSEG_64K
- /* Check for source > 64K on 16-bit machine: */
- if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
- #endif
- stream.next_out = dest;
- stream.avail_out = (uInt)*destLen;
- if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
-
- stream.zalloc = (alloc_func)0;
- stream.zfree = (free_func)0;
- stream.opaque = (voidpf)0;
-
- err = deflateInit(&stream, level);
- if (err != Z_OK) return err;
-
- err = deflate(&stream, Z_FINISH);
- if (err != Z_STREAM_END) {
- deflateEnd(&stream);
- return err == Z_OK ? Z_BUF_ERROR : err;
- }
- *destLen = stream.total_out;
-
- err = deflateEnd(&stream);
- return err;
- }
-
- /* ===========================================================================
- */
- int ZEXPORT compress (Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen)
- {
- return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION);
- }
-
- /* ===========================================================================
- If the default memLevel or windowBits for deflateInit() is changed, then
- this function needs to be updated.
- */
- uLong ZEXPORT compressBound (uLong sourceLen)
- {
- return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + 11;
- }
- /********* End of inlined file: compress.c *********/
-
- #undef DO1
- #undef DO8
-
- /********* Start of inlined file: crc32.c *********/
- /* @(#) $Id: crc32.c,v 1.1 2007/06/07 17:54:37 jules_rms Exp $ */
-
- /*
- Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore
- protection on the static variables used to control the first-use generation
- of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should
- first call get_crc_table() to initialize the tables before allowing more than
- one thread to use crc32().
- */
-
- #ifdef MAKECRCH
- # include <stdio.h>
- # ifndef DYNAMIC_CRC_TABLE
- # define DYNAMIC_CRC_TABLE
- # endif /* !DYNAMIC_CRC_TABLE */
- #endif /* MAKECRCH */
-
- /********* Start of inlined file: zutil.h *********/
- /* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
- /* @(#) $Id: zutil.h,v 1.1 2007/06/07 17:54:37 jules_rms Exp $ */
-
- #ifndef ZUTIL_H
- #define ZUTIL_H
-
- #define ZLIB_INTERNAL
-
- #ifdef STDC
- # ifndef _WIN32_WCE
- # include <stddef.h>
- # endif
- # include <string.h>
- # include <stdlib.h>
- #endif
- #ifdef NO_ERRNO_H
- # ifdef _WIN32_WCE
- /* The Microsoft C Run-Time Library for Windows CE doesn't have
- * errno. We define it as a global variable to simplify porting.
- * Its value is always 0 and should not be used. We rename it to
- * avoid conflict with other libraries that use the same workaround.
- */
- # define errno z_errno
- # endif
- extern int errno;
- #else
- # ifndef _WIN32_WCE
- # include <errno.h>
- # endif
- #endif
-
- #ifndef local
- # define local static
- #endif
- /* compile with -Dlocal if your debugger can't find static symbols */
-
- typedef unsigned char uch;
- typedef uch FAR uchf;
- typedef unsigned short ush;
- typedef ush FAR ushf;
- typedef unsigned long ulg;
-
- extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
- /* (size given to avoid silly warnings with Visual C++) */
-
- #define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
-
- #define ERR_RETURN(strm,err) \
- return (strm->msg = (char*)ERR_MSG(err), (err))
- /* To be used only when the state is known to be valid */
-
- /* common constants */
-
- #ifndef DEF_WBITS
- # define DEF_WBITS MAX_WBITS
- #endif
- /* default windowBits for decompression. MAX_WBITS is for compression only */
-
- #if MAX_MEM_LEVEL >= 8
- # define DEF_MEM_LEVEL 8
- #else
- # define DEF_MEM_LEVEL MAX_MEM_LEVEL
- #endif
- /* default memLevel */
-
- #define STORED_BLOCK 0
- #define STATIC_TREES 1
- #define DYN_TREES 2
- /* The three kinds of block type */
-
- #define MIN_MATCH 3
- #define MAX_MATCH 258
- /* The minimum and maximum match lengths */
-
- #define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
-
- /* target dependencies */
-
- #if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32))
- # define OS_CODE 0x00
- # if defined(__TURBOC__) || defined(__BORLANDC__)
- # if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
- /* Allow compilation with ANSI keywords only enabled */
- void _Cdecl farfree( void *block );
- void *_Cdecl farmalloc( unsigned long nbytes );
- # else
- # include <alloc.h>
- # endif
- # else /* MSC or DJGPP */
- # include <malloc.h>
- # endif
- #endif
-
- #ifdef AMIGA
- # define OS_CODE 0x01
- #endif
-
- #if defined(VAXC) || defined(VMS)
- # define OS_CODE 0x02
- # define F_OPEN(name, mode) \
- fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512")
- #endif
-
- #if defined(ATARI) || defined(atarist)
- # define OS_CODE 0x05
- #endif
-
- #ifdef OS2
- # define OS_CODE 0x06
- # ifdef M_I86
- #include <malloc.h>
- # endif
- #endif
-
- #if defined(MACOS) || TARGET_OS_MAC
- # define OS_CODE 0x07
- # if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
- # include <unix.h> /* for fdopen */
- # else
- # ifndef fdopen
- # define fdopen(fd,mode) NULL /* No fdopen() */
- # endif
- # endif
- #endif
-
- #ifdef TOPS20
- # define OS_CODE 0x0a
- #endif
-
- #ifdef WIN32
- # ifndef __CYGWIN__ /* Cygwin is Unix, not Win32 */
- # define OS_CODE 0x0b
- # endif
- #endif
-
- #ifdef __50SERIES /* Prime/PRIMOS */
- # define OS_CODE 0x0f
- #endif
-
- #if defined(_BEOS_) || defined(RISCOS)
- # define fdopen(fd,mode) NULL /* No fdopen() */
- #endif
-
- #if (defined(_MSC_VER) && (_MSC_VER > 600))
- # if defined(_WIN32_WCE)
- # define fdopen(fd,mode) NULL /* No fdopen() */
- # ifndef _PTRDIFF_T_DEFINED
- typedef int ptrdiff_t;
- # define _PTRDIFF_T_DEFINED
- # endif
- # else
- # define fdopen(fd,type) _fdopen(fd,type)
- # endif
- #endif
-
- /* common defaults */
-
- #ifndef OS_CODE
- # define OS_CODE 0x03 /* assume Unix */
- #endif
-
- #ifndef F_OPEN
- # define F_OPEN(name, mode) fopen((name), (mode))
- #endif
-
- /* functions */
-
- #if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550)
- # ifndef HAVE_VSNPRINTF
- # define HAVE_VSNPRINTF
- # endif
- #endif
- #if defined(__CYGWIN__)
- # ifndef HAVE_VSNPRINTF
- # define HAVE_VSNPRINTF
- # endif
- #endif
- #ifndef HAVE_VSNPRINTF
- # ifdef MSDOS
- /* vsnprintf may exist on some MS-DOS compilers (DJGPP?),
- but for now we just assume it doesn't. */
- # define NO_vsnprintf
- # endif
- # ifdef __TURBOC__
- # define NO_vsnprintf
- # endif
- # ifdef WIN32
- /* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */
- # if !defined(vsnprintf) && !defined(NO_vsnprintf)
- # define vsnprintf _vsnprintf
- # endif
- # endif
- # ifdef __SASC
- # define NO_vsnprintf
- # endif
- #endif
- #ifdef VMS
- # define NO_vsnprintf
- #endif
-
- #if defined(pyr)
- # define NO_MEMCPY
- #endif
- #if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)
- /* Use our own functions for small and medium model with MSC <= 5.0.
- * You may have to use the same strategy for Borland C (untested).
- * The __SC__ check is for Symantec.
- */
- # define NO_MEMCPY
- #endif
- #if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY)
- # define HAVE_MEMCPY
- #endif
- #ifdef HAVE_MEMCPY
- # ifdef SMALL_MEDIUM /* MSDOS small or medium model */
- # define zmemcpy _fmemcpy
- # define zmemcmp _fmemcmp
- # define zmemzero(dest, len) _fmemset(dest, 0, len)
- # else
- # define zmemcpy memcpy
- # define zmemcmp memcmp
- # define zmemzero(dest, len) memset(dest, 0, len)
- # endif
- #else
- extern void zmemcpy OF((Bytef* dest, const Bytef* source, uInt len));
- extern int zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len));
- extern void zmemzero OF((Bytef* dest, uInt len));
- #endif
-
- /* Diagnostic functions */
- #ifdef DEBUG
- # include <stdio.h>
- extern int z_verbose;
- extern void z_error OF((char *m));
- # define Assert(cond,msg) {if(!(cond)) z_error(msg);}
- # define Trace(x) {if (z_verbose>=0) fprintf x ;}
- # define Tracev(x) {if (z_verbose>0) fprintf x ;}
- # define Tracevv(x) {if (z_verbose>1) fprintf x ;}
- # define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;}
- # define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;}
- #else
- # define Assert(cond,msg)
- # define Trace(x)
- # define Tracev(x)
- # define Tracevv(x)
- # define Tracec(c,x)
- # define Tracecv(c,x)
- #endif
-
- voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size));
- void zcfree OF((voidpf opaque, voidpf ptr));
-
- #define ZALLOC(strm, items, size) \
- (*((strm)->zalloc))((strm)->opaque, (items), (size))
- #define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
- #define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
-
- #endif /* ZUTIL_H */
- /********* End of inlined file: zutil.h *********/
-
- /* for STDC and FAR definitions */
-
- #define local static
-
- /* Find a four-byte integer type for crc32_little() and crc32_big(). */
- #ifndef NOBYFOUR
- # ifdef STDC /* need ANSI C limits.h to determine sizes */
- # include <limits.h>
- # define BYFOUR
- # if (UINT_MAX == 0xffffffffUL)
- typedef unsigned int u4;
- # else
- # if (ULONG_MAX == 0xffffffffUL)
- typedef unsigned long u4;
- # else
- # if (USHRT_MAX == 0xffffffffUL)
- typedef unsigned short u4;
- # else
- # undef BYFOUR /* can't find a four-byte integer type! */
- # endif
- # endif
- # endif
- # endif /* STDC */
- #endif /* !NOBYFOUR */
-
- /* Definitions for doing the crc four data bytes at a time. */
- #ifdef BYFOUR
- # define REV(w) (((w)>>24)+(((w)>>8)&0xff00)+ \
- (((w)&0xff00)<<8)+(((w)&0xff)<<24))
- local unsigned long crc32_little OF((unsigned long,
- const unsigned char FAR *, unsigned));
- local unsigned long crc32_big OF((unsigned long,
- const unsigned char FAR *, unsigned));
- # define TBLS 8
- #else
- # define TBLS 1
- #endif /* BYFOUR */
-
- /* Local functions for crc concatenation */
- local unsigned long gf2_matrix_times OF((unsigned long *mat,
- unsigned long vec));
- local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat));
-
- #ifdef DYNAMIC_CRC_TABLE
-
- local volatile int crc_table_empty = 1;
- local unsigned long FAR crc_table[TBLS][256];
- local void make_crc_table OF((void));
- #ifdef MAKECRCH
- local void write_table OF((FILE *, const unsigned long FAR *));
- #endif /* MAKECRCH */
- /*
- Generate tables for a byte-wise 32-bit CRC calculation on the polynomial:
- x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
-
- Polynomials over GF(2) are represented in binary, one bit per coefficient,
- with the lowest powers in the most significant bit. Then adding polynomials
- is just exclusive-or, and multiplying a polynomial by x is a right shift by
- one. If we call the above polynomial p, and represent a byte as the
- polynomial q, also with the lowest power in the most significant bit (so the
- byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,
- where a mod b means the remainder after dividing a by b.
-
- This calculation is done using the shift-register method of multiplying and
- taking the remainder. The register is initialized to zero, and for each
- incoming bit, x^32 is added mod p to the register if the bit is a one (where
- x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by
- x (which is shifting right by one and adding x^32 mod p if the bit shifted
- out is a one). We start with the highest power (least significant bit) of
- q and repeat for all eight bits of q.
-
- The first table is simply the CRC of all possible eight bit values. This is
- all the information needed to generate CRCs on data a byte at a time for all
- combinations of CRC register values and incoming bytes. The remaining tables
- allow for word-at-a-time CRC calculation for both big-endian and little-
- endian machines, where a word is four bytes.
- */
- local void make_crc_table()
- {
- unsigned long c;
- int n, k;
- unsigned long poly; /* polynomial exclusive-or pattern */
- /* terms of polynomial defining this crc (except x^32): */
- static volatile int first = 1; /* flag to limit concurrent making */
- static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
-
- /* See if another task is already doing this (not thread-safe, but better
- than nothing -- significantly reduces duration of vulnerability in
- case the advice about DYNAMIC_CRC_TABLE is ignored) */
- if (first) {
- first = 0;
-
- /* make exclusive-or pattern from polynomial (0xedb88320UL) */
- poly = 0UL;
- for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++)
- poly |= 1UL << (31 - p[n]);
-
- /* generate a crc for every 8-bit value */
- for (n = 0; n < 256; n++) {
- c = (unsigned long)n;
- for (k = 0; k < 8; k++)
- c = c & 1 ? poly ^ (c >> 1) : c >> 1;
- crc_table[0][n] = c;
- }
-
- #ifdef BYFOUR
- /* generate crc for each value followed by one, two, and three zeros,
- and then the byte reversal of those as well as the first table */
- for (n = 0; n < 256; n++) {
- c = crc_table[0][n];
- crc_table[4][n] = REV(c);
- for (k = 1; k < 4; k++) {
- c = crc_table[0][c & 0xff] ^ (c >> 8);
- crc_table[k][n] = c;
- crc_table[k + 4][n] = REV(c);
- }
- }
- #endif /* BYFOUR */
-
- crc_table_empty = 0;
- }
- else { /* not first */
- /* wait for the other guy to finish (not efficient, but rare) */
- while (crc_table_empty)
- ;
- }
-
- #ifdef MAKECRCH
- /* write out CRC tables to crc32.h */
- {
- FILE *out;
-
- out = fopen("crc32.h", "w");
- if (out == NULL) return;
- fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n");
- fprintf(out, " * Generated automatically by crc32.c\n */\n\n");
- fprintf(out, "local const unsigned long FAR ");
- fprintf(out, "crc_table[TBLS][256] =\n{\n {\n");
- write_table(out, crc_table[0]);
- # ifdef BYFOUR
- fprintf(out, "#ifdef BYFOUR\n");
- for (k = 1; k < 8; k++) {
- fprintf(out, " },\n {\n");
- write_table(out, crc_table[k]);
- }
- fprintf(out, "#endif\n");
- # endif /* BYFOUR */
- fprintf(out, " }\n};\n");
- fclose(out);
- }
- #endif /* MAKECRCH */
- }
-
- #ifdef MAKECRCH
- local void write_table(out, table)
- FILE *out;
- const unsigned long FAR *table;
- {
- int n;
-
- for (n = 0; n < 256; n++)
- fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", table[n],
- n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", "));
- }
- #endif /* MAKECRCH */
-
- #else /* !DYNAMIC_CRC_TABLE */
- /* ========================================================================
- * Tables of CRC-32s of all single-byte values, made by make_crc_table().
- */
-
- /********* Start of inlined file: crc32.h *********/
- local const unsigned long FAR crc_table[TBLS][256] =
- {
- {
- 0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL,
- 0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL,
- 0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL,
- 0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL,
- 0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL,
- 0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL,
- 0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL,
- 0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL,
- 0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL,
- 0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL,
- 0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL,
- 0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL,
- 0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL,
- 0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL,
- 0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL,
- 0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL,
- 0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL,
- 0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL,
- 0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL,
- 0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL,
- 0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL,
- 0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL,
- 0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL,
- 0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL,
- 0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL,
- 0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL,
- 0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL,
- 0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL,
- 0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL,
- 0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL,
- 0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL,
- 0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL,
- 0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL,
- 0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL,
- 0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL,
- 0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL,
- 0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL,
- 0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL,
- 0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL,
- 0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL,
- 0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL,
- 0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL,
- 0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL,
- 0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL,
- 0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL,
- 0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL,
- 0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL,
- 0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL,
- 0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL,
- 0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL,
- 0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL,
- 0x2d02ef8dUL
- #ifdef BYFOUR
- },
- {
- 0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL,
- 0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL,
- 0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL,
- 0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL,
- 0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL,
- 0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL,
- 0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL,
- 0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL,
- 0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL,
- 0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL,
- 0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL,
- 0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL,
- 0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL,
- 0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL,
- 0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL,
- 0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL,
- 0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL,
- 0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL,
- 0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL,
- 0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL,
- 0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL,
- 0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL,
- 0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL,
- 0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL,
- 0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL,
- 0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL,
- 0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL,
- 0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL,
- 0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL,
- 0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL,
- 0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL,
- 0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL,
- 0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL,
- 0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL,
- 0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL,
- 0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL,
- 0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL,
- 0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL,
- 0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL,
- 0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL,
- 0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL,
- 0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL,
- 0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL,
- 0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL,
- 0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL,
- 0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL,
- 0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL,
- 0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL,
- 0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL,
- 0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL,
- 0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL,
- 0x9324fd72UL
- },
- {
- 0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL,
- 0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL,
- 0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL,
- 0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL,
- 0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL,
- 0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL,
- 0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL,
- 0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL,
- 0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL,
- 0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL,
- 0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL,
- 0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL,
- 0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL,
- 0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL,
- 0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL,
- 0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL,
- 0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL,
- 0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL,
- 0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL,
- 0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL,
- 0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL,
- 0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL,
- 0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL,
- 0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL,
- 0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL,
- 0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL,
- 0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL,
- 0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL,
- 0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL,
- 0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL,
- 0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL,
- 0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL,
- 0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL,
- 0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL,
- 0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL,
- 0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL,
- 0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL,
- 0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL,
- 0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL,
- 0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL,
- 0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL,
- 0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL,
- 0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL,
- 0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL,
- 0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL,
- 0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL,
- 0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL,
- 0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL,
- 0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL,
- 0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL,
- 0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL,
- 0xbe9834edUL
- },
- {
- 0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL,
- 0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL,
- 0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL,
- 0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL,
- 0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL,
- 0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL,
- 0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL,
- 0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL,
- 0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL,
- 0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL,
- 0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL,
- 0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL,
- 0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL,
- 0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL,
- 0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL,
- 0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL,
- 0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL,
- 0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL,
- 0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL,
- 0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL,
- 0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL,
- 0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL,
- 0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL,
- 0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL,
- 0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL,
- 0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL,
- 0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL,
- 0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL,
- 0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL,
- 0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL,
- 0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL,
- 0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL,
- 0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL,
- 0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL,
- 0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL,
- 0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL,
- 0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL,
- 0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL,
- 0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL,
- 0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL,
- 0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL,
- 0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL,
- 0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL,
- 0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL,
- 0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL,
- 0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL,
- 0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL,
- 0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL,
- 0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL,
- 0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL,
- 0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL,
- 0xde0506f1UL
- },
- {
- 0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL,
- 0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL,
- 0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL,
- 0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL,
- 0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL,
- 0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL,
- 0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL,
- 0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL,
- 0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL,
- 0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL,
- 0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL,
- 0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL,
- 0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL,
- 0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL,
- 0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL,
- 0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL,
- 0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL,
- 0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL,
- 0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL,
- 0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL,
- 0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL,
- 0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL,
- 0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL,
- 0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL,
- 0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL,
- 0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL,
- 0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL,
- 0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL,
- 0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL,
- 0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL,
- 0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL,
- 0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL,
- 0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL,
- 0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL,
- 0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL,
- 0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL,
- 0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL,
- 0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL,
- 0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL,
- 0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL,
- 0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL,
- 0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL,
- 0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL,
- 0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL,
- 0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL,
- 0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL,
- 0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL,
- 0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL,
- 0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL,
- 0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL,
- 0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL,
- 0x8def022dUL
- },
- {
- 0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL,
- 0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL,
- 0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL,
- 0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL,
- 0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL,
- 0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL,
- 0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL,
- 0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL,
- 0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL,
- 0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL,
- 0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL,
- 0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL,
- 0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL,
- 0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL,
- 0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL,
- 0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL,
- 0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL,
- 0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL,
- 0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL,
- 0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL,
- 0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL,
- 0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL,
- 0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL,
- 0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL,
- 0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL,
- 0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL,
- 0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL,
- 0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL,
- 0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL,
- 0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL,
- 0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL,
- 0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL,
- 0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL,
- 0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL,
- 0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL,
- 0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL,
- 0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL,
- 0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL,
- 0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL,
- 0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL,
- 0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL,
- 0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL,
- 0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL,
- 0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL,
- 0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL,
- 0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL,
- 0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL,
- 0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL,
- 0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL,
- 0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL,
- 0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL,
- 0x72fd2493UL
- },
- {
- 0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL,
- 0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL,
- 0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL,
- 0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL,
- 0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL,
- 0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL,
- 0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL,
- 0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL,
- 0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL,
- 0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL,
- 0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL,
- 0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL,
- 0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL,
- 0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL,
- 0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL,
- 0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL,
- 0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL,
- 0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL,
- 0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL,
- 0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL,
- 0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL,
- 0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL,
- 0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL,
- 0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL,
- 0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL,
- 0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL,
- 0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL,
- 0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL,
- 0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL,
- 0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL,
- 0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL,
- 0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL,
- 0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL,
- 0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL,
- 0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL,
- 0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL,
- 0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL,
- 0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL,
- 0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL,
- 0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL,
- 0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL,
- 0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL,
- 0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL,
- 0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL,
- 0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL,
- 0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL,
- 0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL,
- 0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL,
- 0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL,
- 0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL,
- 0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL,
- 0xed3498beUL
- },
- {
- 0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL,
- 0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL,
- 0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL,
- 0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL,
- 0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL,
- 0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL,
- 0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL,
- 0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL,
- 0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL,
- 0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL,
- 0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL,
- 0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL,
- 0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL,
- 0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL,
- 0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL,
- 0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL,
- 0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL,
- 0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL,
- 0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL,
- 0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL,
- 0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL,
- 0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL,
- 0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL,
- 0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL,
- 0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL,
- 0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL,
- 0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL,
- 0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL,
- 0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL,
- 0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL,
- 0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL,
- 0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL,
- 0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL,
- 0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL,
- 0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL,
- 0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL,
- 0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL,
- 0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL,
- 0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL,
- 0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL,
- 0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL,
- 0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL,
- 0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL,
- 0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL,
- 0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL,
- 0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL,
- 0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL,
- 0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL,
- 0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL,
- 0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL,
- 0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL,
- 0xf10605deUL
- #endif
- }
- };
- /********* End of inlined file: crc32.h *********/
-
- #endif /* DYNAMIC_CRC_TABLE */
-
- /* =========================================================================
- * This function can be used by asm versions of crc32()
- */
- const unsigned long FAR * ZEXPORT get_crc_table()
- {
- #ifdef DYNAMIC_CRC_TABLE
- if (crc_table_empty)
- make_crc_table();
- #endif /* DYNAMIC_CRC_TABLE */
- return (const unsigned long FAR *)crc_table;
- }
-
- /* ========================================================================= */
- #define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8)
- #define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1
-
- /* ========================================================================= */
- unsigned long ZEXPORT crc32 (unsigned long crc, const unsigned char FAR *buf, unsigned len)
- {
- if (buf == Z_NULL) return 0UL;
-
- #ifdef DYNAMIC_CRC_TABLE
- if (crc_table_empty)
- make_crc_table();
- #endif /* DYNAMIC_CRC_TABLE */
-
- #ifdef BYFOUR
- if (sizeof(void *) == sizeof(ptrdiff_t)) {
- u4 endian;
-
- endian = 1;
- if (*((unsigned char *)(&endian)))
- return crc32_little(crc, buf, len);
- else
- return crc32_big(crc, buf, len);
- }
- #endif /* BYFOUR */
- crc = crc ^ 0xffffffffUL;
- while (len >= 8) {
- DO8;
- len -= 8;
- }
- if (len) do {
- DO1;
- } while (--len);
- return crc ^ 0xffffffffUL;
- }
-
- #ifdef BYFOUR
-
- /* ========================================================================= */
- #define DOLIT4 c ^= *buf4++; \
- c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \
- crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24]
- #define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4
-
- /* ========================================================================= */
- local unsigned long crc32_little(unsigned long crc, const unsigned char FAR *buf, unsigned len)
- {
- register u4 c;
- register const u4 FAR *buf4;
-
- c = (u4)crc;
- c = ~c;
- while (len && ((ptrdiff_t)buf & 3)) {
- c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
- len--;
- }
-
- buf4 = (const u4 FAR *)(const void FAR *)buf;
- while (len >= 32) {
- DOLIT32;
- len -= 32;
- }
- while (len >= 4) {
- DOLIT4;
- len -= 4;
- }
- buf = (const unsigned char FAR *)buf4;
-
- if (len) do {
- c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
- } while (--len);
- c = ~c;
- return (unsigned long)c;
- }
-
- /* ========================================================================= */
- #define DOBIG4 c ^= *++buf4; \
- c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \
- crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24]
- #define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4
-
- /* ========================================================================= */
- local unsigned long crc32_big (unsigned long crc, const unsigned char FAR *buf, unsigned len)
- {
- register u4 c;
- register const u4 FAR *buf4;
-
- c = REV((u4)crc);
- c = ~c;
- while (len && ((ptrdiff_t)buf & 3)) {
- c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
- len--;
- }
-
- buf4 = (const u4 FAR *)(const void FAR *)buf;
- buf4--;
- while (len >= 32) {
- DOBIG32;
- len -= 32;
- }
- while (len >= 4) {
- DOBIG4;
- len -= 4;
- }
- buf4++;
- buf = (const unsigned char FAR *)buf4;
-
- if (len) do {
- c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
- } while (--len);
- c = ~c;
- return (unsigned long)(REV(c));
- }
-
- #endif /* BYFOUR */
-
- #define GF2_DIM 32 /* dimension of GF(2) vectors (length of CRC) */
-
- /* ========================================================================= */
- local unsigned long gf2_matrix_times (unsigned long *mat, unsigned long vec)
- {
- unsigned long sum;
-
- sum = 0;
- while (vec) {
- if (vec & 1)
- sum ^= *mat;
- vec >>= 1;
- mat++;
- }
- return sum;
- }
-
- /* ========================================================================= */
- local void gf2_matrix_square (unsigned long *square, unsigned long *mat)
- {
- int n;
-
- for (n = 0; n < GF2_DIM; n++)
- square[n] = gf2_matrix_times(mat, mat[n]);
- }
-
- /* ========================================================================= */
- uLong ZEXPORT crc32_combine (uLong crc1, uLong crc2, z_off_t len2)
- {
- int n;
- unsigned long row;
- unsigned long even[GF2_DIM]; /* even-power-of-two zeros operator */
- unsigned long odd[GF2_DIM]; /* odd-power-of-two zeros operator */
-
- /* degenerate case */
- if (len2 == 0)
- return crc1;
-
- /* put operator for one zero bit in odd */
- odd[0] = 0xedb88320L; /* CRC-32 polynomial */
- row = 1;
- for (n = 1; n < GF2_DIM; n++) {
- odd[n] = row;
- row <<= 1;
- }
-
- /* put operator for two zero bits in even */
- gf2_matrix_square(even, odd);
-
- /* put operator for four zero bits in odd */
- gf2_matrix_square(odd, even);
-
- /* apply len2 zeros to crc1 (first square will put the operator for one
- zero byte, eight zero bits, in even) */
- do {
- /* apply zeros operator for this bit of len2 */
- gf2_matrix_square(even, odd);
- if (len2 & 1)
- crc1 = gf2_matrix_times(even, crc1);
- len2 >>= 1;
-
- /* if no more bits set, then done */
- if (len2 == 0)
- break;
-
- /* another iteration of the loop with odd and even swapped */
- gf2_matrix_square(odd, even);
- if (len2 & 1)
- crc1 = gf2_matrix_times(odd, crc1);
- len2 >>= 1;
-
- /* if no more bits set, then done */
- } while (len2 != 0);
-
- /* return combined crc */
- crc1 ^= crc2;
- return crc1;
- }
- /********* End of inlined file: crc32.c *********/
-
- /********* Start of inlined file: deflate.c *********/
- /*
- * ALGORITHM
- *
- * The "deflation" process depends on being able to identify portions
- * of the input text which are identical to earlier input (within a
- * sliding window trailing behind the input currently being processed).
- *
- * The most straightforward technique turns out to be the fastest for
- * most input files: try all possible matches and select the longest.
- * The key feature of this algorithm is that insertions into the string
- * dictionary are very simple and thus fast, and deletions are avoided
- * completely. Insertions are performed at each input character, whereas
- * string matches are performed only when the previous match ends. So it
- * is preferable to spend more time in matches to allow very fast string
- * insertions and avoid deletions. The matching algorithm for small
- * strings is inspired from that of Rabin & Karp. A brute force approach
- * is used to find longer strings when a small match has been found.
- * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze
- * (by Leonid Broukhis).
- * A previous version of this file used a more sophisticated algorithm
- * (by Fiala and Greene) which is guaranteed to run in linear amortized
- * time, but has a larger average cost, uses more memory and is patented.
- * However the F&G algorithm may be faster for some highly redundant
- * files if the parameter max_chain_length (described below) is too large.
- *
- * ACKNOWLEDGEMENTS
- *
- * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and
- * I found it in 'freeze' written by Leonid Broukhis.
- * Thanks to many people for bug reports and testing.
- *
- * REFERENCES
- *
- * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification".
- * Available in http://www.ietf.org/rfc/rfc1951.txt
- *
- * A description of the Rabin and Karp algorithm is given in the book
- * "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
- *
- * Fiala,E.R., and Greene,D.H.
- * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595
- *
- */
-
- /* @(#) $Id: deflate.c,v 1.1 2007/06/07 17:54:37 jules_rms Exp $ */
-
- /********* Start of inlined file: deflate.h *********/
- /* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
- /* @(#) $Id: deflate.h,v 1.1 2007/06/07 17:54:37 jules_rms Exp $ */
-
- #ifndef DEFLATE_H
- #define DEFLATE_H
-
- /* define NO_GZIP when compiling if you want to disable gzip header and
- trailer creation by deflate(). NO_GZIP would be used to avoid linking in
- the crc code when it is not needed. For shared libraries, gzip encoding
- should be left enabled. */
- #ifndef NO_GZIP
- # define GZIP
- #endif
-
- #define NO_DUMMY_DECL
-
- /* ===========================================================================
- * Internal compression state.
- */
-
- #define LENGTH_CODES 29
- /* number of length codes, not counting the special END_BLOCK code */
-
- #define LITERALS 256
- /* number of literal bytes 0..255 */
-
- #define L_CODES (LITERALS+1+LENGTH_CODES)
- /* number of Literal or Length codes, including the END_BLOCK code */
-
- #define D_CODES 30
- /* number of distance codes */
-
- #define BL_CODES 19
- /* number of codes used to transfer the bit lengths */
-
- #define HEAP_SIZE (2*L_CODES+1)
- /* maximum heap size */
-
- #define MAX_BITS 15
- /* All codes must not exceed MAX_BITS bits */
-
- #define INIT_STATE 42
- #define EXTRA_STATE 69
- #define NAME_STATE 73
- #define COMMENT_STATE 91
- #define HCRC_STATE 103
- #define BUSY_STATE 113
- #define FINISH_STATE 666
- /* Stream status */
-
- /* Data structure describing a single value and its code string. */
- typedef struct ct_data_s {
- union {
- ush freq; /* frequency count */
- ush code; /* bit string */
- } fc;
- union {
- ush dad; /* father node in Huffman tree */
- ush len; /* length of bit string */
- } dl;
- } FAR ct_data;
-
- #define Freq fc.freq
- #define Code fc.code
- #define Dad dl.dad
- #define Len dl.len
-
- typedef struct static_tree_desc_s static_tree_desc;
-
- typedef struct tree_desc_s {
- ct_data *dyn_tree; /* the dynamic tree */
- int max_code; /* largest code with non zero frequency */
- static_tree_desc *stat_desc; /* the corresponding static tree */
- } FAR tree_desc;
-
- typedef ush Pos;
- typedef Pos FAR Posf;
- typedef unsigned IPos;
-
- /* A Pos is an index in the character window. We use short instead of int to
- * save space in the various tables. IPos is used only for parameter passing.
- */
-
- typedef struct internal_state {
- z_streamp strm; /* pointer back to this zlib stream */
- int status; /* as the name implies */
- Bytef *pending_buf; /* output still pending */
- ulg pending_buf_size; /* size of pending_buf */
- Bytef *pending_out; /* next pending byte to output to the stream */
- uInt pending; /* nb of bytes in the pending buffer */
- int wrap; /* bit 0 true for zlib, bit 1 true for gzip */
- gz_headerp gzhead; /* gzip header information to write */
- uInt gzindex; /* where in extra, name, or comment */
- Byte method; /* STORED (for zip only) or DEFLATED */
- int last_flush; /* value of flush param for previous deflate call */
-
- /* used by deflate.c: */
-
- uInt w_size; /* LZ77 window size (32K by default) */
- uInt w_bits; /* log2(w_size) (8..16) */
- uInt w_mask; /* w_size - 1 */
-
- Bytef *window;
- /* Sliding window. Input bytes are read into the second half of the window,
- * and move to the first half later to keep a dictionary of at least wSize
- * bytes. With this organization, matches are limited to a distance of
- * wSize-MAX_MATCH bytes, but this ensures that IO is always
- * performed with a length multiple of the block size. Also, it limits
- * the window size to 64K, which is quite useful on MSDOS.
- * To do: use the user input buffer as sliding window.
- */
-
- ulg window_size;
- /* Actual size of window: 2*wSize, except when the user input buffer
- * is directly used as sliding window.
- */
-
- Posf *prev;
- /* Link to older string with same hash index. To limit the size of this
- * array to 64K, this link is maintained only for the last 32K strings.
- * An index in this array is thus a window index modulo 32K.
- */
-
- Posf *head; /* Heads of the hash chains or NIL. */
-
- uInt ins_h; /* hash index of string to be inserted */
- uInt hash_size; /* number of elements in hash table */
- uInt hash_bits; /* log2(hash_size) */
- uInt hash_mask; /* hash_size-1 */
-
- uInt hash_shift;
- /* Number of bits by which ins_h must be shifted at each input
- * step. It must be such that after MIN_MATCH steps, the oldest
- * byte no longer takes part in the hash key, that is:
- * hash_shift * MIN_MATCH >= hash_bits
- */
-
- long block_start;
- /* Window position at the beginning of the current output block. Gets
- * negative when the window is moved backwards.
- */
-
- uInt match_length; /* length of best match */
- IPos prev_match; /* previous match */
- int match_available; /* set if previous match exists */
- uInt strstart; /* start of string to insert */
- uInt match_start; /* start of matching string */
- uInt lookahead; /* number of valid bytes ahead in window */
-
- uInt prev_length;
- /* Length of the best match at previous step. Matches not greater than this
- * are discarded. This is used in the lazy match evaluation.
- */
-
- uInt max_chain_length;
- /* To speed up deflation, hash chains are never searched beyond this
- * length. A higher limit improves compression ratio but degrades the
- * speed.
- */
-
- uInt max_lazy_match;
- /* Attempt to find a better match only when the current match is strictly
- * smaller than this value. This mechanism is used only for compression
- * levels >= 4.
- */
- # define max_insert_length max_lazy_match
- /* Insert new strings in the hash table only if the match length is not
- * greater than this length. This saves time but degrades compression.
- * max_insert_length is used only for compression levels <= 3.
- */
-
- int level; /* compression level (1..9) */
- int strategy; /* favor or force Huffman coding*/
-
- uInt good_match;
- /* Use a faster search when the previous match is longer than this */
-
- int nice_match; /* Stop searching when current match exceeds this */
-
- /* used by trees.c: */
- /* Didn't use ct_data typedef below to supress compiler warning */
- struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */
- struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
- struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */
-
- struct tree_desc_s l_desc; /* desc. for literal tree */
- struct tree_desc_s d_desc; /* desc. for distance tree */
- struct tree_desc_s bl_desc; /* desc. for bit length tree */
-
- ush bl_count[MAX_BITS+1];
- /* number of codes at each bit length for an optimal tree */
-
- int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */
- int heap_len; /* number of elements in the heap */
- int heap_max; /* element of largest frequency */
- /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
- * The same heap array is used to build all trees.
- */
-
- uch depth[2*L_CODES+1];
- /* Depth of each subtree used as tie breaker for trees of equal frequency
- */
-
- uchf *l_buf; /* buffer for literals or lengths */
-
- uInt lit_bufsize;
- /* Size of match buffer for literals/lengths. There are 4 reasons for
- * limiting lit_bufsize to 64K:
- * - frequencies can be kept in 16 bit counters
- * - if compression is not successful for the first block, all input
- * data is still in the window so we can still emit a stored block even
- * when input comes from standard input. (This can also be done for
- * all blocks if lit_bufsize is not greater than 32K.)
- * - if compression is not successful for a file smaller than 64K, we can
- * even emit a stored file instead of a stored block (saving 5 bytes).
- * This is applicable only for zip (not gzip or zlib).
- * - creating new Huffman trees less frequently may not provide fast
- * adaptation to changes in the input data statistics. (Take for
- * example a binary file with poorly compressible code followed by
- * a highly compressible string table.) Smaller buffer sizes give
- * fast adaptation but have of course the overhead of transmitting
- * trees more frequently.
- * - I can't count above 4
- */
-
- uInt last_lit; /* running index in l_buf */
-
- ushf *d_buf;
- /* Buffer for distances. To simplify the code, d_buf and l_buf have
- * the same number of elements. To use different lengths, an extra flag
- * array would be necessary.
- */
-
- ulg opt_len; /* bit length of current block with optimal trees */
- ulg static_len; /* bit length of current block with static trees */
- uInt matches; /* number of string matches in current block */
- int last_eob_len; /* bit length of EOB code for last block */
-
- #ifdef DEBUG
- ulg compressed_len; /* total bit length of compressed file mod 2^32 */
- ulg bits_sent; /* bit length of compressed data sent mod 2^32 */
- #endif
-
- ush bi_buf;
- /* Output buffer. bits are inserted starting at the bottom (least
- * significant bits).
- */
- int bi_valid;
- /* Number of valid bits in bi_buf. All bits above the last valid bit
- * are always zero.
- */
-
- } FAR deflate_state;
-
- /* Output a byte on the stream.
- * IN assertion: there is enough room in pending_buf.
- */
- #define put_byte(s, c) {s->pending_buf[s->pending++] = (c);}
-
- #define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
- /* Minimum amount of lookahead, except at the end of the input file.
- * See deflate.c for comments about the MIN_MATCH+1.
- */
-
- #define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD)
- /* In order to simplify the code, particularly on 16 bit machines, match
- * distances are limited to MAX_DIST instead of WSIZE.
- */
-
- /* in trees.c */
- void _tr_init OF((deflate_state *s));
- int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc));
- void _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len,
- int eof));
- void _tr_align OF((deflate_state *s));
- void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
- int eof));
-
- #define d_code(dist) \
- ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)])
- /* Mapping from a distance to a distance code. dist is the distance - 1 and
- * must not have side effects. _dist_code[256] and _dist_code[257] are never
- * used.
- */
-
- #ifndef DEBUG
- /* Inline versions of _tr_tally for speed: */
-
- #if defined(GEN_TREES_H) || !defined(STDC)
- extern uch _length_code[];
- extern uch _dist_code[];
- #else
- extern const uch _length_code[];
- extern const uch _dist_code[];
- #endif
-
- # define _tr_tally_lit(s, c, flush) \
- { uch cc = (c); \
- s->d_buf[s->last_lit] = 0; \
- s->l_buf[s->last_lit++] = cc; \
- s->dyn_ltree[cc].Freq++; \
- flush = (s->last_lit == s->lit_bufsize-1); \
- }
- # define _tr_tally_dist(s, distance, length, flush) \
- { uch len = (length); \
- ush dist = (distance); \
- s->d_buf[s->last_lit] = dist; \
- s->l_buf[s->last_lit++] = len; \
- dist--; \
- s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \
- s->dyn_dtree[d_code(dist)].Freq++; \
- flush = (s->last_lit == s->lit_bufsize-1); \
- }
- #else
- # define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c)
- # define _tr_tally_dist(s, distance, length, flush) \
- flush = _tr_tally(s, distance, length)
- #endif
-
- #endif /* DEFLATE_H */
- /********* End of inlined file: deflate.h *********/
-
- const char deflate_copyright[] =
- " deflate 1.2.3 Copyright 1995-2005 Jean-loup Gailly ";
- /*
- If you use the zlib library in a product, an acknowledgment is welcome
- in the documentation of your product. If for some reason you cannot
- include such an acknowledgment, I would appreciate that you keep this
- copyright string in the executable of your product.
- */
-
- /* ===========================================================================
- * Function prototypes.
- */
- typedef enum {
- need_more, /* block not completed, need more input or more output */
- block_done, /* block flush performed */
- finish_started, /* finish started, need only more output at next deflate */
- finish_done /* finish done, accept no more input or output */
- } block_state;
-
- typedef block_state (*compress_func) OF((deflate_state *s, int flush));
- /* Compression function. Returns the block state after the call. */
-
- local void fill_window OF((deflate_state *s));
- local block_state deflate_stored OF((deflate_state *s, int flush));
- local block_state deflate_fast OF((deflate_state *s, int flush));
- #ifndef FASTEST
- local block_state deflate_slow OF((deflate_state *s, int flush));
- #endif
- local void lm_init OF((deflate_state *s));
- local void putShortMSB OF((deflate_state *s, uInt b));
- local void flush_pending OF((z_streamp strm));
- local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size));
- #ifndef FASTEST
- #ifdef ASMV
- void match_init OF((void)); /* asm code initialization */
- uInt longest_match OF((deflate_state *s, IPos cur_match));
- #else
- local uInt longest_match OF((deflate_state *s, IPos cur_match));
- #endif
- #endif
- local uInt longest_match_fast OF((deflate_state *s, IPos cur_match));
-
- #ifdef DEBUG
- local void check_match OF((deflate_state *s, IPos start, IPos match,
- int length));
- #endif
-
- /* ===========================================================================
- * Local data
- */
-
- #define NIL 0
- /* Tail of hash chains */
-
- #ifndef TOO_FAR
- # define TOO_FAR 4096
- #endif
- /* Matches of length 3 are discarded if their distance exceeds TOO_FAR */
-
- #define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
- /* Minimum amount of lookahead, except at the end of the input file.
- * See deflate.c for comments about the MIN_MATCH+1.
- */
-
- /* Values for max_lazy_match, good_match and max_chain_length, depending on
- * the desired pack level (0..9). The values given below have been tuned to
- * exclude worst case performance for pathological files. Better values may be
- * found for specific files.
- */
- typedef struct config_s {
- ush good_length; /* reduce lazy search above this match length */
- ush max_lazy; /* do not perform lazy search above this match length */
- ush nice_length; /* quit search above this match length */
- ush max_chain;
- compress_func func;
- } config;
-
- #ifdef FASTEST
- local const config configuration_table[2] = {
- /* good lazy nice chain */
- /* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */
- /* 1 */ {4, 4, 8, 4, deflate_fast}}; /* max speed, no lazy matches */
- #else
- local const config configuration_table[10] = {
- /* good lazy nice chain */
- /* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */
- /* 1 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */
- /* 2 */ {4, 5, 16, 8, deflate_fast},
- /* 3 */ {4, 6, 32, 32, deflate_fast},
-
- /* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */
- /* 5 */ {8, 16, 32, 32, deflate_slow},
- /* 6 */ {8, 16, 128, 128, deflate_slow},
- /* 7 */ {8, 32, 128, 256, deflate_slow},
- /* 8 */ {32, 128, 258, 1024, deflate_slow},
- /* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */
- #endif
-
- /* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4
- * For deflate_fast() (levels <= 3) good is ignored and lazy has a different
- * meaning.
- */
-
- #define EQUAL 0
- /* result of memcmp for equal strings */
-
- #ifndef NO_DUMMY_DECL
- struct static_tree_desc_s {int dummy;}; /* for buggy compilers */
- #endif
-
- /* ===========================================================================
- * Update a hash value with the given input byte
- * IN assertion: all calls to to UPDATE_HASH are made with consecutive
- * input characters, so that a running hash key can be computed from the
- * previous key instead of complete recalculation each time.
- */
- #define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask)
-
- /* ===========================================================================
- * Insert string str in the dictionary and set match_head to the previous head
- * of the hash chain (the most recent string with same hash key). Return
- * the previous length of the hash chain.
- * If this file is compiled with -DFASTEST, the compression level is forced
- * to 1, and no hash chains are maintained.
- * IN assertion: all calls to to INSERT_STRING are made with consecutive
- * input characters and the first MIN_MATCH bytes of str are valid
- * (except for the last MIN_MATCH-1 bytes of the input file).
- */
- #ifdef FASTEST
- #define INSERT_STRING(s, str, match_head) \
- (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
- match_head = s->head[s->ins_h], \
- s->head[s->ins_h] = (Pos)(str))
- #else
- #define INSERT_STRING(s, str, match_head) \
- (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
- match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \
- s->head[s->ins_h] = (Pos)(str))
- #endif
-
- /* ===========================================================================
- * Initialize the hash table (avoiding 64K overflow for 16 bit systems).
- * prev[] will be initialized on the fly.
- */
- #define CLEAR_HASH(s) \
- s->head[s->hash_size-1] = NIL; \
- zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head));
-
- /* ========================================================================= */
- int ZEXPORT deflateInit_(z_streamp strm, int level, const char *version, int stream_size)
- {
- return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL,
- Z_DEFAULT_STRATEGY, version, stream_size);
- /* To do: ignore strm->next_in if we use it as window */
- }
-
- /* ========================================================================= */
- int ZEXPORT deflateInit2_ (z_streamp strm, int level, int method, int windowBits, int memLevel, int strategy, const char *version, int stream_size)
- {
- deflate_state *s;
- int wrap = 1;
- static const char my_version[] = ZLIB_VERSION;
-
- ushf *overlay;
- /* We overlay pending_buf and d_buf+l_buf. This works since the average
- * output size for (length,distance) codes is <= 24 bits.
- */
-
- if (version == Z_NULL || version[0] != my_version[0] ||
- stream_size != sizeof(z_stream)) {
- return Z_VERSION_ERROR;
- }
- if (strm == Z_NULL) return Z_STREAM_ERROR;
-
- strm->msg = Z_NULL;
- if (strm->zalloc == (alloc_func)0) {
- strm->zalloc = zcalloc;
- strm->opaque = (voidpf)0;
- }
- if (strm->zfree == (free_func)0) strm->zfree = zcfree;
-
- #ifdef FASTEST
- if (level != 0) level = 1;
- #else
- if (level == Z_DEFAULT_COMPRESSION) level = 6;
- #endif
-
- if (windowBits < 0) { /* suppress zlib wrapper */
- wrap = 0;
- windowBits = -windowBits;
- }
- #ifdef GZIP
- else if (windowBits > 15) {
- wrap = 2; /* write gzip wrapper instead */
- windowBits -= 16;
- }
- #endif
- if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED ||
- windowBits < 8 || windowBits > 15 || level < 0 || level > 9 ||
- strategy < 0 || strategy > Z_FIXED) {
- return Z_STREAM_ERROR;
- }
- if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */
- s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state));
- if (s == Z_NULL) return Z_MEM_ERROR;
- strm->state = (struct internal_state FAR *)s;
- s->strm = strm;
-
- s->wrap = wrap;
- s->gzhead = Z_NULL;
- s->w_bits = windowBits;
- s->w_size = 1 << s->w_bits;
- s->w_mask = s->w_size - 1;
-
- s->hash_bits = memLevel + 7;
- s->hash_size = 1 << s->hash_bits;
- s->hash_mask = s->hash_size - 1;
- s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH);
-
- s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte));
- s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos));
- s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos));
-
- s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
-
- overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
- s->pending_buf = (uchf *) overlay;
- s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L);
-
- if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
- s->pending_buf == Z_NULL) {
- s->status = FINISH_STATE;
- strm->msg = (char*)ERR_MSG(Z_MEM_ERROR);
- deflateEnd (strm);
- return Z_MEM_ERROR;
- }
- s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
- s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;
-
- s->level = level;
- s->strategy = strategy;
- s->method = (Byte)method;
-
- return deflateReset(strm);
- }
-
- /* ========================================================================= */
- int ZEXPORT deflateSetDictionary (z_streamp strm, const Bytef *dictionary, uInt dictLength)
- {
- deflate_state *s;
- uInt length = dictLength;
- uInt n;
- IPos hash_head = 0;
-
- if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL ||
- strm->state->wrap == 2 ||
- (strm->state->wrap == 1 && strm->state->status != INIT_STATE))
- return Z_STREAM_ERROR;
-
- s = strm->state;
- if (s->wrap)
- strm->adler = adler32(strm->adler, dictionary, dictLength);
-
- if (length < MIN_MATCH) return Z_OK;
- if (length > MAX_DIST(s)) {
- length = MAX_DIST(s);
- dictionary += dictLength - length; /* use the tail of the dictionary */
- }
- zmemcpy(s->window, dictionary, length);
- s->strstart = length;
- s->block_start = (long)length;
-
- /* Insert all strings in the hash table (except for the last two bytes).
- * s->lookahead stays null, so s->ins_h will be recomputed at the next
- * call of fill_window.
- */
- s->ins_h = s->window[0];
- UPDATE_HASH(s, s->ins_h, s->window[1]);
- for (n = 0; n <= length - MIN_MATCH; n++) {
- INSERT_STRING(s, n, hash_head);
- }
- if (hash_head) hash_head = 0; /* to make compiler happy */
- return Z_OK;
- }
-
- /* ========================================================================= */
- int ZEXPORT deflateReset (z_streamp strm)
- {
- deflate_state *s;
-
- if (strm == Z_NULL || strm->state == Z_NULL ||
- strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) {
- return Z_STREAM_ERROR;
- }
-
- strm->total_in = strm->total_out = 0;
- strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */
- strm->data_type = Z_UNKNOWN;
-
- s = (deflate_state *)strm->state;
- s->pending = 0;
- s->pending_out = s->pending_buf;
-
- if (s->wrap < 0) {
- s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */
- }
- s->status = s->wrap ? INIT_STATE : BUSY_STATE;
- strm->adler =
- #ifdef GZIP
- s->wrap == 2 ? crc32(0L, Z_NULL, 0) :
- #endif
- adler32(0L, Z_NULL, 0);
- s->last_flush = Z_NO_FLUSH;
-
- _tr_init(s);
- lm_init(s);
-
- return Z_OK;
- }
-
- /* ========================================================================= */
- int ZEXPORT deflateSetHeader (z_streamp strm, gz_headerp head)
- {
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
- if (strm->state->wrap != 2) return Z_STREAM_ERROR;
- strm->state->gzhead = head;
- return Z_OK;
- }
-
- /* ========================================================================= */
- int ZEXPORT deflatePrime (z_streamp strm, int bits, int value)
- {
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
- strm->state->bi_valid = bits;
- strm->state->bi_buf = (ush)(value & ((1 << bits) - 1));
- return Z_OK;
- }
-
- /* ========================================================================= */
- int ZEXPORT deflateParams (z_streamp strm, int level, int strategy)
- {
- deflate_state *s;
- compress_func func;
- int err = Z_OK;
-
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
- s = strm->state;
-
- #ifdef FASTEST
- if (level != 0) level = 1;
- #else
- if (level == Z_DEFAULT_COMPRESSION) level = 6;
- #endif
- if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) {
- return Z_STREAM_ERROR;
- }
- func = configuration_table[s->level].func;
-
- if (func != configuration_table[level].func && strm->total_in != 0) {
- /* Flush the last buffer: */
- err = deflate(strm, Z_PARTIAL_FLUSH);
- }
- if (s->level != level) {
- s->level = level;
- s->max_lazy_match = configuration_table[level].max_lazy;
- s->good_match = configuration_table[level].good_length;
- s->nice_match = configuration_table[level].nice_length;
- s->max_chain_length = configuration_table[level].max_chain;
- }
- s->strategy = strategy;
- return err;
- }
-
- /* ========================================================================= */
- int ZEXPORT deflateTune (z_streamp strm, int good_length, int max_lazy, int nice_length, int max_chain)
- {
- deflate_state *s;
-
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
- s = strm->state;
- s->good_match = good_length;
- s->max_lazy_match = max_lazy;
- s->nice_match = nice_length;
- s->max_chain_length = max_chain;
- return Z_OK;
- }
-
- /* =========================================================================
- * For the default windowBits of 15 and memLevel of 8, this function returns
- * a close to exact, as well as small, upper bound on the compressed size.
- * They are coded as constants here for a reason--if the #define's are
- * changed, then this function needs to be changed as well. The return
- * value for 15 and 8 only works for those exact settings.
- *
- * For any setting other than those defaults for windowBits and memLevel,
- * the value returned is a conservative worst case for the maximum expansion
- * resulting from using fixed blocks instead of stored blocks, which deflate
- * can emit on compressed data for some combinations of the parameters.
- *
- * This function could be more sophisticated to provide closer upper bounds
- * for every combination of windowBits and memLevel, as well as wrap.
- * But even the conservative upper bound of about 14% expansion does not
- * seem onerous for output buffer allocation.
- */
- uLong ZEXPORT deflateBound (z_streamp strm, uLong sourceLen)
- {
- deflate_state *s;
- uLong destLen;
-
- /* conservative upper bound */
- destLen = sourceLen +
- ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 11;
-
- /* if can't get parameters, return conservative bound */
- if (strm == Z_NULL || strm->state == Z_NULL)
- return destLen;
-
- /* if not default parameters, return conservative bound */
- s = strm->state;
- if (s->w_bits != 15 || s->hash_bits != 8 + 7)
- return destLen;
-
- /* default settings: return tight bound for that case */
- return compressBound(sourceLen);
- }
-
- /* =========================================================================
- * Put a short in the pending buffer. The 16-bit value is put in MSB order.
- * IN assertion: the stream state is correct and there is enough room in
- * pending_buf.
- */
- local void putShortMSB (deflate_state *s, uInt b)
- {
- put_byte(s, (Byte)(b >> 8));
- put_byte(s, (Byte)(b & 0xff));
- }
-
- /* =========================================================================
- * Flush as much pending output as possible. All deflate() output goes
- * through this function so some applications may wish to modify it
- * to avoid allocating a large strm->next_out buffer and copying into it.
- * (See also read_buf()).
- */
- local void flush_pending (z_streamp strm)
- {
- unsigned len = strm->state->pending;
-
- if (len > strm->avail_out) len = strm->avail_out;
- if (len == 0) return;
-
- zmemcpy(strm->next_out, strm->state->pending_out, len);
- strm->next_out += len;
- strm->state->pending_out += len;
- strm->total_out += len;
- strm->avail_out -= len;
- strm->state->pending -= len;
- if (strm->state->pending == 0) {
- strm->state->pending_out = strm->state->pending_buf;
- }
- }
-
- /* ========================================================================= */
- int ZEXPORT deflate (z_streamp strm, int flush)
- {
- int old_flush; /* value of flush param for previous deflate call */
- deflate_state *s;
-
- if (strm == Z_NULL || strm->state == Z_NULL ||
- flush > Z_FINISH || flush < 0) {
- return Z_STREAM_ERROR;
- }
- s = strm->state;
-
- if (strm->next_out == Z_NULL ||
- (strm->next_in == Z_NULL && strm->avail_in != 0) ||
- (s->status == FINISH_STATE && flush != Z_FINISH)) {
- ERR_RETURN(strm, Z_STREAM_ERROR);
- }
- if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR);
-
- s->strm = strm; /* just in case */
- old_flush = s->last_flush;
- s->last_flush = flush;
-
- /* Write the header */
- if (s->status == INIT_STATE) {
- #ifdef GZIP
- if (s->wrap == 2) {
- strm->adler = crc32(0L, Z_NULL, 0);
- put_byte(s, 31);
- put_byte(s, 139);
- put_byte(s, 8);
- if (s->gzhead == NULL) {
- put_byte(s, 0);
- put_byte(s, 0);
- put_byte(s, 0);
- put_byte(s, 0);
- put_byte(s, 0);
- put_byte(s, s->level == 9 ? 2 :
- (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
- 4 : 0));
- put_byte(s, OS_CODE);
- s->status = BUSY_STATE;
- }
- else {
- put_byte(s, (s->gzhead->text ? 1 : 0) +
- (s->gzhead->hcrc ? 2 : 0) +
- (s->gzhead->extra == Z_NULL ? 0 : 4) +
- (s->gzhead->name == Z_NULL ? 0 : 8) +
- (s->gzhead->comment == Z_NULL ? 0 : 16)
- );
- put_byte(s, (Byte)(s->gzhead->time & 0xff));
- put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff));
- put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff));
- put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff));
- put_byte(s, s->level == 9 ? 2 :
- (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
- 4 : 0));
- put_byte(s, s->gzhead->os & 0xff);
- if (s->gzhead->extra != NULL) {
- put_byte(s, s->gzhead->extra_len & 0xff);
- put_byte(s, (s->gzhead->extra_len >> 8) & 0xff);
- }
- if (s->gzhead->hcrc)
- strm->adler = crc32(strm->adler, s->pending_buf,
- s->pending);
- s->gzindex = 0;
- s->status = EXTRA_STATE;
- }
- }
- else
- #endif
- {
- uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
- uInt level_flags;
-
- if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2)
- level_flags = 0;
- else if (s->level < 6)
- level_flags = 1;
- else if (s->level == 6)
- level_flags = 2;
- else
- level_flags = 3;
- header |= (level_flags << 6);
- if (s->strstart != 0) header |= PRESET_DICT;
- header += 31 - (header % 31);
-
- s->status = BUSY_STATE;
- putShortMSB(s, header);
-
- /* Save the adler32 of the preset dictionary: */
- if (s->strstart != 0) {
- putShortMSB(s, (uInt)(strm->adler >> 16));
- putShortMSB(s, (uInt)(strm->adler & 0xffff));
- }
- strm->adler = adler32(0L, Z_NULL, 0);
- }
- }
- #ifdef GZIP
- if (s->status == EXTRA_STATE) {
- if (s->gzhead->extra != NULL) {
- uInt beg = s->pending; /* start of bytes to update crc */
-
- while (s->gzindex < (s->gzhead->extra_len & 0xffff)) {
- if (s->pending == s->pending_buf_size) {
- if (s->gzhead->hcrc && s->pending > beg)
- strm->adler = crc32(strm->adler, s->pending_buf + beg,
- s->pending - beg);
- flush_pending(strm);
- beg = s->pending;
- if (s->pending == s->pending_buf_size)
- break;
- }
- put_byte(s, s->gzhead->extra[s->gzindex]);
- s->gzindex++;
- }
- if (s->gzhead->hcrc && s->pending > beg)
- strm->adler = crc32(strm->adler, s->pending_buf + beg,
- s->pending - beg);
- if (s->gzindex == s->gzhead->extra_len) {
- s->gzindex = 0;
- s->status = NAME_STATE;
- }
- }
- else
- s->status = NAME_STATE;
- }
- if (s->status == NAME_STATE) {
- if (s->gzhead->name != NULL) {
- uInt beg = s->pending; /* start of bytes to update crc */
- int val;
-
- do {
- if (s->pending == s->pending_buf_size) {
- if (s->gzhead->hcrc && s->pending > beg)
- strm->adler = crc32(strm->adler, s->pending_buf + beg,
- s->pending - beg);
- flush_pending(strm);
- beg = s->pending;
- if (s->pending == s->pending_buf_size) {
- val = 1;
- break;
- }
- }
- val = s->gzhead->name[s->gzindex++];
- put_byte(s, val);
- } while (val != 0);
- if (s->gzhead->hcrc && s->pending > beg)
- strm->adler = crc32(strm->adler, s->pending_buf + beg,
- s->pending - beg);
- if (val == 0) {
- s->gzindex = 0;
- s->status = COMMENT_STATE;
- }
- }
- else
- s->status = COMMENT_STATE;
- }
- if (s->status == COMMENT_STATE) {
- if (s->gzhead->comment != NULL) {
- uInt beg = s->pending; /* start of bytes to update crc */
- int val;
-
- do {
- if (s->pending == s->pending_buf_size) {
- if (s->gzhead->hcrc && s->pending > beg)
- strm->adler = crc32(strm->adler, s->pending_buf + beg,
- s->pending - beg);
- flush_pending(strm);
- beg = s->pending;
- if (s->pending == s->pending_buf_size) {
- val = 1;
- break;
- }
- }
- val = s->gzhead->comment[s->gzindex++];
- put_byte(s, val);
- } while (val != 0);
- if (s->gzhead->hcrc && s->pending > beg)
- strm->adler = crc32(strm->adler, s->pending_buf + beg,
- s->pending - beg);
- if (val == 0)
- s->status = HCRC_STATE;
- }
- else
- s->status = HCRC_STATE;
- }
- if (s->status == HCRC_STATE) {
- if (s->gzhead->hcrc) {
- if (s->pending + 2 > s->pending_buf_size)
- flush_pending(strm);
- if (s->pending + 2 <= s->pending_buf_size) {
- put_byte(s, (Byte)(strm->adler & 0xff));
- put_byte(s, (Byte)((strm->adler >> 8) & 0xff));
- strm->adler = crc32(0L, Z_NULL, 0);
- s->status = BUSY_STATE;
- }
- }
- else
- s->status = BUSY_STATE;
- }
- #endif
-
- /* Flush as much pending output as possible */
- if (s->pending != 0) {
- flush_pending(strm);
- if (strm->avail_out == 0) {
- /* Since avail_out is 0, deflate will be called again with
- * more output space, but possibly with both pending and
- * avail_in equal to zero. There won't be anything to do,
- * but this is not an error situation so make sure we
- * return OK instead of BUF_ERROR at next call of deflate:
- */
- s->last_flush = -1;
- return Z_OK;
- }
-
- /* Make sure there is something to do and avoid duplicate consecutive
- * flushes. For repeated and useless calls with Z_FINISH, we keep
- * returning Z_STREAM_END instead of Z_BUF_ERROR.
- */
- } else if (strm->avail_in == 0 && flush <= old_flush &&
- flush != Z_FINISH) {
- ERR_RETURN(strm, Z_BUF_ERROR);
- }
-
- /* User must not provide more input after the first FINISH: */
- if (s->status == FINISH_STATE && strm->avail_in != 0) {
- ERR_RETURN(strm, Z_BUF_ERROR);
- }
-
- /* Start a new block or continue the current one.
- */
- if (strm->avail_in != 0 || s->lookahead != 0 ||
- (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
- block_state bstate;
-
- bstate = (*(configuration_table[s->level].func))(s, flush);
-
- if (bstate == finish_started || bstate == finish_done) {
- s->status = FINISH_STATE;
- }
- if (bstate == need_more || bstate == finish_started) {
- if (strm->avail_out == 0) {
- s->last_flush = -1; /* avoid BUF_ERROR next call, see above */
- }
- return Z_OK;
- /* If flush != Z_NO_FLUSH && avail_out == 0, the next call
- * of deflate should use the same flush parameter to make sure
- * that the flush is complete. So we don't have to output an
- * empty block here, this will be done at next call. This also
- * ensures that for a very small output buffer, we emit at most
- * one empty block.
- */
- }
- if (bstate == block_done) {
- if (flush == Z_PARTIAL_FLUSH) {
- _tr_align(s);
- } else { /* FULL_FLUSH or SYNC_FLUSH */
- _tr_stored_block(s, (char*)0, 0L, 0);
- /* For a full flush, this empty block will be recognized
- * as a special marker by inflate_sync().
- */
- if (flush == Z_FULL_FLUSH) {
- CLEAR_HASH(s); /* forget history */
- }
- }
- flush_pending(strm);
- if (strm->avail_out == 0) {
- s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */
- return Z_OK;
- }
- }
- }
- Assert(strm->avail_out > 0, "bug2");
-
- if (flush != Z_FINISH) return Z_OK;
- if (s->wrap <= 0) return Z_STREAM_END;
-
- /* Write the trailer */
- #ifdef GZIP
- if (s->wrap == 2) {
- put_byte(s, (Byte)(strm->adler & 0xff));
- put_byte(s, (Byte)((strm->adler >> 8) & 0xff));
- put_byte(s, (Byte)((strm->adler >> 16) & 0xff));
- put_byte(s, (Byte)((strm->adler >> 24) & 0xff));
- put_byte(s, (Byte)(strm->total_in & 0xff));
- put_byte(s, (Byte)((strm->total_in >> 8) & 0xff));
- put_byte(s, (Byte)((strm->total_in >> 16) & 0xff));
- put_byte(s, (Byte)((strm->total_in >> 24) & 0xff));
- }
- else
- #endif
- {
- putShortMSB(s, (uInt)(strm->adler >> 16));
- putShortMSB(s, (uInt)(strm->adler & 0xffff));
- }
- flush_pending(strm);
- /* If avail_out is zero, the application will call deflate again
- * to flush the rest.
- */
- if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */
- return s->pending != 0 ? Z_OK : Z_STREAM_END;
- }
-
- /* ========================================================================= */
- int ZEXPORT deflateEnd (z_streamp strm)
- {
- int status;
-
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
-
- status = strm->state->status;
- if (status != INIT_STATE &&
- status != EXTRA_STATE &&
- status != NAME_STATE &&
- status != COMMENT_STATE &&
- status != HCRC_STATE &&
- status != BUSY_STATE &&
- status != FINISH_STATE) {
- return Z_STREAM_ERROR;
- }
-
- /* Deallocate in reverse order of allocations: */
- TRY_FREE(strm, strm->state->pending_buf);
- TRY_FREE(strm, strm->state->head);
- TRY_FREE(strm, strm->state->prev);
- TRY_FREE(strm, strm->state->window);
-
- ZFREE(strm, strm->state);
- strm->state = Z_NULL;
-
- return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK;
- }
-
- /* =========================================================================
- * Copy the source state to the destination state.
- * To simplify the source, this is not supported for 16-bit MSDOS (which
- * doesn't have enough memory anyway to duplicate compression states).
- */
- int ZEXPORT deflateCopy (z_streamp dest, z_streamp source)
- {
- #ifdef MAXSEG_64K
- return Z_STREAM_ERROR;
- #else
- deflate_state *ds;
- deflate_state *ss;
- ushf *overlay;
-
- if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) {
- return Z_STREAM_ERROR;
- }
-
- ss = source->state;
-
- zmemcpy(dest, source, sizeof(z_stream));
-
- ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state));
- if (ds == Z_NULL) return Z_MEM_ERROR;
- dest->state = (struct internal_state FAR *) ds;
- zmemcpy(ds, ss, sizeof(deflate_state));
- ds->strm = dest;
-
- ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
- ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos));
- ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos));
- overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2);
- ds->pending_buf = (uchf *) overlay;
-
- if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL ||
- ds->pending_buf == Z_NULL) {
- deflateEnd (dest);
- return Z_MEM_ERROR;
- }
- /* following zmemcpy do not work for 16-bit MSDOS */
- zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte));
- zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos));
- zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos));
- zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);
-
- ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
- ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush);
- ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize;
-
- ds->l_desc.dyn_tree = ds->dyn_ltree;
- ds->d_desc.dyn_tree = ds->dyn_dtree;
- ds->bl_desc.dyn_tree = ds->bl_tree;
-
- return Z_OK;
- #endif /* MAXSEG_64K */
- }
-
- /* ===========================================================================
- * Read a new buffer from the current input stream, update the adler32
- * and total number of bytes read. All deflate() input goes through
- * this function so some applications may wish to modify it to avoid
- * allocating a large strm->next_in buffer and copying from it.
- * (See also flush_pending()).
- */
- local int read_buf (z_streamp strm, Bytef *buf, unsigned size)
- {
- unsigned len = strm->avail_in;
-
- if (len > size) len = size;
- if (len == 0) return 0;
-
- strm->avail_in -= len;
-
- if (strm->state->wrap == 1) {
- strm->adler = adler32(strm->adler, strm->next_in, len);
- }
- #ifdef GZIP
- else if (strm->state->wrap == 2) {
- strm->adler = crc32(strm->adler, strm->next_in, len);
- }
- #endif
- zmemcpy(buf, strm->next_in, len);
- strm->next_in += len;
- strm->total_in += len;
-
- return (int)len;
- }
-
- /* ===========================================================================
- * Initialize the "longest match" routines for a new zlib stream
- */
- local void lm_init (deflate_state *s)
- {
- s->window_size = (ulg)2L*s->w_size;
-
- CLEAR_HASH(s);
-
- /* Set the default configuration parameters:
- */
- s->max_lazy_match = configuration_table[s->level].max_lazy;
- s->good_match = configuration_table[s->level].good_length;
- s->nice_match = configuration_table[s->level].nice_length;
- s->max_chain_length = configuration_table[s->level].max_chain;
-
- s->strstart = 0;
- s->block_start = 0L;
- s->lookahead = 0;
- s->match_length = s->prev_length = MIN_MATCH-1;
- s->match_available = 0;
- s->ins_h = 0;
- #ifndef FASTEST
- #ifdef ASMV
- match_init(); /* initialize the asm code */
- #endif
- #endif
- }
-
- #ifndef FASTEST
- /* ===========================================================================
- * Set match_start to the longest match starting at the given string and
- * return its length. Matches shorter or equal to prev_length are discarded,
- * in which case the result is equal to prev_length and match_start is
- * garbage.
- * IN assertions: cur_match is the head of the hash chain for the current
- * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
- * OUT assertion: the match length is not greater than s->lookahead.
- */
- #ifndef ASMV
- /* For 80x86 and 680x0, an optimized version will be provided in match.asm or
- * match.S. The code will be functionally equivalent.
- */
- local uInt longest_match(deflate_state *s, IPos cur_match)
- {
- unsigned chain_length = s->max_chain_length;/* max hash chain length */
- register Bytef *scan = s->window + s->strstart; /* current string */
- register Bytef *match; /* matched string */
- register int len; /* length of current match */
- int best_len = s->prev_length; /* best match length so far */
- int nice_match = s->nice_match; /* stop if match long enough */
- IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
- s->strstart - (IPos)MAX_DIST(s) : NIL;
- /* Stop when cur_match becomes <= limit. To simplify the code,
- * we prevent matches with the string of window index 0.
- */
- Posf *prev = s->prev;
- uInt wmask = s->w_mask;
-
- #ifdef UNALIGNED_OK
- /* Compare two bytes at a time. Note: this is not always beneficial.
- * Try with and without -DUNALIGNED_OK to check.
- */
- register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
- register ush scan_start = *(ushf*)scan;
- register ush scan_end = *(ushf*)(scan+best_len-1);
- #else
- register Bytef *strend = s->window + s->strstart + MAX_MATCH;
- register Byte scan_end1 = scan[best_len-1];
- register Byte scan_end = scan[best_len];
- #endif
-
- /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
- * It is easy to get rid of this optimization if necessary.
- */
- Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
-
- /* Do not waste too much time if we already have a good match: */
- if (s->prev_length >= s->good_match) {
- chain_length >>= 2;
- }
- /* Do not look for matches beyond the end of the input. This is necessary
- * to make deflate deterministic.
- */
- if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
-
- Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
-
- do {
- Assert(cur_match < s->strstart, "no future");
- match = s->window + cur_match;
-
- /* Skip to next match if the match length cannot increase
- * or if the match length is less than 2. Note that the checks below
- * for insufficient lookahead only occur occasionally for performance
- * reasons. Therefore uninitialized memory will be accessed, and
- * conditional jumps will be made that depend on those values.
- * However the length of the match is limited to the lookahead, so
- * the output of deflate is not affected by the uninitialized values.
- */
- #if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
- /* This code assumes sizeof(unsigned short) == 2. Do not use
- * UNALIGNED_OK if your compiler uses a different size.
- */
- if (*(ushf*)(match+best_len-1) != scan_end ||
- *(ushf*)match != scan_start) continue;
-
- /* It is not necessary to compare scan[2] and match[2] since they are
- * always equal when the other bytes match, given that the hash keys
- * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at
- * strstart+3, +5, ... up to strstart+257. We check for insufficient
- * lookahead only every 4th comparison; the 128th check will be made
- * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is
- * necessary to put more guard bytes at the end of the window, or
- * to check more often for insufficient lookahead.
- */
- Assert(scan[2] == match[2], "scan[2]?");
- scan++, match++;
- do {
- } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
- *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
- *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
- *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
- scan < strend);
- /* The funny "do {}" generates better code on most compilers */
-
- /* Here, scan <= window+strstart+257 */
- Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
- if (*scan == *match) scan++;
-
- len = (MAX_MATCH - 1) - (int)(strend-scan);
- scan = strend - (MAX_MATCH-1);
-
- #else /* UNALIGNED_OK */
-
- if (match[best_len] != scan_end ||
- match[best_len-1] != scan_end1 ||
- *match != *scan ||
- *++match != scan[1]) continue;
-
- /* The check at best_len-1 can be removed because it will be made
- * again later. (This heuristic is not always a win.)
- * It is not necessary to compare scan[2] and match[2] since they
- * are always equal when the other bytes match, given that
- * the hash keys are equal and that HASH_BITS >= 8.
- */
- scan += 2, match++;
- Assert(*scan == *match, "match[2]?");
-
- /* We check for insufficient lookahead only every 8th comparison;
- * the 256th check will be made at strstart+258.
- */
- do {
- } while (*++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- scan < strend);
-
- Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
-
- len = MAX_MATCH - (int)(strend - scan);
- scan = strend - MAX_MATCH;
-
- #endif /* UNALIGNED_OK */
-
- if (len > best_len) {
- s->match_start = cur_match;
- best_len = len;
- if (len >= nice_match) break;
- #ifdef UNALIGNED_OK
- scan_end = *(ushf*)(scan+best_len-1);
- #else
- scan_end1 = scan[best_len-1];
- scan_end = scan[best_len];
- #endif
- }
- } while ((cur_match = prev[cur_match & wmask]) > limit
- && --chain_length != 0);
-
- if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
- return s->lookahead;
- }
- #endif /* ASMV */
- #endif /* FASTEST */
-
- /* ---------------------------------------------------------------------------
- * Optimized version for level == 1 or strategy == Z_RLE only
- */
- local uInt longest_match_fast (deflate_state *s, IPos cur_match)
- {
- register Bytef *scan = s->window + s->strstart; /* current string */
- register Bytef *match; /* matched string */
- register int len; /* length of current match */
- register Bytef *strend = s->window + s->strstart + MAX_MATCH;
-
- /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
- * It is easy to get rid of this optimization if necessary.
- */
- Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
-
- Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
-
- Assert(cur_match < s->strstart, "no future");
-
- match = s->window + cur_match;
-
- /* Return failure if the match length is less than 2:
- */
- if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1;
-
- /* The check at best_len-1 can be removed because it will be made
- * again later. (This heuristic is not always a win.)
- * It is not necessary to compare scan[2] and match[2] since they
- * are always equal when the other bytes match, given that
- * the hash keys are equal and that HASH_BITS >= 8.
- */
- scan += 2, match += 2;
- Assert(*scan == *match, "match[2]?");
-
- /* We check for insufficient lookahead only every 8th comparison;
- * the 256th check will be made at strstart+258.
- */
- do {
- } while (*++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- scan < strend);
-
- Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
-
- len = MAX_MATCH - (int)(strend - scan);
-
- if (len < MIN_MATCH) return MIN_MATCH - 1;
-
- s->match_start = cur_match;
- return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead;
- }
-
- #ifdef DEBUG
- /* ===========================================================================
- * Check that the match at match_start is indeed a match.
- */
- local void check_match(deflate_state *s, IPos start, IPos match, int length)
- {
- /* check that the match is indeed a match */
- if (zmemcmp(s->window + match,
- s->window + start, length) != EQUAL) {
- fprintf(stderr, " start %u, match %u, length %d\n",
- start, match, length);
- do {
- fprintf(stderr, "%c%c", s->window[match++], s->window[start++]);
- } while (--length != 0);
- z_error("invalid match");
- }
- if (z_verbose > 1) {
- fprintf(stderr,"\\[%d,%d]", start-match, length);
- do { putc(s->window[start++], stderr); } while (--length != 0);
- }
- }
- #else
- # define check_match(s, start, match, length)
- #endif /* DEBUG */
-
- /* ===========================================================================
- * Fill the window when the lookahead becomes insufficient.
- * Updates strstart and lookahead.
- *
- * IN assertion: lookahead < MIN_LOOKAHEAD
- * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
- * At least one byte has been read, or avail_in == 0; reads are
- * performed for at least two bytes (required for the zip translate_eol
- * option -- not supported here).
- */
- local void fill_window (deflate_state *s)
- {
- register unsigned n, m;
- register Posf *p;
- unsigned more; /* Amount of free space at the end of the window. */
- uInt wsize = s->w_size;
-
- do {
- more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);
-
- /* Deal with !@#$% 64K limit: */
- if (sizeof(int) <= 2) {
- if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
- more = wsize;
-
- } else if (more == (unsigned)(-1)) {
- /* Very unlikely, but possible on 16 bit machine if
- * strstart == 0 && lookahead == 1 (input done a byte at time)
- */
- more--;
- }
- }
-
- /* If the window is almost full and there is insufficient lookahead,
- * move the upper half to the lower one to make room in the upper half.
- */
- if (s->strstart >= wsize+MAX_DIST(s)) {
-
- zmemcpy(s->window, s->window+wsize, (unsigned)wsize);
- s->match_start -= wsize;
- s->strstart -= wsize; /* we now have strstart >= MAX_DIST */
- s->block_start -= (long) wsize;
-
- /* Slide the hash table (could be avoided with 32 bit values
- at the expense of memory usage). We slide even when level == 0
- to keep the hash table consistent if we switch back to level > 0
- later. (Using level 0 permanently is not an optimal usage of
- zlib, so we don't care about this pathological case.)
- */
- /* %%% avoid this when Z_RLE */
- n = s->hash_size;
- p = &s->head[n];
- do {
- m = *--p;
- *p = (Pos)(m >= wsize ? m-wsize : NIL);
- } while (--n);
-
- n = wsize;
- #ifndef FASTEST
- p = &s->prev[n];
- do {
- m = *--p;
- *p = (Pos)(m >= wsize ? m-wsize : NIL);
- /* If n is not on any hash chain, prev[n] is garbage but
- * its value will never be used.
- */
- } while (--n);
- #endif
- more += wsize;
- }
- if (s->strm->avail_in == 0) return;
-
- /* If there was no sliding:
- * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
- * more == window_size - lookahead - strstart
- * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
- * => more >= window_size - 2*WSIZE + 2
- * In the BIG_MEM or MMAP case (not yet supported),
- * window_size == input_size + MIN_LOOKAHEAD &&
- * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
- * Otherwise, window_size == 2*WSIZE so more >= 2.
- * If there was sliding, more >= WSIZE. So in all cases, more >= 2.
- */
- Assert(more >= 2, "more < 2");
-
- n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more);
- s->lookahead += n;
-
- /* Initialize the hash value now that we have some input: */
- if (s->lookahead >= MIN_MATCH) {
- s->ins_h = s->window[s->strstart];
- UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
- #if MIN_MATCH != 3
- Call UPDATE_HASH() MIN_MATCH-3 more times
- #endif
- }
- /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
- * but this is not important since only literal bytes will be emitted.
- */
-
- } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0);
- }
-
- /* ===========================================================================
- * Flush the current block, with given end-of-file flag.
- * IN assertion: strstart is set to the end of the current match.
- */
- #define FLUSH_BLOCK_ONLY(s, eof) { \
- _tr_flush_block(s, (s->block_start >= 0L ? \
- (charf *)&s->window[(unsigned)s->block_start] : \
- (charf *)Z_NULL), \
- (ulg)((long)s->strstart - s->block_start), \
- (eof)); \
- s->block_start = s->strstart; \
- flush_pending(s->strm); \
- Tracev((stderr,"[FLUSH]")); \
- }
-
- /* Same but force premature exit if necessary. */
- #define FLUSH_BLOCK(s, eof) { \
- FLUSH_BLOCK_ONLY(s, eof); \
- if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \
- }
-
- /* ===========================================================================
- * Copy without compression as much as possible from the input stream, return
- * the current block state.
- * This function does not insert new strings in the dictionary since
- * uncompressible data is probably not useful. This function is used
- * only for the level=0 compression option.
- * NOTE: this function should be optimized to avoid extra copying from
- * window to pending_buf.
- */
- local block_state deflate_stored(deflate_state *s, int flush)
- {
- /* Stored blocks are limited to 0xffff bytes, pending_buf is limited
- * to pending_buf_size, and each stored block has a 5 byte header:
- */
- ulg max_block_size = 0xffff;
- ulg max_start;
-
- if (max_block_size > s->pending_buf_size - 5) {
- max_block_size = s->pending_buf_size - 5;
- }
-
- /* Copy as much as possible from input to output: */
- for (;;) {
- /* Fill the window as much as possible: */
- if (s->lookahead <= 1) {
-
- Assert(s->strstart < s->w_size+MAX_DIST(s) ||
- s->block_start >= (long)s->w_size, "slide too late");
-
- fill_window(s);
- if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more;
-
- if (s->lookahead == 0) break; /* flush the current block */
- }
- Assert(s->block_start >= 0L, "block gone");
-
- s->strstart += s->lookahead;
- s->lookahead = 0;
-
- /* Emit a stored block if pending_buf will be full: */
- max_start = s->block_start + max_block_size;
- if (s->strstart == 0 || (ulg)s->strstart >= max_start) {
- /* strstart == 0 is possible when wraparound on 16-bit machine */
- s->lookahead = (uInt)(s->strstart - max_start);
- s->strstart = (uInt)max_start;
- FLUSH_BLOCK(s, 0);
- }
- /* Flush if we may have to slide, otherwise block_start may become
- * negative and the data will be gone:
- */
- if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) {
- FLUSH_BLOCK(s, 0);
- }
- }
- FLUSH_BLOCK(s, flush == Z_FINISH);
- return flush == Z_FINISH ? finish_done : block_done;
- }
-
- /* ===========================================================================
- * Compress as much as possible from the input stream, return the current
- * block state.
- * This function does not perform lazy evaluation of matches and inserts
- * new strings in the dictionary only for unmatched strings or for short
- * matches. It is used only for the fast compression options.
- */
- local block_state deflate_fast(deflate_state *s, int flush)
- {
- IPos hash_head = NIL; /* head of the hash chain */
- int bflush; /* set if current block must be flushed */
-
- for (;;) {
- /* Make sure that we always have enough lookahead, except
- * at the end of the input file. We need MAX_MATCH bytes
- * for the next match, plus MIN_MATCH bytes to insert the
- * string following the next match.
- */
- if (s->lookahead < MIN_LOOKAHEAD) {
- fill_window(s);
- if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
- return need_more;
- }
- if (s->lookahead == 0) break; /* flush the current block */
- }
-
- /* Insert the string window[strstart .. strstart+2] in the
- * dictionary, and set hash_head to the head of the hash chain:
- */
- if (s->lookahead >= MIN_MATCH) {
- INSERT_STRING(s, s->strstart, hash_head);
- }
-
- /* Find the longest match, discarding those <= prev_length.
- * At this point we have always match_length < MIN_MATCH
- */
- if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) {
- /* To simplify the code, we prevent matches with the string
- * of window index 0 (in particular we have to avoid a match
- * of the string with itself at the start of the input file).
- */
- #ifdef FASTEST
- if ((s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) ||
- (s->strategy == Z_RLE && s->strstart - hash_head == 1)) {
- s->match_length = longest_match_fast (s, hash_head);
- }
- #else
- if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) {
- s->match_length = longest_match (s, hash_head);
- } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) {
- s->match_length = longest_match_fast (s, hash_head);
- }
- #endif
- /* longest_match() or longest_match_fast() sets match_start */
- }
- if (s->match_length >= MIN_MATCH) {
- check_match(s, s->strstart, s->match_start, s->match_length);
-
- _tr_tally_dist(s, s->strstart - s->match_start,
- s->match_length - MIN_MATCH, bflush);
-
- s->lookahead -= s->match_length;
-
- /* Insert new strings in the hash table only if the match length
- * is not too large. This saves time but degrades compression.
- */
- #ifndef FASTEST
- if (s->match_length <= s->max_insert_length &&
- s->lookahead >= MIN_MATCH) {
- s->match_length--; /* string at strstart already in table */
- do {
- s->strstart++;
- INSERT_STRING(s, s->strstart, hash_head);
- /* strstart never exceeds WSIZE-MAX_MATCH, so there are
- * always MIN_MATCH bytes ahead.
- */
- } while (--s->match_length != 0);
- s->strstart++;
- } else
- #endif
- {
- s->strstart += s->match_length;
- s->match_length = 0;
- s->ins_h = s->window[s->strstart];
- UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
- #if MIN_MATCH != 3
- Call UPDATE_HASH() MIN_MATCH-3 more times
- #endif
- /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not
- * matter since it will be recomputed at next deflate call.
- */
- }
- } else {
- /* No match, output a literal byte */
- Tracevv((stderr,"%c", s->window[s->strstart]));
- _tr_tally_lit (s, s->window[s->strstart], bflush);
- s->lookahead--;
- s->strstart++;
- }
- if (bflush) FLUSH_BLOCK(s, 0);
- }
- FLUSH_BLOCK(s, flush == Z_FINISH);
- return flush == Z_FINISH ? finish_done : block_done;
- }
-
- #ifndef FASTEST
- /* ===========================================================================
- * Same as above, but achieves better compression. We use a lazy
- * evaluation for matches: a match is finally adopted only if there is
- * no better match at the next window position.
- */
- local block_state deflate_slow(deflate_state *s, int flush)
- {
- IPos hash_head = NIL; /* head of hash chain */
- int bflush; /* set if current block must be flushed */
-
- /* Process the input block. */
- for (;;) {
- /* Make sure that we always have enough lookahead, except
- * at the end of the input file. We need MAX_MATCH bytes
- * for the next match, plus MIN_MATCH bytes to insert the
- * string following the next match.
- */
- if (s->lookahead < MIN_LOOKAHEAD) {
- fill_window(s);
- if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
- return need_more;
- }
- if (s->lookahead == 0) break; /* flush the current block */
- }
-
- /* Insert the string window[strstart .. strstart+2] in the
- * dictionary, and set hash_head to the head of the hash chain:
- */
- if (s->lookahead >= MIN_MATCH) {
- INSERT_STRING(s, s->strstart, hash_head);
- }
-
- /* Find the longest match, discarding those <= prev_length.
- */
- s->prev_length = s->match_length, s->prev_match = s->match_start;
- s->match_length = MIN_MATCH-1;
-
- if (hash_head != NIL && s->prev_length < s->max_lazy_match &&
- s->strstart - hash_head <= MAX_DIST(s)) {
- /* To simplify the code, we prevent matches with the string
- * of window index 0 (in particular we have to avoid a match
- * of the string with itself at the start of the input file).
- */
- if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) {
- s->match_length = longest_match (s, hash_head);
- } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) {
- s->match_length = longest_match_fast (s, hash_head);
- }
- /* longest_match() or longest_match_fast() sets match_start */
-
- if (s->match_length <= 5 && (s->strategy == Z_FILTERED
- #if TOO_FAR <= 32767
- || (s->match_length == MIN_MATCH &&
- s->strstart - s->match_start > TOO_FAR)
- #endif
- )) {
-
- /* If prev_match is also MIN_MATCH, match_start is garbage
- * but we will ignore the current match anyway.
- */
- s->match_length = MIN_MATCH-1;
- }
- }
- /* If there was a match at the previous step and the current
- * match is not better, output the previous match:
- */
- if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) {
- uInt max_insert = s->strstart + s->lookahead - MIN_MATCH;
- /* Do not insert strings in hash table beyond this. */
-
- check_match(s, s->strstart-1, s->prev_match, s->prev_length);
-
- _tr_tally_dist(s, s->strstart -1 - s->prev_match,
- s->prev_length - MIN_MATCH, bflush);
-
- /* Insert in hash table all strings up to the end of the match.
- * strstart-1 and strstart are already inserted. If there is not
- * enough lookahead, the last two strings are not inserted in
- * the hash table.
- */
- s->lookahead -= s->prev_length-1;
- s->prev_length -= 2;
- do {
- if (++s->strstart <= max_insert) {
- INSERT_STRING(s, s->strstart, hash_head);
- }
- } while (--s->prev_length != 0);
- s->match_available = 0;
- s->match_length = MIN_MATCH-1;
- s->strstart++;
-
- if (bflush) FLUSH_BLOCK(s, 0);
-
- } else if (s->match_available) {
- /* If there was no match at the previous position, output a
- * single literal. If there was a match but the current match
- * is longer, truncate the previous match to a single literal.
- */
- Tracevv((stderr,"%c", s->window[s->strstart-1]));
- _tr_tally_lit(s, s->window[s->strstart-1], bflush);
- if (bflush) {
- FLUSH_BLOCK_ONLY(s, 0);
- }
- s->strstart++;
- s->lookahead--;
- if (s->strm->avail_out == 0) return need_more;
- } else {
- /* There is no previous match to compare with, wait for
- * the next step to decide.
- */
- s->match_available = 1;
- s->strstart++;
- s->lookahead--;
- }
- }
- Assert (flush != Z_NO_FLUSH, "no flush?");
- if (s->match_available) {
- Tracevv((stderr,"%c", s->window[s->strstart-1]));
- _tr_tally_lit(s, s->window[s->strstart-1], bflush);
- s->match_available = 0;
- }
- FLUSH_BLOCK(s, flush == Z_FINISH);
- return flush == Z_FINISH ? finish_done : block_done;
- }
- #endif /* FASTEST */
-
- #if 0
- /* ===========================================================================
- * For Z_RLE, simply look for runs of bytes, generate matches only of distance
- * one. Do not maintain a hash table. (It will be regenerated if this run of
- * deflate switches away from Z_RLE.)
- */
- local block_state deflate_rle(s, flush)
- deflate_state *s;
- int flush;
- {
- int bflush; /* set if current block must be flushed */
- uInt run; /* length of run */
- uInt max; /* maximum length of run */
- uInt prev; /* byte at distance one to match */
- Bytef *scan; /* scan for end of run */
-
- for (;;) {
- /* Make sure that we always have enough lookahead, except
- * at the end of the input file. We need MAX_MATCH bytes
- * for the longest encodable run.
- */
- if (s->lookahead < MAX_MATCH) {
- fill_window(s);
- if (s->lookahead < MAX_MATCH && flush == Z_NO_FLUSH) {
- return need_more;
- }
- if (s->lookahead == 0) break; /* flush the current block */
- }
-
- /* See how many times the previous byte repeats */
- run = 0;
- if (s->strstart > 0) { /* if there is a previous byte, that is */
- max = s->lookahead < MAX_MATCH ? s->lookahead : MAX_MATCH;
- scan = s->window + s->strstart - 1;
- prev = *scan++;
- do {
- if (*scan++ != prev)
- break;
- } while (++run < max);
- }
-
- /* Emit match if have run of MIN_MATCH or longer, else emit literal */
- if (run >= MIN_MATCH) {
- check_match(s, s->strstart, s->strstart - 1, run);
- _tr_tally_dist(s, 1, run - MIN_MATCH, bflush);
- s->lookahead -= run;
- s->strstart += run;
- } else {
- /* No match, output a literal byte */
- Tracevv((stderr,"%c", s->window[s->strstart]));
- _tr_tally_lit (s, s->window[s->strstart], bflush);
- s->lookahead--;
- s->strstart++;
- }
- if (bflush) FLUSH_BLOCK(s, 0);
- }
- FLUSH_BLOCK(s, flush == Z_FINISH);
- return flush == Z_FINISH ? finish_done : block_done;
- }
- #endif
- /********* End of inlined file: deflate.c *********/
-
- /********* Start of inlined file: infback.c *********/
- /*
- This code is largely copied from inflate.c. Normally either infback.o or
- inflate.o would be linked into an application--not both. The interface
- with inffast.c is retained so that optimized assembler-coded versions of
- inflate_fast() can be used with either inflate.c or infback.c.
- */
-
- /********* Start of inlined file: inftrees.h *********/
- /* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
- #ifndef _INFTREES_H_
- #define _INFTREES_H_
-
- /* Structure for decoding tables. Each entry provides either the
- information needed to do the operation requested by the code that
- indexed that table entry, or it provides a pointer to another
- table that indexes more bits of the code. op indicates whether
- the entry is a pointer to another table, a literal, a length or
- distance, an end-of-block, or an invalid code. For a table
- pointer, the low four bits of op is the number of index bits of
- that table. For a length or distance, the low four bits of op
- is the number of extra bits to get after the code. bits is
- the number of bits in this code or part of the code to drop off
- of the bit buffer. val is the actual byte to output in the case
- of a literal, the base length or distance, or the offset from
- the current table to the next table. Each entry is four bytes. */
- typedef struct {
- unsigned char op; /* operation, extra bits, table bits */
- unsigned char bits; /* bits in this part of the code */
- unsigned short val; /* offset in table or code value */
- } code;
-
- /* op values as set by inflate_table():
- 00000000 - literal
- 0000tttt - table link, tttt != 0 is the number of table index bits
- 0001eeee - length or distance, eeee is the number of extra bits
- 01100000 - end of block
- 01000000 - invalid code
- */
-
- /* Maximum size of dynamic tree. The maximum found in a long but non-
- exhaustive search was 1444 code structures (852 for length/literals
- and 592 for distances, the latter actually the result of an
- exhaustive search). The true maximum is not known, but the value
- below is more than safe. */
- #define ENOUGH 2048
- #define MAXD 592
-
- /* Type of code to build for inftable() */
- typedef enum {
- CODES,
- LENS,
- DISTS
- } codetype;
-
- extern int inflate_table OF((codetype type, unsigned short FAR *lens,
- unsigned codes, code FAR * FAR *table,
- unsigned FAR *bits, unsigned short FAR *work));
-
- #endif
- /********* End of inlined file: inftrees.h *********/
-
- /********* Start of inlined file: inflate.h *********/
- /* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
- #ifndef _INFLATE_H_
- #define _INFLATE_H_
-
- /* define NO_GZIP when compiling if you want to disable gzip header and
- trailer decoding by inflate(). NO_GZIP would be used to avoid linking in
- the crc code when it is not needed. For shared libraries, gzip decoding
- should be left enabled. */
- #ifndef NO_GZIP
- # define GUNZIP
- #endif
-
- /* Possible inflate modes between inflate() calls */
- typedef enum {
- HEAD, /* i: waiting for magic header */
- FLAGS, /* i: waiting for method and flags (gzip) */
- TIME, /* i: waiting for modification time (gzip) */
- OS, /* i: waiting for extra flags and operating system (gzip) */
- EXLEN, /* i: waiting for extra length (gzip) */
- EXTRA, /* i: waiting for extra bytes (gzip) */
- NAME, /* i: waiting for end of file name (gzip) */
- COMMENT, /* i: waiting for end of comment (gzip) */
- HCRC, /* i: waiting for header crc (gzip) */
- DICTID, /* i: waiting for dictionary check value */
- DICT, /* waiting for inflateSetDictionary() call */
- TYPE, /* i: waiting for type bits, including last-flag bit */
- TYPEDO, /* i: same, but skip check to exit inflate on new block */
- STORED, /* i: waiting for stored size (length and complement) */
- COPY, /* i/o: waiting for input or output to copy stored block */
- TABLE, /* i: waiting for dynamic block table lengths */
- LENLENS, /* i: waiting for code length code lengths */
- CODELENS, /* i: waiting for length/lit and distance code lengths */
- LEN, /* i: waiting for length/lit code */
- LENEXT, /* i: waiting for length extra bits */
- DIST, /* i: waiting for distance code */
- DISTEXT, /* i: waiting for distance extra bits */
- MATCH, /* o: waiting for output space to copy string */
- LIT, /* o: waiting for output space to write literal */
- CHECK, /* i: waiting for 32-bit check value */
- LENGTH, /* i: waiting for 32-bit length (gzip) */
- DONE, /* finished check, done -- remain here until reset */
- BAD, /* got a data error -- remain here until reset */
- MEM, /* got an inflate() memory error -- remain here until reset */
- SYNC /* looking for synchronization bytes to restart inflate() */
- } inflate_mode;
-
- /*
- State transitions between above modes -
-
- (most modes can go to the BAD or MEM mode -- not shown for clarity)
-
- Process header:
- HEAD -> (gzip) or (zlib)
- (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME
- NAME -> COMMENT -> HCRC -> TYPE
- (zlib) -> DICTID or TYPE
- DICTID -> DICT -> TYPE
- Read deflate blocks:
- TYPE -> STORED or TABLE or LEN or CHECK
- STORED -> COPY -> TYPE
- TABLE -> LENLENS -> CODELENS -> LEN
- Read deflate codes:
- LEN -> LENEXT or LIT or TYPE
- LENEXT -> DIST -> DISTEXT -> MATCH -> LEN
- LIT -> LEN
- Process trailer:
- CHECK -> LENGTH -> DONE
- */
-
- /* state maintained between inflate() calls. Approximately 7K bytes. */
- struct inflate_state {
- inflate_mode mode; /* current inflate mode */
- int last; /* true if processing last block */
- int wrap; /* bit 0 true for zlib, bit 1 true for gzip */
- int havedict; /* true if dictionary provided */
- int flags; /* gzip header method and flags (0 if zlib) */
- unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */
- unsigned long check; /* protected copy of check value */
- unsigned long total; /* protected copy of output count */
- gz_headerp head; /* where to save gzip header information */
- /* sliding window */
- unsigned wbits; /* log base 2 of requested window size */
- unsigned wsize; /* window size or zero if not using window */
- unsigned whave; /* valid bytes in the window */
- unsigned write; /* window write index */
- unsigned char FAR *window; /* allocated sliding window, if needed */
- /* bit accumulator */
- unsigned long hold; /* input bit accumulator */
- unsigned bits; /* number of bits in "in" */
- /* for string and stored block copying */
- unsigned length; /* literal or length of data to copy */
- unsigned offset; /* distance back to copy string from */
- /* for table and code decoding */
- unsigned extra; /* extra bits needed */
- /* fixed and dynamic code tables */
- code const FAR *lencode; /* starting table for length/literal codes */
- code const FAR *distcode; /* starting table for distance codes */
- unsigned lenbits; /* index bits for lencode */
- unsigned distbits; /* index bits for distcode */
- /* dynamic table building */
- unsigned ncode; /* number of code length code lengths */
- unsigned nlen; /* number of length code lengths */
- unsigned ndist; /* number of distance code lengths */
- unsigned have; /* number of code lengths in lens[] */
- code FAR *next; /* next available space in codes[] */
- unsigned short lens[320]; /* temporary storage for code lengths */
- unsigned short work[288]; /* work area for code table building */
- code codes[ENOUGH]; /* space for code tables */
- };
-
- #endif
- /********* End of inlined file: inflate.h *********/
-
- /********* Start of inlined file: inffast.h *********/
- /* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
- void inflate_fast OF((z_streamp strm, unsigned start));
- /********* End of inlined file: inffast.h *********/
-
- /* function prototypes */
- local void fixedtables1 OF((struct inflate_state FAR *state));
-
- /*
- strm provides memory allocation functions in zalloc and zfree, or
- Z_NULL to use the library memory allocation functions.
-
- windowBits is in the range 8..15, and window is a user-supplied
- window and output buffer that is 2**windowBits bytes.
- */
- int ZEXPORT inflateBackInit_(z_streamp strm, int windowBits, unsigned char FAR *window, const char *version, int stream_size)
- {
- struct inflate_state FAR *state;
-
- if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
- stream_size != (int)(sizeof(z_stream)))
- return Z_VERSION_ERROR;
- if (strm == Z_NULL || window == Z_NULL ||
- windowBits < 8 || windowBits > 15)
- return Z_STREAM_ERROR;
- strm->msg = Z_NULL; /* in case we return an error */
- if (strm->zalloc == (alloc_func)0) {
- strm->zalloc = zcalloc;
- strm->opaque = (voidpf)0;
- }
- if (strm->zfree == (free_func)0) strm->zfree = zcfree;
- state = (struct inflate_state FAR *)ZALLOC(strm, 1,
- sizeof(struct inflate_state));
- if (state == Z_NULL) return Z_MEM_ERROR;
- Tracev((stderr, "inflate: allocated\n"));
- strm->state = (struct internal_state FAR *)state;
- state->dmax = 32768U;
- state->wbits = windowBits;
- state->wsize = 1U << windowBits;
- state->window = window;
- state->write = 0;
- state->whave = 0;
- return Z_OK;
- }
-
- /*
- Return state with length and distance decoding tables and index sizes set to
- fixed code decoding. Normally this returns fixed tables from inffixed.h.
- If BUILDFIXED is defined, then instead this routine builds the tables the
- first time it's called, and returns those tables the first time and
- thereafter. This reduces the size of the code by about 2K bytes, in
- exchange for a little execution time. However, BUILDFIXED should not be
- used for threaded applications, since the rewriting of the tables and virgin
- may not be thread-safe.
- */
- local void fixedtables1 (struct inflate_state FAR *state)
- {
- #ifdef BUILDFIXED
- static int virgin = 1;
- static code *lenfix, *distfix;
- static code fixed[544];
-
- /* build fixed huffman tables if first call (may not be thread safe) */
- if (virgin) {
- unsigned sym, bits;
- static code *next;
-
- /* literal/length table */
- sym = 0;
- while (sym < 144) state->lens[sym++] = 8;
- while (sym < 256) state->lens[sym++] = 9;
- while (sym < 280) state->lens[sym++] = 7;
- while (sym < 288) state->lens[sym++] = 8;
- next = fixed;
- lenfix = next;
- bits = 9;
- inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work);
-
- /* distance table */
- sym = 0;
- while (sym < 32) state->lens[sym++] = 5;
- distfix = next;
- bits = 5;
- inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work);
-
- /* do this just once */
- virgin = 0;
- }
- #else /* !BUILDFIXED */
-
- /********* Start of inlined file: inffixed.h *********/
- /* inffixed.h -- table for decoding fixed codes
- * Generated automatically by makefixed().
- */
-
- /* WARNING: this file should *not* be used by applications. It
- is part of the implementation of the compression library and
- is subject to change. Applications should only use zlib.h.
- */
-
- static const code lenfix[512] = {
- {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48},
- {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128},
- {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59},
- {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176},
- {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20},
- {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100},
- {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8},
- {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216},
- {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76},
- {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114},
- {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2},
- {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148},
- {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42},
- {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86},
- {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15},
- {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236},
- {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62},
- {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142},
- {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31},
- {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162},
- {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25},
- {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105},
- {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4},
- {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202},
- {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69},
- {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125},
- {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13},
- {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195},
- {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35},
- {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91},
- {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19},
- {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246},
- {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55},
- {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135},
- {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99},
- {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190},
- {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16},
- {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96},
- {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6},
- {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209},
- {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72},
- {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116},
- {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4},
- {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153},
- {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44},
- {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82},
- {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11},
- {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229},
- {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58},
- {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138},
- {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51},
- {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173},
- {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30},
- {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110},
- {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0},
- {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195},
- {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65},
- {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121},
- {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9},
- {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258},
- {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37},
- {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93},
- {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23},
- {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251},
- {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51},
- {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131},
- {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67},
- {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183},
- {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23},
- {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103},
- {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9},
- {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223},
- {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79},
- {0,9,255}
- };
-
- static const code distfix[32] = {
- {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025},
- {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193},
- {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385},
- {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577},
- {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073},
- {22,5,193},{64,5,0}
- };
- /********* End of inlined file: inffixed.h *********/
-
- #endif /* BUILDFIXED */
- state->lencode = lenfix;
- state->lenbits = 9;
- state->distcode = distfix;
- state->distbits = 5;
- }
-
- /* Macros for inflateBack(): */
-
- /* Load returned state from inflate_fast() */
- #define LOAD() \
- do { \
- put = strm->next_out; \
- left = strm->avail_out; \
- next = strm->next_in; \
- have = strm->avail_in; \
- hold = state->hold; \
- bits = state->bits; \
- } while (0)
-
- /* Set state from registers for inflate_fast() */
- #define RESTORE() \
- do { \
- strm->next_out = put; \
- strm->avail_out = left; \
- strm->next_in = next; \
- strm->avail_in = have; \
- state->hold = hold; \
- state->bits = bits; \
- } while (0)
-
- /* Clear the input bit accumulator */
- #define INITBITS() \
- do { \
- hold = 0; \
- bits = 0; \
- } while (0)
-
- /* Assure that some input is available. If input is requested, but denied,
- then return a Z_BUF_ERROR from inflateBack(). */
- #define PULL() \
- do { \
- if (have == 0) { \
- have = in(in_desc, &next); \
- if (have == 0) { \
- next = Z_NULL; \
- ret = Z_BUF_ERROR; \
- goto inf_leave; \
- } \
- } \
- } while (0)
-
- /* Get a byte of input into the bit accumulator, or return from inflateBack()
- with an error if there is no input available. */
- #define PULLBYTE() \
- do { \
- PULL(); \
- have--; \
- hold += (unsigned long)(*next++) << bits; \
- bits += 8; \
- } while (0)
-
- /* Assure that there are at least n bits in the bit accumulator. If there is
- not enough available input to do that, then return from inflateBack() with
- an error. */
- #define NEEDBITS(n) \
- do { \
- while (bits < (unsigned)(n)) \
- PULLBYTE(); \
- } while (0)
-
- /* Return the low n bits of the bit accumulator (n < 16) */
- #define BITS(n) \
- ((unsigned)hold & ((1U << (n)) - 1))
-
- /* Remove n bits from the bit accumulator */
- #define DROPBITS(n) \
- do { \
- hold >>= (n); \
- bits -= (unsigned)(n); \
- } while (0)
-
- /* Remove zero to seven bits as needed to go to a byte boundary */
- #define BYTEBITS() \
- do { \
- hold >>= bits & 7; \
- bits -= bits & 7; \
- } while (0)
-
- /* Assure that some output space is available, by writing out the window
- if it's full. If the write fails, return from inflateBack() with a
- Z_BUF_ERROR. */
- #define ROOM() \
- do { \
- if (left == 0) { \
- put = state->window; \
- left = state->wsize; \
- state->whave = left; \
- if (out(out_desc, put, left)) { \
- ret = Z_BUF_ERROR; \
- goto inf_leave; \
- } \
- } \
- } while (0)
-
- /*
- strm provides the memory allocation functions and window buffer on input,
- and provides information on the unused input on return. For Z_DATA_ERROR
- returns, strm will also provide an error message.
-
- in() and out() are the call-back input and output functions. When
- inflateBack() needs more input, it calls in(). When inflateBack() has
- filled the window with output, or when it completes with data in the
- window, it calls out() to write out the data. The application must not
- change the provided input until in() is called again or inflateBack()
- returns. The application must not change the window/output buffer until
- inflateBack() returns.
-
- in() and out() are called with a descriptor parameter provided in the
- inflateBack() call. This parameter can be a structure that provides the
- information required to do the read or write, as well as accumulated
- information on the input and output such as totals and check values.
-
- in() should return zero on failure. out() should return non-zero on
- failure. If either in() or out() fails, than inflateBack() returns a
- Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it
- was in() or out() that caused in the error. Otherwise, inflateBack()
- returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format
- error, or Z_MEM_ERROR if it could not allocate memory for the state.
- inflateBack() can also return Z_STREAM_ERROR if the input parameters
- are not correct, i.e. strm is Z_NULL or the state was not initialized.
- */
- int ZEXPORT inflateBack(z_streamp strm, in_func in, void FAR *in_desc, out_func out, void FAR *out_desc)
- {
- struct inflate_state FAR *state;
- unsigned char FAR *next; /* next input */
- unsigned char FAR *put; /* next output */
- unsigned have, left; /* available input and output */
- unsigned long hold; /* bit buffer */
- unsigned bits; /* bits in bit buffer */
- unsigned copy; /* number of stored or match bytes to copy */
- unsigned char FAR *from; /* where to copy match bytes from */
- code thisx; /* current decoding table entry */
- code last; /* parent table entry */
- unsigned len; /* length to copy for repeats, bits to drop */
- int ret; /* return code */
- static const unsigned short order[19] = /* permutation of code lengths */
- {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
-
- /* Check that the strm exists and that the state was initialized */
- if (strm == Z_NULL || strm->state == Z_NULL)
- return Z_STREAM_ERROR;
- state = (struct inflate_state FAR *)strm->state;
-
- /* Reset the state */
- strm->msg = Z_NULL;
- state->mode = TYPE;
- state->last = 0;
- state->whave = 0;
- next = strm->next_in;
- have = next != Z_NULL ? strm->avail_in : 0;
- hold = 0;
- bits = 0;
- put = state->window;
- left = state->wsize;
-
- /* Inflate until end of block marked as last */
- for (;;)
- switch (state->mode) {
- case TYPE:
- /* determine and dispatch block type */
- if (state->last) {
- BYTEBITS();
- state->mode = DONE;
- break;
- }
- NEEDBITS(3);
- state->last = BITS(1);
- DROPBITS(1);
- switch (BITS(2)) {
- case 0: /* stored block */
- Tracev((stderr, "inflate: stored block%s\n",
- state->last ? " (last)" : ""));
- state->mode = STORED;
- break;
- case 1: /* fixed block */
- fixedtables1(state);
- Tracev((stderr, "inflate: fixed codes block%s\n",
- state->last ? " (last)" : ""));
- state->mode = LEN; /* decode codes */
- break;
- case 2: /* dynamic block */
- Tracev((stderr, "inflate: dynamic codes block%s\n",
- state->last ? " (last)" : ""));
- state->mode = TABLE;
- break;
- case 3:
- strm->msg = (char *)"invalid block type";
- state->mode = BAD;
- }
- DROPBITS(2);
- break;
-
- case STORED:
- /* get and verify stored block length */
- BYTEBITS(); /* go to byte boundary */
- NEEDBITS(32);
- if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
- strm->msg = (char *)"invalid stored block lengths";
- state->mode = BAD;
- break;
- }
- state->length = (unsigned)hold & 0xffff;
- Tracev((stderr, "inflate: stored length %u\n",
- state->length));
- INITBITS();
-
- /* copy stored block from input to output */
- while (state->length != 0) {
- copy = state->length;
- PULL();
- ROOM();
- if (copy > have) copy = have;
- if (copy > left) copy = left;
- zmemcpy(put, next, copy);
- have -= copy;
- next += copy;
- left -= copy;
- put += copy;
- state->length -= copy;
- }
- Tracev((stderr, "inflate: stored end\n"));
- state->mode = TYPE;
- break;
-
- case TABLE:
- /* get dynamic table entries descriptor */
- NEEDBITS(14);
- state->nlen = BITS(5) + 257;
- DROPBITS(5);
- state->ndist = BITS(5) + 1;
- DROPBITS(5);
- state->ncode = BITS(4) + 4;
- DROPBITS(4);
- #ifndef PKZIP_BUG_WORKAROUND
- if (state->nlen > 286 || state->ndist > 30) {
- strm->msg = (char *)"too many length or distance symbols";
- state->mode = BAD;
- break;
- }
- #endif
- Tracev((stderr, "inflate: table sizes ok\n"));
-
- /* get code length code lengths (not a typo) */
- state->have = 0;
- while (state->have < state->ncode) {
- NEEDBITS(3);
- state->lens[order[state->have++]] = (unsigned short)BITS(3);
- DROPBITS(3);
- }
- while (state->have < 19)
- state->lens[order[state->have++]] = 0;
- state->next = state->codes;
- state->lencode = (code const FAR *)(state->next);
- state->lenbits = 7;
- ret = inflate_table(CODES, state->lens, 19, &(state->next),
- &(state->lenbits), state->work);
- if (ret) {
- strm->msg = (char *)"invalid code lengths set";
- state->mode = BAD;
- break;
- }
- Tracev((stderr, "inflate: code lengths ok\n"));
-
- /* get length and distance code code lengths */
- state->have = 0;
- while (state->have < state->nlen + state->ndist) {
- for (;;) {
- thisx = state->lencode[BITS(state->lenbits)];
- if ((unsigned)(thisx.bits) <= bits) break;
- PULLBYTE();
- }
- if (thisx.val < 16) {
- NEEDBITS(thisx.bits);
- DROPBITS(thisx.bits);
- state->lens[state->have++] = thisx.val;
- }
- else {
- if (thisx.val == 16) {
- NEEDBITS(thisx.bits + 2);
- DROPBITS(thisx.bits);
- if (state->have == 0) {
- strm->msg = (char *)"invalid bit length repeat";
- state->mode = BAD;
- break;
- }
- len = (unsigned)(state->lens[state->have - 1]);
- copy = 3 + BITS(2);
- DROPBITS(2);
- }
- else if (thisx.val == 17) {
- NEEDBITS(thisx.bits + 3);
- DROPBITS(thisx.bits);
- len = 0;
- copy = 3 + BITS(3);
- DROPBITS(3);
- }
- else {
- NEEDBITS(thisx.bits + 7);
- DROPBITS(thisx.bits);
- len = 0;
- copy = 11 + BITS(7);
- DROPBITS(7);
- }
- if (state->have + copy > state->nlen + state->ndist) {
- strm->msg = (char *)"invalid bit length repeat";
- state->mode = BAD;
- break;
- }
- while (copy--)
- state->lens[state->have++] = (unsigned short)len;
- }
- }
-
- /* handle error breaks in while */
- if (state->mode == BAD) break;
-
- /* build code tables */
- state->next = state->codes;
- state->lencode = (code const FAR *)(state->next);
- state->lenbits = 9;
- ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
- &(state->lenbits), state->work);
- if (ret) {
- strm->msg = (char *)"invalid literal/lengths set";
- state->mode = BAD;
- break;
- }
- state->distcode = (code const FAR *)(state->next);
- state->distbits = 6;
- ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
- &(state->next), &(state->distbits), state->work);
- if (ret) {
- strm->msg = (char *)"invalid distances set";
- state->mode = BAD;
- break;
- }
- Tracev((stderr, "inflate: codes ok\n"));
- state->mode = LEN;
-
- case LEN:
- /* use inflate_fast() if we have enough input and output */
- if (have >= 6 && left >= 258) {
- RESTORE();
- if (state->whave < state->wsize)
- state->whave = state->wsize - left;
- inflate_fast(strm, state->wsize);
- LOAD();
- break;
- }
-
- /* get a literal, length, or end-of-block code */
- for (;;) {
- thisx = state->lencode[BITS(state->lenbits)];
- if ((unsigned)(thisx.bits) <= bits) break;
- PULLBYTE();
- }
- if (thisx.op && (thisx.op & 0xf0) == 0) {
- last = thisx;
- for (;;) {
- thisx = state->lencode[last.val +
- (BITS(last.bits + last.op) >> last.bits)];
- if ((unsigned)(last.bits + thisx.bits) <= bits) break;
- PULLBYTE();
- }
- DROPBITS(last.bits);
- }
- DROPBITS(thisx.bits);
- state->length = (unsigned)thisx.val;
-
- /* process literal */
- if (thisx.op == 0) {
- Tracevv((stderr, thisx.val >= 0x20 && thisx.val < 0x7f ?
- "inflate: literal '%c'\n" :
- "inflate: literal 0x%02x\n", thisx.val));
- ROOM();
- *put++ = (unsigned char)(state->length);
- left--;
- state->mode = LEN;
- break;
- }
-
- /* process end of block */
- if (thisx.op & 32) {
- Tracevv((stderr, "inflate: end of block\n"));
- state->mode = TYPE;
- break;
- }
-
- /* invalid code */
- if (thisx.op & 64) {
- strm->msg = (char *)"invalid literal/length code";
- state->mode = BAD;
- break;
- }
-
- /* length code -- get extra bits, if any */
- state->extra = (unsigned)(thisx.op) & 15;
- if (state->extra != 0) {
- NEEDBITS(state->extra);
- state->length += BITS(state->extra);
- DROPBITS(state->extra);
- }
- Tracevv((stderr, "inflate: length %u\n", state->length));
-
- /* get distance code */
- for (;;) {
- thisx = state->distcode[BITS(state->distbits)];
- if ((unsigned)(thisx.bits) <= bits) break;
- PULLBYTE();
- }
- if ((thisx.op & 0xf0) == 0) {
- last = thisx;
- for (;;) {
- thisx = state->distcode[last.val +
- (BITS(last.bits + last.op) >> last.bits)];
- if ((unsigned)(last.bits + thisx.bits) <= bits) break;
- PULLBYTE();
- }
- DROPBITS(last.bits);
- }
- DROPBITS(thisx.bits);
- if (thisx.op & 64) {
- strm->msg = (char *)"invalid distance code";
- state->mode = BAD;
- break;
- }
- state->offset = (unsigned)thisx.val;
-
- /* get distance extra bits, if any */
- state->extra = (unsigned)(thisx.op) & 15;
- if (state->extra != 0) {
- NEEDBITS(state->extra);
- state->offset += BITS(state->extra);
- DROPBITS(state->extra);
- }
- if (state->offset > state->wsize - (state->whave < state->wsize ?
- left : 0)) {
- strm->msg = (char *)"invalid distance too far back";
- state->mode = BAD;
- break;
- }
- Tracevv((stderr, "inflate: distance %u\n", state->offset));
-
- /* copy match from window to output */
- do {
- ROOM();
- copy = state->wsize - state->offset;
- if (copy < left) {
- from = put + copy;
- copy = left - copy;
- }
- else {
- from = put - state->offset;
- copy = left;
- }
- if (copy > state->length) copy = state->length;
- state->length -= copy;
- left -= copy;
- do {
- *put++ = *from++;
- } while (--copy);
- } while (state->length != 0);
- break;
-
- case DONE:
- /* inflate stream terminated properly -- write leftover output */
- ret = Z_STREAM_END;
- if (left < state->wsize) {
- if (out(out_desc, state->window, state->wsize - left))
- ret = Z_BUF_ERROR;
- }
- goto inf_leave;
-
- case BAD:
- ret = Z_DATA_ERROR;
- goto inf_leave;
-
- default: /* can't happen, but makes compilers happy */
- ret = Z_STREAM_ERROR;
- goto inf_leave;
- }
-
- /* Return unused input */
- inf_leave:
- strm->next_in = next;
- strm->avail_in = have;
- return ret;
- }
-
- int ZEXPORT inflateBackEnd (z_streamp strm)
- {
- if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
- return Z_STREAM_ERROR;
- ZFREE(strm, strm->state);
- strm->state = Z_NULL;
- Tracev((stderr, "inflate: end\n"));
- return Z_OK;
- }
- /********* End of inlined file: infback.c *********/
-
- /********* Start of inlined file: inffast.c *********/
-
- /********* Start of inlined file: inffast.h *********/
- /* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
- void inflate_fast OF((z_streamp strm, unsigned start));
- /********* End of inlined file: inffast.h *********/
-
- #ifndef ASMINF
-
- /* Allow machine dependent optimization for post-increment or pre-increment.
- Based on testing to date,
- Pre-increment preferred for:
- - PowerPC G3 (Adler)
- - MIPS R5000 (Randers-Pehrson)
- Post-increment preferred for:
- - none
- No measurable difference:
- - Pentium III (Anderson)
- - M68060 (Nikl)
- */
- #ifdef POSTINC
- # define OFF 0
- # define PUP(a) *(a)++
- #else
- # define OFF 1
- # define PUP(a) *++(a)
- #endif
-
- /*
- Decode literal, length, and distance codes and write out the resulting
- literal and match bytes until either not enough input or output is
- available, an end-of-block is encountered, or a data error is encountered.
- When large enough input and output buffers are supplied to inflate(), for
- example, a 16K input buffer and a 64K output buffer, more than 95% of the
- inflate execution time is spent in this routine.
-
- Entry assumptions:
-
- state->mode == LEN
- strm->avail_in >= 6
- strm->avail_out >= 258
- start >= strm->avail_out
- state->bits < 8
-
- On return, state->mode is one of:
-
- LEN -- ran out of enough output space or enough available input
- TYPE -- reached end of block code, inflate() to interpret next block
- BAD -- error in block data
-
- Notes:
-
- - The maximum input bits used by a length/distance pair is 15 bits for the
- length code, 5 bits for the length extra, 15 bits for the distance code,
- and 13 bits for the distance extra. This totals 48 bits, or six bytes.
- Therefore if strm->avail_in >= 6, then there is enough input to avoid
- checking for available input while decoding.
-
- - The maximum bytes that a single length/distance pair can output is 258
- bytes, which is the maximum length that can be coded. inflate_fast()
- requires strm->avail_out >= 258 for each loop to avoid checking for
- output space.
- */
- void inflate_fast (z_streamp strm, unsigned start)
- {
- struct inflate_state FAR *state;
- unsigned char FAR *in; /* local strm->next_in */
- unsigned char FAR *last; /* while in < last, enough input available */
- unsigned char FAR *out; /* local strm->next_out */
- unsigned char FAR *beg; /* inflate()'s initial strm->next_out */
- unsigned char FAR *end; /* while out < end, enough space available */
- #ifdef INFLATE_STRICT
- unsigned dmax; /* maximum distance from zlib header */
- #endif
- unsigned wsize; /* window size or zero if not using window */
- unsigned whave; /* valid bytes in the window */
- unsigned write; /* window write index */
- unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */
- unsigned long hold; /* local strm->hold */
- unsigned bits; /* local strm->bits */
- code const FAR *lcode; /* local strm->lencode */
- code const FAR *dcode; /* local strm->distcode */
- unsigned lmask; /* mask for first level of length codes */
- unsigned dmask; /* mask for first level of distance codes */
- code thisx; /* retrieved table entry */
- unsigned op; /* code bits, operation, extra bits, or */
- /* window position, window bytes to copy */
- unsigned len; /* match length, unused bytes */
- unsigned dist; /* match distance */
- unsigned char FAR *from; /* where to copy match from */
-
- /* copy state to local variables */
- state = (struct inflate_state FAR *)strm->state;
- in = strm->next_in - OFF;
- last = in + (strm->avail_in - 5);
- out = strm->next_out - OFF;
- beg = out - (start - strm->avail_out);
- end = out + (strm->avail_out - 257);
- #ifdef INFLATE_STRICT
- dmax = state->dmax;
- #endif
- wsize = state->wsize;
- whave = state->whave;
- write = state->write;
- window = state->window;
- hold = state->hold;
- bits = state->bits;
- lcode = state->lencode;
- dcode = state->distcode;
- lmask = (1U << state->lenbits) - 1;
- dmask = (1U << state->distbits) - 1;
-
- /* decode literals and length/distances until end-of-block or not enough
- input data or output space */
- do {
- if (bits < 15) {
- hold += (unsigned long)(PUP(in)) << bits;
- bits += 8;
- hold += (unsigned long)(PUP(in)) << bits;
- bits += 8;
- }
- thisx = lcode[hold & lmask];
- dolen:
- op = (unsigned)(thisx.bits);
- hold >>= op;
- bits -= op;
- op = (unsigned)(thisx.op);
- if (op == 0) { /* literal */
- Tracevv((stderr, thisx.val >= 0x20 && thisx.val < 0x7f ?
- "inflate: literal '%c'\n" :
- "inflate: literal 0x%02x\n", thisx.val));
- PUP(out) = (unsigned char)(thisx.val);
- }
- else if (op & 16) { /* length base */
- len = (unsigned)(thisx.val);
- op &= 15; /* number of extra bits */
- if (op) {
- if (bits < op) {
- hold += (unsigned long)(PUP(in)) << bits;
- bits += 8;
- }
- len += (unsigned)hold & ((1U << op) - 1);
- hold >>= op;
- bits -= op;
- }
- Tracevv((stderr, "inflate: length %u\n", len));
- if (bits < 15) {
- hold += (unsigned long)(PUP(in)) << bits;
- bits += 8;
- hold += (unsigned long)(PUP(in)) << bits;
- bits += 8;
- }
- thisx = dcode[hold & dmask];
- dodist:
- op = (unsigned)(thisx.bits);
- hold >>= op;
- bits -= op;
- op = (unsigned)(thisx.op);
- if (op & 16) { /* distance base */
- dist = (unsigned)(thisx.val);
- op &= 15; /* number of extra bits */
- if (bits < op) {
- hold += (unsigned long)(PUP(in)) << bits;
- bits += 8;
- if (bits < op) {
- hold += (unsigned long)(PUP(in)) << bits;
- bits += 8;
- }
- }
- dist += (unsigned)hold & ((1U << op) - 1);
- #ifdef INFLATE_STRICT
- if (dist > dmax) {
- strm->msg = (char *)"invalid distance too far back";
- state->mode = BAD;
- break;
- }
- #endif
- hold >>= op;
- bits -= op;
- Tracevv((stderr, "inflate: distance %u\n", dist));
- op = (unsigned)(out - beg); /* max distance in output */
- if (dist > op) { /* see if copy from window */
- op = dist - op; /* distance back in window */
- if (op > whave) {
- strm->msg = (char *)"invalid distance too far back";
- state->mode = BAD;
- break;
- }
- from = window - OFF;
- if (write == 0) { /* very common case */
- from += wsize - op;
- if (op < len) { /* some from window */
- len -= op;
- do {
- PUP(out) = PUP(from);
- } while (--op);
- from = out - dist; /* rest from output */
- }
- }
- else if (write < op) { /* wrap around window */
- from += wsize + write - op;
- op -= write;
- if (op < len) { /* some from end of window */
- len -= op;
- do {
- PUP(out) = PUP(from);
- } while (--op);
- from = window - OFF;
- if (write < len) { /* some from start of window */
- op = write;
- len -= op;
- do {
- PUP(out) = PUP(from);
- } while (--op);
- from = out - dist; /* rest from output */
- }
- }
- }
- else { /* contiguous in window */
- from += write - op;
- if (op < len) { /* some from window */
- len -= op;
- do {
- PUP(out) = PUP(from);
- } while (--op);
- from = out - dist; /* rest from output */
- }
- }
- while (len > 2) {
- PUP(out) = PUP(from);
- PUP(out) = PUP(from);
- PUP(out) = PUP(from);
- len -= 3;
- }
- if (len) {
- PUP(out) = PUP(from);
- if (len > 1)
- PUP(out) = PUP(from);
- }
- }
- else {
- from = out - dist; /* copy direct from output */
- do { /* minimum length is three */
- PUP(out) = PUP(from);
- PUP(out) = PUP(from);
- PUP(out) = PUP(from);
- len -= 3;
- } while (len > 2);
- if (len) {
- PUP(out) = PUP(from);
- if (len > 1)
- PUP(out) = PUP(from);
- }
- }
- }
- else if ((op & 64) == 0) { /* 2nd level distance code */
- thisx = dcode[thisx.val + (hold & ((1U << op) - 1))];
- goto dodist;
- }
- else {
- strm->msg = (char *)"invalid distance code";
- state->mode = BAD;
- break;
- }
- }
- else if ((op & 64) == 0) { /* 2nd level length code */
- thisx = lcode[thisx.val + (hold & ((1U << op) - 1))];
- goto dolen;
- }
- else if (op & 32) { /* end-of-block */
- Tracevv((stderr, "inflate: end of block\n"));
- state->mode = TYPE;
- break;
- }
- else {
- strm->msg = (char *)"invalid literal/length code";
- state->mode = BAD;
- break;
- }
- } while (in < last && out < end);
-
- /* return unused bytes (on entry, bits < 8, so in won't go too far back) */
- len = bits >> 3;
- in -= len;
- bits -= len << 3;
- hold &= (1U << bits) - 1;
-
- /* update state and return */
- strm->next_in = in + OFF;
- strm->next_out = out + OFF;
- strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last));
- strm->avail_out = (unsigned)(out < end ?
- 257 + (end - out) : 257 - (out - end));
- state->hold = hold;
- state->bits = bits;
- return;
- }
-
- /*
- inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe):
- - Using bit fields for code structure
- - Different op definition to avoid & for extra bits (do & for table bits)
- - Three separate decoding do-loops for direct, window, and write == 0
- - Special case for distance > 1 copies to do overlapped load and store copy
- - Explicit branch predictions (based on measured branch probabilities)
- - Deferring match copy and interspersed it with decoding subsequent codes
- - Swapping literal/length else
- - Swapping window/direct else
- - Larger unrolled copy loops (three is about right)
- - Moving len -= 3 statement into middle of loop
- */
-
- #endif /* !ASMINF */
- /********* End of inlined file: inffast.c *********/
-
- #undef PULLBYTE
- #undef LOAD
- #undef RESTORE
- #undef INITBITS
- #undef NEEDBITS
- #undef DROPBITS
- #undef BYTEBITS
-
- /********* Start of inlined file: inflate.c *********/
- /*
- * Change history:
- *
- * 1.2.beta0 24 Nov 2002
- * - First version -- complete rewrite of inflate to simplify code, avoid
- * creation of window when not needed, minimize use of window when it is
- * needed, make inffast.c even faster, implement gzip decoding, and to
- * improve code readability and style over the previous zlib inflate code
- *
- * 1.2.beta1 25 Nov 2002
- * - Use pointers for available input and output checking in inffast.c
- * - Remove input and output counters in inffast.c
- * - Change inffast.c entry and loop from avail_in >= 7 to >= 6
- * - Remove unnecessary second byte pull from length extra in inffast.c
- * - Unroll direct copy to three copies per loop in inffast.c
- *
- * 1.2.beta2 4 Dec 2002
- * - Change external routine names to reduce potential conflicts
- * - Correct filename to inffixed.h for fixed tables in inflate.c
- * - Make hbuf[] unsigned char to match parameter type in inflate.c
- * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset)
- * to avoid negation problem on Alphas (64 bit) in inflate.c
- *
- * 1.2.beta3 22 Dec 2002
- * - Add comments on state->bits assertion in inffast.c
- * - Add comments on op field in inftrees.h
- * - Fix bug in reuse of allocated window after inflateReset()
- * - Remove bit fields--back to byte structure for speed
- * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths
- * - Change post-increments to pre-increments in inflate_fast(), PPC biased?
- * - Add compile time option, POSTINC, to use post-increments instead (Intel?)
- * - Make MATCH copy in inflate() much faster for when inflate_fast() not used
- * - Use local copies of stream next and avail values, as well as local bit
- * buffer and bit count in inflate()--for speed when inflate_fast() not used
- *
- * 1.2.beta4 1 Jan 2003
- * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings
- * - Move a comment on output buffer sizes from inffast.c to inflate.c
- * - Add comments in inffast.c to introduce the inflate_fast() routine
- * - Rearrange window copies in inflate_fast() for speed and simplification
- * - Unroll last copy for window match in inflate_fast()
- * - Use local copies of window variables in inflate_fast() for speed
- * - Pull out common write == 0 case for speed in inflate_fast()
- * - Make op and len in inflate_fast() unsigned for consistency
- * - Add FAR to lcode and dcode declarations in inflate_fast()
- * - Simplified bad distance check in inflate_fast()
- * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new
- * source file infback.c to provide a call-back interface to inflate for
- * programs like gzip and unzip -- uses window as output buffer to avoid
- * window copying
- *
- * 1.2.beta5 1 Jan 2003
- * - Improved inflateBack() interface to allow the caller to provide initial
- * input in strm.
- * - Fixed stored blocks bug in inflateBack()
- *
- * 1.2.beta6 4 Jan 2003
- * - Added comments in inffast.c on effectiveness of POSTINC
- * - Typecasting all around to reduce compiler warnings
- * - Changed loops from while (1) or do {} while (1) to for (;;), again to
- * make compilers happy
- * - Changed type of window in inflateBackInit() to unsigned char *
- *
- * 1.2.beta7 27 Jan 2003
- * - Changed many types to unsigned or unsigned short to avoid warnings
- * - Added inflateCopy() function
- *
- * 1.2.0 9 Mar 2003
- * - Changed inflateBack() interface to provide separate opaque descriptors
- * for the in() and out() functions
- * - Changed inflateBack() argument and in_func typedef to swap the length
- * and buffer address return values for the input function
- * - Check next_in and next_out for Z_NULL on entry to inflate()
- *
- * The history for versions after 1.2.0 are in ChangeLog in zlib distribution.
- */
-
- /********* Start of inlined file: inffast.h *********/
- /* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
- void inflate_fast OF((z_streamp strm, unsigned start));
- /********* End of inlined file: inffast.h *********/
-
- #ifdef MAKEFIXED
- # ifndef BUILDFIXED
- # define BUILDFIXED
- # endif
- #endif
-
- /* function prototypes */
- local void fixedtables OF((struct inflate_state FAR *state));
- local int updatewindow OF((z_streamp strm, unsigned out));
- #ifdef BUILDFIXED
- void makefixed OF((void));
- #endif
- local unsigned syncsearch OF((unsigned FAR *have, unsigned char FAR *buf,
- unsigned len));
-
- int ZEXPORT inflateReset (z_streamp strm)
- {
- struct inflate_state FAR *state;
-
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
- state = (struct inflate_state FAR *)strm->state;
- strm->total_in = strm->total_out = state->total = 0;
- strm->msg = Z_NULL;
- strm->adler = 1; /* to support ill-conceived Java test suite */
- state->mode = HEAD;
- state->last = 0;
- state->havedict = 0;
- state->dmax = 32768U;
- state->head = Z_NULL;
- state->wsize = 0;
- state->whave = 0;
- state->write = 0;
- state->hold = 0;
- state->bits = 0;
- state->lencode = state->distcode = state->next = state->codes;
- Tracev((stderr, "inflate: reset\n"));
- return Z_OK;
- }
-
- int ZEXPORT inflatePrime (z_streamp strm, int bits, int value)
- {
- struct inflate_state FAR *state;
-
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
- state = (struct inflate_state FAR *)strm->state;
- if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR;
- value &= (1L << bits) - 1;
- state->hold += value << state->bits;
- state->bits += bits;
- return Z_OK;
- }
-
- int ZEXPORT inflateInit2_(z_streamp strm, int windowBits, const char *version, int stream_size)
- {
- struct inflate_state FAR *state;
-
- if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
- stream_size != (int)(sizeof(z_stream)))
- return Z_VERSION_ERROR;
- if (strm == Z_NULL) return Z_STREAM_ERROR;
- strm->msg = Z_NULL; /* in case we return an error */
- if (strm->zalloc == (alloc_func)0) {
- strm->zalloc = zcalloc;
- strm->opaque = (voidpf)0;
- }
- if (strm->zfree == (free_func)0) strm->zfree = zcfree;
- state = (struct inflate_state FAR *)
- ZALLOC(strm, 1, sizeof(struct inflate_state));
- if (state == Z_NULL) return Z_MEM_ERROR;
- Tracev((stderr, "inflate: allocated\n"));
- strm->state = (struct internal_state FAR *)state;
- if (windowBits < 0) {
- state->wrap = 0;
- windowBits = -windowBits;
- }
- else {
- state->wrap = (windowBits >> 4) + 1;
- #ifdef GUNZIP
- if (windowBits < 48) windowBits &= 15;
- #endif
- }
- if (windowBits < 8 || windowBits > 15) {
- ZFREE(strm, state);
- strm->state = Z_NULL;
- return Z_STREAM_ERROR;
- }
- state->wbits = (unsigned)windowBits;
- state->window = Z_NULL;
- return inflateReset(strm);
- }
-
- int ZEXPORT inflateInit_ (z_streamp strm, const char *version, int stream_size)
- {
- return inflateInit2_(strm, DEF_WBITS, version, stream_size);
- }
-
- /*
- Return state with length and distance decoding tables and index sizes set to
- fixed code decoding. Normally this returns fixed tables from inffixed.h.
- If BUILDFIXED is defined, then instead this routine builds the tables the
- first time it's called, and returns those tables the first time and
- thereafter. This reduces the size of the code by about 2K bytes, in
- exchange for a little execution time. However, BUILDFIXED should not be
- used for threaded applications, since the rewriting of the tables and virgin
- may not be thread-safe.
- */
- local void fixedtables (struct inflate_state FAR *state)
- {
- #ifdef BUILDFIXED
- static int virgin = 1;
- static code *lenfix, *distfix;
- static code fixed[544];
-
- /* build fixed huffman tables if first call (may not be thread safe) */
- if (virgin) {
- unsigned sym, bits;
- static code *next;
-
- /* literal/length table */
- sym = 0;
- while (sym < 144) state->lens[sym++] = 8;
- while (sym < 256) state->lens[sym++] = 9;
- while (sym < 280) state->lens[sym++] = 7;
- while (sym < 288) state->lens[sym++] = 8;
- next = fixed;
- lenfix = next;
- bits = 9;
- inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work);
-
- /* distance table */
- sym = 0;
- while (sym < 32) state->lens[sym++] = 5;
- distfix = next;
- bits = 5;
- inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work);
-
- /* do this just once */
- virgin = 0;
- }
- #else /* !BUILDFIXED */
-
- /********* Start of inlined file: inffixed.h *********/
- /* inffixed.h -- table for decoding fixed codes
- * Generated automatically by makefixed().
- */
-
- /* WARNING: this file should *not* be used by applications. It
- is part of the implementation of the compression library and
- is subject to change. Applications should only use zlib.h.
- */
-
- static const code lenfix[512] = {
- {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48},
- {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128},
- {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59},
- {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176},
- {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20},
- {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100},
- {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8},
- {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216},
- {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76},
- {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114},
- {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2},
- {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148},
- {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42},
- {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86},
- {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15},
- {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236},
- {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62},
- {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142},
- {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31},
- {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162},
- {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25},
- {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105},
- {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4},
- {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202},
- {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69},
- {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125},
- {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13},
- {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195},
- {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35},
- {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91},
- {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19},
- {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246},
- {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55},
- {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135},
- {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99},
- {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190},
- {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16},
- {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96},
- {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6},
- {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209},
- {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72},
- {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116},
- {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4},
- {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153},
- {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44},
- {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82},
- {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11},
- {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229},
- {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58},
- {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138},
- {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51},
- {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173},
- {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30},
- {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110},
- {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0},
- {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195},
- {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65},
- {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121},
- {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9},
- {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258},
- {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37},
- {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93},
- {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23},
- {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251},
- {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51},
- {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131},
- {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67},
- {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183},
- {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23},
- {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103},
- {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9},
- {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223},
- {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79},
- {0,9,255}
- };
-
- static const code distfix[32] = {
- {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025},
- {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193},
- {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385},
- {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577},
- {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073},
- {22,5,193},{64,5,0}
- };
- /********* End of inlined file: inffixed.h *********/
-
- #endif /* BUILDFIXED */
- state->lencode = lenfix;
- state->lenbits = 9;
- state->distcode = distfix;
- state->distbits = 5;
- }
-
- #ifdef MAKEFIXED
- #include <stdio.h>
-
- /*
- Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also
- defines BUILDFIXED, so the tables are built on the fly. makefixed() writes
- those tables to stdout, which would be piped to inffixed.h. A small program
- can simply call makefixed to do this:
-
- void makefixed(void);
-
- int main(void)
- {
- makefixed();
- return 0;
- }
-
- Then that can be linked with zlib built with MAKEFIXED defined and run:
-
- a.out > inffixed.h
- */
- void makefixed()
- {
- unsigned low, size;
- struct inflate_state state;
-
- fixedtables(&state);
- puts(" /* inffixed.h -- table for decoding fixed codes");
- puts(" * Generated automatically by makefixed().");
- puts(" */");
- puts("");
- puts(" /* WARNING: this file should *not* be used by applications.");
- puts(" It is part of the implementation of this library and is");
- puts(" subject to change. Applications should only use zlib.h.");
- puts(" */");
- puts("");
- size = 1U << 9;
- printf(" static const code lenfix[%u] = {", size);
- low = 0;
- for (;;) {
- if ((low % 7) == 0) printf("\n ");
- printf("{%u,%u,%d}", state.lencode[low].op, state.lencode[low].bits,
- state.lencode[low].val);
- if (++low == size) break;
- putchar(',');
- }
- puts("\n };");
- size = 1U << 5;
- printf("\n static const code distfix[%u] = {", size);
- low = 0;
- for (;;) {
- if ((low % 6) == 0) printf("\n ");
- printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits,
- state.distcode[low].val);
- if (++low == size) break;
- putchar(',');
- }
- puts("\n };");
- }
- #endif /* MAKEFIXED */
-
- /*
- Update the window with the last wsize (normally 32K) bytes written before
- returning. If window does not exist yet, create it. This is only called
- when a window is already in use, or when output has been written during this
- inflate call, but the end of the deflate stream has not been reached yet.
- It is also called to create a window for dictionary data when a dictionary
- is loaded.
-
- Providing output buffers larger than 32K to inflate() should provide a speed
- advantage, since only the last 32K of output is copied to the sliding window
- upon return from inflate(), and since all distances after the first 32K of
- output will fall in the output data, making match copies simpler and faster.
- The advantage may be dependent on the size of the processor's data caches.
- */
- local int updatewindow (z_streamp strm, unsigned out)
- {
- struct inflate_state FAR *state;
- unsigned copy, dist;
-
- state = (struct inflate_state FAR *)strm->state;
-
- /* if it hasn't been done already, allocate space for the window */
- if (state->window == Z_NULL) {
- state->window = (unsigned char FAR *)
- ZALLOC(strm, 1U << state->wbits,
- sizeof(unsigned char));
- if (state->window == Z_NULL) return 1;
- }
-
- /* if window not in use yet, initialize */
- if (state->wsize == 0) {
- state->wsize = 1U << state->wbits;
- state->write = 0;
- state->whave = 0;
- }
-
- /* copy state->wsize or less output bytes into the circular window */
- copy = out - strm->avail_out;
- if (copy >= state->wsize) {
- zmemcpy(state->window, strm->next_out - state->wsize, state->wsize);
- state->write = 0;
- state->whave = state->wsize;
- }
- else {
- dist = state->wsize - state->write;
- if (dist > copy) dist = copy;
- zmemcpy(state->window + state->write, strm->next_out - copy, dist);
- copy -= dist;
- if (copy) {
- zmemcpy(state->window, strm->next_out - copy, copy);
- state->write = copy;
- state->whave = state->wsize;
- }
- else {
- state->write += dist;
- if (state->write == state->wsize) state->write = 0;
- if (state->whave < state->wsize) state->whave += dist;
- }
- }
- return 0;
- }
-
- /* Macros for inflate(): */
-
- /* check function to use adler32() for zlib or crc32() for gzip */
- #ifdef GUNZIP
- # define UPDATE(check, buf, len) \
- (state->flags ? crc32(check, buf, len) : adler32(check, buf, len))
- #else
- # define UPDATE(check, buf, len) adler32(check, buf, len)
- #endif
-
- /* check macros for header crc */
- #ifdef GUNZIP
- # define CRC2(check, word) \
- do { \
- hbuf[0] = (unsigned char)(word); \
- hbuf[1] = (unsigned char)((word) >> 8); \
- check = crc32(check, hbuf, 2); \
- } while (0)
-
- # define CRC4(check, word) \
- do { \
- hbuf[0] = (unsigned char)(word); \
- hbuf[1] = (unsigned char)((word) >> 8); \
- hbuf[2] = (unsigned char)((word) >> 16); \
- hbuf[3] = (unsigned char)((word) >> 24); \
- check = crc32(check, hbuf, 4); \
- } while (0)
- #endif
-
- /* Load registers with state in inflate() for speed */
- #define LOAD() \
- do { \
- put = strm->next_out; \
- left = strm->avail_out; \
- next = strm->next_in; \
- have = strm->avail_in; \
- hold = state->hold; \
- bits = state->bits; \
- } while (0)
-
- /* Restore state from registers in inflate() */
- #define RESTORE() \
- do { \
- strm->next_out = put; \
- strm->avail_out = left; \
- strm->next_in = next; \
- strm->avail_in = have; \
- state->hold = hold; \
- state->bits = bits; \
- } while (0)
-
- /* Clear the input bit accumulator */
- #define INITBITS() \
- do { \
- hold = 0; \
- bits = 0; \
- } while (0)
-
- /* Get a byte of input into the bit accumulator, or return from inflate()
- if there is no input available. */
- #define PULLBYTE() \
- do { \
- if (have == 0) goto inf_leave; \
- have--; \
- hold += (unsigned long)(*next++) << bits; \
- bits += 8; \
- } while (0)
-
- /* Assure that there are at least n bits in the bit accumulator. If there is
- not enough available input to do that, then return from inflate(). */
- #define NEEDBITS(n) \
- do { \
- while (bits < (unsigned)(n)) \
- PULLBYTE(); \
- } while (0)
-
- /* Return the low n bits of the bit accumulator (n < 16) */
- #define BITS(n) \
- ((unsigned)hold & ((1U << (n)) - 1))
-
- /* Remove n bits from the bit accumulator */
- #define DROPBITS(n) \
- do { \
- hold >>= (n); \
- bits -= (unsigned)(n); \
- } while (0)
-
- /* Remove zero to seven bits as needed to go to a byte boundary */
- #define BYTEBITS() \
- do { \
- hold >>= bits & 7; \
- bits -= bits & 7; \
- } while (0)
-
- /* Reverse the bytes in a 32-bit value */
- #define REVERSE(q) \
- ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \
- (((q) & 0xff00) << 8) + (((q) & 0xff) << 24))
-
- /*
- inflate() uses a state machine to process as much input data and generate as
- much output data as possible before returning. The state machine is
- structured roughly as follows:
-
- for (;;) switch (state) {
- ...
- case STATEn:
- if (not enough input data or output space to make progress)
- return;
- ... make progress ...
- state = STATEm;
- break;
- ...
- }
-
- so when inflate() is called again, the same case is attempted again, and
- if the appropriate resources are provided, the machine proceeds to the
- next state. The NEEDBITS() macro is usually the way the state evaluates
- whether it can proceed or should return. NEEDBITS() does the return if
- the requested bits are not available. The typical use of the BITS macros
- is:
-
- NEEDBITS(n);
- ... do something with BITS(n) ...
- DROPBITS(n);
-
- where NEEDBITS(n) either returns from inflate() if there isn't enough
- input left to load n bits into the accumulator, or it continues. BITS(n)
- gives the low n bits in the accumulator. When done, DROPBITS(n) drops
- the low n bits off the accumulator. INITBITS() clears the accumulator
- and sets the number of available bits to zero. BYTEBITS() discards just
- enough bits to put the accumulator on a byte boundary. After BYTEBITS()
- and a NEEDBITS(8), then BITS(8) would return the next byte in the stream.
-
- NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return
- if there is no input available. The decoding of variable length codes uses
- PULLBYTE() directly in order to pull just enough bytes to decode the next
- code, and no more.
-
- Some states loop until they get enough input, making sure that enough
- state information is maintained to continue the loop where it left off
- if NEEDBITS() returns in the loop. For example, want, need, and keep
- would all have to actually be part of the saved state in case NEEDBITS()
- returns:
-
- case STATEw:
- while (want < need) {
- NEEDBITS(n);
- keep[want++] = BITS(n);
- DROPBITS(n);
- }
- state = STATEx;
- case STATEx:
-
- As shown above, if the next state is also the next case, then the break
- is omitted.
-
- A state may also return if there is not enough output space available to
- complete that state. Those states are copying stored data, writing a
- literal byte, and copying a matching string.
-
- When returning, a "goto inf_leave" is used to update the total counters,
- update the check value, and determine whether any progress has been made
- during that inflate() call in order to return the proper return code.
- Progress is defined as a change in either strm->avail_in or strm->avail_out.
- When there is a window, goto inf_leave will update the window with the last
- output written. If a goto inf_leave occurs in the middle of decompression
- and there is no window currently, goto inf_leave will create one and copy
- output to the window for the next call of inflate().
-
- In this implementation, the flush parameter of inflate() only affects the
- return code (per zlib.h). inflate() always writes as much as possible to
- strm->next_out, given the space available and the provided input--the effect
- documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers
- the allocation of and copying into a sliding window until necessary, which
- provides the effect documented in zlib.h for Z_FINISH when the entire input
- stream available. So the only thing the flush parameter actually does is:
- when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it
- will return Z_BUF_ERROR if it has not reached the end of the stream.
- */
-
- int ZEXPORT inflate (z_streamp strm, int flush)
- {
- struct inflate_state FAR *state;
- unsigned char FAR *next; /* next input */
- unsigned char FAR *put; /* next output */
- unsigned have, left; /* available input and output */
- unsigned long hold; /* bit buffer */
- unsigned bits; /* bits in bit buffer */
- unsigned in, out; /* save starting available input and output */
- unsigned copy; /* number of stored or match bytes to copy */
- unsigned char FAR *from; /* where to copy match bytes from */
- code thisx; /* current decoding table entry */
- code last; /* parent table entry */
- unsigned len; /* length to copy for repeats, bits to drop */
- int ret; /* return code */
- #ifdef GUNZIP
- unsigned char hbuf[4]; /* buffer for gzip header crc calculation */
- #endif
- static const unsigned short order[19] = /* permutation of code lengths */
- {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
-
- if (strm == Z_NULL || strm->state == Z_NULL || strm->next_out == Z_NULL ||
- (strm->next_in == Z_NULL && strm->avail_in != 0))
- return Z_STREAM_ERROR;
-
- state = (struct inflate_state FAR *)strm->state;
- if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */
- LOAD();
- in = have;
- out = left;
- ret = Z_OK;
- for (;;)
- switch (state->mode) {
- case HEAD:
- if (state->wrap == 0) {
- state->mode = TYPEDO;
- break;
- }
- NEEDBITS(16);
- #ifdef GUNZIP
- if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */
- state->check = crc32(0L, Z_NULL, 0);
- CRC2(state->check, hold);
- INITBITS();
- state->mode = FLAGS;
- break;
- }
- state->flags = 0; /* expect zlib header */
- if (state->head != Z_NULL)
- state->head->done = -1;
- if (!(state->wrap & 1) || /* check if zlib header allowed */
- #else
- if (
- #endif
- ((BITS(8) << 8) + (hold >> 8)) % 31) {
- strm->msg = (char *)"incorrect header check";
- state->mode = BAD;
- break;
- }
- if (BITS(4) != Z_DEFLATED) {
- strm->msg = (char *)"unknown compression method";
- state->mode = BAD;
- break;
- }
- DROPBITS(4);
- len = BITS(4) + 8;
- if (len > state->wbits) {
- strm->msg = (char *)"invalid window size";
- state->mode = BAD;
- break;
- }
- state->dmax = 1U << len;
- Tracev((stderr, "inflate: zlib header ok\n"));
- strm->adler = state->check = adler32(0L, Z_NULL, 0);
- state->mode = hold & 0x200 ? DICTID : TYPE;
- INITBITS();
- break;
- #ifdef GUNZIP
- case FLAGS:
- NEEDBITS(16);
- state->flags = (int)(hold);
- if ((state->flags & 0xff) != Z_DEFLATED) {
- strm->msg = (char *)"unknown compression method";
- state->mode = BAD;
- break;
- }
- if (state->flags & 0xe000) {
- strm->msg = (char *)"unknown header flags set";
- state->mode = BAD;
- break;
- }
- if (state->head != Z_NULL)
- state->head->text = (int)((hold >> 8) & 1);
- if (state->flags & 0x0200) CRC2(state->check, hold);
- INITBITS();
- state->mode = TIME;
- case TIME:
- NEEDBITS(32);
- if (state->head != Z_NULL)
- state->head->time = hold;
- if (state->flags & 0x0200) CRC4(state->check, hold);
- INITBITS();
- state->mode = OS;
- case OS:
- NEEDBITS(16);
- if (state->head != Z_NULL) {
- state->head->xflags = (int)(hold & 0xff);
- state->head->os = (int)(hold >> 8);
- }
- if (state->flags & 0x0200) CRC2(state->check, hold);
- INITBITS();
- state->mode = EXLEN;
- case EXLEN:
- if (state->flags & 0x0400) {
- NEEDBITS(16);
- state->length = (unsigned)(hold);
- if (state->head != Z_NULL)
- state->head->extra_len = (unsigned)hold;
- if (state->flags & 0x0200) CRC2(state->check, hold);
- INITBITS();
- }
- else if (state->head != Z_NULL)
- state->head->extra = Z_NULL;
- state->mode = EXTRA;
- case EXTRA:
- if (state->flags & 0x0400) {
- copy = state->length;
- if (copy > have) copy = have;
- if (copy) {
- if (state->head != Z_NULL &&
- state->head->extra != Z_NULL) {
- len = state->head->extra_len - state->length;
- zmemcpy(state->head->extra + len, next,
- len + copy > state->head->extra_max ?
- state->head->extra_max - len : copy);
- }
- if (state->flags & 0x0200)
- state->check = crc32(state->check, next, copy);
- have -= copy;
- next += copy;
- state->length -= copy;
- }
- if (state->length) goto inf_leave;
- }
- state->length = 0;
- state->mode = NAME;
- case NAME:
- if (state->flags & 0x0800) {
- if (have == 0) goto inf_leave;
- copy = 0;
- do {
- len = (unsigned)(next[copy++]);
- if (state->head != Z_NULL &&
- state->head->name != Z_NULL &&
- state->length < state->head->name_max)
- state->head->name[state->length++] = len;
- } while (len && copy < have);
- if (state->flags & 0x0200)
- state->check = crc32(state->check, next, copy);
- have -= copy;
- next += copy;
- if (len) goto inf_leave;
- }
- else if (state->head != Z_NULL)
- state->head->name = Z_NULL;
- state->length = 0;
- state->mode = COMMENT;
- case COMMENT:
- if (state->flags & 0x1000) {
- if (have == 0) goto inf_leave;
- copy = 0;
- do {
- len = (unsigned)(next[copy++]);
- if (state->head != Z_NULL &&
- state->head->comment != Z_NULL &&
- state->length < state->head->comm_max)
- state->head->comment[state->length++] = len;
- } while (len && copy < have);
- if (state->flags & 0x0200)
- state->check = crc32(state->check, next, copy);
- have -= copy;
- next += copy;
- if (len) goto inf_leave;
- }
- else if (state->head != Z_NULL)
- state->head->comment = Z_NULL;
- state->mode = HCRC;
- case HCRC:
- if (state->flags & 0x0200) {
- NEEDBITS(16);
- if (hold != (state->check & 0xffff)) {
- strm->msg = (char *)"header crc mismatch";
- state->mode = BAD;
- break;
- }
- INITBITS();
- }
- if (state->head != Z_NULL) {
- state->head->hcrc = (int)((state->flags >> 9) & 1);
- state->head->done = 1;
- }
- strm->adler = state->check = crc32(0L, Z_NULL, 0);
- state->mode = TYPE;
- break;
- #endif
- case DICTID:
- NEEDBITS(32);
- strm->adler = state->check = REVERSE(hold);
- INITBITS();
- state->mode = DICT;
- case DICT:
- if (state->havedict == 0) {
- RESTORE();
- return Z_NEED_DICT;
- }
- strm->adler = state->check = adler32(0L, Z_NULL, 0);
- state->mode = TYPE;
- case TYPE:
- if (flush == Z_BLOCK) goto inf_leave;
- case TYPEDO:
- if (state->last) {
- BYTEBITS();
- state->mode = CHECK;
- break;
- }
- NEEDBITS(3);
- state->last = BITS(1);
- DROPBITS(1);
- switch (BITS(2)) {
- case 0: /* stored block */
- Tracev((stderr, "inflate: stored block%s\n",
- state->last ? " (last)" : ""));
- state->mode = STORED;
- break;
- case 1: /* fixed block */
- fixedtables(state);
- Tracev((stderr, "inflate: fixed codes block%s\n",
- state->last ? " (last)" : ""));
- state->mode = LEN; /* decode codes */
- break;
- case 2: /* dynamic block */
- Tracev((stderr, "inflate: dynamic codes block%s\n",
- state->last ? " (last)" : ""));
- state->mode = TABLE;
- break;
- case 3:
- strm->msg = (char *)"invalid block type";
- state->mode = BAD;
- }
- DROPBITS(2);
- break;
- case STORED:
- BYTEBITS(); /* go to byte boundary */
- NEEDBITS(32);
- if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
- strm->msg = (char *)"invalid stored block lengths";
- state->mode = BAD;
- break;
- }
- state->length = (unsigned)hold & 0xffff;
- Tracev((stderr, "inflate: stored length %u\n",
- state->length));
- INITBITS();
- state->mode = COPY;
- case COPY:
- copy = state->length;
- if (copy) {
- if (copy > have) copy = have;
- if (copy > left) copy = left;
- if (copy == 0) goto inf_leave;
- zmemcpy(put, next, copy);
- have -= copy;
- next += copy;
- left -= copy;
- put += copy;
- state->length -= copy;
- break;
- }
- Tracev((stderr, "inflate: stored end\n"));
- state->mode = TYPE;
- break;
- case TABLE:
- NEEDBITS(14);
- state->nlen = BITS(5) + 257;
- DROPBITS(5);
- state->ndist = BITS(5) + 1;
- DROPBITS(5);
- state->ncode = BITS(4) + 4;
- DROPBITS(4);
- #ifndef PKZIP_BUG_WORKAROUND
- if (state->nlen > 286 || state->ndist > 30) {
- strm->msg = (char *)"too many length or distance symbols";
- state->mode = BAD;
- break;
- }
- #endif
- Tracev((stderr, "inflate: table sizes ok\n"));
- state->have = 0;
- state->mode = LENLENS;
- case LENLENS:
- while (state->have < state->ncode) {
- NEEDBITS(3);
- state->lens[order[state->have++]] = (unsigned short)BITS(3);
- DROPBITS(3);
- }
- while (state->have < 19)
- state->lens[order[state->have++]] = 0;
- state->next = state->codes;
- state->lencode = (code const FAR *)(state->next);
- state->lenbits = 7;
- ret = inflate_table(CODES, state->lens, 19, &(state->next),
- &(state->lenbits), state->work);
- if (ret) {
- strm->msg = (char *)"invalid code lengths set";
- state->mode = BAD;
- break;
- }
- Tracev((stderr, "inflate: code lengths ok\n"));
- state->have = 0;
- state->mode = CODELENS;
- case CODELENS:
- while (state->have < state->nlen + state->ndist) {
- for (;;) {
- thisx = state->lencode[BITS(state->lenbits)];
- if ((unsigned)(thisx.bits) <= bits) break;
- PULLBYTE();
- }
- if (thisx.val < 16) {
- NEEDBITS(thisx.bits);
- DROPBITS(thisx.bits);
- state->lens[state->have++] = thisx.val;
- }
- else {
- if (thisx.val == 16) {
- NEEDBITS(thisx.bits + 2);
- DROPBITS(thisx.bits);
- if (state->have == 0) {
- strm->msg = (char *)"invalid bit length repeat";
- state->mode = BAD;
- break;
- }
- len = state->lens[state->have - 1];
- copy = 3 + BITS(2);
- DROPBITS(2);
- }
- else if (thisx.val == 17) {
- NEEDBITS(thisx.bits + 3);
- DROPBITS(thisx.bits);
- len = 0;
- copy = 3 + BITS(3);
- DROPBITS(3);
- }
- else {
- NEEDBITS(thisx.bits + 7);
- DROPBITS(thisx.bits);
- len = 0;
- copy = 11 + BITS(7);
- DROPBITS(7);
- }
- if (state->have + copy > state->nlen + state->ndist) {
- strm->msg = (char *)"invalid bit length repeat";
- state->mode = BAD;
- break;
- }
- while (copy--)
- state->lens[state->have++] = (unsigned short)len;
- }
- }
-
- /* handle error breaks in while */
- if (state->mode == BAD) break;
-
- /* build code tables */
- state->next = state->codes;
- state->lencode = (code const FAR *)(state->next);
- state->lenbits = 9;
- ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
- &(state->lenbits), state->work);
- if (ret) {
- strm->msg = (char *)"invalid literal/lengths set";
- state->mode = BAD;
- break;
- }
- state->distcode = (code const FAR *)(state->next);
- state->distbits = 6;
- ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
- &(state->next), &(state->distbits), state->work);
- if (ret) {
- strm->msg = (char *)"invalid distances set";
- state->mode = BAD;
- break;
- }
- Tracev((stderr, "inflate: codes ok\n"));
- state->mode = LEN;
- case LEN:
- if (have >= 6 && left >= 258) {
- RESTORE();
- inflate_fast(strm, out);
- LOAD();
- break;
- }
- for (;;) {
- thisx = state->lencode[BITS(state->lenbits)];
- if ((unsigned)(thisx.bits) <= bits) break;
- PULLBYTE();
- }
- if (thisx.op && (thisx.op & 0xf0) == 0) {
- last = thisx;
- for (;;) {
- thisx = state->lencode[last.val +
- (BITS(last.bits + last.op) >> last.bits)];
- if ((unsigned)(last.bits + thisx.bits) <= bits) break;
- PULLBYTE();
- }
- DROPBITS(last.bits);
- }
- DROPBITS(thisx.bits);
- state->length = (unsigned)thisx.val;
- if ((int)(thisx.op) == 0) {
- Tracevv((stderr, thisx.val >= 0x20 && thisx.val < 0x7f ?
- "inflate: literal '%c'\n" :
- "inflate: literal 0x%02x\n", thisx.val));
- state->mode = LIT;
- break;
- }
- if (thisx.op & 32) {
- Tracevv((stderr, "inflate: end of block\n"));
- state->mode = TYPE;
- break;
- }
- if (thisx.op & 64) {
- strm->msg = (char *)"invalid literal/length code";
- state->mode = BAD;
- break;
- }
- state->extra = (unsigned)(thisx.op) & 15;
- state->mode = LENEXT;
- case LENEXT:
- if (state->extra) {
- NEEDBITS(state->extra);
- state->length += BITS(state->extra);
- DROPBITS(state->extra);
- }
- Tracevv((stderr, "inflate: length %u\n", state->length));
- state->mode = DIST;
- case DIST:
- for (;;) {
- thisx = state->distcode[BITS(state->distbits)];
- if ((unsigned)(thisx.bits) <= bits) break;
- PULLBYTE();
- }
- if ((thisx.op & 0xf0) == 0) {
- last = thisx;
- for (;;) {
- thisx = state->distcode[last.val +
- (BITS(last.bits + last.op) >> last.bits)];
- if ((unsigned)(last.bits + thisx.bits) <= bits) break;
- PULLBYTE();
- }
- DROPBITS(last.bits);
- }
- DROPBITS(thisx.bits);
- if (thisx.op & 64) {
- strm->msg = (char *)"invalid distance code";
- state->mode = BAD;
- break;
- }
- state->offset = (unsigned)thisx.val;
- state->extra = (unsigned)(thisx.op) & 15;
- state->mode = DISTEXT;
- case DISTEXT:
- if (state->extra) {
- NEEDBITS(state->extra);
- state->offset += BITS(state->extra);
- DROPBITS(state->extra);
- }
- #ifdef INFLATE_STRICT
- if (state->offset > state->dmax) {
- strm->msg = (char *)"invalid distance too far back";
- state->mode = BAD;
- break;
- }
- #endif
- if (state->offset > state->whave + out - left) {
- strm->msg = (char *)"invalid distance too far back";
- state->mode = BAD;
- break;
- }
- Tracevv((stderr, "inflate: distance %u\n", state->offset));
- state->mode = MATCH;
- case MATCH:
- if (left == 0) goto inf_leave;
- copy = out - left;
- if (state->offset > copy) { /* copy from window */
- copy = state->offset - copy;
- if (copy > state->write) {
- copy -= state->write;
- from = state->window + (state->wsize - copy);
- }
- else
- from = state->window + (state->write - copy);
- if (copy > state->length) copy = state->length;
- }
- else { /* copy from output */
- from = put - state->offset;
- copy = state->length;
- }
- if (copy > left) copy = left;
- left -= copy;
- state->length -= copy;
- do {
- *put++ = *from++;
- } while (--copy);
- if (state->length == 0) state->mode = LEN;
- break;
- case LIT:
- if (left == 0) goto inf_leave;
- *put++ = (unsigned char)(state->length);
- left--;
- state->mode = LEN;
- break;
- case CHECK:
- if (state->wrap) {
- NEEDBITS(32);
- out -= left;
- strm->total_out += out;
- state->total += out;
- if (out)
- strm->adler = state->check =
- UPDATE(state->check, put - out, out);
- out = left;
- if ((
- #ifdef GUNZIP
- state->flags ? hold :
- #endif
- REVERSE(hold)) != state->check) {
- strm->msg = (char *)"incorrect data check";
- state->mode = BAD;
- break;
- }
- INITBITS();
- Tracev((stderr, "inflate: check matches trailer\n"));
- }
- #ifdef GUNZIP
- state->mode = LENGTH;
- case LENGTH:
- if (state->wrap && state->flags) {
- NEEDBITS(32);
- if (hold != (state->total & 0xffffffffUL)) {
- strm->msg = (char *)"incorrect length check";
- state->mode = BAD;
- break;
- }
- INITBITS();
- Tracev((stderr, "inflate: length matches trailer\n"));
- }
- #endif
- state->mode = DONE;
- case DONE:
- ret = Z_STREAM_END;
- goto inf_leave;
- case BAD:
- ret = Z_DATA_ERROR;
- goto inf_leave;
- case MEM:
- return Z_MEM_ERROR;
- case SYNC:
- default:
- return Z_STREAM_ERROR;
- }
-
- /*
- Return from inflate(), updating the total counts and the check value.
- If there was no progress during the inflate() call, return a buffer
- error. Call updatewindow() to create and/or update the window state.
- Note: a memory error from inflate() is non-recoverable.
- */
- inf_leave:
- RESTORE();
- if (state->wsize || (state->mode < CHECK && out != strm->avail_out))
- if (updatewindow(strm, out)) {
- state->mode = MEM;
- return Z_MEM_ERROR;
- }
- in -= strm->avail_in;
- out -= strm->avail_out;
- strm->total_in += in;
- strm->total_out += out;
- state->total += out;
- if (state->wrap && out)
- strm->adler = state->check =
- UPDATE(state->check, strm->next_out - out, out);
- strm->data_type = state->bits + (state->last ? 64 : 0) +
- (state->mode == TYPE ? 128 : 0);
- if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK)
- ret = Z_BUF_ERROR;
- return ret;
- }
-
- int ZEXPORT inflateEnd (z_streamp strm)
- {
- struct inflate_state FAR *state;
- if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
- return Z_STREAM_ERROR;
- state = (struct inflate_state FAR *)strm->state;
- if (state->window != Z_NULL) ZFREE(strm, state->window);
- ZFREE(strm, strm->state);
- strm->state = Z_NULL;
- Tracev((stderr, "inflate: end\n"));
- return Z_OK;
- }
-
- int ZEXPORT inflateSetDictionary (z_streamp strm, const Bytef *dictionary, uInt dictLength)
- {
- struct inflate_state FAR *state;
- unsigned long id_;
-
- /* check state */
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
- state = (struct inflate_state FAR *)strm->state;
- if (state->wrap != 0 && state->mode != DICT)
- return Z_STREAM_ERROR;
-
- /* check for correct dictionary id */
- if (state->mode == DICT) {
- id_ = adler32(0L, Z_NULL, 0);
- id_ = adler32(id_, dictionary, dictLength);
- if (id_ != state->check)
- return Z_DATA_ERROR;
- }
-
- /* copy dictionary to window */
- if (updatewindow(strm, strm->avail_out)) {
- state->mode = MEM;
- return Z_MEM_ERROR;
- }
- if (dictLength > state->wsize) {
- zmemcpy(state->window, dictionary + dictLength - state->wsize,
- state->wsize);
- state->whave = state->wsize;
- }
- else {
- zmemcpy(state->window + state->wsize - dictLength, dictionary,
- dictLength);
- state->whave = dictLength;
- }
- state->havedict = 1;
- Tracev((stderr, "inflate: dictionary set\n"));
- return Z_OK;
- }
-
- int ZEXPORT inflateGetHeader (z_streamp strm, gz_headerp head)
- {
- struct inflate_state FAR *state;
-
- /* check state */
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
- state = (struct inflate_state FAR *)strm->state;
- if ((state->wrap & 2) == 0) return Z_STREAM_ERROR;
-
- /* save header structure */
- state->head = head;
- head->done = 0;
- return Z_OK;
- }
-
- /*
- Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found
- or when out of input. When called, *have is the number of pattern bytes
- found in order so far, in 0..3. On return *have is updated to the new
- state. If on return *have equals four, then the pattern was found and the
- return value is how many bytes were read including the last byte of the
- pattern. If *have is less than four, then the pattern has not been found
- yet and the return value is len. In the latter case, syncsearch() can be
- called again with more data and the *have state. *have is initialized to
- zero for the first call.
- */
- local unsigned syncsearch (unsigned FAR *have, unsigned char FAR *buf, unsigned len)
- {
- unsigned got;
- unsigned next;
-
- got = *have;
- next = 0;
- while (next < len && got < 4) {
- if ((int)(buf[next]) == (got < 2 ? 0 : 0xff))
- got++;
- else if (buf[next])
- got = 0;
- else
- got = 4 - got;
- next++;
- }
- *have = got;
- return next;
- }
-
- int ZEXPORT inflateSync (z_streamp strm)
- {
- unsigned len; /* number of bytes to look at or looked at */
- unsigned long in, out; /* temporary to save total_in and total_out */
- unsigned char buf[4]; /* to restore bit buffer to byte string */
- struct inflate_state FAR *state;
-
- /* check parameters */
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
- state = (struct inflate_state FAR *)strm->state;
- if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR;
-
- /* if first time, start search in bit buffer */
- if (state->mode != SYNC) {
- state->mode = SYNC;
- state->hold <<= state->bits & 7;
- state->bits -= state->bits & 7;
- len = 0;
- while (state->bits >= 8) {
- buf[len++] = (unsigned char)(state->hold);
- state->hold >>= 8;
- state->bits -= 8;
- }
- state->have = 0;
- syncsearch(&(state->have), buf, len);
- }
-
- /* search available input */
- len = syncsearch(&(state->have), strm->next_in, strm->avail_in);
- strm->avail_in -= len;
- strm->next_in += len;
- strm->total_in += len;
-
- /* return no joy or set up to restart inflate() on a new block */
- if (state->have != 4) return Z_DATA_ERROR;
- in = strm->total_in; out = strm->total_out;
- inflateReset(strm);
- strm->total_in = in; strm->total_out = out;
- state->mode = TYPE;
- return Z_OK;
- }
-
- /*
- Returns true if inflate is currently at the end of a block generated by
- Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
- implementation to provide an additional safety check. PPP uses
- Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored
- block. When decompressing, PPP checks that at the end of input packet,
- inflate is waiting for these length bytes.
- */
- int ZEXPORT inflateSyncPoint (z_streamp strm)
- {
- struct inflate_state FAR *state;
-
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
- state = (struct inflate_state FAR *)strm->state;
- return state->mode == STORED && state->bits == 0;
- }
-
- int ZEXPORT inflateCopy(z_streamp dest, z_streamp source)
- {
- struct inflate_state FAR *state;
- struct inflate_state FAR *copy;
- unsigned char FAR *window;
- unsigned wsize;
-
- /* check input */
- if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL ||
- source->zalloc == (alloc_func)0 || source->zfree == (free_func)0)
- return Z_STREAM_ERROR;
- state = (struct inflate_state FAR *)source->state;
-
- /* allocate space */
- copy = (struct inflate_state FAR *)
- ZALLOC(source, 1, sizeof(struct inflate_state));
- if (copy == Z_NULL) return Z_MEM_ERROR;
- window = Z_NULL;
- if (state->window != Z_NULL) {
- window = (unsigned char FAR *)
- ZALLOC(source, 1U << state->wbits, sizeof(unsigned char));
- if (window == Z_NULL) {
- ZFREE(source, copy);
- return Z_MEM_ERROR;
- }
- }
-
- /* copy state */
- zmemcpy(dest, source, sizeof(z_stream));
- zmemcpy(copy, state, sizeof(struct inflate_state));
- if (state->lencode >= state->codes &&
- state->lencode <= state->codes + ENOUGH - 1) {
- copy->lencode = copy->codes + (state->lencode - state->codes);
- copy->distcode = copy->codes + (state->distcode - state->codes);
- }
- copy->next = copy->codes + (state->next - state->codes);
- if (window != Z_NULL) {
- wsize = 1U << state->wbits;
- zmemcpy(window, state->window, wsize);
- }
- copy->window = window;
- dest->state = (struct internal_state FAR *)copy;
- return Z_OK;
- }
- /********* End of inlined file: inflate.c *********/
-
- /********* Start of inlined file: inftrees.c *********/
-
- #define MAXBITS 15
-
- const char inflate_copyright[] =
- " inflate 1.2.3 Copyright 1995-2005 Mark Adler ";
- /*
- If you use the zlib library in a product, an acknowledgment is welcome
- in the documentation of your product. If for some reason you cannot
- include such an acknowledgment, I would appreciate that you keep this
- copyright string in the executable of your product.
- */
-
- /*
- Build a set of tables to decode the provided canonical Huffman code.
- The code lengths are lens[0..codes-1]. The result starts at *table,
- whose indices are 0..2^bits-1. work is a writable array of at least
- lens shorts, which is used as a work area. type is the type of code
- to be generated, CODES, LENS, or DISTS. On return, zero is success,
- -1 is an invalid code, and +1 means that ENOUGH isn't enough. table
- on return points to the next available entry's address. bits is the
- requested root table index bits, and on return it is the actual root
- table index bits. It will differ if the request is greater than the
- longest code or if it is less than the shortest code.
- */
- int inflate_table (codetype type,
- unsigned short FAR *lens,
- unsigned codes,
- code FAR * FAR *table,
- unsigned FAR *bits,
- unsigned short FAR *work)
- {
- unsigned len; /* a code's length in bits */
- unsigned sym; /* index of code symbols */
- unsigned min, max; /* minimum and maximum code lengths */
- unsigned root; /* number of index bits for root table */
- unsigned curr; /* number of index bits for current table */
- unsigned drop; /* code bits to drop for sub-table */
- int left; /* number of prefix codes available */
- unsigned used; /* code entries in table used */
- unsigned huff; /* Huffman code */
- unsigned incr; /* for incrementing code, index */
- unsigned fill; /* index for replicating entries */
- unsigned low; /* low bits for current root entry */
- unsigned mask; /* mask for low root bits */
- code thisx; /* table entry for duplication */
- code FAR *next; /* next available space in table */
- const unsigned short FAR *base; /* base value table to use */
- const unsigned short FAR *extra; /* extra bits table to use */
- int end; /* use base and extra for symbol > end */
- unsigned short count[MAXBITS+1]; /* number of codes of each length */
- unsigned short offs[MAXBITS+1]; /* offsets in table for each length */
- static const unsigned short lbase[31] = { /* Length codes 257..285 base */
- 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
- 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
- static const unsigned short lext[31] = { /* Length codes 257..285 extra */
- 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
- 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 201, 196};
- static const unsigned short dbase[32] = { /* Distance codes 0..29 base */
- 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
- 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
- 8193, 12289, 16385, 24577, 0, 0};
- static const unsigned short dext[32] = { /* Distance codes 0..29 extra */
- 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22,
- 23, 23, 24, 24, 25, 25, 26, 26, 27, 27,
- 28, 28, 29, 29, 64, 64};
-
- /*
- Process a set of code lengths to create a canonical Huffman code. The
- code lengths are lens[0..codes-1]. Each length corresponds to the
- symbols 0..codes-1. The Huffman code is generated by first sorting the
- symbols by length from short to long, and retaining the symbol order
- for codes with equal lengths. Then the code starts with all zero bits
- for the first code of the shortest length, and the codes are integer
- increments for the same length, and zeros are appended as the length
- increases. For the deflate format, these bits are stored backwards
- from their more natural integer increment ordering, and so when the
- decoding tables are built in the large loop below, the integer codes
- are incremented backwards.
-
- This routine assumes, but does not check, that all of the entries in
- lens[] are in the range 0..MAXBITS. The caller must assure this.
- 1..MAXBITS is interpreted as that code length. zero means that that
- symbol does not occur in this code.
-
- The codes are sorted by computing a count of codes for each length,
- creating from that a table of starting indices for each length in the
- sorted table, and then entering the symbols in order in the sorted
- table. The sorted table is work[], with that space being provided by
- the caller.
-
- The length counts are used for other purposes as well, i.e. finding
- the minimum and maximum length codes, determining if there are any
- codes at all, checking for a valid set of lengths, and looking ahead
- at length counts to determine sub-table sizes when building the
- decoding tables.
- */
-
- /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */
- for (len = 0; len <= MAXBITS; len++)
- count[len] = 0;
- for (sym = 0; sym < codes; sym++)
- count[lens[sym]]++;
-
- /* bound code lengths, force root to be within code lengths */
- root = *bits;
- for (max = MAXBITS; max >= 1; max--)
- if (count[max] != 0) break;
- if (root > max) root = max;
- if (max == 0) { /* no symbols to code at all */
- thisx.op = (unsigned char)64; /* invalid code marker */
- thisx.bits = (unsigned char)1;
- thisx.val = (unsigned short)0;
- *(*table)++ = thisx; /* make a table to force an error */
- *(*table)++ = thisx;
- *bits = 1;
- return 0; /* no symbols, but wait for decoding to report error */
- }
- for (min = 1; min <= MAXBITS; min++)
- if (count[min] != 0) break;
- if (root < min) root = min;
-
- /* check for an over-subscribed or incomplete set of lengths */
- left = 1;
- for (len = 1; len <= MAXBITS; len++) {
- left <<= 1;
- left -= count[len];
- if (left < 0) return -1; /* over-subscribed */
- }
- if (left > 0 && (type == CODES || max != 1))
- return -1; /* incomplete set */
-
- /* generate offsets into symbol table for each length for sorting */
- offs[1] = 0;
- for (len = 1; len < MAXBITS; len++)
- offs[len + 1] = offs[len] + count[len];
-
- /* sort symbols by length, by symbol order within each length */
- for (sym = 0; sym < codes; sym++)
- if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym;
-
- /*
- Create and fill in decoding tables. In this loop, the table being
- filled is at next and has curr index bits. The code being used is huff
- with length len. That code is converted to an index by dropping drop
- bits off of the bottom. For codes where len is less than drop + curr,
- those top drop + curr - len bits are incremented through all values to
- fill the table with replicated entries.
-
- root is the number of index bits for the root table. When len exceeds
- root, sub-tables are created pointed to by the root entry with an index
- of the low root bits of huff. This is saved in low to check for when a
- new sub-table should be started. drop is zero when the root table is
- being filled, and drop is root when sub-tables are being filled.
-
- When a new sub-table is needed, it is necessary to look ahead in the
- code lengths to determine what size sub-table is needed. The length
- counts are used for this, and so count[] is decremented as codes are
- entered in the tables.
-
- used keeps track of how many table entries have been allocated from the
- provided *table space. It is checked when a LENS table is being made
- against the space in *table, ENOUGH, minus the maximum space needed by
- the worst case distance code, MAXD. This should never happen, but the
- sufficiency of ENOUGH has not been proven exhaustively, hence the check.
- This assumes that when type == LENS, bits == 9.
-
- sym increments through all symbols, and the loop terminates when
- all codes of length max, i.e. all codes, have been processed. This
- routine permits incomplete codes, so another loop after this one fills
- in the rest of the decoding tables with invalid code markers.
- */
-
- /* set up for code type */
- switch (type) {
- case CODES:
- base = extra = work; /* dummy value--not used */
- end = 19;
- break;
- case LENS:
- base = lbase;
- base -= 257;
- extra = lext;
- extra -= 257;
- end = 256;
- break;
- default: /* DISTS */
- base = dbase;
- extra = dext;
- end = -1;
- }
-
- /* initialize state for loop */
- huff = 0; /* starting code */
- sym = 0; /* starting code symbol */
- len = min; /* starting code length */
- next = *table; /* current table to fill in */
- curr = root; /* current table index bits */
- drop = 0; /* current bits to drop from code for index */
- low = (unsigned)(-1); /* trigger new sub-table when len > root */
- used = 1U << root; /* use root table entries */
- mask = used - 1; /* mask for comparing low */
-
- /* check available table space */
- if (type == LENS && used >= ENOUGH - MAXD)
- return 1;
-
- /* process all codes and make table entries */
- for (;;) {
- /* create table entry */
- thisx.bits = (unsigned char)(len - drop);
- if ((int)(work[sym]) < end) {
- thisx.op = (unsigned char)0;
- thisx.val = work[sym];
- }
- else if ((int)(work[sym]) > end) {
- thisx.op = (unsigned char)(extra[work[sym]]);
- thisx.val = base[work[sym]];
- }
- else {
- thisx.op = (unsigned char)(32 + 64); /* end of block */
- thisx.val = 0;
- }
-
- /* replicate for those indices with low len bits equal to huff */
- incr = 1U << (len - drop);
- fill = 1U << curr;
- min = fill; /* save offset to next table */
- do {
- fill -= incr;
- next[(huff >> drop) + fill] = thisx;
- } while (fill != 0);
-
- /* backwards increment the len-bit code huff */
- incr = 1U << (len - 1);
- while (huff & incr)
- incr >>= 1;
- if (incr != 0) {
- huff &= incr - 1;
- huff += incr;
- }
- else
- huff = 0;
-
- /* go to next symbol, update count, len */
- sym++;
- if (--(count[len]) == 0) {
- if (len == max) break;
- len = lens[work[sym]];
- }
-
- /* create new sub-table if needed */
- if (len > root && (huff & mask) != low) {
- /* if first time, transition to sub-tables */
- if (drop == 0)
- drop = root;
-
- /* increment past last table */
- next += min; /* here min is 1 << curr */
-
- /* determine length of next table */
- curr = len - drop;
- left = (int)(1 << curr);
- while (curr + drop < max) {
- left -= count[curr + drop];
- if (left <= 0) break;
- curr++;
- left <<= 1;
- }
-
- /* check for enough space */
- used += 1U << curr;
- if (type == LENS && used >= ENOUGH - MAXD)
- return 1;
-
- /* point entry in root table to sub-table */
- low = huff & mask;
- (*table)[low].op = (unsigned char)curr;
- (*table)[low].bits = (unsigned char)root;
- (*table)[low].val = (unsigned short)(next - *table);
- }
- }
-
- /*
- Fill in rest of table for incomplete codes. This loop is similar to the
- loop above in incrementing huff for table indices. It is assumed that
- len is equal to curr + drop, so there is no loop needed to increment
- through high index bits. When the current sub-table is filled, the loop
- drops back to the root table to fill in any remaining entries there.
- */
- thisx.op = (unsigned char)64; /* invalid code marker */
- thisx.bits = (unsigned char)(len - drop);
- thisx.val = (unsigned short)0;
- while (huff != 0) {
- /* when done with sub-table, drop back to root table */
- if (drop != 0 && (huff & mask) != low) {
- drop = 0;
- len = root;
- next = *table;
- thisx.bits = (unsigned char)len;
- }
-
- /* put invalid code marker in table */
- next[huff >> drop] = thisx;
-
- /* backwards increment the len-bit code huff */
- incr = 1U << (len - 1);
- while (huff & incr)
- incr >>= 1;
- if (incr != 0) {
- huff &= incr - 1;
- huff += incr;
- }
- else
- huff = 0;
- }
-
- /* set return parameters */
- *table += used;
- *bits = root;
- return 0;
- }
- /********* End of inlined file: inftrees.c *********/
-
- /********* Start of inlined file: trees.c *********/
- /*
- * ALGORITHM
- *
- * The "deflation" process uses several Huffman trees. The more
- * common source values are represented by shorter bit sequences.
- *
- * Each code tree is stored in a compressed form which is itself
- * a Huffman encoding of the lengths of all the code strings (in
- * ascending order by source values). The actual code strings are
- * reconstructed from the lengths in the inflate process, as described
- * in the deflate specification.
- *
- * REFERENCES
- *
- * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification".
- * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc
- *
- * Storer, James A.
- * Data Compression: Methods and Theory, pp. 49-50.
- * Computer Science Press, 1988. ISBN 0-7167-8156-5.
- *
- * Sedgewick, R.
- * Algorithms, p290.
- * Addison-Wesley, 1983. ISBN 0-201-06672-6.
- */
-
- /* @(#) $Id: trees.c,v 1.1 2007/06/07 17:54:37 jules_rms Exp $ */
-
- /* #define GEN_TREES_H */
-
- #ifdef DEBUG
- # include <ctype.h>
- #endif
-
- /* ===========================================================================
- * Constants
- */
-
- #define MAX_BL_BITS 7
- /* Bit length codes must not exceed MAX_BL_BITS bits */
-
- #define END_BLOCK 256
- /* end of block literal code */
-
- #define REP_3_6 16
- /* repeat previous bit length 3-6 times (2 bits of repeat count) */
-
- #define REPZ_3_10 17
- /* repeat a zero length 3-10 times (3 bits of repeat count) */
-
- #define REPZ_11_138 18
- /* repeat a zero length 11-138 times (7 bits of repeat count) */
-
- local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */
- = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0};
-
- local const int extra_dbits[D_CODES] /* extra bits for each distance code */
- = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13};
-
- local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */
- = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7};
-
- local const uch bl_order[BL_CODES]
- = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15};
- /* The lengths of the bit length codes are sent in order of decreasing
- * probability, to avoid transmitting the lengths for unused bit length codes.
- */
-
- #define Buf_size (8 * 2*sizeof(char))
- /* Number of bits used within bi_buf. (bi_buf might be implemented on
- * more than 16 bits on some systems.)
- */
-
- /* ===========================================================================
- * Local data. These are initialized only once.
- */
-
- #define DIST_CODE_LEN 512 /* see definition of array dist_code below */
-
- #if defined(GEN_TREES_H) || !defined(STDC)
- /* non ANSI compilers may not accept trees.h */
-
- local ct_data static_ltree[L_CODES+2];
- /* The static literal tree. Since the bit lengths are imposed, there is no
- * need for the L_CODES extra codes used during heap construction. However
- * The codes 286 and 287 are needed to build a canonical tree (see _tr_init
- * below).
- */
-
- local ct_data static_dtree[D_CODES];
- /* The static distance tree. (Actually a trivial tree since all codes use
- * 5 bits.)
- */
-
- uch _dist_code[DIST_CODE_LEN];
- /* Distance codes. The first 256 values correspond to the distances
- * 3 .. 258, the last 256 values correspond to the top 8 bits of
- * the 15 bit distances.
- */
-
- uch _length_code[MAX_MATCH-MIN_MATCH+1];
- /* length code for each normalized match length (0 == MIN_MATCH) */
-
- local int base_length[LENGTH_CODES];
- /* First normalized length for each code (0 = MIN_MATCH) */
-
- local int base_dist[D_CODES];
- /* First normalized distance for each code (0 = distance of 1) */
-
- #else
-
- /********* Start of inlined file: trees.h *********/
- local const ct_data static_ltree[L_CODES+2] = {
- {{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}},
- {{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}},
- {{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}},
- {{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}},
- {{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}},
- {{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}},
- {{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}},
- {{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}},
- {{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}},
- {{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}},
- {{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}},
- {{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}},
- {{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}},
- {{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}},
- {{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}},
- {{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}},
- {{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}},
- {{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}},
- {{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}},
- {{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}},
- {{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}},
- {{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}},
- {{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}},
- {{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}},
- {{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}},
- {{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}},
- {{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}},
- {{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}},
- {{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}},
- {{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}},
- {{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}},
- {{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}},
- {{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}},
- {{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}},
- {{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}},
- {{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}},
- {{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}},
- {{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}},
- {{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}},
- {{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}},
- {{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}},
- {{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}},
- {{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}},
- {{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}},
- {{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}},
- {{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}},
- {{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}},
- {{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}},
- {{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}},
- {{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}},
- {{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}},
- {{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}},
- {{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}},
- {{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}},
- {{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}},
- {{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}},
- {{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}},
- {{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}}
- };
-
- local const ct_data static_dtree[D_CODES] = {
- {{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}},
- {{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}},
- {{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}},
- {{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}},
- {{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}},
- {{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}}
- };
-
- const uch _dist_code[DIST_CODE_LEN] = {
- 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8,
- 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 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, 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, 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, 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, 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, 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, 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, 15, 15, 0, 0, 16, 17,
- 18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22,
- 23, 23, 23, 23, 23, 23, 23, 23, 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,
- 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, 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, 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, 29, 29, 29, 29, 29
- };
-
- const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12,
- 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16,
- 17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19,
- 19, 19, 19, 19, 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, 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, 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, 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, 28
- };
-
- local const int base_length[LENGTH_CODES] = {
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56,
- 64, 80, 96, 112, 128, 160, 192, 224, 0
- };
-
- local const int base_dist[D_CODES] = {
- 0, 1, 2, 3, 4, 6, 8, 12, 16, 24,
- 32, 48, 64, 96, 128, 192, 256, 384, 512, 768,
- 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576
- };
- /********* End of inlined file: trees.h *********/
-
- #endif /* GEN_TREES_H */
-
- struct static_tree_desc_s {
- const ct_data *static_tree; /* static tree or NULL */
- const intf *extra_bits; /* extra bits for each code or NULL */
- int extra_base; /* base index for extra_bits */
- int elems; /* max number of elements in the tree */
- int max_length; /* max bit length for the codes */
- };
-
- local static_tree_desc static_l_desc =
- {static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS};
-
- local static_tree_desc static_d_desc =
- {static_dtree, extra_dbits, 0, D_CODES, MAX_BITS};
-
- local static_tree_desc static_bl_desc =
- {(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS};
-
- /* ===========================================================================
- * Local (static) routines in this file.
- */
-
- local void tr_static_init OF((void));
- local void init_block OF((deflate_state *s));
- local void pqdownheap OF((deflate_state *s, ct_data *tree, int k));
- local void gen_bitlen OF((deflate_state *s, tree_desc *desc));
- local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count));
- local void build_tree OF((deflate_state *s, tree_desc *desc));
- local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code));
- local void send_tree OF((deflate_state *s, ct_data *tree, int max_code));
- local int build_bl_tree OF((deflate_state *s));
- local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes,
- int blcodes));
- local void compress_block OF((deflate_state *s, ct_data *ltree,
- ct_data *dtree));
- local void set_data_type OF((deflate_state *s));
- local unsigned bi_reverse OF((unsigned value, int length));
- local void bi_windup OF((deflate_state *s));
- local void bi_flush OF((deflate_state *s));
- local void copy_block OF((deflate_state *s, charf *buf, unsigned len,
- int header));
-
- #ifdef GEN_TREES_H
- local void gen_trees_header OF((void));
- #endif
-
- #ifndef DEBUG
- # define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len)
- /* Send a code of the given tree. c and tree must not have side effects */
-
- #else /* DEBUG */
- # define send_code(s, c, tree) \
- { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \
- send_bits(s, tree[c].Code, tree[c].Len); }
- #endif
-
- /* ===========================================================================
- * Output a short LSB first on the stream.
- * IN assertion: there is enough room in pendingBuf.
- */
- #define put_short(s, w) { \
- put_byte(s, (uch)((w) & 0xff)); \
- put_byte(s, (uch)((ush)(w) >> 8)); \
- }
-
- /* ===========================================================================
- * Send a value on a given number of bits.
- * IN assertion: length <= 16 and value fits in length bits.
- */
- #ifdef DEBUG
- local void send_bits OF((deflate_state *s, int value, int length));
-
- local void send_bits (deflate_state *s, int value, int length)
- {
- Tracevv((stderr," l %2d v %4x ", length, value));
- Assert(length > 0 && length <= 15, "invalid length");
- s->bits_sent += (ulg)length;
-
- /* If not enough room in bi_buf, use (valid) bits from bi_buf and
- * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid))
- * unused bits in value.
- */
- if (s->bi_valid > (int)Buf_size - length) {
- s->bi_buf |= (value << s->bi_valid);
- put_short(s, s->bi_buf);
- s->bi_buf = (ush)value >> (Buf_size - s->bi_valid);
- s->bi_valid += length - Buf_size;
- } else {
- s->bi_buf |= value << s->bi_valid;
- s->bi_valid += length;
- }
- }
- #else /* !DEBUG */
-
- #define send_bits(s, value, length) \
- { int len = length;\
- if (s->bi_valid > (int)Buf_size - len) {\
- int val = value;\
- s->bi_buf |= (val << s->bi_valid);\
- put_short(s, s->bi_buf);\
- s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\
- s->bi_valid += len - Buf_size;\
- } else {\
- s->bi_buf |= (value) << s->bi_valid;\
- s->bi_valid += len;\
- }\
- }
- #endif /* DEBUG */
-
- /* the arguments must not have side effects */
-
- /* ===========================================================================
- * Initialize the various 'constant' tables.
- */
- local void tr_static_init()
- {
- #if defined(GEN_TREES_H) || !defined(STDC)
- static int static_init_done = 0;
- int n; /* iterates over tree elements */
- int bits; /* bit counter */
- int length; /* length value */
- int code; /* code value */
- int dist; /* distance index */
- ush bl_count[MAX_BITS+1];
- /* number of codes at each bit length for an optimal tree */
-
- if (static_init_done) return;
-
- /* For some embedded targets, global variables are not initialized: */
- static_l_desc.static_tree = static_ltree;
- static_l_desc.extra_bits = extra_lbits;
- static_d_desc.static_tree = static_dtree;
- static_d_desc.extra_bits = extra_dbits;
- static_bl_desc.extra_bits = extra_blbits;
-
- /* Initialize the mapping length (0..255) -> length code (0..28) */
- length = 0;
- for (code = 0; code < LENGTH_CODES-1; code++) {
- base_length[code] = length;
- for (n = 0; n < (1<<extra_lbits[code]); n++) {
- _length_code[length++] = (uch)code;
- }
- }
- Assert (length == 256, "tr_static_init: length != 256");
- /* Note that the length 255 (match length 258) can be represented
- * in two different ways: code 284 + 5 bits or code 285, so we
- * overwrite length_code[255] to use the best encoding:
- */
- _length_code[length-1] = (uch)code;
-
- /* Initialize the mapping dist (0..32K) -> dist code (0..29) */
- dist = 0;
- for (code = 0 ; code < 16; code++) {
- base_dist[code] = dist;
- for (n = 0; n < (1<<extra_dbits[code]); n++) {
- _dist_code[dist++] = (uch)code;
- }
- }
- Assert (dist == 256, "tr_static_init: dist != 256");
- dist >>= 7; /* from now on, all distances are divided by 128 */
- for ( ; code < D_CODES; code++) {
- base_dist[code] = dist << 7;
- for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) {
- _dist_code[256 + dist++] = (uch)code;
- }
- }
- Assert (dist == 256, "tr_static_init: 256+dist != 512");
-
- /* Construct the codes of the static literal tree */
- for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0;
- n = 0;
- while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++;
- while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++;
- while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++;
- while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++;
- /* Codes 286 and 287 do not exist, but we must include them in the
- * tree construction to get a canonical Huffman tree (longest code
- * all ones)
- */
- gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count);
-
- /* The static distance tree is trivial: */
- for (n = 0; n < D_CODES; n++) {
- static_dtree[n].Len = 5;
- static_dtree[n].Code = bi_reverse((unsigned)n, 5);
- }
- static_init_done = 1;
-
- # ifdef GEN_TREES_H
- gen_trees_header();
- # endif
- #endif /* defined(GEN_TREES_H) || !defined(STDC) */
- }
-
- /* ===========================================================================
- * Genererate the file trees.h describing the static trees.
- */
- #ifdef GEN_TREES_H
- # ifndef DEBUG
- # include <stdio.h>
- # endif
-
- # define SEPARATOR(i, last, width) \
- ((i) == (last)? "\n};\n\n" : \
- ((i) % (width) == (width)-1 ? ",\n" : ", "))
-
- void gen_trees_header()
- {
- FILE *header = fopen("trees.h", "w");
- int i;
-
- Assert (header != NULL, "Can't open trees.h");
- fprintf(header,
- "/* header created automatically with -DGEN_TREES_H */\n\n");
-
- fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n");
- for (i = 0; i < L_CODES+2; i++) {
- fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code,
- static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5));
- }
-
- fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n");
- for (i = 0; i < D_CODES; i++) {
- fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code,
- static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5));
- }
-
- fprintf(header, "const uch _dist_code[DIST_CODE_LEN] = {\n");
- for (i = 0; i < DIST_CODE_LEN; i++) {
- fprintf(header, "%2u%s", _dist_code[i],
- SEPARATOR(i, DIST_CODE_LEN-1, 20));
- }
-
- fprintf(header, "const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {\n");
- for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) {
- fprintf(header, "%2u%s", _length_code[i],
- SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20));
- }
-
- fprintf(header, "local const int base_length[LENGTH_CODES] = {\n");
- for (i = 0; i < LENGTH_CODES; i++) {
- fprintf(header, "%1u%s", base_length[i],
- SEPARATOR(i, LENGTH_CODES-1, 20));
- }
-
- fprintf(header, "local const int base_dist[D_CODES] = {\n");
- for (i = 0; i < D_CODES; i++) {
- fprintf(header, "%5u%s", base_dist[i],
- SEPARATOR(i, D_CODES-1, 10));
- }
-
- fclose(header);
- }
- #endif /* GEN_TREES_H */
-
- /* ===========================================================================
- * Initialize the tree data structures for a new zlib stream.
- */
- void _tr_init(deflate_state *s)
- {
- tr_static_init();
-
- s->l_desc.dyn_tree = s->dyn_ltree;
- s->l_desc.stat_desc = &static_l_desc;
-
- s->d_desc.dyn_tree = s->dyn_dtree;
- s->d_desc.stat_desc = &static_d_desc;
-
- s->bl_desc.dyn_tree = s->bl_tree;
- s->bl_desc.stat_desc = &static_bl_desc;
-
- s->bi_buf = 0;
- s->bi_valid = 0;
- s->last_eob_len = 8; /* enough lookahead for inflate */
- #ifdef DEBUG
- s->compressed_len = 0L;
- s->bits_sent = 0L;
- #endif
-
- /* Initialize the first block of the first file: */
- init_block(s);
- }
-
- /* ===========================================================================
- * Initialize a new block.
- */
- local void init_block (deflate_state *s)
- {
- int n; /* iterates over tree elements */
-
- /* Initialize the trees. */
- for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0;
- for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0;
- for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0;
-
- s->dyn_ltree[END_BLOCK].Freq = 1;
- s->opt_len = s->static_len = 0L;
- s->last_lit = s->matches = 0;
- }
-
- #define SMALLEST 1
- /* Index within the heap array of least frequent node in the Huffman tree */
-
- /* ===========================================================================
- * Remove the smallest element from the heap and recreate the heap with
- * one less element. Updates heap and heap_len.
- */
- #define pqremove(s, tree, top) \
- {\
- top = s->heap[SMALLEST]; \
- s->heap[SMALLEST] = s->heap[s->heap_len--]; \
- pqdownheap(s, tree, SMALLEST); \
- }
-
- /* ===========================================================================
- * Compares to subtrees, using the tree depth as tie breaker when
- * the subtrees have equal frequency. This minimizes the worst case length.
- */
- #define smaller(tree, n, m, depth) \
- (tree[n].Freq < tree[m].Freq || \
- (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m]))
-
- /* ===========================================================================
- * Restore the heap property by moving down the tree starting at node k,
- * exchanging a node with the smallest of its two sons if necessary, stopping
- * when the heap property is re-established (each father smaller than its
- * two sons).
- */
- local void pqdownheap (deflate_state *s,
- ct_data *tree, /* the tree to restore */
- int k) /* node to move down */
- {
- int v = s->heap[k];
- int j = k << 1; /* left son of k */
- while (j <= s->heap_len) {
- /* Set j to the smallest of the two sons: */
- if (j < s->heap_len &&
- smaller(tree, s->heap[j+1], s->heap[j], s->depth)) {
- j++;
- }
- /* Exit if v is smaller than both sons */
- if (smaller(tree, v, s->heap[j], s->depth)) break;
-
- /* Exchange v with the smallest son */
- s->heap[k] = s->heap[j]; k = j;
-
- /* And continue down the tree, setting j to the left son of k */
- j <<= 1;
- }
- s->heap[k] = v;
- }
-
- /* ===========================================================================
- * Compute the optimal bit lengths for a tree and update the total bit length
- * for the current block.
- * IN assertion: the fields freq and dad are set, heap[heap_max] and
- * above are the tree nodes sorted by increasing frequency.
- * OUT assertions: the field len is set to the optimal bit length, the
- * array bl_count contains the frequencies for each bit length.
- * The length opt_len is updated; static_len is also updated if stree is
- * not null.
- */
- local void gen_bitlen (deflate_state *s, tree_desc *desc)
- {
- ct_data *tree = desc->dyn_tree;
- int max_code = desc->max_code;
- const ct_data *stree = desc->stat_desc->static_tree;
- const intf *extra = desc->stat_desc->extra_bits;
- int base = desc->stat_desc->extra_base;
- int max_length = desc->stat_desc->max_length;
- int h; /* heap index */
- int n, m; /* iterate over the tree elements */
- int bits; /* bit length */
- int xbits; /* extra bits */
- ush f; /* frequency */
- int overflow = 0; /* number of elements with bit length too large */
-
- for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0;
-
- /* In a first pass, compute the optimal bit lengths (which may
- * overflow in the case of the bit length tree).
- */
- tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */
-
- for (h = s->heap_max+1; h < HEAP_SIZE; h++) {
- n = s->heap[h];
- bits = tree[tree[n].Dad].Len + 1;
- if (bits > max_length) bits = max_length, overflow++;
- tree[n].Len = (ush)bits;
- /* We overwrite tree[n].Dad which is no longer needed */
-
- if (n > max_code) continue; /* not a leaf node */
-
- s->bl_count[bits]++;
- xbits = 0;
- if (n >= base) xbits = extra[n-base];
- f = tree[n].Freq;
- s->opt_len += (ulg)f * (bits + xbits);
- if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits);
- }
- if (overflow == 0) return;
-
- Trace((stderr,"\nbit length overflow\n"));
- /* This happens for example on obj2 and pic of the Calgary corpus */
-
- /* Find the first bit length which could increase: */
- do {
- bits = max_length-1;
- while (s->bl_count[bits] == 0) bits--;
- s->bl_count[bits]--; /* move one leaf down the tree */
- s->bl_count[bits+1] += 2; /* move one overflow item as its brother */
- s->bl_count[max_length]--;
- /* The brother of the overflow item also moves one step up,
- * but this does not affect bl_count[max_length]
- */
- overflow -= 2;
- } while (overflow > 0);
-
- /* Now recompute all bit lengths, scanning in increasing frequency.
- * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all
- * lengths instead of fixing only the wrong ones. This idea is taken
- * from 'ar' written by Haruhiko Okumura.)
- */
- for (bits = max_length; bits != 0; bits--) {
- n = s->bl_count[bits];
- while (n != 0) {
- m = s->heap[--h];
- if (m > max_code) continue;
- if ((unsigned) tree[m].Len != (unsigned) bits) {
- Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits));
- s->opt_len += ((long)bits - (long)tree[m].Len)
- *(long)tree[m].Freq;
- tree[m].Len = (ush)bits;
- }
- n--;
- }
- }
- }
-
- /* ===========================================================================
- * Generate the codes for a given tree and bit counts (which need not be
- * optimal).
- * IN assertion: the array bl_count contains the bit length statistics for
- * the given tree and the field len is set for all tree elements.
- * OUT assertion: the field code is set for all tree elements of non
- * zero code length.
- */
- local void gen_codes (ct_data *tree, /* the tree to decorate */
- int max_code, /* largest code with non zero frequency */
- ushf *bl_count) /* number of codes at each bit length */
- {
- ush next_code[MAX_BITS+1]; /* next code value for each bit length */
- ush code = 0; /* running code value */
- int bits; /* bit index */
- int n; /* code index */
-
- /* The distribution counts are first used to generate the code values
- * without bit reversal.
- */
- for (bits = 1; bits <= MAX_BITS; bits++) {
- next_code[bits] = code = (code + bl_count[bits-1]) << 1;
- }
- /* Check that the bit counts in bl_count are consistent. The last code
- * must be all ones.
- */
- Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
- "inconsistent bit counts");
- Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
-
- for (n = 0; n <= max_code; n++) {
- int len = tree[n].Len;
- if (len == 0) continue;
- /* Now reverse the bits */
- tree[n].Code = bi_reverse(next_code[len]++, len);
-
- Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
- n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1));
- }
- }
-
- /* ===========================================================================
- * Construct one Huffman tree and assigns the code bit strings and lengths.
- * Update the total bit length for the current block.
- * IN assertion: the field freq is set for all tree elements.
- * OUT assertions: the fields len and code are set to the optimal bit length
- * and corresponding code. The length opt_len is updated; static_len is
- * also updated if stree is not null. The field max_code is set.
- */
- local void build_tree (deflate_state *s,
- tree_desc *desc) /* the tree descriptor */
- {
- ct_data *tree = desc->dyn_tree;
- const ct_data *stree = desc->stat_desc->static_tree;
- int elems = desc->stat_desc->elems;
- int n, m; /* iterate over heap elements */
- int max_code = -1; /* largest code with non zero frequency */
- int node; /* new node being created */
-
- /* Construct the initial heap, with least frequent element in
- * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
- * heap[0] is not used.
- */
- s->heap_len = 0, s->heap_max = HEAP_SIZE;
-
- for (n = 0; n < elems; n++) {
- if (tree[n].Freq != 0) {
- s->heap[++(s->heap_len)] = max_code = n;
- s->depth[n] = 0;
- } else {
- tree[n].Len = 0;
- }
- }
-
- /* The pkzip format requires that at least one distance code exists,
- * and that at least one bit should be sent even if there is only one
- * possible code. So to avoid special checks later on we force at least
- * two codes of non zero frequency.
- */
- while (s->heap_len < 2) {
- node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0);
- tree[node].Freq = 1;
- s->depth[node] = 0;
- s->opt_len--; if (stree) s->static_len -= stree[node].Len;
- /* node is 0 or 1 so it does not have extra bits */
- }
- desc->max_code = max_code;
-
- /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
- * establish sub-heaps of increasing lengths:
- */
- for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n);
-
- /* Construct the Huffman tree by repeatedly combining the least two
- * frequent nodes.
- */
- node = elems; /* next internal node of the tree */
- do {
- pqremove(s, tree, n); /* n = node of least frequency */
- m = s->heap[SMALLEST]; /* m = node of next least frequency */
-
- s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */
- s->heap[--(s->heap_max)] = m;
-
- /* Create a new node father of n and m */
- tree[node].Freq = tree[n].Freq + tree[m].Freq;
- s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ?
- s->depth[n] : s->depth[m]) + 1);
- tree[n].Dad = tree[m].Dad = (ush)node;
- #ifdef DUMP_BL_TREE
- if (tree == s->bl_tree) {
- fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)",
- node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq);
- }
- #endif
- /* and insert the new node in the heap */
- s->heap[SMALLEST] = node++;
- pqdownheap(s, tree, SMALLEST);
-
- } while (s->heap_len >= 2);
-
- s->heap[--(s->heap_max)] = s->heap[SMALLEST];
-
- /* At this point, the fields freq and dad are set. We can now
- * generate the bit lengths.
- */
- gen_bitlen(s, (tree_desc *)desc);
-
- /* The field len is now set, we can generate the bit codes */
- gen_codes ((ct_data *)tree, max_code, s->bl_count);
- }
-
- /* ===========================================================================
- * Scan a literal or distance tree to determine the frequencies of the codes
- * in the bit length tree.
- */
- local void scan_tree (deflate_state *s,
- ct_data *tree, /* the tree to be scanned */
- int max_code) /* and its largest code of non zero frequency */
- {
- int n; /* iterates over all tree elements */
- int prevlen = -1; /* last emitted length */
- int curlen; /* length of current code */
- int nextlen = tree[0].Len; /* length of next code */
- int count = 0; /* repeat count of the current code */
- int max_count = 7; /* max repeat count */
- int min_count = 4; /* min repeat count */
-
- if (nextlen == 0) max_count = 138, min_count = 3;
- tree[max_code+1].Len = (ush)0xffff; /* guard */
-
- for (n = 0; n <= max_code; n++) {
- curlen = nextlen; nextlen = tree[n+1].Len;
- if (++count < max_count && curlen == nextlen) {
- continue;
- } else if (count < min_count) {
- s->bl_tree[curlen].Freq += count;
- } else if (curlen != 0) {
- if (curlen != prevlen) s->bl_tree[curlen].Freq++;
- s->bl_tree[REP_3_6].Freq++;
- } else if (count <= 10) {
- s->bl_tree[REPZ_3_10].Freq++;
- } else {
- s->bl_tree[REPZ_11_138].Freq++;
- }
- count = 0; prevlen = curlen;
- if (nextlen == 0) {
- max_count = 138, min_count = 3;
- } else if (curlen == nextlen) {
- max_count = 6, min_count = 3;
- } else {
- max_count = 7, min_count = 4;
- }
- }
- }
-
- /* ===========================================================================
- * Send a literal or distance tree in compressed form, using the codes in
- * bl_tree.
- */
- local void send_tree (deflate_state *s,
- ct_data *tree, /* the tree to be scanned */
- int max_code) /* and its largest code of non zero frequency */
- {
- int n; /* iterates over all tree elements */
- int prevlen = -1; /* last emitted length */
- int curlen; /* length of current code */
- int nextlen = tree[0].Len; /* length of next code */
- int count = 0; /* repeat count of the current code */
- int max_count = 7; /* max repeat count */
- int min_count = 4; /* min repeat count */
-
- /* tree[max_code+1].Len = -1; */ /* guard already set */
- if (nextlen == 0) max_count = 138, min_count = 3;
-
- for (n = 0; n <= max_code; n++) {
- curlen = nextlen; nextlen = tree[n+1].Len;
- if (++count < max_count && curlen == nextlen) {
- continue;
- } else if (count < min_count) {
- do { send_code(s, curlen, s->bl_tree); } while (--count != 0);
-
- } else if (curlen != 0) {
- if (curlen != prevlen) {
- send_code(s, curlen, s->bl_tree); count--;
- }
- Assert(count >= 3 && count <= 6, " 3_6?");
- send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2);
-
- } else if (count <= 10) {
- send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3);
-
- } else {
- send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7);
- }
- count = 0; prevlen = curlen;
- if (nextlen == 0) {
- max_count = 138, min_count = 3;
- } else if (curlen == nextlen) {
- max_count = 6, min_count = 3;
- } else {
- max_count = 7, min_count = 4;
- }
- }
- }
-
- /* ===========================================================================
- * Construct the Huffman tree for the bit lengths and return the index in
- * bl_order of the last bit length code to send.
- */
- local int build_bl_tree (deflate_state *s)
- {
- int max_blindex; /* index of last bit length code of non zero freq */
-
- /* Determine the bit length frequencies for literal and distance trees */
- scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code);
- scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code);
-
- /* Build the bit length tree: */
- build_tree(s, (tree_desc *)(&(s->bl_desc)));
- /* opt_len now includes the length of the tree representations, except
- * the lengths of the bit lengths codes and the 5+5+4 bits for the counts.
- */
-
- /* Determine the number of bit length codes to send. The pkzip format
- * requires that at least 4 bit length codes be sent. (appnote.txt says
- * 3 but the actual value used is 4.)
- */
- for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) {
- if (s->bl_tree[bl_order[max_blindex]].Len != 0) break;
- }
- /* Update opt_len to include the bit length tree and counts */
- s->opt_len += 3*(max_blindex+1) + 5+5+4;
- Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld",
- s->opt_len, s->static_len));
-
- return max_blindex;
- }
-
- /* ===========================================================================
- * Send the header for a block using dynamic Huffman trees: the counts, the
- * lengths of the bit length codes, the literal tree and the distance tree.
- * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
- */
- local void send_all_trees (deflate_state *s,
- int lcodes, int dcodes, int blcodes) /* number of codes for each tree */
- {
- int rank; /* index in bl_order */
-
- Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");
- Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,
- "too many codes");
- Tracev((stderr, "\nbl counts: "));
- send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */
- send_bits(s, dcodes-1, 5);
- send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */
- for (rank = 0; rank < blcodes; rank++) {
- Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
- send_bits(s, s->bl_tree[bl_order[rank]].Len, 3);
- }
- Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent));
-
- send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */
- Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent));
-
- send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */
- Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent));
- }
-
- /* ===========================================================================
- * Send a stored block
- */
- void _tr_stored_block (deflate_state *s, charf *buf, ulg stored_len, int eof)
- {
- send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */
- #ifdef DEBUG
- s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L;
- s->compressed_len += (stored_len + 4) << 3;
- #endif
- copy_block(s, buf, (unsigned)stored_len, 1); /* with header */
- }
-
- /* ===========================================================================
- * Send one empty static block to give enough lookahead for inflate.
- * This takes 10 bits, of which 7 may remain in the bit buffer.
- * The current inflate code requires 9 bits of lookahead. If the
- * last two codes for the previous block (real code plus EOB) were coded
- * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode
- * the last real code. In this case we send two empty static blocks instead
- * of one. (There are no problems if the previous block is stored or fixed.)
- * To simplify the code, we assume the worst case of last real code encoded
- * on one bit only.
- */
- void _tr_align (deflate_state *s)
- {
- send_bits(s, STATIC_TREES<<1, 3);
- send_code(s, END_BLOCK, static_ltree);
- #ifdef DEBUG
- s->compressed_len += 10L; /* 3 for block type, 7 for EOB */
- #endif
- bi_flush(s);
- /* Of the 10 bits for the empty block, we have already sent
- * (10 - bi_valid) bits. The lookahead for the last real code (before
- * the EOB of the previous block) was thus at least one plus the length
- * of the EOB plus what we have just sent of the empty static block.
- */
- if (1 + s->last_eob_len + 10 - s->bi_valid < 9) {
- send_bits(s, STATIC_TREES<<1, 3);
- send_code(s, END_BLOCK, static_ltree);
- #ifdef DEBUG
- s->compressed_len += 10L;
- #endif
- bi_flush(s);
- }
- s->last_eob_len = 7;
- }
-
- /* ===========================================================================
- * Determine the best encoding for the current block: dynamic trees, static
- * trees or store, and output the encoded block to the zip file.
- */
- void _tr_flush_block (deflate_state *s,
- charf *buf, /* input block, or NULL if too old */
- ulg stored_len, /* length of input block */
- int eof) /* true if this is the last block for a file */
- {
- ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */
- int max_blindex = 0; /* index of last bit length code of non zero freq */
-
- /* Build the Huffman trees unless a stored block is forced */
- if (s->level > 0) {
-
- /* Check if the file is binary or text */
- if (stored_len > 0 && s->strm->data_type == Z_UNKNOWN)
- set_data_type(s);
-
- /* Construct the literal and distance trees */
- build_tree(s, (tree_desc *)(&(s->l_desc)));
- Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len,
- s->static_len));
-
- build_tree(s, (tree_desc *)(&(s->d_desc)));
- Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len,
- s->static_len));
- /* At this point, opt_len and static_len are the total bit lengths of
- * the compressed block data, excluding the tree representations.
- */
-
- /* Build the bit length tree for the above two trees, and get the index
- * in bl_order of the last bit length code to send.
- */
- max_blindex = build_bl_tree(s);
-
- /* Determine the best encoding. Compute the block lengths in bytes. */
- opt_lenb = (s->opt_len+3+7)>>3;
- static_lenb = (s->static_len+3+7)>>3;
-
- Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ",
- opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,
- s->last_lit));
-
- if (static_lenb <= opt_lenb) opt_lenb = static_lenb;
-
- } else {
- Assert(buf != (char*)0, "lost buf");
- opt_lenb = static_lenb = stored_len + 5; /* force a stored block */
- }
-
- #ifdef FORCE_STORED
- if (buf != (char*)0) { /* force stored block */
- #else
- if (stored_len+4 <= opt_lenb && buf != (char*)0) {
- /* 4: two words for the lengths */
- #endif
- /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
- * Otherwise we can't have processed more than WSIZE input bytes since
- * the last block flush, because compression would have been
- * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
- * transform a block into a stored block.
- */
- _tr_stored_block(s, buf, stored_len, eof);
-
- #ifdef FORCE_STATIC
- } else if (static_lenb >= 0) { /* force static trees */
- #else
- } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) {
- #endif
- send_bits(s, (STATIC_TREES<<1)+eof, 3);
- compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree);
- #ifdef DEBUG
- s->compressed_len += 3 + s->static_len;
- #endif
- } else {
- send_bits(s, (DYN_TREES<<1)+eof, 3);
- send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1,
- max_blindex+1);
- compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree);
- #ifdef DEBUG
- s->compressed_len += 3 + s->opt_len;
- #endif
- }
- Assert (s->compressed_len == s->bits_sent, "bad compressed size");
- /* The above check is made mod 2^32, for files larger than 512 MB
- * and uLong implemented on 32 bits.
- */
- init_block(s);
-
- if (eof) {
- bi_windup(s);
- #ifdef DEBUG
- s->compressed_len += 7; /* align on byte boundary */
- #endif
- }
- Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3,
- s->compressed_len-7*eof));
- }
-
- /* ===========================================================================
- * Save the match info and tally the frequency counts. Return true if
- * the current block must be flushed.
- */
- int _tr_tally (deflate_state *s,
- unsigned dist, /* distance of matched string */
- unsigned lc) /* match length-MIN_MATCH or unmatched char (if dist==0) */
- {
- s->d_buf[s->last_lit] = (ush)dist;
- s->l_buf[s->last_lit++] = (uch)lc;
- if (dist == 0) {
- /* lc is the unmatched char */
- s->dyn_ltree[lc].Freq++;
- } else {
- s->matches++;
- /* Here, lc is the match length - MIN_MATCH */
- dist--; /* dist = match distance - 1 */
- Assert((ush)dist < (ush)MAX_DIST(s) &&
- (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
- (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match");
-
- s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++;
- s->dyn_dtree[d_code(dist)].Freq++;
- }
-
- #ifdef TRUNCATE_BLOCK
- /* Try to guess if it is profitable to stop the current block here */
- if ((s->last_lit & 0x1fff) == 0 && s->level > 2) {
- /* Compute an upper bound for the compressed length */
- ulg out_length = (ulg)s->last_lit*8L;
- ulg in_length = (ulg)((long)s->strstart - s->block_start);
- int dcode;
- for (dcode = 0; dcode < D_CODES; dcode++) {
- out_length += (ulg)s->dyn_dtree[dcode].Freq *
- (5L+extra_dbits[dcode]);
- }
- out_length >>= 3;
- Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ",
- s->last_lit, in_length, out_length,
- 100L - out_length*100L/in_length));
- if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1;
- }
- #endif
- return (s->last_lit == s->lit_bufsize-1);
- /* We avoid equality with lit_bufsize because of wraparound at 64K
- * on 16 bit machines and because stored blocks are restricted to
- * 64K-1 bytes.
- */
- }
-
- /* ===========================================================================
- * Send the block data compressed using the given Huffman trees
- */
- local void compress_block (deflate_state *s,
- ct_data *ltree, /* literal tree */
- ct_data *dtree) /* distance tree */
- {
- unsigned dist; /* distance of matched string */
- int lc; /* match length or unmatched char (if dist == 0) */
- unsigned lx = 0; /* running index in l_buf */
- unsigned code; /* the code to send */
- int extra; /* number of extra bits to send */
-
- if (s->last_lit != 0) do {
- dist = s->d_buf[lx];
- lc = s->l_buf[lx++];
- if (dist == 0) {
- send_code(s, lc, ltree); /* send a literal byte */
- Tracecv(isgraph(lc), (stderr," '%c' ", lc));
- } else {
- /* Here, lc is the match length - MIN_MATCH */
- code = _length_code[lc];
- send_code(s, code+LITERALS+1, ltree); /* send the length code */
- extra = extra_lbits[code];
- if (extra != 0) {
- lc -= base_length[code];
- send_bits(s, lc, extra); /* send the extra length bits */
- }
- dist--; /* dist is now the match distance - 1 */
- code = d_code(dist);
- Assert (code < D_CODES, "bad d_code");
-
- send_code(s, code, dtree); /* send the distance code */
- extra = extra_dbits[code];
- if (extra != 0) {
- dist -= base_dist[code];
- send_bits(s, dist, extra); /* send the extra distance bits */
- }
- } /* literal or match pair ? */
-
- /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */
- Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx,
- "pendingBuf overflow");
-
- } while (lx < s->last_lit);
-
- send_code(s, END_BLOCK, ltree);
- s->last_eob_len = ltree[END_BLOCK].Len;
- }
-
- /* ===========================================================================
- * Set the data type to BINARY or TEXT, using a crude approximation:
- * set it to Z_TEXT if all symbols are either printable characters (33 to 255)
- * or white spaces (9 to 13, or 32); or set it to Z_BINARY otherwise.
- * IN assertion: the fields Freq of dyn_ltree are set.
- */
- local void set_data_type (deflate_state *s)
- {
- int n;
-
- for (n = 0; n < 9; n++)
- if (s->dyn_ltree[n].Freq != 0)
- break;
- if (n == 9)
- for (n = 14; n < 32; n++)
- if (s->dyn_ltree[n].Freq != 0)
- break;
- s->strm->data_type = (n == 32) ? Z_TEXT : Z_BINARY;
- }
-
- /* ===========================================================================
- * Reverse the first len bits of a code, using straightforward code (a faster
- * method would use a table)
- * IN assertion: 1 <= len <= 15
- */
- local unsigned bi_reverse (unsigned code, int len)
- {
- register unsigned res = 0;
- do {
- res |= code & 1;
- code >>= 1, res <<= 1;
- } while (--len > 0);
- return res >> 1;
- }
-
- /* ===========================================================================
- * Flush the bit buffer, keeping at most 7 bits in it.
- */
- local void bi_flush (deflate_state *s)
- {
- if (s->bi_valid == 16) {
- put_short(s, s->bi_buf);
- s->bi_buf = 0;
- s->bi_valid = 0;
- } else if (s->bi_valid >= 8) {
- put_byte(s, (Byte)s->bi_buf);
- s->bi_buf >>= 8;
- s->bi_valid -= 8;
- }
- }
-
- /* ===========================================================================
- * Flush the bit buffer and align the output on a byte boundary
- */
- local void bi_windup (deflate_state *s)
- {
- if (s->bi_valid > 8) {
- put_short(s, s->bi_buf);
- } else if (s->bi_valid > 0) {
- put_byte(s, (Byte)s->bi_buf);
- }
- s->bi_buf = 0;
- s->bi_valid = 0;
- #ifdef DEBUG
- s->bits_sent = (s->bits_sent+7) & ~7;
- #endif
- }
-
- /* ===========================================================================
- * Copy a stored block, storing first the length and its
- * one's complement if requested.
- */
- local void copy_block(deflate_state *s,
- charf *buf, /* the input data */
- unsigned len, /* its length */
- int header) /* true if block header must be written */
- {
- bi_windup(s); /* align on byte boundary */
- s->last_eob_len = 8; /* enough lookahead for inflate */
-
- if (header) {
- put_short(s, (ush)len);
- put_short(s, (ush)~len);
- #ifdef DEBUG
- s->bits_sent += 2*16;
- #endif
- }
- #ifdef DEBUG
- s->bits_sent += (ulg)len<<3;
- #endif
- while (len--) {
- put_byte(s, *buf++);
- }
- }
- /********* End of inlined file: trees.c *********/
-
- /********* Start of inlined file: uncompr.c *********/
- /* @(#) $Id: uncompr.c,v 1.1 2007/06/07 17:54:37 jules_rms Exp $ */
-
- #define ZLIB_INTERNAL
-
- /* ===========================================================================
- Decompresses the source buffer into the destination buffer. sourceLen is
- the byte length of the source buffer. Upon entry, destLen is the total
- size of the destination buffer, which must be large enough to hold the
- entire uncompressed data. (The size of the uncompressed data must have
- been saved previously by the compressor and transmitted to the decompressor
- by some mechanism outside the scope of this compression library.)
- Upon exit, destLen is the actual size of the compressed buffer.
- This function can be used to decompress a whole file at once if the
- input file is mmap'ed.
-
- uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
- enough memory, Z_BUF_ERROR if there was not enough room in the output
- buffer, or Z_DATA_ERROR if the input data was corrupted.
- */
- int ZEXPORT uncompress (Bytef *dest,
- uLongf *destLen,
- const Bytef *source,
- uLong sourceLen)
- {
- z_stream stream;
- int err;
-
- stream.next_in = (Bytef*)source;
- stream.avail_in = (uInt)sourceLen;
- /* Check for source > 64K on 16-bit machine: */
- if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
-
- stream.next_out = dest;
- stream.avail_out = (uInt)*destLen;
- if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
-
- stream.zalloc = (alloc_func)0;
- stream.zfree = (free_func)0;
-
- err = inflateInit(&stream);
- if (err != Z_OK) return err;
-
- err = inflate(&stream, Z_FINISH);
- if (err != Z_STREAM_END) {
- inflateEnd(&stream);
- if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0))
- return Z_DATA_ERROR;
- return err;
- }
- *destLen = stream.total_out;
-
- err = inflateEnd(&stream);
- return err;
- }
- /********* End of inlined file: uncompr.c *********/
-
- /********* Start of inlined file: zutil.c *********/
- /* @(#) $Id: zutil.c,v 1.1 2007/06/07 17:54:37 jules_rms Exp $ */
-
- #ifndef NO_DUMMY_DECL
- struct internal_state {int dummy;}; /* for buggy compilers */
- #endif
-
- const char * const z_errmsg[10] = {
- "need dictionary", /* Z_NEED_DICT 2 */
- "stream end", /* Z_STREAM_END 1 */
- "", /* Z_OK 0 */
- "file error", /* Z_ERRNO (-1) */
- "stream error", /* Z_STREAM_ERROR (-2) */
- "data error", /* Z_DATA_ERROR (-3) */
- "insufficient memory", /* Z_MEM_ERROR (-4) */
- "buffer error", /* Z_BUF_ERROR (-5) */
- "incompatible version",/* Z_VERSION_ERROR (-6) */
- ""};
-
- /*const char * ZEXPORT zlibVersion()
- {
- return ZLIB_VERSION;
- }
-
- uLong ZEXPORT zlibCompileFlags()
- {
- uLong flags;
-
- flags = 0;
- switch (sizeof(uInt)) {
- case 2: break;
- case 4: flags += 1; break;
- case 8: flags += 2; break;
- default: flags += 3;
- }
- switch (sizeof(uLong)) {
- case 2: break;
- case 4: flags += 1 << 2; break;
- case 8: flags += 2 << 2; break;
- default: flags += 3 << 2;
- }
- switch (sizeof(voidpf)) {
- case 2: break;
- case 4: flags += 1 << 4; break;
- case 8: flags += 2 << 4; break;
- default: flags += 3 << 4;
- }
- switch (sizeof(z_off_t)) {
- case 2: break;
- case 4: flags += 1 << 6; break;
- case 8: flags += 2 << 6; break;
- default: flags += 3 << 6;
- }
- #ifdef DEBUG
- flags += 1 << 8;
- #endif
- #if defined(ASMV) || defined(ASMINF)
- flags += 1 << 9;
- #endif
- #ifdef ZLIB_WINAPI
- flags += 1 << 10;
- #endif
- #ifdef BUILDFIXED
- flags += 1 << 12;
- #endif
- #ifdef DYNAMIC_CRC_TABLE
- flags += 1 << 13;
- #endif
- #ifdef NO_GZCOMPRESS
- flags += 1L << 16;
- #endif
- #ifdef NO_GZIP
- flags += 1L << 17;
- #endif
- #ifdef PKZIP_BUG_WORKAROUND
- flags += 1L << 20;
- #endif
- #ifdef FASTEST
- flags += 1L << 21;
- #endif
- #ifdef STDC
- # ifdef NO_vsnprintf
- flags += 1L << 25;
- # ifdef HAS_vsprintf_void
- flags += 1L << 26;
- # endif
- # else
- # ifdef HAS_vsnprintf_void
- flags += 1L << 26;
- # endif
- # endif
- #else
- flags += 1L << 24;
- # ifdef NO_snprintf
- flags += 1L << 25;
- # ifdef HAS_sprintf_void
- flags += 1L << 26;
- # endif
- # else
- # ifdef HAS_snprintf_void
- flags += 1L << 26;
- # endif
- # endif
- #endif
- return flags;
- }*/
-
- #ifdef DEBUG
-
- # ifndef verbose
- # define verbose 0
- # endif
- int z_verbose = verbose;
-
- void z_error (char *m)
- {
- fprintf(stderr, "%s\n", m);
- exit(1);
- }
- #endif
-
- /* exported to allow conversion of error code to string for compress() and
- * uncompress()
- */
- const char * ZEXPORT zError(int err)
- {
- return ERR_MSG(err);
- }
-
- #if defined(_WIN32_WCE)
- /* The Microsoft C Run-Time Library for Windows CE doesn't have
- * errno. We define it as a global variable to simplify porting.
- * Its value is always 0 and should not be used.
- */
- int errno = 0;
- #endif
-
- #ifndef HAVE_MEMCPY
-
- void zmemcpy(dest, source, len)
- Bytef* dest;
- const Bytef* source;
- uInt len;
- {
- if (len == 0) return;
- do {
- *dest++ = *source++; /* ??? to be unrolled */
- } while (--len != 0);
- }
-
- int zmemcmp(s1, s2, len)
- const Bytef* s1;
- const Bytef* s2;
- uInt len;
- {
- uInt j;
-
- for (j = 0; j < len; j++) {
- if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1;
- }
- return 0;
- }
-
- void zmemzero(dest, len)
- Bytef* dest;
- uInt len;
- {
- if (len == 0) return;
- do {
- *dest++ = 0; /* ??? to be unrolled */
- } while (--len != 0);
- }
- #endif
-
- #ifdef SYS16BIT
-
- #ifdef __TURBOC__
- /* Turbo C in 16-bit mode */
-
- # define MY_ZCALLOC
-
- /* Turbo C malloc() does not allow dynamic allocation of 64K bytes
- * and farmalloc(64K) returns a pointer with an offset of 8, so we
- * must fix the pointer. Warning: the pointer must be put back to its
- * original form in order to free it, use zcfree().
- */
-
- #define MAX_PTR 10
- /* 10*64K = 640K */
-
- local int next_ptr = 0;
-
- typedef struct ptr_table_s {
- voidpf org_ptr;
- voidpf new_ptr;
- } ptr_table;
-
- local ptr_table table[MAX_PTR];
- /* This table is used to remember the original form of pointers
- * to large buffers (64K). Such pointers are normalized with a zero offset.
- * Since MSDOS is not a preemptive multitasking OS, this table is not
- * protected from concurrent access. This hack doesn't work anyway on
- * a protected system like OS/2. Use Microsoft C instead.
- */
-
- voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
- {
- voidpf buf = opaque; /* just to make some compilers happy */
- ulg bsize = (ulg)items*size;
-
- /* If we allocate less than 65520 bytes, we assume that farmalloc
- * will return a usable pointer which doesn't have to be normalized.
- */
- if (bsize < 65520L) {
- buf = farmalloc(bsize);
- if (*(ush*)&buf != 0) return buf;
- } else {
- buf = farmalloc(bsize + 16L);
- }
- if (buf == NULL || next_ptr >= MAX_PTR) return NULL;
- table[next_ptr].org_ptr = buf;
-
- /* Normalize the pointer to seg:0 */
- *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4;
- *(ush*)&buf = 0;
- table[next_ptr++].new_ptr = buf;
- return buf;
- }
-
- void zcfree (voidpf opaque, voidpf ptr)
- {
- int n;
- if (*(ush*)&ptr != 0) { /* object < 64K */
- farfree(ptr);
- return;
- }
- /* Find the original pointer */
- for (n = 0; n < next_ptr; n++) {
- if (ptr != table[n].new_ptr) continue;
-
- farfree(table[n].org_ptr);
- while (++n < next_ptr) {
- table[n-1] = table[n];
- }
- next_ptr--;
- return;
- }
- ptr = opaque; /* just to make some compilers happy */
- Assert(0, "zcfree: ptr not found");
- }
-
- #endif /* __TURBOC__ */
-
- #ifdef M_I86
- /* Microsoft C in 16-bit mode */
-
- # define MY_ZCALLOC
-
- #if (!defined(_MSC_VER) || (_MSC_VER <= 600))
- # define _halloc halloc
- # define _hfree hfree
- #endif
-
- voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
- {
- if (opaque) opaque = 0; /* to make compiler happy */
- return _halloc((long)items, size);
- }
-
- void zcfree (voidpf opaque, voidpf ptr)
- {
- if (opaque) opaque = 0; /* to make compiler happy */
- _hfree(ptr);
- }
-
- #endif /* M_I86 */
-
- #endif /* SYS16BIT */
-
- #ifndef MY_ZCALLOC /* Any system without a special alloc function */
-
- #ifndef STDC
- extern voidp malloc OF((uInt size));
- extern voidp calloc OF((uInt items, uInt size));
- extern void free OF((voidpf ptr));
- #endif
-
- voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
- {
- if (opaque) items += size - size; /* make compiler happy */
- return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) :
- (voidpf)calloc(items, size);
- }
-
- void zcfree (voidpf opaque, voidpf ptr)
- {
- free(ptr);
- if (opaque) return; /* make compiler happy */
- }
-
- #endif /* MY_ZCALLOC */
- /********* End of inlined file: zutil.c *********/
-
- #undef Byte
- }
- }
-
- #if JUCE_MSVC
- #pragma warning (pop)
- #endif
-
- BEGIN_JUCE_NAMESPACE
-
- using namespace zlibNamespace;
-
- // internal helper object that holds the zlib structures so they don't have to be
- // included publicly.
- class GZIPDecompressHelper
- {
- private:
- z_stream* stream;
- uint8* data;
- int dataSize;
-
- public:
- bool finished, needsDictionary, error;
-
- GZIPDecompressHelper (const bool noWrap) throw()
- : data (0),
- dataSize (0),
- finished (false),
- needsDictionary (false),
- error (false)
- {
- stream = (z_stream*) juce_calloc (sizeof (z_stream));
-
- if (inflateInit2 (stream, (noWrap) ? -MAX_WBITS
- : MAX_WBITS) != Z_OK)
- {
- juce_free (stream);
- stream = 0;
- error = true;
- finished = true;
- }
- }
-
- ~GZIPDecompressHelper() throw()
- {
- if (stream != 0)
- {
- inflateEnd (stream);
- juce_free (stream);
- }
- }
-
- bool needsInput() const throw() { return dataSize <= 0; }
-
- void setInput (uint8* const data_, const int size) throw()
- {
- data = data_;
- dataSize = size;
- }
-
- int doNextBlock (uint8* const dest, const int destSize) throw()
- {
- if (stream != 0 && data != 0 && ! finished)
- {
- stream->next_in = data;
- stream->next_out = dest;
- stream->avail_in = dataSize;
- stream->avail_out = destSize;
-
- switch (inflate (stream, Z_PARTIAL_FLUSH))
- {
- case Z_STREAM_END:
- finished = true;
- // deliberate fall-through
-
- case Z_OK:
- data += dataSize - stream->avail_in;
- dataSize = stream->avail_in;
- return destSize - stream->avail_out;
-
- case Z_NEED_DICT:
- needsDictionary = true;
- data += dataSize - stream->avail_in;
- dataSize = stream->avail_in;
- break;
-
- case Z_DATA_ERROR:
- case Z_MEM_ERROR:
- error = true;
-
- default:
- break;
- }
- }
-
- return 0;
- }
- };
-
- const int gzipDecompBufferSize = 32768;
-
- GZIPDecompressorInputStream::GZIPDecompressorInputStream (InputStream* const sourceStream_,
- const bool deleteSourceWhenDestroyed_,
- const bool noWrap_,
- const int64 uncompressedStreamLength_)
- : sourceStream (sourceStream_),
- uncompressedStreamLength (uncompressedStreamLength_),
- deleteSourceWhenDestroyed (deleteSourceWhenDestroyed_),
- noWrap (noWrap_),
- isEof (false),
- activeBufferSize (0),
- originalSourcePos (sourceStream_->getPosition()),
- currentPos (0)
- {
- buffer = (uint8*) juce_malloc (gzipDecompBufferSize);
- helper = new GZIPDecompressHelper (noWrap_);
- }
-
- GZIPDecompressorInputStream::~GZIPDecompressorInputStream()
- {
- juce_free (buffer);
-
- if (deleteSourceWhenDestroyed)
- delete sourceStream;
-
- GZIPDecompressHelper* const h = (GZIPDecompressHelper*) helper;
- delete h;
- }
-
- int64 GZIPDecompressorInputStream::getTotalLength()
- {
- return uncompressedStreamLength;
- }
-
- int GZIPDecompressorInputStream::read (void* destBuffer, int howMany)
- {
- GZIPDecompressHelper* const h = (GZIPDecompressHelper*) helper;
-
- if ((howMany > 0) && ! isEof)
- {
- jassert (destBuffer != 0);
-
- if (destBuffer != 0)
- {
- int numRead = 0;
- uint8* d = (uint8*) destBuffer;
-
- while (! h->error)
- {
- const int n = h->doNextBlock (d, howMany);
- currentPos += n;
-
- if (n == 0)
- {
- if (h->finished || h->needsDictionary)
- {
- isEof = true;
- return numRead;
- }
-
- if (h->needsInput())
- {
- activeBufferSize = sourceStream->read (buffer, gzipDecompBufferSize);
-
- if (activeBufferSize > 0)
- {
- h->setInput ((uint8*) buffer, activeBufferSize);
- }
- else
- {
- isEof = true;
- return numRead;
- }
- }
- }
- else
- {
- numRead += n;
- howMany -= n;
- d += n;
-
- if (howMany <= 0)
- return numRead;
- }
- }
- }
- }
-
- return 0;
- }
-
- bool GZIPDecompressorInputStream::isExhausted()
- {
- const GZIPDecompressHelper* const h = (GZIPDecompressHelper*) helper;
-
- return h->error || isEof;
- }
-
- int64 GZIPDecompressorInputStream::getPosition()
- {
- return currentPos;
- }
-
- bool GZIPDecompressorInputStream::setPosition (int64 newPos)
- {
- if (newPos != currentPos)
- {
- if (newPos > currentPos)
- {
- skipNextBytes (newPos - currentPos);
- }
- else
- {
- // reset the stream and start again..
- GZIPDecompressHelper* const h = (GZIPDecompressHelper*) helper;
- delete h;
-
- isEof = false;
- activeBufferSize = 0;
- currentPos = 0;
- helper = new GZIPDecompressHelper (noWrap);
-
- sourceStream->setPosition (originalSourcePos);
- skipNextBytes (newPos);
- }
- }
-
- return true;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_GZIPDecompressorInputStream.cpp *********/
-
- #if ! JUCE_ONLY_BUILD_CORE_LIBRARY
-
- /********* Start of inlined file: juce_FlacAudioFormat.cpp *********/
-
- #ifdef _MSC_VER
- #include <windows.h>
- #endif
-
- #if JUCE_USE_FLAC
-
- #ifdef _MSC_VER
- #pragma warning (disable : 4505)
- #pragma warning (push)
- #endif
-
- namespace FlacNamespace
- {
- #define FLAC__NO_DLL 1
-
- #if ! defined (SIZE_MAX)
- #define SIZE_MAX 0xffffffff
- #endif
-
- #define __STDC_LIMIT_MACROS 1
-
- /********* Start of inlined file: all.h *********/
- #ifndef FLAC__ALL_H
- #define FLAC__ALL_H
-
- /********* Start of inlined file: export.h *********/
- #ifndef FLAC__EXPORT_H
- #define FLAC__EXPORT_H
-
- /** \file include/FLAC/export.h
- *
- * \brief
- * This module contains #defines and symbols for exporting function
- * calls, and providing version information and compiled-in features.
- *
- * See the \link flac_export export \endlink module.
- */
-
- /** \defgroup flac_export FLAC/export.h: export symbols
- * \ingroup flac
- *
- * \brief
- * This module contains #defines and symbols for exporting function
- * calls, and providing version information and compiled-in features.
- *
- * If you are compiling with MSVC and will link to the static library
- * (libFLAC.lib) you should define FLAC__NO_DLL in your project to
- * make sure the symbols are exported properly.
- *
- * \{
- */
-
- #if defined(FLAC__NO_DLL) || !defined(_MSC_VER)
- #define FLAC_API
-
- #else
-
- #ifdef FLAC_API_EXPORTS
- #define FLAC_API _declspec(dllexport)
- #else
- #define FLAC_API _declspec(dllimport)
-
- #endif
- #endif
-
- /** These #defines will mirror the libtool-based library version number, see
- * http://www.gnu.org/software/libtool/manual.html#Libtool-versioning
- */
- #define FLAC_API_VERSION_CURRENT 10
- #define FLAC_API_VERSION_REVISION 0 /**< see above */
- #define FLAC_API_VERSION_AGE 2 /**< see above */
-
- #ifdef __cplusplus
- extern "C" {
- #endif
-
- /** \c 1 if the library has been compiled with support for Ogg FLAC, else \c 0. */
- extern FLAC_API int FLAC_API_SUPPORTS_OGG_FLAC;
-
- #ifdef __cplusplus
- }
- #endif
-
- /* \} */
-
- #endif
- /********* End of inlined file: export.h *********/
-
- /********* Start of inlined file: assert.h *********/
- #ifndef FLAC__ASSERT_H
- #define FLAC__ASSERT_H
-
- /* we need this since some compilers (like MSVC) leave assert()s on release code (and we don't want to use their ASSERT) */
- #ifdef DEBUG
- #include <assert.h>
- #define FLAC__ASSERT(x) assert(x)
- #define FLAC__ASSERT_DECLARATION(x) x
- #else
- #define FLAC__ASSERT(x)
- #define FLAC__ASSERT_DECLARATION(x)
- #endif
-
- #endif
- /********* End of inlined file: assert.h *********/
-
- /********* Start of inlined file: callback.h *********/
- #ifndef FLAC__CALLBACK_H
- #define FLAC__CALLBACK_H
-
- /********* Start of inlined file: ordinals.h *********/
- #ifndef FLAC__ORDINALS_H
- #define FLAC__ORDINALS_H
-
- #if !(defined(_MSC_VER) || defined(__BORLANDC__) || defined(__EMX__))
- #include <inttypes.h>
- #endif
-
- typedef signed char FLAC__int8;
- typedef unsigned char FLAC__uint8;
-
- #if defined(_MSC_VER) || defined(__BORLANDC__)
- typedef __int16 FLAC__int16;
- typedef __int32 FLAC__int32;
- typedef __int64 FLAC__int64;
- typedef unsigned __int16 FLAC__uint16;
- typedef unsigned __int32 FLAC__uint32;
- typedef unsigned __int64 FLAC__uint64;
- #elif defined(__EMX__)
- typedef short FLAC__int16;
- typedef long FLAC__int32;
- typedef long long FLAC__int64;
- typedef unsigned short FLAC__uint16;
- typedef unsigned long FLAC__uint32;
- typedef unsigned long long FLAC__uint64;
- #else
- typedef int16_t FLAC__int16;
- typedef int32_t FLAC__int32;
- typedef int64_t FLAC__int64;
- typedef uint16_t FLAC__uint16;
- typedef uint32_t FLAC__uint32;
- typedef uint64_t FLAC__uint64;
- #endif
-
- typedef int FLAC__bool;
-
- typedef FLAC__uint8 FLAC__byte;
-
- #ifdef true
- #undef true
- #endif
- #ifdef false
- #undef false
- #endif
- #ifndef __cplusplus
- #define true 1
- #define false 0
- #endif
-
- #endif
- /********* End of inlined file: ordinals.h *********/
-
- #include <stdlib.h> /* for size_t */
-
- /** \file include/FLAC/callback.h
- *
- * \brief
- * This module defines the structures for describing I/O callbacks
- * to the other FLAC interfaces.
- *
- * See the detailed documentation for callbacks in the
- * \link flac_callbacks callbacks \endlink module.
- */
-
- /** \defgroup flac_callbacks FLAC/callback.h: I/O callback structures
- * \ingroup flac
- *
- * \brief
- * This module defines the structures for describing I/O callbacks
- * to the other FLAC interfaces.
- *
- * The purpose of the I/O callback functions is to create a common way
- * for the metadata interfaces to handle I/O.
- *
- * Originally the metadata interfaces required filenames as the way of
- * specifying FLAC files to operate on. This is problematic in some
- * environments so there is an additional option to specify a set of
- * callbacks for doing I/O on the FLAC file, instead of the filename.
- *
- * In addition to the callbacks, a FLAC__IOHandle type is defined as an
- * opaque structure for a data source.
- *
- * The callback function prototypes are similar (but not identical) to the
- * stdio functions fread, fwrite, fseek, ftell, feof, and fclose. If you use
- * stdio streams to implement the callbacks, you can pass fread, fwrite, and
- * fclose anywhere a FLAC__IOCallback_Read, FLAC__IOCallback_Write, or
- * FLAC__IOCallback_Close is required, and a FILE* anywhere a FLAC__IOHandle
- * is required. \warning You generally CANNOT directly use fseek or ftell
- * for FLAC__IOCallback_Seek or FLAC__IOCallback_Tell since on most systems
- * these use 32-bit offsets and FLAC requires 64-bit offsets to deal with
- * large files. You will have to find an equivalent function (e.g. ftello),
- * or write a wrapper. The same is true for feof() since this is usually
- * implemented as a macro, not as a function whose address can be taken.
- *
- * \{
- */
-
- #ifdef __cplusplus
- extern "C" {
- #endif
-
- /** This is the opaque handle type used by the callbacks. Typically
- * this is a \c FILE* or address of a file descriptor.
- */
- typedef void* FLAC__IOHandle;
-
- /** Signature for the read callback.
- * The signature and semantics match POSIX fread() implementations
- * and can generally be used interchangeably.
- *
- * \param ptr The address of the read buffer.
- * \param size The size of the records to be read.
- * \param nmemb The number of records to be read.
- * \param handle The handle to the data source.
- * \retval size_t
- * The number of records read.
- */
- typedef size_t (*FLAC__IOCallback_Read) (void *ptr, size_t size, size_t nmemb, FLAC__IOHandle handle);
-
- /** Signature for the write callback.
- * The signature and semantics match POSIX fwrite() implementations
- * and can generally be used interchangeably.
- *
- * \param ptr The address of the write buffer.
- * \param size The size of the records to be written.
- * \param nmemb The number of records to be written.
- * \param handle The handle to the data source.
- * \retval size_t
- * The number of records written.
- */
- typedef size_t (*FLAC__IOCallback_Write) (const void *ptr, size_t size, size_t nmemb, FLAC__IOHandle handle);
-
- /** Signature for the seek callback.
- * The signature and semantics mostly match POSIX fseek() WITH ONE IMPORTANT
- * EXCEPTION: the offset is a 64-bit type whereas fseek() is generally 'long'
- * and 32-bits wide.
- *
- * \param handle The handle to the data source.
- * \param offset The new position, relative to \a whence
- * \param whence \c SEEK_SET, \c SEEK_CUR, or \c SEEK_END
- * \retval int
- * \c 0 on success, \c -1 on error.
- */
- typedef int (*FLAC__IOCallback_Seek) (FLAC__IOHandle handle, FLAC__int64 offset, int whence);
-
- /** Signature for the tell callback.
- * The signature and semantics mostly match POSIX ftell() WITH ONE IMPORTANT
- * EXCEPTION: the offset is a 64-bit type whereas ftell() is generally 'long'
- * and 32-bits wide.
- *
- * \param handle The handle to the data source.
- * \retval FLAC__int64
- * The current position on success, \c -1 on error.
- */
- typedef FLAC__int64 (*FLAC__IOCallback_Tell) (FLAC__IOHandle handle);
-
- /** Signature for the EOF callback.
- * The signature and semantics mostly match POSIX feof() but WATCHOUT:
- * on many systems, feof() is a macro, so in this case a wrapper function
- * must be provided instead.
- *
- * \param handle The handle to the data source.
- * \retval int
- * \c 0 if not at end of file, nonzero if at end of file.
- */
- typedef int (*FLAC__IOCallback_Eof) (FLAC__IOHandle handle);
-
- /** Signature for the close callback.
- * The signature and semantics match POSIX fclose() implementations
- * and can generally be used interchangeably.
- *
- * \param handle The handle to the data source.
- * \retval int
- * \c 0 on success, \c EOF on error.
- */
- typedef int (*FLAC__IOCallback_Close) (FLAC__IOHandle handle);
-
- /** A structure for holding a set of callbacks.
- * Each FLAC interface that requires a FLAC__IOCallbacks structure will
- * describe which of the callbacks are required. The ones that are not
- * required may be set to NULL.
- *
- * If the seek requirement for an interface is optional, you can signify that
- * a data sorce is not seekable by setting the \a seek field to \c NULL.
- */
- typedef struct {
- FLAC__IOCallback_Read read;
- FLAC__IOCallback_Write write;
- FLAC__IOCallback_Seek seek;
- FLAC__IOCallback_Tell tell;
- FLAC__IOCallback_Eof eof;
- FLAC__IOCallback_Close close;
- } FLAC__IOCallbacks;
-
- /* \} */
-
- #ifdef __cplusplus
- }
- #endif
-
- #endif
- /********* End of inlined file: callback.h *********/
-
- /********* Start of inlined file: format.h *********/
- #ifndef FLAC__FORMAT_H
- #define FLAC__FORMAT_H
-
- #ifdef __cplusplus
- extern "C" {
- #endif
-
- /** \file include/FLAC/format.h
- *
- * \brief
- * This module contains structure definitions for the representation
- * of FLAC format components in memory. These are the basic
- * structures used by the rest of the interfaces.
- *
- * See the detailed documentation in the
- * \link flac_format format \endlink module.
- */
-
- /** \defgroup flac_format FLAC/format.h: format components
- * \ingroup flac
- *
- * \brief
- * This module contains structure definitions for the representation
- * of FLAC format components in memory. These are the basic
- * structures used by the rest of the interfaces.
- *
- * First, you should be familiar with the
- * <A HREF="../format.html">FLAC format</A>. Many of the values here
- * follow directly from the specification. As a user of libFLAC, the
- * interesting parts really are the structures that describe the frame
- * header and metadata blocks.
- *
- * The format structures here are very primitive, designed to store
- * information in an efficient way. Reading information from the
- * structures is easy but creating or modifying them directly is
- * more complex. For the most part, as a user of a library, editing
- * is not necessary; however, for metadata blocks it is, so there are
- * convenience functions provided in the \link flac_metadata metadata
- * module \endlink to simplify the manipulation of metadata blocks.
- *
- * \note
- * It's not the best convention, but symbols ending in _LEN are in bits
- * and _LENGTH are in bytes. _LENGTH symbols are \#defines instead of
- * global variables because they are usually used when declaring byte
- * arrays and some compilers require compile-time knowledge of array
- * sizes when declared on the stack.
- *
- * \{
- */
-
- /*
- Most of the values described in this file are defined by the FLAC
- format specification. There is nothing to tune here.
- */
-
- /** The largest legal metadata type code. */
- #define FLAC__MAX_METADATA_TYPE_CODE (126u)
-
- /** The minimum block size, in samples, permitted by the format. */
- #define FLAC__MIN_BLOCK_SIZE (16u)
-
- /** The maximum block size, in samples, permitted by the format. */
- #define FLAC__MAX_BLOCK_SIZE (65535u)
-
- /** The maximum block size, in samples, permitted by the FLAC subset for
- * sample rates up to 48kHz. */
- #define FLAC__SUBSET_MAX_BLOCK_SIZE_48000HZ (4608u)
-
- /** The maximum number of channels permitted by the format. */
- #define FLAC__MAX_CHANNELS (8u)
-
- /** The minimum sample resolution permitted by the format. */
- #define FLAC__MIN_BITS_PER_SAMPLE (4u)
-
- /** The maximum sample resolution permitted by the format. */
- #define FLAC__MAX_BITS_PER_SAMPLE (32u)
-
- /** The maximum sample resolution permitted by libFLAC.
- *
- * \warning
- * FLAC__MAX_BITS_PER_SAMPLE is the limit of the FLAC format. However,
- * the reference encoder/decoder is currently limited to 24 bits because
- * of prevalent 32-bit math, so make sure and use this value when
- * appropriate.
- */
- #define FLAC__REFERENCE_CODEC_MAX_BITS_PER_SAMPLE (24u)
-
- /** The maximum sample rate permitted by the format. The value is
- * ((2 ^ 16) - 1) * 10; see <A HREF="../format.html">FLAC format</A>
- * as to why.
- */
- #define FLAC__MAX_SAMPLE_RATE (655350u)
-
- /** The maximum LPC order permitted by the format. */
- #define FLAC__MAX_LPC_ORDER (32u)
-
- /** The maximum LPC order permitted by the FLAC subset for sample rates
- * up to 48kHz. */
- #define FLAC__SUBSET_MAX_LPC_ORDER_48000HZ (12u)
-
- /** The minimum quantized linear predictor coefficient precision
- * permitted by the format.
- */
- #define FLAC__MIN_QLP_COEFF_PRECISION (5u)
-
- /** The maximum quantized linear predictor coefficient precision
- * permitted by the format.
- */
- #define FLAC__MAX_QLP_COEFF_PRECISION (15u)
-
- /** The maximum order of the fixed predictors permitted by the format. */
- #define FLAC__MAX_FIXED_ORDER (4u)
-
- /** The maximum Rice partition order permitted by the format. */
- #define FLAC__MAX_RICE_PARTITION_ORDER (15u)
-
- /** The maximum Rice partition order permitted by the FLAC Subset. */
- #define FLAC__SUBSET_MAX_RICE_PARTITION_ORDER (8u)
-
- /** The version string of the release, stamped onto the libraries and binaries.
- *
- * \note
- * This does not correspond to the shared library version number, which
- * is used to determine binary compatibility.
- */
- extern FLAC_API const char *FLAC__VERSION_STRING;
-
- /** The vendor string inserted by the encoder into the VORBIS_COMMENT block.
- * This is a NUL-terminated ASCII string; when inserted into the
- * VORBIS_COMMENT the trailing null is stripped.
- */
- extern FLAC_API const char *FLAC__VENDOR_STRING;
-
- /** The byte string representation of the beginning of a FLAC stream. */
- extern FLAC_API const FLAC__byte FLAC__STREAM_SYNC_STRING[4]; /* = "fLaC" */
-
- /** The 32-bit integer big-endian representation of the beginning of
- * a FLAC stream.
- */
- extern FLAC_API const unsigned FLAC__STREAM_SYNC; /* = 0x664C6143 */
-
- /** The length of the FLAC signature in bits. */
- extern FLAC_API const unsigned FLAC__STREAM_SYNC_LEN; /* = 32 bits */
-
- /** The length of the FLAC signature in bytes. */
- #define FLAC__STREAM_SYNC_LENGTH (4u)
-
- /*****************************************************************************
- *
- * Subframe structures
- *
- *****************************************************************************/
-
- /*****************************************************************************/
-
- /** An enumeration of the available entropy coding methods. */
- typedef enum {
- FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE = 0,
- /**< Residual is coded by partitioning into contexts, each with it's own
- * 4-bit Rice parameter. */
-
- FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2 = 1
- /**< Residual is coded by partitioning into contexts, each with it's own
- * 5-bit Rice parameter. */
- } FLAC__EntropyCodingMethodType;
-
- /** Maps a FLAC__EntropyCodingMethodType to a C string.
- *
- * Using a FLAC__EntropyCodingMethodType as the index to this array will
- * give the string equivalent. The contents should not be modified.
- */
- extern FLAC_API const char * const FLAC__EntropyCodingMethodTypeString[];
-
- /** Contents of a Rice partitioned residual
- */
- typedef struct {
-
- unsigned *parameters;
- /**< The Rice parameters for each context. */
-
- unsigned *raw_bits;
- /**< Widths for escape-coded partitions. Will be non-zero for escaped
- * partitions and zero for unescaped partitions.
- */
-
- unsigned capacity_by_order;
- /**< The capacity of the \a parameters and \a raw_bits arrays
- * specified as an order, i.e. the number of array elements
- * allocated is 2 ^ \a capacity_by_order.
- */
- } FLAC__EntropyCodingMethod_PartitionedRiceContents;
-
- /** Header for a Rice partitioned residual. (c.f. <A HREF="../format.html#partitioned_rice">format specification</A>)
- */
- typedef struct {
-
- unsigned order;
- /**< The partition order, i.e. # of contexts = 2 ^ \a order. */
-
- const FLAC__EntropyCodingMethod_PartitionedRiceContents *contents;
- /**< The context's Rice parameters and/or raw bits. */
-
- } FLAC__EntropyCodingMethod_PartitionedRice;
-
- extern FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN; /**< == 4 (bits) */
- extern FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN; /**< == 4 (bits) */
- extern FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN; /**< == 5 (bits) */
- extern FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN; /**< == 5 (bits) */
-
- extern FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER;
- /**< == (1<<FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN)-1 */
- extern FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_ESCAPE_PARAMETER;
- /**< == (1<<FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN)-1 */
-
- /** Header for the entropy coding method. (c.f. <A HREF="../format.html#residual">format specification</A>)
- */
- typedef struct {
- FLAC__EntropyCodingMethodType type;
- union {
- FLAC__EntropyCodingMethod_PartitionedRice partitioned_rice;
- } data;
- } FLAC__EntropyCodingMethod;
-
- extern FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_TYPE_LEN; /**< == 2 (bits) */
-
- /*****************************************************************************/
-
- /** An enumeration of the available subframe types. */
- typedef enum {
- FLAC__SUBFRAME_TYPE_CONSTANT = 0, /**< constant signal */
- FLAC__SUBFRAME_TYPE_VERBATIM = 1, /**< uncompressed signal */
- FLAC__SUBFRAME_TYPE_FIXED = 2, /**< fixed polynomial prediction */
- FLAC__SUBFRAME_TYPE_LPC = 3 /**< linear prediction */
- } FLAC__SubframeType;
-
- /** Maps a FLAC__SubframeType to a C string.
- *
- * Using a FLAC__SubframeType as the index to this array will
- * give the string equivalent. The contents should not be modified.
- */
- extern FLAC_API const char * const FLAC__SubframeTypeString[];
-
- /** CONSTANT subframe. (c.f. <A HREF="../format.html#subframe_constant">format specification</A>)
- */
- typedef struct {
- FLAC__int32 value; /**< The constant signal value. */
- } FLAC__Subframe_Constant;
-
- /** VERBATIM subframe. (c.f. <A HREF="../format.html#subframe_verbatim">format specification</A>)
- */
- typedef struct {
- const FLAC__int32 *data; /**< A pointer to verbatim signal. */
- } FLAC__Subframe_Verbatim;
-
- /** FIXED subframe. (c.f. <A HREF="../format.html#subframe_fixed">format specification</A>)
- */
- typedef struct {
- FLAC__EntropyCodingMethod entropy_coding_method;
- /**< The residual coding method. */
-
- unsigned order;
- /**< The polynomial order. */
-
- FLAC__int32 warmup[FLAC__MAX_FIXED_ORDER];
- /**< Warmup samples to prime the predictor, length == order. */
-
- const FLAC__int32 *residual;
- /**< The residual signal, length == (blocksize minus order) samples. */
- } FLAC__Subframe_Fixed;
-
- /** LPC subframe. (c.f. <A HREF="../format.html#subframe_lpc">format specification</A>)
- */
- typedef struct {
- FLAC__EntropyCodingMethod entropy_coding_method;
- /**< The residual coding method. */
-
- unsigned order;
- /**< The FIR order. */
-
- unsigned qlp_coeff_precision;
- /**< Quantized FIR filter coefficient precision in bits. */
-
- int quantization_level;
- /**< The qlp coeff shift needed. */
-
- FLAC__int32 qlp_coeff[FLAC__MAX_LPC_ORDER];
- /**< FIR filter coefficients. */
-
- FLAC__int32 warmup[FLAC__MAX_LPC_ORDER];
- /**< Warmup samples to prime the predictor, length == order. */
-
- const FLAC__int32 *residual;
- /**< The residual signal, length == (blocksize minus order) samples. */
- } FLAC__Subframe_LPC;
-
- extern FLAC_API const unsigned FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN; /**< == 4 (bits) */
- extern FLAC_API const unsigned FLAC__SUBFRAME_LPC_QLP_SHIFT_LEN; /**< == 5 (bits) */
-
- /** FLAC subframe structure. (c.f. <A HREF="../format.html#subframe">format specification</A>)
- */
- typedef struct {
- FLAC__SubframeType type;
- union {
- FLAC__Subframe_Constant constant;
- FLAC__Subframe_Fixed fixed;
- FLAC__Subframe_LPC lpc;
- FLAC__Subframe_Verbatim verbatim;
- } data;
- unsigned wasted_bits;
- } FLAC__Subframe;
-
- /** == 1 (bit)
- *
- * This used to be a zero-padding bit (hence the name
- * FLAC__SUBFRAME_ZERO_PAD_LEN) but is now a reserved bit. It still has a
- * mandatory value of \c 0 but in the future may take on the value \c 0 or \c 1
- * to mean something else.
- */
- extern FLAC_API const unsigned FLAC__SUBFRAME_ZERO_PAD_LEN;
- extern FLAC_API const unsigned FLAC__SUBFRAME_TYPE_LEN; /**< == 6 (bits) */
- extern FLAC_API const unsigned FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN; /**< == 1 (bit) */
-
- extern FLAC_API const unsigned FLAC__SUBFRAME_TYPE_CONSTANT_BYTE_ALIGNED_MASK; /**< = 0x00 */
- extern FLAC_API const unsigned FLAC__SUBFRAME_TYPE_VERBATIM_BYTE_ALIGNED_MASK; /**< = 0x02 */
- extern FLAC_API const unsigned FLAC__SUBFRAME_TYPE_FIXED_BYTE_ALIGNED_MASK; /**< = 0x10 */
- extern FLAC_API const unsigned FLAC__SUBFRAME_TYPE_LPC_BYTE_ALIGNED_MASK; /**< = 0x40 */
-
- /*****************************************************************************/
-
- /*****************************************************************************
- *
- * Frame structures
- *
- *****************************************************************************/
-
- /** An enumeration of the available channel assignments. */
- typedef enum {
- FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT = 0, /**< independent channels */
- FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE = 1, /**< left+side stereo */
- FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE = 2, /**< right+side stereo */
- FLAC__CHANNEL_ASSIGNMENT_MID_SIDE = 3 /**< mid+side stereo */
- } FLAC__ChannelAssignment;
-
- /** Maps a FLAC__ChannelAssignment to a C string.
- *
- * Using a FLAC__ChannelAssignment as the index to this array will
- * give the string equivalent. The contents should not be modified.
- */
- extern FLAC_API const char * const FLAC__ChannelAssignmentString[];
-
- /** An enumeration of the possible frame numbering methods. */
- typedef enum {
- FLAC__FRAME_NUMBER_TYPE_FRAME_NUMBER, /**< number contains the frame number */
- FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER /**< number contains the sample number of first sample in frame */
- } FLAC__FrameNumberType;
-
- /** Maps a FLAC__FrameNumberType to a C string.
- *
- * Using a FLAC__FrameNumberType as the index to this array will
- * give the string equivalent. The contents should not be modified.
- */
- extern FLAC_API const char * const FLAC__FrameNumberTypeString[];
-
- /** FLAC frame header structure. (c.f. <A HREF="../format.html#frame_header">format specification</A>)
- */
- typedef struct {
- unsigned blocksize;
- /**< The number of samples per subframe. */
-
- unsigned sample_rate;
- /**< The sample rate in Hz. */
-
- unsigned channels;
- /**< The number of channels (== number of subframes). */
-
- FLAC__ChannelAssignment channel_assignment;
- /**< The channel assignment for the frame. */
-
- unsigned bits_per_sample;
- /**< The sample resolution. */
-
- FLAC__FrameNumberType number_type;
- /**< The numbering scheme used for the frame. As a convenience, the
- * decoder will always convert a frame number to a sample number because
- * the rules are complex. */
-
- union {
- FLAC__uint32 frame_number;
- FLAC__uint64 sample_number;
- } number;
- /**< The frame number or sample number of first sample in frame;
- * use the \a number_type value to determine which to use. */
-
- FLAC__uint8 crc;
- /**< CRC-8 (polynomial = x^8 + x^2 + x^1 + x^0, initialized with 0)
- * of the raw frame header bytes, meaning everything before the CRC byte
- * including the sync code.
- */
- } FLAC__FrameHeader;
-
- extern FLAC_API const unsigned FLAC__FRAME_HEADER_SYNC; /**< == 0x3ffe; the frame header sync code */
- extern FLAC_API const unsigned FLAC__FRAME_HEADER_SYNC_LEN; /**< == 14 (bits) */
- extern FLAC_API const unsigned FLAC__FRAME_HEADER_RESERVED_LEN; /**< == 1 (bits) */
- extern FLAC_API const unsigned FLAC__FRAME_HEADER_BLOCKING_STRATEGY_LEN; /**< == 1 (bits) */
- extern FLAC_API const unsigned FLAC__FRAME_HEADER_BLOCK_SIZE_LEN; /**< == 4 (bits) */
- extern FLAC_API const unsigned FLAC__FRAME_HEADER_SAMPLE_RATE_LEN; /**< == 4 (bits) */
- extern FLAC_API const unsigned FLAC__FRAME_HEADER_CHANNEL_ASSIGNMENT_LEN; /**< == 4 (bits) */
- extern FLAC_API const unsigned FLAC__FRAME_HEADER_BITS_PER_SAMPLE_LEN; /**< == 3 (bits) */
- extern FLAC_API const unsigned FLAC__FRAME_HEADER_ZERO_PAD_LEN; /**< == 1 (bit) */
- extern FLAC_API const unsigned FLAC__FRAME_HEADER_CRC_LEN; /**< == 8 (bits) */
-
- /** FLAC frame footer structure. (c.f. <A HREF="../format.html#frame_footer">format specification</A>)
- */
- typedef struct {
- FLAC__uint16 crc;
- /**< CRC-16 (polynomial = x^16 + x^15 + x^2 + x^0, initialized with
- * 0) of the bytes before the crc, back to and including the frame header
- * sync code.
- */
- } FLAC__FrameFooter;
-
- extern FLAC_API const unsigned FLAC__FRAME_FOOTER_CRC_LEN; /**< == 16 (bits) */
-
- /** FLAC frame structure. (c.f. <A HREF="../format.html#frame">format specification</A>)
- */
- typedef struct {
- FLAC__FrameHeader header;
- FLAC__Subframe subframes[FLAC__MAX_CHANNELS];
- FLAC__FrameFooter footer;
- } FLAC__Frame;
-
- /*****************************************************************************/
-
- /*****************************************************************************
- *
- * Meta-data structures
- *
- *****************************************************************************/
-
- /** An enumeration of the available metadata block types. */
- typedef enum {
-
- FLAC__METADATA_TYPE_STREAMINFO = 0,
- /**< <A HREF="../format.html#metadata_block_streaminfo">STREAMINFO</A> block */
-
- FLAC__METADATA_TYPE_PADDING = 1,
- /**< <A HREF="../format.html#metadata_block_padding">PADDING</A> block */
-
- FLAC__METADATA_TYPE_APPLICATION = 2,
- /**< <A HREF="../format.html#metadata_block_application">APPLICATION</A> block */
-
- FLAC__METADATA_TYPE_SEEKTABLE = 3,
- /**< <A HREF="../format.html#metadata_block_seektable">SEEKTABLE</A> block */
-
- FLAC__METADATA_TYPE_VORBIS_COMMENT = 4,
- /**< <A HREF="../format.html#metadata_block_vorbis_comment">VORBISCOMMENT</A> block (a.k.a. FLAC tags) */
-
- FLAC__METADATA_TYPE_CUESHEET = 5,
- /**< <A HREF="../format.html#metadata_block_cuesheet">CUESHEET</A> block */
-
- FLAC__METADATA_TYPE_PICTURE = 6,
- /**< <A HREF="../format.html#metadata_block_picture">PICTURE</A> block */
-
- FLAC__METADATA_TYPE_UNDEFINED = 7
- /**< marker to denote beginning of undefined type range; this number will increase as new metadata types are added */
-
- } FLAC__MetadataType;
-
- /** Maps a FLAC__MetadataType to a C string.
- *
- * Using a FLAC__MetadataType as the index to this array will
- * give the string equivalent. The contents should not be modified.
- */
- extern FLAC_API const char * const FLAC__MetadataTypeString[];
-
- /** FLAC STREAMINFO structure. (c.f. <A HREF="../format.html#metadata_block_streaminfo">format specification</A>)
- */
- typedef struct {
- unsigned min_blocksize, max_blocksize;
- unsigned min_framesize, max_framesize;
- unsigned sample_rate;
- unsigned channels;
- unsigned bits_per_sample;
- FLAC__uint64 total_samples;
- FLAC__byte md5sum[16];
- } FLAC__StreamMetadata_StreamInfo;
-
- extern FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN; /**< == 16 (bits) */
- extern FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN; /**< == 16 (bits) */
- extern FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN; /**< == 24 (bits) */
- extern FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN; /**< == 24 (bits) */
- extern FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN; /**< == 20 (bits) */
- extern FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN; /**< == 3 (bits) */
- extern FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN; /**< == 5 (bits) */
- extern FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN; /**< == 36 (bits) */
- extern FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MD5SUM_LEN; /**< == 128 (bits) */
-
- /** The total stream length of the STREAMINFO block in bytes. */
- #define FLAC__STREAM_METADATA_STREAMINFO_LENGTH (34u)
-
- /** FLAC PADDING structure. (c.f. <A HREF="../format.html#metadata_block_padding">format specification</A>)
- */
- typedef struct {
- int dummy;
- /**< Conceptually this is an empty struct since we don't store the
- * padding bytes. Empty structs are not allowed by some C compilers,
- * hence the dummy.
- */
- } FLAC__StreamMetadata_Padding;
-
- /** FLAC APPLICATION structure. (c.f. <A HREF="../format.html#metadata_block_application">format specification</A>)
- */
- typedef struct {
- FLAC__byte id[4];
- FLAC__byte *data;
- } FLAC__StreamMetadata_Application;
-
- extern FLAC_API const unsigned FLAC__STREAM_METADATA_APPLICATION_ID_LEN; /**< == 32 (bits) */
-
- /** SeekPoint structure used in SEEKTABLE blocks. (c.f. <A HREF="../format.html#seekpoint">format specification</A>)
- */
- typedef struct {
- FLAC__uint64 sample_number;
- /**< The sample number of the target frame. */
-
- FLAC__uint64 stream_offset;
- /**< The offset, in bytes, of the target frame with respect to
- * beginning of the first frame. */
-
- unsigned frame_samples;
- /**< The number of samples in the target frame. */
- } FLAC__StreamMetadata_SeekPoint;
-
- extern FLAC_API const unsigned FLAC__STREAM_METADATA_SEEKPOINT_SAMPLE_NUMBER_LEN; /**< == 64 (bits) */
- extern FLAC_API const unsigned FLAC__STREAM_METADATA_SEEKPOINT_STREAM_OFFSET_LEN; /**< == 64 (bits) */
- extern FLAC_API const unsigned FLAC__STREAM_METADATA_SEEKPOINT_FRAME_SAMPLES_LEN; /**< == 16 (bits) */
-
- /** The total stream length of a seek point in bytes. */
- #define FLAC__STREAM_METADATA_SEEKPOINT_LENGTH (18u)
-
- /** The value used in the \a sample_number field of
- * FLAC__StreamMetadataSeekPoint used to indicate a placeholder
- * point (== 0xffffffffffffffff).
- */
- extern FLAC_API const FLAC__uint64 FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER;
-
- /** FLAC SEEKTABLE structure. (c.f. <A HREF="../format.html#metadata_block_seektable">format specification</A>)
- *
- * \note From the format specification:
- * - The seek points must be sorted by ascending sample number.
- * - Each seek point's sample number must be the first sample of the
- * target frame.
- * - Each seek point's sample number must be unique within the table.
- * - Existence of a SEEKTABLE block implies a correct setting of
- * total_samples in the stream_info block.
- * - Behavior is undefined when more than one SEEKTABLE block is
- * present in a stream.
- */
- typedef struct {
- unsigned num_points;
- FLAC__StreamMetadata_SeekPoint *points;
- } FLAC__StreamMetadata_SeekTable;
-
- /** Vorbis comment entry structure used in VORBIS_COMMENT blocks. (c.f. <A HREF="../format.html#metadata_block_vorbis_comment">format specification</A>)
- *
- * For convenience, the APIs maintain a trailing NUL character at the end of
- * \a entry which is not counted toward \a length, i.e.
- * \code strlen(entry) == length \endcode
- */
- typedef struct {
- FLAC__uint32 length;
- FLAC__byte *entry;
- } FLAC__StreamMetadata_VorbisComment_Entry;
-
- extern FLAC_API const unsigned FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN; /**< == 32 (bits) */
-
- /** FLAC VORBIS_COMMENT structure. (c.f. <A HREF="../format.html#metadata_block_vorbis_comment">format specification</A>)
- */
- typedef struct {
- FLAC__StreamMetadata_VorbisComment_Entry vendor_string;
- FLAC__uint32 num_comments;
- FLAC__StreamMetadata_VorbisComment_Entry *comments;
- } FLAC__StreamMetadata_VorbisComment;
-
- extern FLAC_API const unsigned FLAC__STREAM_METADATA_VORBIS_COMMENT_NUM_COMMENTS_LEN; /**< == 32 (bits) */
-
- /** FLAC CUESHEET track index structure. (See the
- * <A HREF="../format.html#cuesheet_track_index">format specification</A> for
- * the full description of each field.)
- */
- typedef struct {
- FLAC__uint64 offset;
- /**< Offset in samples, relative to the track offset, of the index
- * point.
- */
-
- FLAC__byte number;
- /**< The index point number. */
- } FLAC__StreamMetadata_CueSheet_Index;
-
- extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_INDEX_OFFSET_LEN; /**< == 64 (bits) */
- extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_INDEX_NUMBER_LEN; /**< == 8 (bits) */
- extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN; /**< == 3*8 (bits) */
-
- /** FLAC CUESHEET track structure. (See the
- * <A HREF="../format.html#cuesheet_track">format specification</A> for
- * the full description of each field.)
- */
- typedef struct {
- FLAC__uint64 offset;
- /**< Track offset in samples, relative to the beginning of the FLAC audio stream. */
-
- FLAC__byte number;
- /**< The track number. */
-
- char isrc[13];
- /**< Track ISRC. This is a 12-digit alphanumeric code plus a trailing \c NUL byte */
-
- unsigned type:1;
- /**< The track type: 0 for audio, 1 for non-audio. */
-
- unsigned pre_emphasis:1;
- /**< The pre-emphasis flag: 0 for no pre-emphasis, 1 for pre-emphasis. */
-
- FLAC__byte num_indices;
- /**< The number of track index points. */
-
- FLAC__StreamMetadata_CueSheet_Index *indices;
- /**< NULL if num_indices == 0, else pointer to array of index points. */
-
- } FLAC__StreamMetadata_CueSheet_Track;
-
- extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_OFFSET_LEN; /**< == 64 (bits) */
- extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_NUMBER_LEN; /**< == 8 (bits) */
- extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN; /**< == 12*8 (bits) */
- extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_TYPE_LEN; /**< == 1 (bit) */
- extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_PRE_EMPHASIS_LEN; /**< == 1 (bit) */
- extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_RESERVED_LEN; /**< == 6+13*8 (bits) */
- extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_NUM_INDICES_LEN; /**< == 8 (bits) */
-
- /** FLAC CUESHEET structure. (See the
- * <A HREF="../format.html#metadata_block_cuesheet">format specification</A>
- * for the full description of each field.)
- */
- typedef struct {
- char media_catalog_number[129];
- /**< Media catalog number, in ASCII printable characters 0x20-0x7e. In
- * general, the media catalog number may be 0 to 128 bytes long; any
- * unused characters should be right-padded with NUL characters.
- */
-
- FLAC__uint64 lead_in;
- /**< The number of lead-in samples. */
-
- FLAC__bool is_cd;
- /**< \c true if CUESHEET corresponds to a Compact Disc, else \c false. */
-
- unsigned num_tracks;
- /**< The number of tracks. */
-
- FLAC__StreamMetadata_CueSheet_Track *tracks;
- /**< NULL if num_tracks == 0, else pointer to array of tracks. */
-
- } FLAC__StreamMetadata_CueSheet;
-
- extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_MEDIA_CATALOG_NUMBER_LEN; /**< == 128*8 (bits) */
- extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_LEAD_IN_LEN; /**< == 64 (bits) */
- extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_IS_CD_LEN; /**< == 1 (bit) */
- extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_RESERVED_LEN; /**< == 7+258*8 (bits) */
- extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_NUM_TRACKS_LEN; /**< == 8 (bits) */
-
- /** An enumeration of the PICTURE types (see FLAC__StreamMetadataPicture and id3 v2.4 APIC tag). */
- typedef enum {
- FLAC__STREAM_METADATA_PICTURE_TYPE_OTHER = 0, /**< Other */
- FLAC__STREAM_METADATA_PICTURE_TYPE_FILE_ICON_STANDARD = 1, /**< 32x32 pixels 'file icon' (PNG only) */
- FLAC__STREAM_METADATA_PICTURE_TYPE_FILE_ICON = 2, /**< Other file icon */
- FLAC__STREAM_METADATA_PICTURE_TYPE_FRONT_COVER = 3, /**< Cover (front) */
- FLAC__STREAM_METADATA_PICTURE_TYPE_BACK_COVER = 4, /**< Cover (back) */
- FLAC__STREAM_METADATA_PICTURE_TYPE_LEAFLET_PAGE = 5, /**< Leaflet page */
- FLAC__STREAM_METADATA_PICTURE_TYPE_MEDIA = 6, /**< Media (e.g. label side of CD) */
- FLAC__STREAM_METADATA_PICTURE_TYPE_LEAD_ARTIST = 7, /**< Lead artist/lead performer/soloist */
- FLAC__STREAM_METADATA_PICTURE_TYPE_ARTIST = 8, /**< Artist/performer */
- FLAC__STREAM_METADATA_PICTURE_TYPE_CONDUCTOR = 9, /**< Conductor */
- FLAC__STREAM_METADATA_PICTURE_TYPE_BAND = 10, /**< Band/Orchestra */
- FLAC__STREAM_METADATA_PICTURE_TYPE_COMPOSER = 11, /**< Composer */
- FLAC__STREAM_METADATA_PICTURE_TYPE_LYRICIST = 12, /**< Lyricist/text writer */
- FLAC__STREAM_METADATA_PICTURE_TYPE_RECORDING_LOCATION = 13, /**< Recording Location */
- FLAC__STREAM_METADATA_PICTURE_TYPE_DURING_RECORDING = 14, /**< During recording */
- FLAC__STREAM_METADATA_PICTURE_TYPE_DURING_PERFORMANCE = 15, /**< During performance */
- FLAC__STREAM_METADATA_PICTURE_TYPE_VIDEO_SCREEN_CAPTURE = 16, /**< Movie/video screen capture */
- FLAC__STREAM_METADATA_PICTURE_TYPE_FISH = 17, /**< A bright coloured fish */
- FLAC__STREAM_METADATA_PICTURE_TYPE_ILLUSTRATION = 18, /**< Illustration */
- FLAC__STREAM_METADATA_PICTURE_TYPE_BAND_LOGOTYPE = 19, /**< Band/artist logotype */
- FLAC__STREAM_METADATA_PICTURE_TYPE_PUBLISHER_LOGOTYPE = 20, /**< Publisher/Studio logotype */
- FLAC__STREAM_METADATA_PICTURE_TYPE_UNDEFINED
- } FLAC__StreamMetadata_Picture_Type;
-
- /** Maps a FLAC__StreamMetadata_Picture_Type to a C string.
- *
- * Using a FLAC__StreamMetadata_Picture_Type as the index to this array
- * will give the string equivalent. The contents should not be
- * modified.
- */
- extern FLAC_API const char * const FLAC__StreamMetadata_Picture_TypeString[];
-
- /** FLAC PICTURE structure. (See the
- * <A HREF="../format.html#metadata_block_picture">format specification</A>
- * for the full description of each field.)
- */
- typedef struct {
- FLAC__StreamMetadata_Picture_Type type;
- /**< The kind of picture stored. */
-
- char *mime_type;
- /**< Picture data's MIME type, in ASCII printable characters
- * 0x20-0x7e, NUL terminated. For best compatibility with players,
- * use picture data of MIME type \c image/jpeg or \c image/png. A
- * MIME type of '-->' is also allowed, in which case the picture
- * data should be a complete URL. In file storage, the MIME type is
- * stored as a 32-bit length followed by the ASCII string with no NUL
- * terminator, but is converted to a plain C string in this structure
- * for convenience.
- */
-
- FLAC__byte *description;
- /**< Picture's description in UTF-8, NUL terminated. In file storage,
- * the description is stored as a 32-bit length followed by the UTF-8
- * string with no NUL terminator, but is converted to a plain C string
- * in this structure for convenience.
- */
-
- FLAC__uint32 width;
- /**< Picture's width in pixels. */
-
- FLAC__uint32 height;
- /**< Picture's height in pixels. */
-
- FLAC__uint32 depth;
- /**< Picture's color depth in bits-per-pixel. */
-
- FLAC__uint32 colors;
- /**< For indexed palettes (like GIF), picture's number of colors (the
- * number of palette entries), or \c 0 for non-indexed (i.e. 2^depth).
- */
-
- FLAC__uint32 data_length;
- /**< Length of binary picture data in bytes. */
-
- FLAC__byte *data;
- /**< Binary picture data. */
-
- } FLAC__StreamMetadata_Picture;
-
- extern FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_TYPE_LEN; /**< == 32 (bits) */
- extern FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_MIME_TYPE_LENGTH_LEN; /**< == 32 (bits) */
- extern FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_DESCRIPTION_LENGTH_LEN; /**< == 32 (bits) */
- extern FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_WIDTH_LEN; /**< == 32 (bits) */
- extern FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_HEIGHT_LEN; /**< == 32 (bits) */
- extern FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_DEPTH_LEN; /**< == 32 (bits) */
- extern FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_COLORS_LEN; /**< == 32 (bits) */
- extern FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_DATA_LENGTH_LEN; /**< == 32 (bits) */
-
- /** Structure that is used when a metadata block of unknown type is loaded.
- * The contents are opaque. The structure is used only internally to
- * correctly handle unknown metadata.
- */
- typedef struct {
- FLAC__byte *data;
- } FLAC__StreamMetadata_Unknown;
-
- /** FLAC metadata block structure. (c.f. <A HREF="../format.html#metadata_block">format specification</A>)
- */
- typedef struct {
- FLAC__MetadataType type;
- /**< The type of the metadata block; used determine which member of the
- * \a data union to dereference. If type >= FLAC__METADATA_TYPE_UNDEFINED
- * then \a data.unknown must be used. */
-
- FLAC__bool is_last;
- /**< \c true if this metadata block is the last, else \a false */
-
- unsigned length;
- /**< Length, in bytes, of the block data as it appears in the stream. */
-
- union {
- FLAC__StreamMetadata_StreamInfo stream_info;
- FLAC__StreamMetadata_Padding padding;
- FLAC__StreamMetadata_Application application;
- FLAC__StreamMetadata_SeekTable seek_table;
- FLAC__StreamMetadata_VorbisComment vorbis_comment;
- FLAC__StreamMetadata_CueSheet cue_sheet;
- FLAC__StreamMetadata_Picture picture;
- FLAC__StreamMetadata_Unknown unknown;
- } data;
- /**< Polymorphic block data; use the \a type value to determine which
- * to use. */
- } FLAC__StreamMetadata;
-
- extern FLAC_API const unsigned FLAC__STREAM_METADATA_IS_LAST_LEN; /**< == 1 (bit) */
- extern FLAC_API const unsigned FLAC__STREAM_METADATA_TYPE_LEN; /**< == 7 (bits) */
- extern FLAC_API const unsigned FLAC__STREAM_METADATA_LENGTH_LEN; /**< == 24 (bits) */
-
- /** The total stream length of a metadata block header in bytes. */
- #define FLAC__STREAM_METADATA_HEADER_LENGTH (4u)
-
- /*****************************************************************************/
-
- /*****************************************************************************
- *
- * Utility functions
- *
- *****************************************************************************/
-
- /** Tests that a sample rate is valid for FLAC.
- *
- * \param sample_rate The sample rate to test for compliance.
- * \retval FLAC__bool
- * \c true if the given sample rate conforms to the specification, else
- * \c false.
- */
- FLAC_API FLAC__bool FLAC__format_sample_rate_is_valid(unsigned sample_rate);
-
- /** Tests that a sample rate is valid for the FLAC subset. The subset rules
- * for valid sample rates are slightly more complex since the rate has to
- * be expressible completely in the frame header.
- *
- * \param sample_rate The sample rate to test for compliance.
- * \retval FLAC__bool
- * \c true if the given sample rate conforms to the specification for the
- * subset, else \c false.
- */
- FLAC_API FLAC__bool FLAC__format_sample_rate_is_subset(unsigned sample_rate);
-
- /** Check a Vorbis comment entry name to see if it conforms to the Vorbis
- * comment specification.
- *
- * Vorbis comment names must be composed only of characters from
- * [0x20-0x3C,0x3E-0x7D].
- *
- * \param name A NUL-terminated string to be checked.
- * \assert
- * \code name != NULL \endcode
- * \retval FLAC__bool
- * \c false if entry name is illegal, else \c true.
- */
- FLAC_API FLAC__bool FLAC__format_vorbiscomment_entry_name_is_legal(const char *name);
-
- /** Check a Vorbis comment entry value to see if it conforms to the Vorbis
- * comment specification.
- *
- * Vorbis comment values must be valid UTF-8 sequences.
- *
- * \param value A string to be checked.
- * \param length A the length of \a value in bytes. May be
- * \c (unsigned)(-1) to indicate that \a value is a plain
- * UTF-8 NUL-terminated string.
- * \assert
- * \code value != NULL \endcode
- * \retval FLAC__bool
- * \c false if entry name is illegal, else \c true.
- */
- FLAC_API FLAC__bool FLAC__format_vorbiscomment_entry_value_is_legal(const FLAC__byte *value, unsigned length);
-
- /** Check a Vorbis comment entry to see if it conforms to the Vorbis
- * comment specification.
- *
- * Vorbis comment entries must be of the form 'name=value', and 'name' and
- * 'value' must be legal according to
- * FLAC__format_vorbiscomment_entry_name_is_legal() and
- * FLAC__format_vorbiscomment_entry_value_is_legal() respectively.
- *
- * \param entry An entry to be checked.
- * \param length The length of \a entry in bytes.
- * \assert
- * \code value != NULL \endcode
- * \retval FLAC__bool
- * \c false if entry name is illegal, else \c true.
- */
- FLAC_API FLAC__bool FLAC__format_vorbiscomment_entry_is_legal(const FLAC__byte *entry, unsigned length);
-
- /** Check a seek table to see if it conforms to the FLAC specification.
- * See the format specification for limits on the contents of the
- * seek table.
- *
- * \param seek_table A pointer to a seek table to be checked.
- * \assert
- * \code seek_table != NULL \endcode
- * \retval FLAC__bool
- * \c false if seek table is illegal, else \c true.
- */
- FLAC_API FLAC__bool FLAC__format_seektable_is_legal(const FLAC__StreamMetadata_SeekTable *seek_table);
-
- /** Sort a seek table's seek points according to the format specification.
- * This includes a "unique-ification" step to remove duplicates, i.e.
- * seek points with identical \a sample_number values. Duplicate seek
- * points are converted into placeholder points and sorted to the end of
- * the table.
- *
- * \param seek_table A pointer to a seek table to be sorted.
- * \assert
- * \code seek_table != NULL \endcode
- * \retval unsigned
- * The number of duplicate seek points converted into placeholders.
- */
- FLAC_API unsigned FLAC__format_seektable_sort(FLAC__StreamMetadata_SeekTable *seek_table);
-
- /** Check a cue sheet to see if it conforms to the FLAC specification.
- * See the format specification for limits on the contents of the
- * cue sheet.
- *
- * \param cue_sheet A pointer to an existing cue sheet to be checked.
- * \param check_cd_da_subset If \c true, check CUESHEET against more
- * stringent requirements for a CD-DA (audio) disc.
- * \param violation Address of a pointer to a string. If there is a
- * violation, a pointer to a string explanation of the
- * violation will be returned here. \a violation may be
- * \c NULL if you don't need the returned string. Do not
- * free the returned string; it will always point to static
- * data.
- * \assert
- * \code cue_sheet != NULL \endcode
- * \retval FLAC__bool
- * \c false if cue sheet is illegal, else \c true.
- */
- FLAC_API FLAC__bool FLAC__format_cuesheet_is_legal(const FLAC__StreamMetadata_CueSheet *cue_sheet, FLAC__bool check_cd_da_subset, const char **violation);
-
- /** Check picture data to see if it conforms to the FLAC specification.
- * See the format specification for limits on the contents of the
- * PICTURE block.
- *
- * \param picture A pointer to existing picture data to be checked.
- * \param violation Address of a pointer to a string. If there is a
- * violation, a pointer to a string explanation of the
- * violation will be returned here. \a violation may be
- * \c NULL if you don't need the returned string. Do not
- * free the returned string; it will always point to static
- * data.
- * \assert
- * \code picture != NULL \endcode
- * \retval FLAC__bool
- * \c false if picture data is illegal, else \c true.
- */
- FLAC_API FLAC__bool FLAC__format_picture_is_legal(const FLAC__StreamMetadata_Picture *picture, const char **violation);
-
- /* \} */
-
- #ifdef __cplusplus
- }
- #endif
-
- #endif
- /********* End of inlined file: format.h *********/
-
- /********* Start of inlined file: metadata.h *********/
- #ifndef FLAC__METADATA_H
- #define FLAC__METADATA_H
-
- #include <sys/types.h> /* for off_t */
-
- /* --------------------------------------------------------------------
- (For an example of how all these routines are used, see the source
- code for the unit tests in src/test_libFLAC/metadata_*.c, or
- metaflac in src/metaflac/)
- ------------------------------------------------------------------*/
-
- /** \file include/FLAC/metadata.h
- *
- * \brief
- * This module provides functions for creating and manipulating FLAC
- * metadata blocks in memory, and three progressively more powerful
- * interfaces for traversing and editing metadata in FLAC files.
- *
- * See the detailed documentation for each interface in the
- * \link flac_metadata metadata \endlink module.
- */
-
- /** \defgroup flac_metadata FLAC/metadata.h: metadata interfaces
- * \ingroup flac
- *
- * \brief
- * This module provides functions for creating and manipulating FLAC
- * metadata blocks in memory, and three progressively more powerful
- * interfaces for traversing and editing metadata in native FLAC files.
- * Note that currently only the Chain interface (level 2) supports Ogg
- * FLAC files, and it is read-only i.e. no writing back changed
- * metadata to file.
- *
- * There are three metadata interfaces of increasing complexity:
- *
- * Level 0:
- * Read-only access to the STREAMINFO, VORBIS_COMMENT, CUESHEET, and
- * PICTURE blocks.
- *
- * Level 1:
- * Read-write access to all metadata blocks. This level is write-
- * efficient in most cases (more on this below), and uses less memory
- * than level 2.
- *
- * Level 2:
- * Read-write access to all metadata blocks. This level is write-
- * efficient in all cases, but uses more memory since all metadata for
- * the whole file is read into memory and manipulated before writing
- * out again.
- *
- * What do we mean by efficient? Since FLAC metadata appears at the
- * beginning of the file, when writing metadata back to a FLAC file
- * it is possible to grow or shrink the metadata such that the entire
- * file must be rewritten. However, if the size remains the same during
- * changes or PADDING blocks are utilized, only the metadata needs to be
- * overwritten, which is much faster.
- *
- * Efficient means the whole file is rewritten at most one time, and only
- * when necessary. Level 1 is not efficient only in the case that you
- * cause more than one metadata block to grow or shrink beyond what can
- * be accomodated by padding. In this case you should probably use level
- * 2, which allows you to edit all the metadata for a file in memory and
- * write it out all at once.
- *
- * All levels know how to skip over and not disturb an ID3v2 tag at the
- * front of the file.
- *
- * All levels access files via their filenames. In addition, level 2
- * has additional alternative read and write functions that take an I/O
- * handle and callbacks, for situations where access by filename is not
- * possible.
- *
- * In addition to the three interfaces, this module defines functions for
- * creating and manipulating various metadata objects in memory. As we see
- * from the Format module, FLAC metadata blocks in memory are very primitive
- * structures for storing information in an efficient way. Reading
- * information from the structures is easy but creating or modifying them
- * directly is more complex. The metadata object routines here facilitate
- * this by taking care of the consistency and memory management drudgery.
- *
- * Unless you will be using the level 1 or 2 interfaces to modify existing
- * metadata however, you will not probably not need these.
- *
- * From a dependency standpoint, none of the encoders or decoders require
- * the metadata module. This is so that embedded users can strip out the
- * metadata module from libFLAC to reduce the size and complexity.
- */
-
- #ifdef __cplusplus
- extern "C" {
- #endif
-
- /** \defgroup flac_metadata_level0 FLAC/metadata.h: metadata level 0 interface
- * \ingroup flac_metadata
- *
- * \brief
- * The level 0 interface consists of individual routines to read the
- * STREAMINFO, VORBIS_COMMENT, CUESHEET, and PICTURE blocks, requiring
- * only a filename.
- *
- * They try to skip any ID3v2 tag at the head of the file.
- *
- * \{
- */
-
- /** Read the STREAMINFO metadata block of the given FLAC file. This function
- * will try to skip any ID3v2 tag at the head of the file.
- *
- * \param filename The path to the FLAC file to read.
- * \param streaminfo A pointer to space for the STREAMINFO block. Since
- * FLAC__StreamMetadata is a simple structure with no
- * memory allocation involved, you pass the address of
- * an existing structure. It need not be initialized.
- * \assert
- * \code filename != NULL \endcode
- * \code streaminfo != NULL \endcode
- * \retval FLAC__bool
- * \c true if a valid STREAMINFO block was read from \a filename. Returns
- * \c false if there was a memory allocation error, a file decoder error,
- * or the file contained no STREAMINFO block. (A memory allocation error
- * is possible because this function must set up a file decoder.)
- */
- FLAC_API FLAC__bool FLAC__metadata_get_streaminfo(const char *filename, FLAC__StreamMetadata *streaminfo);
-
- /** Read the VORBIS_COMMENT metadata block of the given FLAC file. This
- * function will try to skip any ID3v2 tag at the head of the file.
- *
- * \param filename The path to the FLAC file to read.
- * \param tags The address where the returned pointer will be
- * stored. The \a tags object must be deleted by
- * the caller using FLAC__metadata_object_delete().
- * \assert
- * \code filename != NULL \endcode
- * \code tags != NULL \endcode
- * \retval FLAC__bool
- * \c true if a valid VORBIS_COMMENT block was read from \a filename,
- * and \a *tags will be set to the address of the metadata structure.
- * Returns \c false if there was a memory allocation error, a file
- * decoder error, or the file contained no VORBIS_COMMENT block, and
- * \a *tags will be set to \c NULL.
- */
- FLAC_API FLAC__bool FLAC__metadata_get_tags(const char *filename, FLAC__StreamMetadata **tags);
-
- /** Read the CUESHEET metadata block of the given FLAC file. This
- * function will try to skip any ID3v2 tag at the head of the file.
- *
- * \param filename The path to the FLAC file to read.
- * \param cuesheet The address where the returned pointer will be
- * stored. The \a cuesheet object must be deleted by
- * the caller using FLAC__metadata_object_delete().
- * \assert
- * \code filename != NULL \endcode
- * \code cuesheet != NULL \endcode
- * \retval FLAC__bool
- * \c true if a valid CUESHEET block was read from \a filename,
- * and \a *cuesheet will be set to the address of the metadata
- * structure. Returns \c false if there was a memory allocation
- * error, a file decoder error, or the file contained no CUESHEET
- * block, and \a *cuesheet will be set to \c NULL.
- */
- FLAC_API FLAC__bool FLAC__metadata_get_cuesheet(const char *filename, FLAC__StreamMetadata **cuesheet);
-
- /** Read a PICTURE metadata block of the given FLAC file. This
- * function will try to skip any ID3v2 tag at the head of the file.
- * Since there can be more than one PICTURE block in a file, this
- * function takes a number of parameters that act as constraints to
- * the search. The PICTURE block with the largest area matching all
- * the constraints will be returned, or \a *picture will be set to
- * \c NULL if there was no such block.
- *
- * \param filename The path to the FLAC file to read.
- * \param picture The address where the returned pointer will be
- * stored. The \a picture object must be deleted by
- * the caller using FLAC__metadata_object_delete().
- * \param type The desired picture type. Use \c -1 to mean
- * "any type".
- * \param mime_type The desired MIME type, e.g. "image/jpeg". The
- * string will be matched exactly. Use \c NULL to
- * mean "any MIME type".
- * \param description The desired description. The string will be
- * matched exactly. Use \c NULL to mean "any
- * description".
- * \param max_width The maximum width in pixels desired. Use
- * \c (unsigned)(-1) to mean "any width".
- * \param max_height The maximum height in pixels desired. Use
- * \c (unsigned)(-1) to mean "any height".
- * \param max_depth The maximum color depth in bits-per-pixel desired.
- * Use \c (unsigned)(-1) to mean "any depth".
- * \param max_colors The maximum number of colors desired. Use
- * \c (unsigned)(-1) to mean "any number of colors".
- * \assert
- * \code filename != NULL \endcode
- * \code picture != NULL \endcode
- * \retval FLAC__bool
- * \c true if a valid PICTURE block was read from \a filename,
- * and \a *picture will be set to the address of the metadata
- * structure. Returns \c false if there was a memory allocation
- * error, a file decoder error, or the file contained no PICTURE
- * block, and \a *picture will be set to \c NULL.
- */
- FLAC_API FLAC__bool FLAC__metadata_get_picture(const char *filename, FLAC__StreamMetadata **picture, FLAC__StreamMetadata_Picture_Type type, const char *mime_type, const FLAC__byte *description, unsigned max_width, unsigned max_height, unsigned max_depth, unsigned max_colors);
-
- /* \} */
-
- /** \defgroup flac_metadata_level1 FLAC/metadata.h: metadata level 1 interface
- * \ingroup flac_metadata
- *
- * \brief
- * The level 1 interface provides read-write access to FLAC file metadata and
- * operates directly on the FLAC file.
- *
- * The general usage of this interface is:
- *
- * - Create an iterator using FLAC__metadata_simple_iterator_new()
- * - Attach it to a file using FLAC__metadata_simple_iterator_init() and check
- * the exit code. Call FLAC__metadata_simple_iterator_is_writable() to
- * see if the file is writable, or only read access is allowed.
- * - Use FLAC__metadata_simple_iterator_next() and
- * FLAC__metadata_simple_iterator_prev() to traverse the blocks.
- * This is does not read the actual blocks themselves.
- * FLAC__metadata_simple_iterator_next() is relatively fast.
- * FLAC__metadata_simple_iterator_prev() is slower since it needs to search
- * forward from the front of the file.
- * - Use FLAC__metadata_simple_iterator_get_block_type() or
- * FLAC__metadata_simple_iterator_get_block() to access the actual data at
- * the current iterator position. The returned object is yours to modify
- * and free.
- * - Use FLAC__metadata_simple_iterator_set_block() to write a modified block
- * back. You must have write permission to the original file. Make sure to
- * read the whole comment to FLAC__metadata_simple_iterator_set_block()
- * below.
- * - Use FLAC__metadata_simple_iterator_insert_block_after() to add new blocks.
- * Use the object creation functions from
- * \link flac_metadata_object here \endlink to generate new objects.
- * - Use FLAC__metadata_simple_iterator_delete_block() to remove the block
- * currently referred to by the iterator, or replace it with padding.
- * - Destroy the iterator with FLAC__metadata_simple_iterator_delete() when
- * finished.
- *
- * \note
- * The FLAC file remains open the whole time between
- * FLAC__metadata_simple_iterator_init() and
- * FLAC__metadata_simple_iterator_delete(), so make sure you are not altering
- * the file during this time.
- *
- * \note
- * Do not modify the \a is_last, \a length, or \a type fields of returned
- * FLAC__StreamMetadata objects. These are managed automatically.
- *
- * \note
- * If any of the modification functions
- * (FLAC__metadata_simple_iterator_set_block(),
- * FLAC__metadata_simple_iterator_delete_block(),
- * FLAC__metadata_simple_iterator_insert_block_after(), etc.) return \c false,
- * you should delete the iterator as it may no longer be valid.
- *
- * \{
- */
-
- struct FLAC__Metadata_SimpleIterator;
- /** The opaque structure definition for the level 1 iterator type.
- * See the
- * \link flac_metadata_level1 metadata level 1 module \endlink
- * for a detailed description.
- */
- typedef struct FLAC__Metadata_SimpleIterator FLAC__Metadata_SimpleIterator;
-
- /** Status type for FLAC__Metadata_SimpleIterator.
- *
- * The iterator's current status can be obtained by calling FLAC__metadata_simple_iterator_status().
- */
- typedef enum {
-
- FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK = 0,
- /**< The iterator is in the normal OK state */
-
- FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ILLEGAL_INPUT,
- /**< The data passed into a function violated the function's usage criteria */
-
- FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ERROR_OPENING_FILE,
- /**< The iterator could not open the target file */
-
- FLAC__METADATA_SIMPLE_ITERATOR_STATUS_NOT_A_FLAC_FILE,
- /**< The iterator could not find the FLAC signature at the start of the file */
-
- FLAC__METADATA_SIMPLE_ITERATOR_STATUS_NOT_WRITABLE,
- /**< The iterator tried to write to a file that was not writable */
-
- FLAC__METADATA_SIMPLE_ITERATOR_STATUS_BAD_METADATA,
- /**< The iterator encountered input that does not conform to the FLAC metadata specification */
-
- FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR,
- /**< The iterator encountered an error while reading the FLAC file */
-
- FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR,
- /**< The iterator encountered an error while seeking in the FLAC file */
-
- FLAC__METADATA_SIMPLE_ITERATOR_STATUS_WRITE_ERROR,
- /**< The iterator encountered an error while writing the FLAC file */
-
- FLAC__METADATA_SIMPLE_ITERATOR_STATUS_RENAME_ERROR,
- /**< The iterator encountered an error renaming the FLAC file */
-
- FLAC__METADATA_SIMPLE_ITERATOR_STATUS_UNLINK_ERROR,
- /**< The iterator encountered an error removing the temporary file */
-
- FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR,
- /**< Memory allocation failed */
-
- FLAC__METADATA_SIMPLE_ITERATOR_STATUS_INTERNAL_ERROR
- /**< The caller violated an assertion or an unexpected error occurred */
-
- } FLAC__Metadata_SimpleIteratorStatus;
-
- /** Maps a FLAC__Metadata_SimpleIteratorStatus to a C string.
- *
- * Using a FLAC__Metadata_SimpleIteratorStatus as the index to this array
- * will give the string equivalent. The contents should not be modified.
- */
- extern FLAC_API const char * const FLAC__Metadata_SimpleIteratorStatusString[];
-
- /** Create a new iterator instance.
- *
- * \retval FLAC__Metadata_SimpleIterator*
- * \c NULL if there was an error allocating memory, else the new instance.
- */
- FLAC_API FLAC__Metadata_SimpleIterator *FLAC__metadata_simple_iterator_new(void);
-
- /** Free an iterator instance. Deletes the object pointed to by \a iterator.
- *
- * \param iterator A pointer to an existing iterator.
- * \assert
- * \code iterator != NULL \endcode
- */
- FLAC_API void FLAC__metadata_simple_iterator_delete(FLAC__Metadata_SimpleIterator *iterator);
-
- /** Get the current status of the iterator. Call this after a function
- * returns \c false to get the reason for the error. Also resets the status
- * to FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK.
- *
- * \param iterator A pointer to an existing iterator.
- * \assert
- * \code iterator != NULL \endcode
- * \retval FLAC__Metadata_SimpleIteratorStatus
- * The current status of the iterator.
- */
- FLAC_API FLAC__Metadata_SimpleIteratorStatus FLAC__metadata_simple_iterator_status(FLAC__Metadata_SimpleIterator *iterator);
-
- /** Initialize the iterator to point to the first metadata block in the
- * given FLAC file.
- *
- * \param iterator A pointer to an existing iterator.
- * \param filename The path to the FLAC file.
- * \param read_only If \c true, the FLAC file will be opened
- * in read-only mode; if \c false, the FLAC
- * file will be opened for edit even if no
- * edits are performed.
- * \param preserve_file_stats If \c true, the owner and modification
- * time will be preserved even if the FLAC
- * file is written to.
- * \assert
- * \code iterator != NULL \endcode
- * \code filename != NULL \endcode
- * \retval FLAC__bool
- * \c false if a memory allocation error occurs, the file can't be
- * opened, or another error occurs, else \c true.
- */
- FLAC_API FLAC__bool FLAC__metadata_simple_iterator_init(FLAC__Metadata_SimpleIterator *iterator, const char *filename, FLAC__bool read_only, FLAC__bool preserve_file_stats);
-
- /** Returns \c true if the FLAC file is writable. If \c false, calls to
- * FLAC__metadata_simple_iterator_set_block() and
- * FLAC__metadata_simple_iterator_insert_block_after() will fail.
- *
- * \param iterator A pointer to an existing iterator.
- * \assert
- * \code iterator != NULL \endcode
- * \retval FLAC__bool
- * See above.
- */
- FLAC_API FLAC__bool FLAC__metadata_simple_iterator_is_writable(const FLAC__Metadata_SimpleIterator *iterator);
-
- /** Moves the iterator forward one metadata block, returning \c false if
- * already at the end.
- *
- * \param iterator A pointer to an existing initialized iterator.
- * \assert
- * \code iterator != NULL \endcode
- * \a iterator has been successfully initialized with
- * FLAC__metadata_simple_iterator_init()
- * \retval FLAC__bool
- * \c false if already at the last metadata block of the chain, else
- * \c true.
- */
- FLAC_API FLAC__bool FLAC__metadata_simple_iterator_next(FLAC__Metadata_SimpleIterator *iterator);
-
- /** Moves the iterator backward one metadata block, returning \c false if
- * already at the beginning.
- *
- * \param iterator A pointer to an existing initialized iterator.
- * \assert
- * \code iterator != NULL \endcode
- * \a iterator has been successfully initialized with
- * FLAC__metadata_simple_iterator_init()
- * \retval FLAC__bool
- * \c false if already at the first metadata block of the chain, else
- * \c true.
- */
- FLAC_API FLAC__bool FLAC__metadata_simple_iterator_prev(FLAC__Metadata_SimpleIterator *iterator);
-
- /** Returns a flag telling if the current metadata block is the last.
- *
- * \param iterator A pointer to an existing initialized iterator.
- * \assert
- * \code iterator != NULL \endcode
- * \a iterator has been successfully initialized with
- * FLAC__metadata_simple_iterator_init()
- * \retval FLAC__bool
- * \c true if the current metadata block is the last in the file,
- * else \c false.
- */
- FLAC_API FLAC__bool FLAC__metadata_simple_iterator_is_last(const FLAC__Metadata_SimpleIterator *iterator);
-
- /** Get the offset of the metadata block at the current position. This
- * avoids reading the actual block data which can save time for large
- * blocks.
- *
- * \param iterator A pointer to an existing initialized iterator.
- * \assert
- * \code iterator != NULL \endcode
- * \a iterator has been successfully initialized with
- * FLAC__metadata_simple_iterator_init()
- * \retval off_t
- * The offset of the metadata block at the current iterator position.
- * This is the byte offset relative to the beginning of the file of
- * the current metadata block's header.
- */
- FLAC_API off_t FLAC__metadata_simple_iterator_get_block_offset(const FLAC__Metadata_SimpleIterator *iterator);
-
- /** Get the type of the metadata block at the current position. This
- * avoids reading the actual block data which can save time for large
- * blocks.
- *
- * \param iterator A pointer to an existing initialized iterator.
- * \assert
- * \code iterator != NULL \endcode
- * \a iterator has been successfully initialized with
- * FLAC__metadata_simple_iterator_init()
- * \retval FLAC__MetadataType
- * The type of the metadata block at the current iterator position.
- */
- FLAC_API FLAC__MetadataType FLAC__metadata_simple_iterator_get_block_type(const FLAC__Metadata_SimpleIterator *iterator);
-
- /** Get the length of the metadata block at the current position. This
- * avoids reading the actual block data which can save time for large
- * blocks.
- *
- * \param iterator A pointer to an existing initialized iterator.
- * \assert
- * \code iterator != NULL \endcode
- * \a iterator has been successfully initialized with
- * FLAC__metadata_simple_iterator_init()
- * \retval unsigned
- * The length of the metadata block at the current iterator position.
- * The is same length as that in the
- * <a href="http://flac.sourceforge.net/format.html#metadata_block_header">metadata block header</a>,
- * i.e. the length of the metadata body that follows the header.
- */
- FLAC_API unsigned FLAC__metadata_simple_iterator_get_block_length(const FLAC__Metadata_SimpleIterator *iterator);
-
- /** Get the application ID of the \c APPLICATION block at the current
- * position. This avoids reading the actual block data which can save
- * time for large blocks.
- *
- * \param iterator A pointer to an existing initialized iterator.
- * \param id A pointer to a buffer of at least \c 4 bytes where
- * the ID will be stored.
- * \assert
- * \code iterator != NULL \endcode
- * \code id != NULL \endcode
- * \a iterator has been successfully initialized with
- * FLAC__metadata_simple_iterator_init()
- * \retval FLAC__bool
- * \c true if the ID was successfully read, else \c false, in which
- * case you should check FLAC__metadata_simple_iterator_status() to
- * find out why. If the status is
- * \c FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ILLEGAL_INPUT, then the
- * current metadata block is not an \c APPLICATION block. Otherwise
- * if the status is
- * \c FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR or
- * \c FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR, an I/O error
- * occurred and the iterator can no longer be used.
- */
- FLAC_API FLAC__bool FLAC__metadata_simple_iterator_get_application_id(FLAC__Metadata_SimpleIterator *iterator, FLAC__byte *id);
-
- /** Get the metadata block at the current position. You can modify the
- * block but must use FLAC__metadata_simple_iterator_set_block() to
- * write it back to the FLAC file.
- *
- * You must call FLAC__metadata_object_delete() on the returned object
- * when you are finished with it.
- *
- * \param iterator A pointer to an existing initialized iterator.
- * \assert
- * \code iterator != NULL \endcode
- * \a iterator has been successfully initialized with
- * FLAC__metadata_simple_iterator_init()
- * \retval FLAC__StreamMetadata*
- * The current metadata block, or \c NULL if there was a memory
- * allocation error.
- */
- FLAC_API FLAC__StreamMetadata *FLAC__metadata_simple_iterator_get_block(FLAC__Metadata_SimpleIterator *iterator);
-
- /** Write a block back to the FLAC file. This function tries to be
- * as efficient as possible; how the block is actually written is
- * shown by the following:
- *
- * Existing block is a STREAMINFO block and the new block is a
- * STREAMINFO block: the new block is written in place. Make sure
- * you know what you're doing when changing the values of a
- * STREAMINFO block.
- *
- * Existing block is a STREAMINFO block and the new block is a
- * not a STREAMINFO block: this is an error since the first block
- * must be a STREAMINFO block. Returns \c false without altering the
- * file.
- *
- * Existing block is not a STREAMINFO block and the new block is a
- * STREAMINFO block: this is an error since there may be only one
- * STREAMINFO block. Returns \c false without altering the file.
- *
- * Existing block and new block are the same length: the existing
- * block will be replaced by the new block, written in place.
- *
- * Existing block is longer than new block: if use_padding is \c true,
- * the existing block will be overwritten in place with the new
- * block followed by a PADDING block, if possible, to make the total
- * size the same as the existing block. Remember that a padding
- * block requires at least four bytes so if the difference in size
- * between the new block and existing block is less than that, the
- * entire file will have to be rewritten, using the new block's
- * exact size. If use_padding is \c false, the entire file will be
- * rewritten, replacing the existing block by the new block.
- *
- * Existing block is shorter than new block: if use_padding is \c true,
- * the function will try and expand the new block into the following
- * PADDING block, if it exists and doing so won't shrink the PADDING
- * block to less than 4 bytes. If there is no following PADDING
- * block, or it will shrink to less than 4 bytes, or use_padding is
- * \c false, the entire file is rewritten, replacing the existing block
- * with the new block. Note that in this case any following PADDING
- * block is preserved as is.
- *
- * After writing the block, the iterator will remain in the same
- * place, i.e. pointing to the new block.
- *
- * \param iterator A pointer to an existing initialized iterator.
- * \param block The block to set.
- * \param use_padding See above.
- * \assert
- * \code iterator != NULL \endcode
- * \a iterator has been successfully initialized with
- * FLAC__metadata_simple_iterator_init()
- * \code block != NULL \endcode
- * \retval FLAC__bool
- * \c true if successful, else \c false.
- */
- FLAC_API FLAC__bool FLAC__metadata_simple_iterator_set_block(FLAC__Metadata_SimpleIterator *iterator, FLAC__StreamMetadata *block, FLAC__bool use_padding);
-
- /** This is similar to FLAC__metadata_simple_iterator_set_block()
- * except that instead of writing over an existing block, it appends
- * a block after the existing block. \a use_padding is again used to
- * tell the function to try an expand into following padding in an
- * attempt to avoid rewriting the entire file.
- *
- * This function will fail and return \c false if given a STREAMINFO
- * block.
- *
- * After writing the block, the iterator will be pointing to the
- * new block.
- *
- * \param iterator A pointer to an existing initialized iterator.
- * \param block The block to set.
- * \param use_padding See above.
- * \assert
- * \code iterator != NULL \endcode
- * \a iterator has been successfully initialized with
- * FLAC__metadata_simple_iterator_init()
- * \code block != NULL \endcode
- * \retval FLAC__bool
- * \c true if successful, else \c false.
- */
- FLAC_API FLAC__bool FLAC__metadata_simple_iterator_insert_block_after(FLAC__Metadata_SimpleIterator *iterator, FLAC__StreamMetadata *block, FLAC__bool use_padding);
-
- /** Deletes the block at the current position. This will cause the
- * entire FLAC file to be rewritten, unless \a use_padding is \c true,
- * in which case the block will be replaced by an equal-sized PADDING
- * block. The iterator will be left pointing to the block before the
- * one just deleted.
- *
- * You may not delete the STREAMINFO block.
- *
- * \param iterator A pointer to an existing initialized iterator.
- * \param use_padding See above.
- * \assert
- * \code iterator != NULL \endcode
- * \a iterator has been successfully initialized with
- * FLAC__metadata_simple_iterator_init()
- * \retval FLAC__bool
- * \c true if successful, else \c false.
- */
- FLAC_API FLAC__bool FLAC__metadata_simple_iterator_delete_block(FLAC__Metadata_SimpleIterator *iterator, FLAC__bool use_padding);
-
- /* \} */
-
- /** \defgroup flac_metadata_level2 FLAC/metadata.h: metadata level 2 interface
- * \ingroup flac_metadata
- *
- * \brief
- * The level 2 interface provides read-write access to FLAC file metadata;
- * all metadata is read into memory, operated on in memory, and then written
- * to file, which is more efficient than level 1 when editing multiple blocks.
- *
- * Currently Ogg FLAC is supported for read only, via
- * FLAC__metadata_chain_read_ogg() but a subsequent
- * FLAC__metadata_chain_write() will fail.
- *
- * The general usage of this interface is:
- *
- * - Create a new chain using FLAC__metadata_chain_new(). A chain is a
- * linked list of FLAC metadata blocks.
- * - Read all metadata into the the chain from a FLAC file using
- * FLAC__metadata_chain_read() or FLAC__metadata_chain_read_ogg() and
- * check the status.
- * - Optionally, consolidate the padding using
- * FLAC__metadata_chain_merge_padding() or
- * FLAC__metadata_chain_sort_padding().
- * - Create a new iterator using FLAC__metadata_iterator_new()
- * - Initialize the iterator to point to the first element in the chain
- * using FLAC__metadata_iterator_init()
- * - Traverse the chain using FLAC__metadata_iterator_next and
- * FLAC__metadata_iterator_prev().
- * - Get a block for reading or modification using
- * FLAC__metadata_iterator_get_block(). The pointer to the object
- * inside the chain is returned, so the block is yours to modify.
- * Changes will be reflected in the FLAC file when you write the
- * chain. You can also add and delete blocks (see functions below).
- * - When done, write out the chain using FLAC__metadata_chain_write().
- * Make sure to read the whole comment to the function below.
- * - Delete the chain using FLAC__metadata_chain_delete().
- *
- * \note
- * Even though the FLAC file is not open while the chain is being
- * manipulated, you must not alter the file externally during
- * this time. The chain assumes the FLAC file will not change
- * between the time of FLAC__metadata_chain_read()/FLAC__metadata_chain_read_ogg()
- * and FLAC__metadata_chain_write().
- *
- * \note
- * Do not modify the is_last, length, or type fields of returned
- * FLAC__StreamMetadata objects. These are managed automatically.
- *
- * \note
- * The metadata objects returned by FLAC__metadata_iterator_get_block()
- * are owned by the chain; do not FLAC__metadata_object_delete() them.
- * In the same way, blocks passed to FLAC__metadata_iterator_set_block()
- * become owned by the chain and they will be deleted when the chain is
- * deleted.
- *
- * \{
- */
-
- struct FLAC__Metadata_Chain;
- /** The opaque structure definition for the level 2 chain type.
- */
- typedef struct FLAC__Metadata_Chain FLAC__Metadata_Chain;
-
- struct FLAC__Metadata_Iterator;
- /** The opaque structure definition for the level 2 iterator type.
- */
- typedef struct FLAC__Metadata_Iterator FLAC__Metadata_Iterator;
-
- typedef enum {
- FLAC__METADATA_CHAIN_STATUS_OK = 0,
- /**< The chain is in the normal OK state */
-
- FLAC__METADATA_CHAIN_STATUS_ILLEGAL_INPUT,
- /**< The data passed into a function violated the function's usage criteria */
-
- FLAC__METADATA_CHAIN_STATUS_ERROR_OPENING_FILE,
- /**< The chain could not open the target file */
-
- FLAC__METADATA_CHAIN_STATUS_NOT_A_FLAC_FILE,
- /**< The chain could not find the FLAC signature at the start of the file */
-
- FLAC__METADATA_CHAIN_STATUS_NOT_WRITABLE,
- /**< The chain tried to write to a file that was not writable */
-
- FLAC__METADATA_CHAIN_STATUS_BAD_METADATA,
- /**< The chain encountered input that does not conform to the FLAC metadata specification */
-
- FLAC__METADATA_CHAIN_STATUS_READ_ERROR,
- /**< The chain encountered an error while reading the FLAC file */
-
- FLAC__METADATA_CHAIN_STATUS_SEEK_ERROR,
- /**< The chain encountered an error while seeking in the FLAC file */
-
- FLAC__METADATA_CHAIN_STATUS_WRITE_ERROR,
- /**< The chain encountered an error while writing the FLAC file */
-
- FLAC__METADATA_CHAIN_STATUS_RENAME_ERROR,
- /**< The chain encountered an error renaming the FLAC file */
-
- FLAC__METADATA_CHAIN_STATUS_UNLINK_ERROR,
- /**< The chain encountered an error removing the temporary file */
-
- FLAC__METADATA_CHAIN_STATUS_MEMORY_ALLOCATION_ERROR,
- /**< Memory allocation failed */
-
- FLAC__METADATA_CHAIN_STATUS_INTERNAL_ERROR,
- /**< The caller violated an assertion or an unexpected error occurred */
-
- FLAC__METADATA_CHAIN_STATUS_INVALID_CALLBACKS,
- /**< One or more of the required callbacks was NULL */
-
- FLAC__METADATA_CHAIN_STATUS_READ_WRITE_MISMATCH,
- /**< FLAC__metadata_chain_write() was called on a chain read by
- * FLAC__metadata_chain_read_with_callbacks()/FLAC__metadata_chain_read_ogg_with_callbacks(),
- * or
- * FLAC__metadata_chain_write_with_callbacks()/FLAC__metadata_chain_write_with_callbacks_and_tempfile()
- * was called on a chain read by
- * FLAC__metadata_chain_read()/FLAC__metadata_chain_read_ogg().
- * Matching read/write methods must always be used. */
-
- FLAC__METADATA_CHAIN_STATUS_WRONG_WRITE_CALL
- /**< FLAC__metadata_chain_write_with_callbacks() was called when the
- * chain write requires a tempfile; use
- * FLAC__metadata_chain_write_with_callbacks_and_tempfile() instead.
- * Or, FLAC__metadata_chain_write_with_callbacks_and_tempfile() was
- * called when the chain write does not require a tempfile; use
- * FLAC__metadata_chain_write_with_callbacks() instead.
- * Always check FLAC__metadata_chain_check_if_tempfile_needed()
- * before writing via callbacks. */
-
- } FLAC__Metadata_ChainStatus;
-
- /** Maps a FLAC__Metadata_ChainStatus to a C string.
- *
- * Using a FLAC__Metadata_ChainStatus as the index to this array
- * will give the string equivalent. The contents should not be modified.
- */
- extern FLAC_API const char * const FLAC__Metadata_ChainStatusString[];
-
- /*********** FLAC__Metadata_Chain ***********/
-
- /** Create a new chain instance.
- *
- * \retval FLAC__Metadata_Chain*
- * \c NULL if there was an error allocating memory, else the new instance.
- */
- FLAC_API FLAC__Metadata_Chain *FLAC__metadata_chain_new(void);
-
- /** Free a chain instance. Deletes the object pointed to by \a chain.
- *
- * \param chain A pointer to an existing chain.
- * \assert
- * \code chain != NULL \endcode
- */
- FLAC_API void FLAC__metadata_chain_delete(FLAC__Metadata_Chain *chain);
-
- /** Get the current status of the chain. Call this after a function
- * returns \c false to get the reason for the error. Also resets the
- * status to FLAC__METADATA_CHAIN_STATUS_OK.
- *
- * \param chain A pointer to an existing chain.
- * \assert
- * \code chain != NULL \endcode
- * \retval FLAC__Metadata_ChainStatus
- * The current status of the chain.
- */
- FLAC_API FLAC__Metadata_ChainStatus FLAC__metadata_chain_status(FLAC__Metadata_Chain *chain);
-
- /** Read all metadata from a FLAC file into the chain.
- *
- * \param chain A pointer to an existing chain.
- * \param filename The path to the FLAC file to read.
- * \assert
- * \code chain != NULL \endcode
- * \code filename != NULL \endcode
- * \retval FLAC__bool
- * \c true if a valid list of metadata blocks was read from
- * \a filename, else \c false. On failure, check the status with
- * FLAC__metadata_chain_status().
- */
- FLAC_API FLAC__bool FLAC__metadata_chain_read(FLAC__Metadata_Chain *chain, const char *filename);
-
- /** Read all metadata from an Ogg FLAC file into the chain.
- *
- * \note Ogg FLAC metadata data writing is not supported yet and
- * FLAC__metadata_chain_write() will fail.
- *
- * \param chain A pointer to an existing chain.
- * \param filename The path to the Ogg FLAC file to read.
- * \assert
- * \code chain != NULL \endcode
- * \code filename != NULL \endcode
- * \retval FLAC__bool
- * \c true if a valid list of metadata blocks was read from
- * \a filename, else \c false. On failure, check the status with
- * FLAC__metadata_chain_status().
- */
- FLAC_API FLAC__bool FLAC__metadata_chain_read_ogg(FLAC__Metadata_Chain *chain, const char *filename);
-
- /** Read all metadata from a FLAC stream into the chain via I/O callbacks.
- *
- * The \a handle need only be open for reading, but must be seekable.
- * The equivalent minimum stdio fopen() file mode is \c "r" (or \c "rb"
- * for Windows).
- *
- * \param chain A pointer to an existing chain.
- * \param handle The I/O handle of the FLAC stream to read. The
- * handle will NOT be closed after the metadata is read;
- * that is the duty of the caller.
- * \param callbacks
- * A set of callbacks to use for I/O. The mandatory
- * callbacks are \a read, \a seek, and \a tell.
- * \assert
- * \code chain != NULL \endcode
- * \retval FLAC__bool
- * \c true if a valid list of metadata blocks was read from
- * \a handle, else \c false. On failure, check the status with
- * FLAC__metadata_chain_status().
- */
- FLAC_API FLAC__bool FLAC__metadata_chain_read_with_callbacks(FLAC__Metadata_Chain *chain, FLAC__IOHandle handle, FLAC__IOCallbacks callbacks);
-
- /** Read all metadata from an Ogg FLAC stream into the chain via I/O callbacks.
- *
- * The \a handle need only be open for reading, but must be seekable.
- * The equivalent minimum stdio fopen() file mode is \c "r" (or \c "rb"
- * for Windows).
- *
- * \note Ogg FLAC metadata data writing is not supported yet and
- * FLAC__metadata_chain_write() will fail.
- *
- * \param chain A pointer to an existing chain.
- * \param handle The I/O handle of the Ogg FLAC stream to read. The
- * handle will NOT be closed after the metadata is read;
- * that is the duty of the caller.
- * \param callbacks
- * A set of callbacks to use for I/O. The mandatory
- * callbacks are \a read, \a seek, and \a tell.
- * \assert
- * \code chain != NULL \endcode
- * \retval FLAC__bool
- * \c true if a valid list of metadata blocks was read from
- * \a handle, else \c false. On failure, check the status with
- * FLAC__metadata_chain_status().
- */
- FLAC_API FLAC__bool FLAC__metadata_chain_read_ogg_with_callbacks(FLAC__Metadata_Chain *chain, FLAC__IOHandle handle, FLAC__IOCallbacks callbacks);
-
- /** Checks if writing the given chain would require the use of a
- * temporary file, or if it could be written in place.
- *
- * Under certain conditions, padding can be utilized so that writing
- * edited metadata back to the FLAC file does not require rewriting the
- * entire file. If rewriting is required, then a temporary workfile is
- * required. When writing metadata using callbacks, you must check
- * this function to know whether to call
- * FLAC__metadata_chain_write_with_callbacks() or
- * FLAC__metadata_chain_write_with_callbacks_and_tempfile(). When
- * writing with FLAC__metadata_chain_write(), the temporary file is
- * handled internally.
- *
- * \param chain A pointer to an existing chain.
- * \param use_padding
- * Whether or not padding will be allowed to be used
- * during the write. The value of \a use_padding given
- * here must match the value later passed to
- * FLAC__metadata_chain_write_with_callbacks() or
- * FLAC__metadata_chain_write_with_callbacks_with_tempfile().
- * \assert
- * \code chain != NULL \endcode
- * \retval FLAC__bool
- * \c true if writing the current chain would require a tempfile, or
- * \c false if metadata can be written in place.
- */
- FLAC_API FLAC__bool FLAC__metadata_chain_check_if_tempfile_needed(FLAC__Metadata_Chain *chain, FLAC__bool use_padding);
-
- /** Write all metadata out to the FLAC file. This function tries to be as
- * efficient as possible; how the metadata is actually written is shown by
- * the following:
- *
- * If the current chain is the same size as the existing metadata, the new
- * data is written in place.
- *
- * If the current chain is longer than the existing metadata, and
- * \a use_padding is \c true, and the last block is a PADDING block of
- * sufficient length, the function will truncate the final padding block
- * so that the overall size of the metadata is the same as the existing
- * metadata, and then just rewrite the metadata. Otherwise, if not all of
- * the above conditions are met, the entire FLAC file must be rewritten.
- * If you want to use padding this way it is a good idea to call
- * FLAC__metadata_chain_sort_padding() first so that you have the maximum
- * amount of padding to work with, unless you need to preserve ordering
- * of the PADDING blocks for some reason.
- *
- * If the current chain is shorter than the existing metadata, and
- * \a use_padding is \c true, and the final block is a PADDING block, the padding
- * is extended to make the overall size the same as the existing data. If
- * \a use_padding is \c true and the last block is not a PADDING block, a new
- * PADDING block is added to the end of the new data to make it the same
- * size as the existing data (if possible, see the note to
- * FLAC__metadata_simple_iterator_set_block() about the four byte limit)
- * and the new data is written in place. If none of the above apply or
- * \a use_padding is \c false, the entire FLAC file is rewritten.
- *
- * If \a preserve_file_stats is \c true, the owner and modification time will
- * be preserved even if the FLAC file is written.
- *
- * For this write function to be used, the chain must have been read with
- * FLAC__metadata_chain_read()/FLAC__metadata_chain_read_ogg(), not
- * FLAC__metadata_chain_read_with_callbacks()/FLAC__metadata_chain_read_ogg_with_callbacks().
- *
- * \param chain A pointer to an existing chain.
- * \param use_padding See above.
- * \param preserve_file_stats See above.
- * \assert
- * \code chain != NULL \endcode
- * \retval FLAC__bool
- * \c true if the write succeeded, else \c false. On failure,
- * check the status with FLAC__metadata_chain_status().
- */
- FLAC_API FLAC__bool FLAC__metadata_chain_write(FLAC__Metadata_Chain *chain, FLAC__bool use_padding, FLAC__bool preserve_file_stats);
-
- /** Write all metadata out to a FLAC stream via callbacks.
- *
- * (See FLAC__metadata_chain_write() for the details on how padding is
- * used to write metadata in place if possible.)
- *
- * The \a handle must be open for updating and be seekable. The
- * equivalent minimum stdio fopen() file mode is \c "r+" (or \c "r+b"
- * for Windows).
- *
- * For this write function to be used, the chain must have been read with
- * FLAC__metadata_chain_read_with_callbacks()/FLAC__metadata_chain_read_ogg_with_callbacks(),
- * not FLAC__metadata_chain_read()/FLAC__metadata_chain_read_ogg().
- * Also, FLAC__metadata_chain_check_if_tempfile_needed() must have returned
- * \c false.
- *
- * \param chain A pointer to an existing chain.
- * \param use_padding See FLAC__metadata_chain_write()
- * \param handle The I/O handle of the FLAC stream to write. The
- * handle will NOT be closed after the metadata is
- * written; that is the duty of the caller.
- * \param callbacks A set of callbacks to use for I/O. The mandatory
- * callbacks are \a write and \a seek.
- * \assert
- * \code chain != NULL \endcode
- * \retval FLAC__bool
- * \c true if the write succeeded, else \c false. On failure,
- * check the status with FLAC__metadata_chain_status().
- */
- FLAC_API FLAC__bool FLAC__metadata_chain_write_with_callbacks(FLAC__Metadata_Chain *chain, FLAC__bool use_padding, FLAC__IOHandle handle, FLAC__IOCallbacks callbacks);
-
- /** Write all metadata out to a FLAC stream via callbacks.
- *
- * (See FLAC__metadata_chain_write() for the details on how padding is
- * used to write metadata in place if possible.)
- *
- * This version of the write-with-callbacks function must be used when
- * FLAC__metadata_chain_check_if_tempfile_needed() returns true. In
- * this function, you must supply an I/O handle corresponding to the
- * FLAC file to edit, and a temporary handle to which the new FLAC
- * file will be written. It is the caller's job to move this temporary
- * FLAC file on top of the original FLAC file to complete the metadata
- * edit.
- *
- * The \a handle must be open for reading and be seekable. The
- * equivalent minimum stdio fopen() file mode is \c "r" (or \c "rb"
- * for Windows).
- *
- * The \a temp_handle must be open for writing. The
- * equivalent minimum stdio fopen() file mode is \c "w" (or \c "wb"
- * for Windows). It should be an empty stream, or at least positioned
- * at the start-of-file (in which case it is the caller's duty to
- * truncate it on return).
- *
- * For this write function to be used, the chain must have been read with
- * FLAC__metadata_chain_read_with_callbacks()/FLAC__metadata_chain_read_ogg_with_callbacks(),
- * not FLAC__metadata_chain_read()/FLAC__metadata_chain_read_ogg().
- * Also, FLAC__metadata_chain_check_if_tempfile_needed() must have returned
- * \c true.
- *
- * \param chain A pointer to an existing chain.
- * \param use_padding See FLAC__metadata_chain_write()
- * \param handle The I/O handle of the original FLAC stream to read.
- * The handle will NOT be closed after the metadata is
- * written; that is the duty of the caller.
- * \param callbacks A set of callbacks to use for I/O on \a handle.
- * The mandatory callbacks are \a read, \a seek, and
- * \a eof.
- * \param temp_handle The I/O handle of the FLAC stream to write. The
- * handle will NOT be closed after the metadata is
- * written; that is the duty of the caller.
- * \param temp_callbacks
- * A set of callbacks to use for I/O on temp_handle.
- * The only mandatory callback is \a write.
- * \assert
- * \code chain != NULL \endcode
- * \retval FLAC__bool
- * \c true if the write succeeded, else \c false. On failure,
- * check the status with FLAC__metadata_chain_status().
- */
- FLAC_API FLAC__bool FLAC__metadata_chain_write_with_callbacks_and_tempfile(FLAC__Metadata_Chain *chain, FLAC__bool use_padding, FLAC__IOHandle handle, FLAC__IOCallbacks callbacks, FLAC__IOHandle temp_handle, FLAC__IOCallbacks temp_callbacks);
-
- /** Merge adjacent PADDING blocks into a single block.
- *
- * \note This function does not write to the FLAC file, it only
- * modifies the chain.
- *
- * \warning Any iterator on the current chain will become invalid after this
- * call. You should delete the iterator and get a new one.
- *
- * \param chain A pointer to an existing chain.
- * \assert
- * \code chain != NULL \endcode
- */
- FLAC_API void FLAC__metadata_chain_merge_padding(FLAC__Metadata_Chain *chain);
-
- /** This function will move all PADDING blocks to the end on the metadata,
- * then merge them into a single block.
- *
- * \note This function does not write to the FLAC file, it only
- * modifies the chain.
- *
- * \warning Any iterator on the current chain will become invalid after this
- * call. You should delete the iterator and get a new one.
- *
- * \param chain A pointer to an existing chain.
- * \assert
- * \code chain != NULL \endcode
- */
- FLAC_API void FLAC__metadata_chain_sort_padding(FLAC__Metadata_Chain *chain);
-
- /*********** FLAC__Metadata_Iterator ***********/
-
- /** Create a new iterator instance.
- *
- * \retval FLAC__Metadata_Iterator*
- * \c NULL if there was an error allocating memory, else the new instance.
- */
- FLAC_API FLAC__Metadata_Iterator *FLAC__metadata_iterator_new(void);
-
- /** Free an iterator instance. Deletes the object pointed to by \a iterator.
- *
- * \param iterator A pointer to an existing iterator.
- * \assert
- * \code iterator != NULL \endcode
- */
- FLAC_API void FLAC__metadata_iterator_delete(FLAC__Metadata_Iterator *iterator);
-
- /** Initialize the iterator to point to the first metadata block in the
- * given chain.
- *
- * \param iterator A pointer to an existing iterator.
- * \param chain A pointer to an existing and initialized (read) chain.
- * \assert
- * \code iterator != NULL \endcode
- * \code chain != NULL \endcode
- */
- FLAC_API void FLAC__metadata_iterator_init(FLAC__Metadata_Iterator *iterator, FLAC__Metadata_Chain *chain);
-
- /** Moves the iterator forward one metadata block, returning \c false if
- * already at the end.
- *
- * \param iterator A pointer to an existing initialized iterator.
- * \assert
- * \code iterator != NULL \endcode
- * \a iterator has been successfully initialized with
- * FLAC__metadata_iterator_init()
- * \retval FLAC__bool
- * \c false if already at the last metadata block of the chain, else
- * \c true.
- */
- FLAC_API FLAC__bool FLAC__metadata_iterator_next(FLAC__Metadata_Iterator *iterator);
-
- /** Moves the iterator backward one metadata block, returning \c false if
- * already at the beginning.
- *
- * \param iterator A pointer to an existing initialized iterator.
- * \assert
- * \code iterator != NULL \endcode
- * \a iterator has been successfully initialized with
- * FLAC__metadata_iterator_init()
- * \retval FLAC__bool
- * \c false if already at the first metadata block of the chain, else
- * \c true.
- */
- FLAC_API FLAC__bool FLAC__metadata_iterator_prev(FLAC__Metadata_Iterator *iterator);
-
- /** Get the type of the metadata block at the current position.
- *
- * \param iterator A pointer to an existing initialized iterator.
- * \assert
- * \code iterator != NULL \endcode
- * \a iterator has been successfully initialized with
- * FLAC__metadata_iterator_init()
- * \retval FLAC__MetadataType
- * The type of the metadata block at the current iterator position.
- */
- FLAC_API FLAC__MetadataType FLAC__metadata_iterator_get_block_type(const FLAC__Metadata_Iterator *iterator);
-
- /** Get the metadata block at the current position. You can modify
- * the block in place but must write the chain before the changes
- * are reflected to the FLAC file. You do not need to call
- * FLAC__metadata_iterator_set_block() to reflect the changes;
- * the pointer returned by FLAC__metadata_iterator_get_block()
- * points directly into the chain.
- *
- * \warning
- * Do not call FLAC__metadata_object_delete() on the returned object;
- * to delete a block use FLAC__metadata_iterator_delete_block().
- *
- * \param iterator A pointer to an existing initialized iterator.
- * \assert
- * \code iterator != NULL \endcode
- * \a iterator has been successfully initialized with
- * FLAC__metadata_iterator_init()
- * \retval FLAC__StreamMetadata*
- * The current metadata block.
- */
- FLAC_API FLAC__StreamMetadata *FLAC__metadata_iterator_get_block(FLAC__Metadata_Iterator *iterator);
-
- /** Set the metadata block at the current position, replacing the existing
- * block. The new block passed in becomes owned by the chain and it will be
- * deleted when the chain is deleted.
- *
- * \param iterator A pointer to an existing initialized iterator.
- * \param block A pointer to a metadata block.
- * \assert
- * \code iterator != NULL \endcode
- * \a iterator has been successfully initialized with
- * FLAC__metadata_iterator_init()
- * \code block != NULL \endcode
- * \retval FLAC__bool
- * \c false if the conditions in the above description are not met, or
- * a memory allocation error occurs, otherwise \c true.
- */
- FLAC_API FLAC__bool FLAC__metadata_iterator_set_block(FLAC__Metadata_Iterator *iterator, FLAC__StreamMetadata *block);
-
- /** Removes the current block from the chain. If \a replace_with_padding is
- * \c true, the block will instead be replaced with a padding block of equal
- * size. You can not delete the STREAMINFO block. The iterator will be
- * left pointing to the block before the one just "deleted", even if
- * \a replace_with_padding is \c true.
- *
- * \param iterator A pointer to an existing initialized iterator.
- * \param replace_with_padding See above.
- * \assert
- * \code iterator != NULL \endcode
- * \a iterator has been successfully initialized with
- * FLAC__metadata_iterator_init()
- * \retval FLAC__bool
- * \c false if the conditions in the above description are not met,
- * otherwise \c true.
- */
- FLAC_API FLAC__bool FLAC__metadata_iterator_delete_block(FLAC__Metadata_Iterator *iterator, FLAC__bool replace_with_padding);
-
- /** Insert a new block before the current block. You cannot insert a block
- * before the first STREAMINFO block. You cannot insert a STREAMINFO block
- * as there can be only one, the one that already exists at the head when you
- * read in a chain. The chain takes ownership of the new block and it will be
- * deleted when the chain is deleted. The iterator will be left pointing to
- * the new block.
- *
- * \param iterator A pointer to an existing initialized iterator.
- * \param block A pointer to a metadata block to insert.
- * \assert
- * \code iterator != NULL \endcode
- * \a iterator has been successfully initialized with
- * FLAC__metadata_iterator_init()
- * \retval FLAC__bool
- * \c false if the conditions in the above description are not met, or
- * a memory allocation error occurs, otherwise \c true.
- */
- FLAC_API FLAC__bool FLAC__metadata_iterator_insert_block_before(FLAC__Metadata_Iterator *iterator, FLAC__StreamMetadata *block);
-
- /** Insert a new block after the current block. You cannot insert a STREAMINFO
- * block as there can be only one, the one that already exists at the head when
- * you read in a chain. The chain takes ownership of the new block and it will
- * be deleted when the chain is deleted. The iterator will be left pointing to
- * the new block.
- *
- * \param iterator A pointer to an existing initialized iterator.
- * \param block A pointer to a metadata block to insert.
- * \assert
- * \code iterator != NULL \endcode
- * \a iterator has been successfully initialized with
- * FLAC__metadata_iterator_init()
- * \retval FLAC__bool
- * \c false if the conditions in the above description are not met, or
- * a memory allocation error occurs, otherwise \c true.
- */
- FLAC_API FLAC__bool FLAC__metadata_iterator_insert_block_after(FLAC__Metadata_Iterator *iterator, FLAC__StreamMetadata *block);
-
- /* \} */
-
- /** \defgroup flac_metadata_object FLAC/metadata.h: metadata object methods
- * \ingroup flac_metadata
- *
- * \brief
- * This module contains methods for manipulating FLAC metadata objects.
- *
- * Since many are variable length we have to be careful about the memory
- * management. We decree that all pointers to data in the object are
- * owned by the object and memory-managed by the object.
- *
- * Use the FLAC__metadata_object_new() and FLAC__metadata_object_delete()
- * functions to create all instances. When using the
- * FLAC__metadata_object_set_*() functions to set pointers to data, set
- * \a copy to \c true to have the function make it's own copy of the data, or
- * to \c false to give the object ownership of your data. In the latter case
- * your pointer must be freeable by free() and will be free()d when the object
- * is FLAC__metadata_object_delete()d. It is legal to pass a null pointer as
- * the data pointer to a FLAC__metadata_object_set_*() function as long as
- * the length argument is 0 and the \a copy argument is \c false.
- *
- * The FLAC__metadata_object_new() and FLAC__metadata_object_clone() function
- * will return \c NULL in the case of a memory allocation error, otherwise a new
- * object. The FLAC__metadata_object_set_*() functions return \c false in the
- * case of a memory allocation error.
- *
- * We don't have the convenience of C++ here, so note that the library relies
- * on you to keep the types straight. In other words, if you pass, for
- * example, a FLAC__StreamMetadata* that represents a STREAMINFO block to
- * FLAC__metadata_object_application_set_data(), you will get an assertion
- * failure.
- *
- * For convenience the FLAC__metadata_object_vorbiscomment_*() functions
- * maintain a trailing NUL on each Vorbis comment entry. This is not counted
- * toward the length or stored in the stream, but it can make working with plain
- * comments (those that don't contain embedded-NULs in the value) easier.
- * Entries passed into these functions have trailing NULs added if missing, and
- * returned entries are guaranteed to have a trailing NUL.
- *
- * The FLAC__metadata_object_vorbiscomment_*() functions that take a Vorbis
- * comment entry/name/value will first validate that it complies with the Vorbis
- * comment specification and return false if it does not.
- *
- * There is no need to recalculate the length field on metadata blocks you
- * have modified. They will be calculated automatically before they are
- * written back to a file.
- *
- * \{
- */
-
- /** Create a new metadata object instance of the given type.
- *
- * The object will be "empty"; i.e. values and data pointers will be \c 0,
- * with the exception of FLAC__METADATA_TYPE_VORBIS_COMMENT, which will have
- * the vendor string set (but zero comments).
- *
- * Do not pass in a value greater than or equal to
- * \a FLAC__METADATA_TYPE_UNDEFINED unless you really know what you're
- * doing.
- *
- * \param type Type of object to create
- * \retval FLAC__StreamMetadata*
- * \c NULL if there was an error allocating memory or the type code is
- * greater than FLAC__MAX_METADATA_TYPE_CODE, else the new instance.
- */
- FLAC_API FLAC__StreamMetadata *FLAC__metadata_object_new(FLAC__MetadataType type);
-
- /** Create a copy of an existing metadata object.
- *
- * The copy is a "deep" copy, i.e. dynamically allocated data within the
- * object is also copied. The caller takes ownership of the new block and
- * is responsible for freeing it with FLAC__metadata_object_delete().
- *
- * \param object Pointer to object to copy.
- * \assert
- * \code object != NULL \endcode
- * \retval FLAC__StreamMetadata*
- * \c NULL if there was an error allocating memory, else the new instance.
- */
- FLAC_API FLAC__StreamMetadata *FLAC__metadata_object_clone(const FLAC__StreamMetadata *object);
-
- /** Free a metadata object. Deletes the object pointed to by \a object.
- *
- * The delete is a "deep" delete, i.e. dynamically allocated data within the
- * object is also deleted.
- *
- * \param object A pointer to an existing object.
- * \assert
- * \code object != NULL \endcode
- */
- FLAC_API void FLAC__metadata_object_delete(FLAC__StreamMetadata *object);
-
- /** Compares two metadata objects.
- *
- * The compare is "deep", i.e. dynamically allocated data within the
- * object is also compared.
- *
- * \param block1 A pointer to an existing object.
- * \param block2 A pointer to an existing object.
- * \assert
- * \code block1 != NULL \endcode
- * \code block2 != NULL \endcode
- * \retval FLAC__bool
- * \c true if objects are identical, else \c false.
- */
- FLAC_API FLAC__bool FLAC__metadata_object_is_equal(const FLAC__StreamMetadata *block1, const FLAC__StreamMetadata *block2);
-
- /** Sets the application data of an APPLICATION block.
- *
- * If \a copy is \c true, a copy of the data is stored; otherwise, the object
- * takes ownership of the pointer. The existing data will be freed if this
- * function is successful, otherwise the original data will remain if \a copy
- * is \c true and malloc() fails.
- *
- * \note It is safe to pass a const pointer to \a data if \a copy is \c true.
- *
- * \param object A pointer to an existing APPLICATION object.
- * \param data A pointer to the data to set.
- * \param length The length of \a data in bytes.
- * \param copy See above.
- * \assert
- * \code object != NULL \endcode
- * \code object->type == FLAC__METADATA_TYPE_APPLICATION \endcode
- * \code (data != NULL && length > 0) ||
- * (data == NULL && length == 0 && copy == false) \endcode
- * \retval FLAC__bool
- * \c false if \a copy is \c true and malloc() fails, else \c true.
- */
- FLAC_API FLAC__bool FLAC__metadata_object_application_set_data(FLAC__StreamMetadata *object, FLAC__byte *data, unsigned length, FLAC__bool copy);
-
- /** Resize the seekpoint array.
- *
- * If the size shrinks, elements will truncated; if it grows, new placeholder
- * points will be added to the end.
- *
- * \param object A pointer to an existing SEEKTABLE object.
- * \param new_num_points The desired length of the array; may be \c 0.
- * \assert
- * \code object != NULL \endcode
- * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode
- * \code (object->data.seek_table.points == NULL && object->data.seek_table.num_points == 0) ||
- * (object->data.seek_table.points != NULL && object->data.seek_table.num_points > 0) \endcode
- * \retval FLAC__bool
- * \c false if memory allocation error, else \c true.
- */
- FLAC_API FLAC__bool FLAC__metadata_object_seektable_resize_points(FLAC__StreamMetadata *object, unsigned new_num_points);
-
- /** Set a seekpoint in a seektable.
- *
- * \param object A pointer to an existing SEEKTABLE object.
- * \param point_num Index into seekpoint array to set.
- * \param point The point to set.
- * \assert
- * \code object != NULL \endcode
- * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode
- * \code object->data.seek_table.num_points > point_num \endcode
- */
- FLAC_API void FLAC__metadata_object_seektable_set_point(FLAC__StreamMetadata *object, unsigned point_num, FLAC__StreamMetadata_SeekPoint point);
-
- /** Insert a seekpoint into a seektable.
- *
- * \param object A pointer to an existing SEEKTABLE object.
- * \param point_num Index into seekpoint array to set.
- * \param point The point to set.
- * \assert
- * \code object != NULL \endcode
- * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode
- * \code object->data.seek_table.num_points >= point_num \endcode
- * \retval FLAC__bool
- * \c false if memory allocation error, else \c true.
- */
- FLAC_API FLAC__bool FLAC__metadata_object_seektable_insert_point(FLAC__StreamMetadata *object, unsigned point_num, FLAC__StreamMetadata_SeekPoint point);
-
- /** Delete a seekpoint from a seektable.
- *
- * \param object A pointer to an existing SEEKTABLE object.
- * \param point_num Index into seekpoint array to set.
- * \assert
- * \code object != NULL \endcode
- * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode
- * \code object->data.seek_table.num_points > point_num \endcode
- * \retval FLAC__bool
- * \c false if memory allocation error, else \c true.
- */
- FLAC_API FLAC__bool FLAC__metadata_object_seektable_delete_point(FLAC__StreamMetadata *object, unsigned point_num);
-
- /** Check a seektable to see if it conforms to the FLAC specification.
- * See the format specification for limits on the contents of the
- * seektable.
- *
- * \param object A pointer to an existing SEEKTABLE object.
- * \assert
- * \code object != NULL \endcode
- * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode
- * \retval FLAC__bool
- * \c false if seek table is illegal, else \c true.
- */
- FLAC_API FLAC__bool FLAC__metadata_object_seektable_is_legal(const FLAC__StreamMetadata *object);
-
- /** Append a number of placeholder points to the end of a seek table.
- *
- * \note
- * As with the other ..._seektable_template_... functions, you should
- * call FLAC__metadata_object_seektable_template_sort() when finished
- * to make the seek table legal.
- *
- * \param object A pointer to an existing SEEKTABLE object.
- * \param num The number of placeholder points to append.
- * \assert
- * \code object != NULL \endcode
- * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode
- * \retval FLAC__bool
- * \c false if memory allocation fails, else \c true.
- */
- FLAC_API FLAC__bool FLAC__metadata_object_seektable_template_append_placeholders(FLAC__StreamMetadata *object, unsigned num);
-
- /** Append a specific seek point template to the end of a seek table.
- *
- * \note
- * As with the other ..._seektable_template_... functions, you should
- * call FLAC__metadata_object_seektable_template_sort() when finished
- * to make the seek table legal.
- *
- * \param object A pointer to an existing SEEKTABLE object.
- * \param sample_number The sample number of the seek point template.
- * \assert
- * \code object != NULL \endcode
- * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode
- * \retval FLAC__bool
- * \c false if memory allocation fails, else \c true.
- */
- FLAC_API FLAC__bool FLAC__metadata_object_seektable_template_append_point(FLAC__StreamMetadata *object, FLAC__uint64 sample_number);
-
- /** Append specific seek point templates to the end of a seek table.
- *
- * \note
- * As with the other ..._seektable_template_... functions, you should
- * call FLAC__metadata_object_seektable_template_sort() when finished
- * to make the seek table legal.
- *
- * \param object A pointer to an existing SEEKTABLE object.
- * \param sample_numbers An array of sample numbers for the seek points.
- * \param num The number of seek point templates to append.
- * \assert
- * \code object != NULL \endcode
- * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode
- * \retval FLAC__bool
- * \c false if memory allocation fails, else \c true.
- */
- FLAC_API FLAC__bool FLAC__metadata_object_seektable_template_append_points(FLAC__StreamMetadata *object, FLAC__uint64 sample_numbers[], unsigned num);
-
- /** Append a set of evenly-spaced seek point templates to the end of a
- * seek table.
- *
- * \note
- * As with the other ..._seektable_template_... functions, you should
- * call FLAC__metadata_object_seektable_template_sort() when finished
- * to make the seek table legal.
- *
- * \param object A pointer to an existing SEEKTABLE object.
- * \param num The number of placeholder points to append.
- * \param total_samples The total number of samples to be encoded;
- * the seekpoints will be spaced approximately
- * \a total_samples / \a num samples apart.
- * \assert
- * \code object != NULL \endcode
- * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode
- * \code total_samples > 0 \endcode
- * \retval FLAC__bool
- * \c false if memory allocation fails, else \c true.
- */
- FLAC_API FLAC__bool FLAC__metadata_object_seektable_template_append_spaced_points(FLAC__StreamMetadata *object, unsigned num, FLAC__uint64 total_samples);
-
- /** Append a set of evenly-spaced seek point templates to the end of a
- * seek table.
- *
- * \note
- * As with the other ..._seektable_template_... functions, you should
- * call FLAC__metadata_object_seektable_template_sort() when finished
- * to make the seek table legal.
- *
- * \param object A pointer to an existing SEEKTABLE object.
- * \param samples The number of samples apart to space the placeholder
- * points. The first point will be at sample \c 0, the
- * second at sample \a samples, then 2*\a samples, and
- * so on. As long as \a samples and \a total_samples
- * are greater than \c 0, there will always be at least
- * one seekpoint at sample \c 0.
- * \param total_samples The total number of samples to be encoded;
- * the seekpoints will be spaced
- * \a samples samples apart.
- * \assert
- * \code object != NULL \endcode
- * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode
- * \code samples > 0 \endcode
- * \code total_samples > 0 \endcode
- * \retval FLAC__bool
- * \c false if memory allocation fails, else \c true.
- */
- FLAC_API FLAC__bool FLAC__metadata_object_seektable_template_append_spaced_points_by_samples(FLAC__StreamMetadata *object, unsigned samples, FLAC__uint64 total_samples);
-
- /** Sort a seek table's seek points according to the format specification,
- * removing duplicates.
- *
- * \param object A pointer to a seek table to be sorted.
- * \param compact If \c false, behaves like FLAC__format_seektable_sort().
- * If \c true, duplicates are deleted and the seek table is
- * shrunk appropriately; the number of placeholder points
- * present in the seek table will be the same after the call
- * as before.
- * \assert
- * \code object != NULL \endcode
- * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode
- * \retval FLAC__bool
- * \c false if realloc() fails, else \c true.
- */
- FLAC_API FLAC__bool FLAC__metadata_object_seektable_template_sort(FLAC__StreamMetadata *object, FLAC__bool compact);
-
- /** Sets the vendor string in a VORBIS_COMMENT block.
- *
- * For convenience, a trailing NUL is added to the entry if it doesn't have
- * one already.
- *
- * If \a copy is \c true, a copy of the entry is stored; otherwise, the object
- * takes ownership of the \c entry.entry pointer.
- *
- * \note If this function returns \c false, the caller still owns the
- * pointer.
- *
- * \param object A pointer to an existing VORBIS_COMMENT object.
- * \param entry The entry to set the vendor string to.
- * \param copy See above.
- * \assert
- * \code object != NULL \endcode
- * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode
- * \code (entry.entry != NULL && entry.length > 0) ||
- * (entry.entry == NULL && entry.length == 0) \endcode
- * \retval FLAC__bool
- * \c false if memory allocation fails or \a entry does not comply with the
- * Vorbis comment specification, else \c true.
- */
- FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_set_vendor_string(FLAC__StreamMetadata *object, FLAC__StreamMetadata_VorbisComment_Entry entry, FLAC__bool copy);
-
- /** Resize the comment array.
- *
- * If the size shrinks, elements will truncated; if it grows, new empty
- * fields will be added to the end.
- *
- * \param object A pointer to an existing VORBIS_COMMENT object.
- * \param new_num_comments The desired length of the array; may be \c 0.
- * \assert
- * \code object != NULL \endcode
- * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode
- * \code (object->data.vorbis_comment.comments == NULL && object->data.vorbis_comment.num_comments == 0) ||
- * (object->data.vorbis_comment.comments != NULL && object->data.vorbis_comment.num_comments > 0) \endcode
- * \retval FLAC__bool
- * \c false if memory allocation fails, else \c true.
- */
- FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_resize_comments(FLAC__StreamMetadata *object, unsigned new_num_comments);
-
- /** Sets a comment in a VORBIS_COMMENT block.
- *
- * For convenience, a trailing NUL is added to the entry if it doesn't have
- * one already.
- *
- * If \a copy is \c true, a copy of the entry is stored; otherwise, the object
- * takes ownership of the \c entry.entry pointer.
- *
- * \note If this function returns \c false, the caller still owns the
- * pointer.
- *
- * \param object A pointer to an existing VORBIS_COMMENT object.
- * \param comment_num Index into comment array to set.
- * \param entry The entry to set the comment to.
- * \param copy See above.
- * \assert
- * \code object != NULL \endcode
- * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode
- * \code comment_num < object->data.vorbis_comment.num_comments \endcode
- * \code (entry.entry != NULL && entry.length > 0) ||
- * (entry.entry == NULL && entry.length == 0) \endcode
- * \retval FLAC__bool
- * \c false if memory allocation fails or \a entry does not comply with the
- * Vorbis comment specification, else \c true.
- */
- FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_set_comment(FLAC__StreamMetadata *object, unsigned comment_num, FLAC__StreamMetadata_VorbisComment_Entry entry, FLAC__bool copy);
-
- /** Insert a comment in a VORBIS_COMMENT block at the given index.
- *
- * For convenience, a trailing NUL is added to the entry if it doesn't have
- * one already.
- *
- * If \a copy is \c true, a copy of the entry is stored; otherwise, the object
- * takes ownership of the \c entry.entry pointer.
- *
- * \note If this function returns \c false, the caller still owns the
- * pointer.
- *
- * \param object A pointer to an existing VORBIS_COMMENT object.
- * \param comment_num The index at which to insert the comment. The comments
- * at and after \a comment_num move right one position.
- * To append a comment to the end, set \a comment_num to
- * \c object->data.vorbis_comment.num_comments .
- * \param entry The comment to insert.
- * \param copy See above.
- * \assert
- * \code object != NULL \endcode
- * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode
- * \code object->data.vorbis_comment.num_comments >= comment_num \endcode
- * \code (entry.entry != NULL && entry.length > 0) ||
- * (entry.entry == NULL && entry.length == 0 && copy == false) \endcode
- * \retval FLAC__bool
- * \c false if memory allocation fails or \a entry does not comply with the
- * Vorbis comment specification, else \c true.
- */
- FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_insert_comment(FLAC__StreamMetadata *object, unsigned comment_num, FLAC__StreamMetadata_VorbisComment_Entry entry, FLAC__bool copy);
-
- /** Appends a comment to a VORBIS_COMMENT block.
- *
- * For convenience, a trailing NUL is added to the entry if it doesn't have
- * one already.
- *
- * If \a copy is \c true, a copy of the entry is stored; otherwise, the object
- * takes ownership of the \c entry.entry pointer.
- *
- * \note If this function returns \c false, the caller still owns the
- * pointer.
- *
- * \param object A pointer to an existing VORBIS_COMMENT object.
- * \param entry The comment to insert.
- * \param copy See above.
- * \assert
- * \code object != NULL \endcode
- * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode
- * \code (entry.entry != NULL && entry.length > 0) ||
- * (entry.entry == NULL && entry.length == 0 && copy == false) \endcode
- * \retval FLAC__bool
- * \c false if memory allocation fails or \a entry does not comply with the
- * Vorbis comment specification, else \c true.
- */
- FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_append_comment(FLAC__StreamMetadata *object, FLAC__StreamMetadata_VorbisComment_Entry entry, FLAC__bool copy);
-
- /** Replaces comments in a VORBIS_COMMENT block with a new one.
- *
- * For convenience, a trailing NUL is added to the entry if it doesn't have
- * one already.
- *
- * Depending on the the value of \a all, either all or just the first comment
- * whose field name(s) match the given entry's name will be replaced by the
- * given entry. If no comments match, \a entry will simply be appended.
- *
- * If \a copy is \c true, a copy of the entry is stored; otherwise, the object
- * takes ownership of the \c entry.entry pointer.
- *
- * \note If this function returns \c false, the caller still owns the
- * pointer.
- *
- * \param object A pointer to an existing VORBIS_COMMENT object.
- * \param entry The comment to insert.
- * \param all If \c true, all comments whose field name matches
- * \a entry's field name will be removed, and \a entry will
- * be inserted at the position of the first matching
- * comment. If \c false, only the first comment whose
- * field name matches \a entry's field name will be
- * replaced with \a entry.
- * \param copy See above.
- * \assert
- * \code object != NULL \endcode
- * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode
- * \code (entry.entry != NULL && entry.length > 0) ||
- * (entry.entry == NULL && entry.length == 0 && copy == false) \endcode
- * \retval FLAC__bool
- * \c false if memory allocation fails or \a entry does not comply with the
- * Vorbis comment specification, else \c true.
- */
- FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_replace_comment(FLAC__StreamMetadata *object, FLAC__StreamMetadata_VorbisComment_Entry entry, FLAC__bool all, FLAC__bool copy);
-
- /** Delete a comment in a VORBIS_COMMENT block at the given index.
- *
- * \param object A pointer to an existing VORBIS_COMMENT object.
- * \param comment_num The index of the comment to delete.
- * \assert
- * \code object != NULL \endcode
- * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode
- * \code object->data.vorbis_comment.num_comments > comment_num \endcode
- * \retval FLAC__bool
- * \c false if realloc() fails, else \c true.
- */
- FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_delete_comment(FLAC__StreamMetadata *object, unsigned comment_num);
-
- /** Creates a Vorbis comment entry from NUL-terminated name and value strings.
- *
- * On return, the filled-in \a entry->entry pointer will point to malloc()ed
- * memory and shall be owned by the caller. For convenience the entry will
- * have a terminating NUL.
- *
- * \param entry A pointer to a Vorbis comment entry. The entry's
- * \c entry pointer should not point to allocated
- * memory as it will be overwritten.
- * \param field_name The field name in ASCII, \c NUL terminated.
- * \param field_value The field value in UTF-8, \c NUL terminated.
- * \assert
- * \code entry != NULL \endcode
- * \code field_name != NULL \endcode
- * \code field_value != NULL \endcode
- * \retval FLAC__bool
- * \c false if malloc() fails, or if \a field_name or \a field_value does
- * not comply with the Vorbis comment specification, else \c true.
- */
- FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_entry_from_name_value_pair(FLAC__StreamMetadata_VorbisComment_Entry *entry, const char *field_name, const char *field_value);
-
- /** Splits a Vorbis comment entry into NUL-terminated name and value strings.
- *
- * The returned pointers to name and value will be allocated by malloc()
- * and shall be owned by the caller.
- *
- * \param entry An existing Vorbis comment entry.
- * \param field_name The address of where the returned pointer to the
- * field name will be stored.
- * \param field_value The address of where the returned pointer to the
- * field value will be stored.
- * \assert
- * \code (entry.entry != NULL && entry.length > 0) \endcode
- * \code memchr(entry.entry, '=', entry.length) != NULL \endcode
- * \code field_name != NULL \endcode
- * \code field_value != NULL \endcode
- * \retval FLAC__bool
- * \c false if memory allocation fails or \a entry does not comply with the
- * Vorbis comment specification, else \c true.
- */
- FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_entry_to_name_value_pair(const FLAC__StreamMetadata_VorbisComment_Entry entry, char **field_name, char **field_value);
-
- /** Check if the given Vorbis comment entry's field name matches the given
- * field name.
- *
- * \param entry An existing Vorbis comment entry.
- * \param field_name The field name to check.
- * \param field_name_length The length of \a field_name, not including the
- * terminating \c NUL.
- * \assert
- * \code (entry.entry != NULL && entry.length > 0) \endcode
- * \retval FLAC__bool
- * \c true if the field names match, else \c false
- */
- FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_entry_matches(const FLAC__StreamMetadata_VorbisComment_Entry entry, const char *field_name, unsigned field_name_length);
-
- /** Find a Vorbis comment with the given field name.
- *
- * The search begins at entry number \a offset; use an offset of 0 to
- * search from the beginning of the comment array.
- *
- * \param object A pointer to an existing VORBIS_COMMENT object.
- * \param offset The offset into the comment array from where to start
- * the search.
- * \param field_name The field name of the comment to find.
- * \assert
- * \code object != NULL \endcode
- * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode
- * \code field_name != NULL \endcode
- * \retval int
- * The offset in the comment array of the first comment whose field
- * name matches \a field_name, or \c -1 if no match was found.
- */
- FLAC_API int FLAC__metadata_object_vorbiscomment_find_entry_from(const FLAC__StreamMetadata *object, unsigned offset, const char *field_name);
-
- /** Remove first Vorbis comment matching the given field name.
- *
- * \param object A pointer to an existing VORBIS_COMMENT object.
- * \param field_name The field name of comment to delete.
- * \assert
- * \code object != NULL \endcode
- * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode
- * \retval int
- * \c -1 for memory allocation error, \c 0 for no matching entries,
- * \c 1 for one matching entry deleted.
- */
- FLAC_API int FLAC__metadata_object_vorbiscomment_remove_entry_matching(FLAC__StreamMetadata *object, const char *field_name);
-
- /** Remove all Vorbis comments matching the given field name.
- *
- * \param object A pointer to an existing VORBIS_COMMENT object.
- * \param field_name The field name of comments to delete.
- * \assert
- * \code object != NULL \endcode
- * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode
- * \retval int
- * \c -1 for memory allocation error, \c 0 for no matching entries,
- * else the number of matching entries deleted.
- */
- FLAC_API int FLAC__metadata_object_vorbiscomment_remove_entries_matching(FLAC__StreamMetadata *object, const char *field_name);
-
- /** Create a new CUESHEET track instance.
- *
- * The object will be "empty"; i.e. values and data pointers will be \c 0.
- *
- * \retval FLAC__StreamMetadata_CueSheet_Track*
- * \c NULL if there was an error allocating memory, else the new instance.
- */
- FLAC_API FLAC__StreamMetadata_CueSheet_Track *FLAC__metadata_object_cuesheet_track_new(void);
-
- /** Create a copy of an existing CUESHEET track object.
- *
- * The copy is a "deep" copy, i.e. dynamically allocated data within the
- * object is also copied. The caller takes ownership of the new object and
- * is responsible for freeing it with
- * FLAC__metadata_object_cuesheet_track_delete().
- *
- * \param object Pointer to object to copy.
- * \assert
- * \code object != NULL \endcode
- * \retval FLAC__StreamMetadata_CueSheet_Track*
- * \c NULL if there was an error allocating memory, else the new instance.
- */
- FLAC_API FLAC__StreamMetadata_CueSheet_Track *FLAC__metadata_object_cuesheet_track_clone(const FLAC__StreamMetadata_CueSheet_Track *object);
-
- /** Delete a CUESHEET track object
- *
- * \param object A pointer to an existing CUESHEET track object.
- * \assert
- * \code object != NULL \endcode
- */
- FLAC_API void FLAC__metadata_object_cuesheet_track_delete(FLAC__StreamMetadata_CueSheet_Track *object);
-
- /** Resize a track's index point array.
- *
- * If the size shrinks, elements will truncated; if it grows, new blank
- * indices will be added to the end.
- *
- * \param object A pointer to an existing CUESHEET object.
- * \param track_num The index of the track to modify. NOTE: this is not
- * necessarily the same as the track's \a number field.
- * \param new_num_indices The desired length of the array; may be \c 0.
- * \assert
- * \code object != NULL \endcode
- * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode
- * \code object->data.cue_sheet.num_tracks > track_num \endcode
- * \code (object->data.cue_sheet.tracks[track_num].indices == NULL && object->data.cue_sheet.tracks[track_num].num_indices == 0) ||
- * (object->data.cue_sheet.tracks[track_num].indices != NULL && object->data.cue_sheet.tracks[track_num].num_indices > 0) \endcode
- * \retval FLAC__bool
- * \c false if memory allocation error, else \c true.
- */
- FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_track_resize_indices(FLAC__StreamMetadata *object, unsigned track_num, unsigned new_num_indices);
-
- /** Insert an index point in a CUESHEET track at the given index.
- *
- * \param object A pointer to an existing CUESHEET object.
- * \param track_num The index of the track to modify. NOTE: this is not
- * necessarily the same as the track's \a number field.
- * \param index_num The index into the track's index array at which to
- * insert the index point. NOTE: this is not necessarily
- * the same as the index point's \a number field. The
- * indices at and after \a index_num move right one
- * position. To append an index point to the end, set
- * \a index_num to
- * \c object->data.cue_sheet.tracks[track_num].num_indices .
- * \param index The index point to insert.
- * \assert
- * \code object != NULL \endcode
- * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode
- * \code object->data.cue_sheet.num_tracks > track_num \endcode
- * \code object->data.cue_sheet.tracks[track_num].num_indices >= index_num \endcode
- * \retval FLAC__bool
- * \c false if realloc() fails, else \c true.
- */
- FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_track_insert_index(FLAC__StreamMetadata *object, unsigned track_num, unsigned index_num, FLAC__StreamMetadata_CueSheet_Index index);
-
- /** Insert a blank index point in a CUESHEET track at the given index.
- *
- * A blank index point is one in which all field values are zero.
- *
- * \param object A pointer to an existing CUESHEET object.
- * \param track_num The index of the track to modify. NOTE: this is not
- * necessarily the same as the track's \a number field.
- * \param index_num The index into the track's index array at which to
- * insert the index point. NOTE: this is not necessarily
- * the same as the index point's \a number field. The
- * indices at and after \a index_num move right one
- * position. To append an index point to the end, set
- * \a index_num to
- * \c object->data.cue_sheet.tracks[track_num].num_indices .
- * \assert
- * \code object != NULL \endcode
- * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode
- * \code object->data.cue_sheet.num_tracks > track_num \endcode
- * \code object->data.cue_sheet.tracks[track_num].num_indices >= index_num \endcode
- * \retval FLAC__bool
- * \c false if realloc() fails, else \c true.
- */
- FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_track_insert_blank_index(FLAC__StreamMetadata *object, unsigned track_num, unsigned index_num);
-
- /** Delete an index point in a CUESHEET track at the given index.
- *
- * \param object A pointer to an existing CUESHEET object.
- * \param track_num The index into the track array of the track to
- * modify. NOTE: this is not necessarily the same
- * as the track's \a number field.
- * \param index_num The index into the track's index array of the index
- * to delete. NOTE: this is not necessarily the same
- * as the index's \a number field.
- * \assert
- * \code object != NULL \endcode
- * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode
- * \code object->data.cue_sheet.num_tracks > track_num \endcode
- * \code object->data.cue_sheet.tracks[track_num].num_indices > index_num \endcode
- * \retval FLAC__bool
- * \c false if realloc() fails, else \c true.
- */
- FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_track_delete_index(FLAC__StreamMetadata *object, unsigned track_num, unsigned index_num);
-
- /** Resize the track array.
- *
- * If the size shrinks, elements will truncated; if it grows, new blank
- * tracks will be added to the end.
- *
- * \param object A pointer to an existing CUESHEET object.
- * \param new_num_tracks The desired length of the array; may be \c 0.
- * \assert
- * \code object != NULL \endcode
- * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode
- * \code (object->data.cue_sheet.tracks == NULL && object->data.cue_sheet.num_tracks == 0) ||
- * (object->data.cue_sheet.tracks != NULL && object->data.cue_sheet.num_tracks > 0) \endcode
- * \retval FLAC__bool
- * \c false if memory allocation error, else \c true.
- */
- FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_resize_tracks(FLAC__StreamMetadata *object, unsigned new_num_tracks);
-
- /** Sets a track in a CUESHEET block.
- *
- * If \a copy is \c true, a copy of the track is stored; otherwise, the object
- * takes ownership of the \a track pointer.
- *
- * \param object A pointer to an existing CUESHEET object.
- * \param track_num Index into track array to set. NOTE: this is not
- * necessarily the same as the track's \a number field.
- * \param track The track to set the track to. You may safely pass in
- * a const pointer if \a copy is \c true.
- * \param copy See above.
- * \assert
- * \code object != NULL \endcode
- * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode
- * \code track_num < object->data.cue_sheet.num_tracks \endcode
- * \code (track->indices != NULL && track->num_indices > 0) ||
- * (track->indices == NULL && track->num_indices == 0)
- * \retval FLAC__bool
- * \c false if \a copy is \c true and malloc() fails, else \c true.
- */
- FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_set_track(FLAC__StreamMetadata *object, unsigned track_num, FLAC__StreamMetadata_CueSheet_Track *track, FLAC__bool copy);
-
- /** Insert a track in a CUESHEET block at the given index.
- *
- * If \a copy is \c true, a copy of the track is stored; otherwise, the object
- * takes ownership of the \a track pointer.
- *
- * \param object A pointer to an existing CUESHEET object.
- * \param track_num The index at which to insert the track. NOTE: this
- * is not necessarily the same as the track's \a number
- * field. The tracks at and after \a track_num move right
- * one position. To append a track to the end, set
- * \a track_num to \c object->data.cue_sheet.num_tracks .
- * \param track The track to insert. You may safely pass in a const
- * pointer if \a copy is \c true.
- * \param copy See above.
- * \assert
- * \code object != NULL \endcode
- * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode
- * \code object->data.cue_sheet.num_tracks >= track_num \endcode
- * \retval FLAC__bool
- * \c false if \a copy is \c true and malloc() fails, else \c true.
- */
- FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_insert_track(FLAC__StreamMetadata *object, unsigned track_num, FLAC__StreamMetadata_CueSheet_Track *track, FLAC__bool copy);
-
- /** Insert a blank track in a CUESHEET block at the given index.
- *
- * A blank track is one in which all field values are zero.
- *
- * \param object A pointer to an existing CUESHEET object.
- * \param track_num The index at which to insert the track. NOTE: this
- * is not necessarily the same as the track's \a number
- * field. The tracks at and after \a track_num move right
- * one position. To append a track to the end, set
- * \a track_num to \c object->data.cue_sheet.num_tracks .
- * \assert
- * \code object != NULL \endcode
- * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode
- * \code object->data.cue_sheet.num_tracks >= track_num \endcode
- * \retval FLAC__bool
- * \c false if \a copy is \c true and malloc() fails, else \c true.
- */
- FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_insert_blank_track(FLAC__StreamMetadata *object, unsigned track_num);
-
- /** Delete a track in a CUESHEET block at the given index.
- *
- * \param object A pointer to an existing CUESHEET object.
- * \param track_num The index into the track array of the track to
- * delete. NOTE: this is not necessarily the same
- * as the track's \a number field.
- * \assert
- * \code object != NULL \endcode
- * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode
- * \code object->data.cue_sheet.num_tracks > track_num \endcode
- * \retval FLAC__bool
- * \c false if realloc() fails, else \c true.
- */
- FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_delete_track(FLAC__StreamMetadata *object, unsigned track_num);
-
- /** Check a cue sheet to see if it conforms to the FLAC specification.
- * See the format specification for limits on the contents of the
- * cue sheet.
- *
- * \param object A pointer to an existing CUESHEET object.
- * \param check_cd_da_subset If \c true, check CUESHEET against more
- * stringent requirements for a CD-DA (audio) disc.
- * \param violation Address of a pointer to a string. If there is a
- * violation, a pointer to a string explanation of the
- * violation will be returned here. \a violation may be
- * \c NULL if you don't need the returned string. Do not
- * free the returned string; it will always point to static
- * data.
- * \assert
- * \code object != NULL \endcode
- * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode
- * \retval FLAC__bool
- * \c false if cue sheet is illegal, else \c true.
- */
- FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_is_legal(const FLAC__StreamMetadata *object, FLAC__bool check_cd_da_subset, const char **violation);
-
- /** Calculate and return the CDDB/freedb ID for a cue sheet. The function
- * assumes the cue sheet corresponds to a CD; the result is undefined
- * if the cuesheet's is_cd bit is not set.
- *
- * \param object A pointer to an existing CUESHEET object.
- * \assert
- * \code object != NULL \endcode
- * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode
- * \retval FLAC__uint32
- * The unsigned integer representation of the CDDB/freedb ID
- */
- FLAC_API FLAC__uint32 FLAC__metadata_object_cuesheet_calculate_cddb_id(const FLAC__StreamMetadata *object);
-
- /** Sets the MIME type of a PICTURE block.
- *
- * If \a copy is \c true, a copy of the string is stored; otherwise, the object
- * takes ownership of the pointer. The existing string will be freed if this
- * function is successful, otherwise the original string will remain if \a copy
- * is \c true and malloc() fails.
- *
- * \note It is safe to pass a const pointer to \a mime_type if \a copy is \c true.
- *
- * \param object A pointer to an existing PICTURE object.
- * \param mime_type A pointer to the MIME type string. The string must be
- * ASCII characters 0x20-0x7e, NUL-terminated. No validation
- * is done.
- * \param copy See above.
- * \assert
- * \code object != NULL \endcode
- * \code object->type == FLAC__METADATA_TYPE_PICTURE \endcode
- * \code (mime_type != NULL) \endcode
- * \retval FLAC__bool
- * \c false if \a copy is \c true and malloc() fails, else \c true.
- */
- FLAC_API FLAC__bool FLAC__metadata_object_picture_set_mime_type(FLAC__StreamMetadata *object, char *mime_type, FLAC__bool copy);
-
- /** Sets the description of a PICTURE block.
- *
- * If \a copy is \c true, a copy of the string is stored; otherwise, the object
- * takes ownership of the pointer. The existing string will be freed if this
- * function is successful, otherwise the original string will remain if \a copy
- * is \c true and malloc() fails.
- *
- * \note It is safe to pass a const pointer to \a description if \a copy is \c true.
- *
- * \param object A pointer to an existing PICTURE object.
- * \param description A pointer to the description string. The string must be
- * valid UTF-8, NUL-terminated. No validation is done.
- * \param copy See above.
- * \assert
- * \code object != NULL \endcode
- * \code object->type == FLAC__METADATA_TYPE_PICTURE \endcode
- * \code (description != NULL) \endcode
- * \retval FLAC__bool
- * \c false if \a copy is \c true and malloc() fails, else \c true.
- */
- FLAC_API FLAC__bool FLAC__metadata_object_picture_set_description(FLAC__StreamMetadata *object, FLAC__byte *description, FLAC__bool copy);
-
- /** Sets the picture data of a PICTURE block.
- *
- * If \a copy is \c true, a copy of the data is stored; otherwise, the object
- * takes ownership of the pointer. Also sets the \a data_length field of the
- * metadata object to what is passed in as the \a length parameter. The
- * existing data will be freed if this function is successful, otherwise the
- * original data and data_length will remain if \a copy is \c true and
- * malloc() fails.
- *
- * \note It is safe to pass a const pointer to \a data if \a copy is \c true.
- *
- * \param object A pointer to an existing PICTURE object.
- * \param data A pointer to the data to set.
- * \param length The length of \a data in bytes.
- * \param copy See above.
- * \assert
- * \code object != NULL \endcode
- * \code object->type == FLAC__METADATA_TYPE_PICTURE \endcode
- * \code (data != NULL && length > 0) ||
- * (data == NULL && length == 0 && copy == false) \endcode
- * \retval FLAC__bool
- * \c false if \a copy is \c true and malloc() fails, else \c true.
- */
- FLAC_API FLAC__bool FLAC__metadata_object_picture_set_data(FLAC__StreamMetadata *object, FLAC__byte *data, FLAC__uint32 length, FLAC__bool copy);
-
- /** Check a PICTURE block to see if it conforms to the FLAC specification.
- * See the format specification for limits on the contents of the
- * PICTURE block.
- *
- * \param object A pointer to existing PICTURE block to be checked.
- * \param violation Address of a pointer to a string. If there is a
- * violation, a pointer to a string explanation of the
- * violation will be returned here. \a violation may be
- * \c NULL if you don't need the returned string. Do not
- * free the returned string; it will always point to static
- * data.
- * \assert
- * \code object != NULL \endcode
- * \code object->type == FLAC__METADATA_TYPE_PICTURE \endcode
- * \retval FLAC__bool
- * \c false if PICTURE block is illegal, else \c true.
- */
- FLAC_API FLAC__bool FLAC__metadata_object_picture_is_legal(const FLAC__StreamMetadata *object, const char **violation);
-
- /* \} */
-
- #ifdef __cplusplus
- }
- #endif
-
- #endif
- /********* End of inlined file: metadata.h *********/
-
- /********* Start of inlined file: stream_decoder.h *********/
- #ifndef FLAC__STREAM_DECODER_H
- #define FLAC__STREAM_DECODER_H
-
- #include <stdio.h> /* for FILE */
-
- #ifdef __cplusplus
- extern "C" {
- #endif
-
- /** \file include/FLAC/stream_decoder.h
- *
- * \brief
- * This module contains the functions which implement the stream
- * decoder.
- *
- * See the detailed documentation in the
- * \link flac_stream_decoder stream decoder \endlink module.
- */
-
- /** \defgroup flac_decoder FLAC/ \*_decoder.h: decoder interfaces
- * \ingroup flac
- *
- * \brief
- * This module describes the decoder layers provided by libFLAC.
- *
- * The stream decoder can be used to decode complete streams either from
- * the client via callbacks, or directly from a file, depending on how
- * it is initialized. When decoding via callbacks, the client provides
- * callbacks for reading FLAC data and writing decoded samples, and
- * handling metadata and errors. If the client also supplies seek-related
- * callback, the decoder function for sample-accurate seeking within the
- * FLAC input is also available. When decoding from a file, the client
- * needs only supply a filename or open \c FILE* and write/metadata/error
- * callbacks; the rest of the callbacks are supplied internally. For more
- * info see the \link flac_stream_decoder stream decoder \endlink module.
- */
-
- /** \defgroup flac_stream_decoder FLAC/stream_decoder.h: stream decoder interface
- * \ingroup flac_decoder
- *
- * \brief
- * This module contains the functions which implement the stream
- * decoder.
- *
- * The stream decoder can decode native FLAC, and optionally Ogg FLAC
- * (check FLAC_API_SUPPORTS_OGG_FLAC) streams and files.
- *
- * The basic usage of this decoder is as follows:
- * - The program creates an instance of a decoder using
- * FLAC__stream_decoder_new().
- * - The program overrides the default settings using
- * FLAC__stream_decoder_set_*() functions.
- * - The program initializes the instance to validate the settings and
- * prepare for decoding using
- * - FLAC__stream_decoder_init_stream() or FLAC__stream_decoder_init_FILE()
- * or FLAC__stream_decoder_init_file() for native FLAC,
- * - FLAC__stream_decoder_init_ogg_stream() or FLAC__stream_decoder_init_ogg_FILE()
- * or FLAC__stream_decoder_init_ogg_file() for Ogg FLAC
- * - The program calls the FLAC__stream_decoder_process_*() functions
- * to decode data, which subsequently calls the callbacks.
- * - The program finishes the decoding with FLAC__stream_decoder_finish(),
- * which flushes the input and output and resets the decoder to the
- * uninitialized state.
- * - The instance may be used again or deleted with
- * FLAC__stream_decoder_delete().
- *
- * In more detail, the program will create a new instance by calling
- * FLAC__stream_decoder_new(), then call FLAC__stream_decoder_set_*()
- * functions to override the default decoder options, and call
- * one of the FLAC__stream_decoder_init_*() functions.
- *
- * There are three initialization functions for native FLAC, one for
- * setting up the decoder to decode FLAC data from the client via
- * callbacks, and two for decoding directly from a FLAC file.
- *
- * For decoding via callbacks, use FLAC__stream_decoder_init_stream().
- * You must also supply several callbacks for handling I/O. Some (like
- * seeking) are optional, depending on the capabilities of the input.
- *
- * For decoding directly from a file, use FLAC__stream_decoder_init_FILE()
- * or FLAC__stream_decoder_init_file(). Then you must only supply an open
- * \c FILE* or filename and fewer callbacks; the decoder will handle
- * the other callbacks internally.
- *
- * There are three similarly-named init functions for decoding from Ogg
- * FLAC streams. Check \c FLAC_API_SUPPORTS_OGG_FLAC to find out if the
- * library has been built with Ogg support.
- *
- * Once the decoder is initialized, your program will call one of several
- * functions to start the decoding process:
- *
- * - FLAC__stream_decoder_process_single() - Tells the decoder to process at
- * most one metadata block or audio frame and return, calling either the
- * metadata callback or write callback, respectively, once. If the decoder
- * loses sync it will return with only the error callback being called.
- * - FLAC__stream_decoder_process_until_end_of_metadata() - Tells the decoder
- * to process the stream from the current location and stop upon reaching
- * the first audio frame. The client will get one metadata, write, or error
- * callback per metadata block, audio frame, or sync error, respectively.
- * - FLAC__stream_decoder_process_until_end_of_stream() - Tells the decoder
- * to process the stream from the current location until the read callback
- * returns FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM or
- * FLAC__STREAM_DECODER_READ_STATUS_ABORT. The client will get one metadata,
- * write, or error callback per metadata block, audio frame, or sync error,
- * respectively.
- *
- * When the decoder has finished decoding (normally or through an abort),
- * the instance is finished by calling FLAC__stream_decoder_finish(), which
- * ensures the decoder is in the correct state and frees memory. Then the
- * instance may be deleted with FLAC__stream_decoder_delete() or initialized
- * again to decode another stream.
- *
- * Seeking is exposed through the FLAC__stream_decoder_seek_absolute() method.
- * At any point after the stream decoder has been initialized, the client can
- * call this function to seek to an exact sample within the stream.
- * Subsequently, the first time the write callback is called it will be
- * passed a (possibly partial) block starting at that sample.
- *
- * If the client cannot seek via the callback interface provided, but still
- * has another way of seeking, it can flush the decoder using
- * FLAC__stream_decoder_flush() and start feeding data from the new position
- * through the read callback.
- *
- * The stream decoder also provides MD5 signature checking. If this is
- * turned on before initialization, FLAC__stream_decoder_finish() will
- * report when the decoded MD5 signature does not match the one stored
- * in the STREAMINFO block. MD5 checking is automatically turned off
- * (until the next FLAC__stream_decoder_reset()) if there is no signature
- * in the STREAMINFO block or when a seek is attempted.
- *
- * The FLAC__stream_decoder_set_metadata_*() functions deserve special
- * attention. By default, the decoder only calls the metadata_callback for
- * the STREAMINFO block. These functions allow you to tell the decoder
- * explicitly which blocks to parse and return via the metadata_callback
- * and/or which to skip. Use a FLAC__stream_decoder_set_metadata_respond_all(),
- * FLAC__stream_decoder_set_metadata_ignore() ... or FLAC__stream_decoder_set_metadata_ignore_all(),
- * FLAC__stream_decoder_set_metadata_respond() ... sequence to exactly specify
- * which blocks to return. Remember that metadata blocks can potentially
- * be big (for example, cover art) so filtering out the ones you don't
- * use can reduce the memory requirements of the decoder. Also note the
- * special forms FLAC__stream_decoder_set_metadata_respond_application(id)
- * and FLAC__stream_decoder_set_metadata_ignore_application(id) for
- * filtering APPLICATION blocks based on the application ID.
- *
- * STREAMINFO and SEEKTABLE blocks are always parsed and used internally, but
- * they still can legally be filtered from the metadata_callback.
- *
- * \note
- * The "set" functions may only be called when the decoder is in the
- * state FLAC__STREAM_DECODER_UNINITIALIZED, i.e. after
- * FLAC__stream_decoder_new() or FLAC__stream_decoder_finish(), but
- * before FLAC__stream_decoder_init_*(). If this is the case they will
- * return \c true, otherwise \c false.
- *
- * \note
- * FLAC__stream_decoder_finish() resets all settings to the constructor
- * defaults, including the callbacks.
- *
- * \{
- */
-
- /** State values for a FLAC__StreamDecoder
- *
- * The decoder's state can be obtained by calling FLAC__stream_decoder_get_state().
- */
- typedef enum {
-
- FLAC__STREAM_DECODER_SEARCH_FOR_METADATA = 0,
- /**< The decoder is ready to search for metadata. */
-
- FLAC__STREAM_DECODER_READ_METADATA,
- /**< The decoder is ready to or is in the process of reading metadata. */
-
- FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC,
- /**< The decoder is ready to or is in the process of searching for the
- * frame sync code.
- */
-
- FLAC__STREAM_DECODER_READ_FRAME,
- /**< The decoder is ready to or is in the process of reading a frame. */
-
- FLAC__STREAM_DECODER_END_OF_STREAM,
- /**< The decoder has reached the end of the stream. */
-
- FLAC__STREAM_DECODER_OGG_ERROR,
- /**< An error occurred in the underlying Ogg layer. */
-
- FLAC__STREAM_DECODER_SEEK_ERROR,
- /**< An error occurred while seeking. The decoder must be flushed
- * with FLAC__stream_decoder_flush() or reset with
- * FLAC__stream_decoder_reset() before decoding can continue.
- */
-
- FLAC__STREAM_DECODER_ABORTED,
- /**< The decoder was aborted by the read callback. */
-
- FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR,
- /**< An error occurred allocating memory. The decoder is in an invalid
- * state and can no longer be used.
- */
-
- FLAC__STREAM_DECODER_UNINITIALIZED
- /**< The decoder is in the uninitialized state; one of the
- * FLAC__stream_decoder_init_*() functions must be called before samples
- * can be processed.
- */
-
- } FLAC__StreamDecoderState;
-
- /** Maps a FLAC__StreamDecoderState to a C string.
- *
- * Using a FLAC__StreamDecoderState as the index to this array
- * will give the string equivalent. The contents should not be modified.
- */
- extern FLAC_API const char * const FLAC__StreamDecoderStateString[];
-
- /** Possible return values for the FLAC__stream_decoder_init_*() functions.
- */
- typedef enum {
-
- FLAC__STREAM_DECODER_INIT_STATUS_OK = 0,
- /**< Initialization was successful. */
-
- FLAC__STREAM_DECODER_INIT_STATUS_UNSUPPORTED_CONTAINER,
- /**< The library was not compiled with support for the given container
- * format.
- */
-
- FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS,
- /**< A required callback was not supplied. */
-
- FLAC__STREAM_DECODER_INIT_STATUS_MEMORY_ALLOCATION_ERROR,
- /**< An error occurred allocating memory. */
-
- FLAC__STREAM_DECODER_INIT_STATUS_ERROR_OPENING_FILE,
- /**< fopen() failed in FLAC__stream_decoder_init_file() or
- * FLAC__stream_decoder_init_ogg_file(). */
-
- FLAC__STREAM_DECODER_INIT_STATUS_ALREADY_INITIALIZED
- /**< FLAC__stream_decoder_init_*() was called when the decoder was
- * already initialized, usually because
- * FLAC__stream_decoder_finish() was not called.
- */
-
- } FLAC__StreamDecoderInitStatus;
-
- /** Maps a FLAC__StreamDecoderInitStatus to a C string.
- *
- * Using a FLAC__StreamDecoderInitStatus as the index to this array
- * will give the string equivalent. The contents should not be modified.
- */
- extern FLAC_API const char * const FLAC__StreamDecoderInitStatusString[];
-
- /** Return values for the FLAC__StreamDecoder read callback.
- */
- typedef enum {
-
- FLAC__STREAM_DECODER_READ_STATUS_CONTINUE,
- /**< The read was OK and decoding can continue. */
-
- FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM,
- /**< The read was attempted while at the end of the stream. Note that
- * the client must only return this value when the read callback was
- * called when already at the end of the stream. Otherwise, if the read
- * itself moves to the end of the stream, the client should still return
- * the data and \c FLAC__STREAM_DECODER_READ_STATUS_CONTINUE, and then on
- * the next read callback it should return
- * \c FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM with a byte count
- * of \c 0.
- */
-
- FLAC__STREAM_DECODER_READ_STATUS_ABORT
- /**< An unrecoverable error occurred. The decoder will return from the process call. */
-
- } FLAC__StreamDecoderReadStatus;
-
- /** Maps a FLAC__StreamDecoderReadStatus to a C string.
- *
- * Using a FLAC__StreamDecoderReadStatus as the index to this array
- * will give the string equivalent. The contents should not be modified.
- */
- extern FLAC_API const char * const FLAC__StreamDecoderReadStatusString[];
-
- /** Return values for the FLAC__StreamDecoder seek callback.
- */
- typedef enum {
-
- FLAC__STREAM_DECODER_SEEK_STATUS_OK,
- /**< The seek was OK and decoding can continue. */
-
- FLAC__STREAM_DECODER_SEEK_STATUS_ERROR,
- /**< An unrecoverable error occurred. The decoder will return from the process call. */
-
- FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED
- /**< Client does not support seeking. */
-
- } FLAC__StreamDecoderSeekStatus;
-
- /** Maps a FLAC__StreamDecoderSeekStatus to a C string.
- *
- * Using a FLAC__StreamDecoderSeekStatus as the index to this array
- * will give the string equivalent. The contents should not be modified.
- */
- extern FLAC_API const char * const FLAC__StreamDecoderSeekStatusString[];
-
- /** Return values for the FLAC__StreamDecoder tell callback.
- */
- typedef enum {
-
- FLAC__STREAM_DECODER_TELL_STATUS_OK,
- /**< The tell was OK and decoding can continue. */
-
- FLAC__STREAM_DECODER_TELL_STATUS_ERROR,
- /**< An unrecoverable error occurred. The decoder will return from the process call. */
-
- FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED
- /**< Client does not support telling the position. */
-
- } FLAC__StreamDecoderTellStatus;
-
- /** Maps a FLAC__StreamDecoderTellStatus to a C string.
- *
- * Using a FLAC__StreamDecoderTellStatus as the index to this array
- * will give the string equivalent. The contents should not be modified.
- */
- extern FLAC_API const char * const FLAC__StreamDecoderTellStatusString[];
-
- /** Return values for the FLAC__StreamDecoder length callback.
- */
- typedef enum {
-
- FLAC__STREAM_DECODER_LENGTH_STATUS_OK,
- /**< The length call was OK and decoding can continue. */
-
- FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR,
- /**< An unrecoverable error occurred. The decoder will return from the process call. */
-
- FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED
- /**< Client does not support reporting the length. */
-
- } FLAC__StreamDecoderLengthStatus;
-
- /** Maps a FLAC__StreamDecoderLengthStatus to a C string.
- *
- * Using a FLAC__StreamDecoderLengthStatus as the index to this array
- * will give the string equivalent. The contents should not be modified.
- */
- extern FLAC_API const char * const FLAC__StreamDecoderLengthStatusString[];
-
- /** Return values for the FLAC__StreamDecoder write callback.
- */
- typedef enum {
-
- FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE,
- /**< The write was OK and decoding can continue. */
-
- FLAC__STREAM_DECODER_WRITE_STATUS_ABORT
- /**< An unrecoverable error occurred. The decoder will return from the process call. */
-
- } FLAC__StreamDecoderWriteStatus;
-
- /** Maps a FLAC__StreamDecoderWriteStatus to a C string.
- *
- * Using a FLAC__StreamDecoderWriteStatus as the index to this array
- * will give the string equivalent. The contents should not be modified.
- */
- extern FLAC_API const char * const FLAC__StreamDecoderWriteStatusString[];
-
- /** Possible values passed back to the FLAC__StreamDecoder error callback.
- * \c FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC is the generic catch-
- * all. The rest could be caused by bad sync (false synchronization on
- * data that is not the start of a frame) or corrupted data. The error
- * itself is the decoder's best guess at what happened assuming a correct
- * sync. For example \c FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER
- * could be caused by a correct sync on the start of a frame, but some
- * data in the frame header was corrupted. Or it could be the result of
- * syncing on a point the stream that looked like the starting of a frame
- * but was not. \c FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM
- * could be because the decoder encountered a valid frame made by a future
- * version of the encoder which it cannot parse, or because of a false
- * sync making it appear as though an encountered frame was generated by
- * a future encoder.
- */
- typedef enum {
-
- FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC,
- /**< An error in the stream caused the decoder to lose synchronization. */
-
- FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER,
- /**< The decoder encountered a corrupted frame header. */
-
- FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH,
- /**< The frame's data did not match the CRC in the footer. */
-
- FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM
- /**< The decoder encountered reserved fields in use in the stream. */
-
- } FLAC__StreamDecoderErrorStatus;
-
- /** Maps a FLAC__StreamDecoderErrorStatus to a C string.
- *
- * Using a FLAC__StreamDecoderErrorStatus as the index to this array
- * will give the string equivalent. The contents should not be modified.
- */
- extern FLAC_API const char * const FLAC__StreamDecoderErrorStatusString[];
-
- /***********************************************************************
- *
- * class FLAC__StreamDecoder
- *
- ***********************************************************************/
-
- struct FLAC__StreamDecoderProtected;
- struct FLAC__StreamDecoderPrivate;
- /** The opaque structure definition for the stream decoder type.
- * See the \link flac_stream_decoder stream decoder module \endlink
- * for a detailed description.
- */
- typedef struct {
- struct FLAC__StreamDecoderProtected *protected_; /* avoid the C++ keyword 'protected' */
- struct FLAC__StreamDecoderPrivate *private_; /* avoid the C++ keyword 'private' */
- } FLAC__StreamDecoder;
-
- /** Signature for the read callback.
- *
- * A function pointer matching this signature must be passed to
- * FLAC__stream_decoder_init*_stream(). The supplied function will be
- * called when the decoder needs more input data. The address of the
- * buffer to be filled is supplied, along with the number of bytes the
- * buffer can hold. The callback may choose to supply less data and
- * modify the byte count but must be careful not to overflow the buffer.
- * The callback then returns a status code chosen from
- * FLAC__StreamDecoderReadStatus.
- *
- * Here is an example of a read callback for stdio streams:
- * \code
- * FLAC__StreamDecoderReadStatus read_cb(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data)
- * {
- * FILE *file = ((MyClientData*)client_data)->file;
- * if(*bytes > 0) {
- * *bytes = fread(buffer, sizeof(FLAC__byte), *bytes, file);
- * if(ferror(file))
- * return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
- * else if(*bytes == 0)
- * return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
- * else
- * return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
- * }
- * else
- * return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
- * }
- * \endcode
- *
- * \note In general, FLAC__StreamDecoder functions which change the
- * state should not be called on the \a decoder while in the callback.
- *
- * \param decoder The decoder instance calling the callback.
- * \param buffer A pointer to a location for the callee to store
- * data to be decoded.
- * \param bytes A pointer to the size of the buffer. On entry
- * to the callback, it contains the maximum number
- * of bytes that may be stored in \a buffer. The
- * callee must set it to the actual number of bytes
- * stored (0 in case of error or end-of-stream) before
- * returning.
- * \param client_data The callee's client data set through
- * FLAC__stream_decoder_init_*().
- * \retval FLAC__StreamDecoderReadStatus
- * The callee's return status. Note that the callback should return
- * \c FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM if and only if
- * zero bytes were read and there is no more data to be read.
- */
- typedef FLAC__StreamDecoderReadStatus (*FLAC__StreamDecoderReadCallback)(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data);
-
- /** Signature for the seek callback.
- *
- * A function pointer matching this signature may be passed to
- * FLAC__stream_decoder_init*_stream(). The supplied function will be
- * called when the decoder needs to seek the input stream. The decoder
- * will pass the absolute byte offset to seek to, 0 meaning the
- * beginning of the stream.
- *
- * Here is an example of a seek callback for stdio streams:
- * \code
- * FLAC__StreamDecoderSeekStatus seek_cb(const FLAC__StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data)
- * {
- * FILE *file = ((MyClientData*)client_data)->file;
- * if(file == stdin)
- * return FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED;
- * else if(fseeko(file, (off_t)absolute_byte_offset, SEEK_SET) < 0)
- * return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR;
- * else
- * return FLAC__STREAM_DECODER_SEEK_STATUS_OK;
- * }
- * \endcode
- *
- * \note In general, FLAC__StreamDecoder functions which change the
- * state should not be called on the \a decoder while in the callback.
- *
- * \param decoder The decoder instance calling the callback.
- * \param absolute_byte_offset The offset from the beginning of the stream
- * to seek to.
- * \param client_data The callee's client data set through
- * FLAC__stream_decoder_init_*().
- * \retval FLAC__StreamDecoderSeekStatus
- * The callee's return status.
- */
- typedef FLAC__StreamDecoderSeekStatus (*FLAC__StreamDecoderSeekCallback)(const FLAC__StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data);
-
- /** Signature for the tell callback.
- *
- * A function pointer matching this signature may be passed to
- * FLAC__stream_decoder_init*_stream(). The supplied function will be
- * called when the decoder wants to know the current position of the
- * stream. The callback should return the byte offset from the
- * beginning of the stream.
- *
- * Here is an example of a tell callback for stdio streams:
- * \code
- * FLAC__StreamDecoderTellStatus tell_cb(const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
- * {
- * FILE *file = ((MyClientData*)client_data)->file;
- * off_t pos;
- * if(file == stdin)
- * return FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED;
- * else if((pos = ftello(file)) < 0)
- * return FLAC__STREAM_DECODER_TELL_STATUS_ERROR;
- * else {
- * *absolute_byte_offset = (FLAC__uint64)pos;
- * return FLAC__STREAM_DECODER_TELL_STATUS_OK;
- * }
- * }
- * \endcode
- *
- * \note In general, FLAC__StreamDecoder functions which change the
- * state should not be called on the \a decoder while in the callback.
- *
- * \param decoder The decoder instance calling the callback.
- * \param absolute_byte_offset A pointer to storage for the current offset
- * from the beginning of the stream.
- * \param client_data The callee's client data set through
- * FLAC__stream_decoder_init_*().
- * \retval FLAC__StreamDecoderTellStatus
- * The callee's return status.
- */
- typedef FLAC__StreamDecoderTellStatus (*FLAC__StreamDecoderTellCallback)(const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data);
-
- /** Signature for the length callback.
- *
- * A function pointer matching this signature may be passed to
- * FLAC__stream_decoder_init*_stream(). The supplied function will be
- * called when the decoder wants to know the total length of the stream
- * in bytes.
- *
- * Here is an example of a length callback for stdio streams:
- * \code
- * FLAC__StreamDecoderLengthStatus length_cb(const FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data)
- * {
- * FILE *file = ((MyClientData*)client_data)->file;
- * struct stat filestats;
- *
- * if(file == stdin)
- * return FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED;
- * else if(fstat(fileno(file), &filestats) != 0)
- * return FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR;
- * else {
- * *stream_length = (FLAC__uint64)filestats.st_size;
- * return FLAC__STREAM_DECODER_LENGTH_STATUS_OK;
- * }
- * }
- * \endcode
- *
- * \note In general, FLAC__StreamDecoder functions which change the
- * state should not be called on the \a decoder while in the callback.
- *
- * \param decoder The decoder instance calling the callback.
- * \param stream_length A pointer to storage for the length of the stream
- * in bytes.
- * \param client_data The callee's client data set through
- * FLAC__stream_decoder_init_*().
- * \retval FLAC__StreamDecoderLengthStatus
- * The callee's return status.
- */
- typedef FLAC__StreamDecoderLengthStatus (*FLAC__StreamDecoderLengthCallback)(const FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data);
-
- /** Signature for the EOF callback.
- *
- * A function pointer matching this signature may be passed to
- * FLAC__stream_decoder_init*_stream(). The supplied function will be
- * called when the decoder needs to know if the end of the stream has
- * been reached.
- *
- * Here is an example of a EOF callback for stdio streams:
- * FLAC__bool eof_cb(const FLAC__StreamDecoder *decoder, void *client_data)
- * \code
- * {
- * FILE *file = ((MyClientData*)client_data)->file;
- * return feof(file)? true : false;
- * }
- * \endcode
- *
- * \note In general, FLAC__StreamDecoder functions which change the
- * state should not be called on the \a decoder while in the callback.
- *
- * \param decoder The decoder instance calling the callback.
- * \param client_data The callee's client data set through
- * FLAC__stream_decoder_init_*().
- * \retval FLAC__bool
- * \c true if the currently at the end of the stream, else \c false.
- */
- typedef FLAC__bool (*FLAC__StreamDecoderEofCallback)(const FLAC__StreamDecoder *decoder, void *client_data);
-
- /** Signature for the write callback.
- *
- * A function pointer matching this signature must be passed to one of
- * the FLAC__stream_decoder_init_*() functions.
- * The supplied function will be called when the decoder has decoded a
- * single audio frame. The decoder will pass the frame metadata as well
- * as an array of pointers (one for each channel) pointing to the
- * decoded audio.
- *
- * \note In general, FLAC__StreamDecoder functions which change the
- * state should not be called on the \a decoder while in the callback.
- *
- * \param decoder The decoder instance calling the callback.
- * \param frame The description of the decoded frame. See
- * FLAC__Frame.
- * \param buffer An array of pointers to decoded channels of data.
- * Each pointer will point to an array of signed
- * samples of length \a frame->header.blocksize.
- * Channels will be ordered according to the FLAC
- * specification; see the documentation for the
- * <A HREF="../format.html#frame_header">frame header</A>.
- * \param client_data The callee's client data set through
- * FLAC__stream_decoder_init_*().
- * \retval FLAC__StreamDecoderWriteStatus
- * The callee's return status.
- */
- typedef FLAC__StreamDecoderWriteStatus (*FLAC__StreamDecoderWriteCallback)(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data);
-
- /** Signature for the metadata callback.
- *
- * A function pointer matching this signature must be passed to one of
- * the FLAC__stream_decoder_init_*() functions.
- * The supplied function will be called when the decoder has decoded a
- * metadata block. In a valid FLAC file there will always be one
- * \c STREAMINFO block, followed by zero or more other metadata blocks.
- * These will be supplied by the decoder in the same order as they
- * appear in the stream and always before the first audio frame (i.e.
- * write callback). The metadata block that is passed in must not be
- * modified, and it doesn't live beyond the callback, so you should make
- * a copy of it with FLAC__metadata_object_clone() if you will need it
- * elsewhere. Since metadata blocks can potentially be large, by
- * default the decoder only calls the metadata callback for the
- * \c STREAMINFO block; you can instruct the decoder to pass or filter
- * other blocks with FLAC__stream_decoder_set_metadata_*() calls.
- *
- * \note In general, FLAC__StreamDecoder functions which change the
- * state should not be called on the \a decoder while in the callback.
- *
- * \param decoder The decoder instance calling the callback.
- * \param metadata The decoded metadata block.
- * \param client_data The callee's client data set through
- * FLAC__stream_decoder_init_*().
- */
- typedef void (*FLAC__StreamDecoderMetadataCallback)(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data);
-
- /** Signature for the error callback.
- *
- * A function pointer matching this signature must be passed to one of
- * the FLAC__stream_decoder_init_*() functions.
- * The supplied function will be called whenever an error occurs during
- * decoding.
- *
- * \note In general, FLAC__StreamDecoder functions which change the
- * state should not be called on the \a decoder while in the callback.
- *
- * \param decoder The decoder instance calling the callback.
- * \param status The error encountered by the decoder.
- * \param client_data The callee's client data set through
- * FLAC__stream_decoder_init_*().
- */
- typedef void (*FLAC__StreamDecoderErrorCallback)(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);
-
- /***********************************************************************
- *
- * Class constructor/destructor
- *
- ***********************************************************************/
-
- /** Create a new stream decoder instance. The instance is created with
- * default settings; see the individual FLAC__stream_decoder_set_*()
- * functions for each setting's default.
- *
- * \retval FLAC__StreamDecoder*
- * \c NULL if there was an error allocating memory, else the new instance.
- */
- FLAC_API FLAC__StreamDecoder *FLAC__stream_decoder_new(void);
-
- /** Free a decoder instance. Deletes the object pointed to by \a decoder.
- *
- * \param decoder A pointer to an existing decoder.
- * \assert
- * \code decoder != NULL \endcode
- */
- FLAC_API void FLAC__stream_decoder_delete(FLAC__StreamDecoder *decoder);
-
- /***********************************************************************
- *
- * Public class method prototypes
- *
- ***********************************************************************/
-
- /** Set the serial number for the FLAC stream within the Ogg container.
- * The default behavior is to use the serial number of the first Ogg
- * page. Setting a serial number here will explicitly specify which
- * stream is to be decoded.
- *
- * \note
- * This does not need to be set for native FLAC decoding.
- *
- * \default \c use serial number of first page
- * \param decoder A decoder instance to set.
- * \param serial_number See above.
- * \assert
- * \code decoder != NULL \endcode
- * \retval FLAC__bool
- * \c false if the decoder is already initialized, else \c true.
- */
- FLAC_API FLAC__bool FLAC__stream_decoder_set_ogg_serial_number(FLAC__StreamDecoder *decoder, long serial_number);
-
- /** Set the "MD5 signature checking" flag. If \c true, the decoder will
- * compute the MD5 signature of the unencoded audio data while decoding
- * and compare it to the signature from the STREAMINFO block, if it
- * exists, during FLAC__stream_decoder_finish().
- *
- * MD5 signature checking will be turned off (until the next
- * FLAC__stream_decoder_reset()) if there is no signature in the
- * STREAMINFO block or when a seek is attempted.
- *
- * Clients that do not use the MD5 check should leave this off to speed
- * up decoding.
- *
- * \default \c false
- * \param decoder A decoder instance to set.
- * \param value Flag value (see above).
- * \assert
- * \code decoder != NULL \endcode
- * \retval FLAC__bool
- * \c false if the decoder is already initialized, else \c true.
- */
- FLAC_API FLAC__bool FLAC__stream_decoder_set_md5_checking(FLAC__StreamDecoder *decoder, FLAC__bool value);
-
- /** Direct the decoder to pass on all metadata blocks of type \a type.
- *
- * \default By default, only the \c STREAMINFO block is returned via the
- * metadata callback.
- * \param decoder A decoder instance to set.
- * \param type See above.
- * \assert
- * \code decoder != NULL \endcode
- * \a type is valid
- * \retval FLAC__bool
- * \c false if the decoder is already initialized, else \c true.
- */
- FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_respond(FLAC__StreamDecoder *decoder, FLAC__MetadataType type);
-
- /** Direct the decoder to pass on all APPLICATION metadata blocks of the
- * given \a id.
- *
- * \default By default, only the \c STREAMINFO block is returned via the
- * metadata callback.
- * \param decoder A decoder instance to set.
- * \param id See above.
- * \assert
- * \code decoder != NULL \endcode
- * \code id != NULL \endcode
- * \retval FLAC__bool
- * \c false if the decoder is already initialized, else \c true.
- */
- FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_respond_application(FLAC__StreamDecoder *decoder, const FLAC__byte id[4]);
-
- /** Direct the decoder to pass on all metadata blocks of any type.
- *
- * \default By default, only the \c STREAMINFO block is returned via the
- * metadata callback.
- * \param decoder A decoder instance to set.
- * \assert
- * \code decoder != NULL \endcode
- * \retval FLAC__bool
- * \c false if the decoder is already initialized, else \c true.
- */
- FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_respond_all(FLAC__StreamDecoder *decoder);
-
- /** Direct the decoder to filter out all metadata blocks of type \a type.
- *
- * \default By default, only the \c STREAMINFO block is returned via the
- * metadata callback.
- * \param decoder A decoder instance to set.
- * \param type See above.
- * \assert
- * \code decoder != NULL \endcode
- * \a type is valid
- * \retval FLAC__bool
- * \c false if the decoder is already initialized, else \c true.
- */
- FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_ignore(FLAC__StreamDecoder *decoder, FLAC__MetadataType type);
-
- /** Direct the decoder to filter out all APPLICATION metadata blocks of
- * the given \a id.
- *
- * \default By default, only the \c STREAMINFO block is returned via the
- * metadata callback.
- * \param decoder A decoder instance to set.
- * \param id See above.
- * \assert
- * \code decoder != NULL \endcode
- * \code id != NULL \endcode
- * \retval FLAC__bool
- * \c false if the decoder is already initialized, else \c true.
- */
- FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_ignore_application(FLAC__StreamDecoder *decoder, const FLAC__byte id[4]);
-
- /** Direct the decoder to filter out all metadata blocks of any type.
- *
- * \default By default, only the \c STREAMINFO block is returned via the
- * metadata callback.
- * \param decoder A decoder instance to set.
- * \assert
- * \code decoder != NULL \endcode
- * \retval FLAC__bool
- * \c false if the decoder is already initialized, else \c true.
- */
- FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_ignore_all(FLAC__StreamDecoder *decoder);
-
- /** Get the current decoder state.
- *
- * \param decoder A decoder instance to query.
- * \assert
- * \code decoder != NULL \endcode
- * \retval FLAC__StreamDecoderState
- * The current decoder state.
- */
- FLAC_API FLAC__StreamDecoderState FLAC__stream_decoder_get_state(const FLAC__StreamDecoder *decoder);
-
- /** Get the current decoder state as a C string.
- *
- * \param decoder A decoder instance to query.
- * \assert
- * \code decoder != NULL \endcode
- * \retval const char *
- * The decoder state as a C string. Do not modify the contents.
- */
- FLAC_API const char *FLAC__stream_decoder_get_resolved_state_string(const FLAC__StreamDecoder *decoder);
-
- /** Get the "MD5 signature checking" flag.
- * This is the value of the setting, not whether or not the decoder is
- * currently checking the MD5 (remember, it can be turned off automatically
- * by a seek). When the decoder is reset the flag will be restored to the
- * value returned by this function.
- *
- * \param decoder A decoder instance to query.
- * \assert
- * \code decoder != NULL \endcode
- * \retval FLAC__bool
- * See above.
- */
- FLAC_API FLAC__bool FLAC__stream_decoder_get_md5_checking(const FLAC__StreamDecoder *decoder);
-
- /** Get the total number of samples in the stream being decoded.
- * Will only be valid after decoding has started and will contain the
- * value from the \c STREAMINFO block. A value of \c 0 means "unknown".
- *
- * \param decoder A decoder instance to query.
- * \assert
- * \code decoder != NULL \endcode
- * \retval unsigned
- * See above.
- */
- FLAC_API FLAC__uint64 FLAC__stream_decoder_get_total_samples(const FLAC__StreamDecoder *decoder);
-
- /** Get the current number of channels in the stream being decoded.
- * Will only be valid after decoding has started and will contain the
- * value from the most recently decoded frame header.
- *
- * \param decoder A decoder instance to query.
- * \assert
- * \code decoder != NULL \endcode
- * \retval unsigned
- * See above.
- */
- FLAC_API unsigned FLAC__stream_decoder_get_channels(const FLAC__StreamDecoder *decoder);
-
- /** Get the current channel assignment in the stream being decoded.
- * Will only be valid after decoding has started and will contain the
- * value from the most recently decoded frame header.
- *
- * \param decoder A decoder instance to query.
- * \assert
- * \code decoder != NULL \endcode
- * \retval FLAC__ChannelAssignment
- * See above.
- */
- FLAC_API FLAC__ChannelAssignment FLAC__stream_decoder_get_channel_assignment(const FLAC__StreamDecoder *decoder);
-
- /** Get the current sample resolution in the stream being decoded.
- * Will only be valid after decoding has started and will contain the
- * value from the most recently decoded frame header.
- *
- * \param decoder A decoder instance to query.
- * \assert
- * \code decoder != NULL \endcode
- * \retval unsigned
- * See above.
- */
- FLAC_API unsigned FLAC__stream_decoder_get_bits_per_sample(const FLAC__StreamDecoder *decoder);
-
- /** Get the current sample rate in Hz of the stream being decoded.
- * Will only be valid after decoding has started and will contain the
- * value from the most recently decoded frame header.
- *
- * \param decoder A decoder instance to query.
- * \assert
- * \code decoder != NULL \endcode
- * \retval unsigned
- * See above.
- */
- FLAC_API unsigned FLAC__stream_decoder_get_sample_rate(const FLAC__StreamDecoder *decoder);
-
- /** Get the current blocksize of the stream being decoded.
- * Will only be valid after decoding has started and will contain the
- * value from the most recently decoded frame header.
- *
- * \param decoder A decoder instance to query.
- * \assert
- * \code decoder != NULL \endcode
- * \retval unsigned
- * See above.
- */
- FLAC_API unsigned FLAC__stream_decoder_get_blocksize(const FLAC__StreamDecoder *decoder);
-
- /** Returns the decoder's current read position within the stream.
- * The position is the byte offset from the start of the stream.
- * Bytes before this position have been fully decoded. Note that
- * there may still be undecoded bytes in the decoder's read FIFO.
- * The returned position is correct even after a seek.
- *
- * \warning This function currently only works for native FLAC,
- * not Ogg FLAC streams.
- *
- * \param decoder A decoder instance to query.
- * \param position Address at which to return the desired position.
- * \assert
- * \code decoder != NULL \endcode
- * \code position != NULL \endcode
- * \retval FLAC__bool
- * \c true if successful, \c false if the stream is not native FLAC,
- * or there was an error from the 'tell' callback or it returned
- * \c FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED.
- */
- FLAC_API FLAC__bool FLAC__stream_decoder_get_decode_position(const FLAC__StreamDecoder *decoder, FLAC__uint64 *position);
-
- /** Initialize the decoder instance to decode native FLAC streams.
- *
- * This flavor of initialization sets up the decoder to decode from a
- * native FLAC stream. I/O is performed via callbacks to the client.
- * For decoding from a plain file via filename or open FILE*,
- * FLAC__stream_decoder_init_file() and FLAC__stream_decoder_init_FILE()
- * provide a simpler interface.
- *
- * This function should be called after FLAC__stream_decoder_new() and
- * FLAC__stream_decoder_set_*() but before any of the
- * FLAC__stream_decoder_process_*() functions. Will set and return the
- * decoder state, which will be FLAC__STREAM_DECODER_SEARCH_FOR_METADATA
- * if initialization succeeded.
- *
- * \param decoder An uninitialized decoder instance.
- * \param read_callback See FLAC__StreamDecoderReadCallback. This
- * pointer must not be \c NULL.
- * \param seek_callback See FLAC__StreamDecoderSeekCallback. This
- * pointer may be \c NULL if seeking is not
- * supported. If \a seek_callback is not \c NULL then a
- * \a tell_callback, \a length_callback, and \a eof_callback must also be supplied.
- * Alternatively, a dummy seek callback that just
- * returns \c FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED
- * may also be supplied, all though this is slightly
- * less efficient for the decoder.
- * \param tell_callback See FLAC__StreamDecoderTellCallback. This
- * pointer may be \c NULL if not supported by the client. If
- * \a seek_callback is not \c NULL then a
- * \a tell_callback must also be supplied.
- * Alternatively, a dummy tell callback that just
- * returns \c FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED
- * may also be supplied, all though this is slightly
- * less efficient for the decoder.
- * \param length_callback See FLAC__StreamDecoderLengthCallback. This
- * pointer may be \c NULL if not supported by the client. If
- * \a seek_callback is not \c NULL then a
- * \a length_callback must also be supplied.
- * Alternatively, a dummy length callback that just
- * returns \c FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED
- * may also be supplied, all though this is slightly
- * less efficient for the decoder.
- * \param eof_callback See FLAC__StreamDecoderEofCallback. This
- * pointer may be \c NULL if not supported by the client. If
- * \a seek_callback is not \c NULL then a
- * \a eof_callback must also be supplied.
- * Alternatively, a dummy length callback that just
- * returns \c false
- * may also be supplied, all though this is slightly
- * less efficient for the decoder.
- * \param write_callback See FLAC__StreamDecoderWriteCallback. This
- * pointer must not be \c NULL.
- * \param metadata_callback See FLAC__StreamDecoderMetadataCallback. This
- * pointer may be \c NULL if the callback is not
- * desired.
- * \param error_callback See FLAC__StreamDecoderErrorCallback. This
- * pointer must not be \c NULL.
- * \param client_data This value will be supplied to callbacks in their
- * \a client_data argument.
- * \assert
- * \code decoder != NULL \endcode
- * \retval FLAC__StreamDecoderInitStatus
- * \c FLAC__STREAM_DECODER_INIT_STATUS_OK if initialization was successful;
- * see FLAC__StreamDecoderInitStatus for the meanings of other return values.
- */
- FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_stream(
- FLAC__StreamDecoder *decoder,
- FLAC__StreamDecoderReadCallback read_callback,
- FLAC__StreamDecoderSeekCallback seek_callback,
- FLAC__StreamDecoderTellCallback tell_callback,
- FLAC__StreamDecoderLengthCallback length_callback,
- FLAC__StreamDecoderEofCallback eof_callback,
- FLAC__StreamDecoderWriteCallback write_callback,
- FLAC__StreamDecoderMetadataCallback metadata_callback,
- FLAC__StreamDecoderErrorCallback error_callback,
- void *client_data
- );
-
- /** Initialize the decoder instance to decode Ogg FLAC streams.
- *
- * This flavor of initialization sets up the decoder to decode from a
- * FLAC stream in an Ogg container. I/O is performed via callbacks to the
- * client. For decoding from a plain file via filename or open FILE*,
- * FLAC__stream_decoder_init_ogg_file() and FLAC__stream_decoder_init_ogg_FILE()
- * provide a simpler interface.
- *
- * This function should be called after FLAC__stream_decoder_new() and
- * FLAC__stream_decoder_set_*() but before any of the
- * FLAC__stream_decoder_process_*() functions. Will set and return the
- * decoder state, which will be FLAC__STREAM_DECODER_SEARCH_FOR_METADATA
- * if initialization succeeded.
- *
- * \note Support for Ogg FLAC in the library is optional. If this
- * library has been built without support for Ogg FLAC, this function
- * will return \c FLAC__STREAM_DECODER_INIT_STATUS_UNSUPPORTED_CONTAINER.
- *
- * \param decoder An uninitialized decoder instance.
- * \param read_callback See FLAC__StreamDecoderReadCallback. This
- * pointer must not be \c NULL.
- * \param seek_callback See FLAC__StreamDecoderSeekCallback. This
- * pointer may be \c NULL if seeking is not
- * supported. If \a seek_callback is not \c NULL then a
- * \a tell_callback, \a length_callback, and \a eof_callback must also be supplied.
- * Alternatively, a dummy seek callback that just
- * returns \c FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED
- * may also be supplied, all though this is slightly
- * less efficient for the decoder.
- * \param tell_callback See FLAC__StreamDecoderTellCallback. This
- * pointer may be \c NULL if not supported by the client. If
- * \a seek_callback is not \c NULL then a
- * \a tell_callback must also be supplied.
- * Alternatively, a dummy tell callback that just
- * returns \c FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED
- * may also be supplied, all though this is slightly
- * less efficient for the decoder.
- * \param length_callback See FLAC__StreamDecoderLengthCallback. This
- * pointer may be \c NULL if not supported by the client. If
- * \a seek_callback is not \c NULL then a
- * \a length_callback must also be supplied.
- * Alternatively, a dummy length callback that just
- * returns \c FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED
- * may also be supplied, all though this is slightly
- * less efficient for the decoder.
- * \param eof_callback See FLAC__StreamDecoderEofCallback. This
- * pointer may be \c NULL if not supported by the client. If
- * \a seek_callback is not \c NULL then a
- * \a eof_callback must also be supplied.
- * Alternatively, a dummy length callback that just
- * returns \c false
- * may also be supplied, all though this is slightly
- * less efficient for the decoder.
- * \param write_callback See FLAC__StreamDecoderWriteCallback. This
- * pointer must not be \c NULL.
- * \param metadata_callback See FLAC__StreamDecoderMetadataCallback. This
- * pointer may be \c NULL if the callback is not
- * desired.
- * \param error_callback See FLAC__StreamDecoderErrorCallback. This
- * pointer must not be \c NULL.
- * \param client_data This value will be supplied to callbacks in their
- * \a client_data argument.
- * \assert
- * \code decoder != NULL \endcode
- * \retval FLAC__StreamDecoderInitStatus
- * \c FLAC__STREAM_DECODER_INIT_STATUS_OK if initialization was successful;
- * see FLAC__StreamDecoderInitStatus for the meanings of other return values.
- */
- FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_ogg_stream(
- FLAC__StreamDecoder *decoder,
- FLAC__StreamDecoderReadCallback read_callback,
- FLAC__StreamDecoderSeekCallback seek_callback,
- FLAC__StreamDecoderTellCallback tell_callback,
- FLAC__StreamDecoderLengthCallback length_callback,
- FLAC__StreamDecoderEofCallback eof_callback,
- FLAC__StreamDecoderWriteCallback write_callback,
- FLAC__StreamDecoderMetadataCallback metadata_callback,
- FLAC__StreamDecoderErrorCallback error_callback,
- void *client_data
- );
-
- /** Initialize the decoder instance to decode native FLAC files.
- *
- * This flavor of initialization sets up the decoder to decode from a
- * plain native FLAC file. For non-stdio streams, you must use
- * FLAC__stream_decoder_init_stream() and provide callbacks for the I/O.
- *
- * This function should be called after FLAC__stream_decoder_new() and
- * FLAC__stream_decoder_set_*() but before any of the
- * FLAC__stream_decoder_process_*() functions. Will set and return the
- * decoder state, which will be FLAC__STREAM_DECODER_SEARCH_FOR_METADATA
- * if initialization succeeded.
- *
- * \param decoder An uninitialized decoder instance.
- * \param file An open FLAC file. The file should have been
- * opened with mode \c "rb" and rewound. The file
- * becomes owned by the decoder and should not be
- * manipulated by the client while decoding.
- * Unless \a file is \c stdin, it will be closed
- * when FLAC__stream_decoder_finish() is called.
- * Note however that seeking will not work when
- * decoding from \c stdout since it is not seekable.
- * \param write_callback See FLAC__StreamDecoderWriteCallback. This
- * pointer must not be \c NULL.
- * \param metadata_callback See FLAC__StreamDecoderMetadataCallback. This
- * pointer may be \c NULL if the callback is not
- * desired.
- * \param error_callback See FLAC__StreamDecoderErrorCallback. This
- * pointer must not be \c NULL.
- * \param client_data This value will be supplied to callbacks in their
- * \a client_data argument.
- * \assert
- * \code decoder != NULL \endcode
- * \code file != NULL \endcode
- * \retval FLAC__StreamDecoderInitStatus
- * \c FLAC__STREAM_DECODER_INIT_STATUS_OK if initialization was successful;
- * see FLAC__StreamDecoderInitStatus for the meanings of other return values.
- */
- FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_FILE(
- FLAC__StreamDecoder *decoder,
- FILE *file,
- FLAC__StreamDecoderWriteCallback write_callback,
- FLAC__StreamDecoderMetadataCallback metadata_callback,
- FLAC__StreamDecoderErrorCallback error_callback,
- void *client_data
- );
-
- /** Initialize the decoder instance to decode Ogg FLAC files.
- *
- * This flavor of initialization sets up the decoder to decode from a
- * plain Ogg FLAC file. For non-stdio streams, you must use
- * FLAC__stream_decoder_init_ogg_stream() and provide callbacks for the I/O.
- *
- * This function should be called after FLAC__stream_decoder_new() and
- * FLAC__stream_decoder_set_*() but before any of the
- * FLAC__stream_decoder_process_*() functions. Will set and return the
- * decoder state, which will be FLAC__STREAM_DECODER_SEARCH_FOR_METADATA
- * if initialization succeeded.
- *
- * \note Support for Ogg FLAC in the library is optional. If this
- * library has been built without support for Ogg FLAC, this function
- * will return \c FLAC__STREAM_DECODER_INIT_STATUS_UNSUPPORTED_CONTAINER.
- *
- * \param decoder An uninitialized decoder instance.
- * \param file An open FLAC file. The file should have been
- * opened with mode \c "rb" and rewound. The file
- * becomes owned by the decoder and should not be
- * manipulated by the client while decoding.
- * Unless \a file is \c stdin, it will be closed
- * when FLAC__stream_decoder_finish() is called.
- * Note however that seeking will not work when
- * decoding from \c stdout since it is not seekable.
- * \param write_callback See FLAC__StreamDecoderWriteCallback. This
- * pointer must not be \c NULL.
- * \param metadata_callback See FLAC__StreamDecoderMetadataCallback. This
- * pointer may be \c NULL if the callback is not
- * desired.
- * \param error_callback See FLAC__StreamDecoderErrorCallback. This
- * pointer must not be \c NULL.
- * \param client_data This value will be supplied to callbacks in their
- * \a client_data argument.
- * \assert
- * \code decoder != NULL \endcode
- * \code file != NULL \endcode
- * \retval FLAC__StreamDecoderInitStatus
- * \c FLAC__STREAM_DECODER_INIT_STATUS_OK if initialization was successful;
- * see FLAC__StreamDecoderInitStatus for the meanings of other return values.
- */
- FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_ogg_FILE(
- FLAC__StreamDecoder *decoder,
- FILE *file,
- FLAC__StreamDecoderWriteCallback write_callback,
- FLAC__StreamDecoderMetadataCallback metadata_callback,
- FLAC__StreamDecoderErrorCallback error_callback,
- void *client_data
- );
-
- /** Initialize the decoder instance to decode native FLAC files.
- *
- * This flavor of initialization sets up the decoder to decode from a plain
- * native FLAC file. If POSIX fopen() semantics are not sufficient, (for
- * example, with Unicode filenames on Windows), you must use
- * FLAC__stream_decoder_init_FILE(), or FLAC__stream_decoder_init_stream()
- * and provide callbacks for the I/O.
- *
- * This function should be called after FLAC__stream_decoder_new() and
- * FLAC__stream_decoder_set_*() but before any of the
- * FLAC__stream_decoder_process_*() functions. Will set and return the
- * decoder state, which will be FLAC__STREAM_DECODER_SEARCH_FOR_METADATA
- * if initialization succeeded.
- *
- * \param decoder An uninitialized decoder instance.
- * \param filename The name of the file to decode from. The file will
- * be opened with fopen(). Use \c NULL to decode from
- * \c stdin. Note that \c stdin is not seekable.
- * \param write_callback See FLAC__StreamDecoderWriteCallback. This
- * pointer must not be \c NULL.
- * \param metadata_callback See FLAC__StreamDecoderMetadataCallback. This
- * pointer may be \c NULL if the callback is not
- * desired.
- * \param error_callback See FLAC__StreamDecoderErrorCallback. This
- * pointer must not be \c NULL.
- * \param client_data This value will be supplied to callbacks in their
- * \a client_data argument.
- * \assert
- * \code decoder != NULL \endcode
- * \retval FLAC__StreamDecoderInitStatus
- * \c FLAC__STREAM_DECODER_INIT_STATUS_OK if initialization was successful;
- * see FLAC__StreamDecoderInitStatus for the meanings of other return values.
- */
- FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_file(
- FLAC__StreamDecoder *decoder,
- const char *filename,
- FLAC__StreamDecoderWriteCallback write_callback,
- FLAC__StreamDecoderMetadataCallback metadata_callback,
- FLAC__StreamDecoderErrorCallback error_callback,
- void *client_data
- );
-
- /** Initialize the decoder instance to decode Ogg FLAC files.
- *
- * This flavor of initialization sets up the decoder to decode from a plain
- * Ogg FLAC file. If POSIX fopen() semantics are not sufficient, (for
- * example, with Unicode filenames on Windows), you must use
- * FLAC__stream_decoder_init_ogg_FILE(), or FLAC__stream_decoder_init_ogg_stream()
- * and provide callbacks for the I/O.
- *
- * This function should be called after FLAC__stream_decoder_new() and
- * FLAC__stream_decoder_set_*() but before any of the
- * FLAC__stream_decoder_process_*() functions. Will set and return the
- * decoder state, which will be FLAC__STREAM_DECODER_SEARCH_FOR_METADATA
- * if initialization succeeded.
- *
- * \note Support for Ogg FLAC in the library is optional. If this
- * library has been built without support for Ogg FLAC, this function
- * will return \c FLAC__STREAM_DECODER_INIT_STATUS_UNSUPPORTED_CONTAINER.
- *
- * \param decoder An uninitialized decoder instance.
- * \param filename The name of the file to decode from. The file will
- * be opened with fopen(). Use \c NULL to decode from
- * \c stdin. Note that \c stdin is not seekable.
- * \param write_callback See FLAC__StreamDecoderWriteCallback. This
- * pointer must not be \c NULL.
- * \param metadata_callback See FLAC__StreamDecoderMetadataCallback. This
- * pointer may be \c NULL if the callback is not
- * desired.
- * \param error_callback See FLAC__StreamDecoderErrorCallback. This
- * pointer must not be \c NULL.
- * \param client_data This value will be supplied to callbacks in their
- * \a client_data argument.
- * \assert
- * \code decoder != NULL \endcode
- * \retval FLAC__StreamDecoderInitStatus
- * \c FLAC__STREAM_DECODER_INIT_STATUS_OK if initialization was successful;
- * see FLAC__StreamDecoderInitStatus for the meanings of other return values.
- */
- FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_ogg_file(
- FLAC__StreamDecoder *decoder,
- const char *filename,
- FLAC__StreamDecoderWriteCallback write_callback,
- FLAC__StreamDecoderMetadataCallback metadata_callback,
- FLAC__StreamDecoderErrorCallback error_callback,
- void *client_data
- );
-
- /** Finish the decoding process.
- * Flushes the decoding buffer, releases resources, resets the decoder
- * settings to their defaults, and returns the decoder state to
- * FLAC__STREAM_DECODER_UNINITIALIZED.
- *
- * In the event of a prematurely-terminated decode, it is not strictly
- * necessary to call this immediately before FLAC__stream_decoder_delete()
- * but it is good practice to match every FLAC__stream_decoder_init_*()
- * with a FLAC__stream_decoder_finish().
- *
- * \param decoder An uninitialized decoder instance.
- * \assert
- * \code decoder != NULL \endcode
- * \retval FLAC__bool
- * \c false if MD5 checking is on AND a STREAMINFO block was available
- * AND the MD5 signature in the STREAMINFO block was non-zero AND the
- * signature does not match the one computed by the decoder; else
- * \c true.
- */
- FLAC_API FLAC__bool FLAC__stream_decoder_finish(FLAC__StreamDecoder *decoder);
-
- /** Flush the stream input.
- * The decoder's input buffer will be cleared and the state set to
- * \c FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC. This will also turn
- * off MD5 checking.
- *
- * \param decoder A decoder instance.
- * \assert
- * \code decoder != NULL \endcode
- * \retval FLAC__bool
- * \c true if successful, else \c false if a memory allocation
- * error occurs (in which case the state will be set to
- * \c FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR).
- */
- FLAC_API FLAC__bool FLAC__stream_decoder_flush(FLAC__StreamDecoder *decoder);
-
- /** Reset the decoding process.
- * The decoder's input buffer will be cleared and the state set to
- * \c FLAC__STREAM_DECODER_SEARCH_FOR_METADATA. This is similar to
- * FLAC__stream_decoder_finish() except that the settings are
- * preserved; there is no need to call FLAC__stream_decoder_init_*()
- * before decoding again. MD5 checking will be restored to its original
- * setting.
- *
- * If the decoder is seekable, or was initialized with
- * FLAC__stream_decoder_init*_FILE() or FLAC__stream_decoder_init*_file(),
- * the decoder will also attempt to seek to the beginning of the file.
- * If this rewind fails, this function will return \c false. It follows
- * that FLAC__stream_decoder_reset() cannot be used when decoding from
- * \c stdin.
- *
- * If the decoder was initialized with FLAC__stream_encoder_init*_stream()
- * and is not seekable (i.e. no seek callback was provided or the seek
- * callback returns \c FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED), it
- * is the duty of the client to start feeding data from the beginning of
- * the stream on the next FLAC__stream_decoder_process() or
- * FLAC__stream_decoder_process_interleaved() call.
- *
- * \param decoder A decoder instance.
- * \assert
- * \code decoder != NULL \endcode
- * \retval FLAC__bool
- * \c true if successful, else \c false if a memory allocation occurs
- * (in which case the state will be set to
- * \c FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR) or a seek error
- * occurs (the state will be unchanged).
- */
- FLAC_API FLAC__bool FLAC__stream_decoder_reset(FLAC__StreamDecoder *decoder);
-
- /** Decode one metadata block or audio frame.
- * This version instructs the decoder to decode a either a single metadata
- * block or a single frame and stop, unless the callbacks return a fatal
- * error or the read callback returns
- * \c FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM.
- *
- * As the decoder needs more input it will call the read callback.
- * Depending on what was decoded, the metadata or write callback will be
- * called with the decoded metadata block or audio frame.
- *
- * Unless there is a fatal read error or end of stream, this function
- * will return once one whole frame is decoded. In other words, if the
- * stream is not synchronized or points to a corrupt frame header, the
- * decoder will continue to try and resync until it gets to a valid
- * frame, then decode one frame, then return. If the decoder points to
- * a frame whose frame CRC in the frame footer does not match the
- * computed frame CRC, this function will issue a
- * FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH error to the
- * error callback, and return, having decoded one complete, although
- * corrupt, frame. (Such corrupted frames are sent as silence of the
- * correct length to the write callback.)
- *
- * \param decoder An initialized decoder instance.
- * \assert
- * \code decoder != NULL \endcode
- * \retval FLAC__bool
- * \c false if any fatal read, write, or memory allocation error
- * occurred (meaning decoding must stop), else \c true; for more
- * information about the decoder, check the decoder state with
- * FLAC__stream_decoder_get_state().
- */
- FLAC_API FLAC__bool FLAC__stream_decoder_process_single(FLAC__StreamDecoder *decoder);
-
- /** Decode until the end of the metadata.
- * This version instructs the decoder to decode from the current position
- * and continue until all the metadata has been read, or until the
- * callbacks return a fatal error or the read callback returns
- * \c FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM.
- *
- * As the decoder needs more input it will call the read callback.
- * As each metadata block is decoded, the metadata callback will be called
- * with the decoded metadata.
- *
- * \param decoder An initialized decoder instance.
- * \assert
- * \code decoder != NULL \endcode
- * \retval FLAC__bool
- * \c false if any fatal read, write, or memory allocation error
- * occurred (meaning decoding must stop), else \c true; for more
- * information about the decoder, check the decoder state with
- * FLAC__stream_decoder_get_state().
- */
- FLAC_API FLAC__bool FLAC__stream_decoder_process_until_end_of_metadata(FLAC__StreamDecoder *decoder);
-
- /** Decode until the end of the stream.
- * This version instructs the decoder to decode from the current position
- * and continue until the end of stream (the read callback returns
- * \c FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM), or until the
- * callbacks return a fatal error.
- *
- * As the decoder needs more input it will call the read callback.
- * As each metadata block and frame is decoded, the metadata or write
- * callback will be called with the decoded metadata or frame.
- *
- * \param decoder An initialized decoder instance.
- * \assert
- * \code decoder != NULL \endcode
- * \retval FLAC__bool
- * \c false if any fatal read, write, or memory allocation error
- * occurred (meaning decoding must stop), else \c true; for more
- * information about the decoder, check the decoder state with
- * FLAC__stream_decoder_get_state().
- */
- FLAC_API FLAC__bool FLAC__stream_decoder_process_until_end_of_stream(FLAC__StreamDecoder *decoder);
-
- /** Skip one audio frame.
- * This version instructs the decoder to 'skip' a single frame and stop,
- * unless the callbacks return a fatal error or the read callback returns
- * \c FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM.
- *
- * The decoding flow is the same as what occurs when
- * FLAC__stream_decoder_process_single() is called to process an audio
- * frame, except that this function does not decode the parsed data into
- * PCM or call the write callback. The integrity of the frame is still
- * checked the same way as in the other process functions.
- *
- * This function will return once one whole frame is skipped, in the
- * same way that FLAC__stream_decoder_process_single() will return once
- * one whole frame is decoded.
- *
- * This function can be used in more quickly determining FLAC frame
- * boundaries when decoding of the actual data is not needed, for
- * example when an application is separating a FLAC stream into frames
- * for editing or storing in a container. To do this, the application
- * can use FLAC__stream_decoder_skip_single_frame() to quickly advance
- * to the next frame, then use
- * FLAC__stream_decoder_get_decode_position() to find the new frame
- * boundary.
- *
- * This function should only be called when the stream has advanced
- * past all the metadata, otherwise it will return \c false.
- *
- * \param decoder An initialized decoder instance not in a metadata
- * state.
- * \assert
- * \code decoder != NULL \endcode
- * \retval FLAC__bool
- * \c false if any fatal read, write, or memory allocation error
- * occurred (meaning decoding must stop), or if the decoder
- * is in the FLAC__STREAM_DECODER_SEARCH_FOR_METADATA or
- * FLAC__STREAM_DECODER_READ_METADATA state, else \c true; for more
- * information about the decoder, check the decoder state with
- * FLAC__stream_decoder_get_state().
- */
- FLAC_API FLAC__bool FLAC__stream_decoder_skip_single_frame(FLAC__StreamDecoder *decoder);
-
- /** Flush the input and seek to an absolute sample.
- * Decoding will resume at the given sample. Note that because of
- * this, the next write callback may contain a partial block. The
- * client must support seeking the input or this function will fail
- * and return \c false. Furthermore, if the decoder state is
- * \c FLAC__STREAM_DECODER_SEEK_ERROR, then the decoder must be flushed
- * with FLAC__stream_decoder_flush() or reset with
- * FLAC__stream_decoder_reset() before decoding can continue.
- *
- * \param decoder A decoder instance.
- * \param sample The target sample number to seek to.
- * \assert
- * \code decoder != NULL \endcode
- * \retval FLAC__bool
- * \c true if successful, else \c false.
- */
- FLAC_API FLAC__bool FLAC__stream_decoder_seek_absolute(FLAC__StreamDecoder *decoder, FLAC__uint64 sample);
-
- /* \} */
-
- #ifdef __cplusplus
- }
- #endif
-
- #endif
- /********* End of inlined file: stream_decoder.h *********/
-
- /********* Start of inlined file: stream_encoder.h *********/
- #ifndef FLAC__STREAM_ENCODER_H
- #define FLAC__STREAM_ENCODER_H
-
- #include <stdio.h> /* for FILE */
-
- #ifdef __cplusplus
- extern "C" {
- #endif
-
- /** \file include/FLAC/stream_encoder.h
- *
- * \brief
- * This module contains the functions which implement the stream
- * encoder.
- *
- * See the detailed documentation in the
- * \link flac_stream_encoder stream encoder \endlink module.
- */
-
- /** \defgroup flac_encoder FLAC/ \*_encoder.h: encoder interfaces
- * \ingroup flac
- *
- * \brief
- * This module describes the encoder layers provided by libFLAC.
- *
- * The stream encoder can be used to encode complete streams either to the
- * client via callbacks, or directly to a file, depending on how it is
- * initialized. When encoding via callbacks, the client provides a write
- * callback which will be called whenever FLAC data is ready to be written.
- * If the client also supplies a seek callback, the encoder will also
- * automatically handle the writing back of metadata discovered while
- * encoding, like stream info, seek points offsets, etc. When encoding to
- * a file, the client needs only supply a filename or open \c FILE* and an
- * optional progress callback for periodic notification of progress; the
- * write and seek callbacks are supplied internally. For more info see the
- * \link flac_stream_encoder stream encoder \endlink module.
- */
-
- /** \defgroup flac_stream_encoder FLAC/stream_encoder.h: stream encoder interface
- * \ingroup flac_encoder
- *
- * \brief
- * This module contains the functions which implement the stream
- * encoder.
- *
- * The stream encoder can encode to native FLAC, and optionally Ogg FLAC
- * (check FLAC_API_SUPPORTS_OGG_FLAC) streams and files.
- *
- * The basic usage of this encoder is as follows:
- * - The program creates an instance of an encoder using
- * FLAC__stream_encoder_new().
- * - The program overrides the default settings using
- * FLAC__stream_encoder_set_*() functions. At a minimum, the following
- * functions should be called:
- * - FLAC__stream_encoder_set_channels()
- * - FLAC__stream_encoder_set_bits_per_sample()
- * - FLAC__stream_encoder_set_sample_rate()
- * - FLAC__stream_encoder_set_ogg_serial_number() (if encoding to Ogg FLAC)
- * - FLAC__stream_encoder_set_total_samples_estimate() (if known)
- * - If the application wants to control the compression level or set its own
- * metadata, then the following should also be called:
- * - FLAC__stream_encoder_set_compression_level()
- * - FLAC__stream_encoder_set_verify()
- * - FLAC__stream_encoder_set_metadata()
- * - The rest of the set functions should only be called if the client needs
- * exact control over how the audio is compressed; thorough understanding
- * of the FLAC format is necessary to achieve good results.
- * - The program initializes the instance to validate the settings and
- * prepare for encoding using
- * - FLAC__stream_encoder_init_stream() or FLAC__stream_encoder_init_FILE()
- * or FLAC__stream_encoder_init_file() for native FLAC
- * - FLAC__stream_encoder_init_ogg_stream() or FLAC__stream_encoder_init_ogg_FILE()
- * or FLAC__stream_encoder_init_ogg_file() for Ogg FLAC
- * - The program calls FLAC__stream_encoder_process() or
- * FLAC__stream_encoder_process_interleaved() to encode data, which
- * subsequently calls the callbacks when there is encoder data ready
- * to be written.
- * - The program finishes the encoding with FLAC__stream_encoder_finish(),
- * which causes the encoder to encode any data still in its input pipe,
- * update the metadata with the final encoding statistics if output
- * seeking is possible, and finally reset the encoder to the
- * uninitialized state.
- * - The instance may be used again or deleted with
- * FLAC__stream_encoder_delete().
- *
- * In more detail, the stream encoder functions similarly to the
- * \link flac_stream_decoder stream decoder \endlink, but has fewer
- * callbacks and more options. Typically the client will create a new
- * instance by calling FLAC__stream_encoder_new(), then set the necessary
- * parameters with FLAC__stream_encoder_set_*(), and initialize it by
- * calling one of the FLAC__stream_encoder_init_*() functions.
- *
- * Unlike the decoders, the stream encoder has many options that can
- * affect the speed and compression ratio. When setting these parameters
- * you should have some basic knowledge of the format (see the
- * <A HREF="../documentation.html#format">user-level documentation</A>
- * or the <A HREF="../format.html">formal description</A>). The
- * FLAC__stream_encoder_set_*() functions themselves do not validate the
- * values as many are interdependent. The FLAC__stream_encoder_init_*()
- * functions will do this, so make sure to pay attention to the state
- * returned by FLAC__stream_encoder_init_*() to make sure that it is
- * FLAC__STREAM_ENCODER_INIT_STATUS_OK. Any parameters that are not set
- * before FLAC__stream_encoder_init_*() will take on the defaults from
- * the constructor.
- *
- * There are three initialization functions for native FLAC, one for
- * setting up the encoder to encode FLAC data to the client via
- * callbacks, and two for encoding directly to a file.
- *
- * For encoding via callbacks, use FLAC__stream_encoder_init_stream().
- * You must also supply a write callback which will be called anytime
- * there is raw encoded data to write. If the client can seek the output
- * it is best to also supply seek and tell callbacks, as this allows the
- * encoder to go back after encoding is finished to write back
- * information that was collected while encoding, like seek point offsets,
- * frame sizes, etc.
- *
- * For encoding directly to a file, use FLAC__stream_encoder_init_FILE()
- * or FLAC__stream_encoder_init_file(). Then you must only supply a
- * filename or open \c FILE*; the encoder will handle all the callbacks
- * internally. You may also supply a progress callback for periodic
- * notification of the encoding progress.
- *
- * There are three similarly-named init functions for encoding to Ogg
- * FLAC streams. Check \c FLAC_API_SUPPORTS_OGG_FLAC to find out if the
- * library has been built with Ogg support.
- *
- * The call to FLAC__stream_encoder_init_*() currently will also immediately
- * call the write callback several times, once with the \c fLaC signature,
- * and once for each encoded metadata block. Note that for Ogg FLAC
- * encoding you will usually get at least twice the number of callbacks than
- * with native FLAC, one for the Ogg page header and one for the page body.
- *
- * After initializing the instance, the client may feed audio data to the
- * encoder in one of two ways:
- *
- * - Channel separate, through FLAC__stream_encoder_process() - The client
- * will pass an array of pointers to buffers, one for each channel, to
- * the encoder, each of the same length. The samples need not be
- * block-aligned, but each channel should have the same number of samples.
- * - Channel interleaved, through
- * FLAC__stream_encoder_process_interleaved() - The client will pass a single
- * pointer to data that is channel-interleaved (i.e. channel0_sample0,
- * channel1_sample0, ... , channelN_sample0, channel0_sample1, ...).
- * Again, the samples need not be block-aligned but they must be
- * sample-aligned, i.e. the first value should be channel0_sample0 and
- * the last value channelN_sampleM.
- *
- * Note that for either process call, each sample in the buffers should be a
- * signed integer, right-justified to the resolution set by
- * FLAC__stream_encoder_set_bits_per_sample(). For example, if the resolution
- * is 16 bits per sample, the samples should all be in the range [-32768,32767].
- *
- * When the client is finished encoding data, it calls
- * FLAC__stream_encoder_finish(), which causes the encoder to encode any
- * data still in its input pipe, and call the metadata callback with the
- * final encoding statistics. Then the instance may be deleted with
- * FLAC__stream_encoder_delete() or initialized again to encode another
- * stream.
- *
- * For programs that write their own metadata, but that do not know the
- * actual metadata until after encoding, it is advantageous to instruct
- * the encoder to write a PADDING block of the correct size, so that
- * instead of rewriting the whole stream after encoding, the program can
- * just overwrite the PADDING block. If only the maximum size of the
- * metadata is known, the program can write a slightly larger padding
- * block, then split it after encoding.
- *
- * Make sure you understand how lengths are calculated. All FLAC metadata
- * blocks have a 4 byte header which contains the type and length. This
- * length does not include the 4 bytes of the header. See the format page
- * for the specification of metadata blocks and their lengths.
- *
- * \note
- * If you are writing the FLAC data to a file via callbacks, make sure it
- * is open for update (e.g. mode "w+" for stdio streams). This is because
- * after the first encoding pass, the encoder will try to seek back to the
- * beginning of the stream, to the STREAMINFO block, to write some data
- * there. (If using FLAC__stream_encoder_init*_file() or
- * FLAC__stream_encoder_init*_FILE(), the file is managed internally.)
- *
- * \note
- * The "set" functions may only be called when the encoder is in the
- * state FLAC__STREAM_ENCODER_UNINITIALIZED, i.e. after
- * FLAC__stream_encoder_new() or FLAC__stream_encoder_finish(), but
- * before FLAC__stream_encoder_init_*(). If this is the case they will
- * return \c true, otherwise \c false.
- *
- * \note
- * FLAC__stream_encoder_finish() resets all settings to the constructor
- * defaults.
- *
- * \{
- */
-
- /** State values for a FLAC__StreamEncoder.
- *
- * The encoder's state can be obtained by calling FLAC__stream_encoder_get_state().
- *
- * If the encoder gets into any other state besides \c FLAC__STREAM_ENCODER_OK
- * or \c FLAC__STREAM_ENCODER_UNINITIALIZED, it becomes invalid for encoding and
- * must be deleted with FLAC__stream_encoder_delete().
- */
- typedef enum {
-
- FLAC__STREAM_ENCODER_OK = 0,
- /**< The encoder is in the normal OK state and samples can be processed. */
-
- FLAC__STREAM_ENCODER_UNINITIALIZED,
- /**< The encoder is in the uninitialized state; one of the
- * FLAC__stream_encoder_init_*() functions must be called before samples
- * can be processed.
- */
-
- FLAC__STREAM_ENCODER_OGG_ERROR,
- /**< An error occurred in the underlying Ogg layer. */
-
- FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR,
- /**< An error occurred in the underlying verify stream decoder;
- * check FLAC__stream_encoder_get_verify_decoder_state().
- */
-
- FLAC__STREAM_ENCODER_VERIFY_MISMATCH_IN_AUDIO_DATA,
- /**< The verify decoder detected a mismatch between the original
- * audio signal and the decoded audio signal.
- */
-
- FLAC__STREAM_ENCODER_CLIENT_ERROR,
- /**< One of the callbacks returned a fatal error. */
-
- FLAC__STREAM_ENCODER_IO_ERROR,
- /**< An I/O error occurred while opening/reading/writing a file.
- * Check \c errno.
- */
-
- FLAC__STREAM_ENCODER_FRAMING_ERROR,
- /**< An error occurred while writing the stream; usually, the
- * write_callback returned an error.
- */
-
- FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR
- /**< Memory allocation failed. */
-
- } FLAC__StreamEncoderState;
-
- /** Maps a FLAC__StreamEncoderState to a C string.
- *
- * Using a FLAC__StreamEncoderState as the index to this array
- * will give the string equivalent. The contents should not be modified.
- */
- extern FLAC_API const char * const FLAC__StreamEncoderStateString[];
-
- /** Possible return values for the FLAC__stream_encoder_init_*() functions.
- */
- typedef enum {
-
- FLAC__STREAM_ENCODER_INIT_STATUS_OK = 0,
- /**< Initialization was successful. */
-
- FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR,
- /**< General failure to set up encoder; call FLAC__stream_encoder_get_state() for cause. */
-
- FLAC__STREAM_ENCODER_INIT_STATUS_UNSUPPORTED_CONTAINER,
- /**< The library was not compiled with support for the given container
- * format.
- */
-
- FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_CALLBACKS,
- /**< A required callback was not supplied. */
-
- FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_NUMBER_OF_CHANNELS,
- /**< The encoder has an invalid setting for number of channels. */
-
- FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_BITS_PER_SAMPLE,
- /**< The encoder has an invalid setting for bits-per-sample.
- * FLAC supports 4-32 bps but the reference encoder currently supports
- * only up to 24 bps.
- */
-
- FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_SAMPLE_RATE,
- /**< The encoder has an invalid setting for the input sample rate. */
-
- FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_BLOCK_SIZE,
- /**< The encoder has an invalid setting for the block size. */
-
- FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_MAX_LPC_ORDER,
- /**< The encoder has an invalid setting for the maximum LPC order. */
-
- FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_QLP_COEFF_PRECISION,
- /**< The encoder has an invalid setting for the precision of the quantized linear predictor coefficients. */
-
- FLAC__STREAM_ENCODER_INIT_STATUS_BLOCK_SIZE_TOO_SMALL_FOR_LPC_ORDER,
- /**< The specified block size is less than the maximum LPC order. */
-
- FLAC__STREAM_ENCODER_INIT_STATUS_NOT_STREAMABLE,
- /**< The encoder is bound to the <A HREF="../format.html#subset">Subset</A> but other settings violate it. */
-
- FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_METADATA,
- /**< The metadata input to the encoder is invalid, in one of the following ways:
- * - FLAC__stream_encoder_set_metadata() was called with a null pointer but a block count > 0
- * - One of the metadata blocks contains an undefined type
- * - It contains an illegal CUESHEET as checked by FLAC__format_cuesheet_is_legal()
- * - It contains an illegal SEEKTABLE as checked by FLAC__format_seektable_is_legal()
- * - It contains more than one SEEKTABLE block or more than one VORBIS_COMMENT block
- */
-
- FLAC__STREAM_ENCODER_INIT_STATUS_ALREADY_INITIALIZED
- /**< FLAC__stream_encoder_init_*() was called when the encoder was
- * already initialized, usually because
- * FLAC__stream_encoder_finish() was not called.
- */
-
- } FLAC__StreamEncoderInitStatus;
-
- /** Maps a FLAC__StreamEncoderInitStatus to a C string.
- *
- * Using a FLAC__StreamEncoderInitStatus as the index to this array
- * will give the string equivalent. The contents should not be modified.
- */
- extern FLAC_API const char * const FLAC__StreamEncoderInitStatusString[];
-
- /** Return values for the FLAC__StreamEncoder read callback.
- */
- typedef enum {
-
- FLAC__STREAM_ENCODER_READ_STATUS_CONTINUE,
- /**< The read was OK and decoding can continue. */
-
- FLAC__STREAM_ENCODER_READ_STATUS_END_OF_STREAM,
- /**< The read was attempted at the end of the stream. */
-
- FLAC__STREAM_ENCODER_READ_STATUS_ABORT,
- /**< An unrecoverable error occurred. */
-
- FLAC__STREAM_ENCODER_READ_STATUS_UNSUPPORTED
- /**< Client does not support reading back from the output. */
-
- } FLAC__StreamEncoderReadStatus;
-
- /** Maps a FLAC__StreamEncoderReadStatus to a C string.
- *
- * Using a FLAC__StreamEncoderReadStatus as the index to this array
- * will give the string equivalent. The contents should not be modified.
- */
- extern FLAC_API const char * const FLAC__StreamEncoderReadStatusString[];
-
- /** Return values for the FLAC__StreamEncoder write callback.
- */
- typedef enum {
-
- FLAC__STREAM_ENCODER_WRITE_STATUS_OK = 0,
- /**< The write was OK and encoding can continue. */
-
- FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR
- /**< An unrecoverable error occurred. The encoder will return from the process call. */
-
- } FLAC__StreamEncoderWriteStatus;
-
- /** Maps a FLAC__StreamEncoderWriteStatus to a C string.
- *
- * Using a FLAC__StreamEncoderWriteStatus as the index to this array
- * will give the string equivalent. The contents should not be modified.
- */
- extern FLAC_API const char * const FLAC__StreamEncoderWriteStatusString[];
-
- /** Return values for the FLAC__StreamEncoder seek callback.
- */
- typedef enum {
-
- FLAC__STREAM_ENCODER_SEEK_STATUS_OK,
- /**< The seek was OK and encoding can continue. */
-
- FLAC__STREAM_ENCODER_SEEK_STATUS_ERROR,
- /**< An unrecoverable error occurred. */
-
- FLAC__STREAM_ENCODER_SEEK_STATUS_UNSUPPORTED
- /**< Client does not support seeking. */
-
- } FLAC__StreamEncoderSeekStatus;
-
- /** Maps a FLAC__StreamEncoderSeekStatus to a C string.
- *
- * Using a FLAC__StreamEncoderSeekStatus as the index to this array
- * will give the string equivalent. The contents should not be modified.
- */
- extern FLAC_API const char * const FLAC__StreamEncoderSeekStatusString[];
-
- /** Return values for the FLAC__StreamEncoder tell callback.
- */
- typedef enum {
-
- FLAC__STREAM_ENCODER_TELL_STATUS_OK,
- /**< The tell was OK and encoding can continue. */
-
- FLAC__STREAM_ENCODER_TELL_STATUS_ERROR,
- /**< An unrecoverable error occurred. */
-
- FLAC__STREAM_ENCODER_TELL_STATUS_UNSUPPORTED
- /**< Client does not support seeking. */
-
- } FLAC__StreamEncoderTellStatus;
-
- /** Maps a FLAC__StreamEncoderTellStatus to a C string.
- *
- * Using a FLAC__StreamEncoderTellStatus as the index to this array
- * will give the string equivalent. The contents should not be modified.
- */
- extern FLAC_API const char * const FLAC__StreamEncoderTellStatusString[];
-
- /***********************************************************************
- *
- * class FLAC__StreamEncoder
- *
- ***********************************************************************/
-
- struct FLAC__StreamEncoderProtected;
- struct FLAC__StreamEncoderPrivate;
- /** The opaque structure definition for the stream encoder type.
- * See the \link flac_stream_encoder stream encoder module \endlink
- * for a detailed description.
- */
- typedef struct {
- struct FLAC__StreamEncoderProtected *protected_; /* avoid the C++ keyword 'protected' */
- struct FLAC__StreamEncoderPrivate *private_; /* avoid the C++ keyword 'private' */
- } FLAC__StreamEncoder;
-
- /** Signature for the read callback.
- *
- * A function pointer matching this signature must be passed to
- * FLAC__stream_encoder_init_ogg_stream() if seeking is supported.
- * The supplied function will be called when the encoder needs to read back
- * encoded data. This happens during the metadata callback, when the encoder
- * has to read, modify, and rewrite the metadata (e.g. seekpoints) gathered
- * while encoding. The address of the buffer to be filled is supplied, along
- * with the number of bytes the buffer can hold. The callback may choose to
- * supply less data and modify the byte count but must be careful not to
- * overflow the buffer. The callback then returns a status code chosen from
- * FLAC__StreamEncoderReadStatus.
- *
- * Here is an example of a read callback for stdio streams:
- * \code
- * FLAC__StreamEncoderReadStatus read_cb(const FLAC__StreamEncoder *encoder, FLAC__byte buffer[], size_t *bytes, void *client_data)
- * {
- * FILE *file = ((MyClientData*)client_data)->file;
- * if(*bytes > 0) {
- * *bytes = fread(buffer, sizeof(FLAC__byte), *bytes, file);
- * if(ferror(file))
- * return FLAC__STREAM_ENCODER_READ_STATUS_ABORT;
- * else if(*bytes == 0)
- * return FLAC__STREAM_ENCODER_READ_STATUS_END_OF_STREAM;
- * else
- * return FLAC__STREAM_ENCODER_READ_STATUS_CONTINUE;
- * }
- * else
- * return FLAC__STREAM_ENCODER_READ_STATUS_ABORT;
- * }
- * \endcode
- *
- * \note In general, FLAC__StreamEncoder functions which change the
- * state should not be called on the \a encoder while in the callback.
- *
- * \param encoder The encoder instance calling the callback.
- * \param buffer A pointer to a location for the callee to store
- * data to be encoded.
- * \param bytes A pointer to the size of the buffer. On entry
- * to the callback, it contains the maximum number
- * of bytes that may be stored in \a buffer. The
- * callee must set it to the actual number of bytes
- * stored (0 in case of error or end-of-stream) before
- * returning.
- * \param client_data The callee's client data set through
- * FLAC__stream_encoder_set_client_data().
- * \retval FLAC__StreamEncoderReadStatus
- * The callee's return status.
- */
- typedef FLAC__StreamEncoderReadStatus (*FLAC__StreamEncoderReadCallback)(const FLAC__StreamEncoder *encoder, FLAC__byte buffer[], size_t *bytes, void *client_data);
-
- /** Signature for the write callback.
- *
- * A function pointer matching this signature must be passed to
- * FLAC__stream_encoder_init*_stream(). The supplied function will be called
- * by the encoder anytime there is raw encoded data ready to write. It may
- * include metadata mixed with encoded audio frames and the data is not
- * guaranteed to be aligned on frame or metadata block boundaries.
- *
- * The only duty of the callback is to write out the \a bytes worth of data
- * in \a buffer to the current position in the output stream. The arguments
- * \a samples and \a current_frame are purely informational. If \a samples
- * is greater than \c 0, then \a current_frame will hold the current frame
- * number that is being written; otherwise it indicates that the write
- * callback is being called to write metadata.
- *
- * \note
- * Unlike when writing to native FLAC, when writing to Ogg FLAC the
- * write callback will be called twice when writing each audio
- * frame; once for the page header, and once for the page body.
- * When writing the page header, the \a samples argument to the
- * write callback will be \c 0.
- *
- * \note In general, FLAC__StreamEncoder functions which change the
- * state should not be called on the \a encoder while in the callback.
- *
- * \param encoder The encoder instance calling the callback.
- * \param buffer An array of encoded data of length \a bytes.
- * \param bytes The byte length of \a buffer.
- * \param samples The number of samples encoded by \a buffer.
- * \c 0 has a special meaning; see above.
- * \param current_frame The number of the current frame being encoded.
- * \param client_data The callee's client data set through
- * FLAC__stream_encoder_init_*().
- * \retval FLAC__StreamEncoderWriteStatus
- * The callee's return status.
- */
- typedef FLAC__StreamEncoderWriteStatus (*FLAC__StreamEncoderWriteCallback)(const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], size_t bytes, unsigned samples, unsigned current_frame, void *client_data);
-
- /** Signature for the seek callback.
- *
- * A function pointer matching this signature may be passed to
- * FLAC__stream_encoder_init*_stream(). The supplied function will be called
- * when the encoder needs to seek the output stream. The encoder will pass
- * the absolute byte offset to seek to, 0 meaning the beginning of the stream.
- *
- * Here is an example of a seek callback for stdio streams:
- * \code
- * FLAC__StreamEncoderSeekStatus seek_cb(const FLAC__StreamEncoder *encoder, FLAC__uint64 absolute_byte_offset, void *client_data)
- * {
- * FILE *file = ((MyClientData*)client_data)->file;
- * if(file == stdin)
- * return FLAC__STREAM_ENCODER_SEEK_STATUS_UNSUPPORTED;
- * else if(fseeko(file, (off_t)absolute_byte_offset, SEEK_SET) < 0)
- * return FLAC__STREAM_ENCODER_SEEK_STATUS_ERROR;
- * else
- * return FLAC__STREAM_ENCODER_SEEK_STATUS_OK;
- * }
- * \endcode
- *
- * \note In general, FLAC__StreamEncoder functions which change the
- * state should not be called on the \a encoder while in the callback.
- *
- * \param encoder The encoder instance calling the callback.
- * \param absolute_byte_offset The offset from the beginning of the stream
- * to seek to.
- * \param client_data The callee's client data set through
- * FLAC__stream_encoder_init_*().
- * \retval FLAC__StreamEncoderSeekStatus
- * The callee's return status.
- */
- typedef FLAC__StreamEncoderSeekStatus (*FLAC__StreamEncoderSeekCallback)(const FLAC__StreamEncoder *encoder, FLAC__uint64 absolute_byte_offset, void *client_data);
-
- /** Signature for the tell callback.
- *
- * A function pointer matching this signature may be passed to
- * FLAC__stream_encoder_init*_stream(). The supplied function will be called
- * when the encoder needs to know the current position of the output stream.
- *
- * \warning
- * The callback must return the true current byte offset of the output to
- * which the encoder is writing. If you are buffering the output, make
- * sure and take this into account. If you are writing directly to a
- * FILE* from your write callback, ftell() is sufficient. If you are
- * writing directly to a file descriptor from your write callback, you
- * can use lseek(fd, SEEK_CUR, 0). The encoder may later seek back to
- * these points to rewrite metadata after encoding.
- *
- * Here is an example of a tell callback for stdio streams:
- * \code
- * FLAC__StreamEncoderTellStatus tell_cb(const FLAC__StreamEncoder *encoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
- * {
- * FILE *file = ((MyClientData*)client_data)->file;
- * off_t pos;
- * if(file == stdin)
- * return FLAC__STREAM_ENCODER_TELL_STATUS_UNSUPPORTED;
- * else if((pos = ftello(file)) < 0)
- * return FLAC__STREAM_ENCODER_TELL_STATUS_ERROR;
- * else {
- * *absolute_byte_offset = (FLAC__uint64)pos;
- * return FLAC__STREAM_ENCODER_TELL_STATUS_OK;
- * }
- * }
- * \endcode
- *
- * \note In general, FLAC__StreamEncoder functions which change the
- * state should not be called on the \a encoder while in the callback.
- *
- * \param encoder The encoder instance calling the callback.
- * \param absolute_byte_offset The address at which to store the current
- * position of the output.
- * \param client_data The callee's client data set through
- * FLAC__stream_encoder_init_*().
- * \retval FLAC__StreamEncoderTellStatus
- * The callee's return status.
- */
- typedef FLAC__StreamEncoderTellStatus (*FLAC__StreamEncoderTellCallback)(const FLAC__StreamEncoder *encoder, FLAC__uint64 *absolute_byte_offset, void *client_data);
-
- /** Signature for the metadata callback.
- *
- * A function pointer matching this signature may be passed to
- * FLAC__stream_encoder_init*_stream(). The supplied function will be called
- * once at the end of encoding with the populated STREAMINFO structure. This
- * is so the client can seek back to the beginning of the file and write the
- * STREAMINFO block with the correct statistics after encoding (like
- * minimum/maximum frame size and total samples).
- *
- * \note In general, FLAC__StreamEncoder functions which change the
- * state should not be called on the \a encoder while in the callback.
- *
- * \param encoder The encoder instance calling the callback.
- * \param metadata The final populated STREAMINFO block.
- * \param client_data The callee's client data set through
- * FLAC__stream_encoder_init_*().
- */
- typedef void (*FLAC__StreamEncoderMetadataCallback)(const FLAC__StreamEncoder *encoder, const FLAC__StreamMetadata *metadata, void *client_data);
-
- /** Signature for the progress callback.
- *
- * A function pointer matching this signature may be passed to
- * FLAC__stream_encoder_init*_file() or FLAC__stream_encoder_init*_FILE().
- * The supplied function will be called when the encoder has finished
- * writing a frame. The \c total_frames_estimate argument to the
- * callback will be based on the value from
- * FLAC__stream_encoder_set_total_samples_estimate().
- *
- * \note In general, FLAC__StreamEncoder functions which change the
- * state should not be called on the \a encoder while in the callback.
- *
- * \param encoder The encoder instance calling the callback.
- * \param bytes_written Bytes written so far.
- * \param samples_written Samples written so far.
- * \param frames_written Frames written so far.
- * \param total_frames_estimate The estimate of the total number of
- * frames to be written.
- * \param client_data The callee's client data set through
- * FLAC__stream_encoder_init_*().
- */
- typedef void (*FLAC__StreamEncoderProgressCallback)(const FLAC__StreamEncoder *encoder, FLAC__uint64 bytes_written, FLAC__uint64 samples_written, unsigned frames_written, unsigned total_frames_estimate, void *client_data);
-
- /***********************************************************************
- *
- * Class constructor/destructor
- *
- ***********************************************************************/
-
- /** Create a new stream encoder instance. The instance is created with
- * default settings; see the individual FLAC__stream_encoder_set_*()
- * functions for each setting's default.
- *
- * \retval FLAC__StreamEncoder*
- * \c NULL if there was an error allocating memory, else the new instance.
- */
- FLAC_API FLAC__StreamEncoder *FLAC__stream_encoder_new(void);
-
- /** Free an encoder instance. Deletes the object pointed to by \a encoder.
- *
- * \param encoder A pointer to an existing encoder.
- * \assert
- * \code encoder != NULL \endcode
- */
- FLAC_API void FLAC__stream_encoder_delete(FLAC__StreamEncoder *encoder);
-
- /***********************************************************************
- *
- * Public class method prototypes
- *
- ***********************************************************************/
-
- /** Set the serial number for the FLAC stream to use in the Ogg container.
- *
- * \note
- * This does not need to be set for native FLAC encoding.
- *
- * \note
- * It is recommended to set a serial number explicitly as the default of '0'
- * may collide with other streams.
- *
- * \default \c 0
- * \param encoder An encoder instance to set.
- * \param serial_number See above.
- * \assert
- * \code encoder != NULL \endcode
- * \retval FLAC__bool
- * \c false if the encoder is already initialized, else \c true.
- */
- FLAC_API FLAC__bool FLAC__stream_encoder_set_ogg_serial_number(FLAC__StreamEncoder *encoder, long serial_number);
-
- /** Set the "verify" flag. If \c true, the encoder will verify it's own
- * encoded output by feeding it through an internal decoder and comparing
- * the original signal against the decoded signal. If a mismatch occurs,
- * the process call will return \c false. Note that this will slow the
- * encoding process by the extra time required for decoding and comparison.
- *
- * \default \c false
- * \param encoder An encoder instance to set.
- * \param value Flag value (see above).
- * \assert
- * \code encoder != NULL \endcode
- * \retval FLAC__bool
- * \c false if the encoder is already initialized, else \c true.
- */
- FLAC_API FLAC__bool FLAC__stream_encoder_set_verify(FLAC__StreamEncoder *encoder, FLAC__bool value);
-
- /** Set the <A HREF="../format.html#subset">Subset</A> flag. If \c true,
- * the encoder will comply with the Subset and will check the
- * settings during FLAC__stream_encoder_init_*() to see if all settings
- * comply. If \c false, the settings may take advantage of the full
- * range that the format allows.
- *
- * Make sure you know what it entails before setting this to \c false.
- *
- * \default \c true
- * \param encoder An encoder instance to set.
- * \param value Flag value (see above).
- * \assert
- * \code encoder != NULL \endcode
- * \retval FLAC__bool
- * \c false if the encoder is already initialized, else \c true.
- */
- FLAC_API FLAC__bool FLAC__stream_encoder_set_streamable_subset(FLAC__StreamEncoder *encoder, FLAC__bool value);
-
- /** Set the number of channels to be encoded.
- *
- * \default \c 2
- * \param encoder An encoder instance to set.
- * \param value See above.
- * \assert
- * \code encoder != NULL \endcode
- * \retval FLAC__bool
- * \c false if the encoder is already initialized, else \c true.
- */
- FLAC_API FLAC__bool FLAC__stream_encoder_set_channels(FLAC__StreamEncoder *encoder, unsigned value);
-
- /** Set the sample resolution of the input to be encoded.
- *
- * \warning
- * Do not feed the encoder data that is wider than the value you
- * set here or you will generate an invalid stream.
- *
- * \default \c 16
- * \param encoder An encoder instance to set.
- * \param value See above.
- * \assert
- * \code encoder != NULL \endcode
- * \retval FLAC__bool
- * \c false if the encoder is already initialized, else \c true.
- */
- FLAC_API FLAC__bool FLAC__stream_encoder_set_bits_per_sample(FLAC__StreamEncoder *encoder, unsigned value);
-
- /** Set the sample rate (in Hz) of the input to be encoded.
- *
- * \default \c 44100
- * \param encoder An encoder instance to set.
- * \param value See above.
- * \assert
- * \code encoder != NULL \endcode
- * \retval FLAC__bool
- * \c false if the encoder is already initialized, else \c true.
- */
- FLAC_API FLAC__bool FLAC__stream_encoder_set_sample_rate(FLAC__StreamEncoder *encoder, unsigned value);
-
- /** Set the compression level
- *
- * The compression level is roughly proportional to the amount of effort
- * the encoder expends to compress the file. A higher level usually
- * means more computation but higher compression. The default level is
- * suitable for most applications.
- *
- * Currently the levels range from \c 0 (fastest, least compression) to
- * \c 8 (slowest, most compression). A value larger than \c 8 will be
- * treated as \c 8.
- *
- * This function automatically calls the following other \c _set_
- * functions with appropriate values, so the client does not need to
- * unless it specifically wants to override them:
- * - FLAC__stream_encoder_set_do_mid_side_stereo()
- * - FLAC__stream_encoder_set_loose_mid_side_stereo()
- * - FLAC__stream_encoder_set_apodization()
- * - FLAC__stream_encoder_set_max_lpc_order()
- * - FLAC__stream_encoder_set_qlp_coeff_precision()
- * - FLAC__stream_encoder_set_do_qlp_coeff_prec_search()
- * - FLAC__stream_encoder_set_do_escape_coding()
- * - FLAC__stream_encoder_set_do_exhaustive_model_search()
- * - FLAC__stream_encoder_set_min_residual_partition_order()
- * - FLAC__stream_encoder_set_max_residual_partition_order()
- * - FLAC__stream_encoder_set_rice_parameter_search_dist()
- *
- * The actual values set for each level are:
- * <table>
- * <tr>
- * <td><b>level</b><td>
- * <td>do mid-side stereo<td>
- * <td>loose mid-side stereo<td>
- * <td>apodization<td>
- * <td>max lpc order<td>
- * <td>qlp coeff precision<td>
- * <td>qlp coeff prec search<td>
- * <td>escape coding<td>
- * <td>exhaustive model search<td>
- * <td>min residual partition order<td>
- * <td>max residual partition order<td>
- * <td>rice parameter search dist<td>
- * </tr>
- * <tr> <td><b>0</b><td> <td>false<td> <td>false<td> <td>tukey(0.5)<td> <td>0<td> <td>0<td> <td>false<td> <td>false<td> <td>false<td> <td>0<td> <td>3<td> <td>0<td> </tr>
- * <tr> <td><b>1</b><td> <td>true<td> <td>true<td> <td>tukey(0.5)<td> <td>0<td> <td>0<td> <td>false<td> <td>false<td> <td>false<td> <td>0<td> <td>3<td> <td>0<td> </tr>
- * <tr> <td><b>2</b><td> <td>true<td> <td>false<td> <td>tukey(0.5)<td> <td>0<td> <td>0<td> <td>false<td> <td>false<td> <td>false<td> <td>0<td> <td>3<td> <td>0<td> </tr>
- * <tr> <td><b>3</b><td> <td>false<td> <td>false<td> <td>tukey(0.5)<td> <td>6<td> <td>0<td> <td>false<td> <td>false<td> <td>false<td> <td>0<td> <td>4<td> <td>0<td> </tr>
- * <tr> <td><b>4</b><td> <td>true<td> <td>true<td> <td>tukey(0.5)<td> <td>8<td> <td>0<td> <td>false<td> <td>false<td> <td>false<td> <td>0<td> <td>4<td> <td>0<td> </tr>
- * <tr> <td><b>5</b><td> <td>true<td> <td>false<td> <td>tukey(0.5)<td> <td>8<td> <td>0<td> <td>false<td> <td>false<td> <td>false<td> <td>0<td> <td>5<td> <td>0<td> </tr>
- * <tr> <td><b>6</b><td> <td>true<td> <td>false<td> <td>tukey(0.5)<td> <td>8<td> <td>0<td> <td>false<td> <td>false<td> <td>false<td> <td>0<td> <td>6<td> <td>0<td> </tr>
- * <tr> <td><b>7</b><td> <td>true<td> <td>false<td> <td>tukey(0.5)<td> <td>8<td> <td>0<td> <td>false<td> <td>false<td> <td>true<td> <td>0<td> <td>6<td> <td>0<td> </tr>
- * <tr> <td><b>8</b><td> <td>true<td> <td>false<td> <td>tukey(0.5)<td> <td>12<td> <td>0<td> <td>false<td> <td>false<td> <td>true<td> <td>0<td> <td>6<td> <td>0<td> </tr>
- * </table>
- *
- * \default \c 5
- * \param encoder An encoder instance to set.
- * \param value See above.
- * \assert
- * \code encoder != NULL \endcode
- * \retval FLAC__bool
- * \c false if the encoder is already initialized, else \c true.
- */
- FLAC_API FLAC__bool FLAC__stream_encoder_set_compression_level(FLAC__StreamEncoder *encoder, unsigned value);
-
- /** Set the blocksize to use while encoding.
- *
- * The number of samples to use per frame. Use \c 0 to let the encoder
- * estimate a blocksize; this is usually best.
- *
- * \default \c 0
- * \param encoder An encoder instance to set.
- * \param value See above.
- * \assert
- * \code encoder != NULL \endcode
- * \retval FLAC__bool
- * \c false if the encoder is already initialized, else \c true.
- */
- FLAC_API FLAC__bool FLAC__stream_encoder_set_blocksize(FLAC__StreamEncoder *encoder, unsigned value);
-
- /** Set to \c true to enable mid-side encoding on stereo input. The
- * number of channels must be 2 for this to have any effect. Set to
- * \c false to use only independent channel coding.
- *
- * \default \c false
- * \param encoder An encoder instance to set.
- * \param value Flag value (see above).
- * \assert
- * \code encoder != NULL \endcode
- * \retval FLAC__bool
- * \c false if the encoder is already initialized, else \c true.
- */
- FLAC_API FLAC__bool FLAC__stream_encoder_set_do_mid_side_stereo(FLAC__StreamEncoder *encoder, FLAC__bool value);
-
- /** Set to \c true to enable adaptive switching between mid-side and
- * left-right encoding on stereo input. Set to \c false to use
- * exhaustive searching. Setting this to \c true requires
- * FLAC__stream_encoder_set_do_mid_side_stereo() to also be set to
- * \c true in order to have any effect.
- *
- * \default \c false
- * \param encoder An encoder instance to set.
- * \param value Flag value (see above).
- * \assert
- * \code encoder != NULL \endcode
- * \retval FLAC__bool
- * \c false if the encoder is already initialized, else \c true.
- */
- FLAC_API FLAC__bool FLAC__stream_encoder_set_loose_mid_side_stereo(FLAC__StreamEncoder *encoder, FLAC__bool value);
-
- /** Sets the apodization function(s) the encoder will use when windowing
- * audio data for LPC analysis.
- *
- * The \a specification is a plain ASCII string which specifies exactly
- * which functions to use. There may be more than one (up to 32),
- * separated by \c ';' characters. Some functions take one or more
- * comma-separated arguments in parentheses.
- *
- * The available functions are \c bartlett, \c bartlett_hann,
- * \c blackman, \c blackman_harris_4term_92db, \c connes, \c flattop,
- * \c gauss(STDDEV), \c hamming, \c hann, \c kaiser_bessel, \c nuttall,
- * \c rectangle, \c triangle, \c tukey(P), \c welch.
- *
- * For \c gauss(STDDEV), STDDEV specifies the standard deviation
- * (0<STDDEV<=0.5).
- *
- * For \c tukey(P), P specifies the fraction of the window that is
- * tapered (0<=P<=1). P=0 corresponds to \c rectangle and P=1
- * corresponds to \c hann.
- *
- * Example specifications are \c "blackman" or
- * \c "hann;triangle;tukey(0.5);tukey(0.25);tukey(0.125)"
- *
- * Any function that is specified erroneously is silently dropped. Up
- * to 32 functions are kept, the rest are dropped. If the specification
- * is empty the encoder defaults to \c "tukey(0.5)".
- *
- * When more than one function is specified, then for every subframe the
- * encoder will try each of them separately and choose the window that
- * results in the smallest compressed subframe.
- *
- * Note that each function specified causes the encoder to occupy a
- * floating point array in which to store the window.
- *
- * \default \c "tukey(0.5)"
- * \param encoder An encoder instance to set.
- * \param specification See above.
- * \assert
- * \code encoder != NULL \endcode
- * \code specification != NULL \endcode
- * \retval FLAC__bool
- * \c false if the encoder is already initialized, else \c true.
- */
- FLAC_API FLAC__bool FLAC__stream_encoder_set_apodization(FLAC__StreamEncoder *encoder, const char *specification);
-
- /** Set the maximum LPC order, or \c 0 to use only the fixed predictors.
- *
- * \default \c 0
- * \param encoder An encoder instance to set.
- * \param value See above.
- * \assert
- * \code encoder != NULL \endcode
- * \retval FLAC__bool
- * \c false if the encoder is already initialized, else \c true.
- */
- FLAC_API FLAC__bool FLAC__stream_encoder_set_max_lpc_order(FLAC__StreamEncoder *encoder, unsigned value);
-
- /** Set the precision, in bits, of the quantized linear predictor
- * coefficients, or \c 0 to let the encoder select it based on the
- * blocksize.
- *
- * \note
- * In the current implementation, qlp_coeff_precision + bits_per_sample must
- * be less than 32.
- *
- * \default \c 0
- * \param encoder An encoder instance to set.
- * \param value See above.
- * \assert
- * \code encoder != NULL \endcode
- * \retval FLAC__bool
- * \c false if the encoder is already initialized, else \c true.
- */
- FLAC_API FLAC__bool FLAC__stream_encoder_set_qlp_coeff_precision(FLAC__StreamEncoder *encoder, unsigned value);
-
- /** Set to \c false to use only the specified quantized linear predictor
- * coefficient precision, or \c true to search neighboring precision
- * values and use the best one.
- *
- * \default \c false
- * \param encoder An encoder instance to set.
- * \param value See above.
- * \assert
- * \code encoder != NULL \endcode
- * \retval FLAC__bool
- * \c false if the encoder is already initialized, else \c true.
- */
- FLAC_API FLAC__bool FLAC__stream_encoder_set_do_qlp_coeff_prec_search(FLAC__StreamEncoder *encoder, FLAC__bool value);
-
- /** Deprecated. Setting this value has no effect.
- *
- * \default \c false
- * \param encoder An encoder instance to set.
- * \param value See above.
- * \assert
- * \code encoder != NULL \endcode
- * \retval FLAC__bool
- * \c false if the encoder is already initialized, else \c true.
- */
- FLAC_API FLAC__bool FLAC__stream_encoder_set_do_escape_coding(FLAC__StreamEncoder *encoder, FLAC__bool value);
-
- /** Set to \c false to let the encoder estimate the best model order
- * based on the residual signal energy, or \c true to force the
- * encoder to evaluate all order models and select the best.
- *
- * \default \c false
- * \param encoder An encoder instance to set.
- * \param value See above.
- * \assert
- * \code encoder != NULL \endcode
- * \retval FLAC__bool
- * \c false if the encoder is already initialized, else \c true.
- */
- FLAC_API FLAC__bool FLAC__stream_encoder_set_do_exhaustive_model_search(FLAC__StreamEncoder *encoder, FLAC__bool value);
-
- /** Set the minimum partition order to search when coding the residual.
- * This is used in tandem with
- * FLAC__stream_encoder_set_max_residual_partition_order().
- *
- * The partition order determines the context size in the residual.
- * The context size will be approximately <tt>blocksize / (2 ^ order)</tt>.
- *
- * Set both min and max values to \c 0 to force a single context,
- * whose Rice parameter is based on the residual signal variance.
- * Otherwise, set a min and max order, and the encoder will search
- * all orders, using the mean of each context for its Rice parameter,
- * and use the best.
- *
- * \default \c 0
- * \param encoder An encoder instance to set.
- * \param value See above.
- * \assert
- * \code encoder != NULL \endcode
- * \retval FLAC__bool
- * \c false if the encoder is already initialized, else \c true.
- */
- FLAC_API FLAC__bool FLAC__stream_encoder_set_min_residual_partition_order(FLAC__StreamEncoder *encoder, unsigned value);
-
- /** Set the maximum partition order to search when coding the residual.
- * This is used in tandem with
- * FLAC__stream_encoder_set_min_residual_partition_order().
- *
- * The partition order determines the context size in the residual.
- * The context size will be approximately <tt>blocksize / (2 ^ order)</tt>.
- *
- * Set both min and max values to \c 0 to force a single context,
- * whose Rice parameter is based on the residual signal variance.
- * Otherwise, set a min and max order, and the encoder will search
- * all orders, using the mean of each context for its Rice parameter,
- * and use the best.
- *
- * \default \c 0
- * \param encoder An encoder instance to set.
- * \param value See above.
- * \assert
- * \code encoder != NULL \endcode
- * \retval FLAC__bool
- * \c false if the encoder is already initialized, else \c true.
- */
- FLAC_API FLAC__bool FLAC__stream_encoder_set_max_residual_partition_order(FLAC__StreamEncoder *encoder, unsigned value);
-
- /** Deprecated. Setting this value has no effect.
- *
- * \default \c 0
- * \param encoder An encoder instance to set.
- * \param value See above.
- * \assert
- * \code encoder != NULL \endcode
- * \retval FLAC__bool
- * \c false if the encoder is already initialized, else \c true.
- */
- FLAC_API FLAC__bool FLAC__stream_encoder_set_rice_parameter_search_dist(FLAC__StreamEncoder *encoder, unsigned value);
-
- /** Set an estimate of the total samples that will be encoded.
- * This is merely an estimate and may be set to \c 0 if unknown.
- * This value will be written to the STREAMINFO block before encoding,
- * and can remove the need for the caller to rewrite the value later
- * if the value is known before encoding.
- *
- * \default \c 0
- * \param encoder An encoder instance to set.
- * \param value See above.
- * \assert
- * \code encoder != NULL \endcode
- * \retval FLAC__bool
- * \c false if the encoder is already initialized, else \c true.
- */
- FLAC_API FLAC__bool FLAC__stream_encoder_set_total_samples_estimate(FLAC__StreamEncoder *encoder, FLAC__uint64 value);
-
- /** Set the metadata blocks to be emitted to the stream before encoding.
- * A value of \c NULL, \c 0 implies no metadata; otherwise, supply an
- * array of pointers to metadata blocks. The array is non-const since
- * the encoder may need to change the \a is_last flag inside them, and
- * in some cases update seek point offsets. Otherwise, the encoder will
- * not modify or free the blocks. It is up to the caller to free the
- * metadata blocks after encoding finishes.
- *
- * \note
- * The encoder stores only copies of the pointers in the \a metadata array;
- * the metadata blocks themselves must survive at least until after
- * FLAC__stream_encoder_finish() returns. Do not free the blocks until then.
- *
- * \note
- * The STREAMINFO block is always written and no STREAMINFO block may
- * occur in the supplied array.
- *
- * \note
- * By default the encoder does not create a SEEKTABLE. If one is supplied
- * in the \a metadata array, but the client has specified that it does not
- * support seeking, then the SEEKTABLE will be written verbatim. However
- * by itself this is not very useful as the client will not know the stream
- * offsets for the seekpoints ahead of time. In order to get a proper
- * seektable the client must support seeking. See next note.
- *
- * \note
- * SEEKTABLE blocks are handled specially. Since you will not know
- * the values for the seek point stream offsets, you should pass in
- * a SEEKTABLE 'template', that is, a SEEKTABLE object with the
- * required sample numbers (or placeholder points), with \c 0 for the
- * \a frame_samples and \a stream_offset fields for each point. If the
- * client has specified that it supports seeking by providing a seek
- * callback to FLAC__stream_encoder_init_stream() or both seek AND read
- * callback to FLAC__stream_encoder_init_ogg_stream() (or by using
- * FLAC__stream_encoder_init*_file() or FLAC__stream_encoder_init*_FILE()),
- * then while it is encoding the encoder will fill the stream offsets in
- * for you and when encoding is finished, it will seek back and write the
- * real values into the SEEKTABLE block in the stream. There are helper
- * routines for manipulating seektable template blocks; see metadata.h:
- * FLAC__metadata_object_seektable_template_*(). If the client does
- * not support seeking, the SEEKTABLE will have inaccurate offsets which
- * will slow down or remove the ability to seek in the FLAC stream.
- *
- * \note
- * The encoder instance \b will modify the first \c SEEKTABLE block
- * as it transforms the template to a valid seektable while encoding,
- * but it is still up to the caller to free all metadata blocks after
- * encoding.
- *
- * \note
- * A VORBIS_COMMENT block may be supplied. The vendor string in it
- * will be ignored. libFLAC will use it's own vendor string. libFLAC
- * will not modify the passed-in VORBIS_COMMENT's vendor string, it
- * will simply write it's own into the stream. If no VORBIS_COMMENT
- * block is present in the \a metadata array, libFLAC will write an
- * empty one, containing only the vendor string.
- *
- * \note The Ogg FLAC mapping requires that the VORBIS_COMMENT block be
- * the second metadata block of the stream. The encoder already supplies
- * the STREAMINFO block automatically. If \a metadata does not contain a
- * VORBIS_COMMENT block, the encoder will supply that too. Otherwise, if
- * \a metadata does contain a VORBIS_COMMENT block and it is not the
- * first, the init function will reorder \a metadata by moving the
- * VORBIS_COMMENT block to the front; the relative ordering of the other
- * blocks will remain as they were.
- *
- * \note The Ogg FLAC mapping limits the number of metadata blocks per
- * stream to \c 65535. If \a num_blocks exceeds this the function will
- * return \c false.
- *
- * \default \c NULL, 0
- * \param encoder An encoder instance to set.
- * \param metadata See above.
- * \param num_blocks See above.
- * \assert
- * \code encoder != NULL \endcode
- * \retval FLAC__bool
- * \c false if the encoder is already initialized, else \c true.
- * \c false if the encoder is already initialized, or if
- * \a num_blocks > 65535 if encoding to Ogg FLAC, else \c true.
- */
- FLAC_API FLAC__bool FLAC__stream_encoder_set_metadata(FLAC__StreamEncoder *encoder, FLAC__StreamMetadata **metadata, unsigned num_blocks);
-
- /** Get the current encoder state.
- *
- * \param encoder An encoder instance to query.
- * \assert
- * \code encoder != NULL \endcode
- * \retval FLAC__StreamEncoderState
- * The current encoder state.
- */
- FLAC_API FLAC__StreamEncoderState FLAC__stream_encoder_get_state(const FLAC__StreamEncoder *encoder);
-
- /** Get the state of the verify stream decoder.
- * Useful when the stream encoder state is
- * \c FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR.
- *
- * \param encoder An encoder instance to query.
- * \assert
- * \code encoder != NULL \endcode
- * \retval FLAC__StreamDecoderState
- * The verify stream decoder state.
- */
- FLAC_API FLAC__StreamDecoderState FLAC__stream_encoder_get_verify_decoder_state(const FLAC__StreamEncoder *encoder);
-
- /** Get the current encoder state as a C string.
- * This version automatically resolves
- * \c FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR by getting the
- * verify decoder's state.
- *
- * \param encoder A encoder instance to query.
- * \assert
- * \code encoder != NULL \endcode
- * \retval const char *
- * The encoder state as a C string. Do not modify the contents.
- */
- FLAC_API const char *FLAC__stream_encoder_get_resolved_state_string(const FLAC__StreamEncoder *encoder);
-
- /** Get relevant values about the nature of a verify decoder error.
- * Useful when the stream encoder state is
- * \c FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR. The arguments should
- * be addresses in which the stats will be returned, or NULL if value
- * is not desired.
- *
- * \param encoder An encoder instance to query.
- * \param absolute_sample The absolute sample number of the mismatch.
- * \param frame_number The number of the frame in which the mismatch occurred.
- * \param channel The channel in which the mismatch occurred.
- * \param sample The number of the sample (relative to the frame) in
- * which the mismatch occurred.
- * \param expected The expected value for the sample in question.
- * \param got The actual value returned by the decoder.
- * \assert
- * \code encoder != NULL \endcode
- */
- FLAC_API void FLAC__stream_encoder_get_verify_decoder_error_stats(const FLAC__StreamEncoder *encoder, FLAC__uint64 *absolute_sample, unsigned *frame_number, unsigned *channel, unsigned *sample, FLAC__int32 *expected, FLAC__int32 *got);
-
- /** Get the "verify" flag.
- *
- * \param encoder An encoder instance to query.
- * \assert
- * \code encoder != NULL \endcode
- * \retval FLAC__bool
- * See FLAC__stream_encoder_set_verify().
- */
- FLAC_API FLAC__bool FLAC__stream_encoder_get_verify(const FLAC__StreamEncoder *encoder);
-
- /** Get the <A HREF="../format.html#subset>Subset</A> flag.
- *
- * \param encoder An encoder instance to query.
- * \assert
- * \code encoder != NULL \endcode
- * \retval FLAC__bool
- * See FLAC__stream_encoder_set_streamable_subset().
- */
- FLAC_API FLAC__bool FLAC__stream_encoder_get_streamable_subset(const FLAC__StreamEncoder *encoder);
-
- /** Get the number of input channels being processed.
- *
- * \param encoder An encoder instance to query.
- * \assert
- * \code encoder != NULL \endcode
- * \retval unsigned
- * See FLAC__stream_encoder_set_channels().
- */
- FLAC_API unsigned FLAC__stream_encoder_get_channels(const FLAC__StreamEncoder *encoder);
-
- /** Get the input sample resolution setting.
- *
- * \param encoder An encoder instance to query.
- * \assert
- * \code encoder != NULL \endcode
- * \retval unsigned
- * See FLAC__stream_encoder_set_bits_per_sample().
- */
- FLAC_API unsigned FLAC__stream_encoder_get_bits_per_sample(const FLAC__StreamEncoder *encoder);
-
- /** Get the input sample rate setting.
- *
- * \param encoder An encoder instance to query.
- * \assert
- * \code encoder != NULL \endcode
- * \retval unsigned
- * See FLAC__stream_encoder_set_sample_rate().
- */
- FLAC_API unsigned FLAC__stream_encoder_get_sample_rate(const FLAC__StreamEncoder *encoder);
-
- /** Get the blocksize setting.
- *
- * \param encoder An encoder instance to query.
- * \assert
- * \code encoder != NULL \endcode
- * \retval unsigned
- * See FLAC__stream_encoder_set_blocksize().
- */
- FLAC_API unsigned FLAC__stream_encoder_get_blocksize(const FLAC__StreamEncoder *encoder);
-
- /** Get the "mid/side stereo coding" flag.
- *
- * \param encoder An encoder instance to query.
- * \assert
- * \code encoder != NULL \endcode
- * \retval FLAC__bool
- * See FLAC__stream_encoder_get_do_mid_side_stereo().
- */
- FLAC_API FLAC__bool FLAC__stream_encoder_get_do_mid_side_stereo(const FLAC__StreamEncoder *encoder);
-
- /** Get the "adaptive mid/side switching" flag.
- *
- * \param encoder An encoder instance to query.
- * \assert
- * \code encoder != NULL \endcode
- * \retval FLAC__bool
- * See FLAC__stream_encoder_set_loose_mid_side_stereo().
- */
- FLAC_API FLAC__bool FLAC__stream_encoder_get_loose_mid_side_stereo(const FLAC__StreamEncoder *encoder);
-
- /** Get the maximum LPC order setting.
- *
- * \param encoder An encoder instance to query.
- * \assert
- * \code encoder != NULL \endcode
- * \retval unsigned
- * See FLAC__stream_encoder_set_max_lpc_order().
- */
- FLAC_API unsigned FLAC__stream_encoder_get_max_lpc_order(const FLAC__StreamEncoder *encoder);
-
- /** Get the quantized linear predictor coefficient precision setting.
- *
- * \param encoder An encoder instance to query.
- * \assert
- * \code encoder != NULL \endcode
- * \retval unsigned
- * See FLAC__stream_encoder_set_qlp_coeff_precision().
- */
- FLAC_API unsigned FLAC__stream_encoder_get_qlp_coeff_precision(const FLAC__StreamEncoder *encoder);
-
- /** Get the qlp coefficient precision search flag.
- *
- * \param encoder An encoder instance to query.
- * \assert
- * \code encoder != NULL \endcode
- * \retval FLAC__bool
- * See FLAC__stream_encoder_set_do_qlp_coeff_prec_search().
- */
- FLAC_API FLAC__bool FLAC__stream_encoder_get_do_qlp_coeff_prec_search(const FLAC__StreamEncoder *encoder);
-
- /** Get the "escape coding" flag.
- *
- * \param encoder An encoder instance to query.
- * \assert
- * \code encoder != NULL \endcode
- * \retval FLAC__bool
- * See FLAC__stream_encoder_set_do_escape_coding().
- */
- FLAC_API FLAC__bool FLAC__stream_encoder_get_do_escape_coding(const FLAC__StreamEncoder *encoder);
-
- /** Get the exhaustive model search flag.
- *
- * \param encoder An encoder instance to query.
- * \assert
- * \code encoder != NULL \endcode
- * \retval FLAC__bool
- * See FLAC__stream_encoder_set_do_exhaustive_model_search().
- */
- FLAC_API FLAC__bool FLAC__stream_encoder_get_do_exhaustive_model_search(const FLAC__StreamEncoder *encoder);
-
- /** Get the minimum residual partition order setting.
- *
- * \param encoder An encoder instance to query.
- * \assert
- * \code encoder != NULL \endcode
- * \retval unsigned
- * See FLAC__stream_encoder_set_min_residual_partition_order().
- */
- FLAC_API unsigned FLAC__stream_encoder_get_min_residual_partition_order(const FLAC__StreamEncoder *encoder);
-
- /** Get maximum residual partition order setting.
- *
- * \param encoder An encoder instance to query.
- * \assert
- * \code encoder != NULL \endcode
- * \retval unsigned
- * See FLAC__stream_encoder_set_max_residual_partition_order().
- */
- FLAC_API unsigned FLAC__stream_encoder_get_max_residual_partition_order(const FLAC__StreamEncoder *encoder);
-
- /** Get the Rice parameter search distance setting.
- *
- * \param encoder An encoder instance to query.
- * \assert
- * \code encoder != NULL \endcode
- * \retval unsigned
- * See FLAC__stream_encoder_set_rice_parameter_search_dist().
- */
- FLAC_API unsigned FLAC__stream_encoder_get_rice_parameter_search_dist(const FLAC__StreamEncoder *encoder);
-
- /** Get the previously set estimate of the total samples to be encoded.
- * The encoder merely mimics back the value given to
- * FLAC__stream_encoder_set_total_samples_estimate() since it has no
- * other way of knowing how many samples the client will encode.
- *
- * \param encoder An encoder instance to set.
- * \assert
- * \code encoder != NULL \endcode
- * \retval FLAC__uint64
- * See FLAC__stream_encoder_get_total_samples_estimate().
- */
- FLAC_API FLAC__uint64 FLAC__stream_encoder_get_total_samples_estimate(const FLAC__StreamEncoder *encoder);
-
- /** Initialize the encoder instance to encode native FLAC streams.
- *
- * This flavor of initialization sets up the encoder to encode to a
- * native FLAC stream. I/O is performed via callbacks to the client.
- * For encoding to a plain file via filename or open \c FILE*,
- * FLAC__stream_encoder_init_file() and FLAC__stream_encoder_init_FILE()
- * provide a simpler interface.
- *
- * This function should be called after FLAC__stream_encoder_new() and
- * FLAC__stream_encoder_set_*() but before FLAC__stream_encoder_process()
- * or FLAC__stream_encoder_process_interleaved().
- * initialization succeeded.
- *
- * The call to FLAC__stream_encoder_init_stream() currently will also
- * immediately call the write callback several times, once with the \c fLaC
- * signature, and once for each encoded metadata block.
- *
- * \param encoder An uninitialized encoder instance.
- * \param write_callback See FLAC__StreamEncoderWriteCallback. This
- * pointer must not be \c NULL.
- * \param seek_callback See FLAC__StreamEncoderSeekCallback. This
- * pointer may be \c NULL if seeking is not
- * supported. The encoder uses seeking to go back
- * and write some some stream statistics to the
- * STREAMINFO block; this is recommended but not
- * necessary to create a valid FLAC stream. If
- * \a seek_callback is not \c NULL then a
- * \a tell_callback must also be supplied.
- * Alternatively, a dummy seek callback that just
- * returns \c FLAC__STREAM_ENCODER_SEEK_STATUS_UNSUPPORTED
- * may also be supplied, all though this is slightly
- * less efficient for the encoder.
- * \param tell_callback See FLAC__StreamEncoderTellCallback. This
- * pointer may be \c NULL if seeking is not
- * supported. If \a seek_callback is \c NULL then
- * this argument will be ignored. If
- * \a seek_callback is not \c NULL then a
- * \a tell_callback must also be supplied.
- * Alternatively, a dummy tell callback that just
- * returns \c FLAC__STREAM_ENCODER_TELL_STATUS_UNSUPPORTED
- * may also be supplied, all though this is slightly
- * less efficient for the encoder.
- * \param metadata_callback See FLAC__StreamEncoderMetadataCallback. This
- * pointer may be \c NULL if the callback is not
- * desired. If the client provides a seek callback,
- * this function is not necessary as the encoder
- * will automatically seek back and update the
- * STREAMINFO block. It may also be \c NULL if the
- * client does not support seeking, since it will
- * have no way of going back to update the
- * STREAMINFO. However the client can still supply
- * a callback if it would like to know the details
- * from the STREAMINFO.
- * \param client_data This value will be supplied to callbacks in their
- * \a client_data argument.
- * \assert
- * \code encoder != NULL \endcode
- * \retval FLAC__StreamEncoderInitStatus
- * \c FLAC__STREAM_ENCODER_INIT_STATUS_OK if initialization was successful;
- * see FLAC__StreamEncoderInitStatus for the meanings of other return values.
- */
- FLAC_API FLAC__StreamEncoderInitStatus FLAC__stream_encoder_init_stream(FLAC__StreamEncoder *encoder, FLAC__StreamEncoderWriteCallback write_callback, FLAC__StreamEncoderSeekCallback seek_callback, FLAC__StreamEncoderTellCallback tell_callback, FLAC__StreamEncoderMetadataCallback metadata_callback, void *client_data);
-
- /** Initialize the encoder instance to encode Ogg FLAC streams.
- *
- * This flavor of initialization sets up the encoder to encode to a FLAC
- * stream in an Ogg container. I/O is performed via callbacks to the
- * client. For encoding to a plain file via filename or open \c FILE*,
- * FLAC__stream_encoder_init_ogg_file() and FLAC__stream_encoder_init_ogg_FILE()
- * provide a simpler interface.
- *
- * This function should be called after FLAC__stream_encoder_new() and
- * FLAC__stream_encoder_set_*() but before FLAC__stream_encoder_process()
- * or FLAC__stream_encoder_process_interleaved().
- * initialization succeeded.
- *
- * The call to FLAC__stream_encoder_init_ogg_stream() currently will also
- * immediately call the write callback several times to write the metadata
- * packets.
- *
- * \param encoder An uninitialized encoder instance.
- * \param read_callback See FLAC__StreamEncoderReadCallback. This
- * pointer must not be \c NULL if \a seek_callback
- * is non-NULL since they are both needed to be
- * able to write data back to the Ogg FLAC stream
- * in the post-encode phase.
- * \param write_callback See FLAC__StreamEncoderWriteCallback. This
- * pointer must not be \c NULL.
- * \param seek_callback See FLAC__StreamEncoderSeekCallback. This
- * pointer may be \c NULL if seeking is not
- * supported. The encoder uses seeking to go back
- * and write some some stream statistics to the
- * STREAMINFO block; this is recommended but not
- * necessary to create a valid FLAC stream. If
- * \a seek_callback is not \c NULL then a
- * \a tell_callback must also be supplied.
- * Alternatively, a dummy seek callback that just
- * returns \c FLAC__STREAM_ENCODER_SEEK_STATUS_UNSUPPORTED
- * may also be supplied, all though this is slightly
- * less efficient for the encoder.
- * \param tell_callback See FLAC__StreamEncoderTellCallback. This
- * pointer may be \c NULL if seeking is not
- * supported. If \a seek_callback is \c NULL then
- * this argument will be ignored. If
- * \a seek_callback is not \c NULL then a
- * \a tell_callback must also be supplied.
- * Alternatively, a dummy tell callback that just
- * returns \c FLAC__STREAM_ENCODER_TELL_STATUS_UNSUPPORTED
- * may also be supplied, all though this is slightly
- * less efficient for the encoder.
- * \param metadata_callback See FLAC__StreamEncoderMetadataCallback. This
- * pointer may be \c NULL if the callback is not
- * desired. If the client provides a seek callback,
- * this function is not necessary as the encoder
- * will automatically seek back and update the
- * STREAMINFO block. It may also be \c NULL if the
- * client does not support seeking, since it will
- * have no way of going back to update the
- * STREAMINFO. However the client can still supply
- * a callback if it would like to know the details
- * from the STREAMINFO.
- * \param client_data This value will be supplied to callbacks in their
- * \a client_data argument.
- * \assert
- * \code encoder != NULL \endcode
- * \retval FLAC__StreamEncoderInitStatus
- * \c FLAC__STREAM_ENCODER_INIT_STATUS_OK if initialization was successful;
- * see FLAC__StreamEncoderInitStatus for the meanings of other return values.
- */
- FLAC_API FLAC__StreamEncoderInitStatus FLAC__stream_encoder_init_ogg_stream(FLAC__StreamEncoder *encoder, FLAC__StreamEncoderReadCallback read_callback, FLAC__StreamEncoderWriteCallback write_callback, FLAC__StreamEncoderSeekCallback seek_callback, FLAC__StreamEncoderTellCallback tell_callback, FLAC__StreamEncoderMetadataCallback metadata_callback, void *client_data);
-
- /** Initialize the encoder instance to encode native FLAC files.
- *
- * This flavor of initialization sets up the encoder to encode to a
- * plain native FLAC file. For non-stdio streams, you must use
- * FLAC__stream_encoder_init_stream() and provide callbacks for the I/O.
- *
- * This function should be called after FLAC__stream_encoder_new() and
- * FLAC__stream_encoder_set_*() but before FLAC__stream_encoder_process()
- * or FLAC__stream_encoder_process_interleaved().
- * initialization succeeded.
- *
- * \param encoder An uninitialized encoder instance.
- * \param file An open file. The file should have been opened
- * with mode \c "w+b" and rewound. The file
- * becomes owned by the encoder and should not be
- * manipulated by the client while encoding.
- * Unless \a file is \c stdout, it will be closed
- * when FLAC__stream_encoder_finish() is called.
- * Note however that a proper SEEKTABLE cannot be
- * created when encoding to \c stdout since it is
- * not seekable.
- * \param progress_callback See FLAC__StreamEncoderProgressCallback. This
- * pointer may be \c NULL if the callback is not
- * desired.
- * \param client_data This value will be supplied to callbacks in their
- * \a client_data argument.
- * \assert
- * \code encoder != NULL \endcode
- * \code file != NULL \endcode
- * \retval FLAC__StreamEncoderInitStatus
- * \c FLAC__STREAM_ENCODER_INIT_STATUS_OK if initialization was successful;
- * see FLAC__StreamEncoderInitStatus for the meanings of other return values.
- */
- FLAC_API FLAC__StreamEncoderInitStatus FLAC__stream_encoder_init_FILE(FLAC__StreamEncoder *encoder, FILE *file, FLAC__StreamEncoderProgressCallback progress_callback, void *client_data);
-
- /** Initialize the encoder instance to encode Ogg FLAC files.
- *
- * This flavor of initialization sets up the encoder to encode to a
- * plain Ogg FLAC file. For non-stdio streams, you must use
- * FLAC__stream_encoder_init_ogg_stream() and provide callbacks for the I/O.
- *
- * This function should be called after FLAC__stream_encoder_new() and
- * FLAC__stream_encoder_set_*() but before FLAC__stream_encoder_process()
- * or FLAC__stream_encoder_process_interleaved().
- * initialization succeeded.
- *
- * \param encoder An uninitialized encoder instance.
- * \param file An open file. The file should have been opened
- * with mode \c "w+b" and rewound. The file
- * becomes owned by the encoder and should not be
- * manipulated by the client while encoding.
- * Unless \a file is \c stdout, it will be closed
- * when FLAC__stream_encoder_finish() is called.
- * Note however that a proper SEEKTABLE cannot be
- * created when encoding to \c stdout since it is
- * not seekable.
- * \param progress_callback See FLAC__StreamEncoderProgressCallback. This
- * pointer may be \c NULL if the callback is not
- * desired.
- * \param client_data This value will be supplied to callbacks in their
- * \a client_data argument.
- * \assert
- * \code encoder != NULL \endcode
- * \code file != NULL \endcode
- * \retval FLAC__StreamEncoderInitStatus
- * \c FLAC__STREAM_ENCODER_INIT_STATUS_OK if initialization was successful;
- * see FLAC__StreamEncoderInitStatus for the meanings of other return values.
- */
- FLAC_API FLAC__StreamEncoderInitStatus FLAC__stream_encoder_init_ogg_FILE(FLAC__StreamEncoder *encoder, FILE *file, FLAC__StreamEncoderProgressCallback progress_callback, void *client_data);
-
- /** Initialize the encoder instance to encode native FLAC files.
- *
- * This flavor of initialization sets up the encoder to encode to a plain
- * FLAC file. If POSIX fopen() semantics are not sufficient (for example,
- * with Unicode filenames on Windows), you must use
- * FLAC__stream_encoder_init_FILE(), or FLAC__stream_encoder_init_stream()
- * and provide callbacks for the I/O.
- *
- * This function should be called after FLAC__stream_encoder_new() and
- * FLAC__stream_encoder_set_*() but before FLAC__stream_encoder_process()
- * or FLAC__stream_encoder_process_interleaved().
- * initialization succeeded.
- *
- * \param encoder An uninitialized encoder instance.
- * \param filename The name of the file to encode to. The file will
- * be opened with fopen(). Use \c NULL to encode to
- * \c stdout. Note however that a proper SEEKTABLE
- * cannot be created when encoding to \c stdout since
- * it is not seekable.
- * \param progress_callback See FLAC__StreamEncoderProgressCallback. This
- * pointer may be \c NULL if the callback is not
- * desired.
- * \param client_data This value will be supplied to callbacks in their
- * \a client_data argument.
- * \assert
- * \code encoder != NULL \endcode
- * \retval FLAC__StreamEncoderInitStatus
- * \c FLAC__STREAM_ENCODER_INIT_STATUS_OK if initialization was successful;
- * see FLAC__StreamEncoderInitStatus for the meanings of other return values.
- */
- FLAC_API FLAC__StreamEncoderInitStatus FLAC__stream_encoder_init_file(FLAC__StreamEncoder *encoder, const char *filename, FLAC__StreamEncoderProgressCallback progress_callback, void *client_data);
-
- /** Initialize the encoder instance to encode Ogg FLAC files.
- *
- * This flavor of initialization sets up the encoder to encode to a plain
- * Ogg FLAC file. If POSIX fopen() semantics are not sufficient (for example,
- * with Unicode filenames on Windows), you must use
- * FLAC__stream_encoder_init_ogg_FILE(), or FLAC__stream_encoder_init_ogg_stream()
- * and provide callbacks for the I/O.
- *
- * This function should be called after FLAC__stream_encoder_new() and
- * FLAC__stream_encoder_set_*() but before FLAC__stream_encoder_process()
- * or FLAC__stream_encoder_process_interleaved().
- * initialization succeeded.
- *
- * \param encoder An uninitialized encoder instance.
- * \param filename The name of the file to encode to. The file will
- * be opened with fopen(). Use \c NULL to encode to
- * \c stdout. Note however that a proper SEEKTABLE
- * cannot be created when encoding to \c stdout since
- * it is not seekable.
- * \param progress_callback See FLAC__StreamEncoderProgressCallback. This
- * pointer may be \c NULL if the callback is not
- * desired.
- * \param client_data This value will be supplied to callbacks in their
- * \a client_data argument.
- * \assert
- * \code encoder != NULL \endcode
- * \retval FLAC__StreamEncoderInitStatus
- * \c FLAC__STREAM_ENCODER_INIT_STATUS_OK if initialization was successful;
- * see FLAC__StreamEncoderInitStatus for the meanings of other return values.
- */
- FLAC_API FLAC__StreamEncoderInitStatus FLAC__stream_encoder_init_ogg_file(FLAC__StreamEncoder *encoder, const char *filename, FLAC__StreamEncoderProgressCallback progress_callback, void *client_data);
-
- /** Finish the encoding process.
- * Flushes the encoding buffer, releases resources, resets the encoder
- * settings to their defaults, and returns the encoder state to
- * FLAC__STREAM_ENCODER_UNINITIALIZED. Note that this can generate
- * one or more write callbacks before returning, and will generate
- * a metadata callback.
- *
- * Note that in the course of processing the last frame, errors can
- * occur, so the caller should be sure to check the return value to
- * ensure the file was encoded properly.
- *
- * In the event of a prematurely-terminated encode, it is not strictly
- * necessary to call this immediately before FLAC__stream_encoder_delete()
- * but it is good practice to match every FLAC__stream_encoder_init_*()
- * with a FLAC__stream_encoder_finish().
- *
- * \param encoder An uninitialized encoder instance.
- * \assert
- * \code encoder != NULL \endcode
- * \retval FLAC__bool
- * \c false if an error occurred processing the last frame; or if verify
- * mode is set (see FLAC__stream_encoder_set_verify()), there was a
- * verify mismatch; else \c true. If \c false, caller should check the
- * state with FLAC__stream_encoder_get_state() for more information
- * about the error.
- */
- FLAC_API FLAC__bool FLAC__stream_encoder_finish(FLAC__StreamEncoder *encoder);
-
- /** Submit data for encoding.
- * This version allows you to supply the input data via an array of
- * pointers, each pointer pointing to an array of \a samples samples
- * representing one channel. The samples need not be block-aligned,
- * but each channel should have the same number of samples. Each sample
- * should be a signed integer, right-justified to the resolution set by
- * FLAC__stream_encoder_set_bits_per_sample(). For example, if the
- * resolution is 16 bits per sample, the samples should all be in the
- * range [-32768,32767].
- *
- * For applications where channel order is important, channels must
- * follow the order as described in the
- * <A HREF="../format.html#frame_header">frame header</A>.
- *
- * \param encoder An initialized encoder instance in the OK state.
- * \param buffer An array of pointers to each channel's signal.
- * \param samples The number of samples in one channel.
- * \assert
- * \code encoder != NULL \endcode
- * \code FLAC__stream_encoder_get_state(encoder) == FLAC__STREAM_ENCODER_OK \endcode
- * \retval FLAC__bool
- * \c true if successful, else \c false; in this case, check the
- * encoder state with FLAC__stream_encoder_get_state() to see what
- * went wrong.
- */
- FLAC_API FLAC__bool FLAC__stream_encoder_process(FLAC__StreamEncoder *encoder, const FLAC__int32 * const buffer[], unsigned samples);
-
- /** Submit data for encoding.
- * This version allows you to supply the input data where the channels
- * are interleaved into a single array (i.e. channel0_sample0,
- * channel1_sample0, ... , channelN_sample0, channel0_sample1, ...).
- * The samples need not be block-aligned but they must be
- * sample-aligned, i.e. the first value should be channel0_sample0
- * and the last value channelN_sampleM. Each sample should be a signed
- * integer, right-justified to the resolution set by
- * FLAC__stream_encoder_set_bits_per_sample(). For example, if the
- * resolution is 16 bits per sample, the samples should all be in the
- * range [-32768,32767].
- *
- * For applications where channel order is important, channels must
- * follow the order as described in the
- * <A HREF="../format.html#frame_header">frame header</A>.
- *
- * \param encoder An initialized encoder instance in the OK state.
- * \param buffer An array of channel-interleaved data (see above).
- * \param samples The number of samples in one channel, the same as for
- * FLAC__stream_encoder_process(). For example, if
- * encoding two channels, \c 1000 \a samples corresponds
- * to a \a buffer of 2000 values.
- * \assert
- * \code encoder != NULL \endcode
- * \code FLAC__stream_encoder_get_state(encoder) == FLAC__STREAM_ENCODER_OK \endcode
- * \retval FLAC__bool
- * \c true if successful, else \c false; in this case, check the
- * encoder state with FLAC__stream_encoder_get_state() to see what
- * went wrong.
- */
- FLAC_API FLAC__bool FLAC__stream_encoder_process_interleaved(FLAC__StreamEncoder *encoder, const FLAC__int32 buffer[], unsigned samples);
-
- /* \} */
-
- #ifdef __cplusplus
- }
- #endif
-
- #endif
- /********* End of inlined file: stream_encoder.h *********/
-
- #ifdef _MSC_VER
- /* OPT: an MSVC built-in would be better */
- static _inline FLAC__uint32 local_swap32_(FLAC__uint32 x)
- {
- x = ((x<<8)&0xFF00FF00) | ((x>>8)&0x00FF00FF);
- return (x>>16) | (x<<16);
- }
- #endif
-
- #if defined(_MSC_VER) && defined(_X86_)
- /* OPT: an MSVC built-in would be better */
- static void local_swap32_block_(FLAC__uint32 *start, FLAC__uint32 len)
- {
- __asm {
- mov edx, start
- mov ecx, len
- test ecx, ecx
- loop1:
- jz done1
- mov eax, [edx]
- bswap eax
- mov [edx], eax
- add edx, 4
- dec ecx
- jmp short loop1
- done1:
- }
- }
- #endif
-
- /** \mainpage
- *
- * \section intro Introduction
- *
- * This is the documentation for the FLAC C and C++ APIs. It is
- * highly interconnected; this introduction should give you a top
- * level idea of the structure and how to find the information you
- * need. As a prerequisite you should have at least a basic
- * knowledge of the FLAC format, documented
- * <A HREF="../format.html">here</A>.
- *
- * \section c_api FLAC C API
- *
- * The FLAC C API is the interface to libFLAC, a set of structures
- * describing the components of FLAC streams, and functions for
- * encoding and decoding streams, as well as manipulating FLAC
- * metadata in files. The public include files will be installed
- * in your include area (for example /usr/include/FLAC/...).
- *
- * By writing a little code and linking against libFLAC, it is
- * relatively easy to add FLAC support to another program. The
- * library is licensed under <A HREF="../license.html">Xiph's BSD license</A>.
- * Complete source code of libFLAC as well as the command-line
- * encoder and plugins is available and is a useful source of
- * examples.
- *
- * Aside from encoders and decoders, libFLAC provides a powerful
- * metadata interface for manipulating metadata in FLAC files. It
- * allows the user to add, delete, and modify FLAC metadata blocks
- * and it can automatically take advantage of PADDING blocks to avoid
- * rewriting the entire FLAC file when changing the size of the
- * metadata.
- *
- * libFLAC usually only requires the standard C library and C math
- * library. In particular, threading is not used so there is no
- * dependency on a thread library. However, libFLAC does not use
- * global variables and should be thread-safe.
- *
- * libFLAC also supports encoding to and decoding from Ogg FLAC.
- * However the metadata editing interfaces currently have limited
- * read-only support for Ogg FLAC files.
- *
- * \section cpp_api FLAC C++ API
- *
- * The FLAC C++ API is a set of classes that encapsulate the
- * structures and functions in libFLAC. They provide slightly more
- * functionality with respect to metadata but are otherwise
- * equivalent. For the most part, they share the same usage as
- * their counterparts in libFLAC, and the FLAC C API documentation
- * can be used as a supplement. The public include files
- * for the C++ API will be installed in your include area (for
- * example /usr/include/FLAC++/...).
- *
- * libFLAC++ is also licensed under
- * <A HREF="../license.html">Xiph's BSD license</A>.
- *
- * \section getting_started Getting Started
- *
- * A good starting point for learning the API is to browse through
- * the <A HREF="modules.html">modules</A>. Modules are logical
- * groupings of related functions or classes, which correspond roughly
- * to header files or sections of header files. Each module includes a
- * detailed description of the general usage of its functions or
- * classes.
- *
- * From there you can go on to look at the documentation of
- * individual functions. You can see different views of the individual
- * functions through the links in top bar across this page.
- *
- * If you prefer a more hands-on approach, you can jump right to some
- * <A HREF="../documentation_example_code.html">example code</A>.
- *
- * \section porting_guide Porting Guide
- *
- * Starting with FLAC 1.1.3 a \link porting Porting Guide \endlink
- * has been introduced which gives detailed instructions on how to
- * port your code to newer versions of FLAC.
- *
- * \section embedded_developers Embedded Developers
- *
- * libFLAC has grown larger over time as more functionality has been
- * included, but much of it may be unnecessary for a particular embedded
- * implementation. Unused parts may be pruned by some simple editing of
- * src/libFLAC/Makefile.am. In general, the decoders, encoders, and
- * metadata interface are all independent from each other.
- *
- * It is easiest to just describe the dependencies:
- *
- * - All modules depend on the \link flac_format Format \endlink module.
- * - The decoders and encoders depend on the bitbuffer.
- * - The decoder is independent of the encoder. The encoder uses the
- * decoder because of the verify feature, but this can be removed if
- * not needed.
- * - Parts of the metadata interface require the stream decoder (but not
- * the encoder).
- * - Ogg support is selectable through the compile time macro
- * \c FLAC__HAS_OGG.
- *
- * For example, if your application only requires the stream decoder, no
- * encoder, and no metadata interface, you can remove the stream encoder
- * and the metadata interface, which will greatly reduce the size of the
- * library.
- *
- * Also, there are several places in the libFLAC code with comments marked
- * with "OPT:" where a #define can be changed to enable code that might be
- * faster on a specific platform. Experimenting with these can yield faster
- * binaries.
- */
-
- /** \defgroup porting Porting Guide for New Versions
- *
- * This module describes differences in the library interfaces from
- * version to version. It assists in the porting of code that uses
- * the libraries to newer versions of FLAC.
- *
- * One simple facility for making porting easier that has been added
- * in FLAC 1.1.3 is a set of \c #defines in \c export.h of each
- * library's includes (e.g. \c include/FLAC/export.h). The
- * \c #defines mirror the libraries'
- * <A HREF="http://www.gnu.org/software/libtool/manual.html#Libtool-versioning">libtool version numbers</A>,
- * e.g. in libFLAC there are \c FLAC_API_VERSION_CURRENT,
- * \c FLAC_API_VERSION_REVISION, and \c FLAC_API_VERSION_AGE.
- * These can be used to support multiple versions of an API during the
- * transition phase, e.g.
- *
- * \code
- * #if !defined(FLAC_API_VERSION_CURRENT) || FLAC_API_VERSION_CURRENT <= 7
- * legacy code
- * #else
- * new code
- * #endif
- * \endcode
- *
- * The the source will work for multiple versions and the legacy code can
- * easily be removed when the transition is complete.
- *
- * Another available symbol is FLAC_API_SUPPORTS_OGG_FLAC (defined in
- * include/FLAC/export.h), which can be used to determine whether or not
- * the library has been compiled with support for Ogg FLAC. This is
- * simpler than trying to call an Ogg init function and catching the
- * error.
- */
-
- /** \defgroup porting_1_1_2_to_1_1_3 Porting from FLAC 1.1.2 to 1.1.3
- * \ingroup porting
- *
- * \brief
- * This module describes porting from FLAC 1.1.2 to FLAC 1.1.3.
- *
- * The main change between the APIs in 1.1.2 and 1.1.3 is that they have
- * been simplified. First, libOggFLAC has been merged into libFLAC and
- * libOggFLAC++ has been merged into libFLAC++. Second, both the three
- * decoding layers and three encoding layers have been merged into a
- * single stream decoder and stream encoder. That is, the functionality
- * of FLAC__SeekableStreamDecoder and FLAC__FileDecoder has been merged
- * into FLAC__StreamDecoder, and FLAC__SeekableStreamEncoder and
- * FLAC__FileEncoder into FLAC__StreamEncoder. Only the
- * FLAC__StreamDecoder and FLAC__StreamEncoder remain. What this means
- * is there is now a single API that can be used to encode or decode
- * streams to/from native FLAC or Ogg FLAC and the single API can work
- * on both seekable and non-seekable streams.
- *
- * Instead of creating an encoder or decoder of a certain layer, now the
- * client will always create a FLAC__StreamEncoder or
- * FLAC__StreamDecoder. The old layers are now differentiated by the
- * initialization function. For example, for the decoder,
- * FLAC__stream_decoder_init() has been replaced by
- * FLAC__stream_decoder_init_stream(). This init function takes
- * callbacks for the I/O, and the seeking callbacks are optional. This
- * allows the client to use the same object for seekable and
- * non-seekable streams. For decoding a FLAC file directly, the client
- * can use FLAC__stream_decoder_init_file() and pass just a filename
- * and fewer callbacks; most of the other callbacks are supplied
- * internally. For situations where fopen()ing by filename is not
- * possible (e.g. Unicode filenames on Windows) the client can instead
- * open the file itself and supply the FILE* to
- * FLAC__stream_decoder_init_FILE(). The init functions now returns a
- * FLAC__StreamDecoderInitStatus instead of FLAC__StreamDecoderState.
- * Since the callbacks and client data are now passed to the init
- * function, the FLAC__stream_decoder_set_*_callback() functions and
- * FLAC__stream_decoder_set_client_data() are no longer needed. The
- * rest of the calls to the decoder are the same as before.
- *
- * There are counterpart init functions for Ogg FLAC, e.g.
- * FLAC__stream_decoder_init_ogg_stream(). All the rest of the calls
- * and callbacks are the same as for native FLAC.
- *
- * As an example, in FLAC 1.1.2 a seekable stream decoder would have
- * been set up like so:
- *
- * \code
- * FLAC__SeekableStreamDecoder *decoder = FLAC__seekable_stream_decoder_new();
- * if(decoder == NULL) do_something;
- * FLAC__seekable_stream_decoder_set_md5_checking(decoder, true);
- * [... other settings ...]
- * FLAC__seekable_stream_decoder_set_read_callback(decoder, my_read_callback);
- * FLAC__seekable_stream_decoder_set_seek_callback(decoder, my_seek_callback);
- * FLAC__seekable_stream_decoder_set_tell_callback(decoder, my_tell_callback);
- * FLAC__seekable_stream_decoder_set_length_callback(decoder, my_length_callback);
- * FLAC__seekable_stream_decoder_set_eof_callback(decoder, my_eof_callback);
- * FLAC__seekable_stream_decoder_set_write_callback(decoder, my_write_callback);
- * FLAC__seekable_stream_decoder_set_metadata_callback(decoder, my_metadata_callback);
- * FLAC__seekable_stream_decoder_set_error_callback(decoder, my_error_callback);
- * FLAC__seekable_stream_decoder_set_client_data(decoder, my_client_data);
- * if(FLAC__seekable_stream_decoder_init(decoder) != FLAC__SEEKABLE_STREAM_DECODER_OK) do_something;
- * \endcode
- *
- * In FLAC 1.1.3 it is like this:
- *
- * \code
- * FLAC__StreamDecoder *decoder = FLAC__stream_decoder_new();
- * if(decoder == NULL) do_something;
- * FLAC__stream_decoder_set_md5_checking(decoder, true);
- * [... other settings ...]
- * if(FLAC__stream_decoder_init_stream(
- * decoder,
- * my_read_callback,
- * my_seek_callback, // or NULL
- * my_tell_callback, // or NULL
- * my_length_callback, // or NULL
- * my_eof_callback, // or NULL
- * my_write_callback,
- * my_metadata_callback, // or NULL
- * my_error_callback,
- * my_client_data
- * ) != FLAC__STREAM_DECODER_INIT_STATUS_OK) do_something;
- * \endcode
- *
- * or you could do;
- *
- * \code
- * [...]
- * FILE *file = fopen("somefile.flac","rb");
- * if(file == NULL) do_somthing;
- * if(FLAC__stream_decoder_init_FILE(
- * decoder,
- * file,
- * my_write_callback,
- * my_metadata_callback, // or NULL
- * my_error_callback,
- * my_client_data
- * ) != FLAC__STREAM_DECODER_INIT_STATUS_OK) do_something;
- * \endcode
- *
- * or just:
- *
- * \code
- * [...]
- * if(FLAC__stream_decoder_init_file(
- * decoder,
- * "somefile.flac",
- * my_write_callback,
- * my_metadata_callback, // or NULL
- * my_error_callback,
- * my_client_data
- * ) != FLAC__STREAM_DECODER_INIT_STATUS_OK) do_something;
- * \endcode
- *
- * Another small change to the decoder is in how it handles unparseable
- * streams. Before, when the decoder found an unparseable stream
- * (reserved for when the decoder encounters a stream from a future
- * encoder that it can't parse), it changed the state to
- * \c FLAC__STREAM_DECODER_UNPARSEABLE_STREAM. Now the decoder instead
- * drops sync and calls the error callback with a new error code
- * \c FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM. This is
- * more robust. If your error callback does not discriminate on the the
- * error state, your code does not need to be changed.
- *
- * The encoder now has a new setting:
- * FLAC__stream_encoder_set_apodization(). This is for setting the
- * method used to window the data before LPC analysis. You only need to
- * add a call to this function if the default is not suitable. There
- * are also two new convenience functions that may be useful:
- * FLAC__metadata_object_cuesheet_calculate_cddb_id() and
- * FLAC__metadata_get_cuesheet().
- *
- * The \a bytes parameter to FLAC__StreamDecoderReadCallback,
- * FLAC__StreamEncoderReadCallback, and FLAC__StreamEncoderWriteCallback
- * is now \c size_t instead of \c unsigned.
- */
-
- /** \defgroup porting_1_1_3_to_1_1_4 Porting from FLAC 1.1.3 to 1.1.4
- * \ingroup porting
- *
- * \brief
- * This module describes porting from FLAC 1.1.3 to FLAC 1.1.4.
- *
- * There were no changes to any of the interfaces from 1.1.3 to 1.1.4.
- * There was a slight change in the implementation of
- * FLAC__stream_encoder_set_metadata(); the function now makes a copy
- * of the \a metadata array of pointers so the client no longer needs
- * to maintain it after the call. The objects themselves that are
- * pointed to by the array are still not copied though and must be
- * maintained until the call to FLAC__stream_encoder_finish().
- */
-
- /** \defgroup porting_1_1_4_to_1_2_0 Porting from FLAC 1.1.4 to 1.2.0
- * \ingroup porting
- *
- * \brief
- * This module describes porting from FLAC 1.1.4 to FLAC 1.2.0.
- *
- * There were only very minor changes to the interfaces from 1.1.4 to 1.2.0.
- * In libFLAC, \c FLAC__format_sample_rate_is_subset() was added.
- * In libFLAC++, \c FLAC::Decoder::Stream::get_decode_position() was added.
- *
- * Finally, value of the constant \c FLAC__FRAME_HEADER_RESERVED_LEN
- * has changed to reflect the conversion of one of the reserved bits
- * into active use. It used to be \c 2 and now is \c 1. However the
- * FLAC frame header length has not changed, so to skip the proper
- * number of bits, use \c FLAC__FRAME_HEADER_RESERVED_LEN +
- * \c FLAC__FRAME_HEADER_BLOCKING_STRATEGY_LEN
- */
-
- /** \defgroup flac FLAC C API
- *
- * The FLAC C API is the interface to libFLAC, a set of structures
- * describing the components of FLAC streams, and functions for
- * encoding and decoding streams, as well as manipulating FLAC
- * metadata in files.
- *
- * You should start with the format components as all other modules
- * are dependent on it.
- */
-
- #endif
- /********* End of inlined file: all.h *********/
-
- /********* Start of inlined file: bitmath.c *********/
-
- /********* Start of inlined file: juce_FlacHeader.h *********/
- // This file is included at the start of each FLAC .c file, just to do a few housekeeping
- // tasks..
-
- #define VERSION "1.2.1"
-
- #define FLAC__NO_DLL 1
-
- #ifdef _MSC_VER
- #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4312)
- #endif
-
- #if ! (defined (_WIN32) || defined (_WIN64) || defined (LINUX))
- #define FLAC__SYS_DARWIN 1
- #endif
- /********* End of inlined file: juce_FlacHeader.h *********/
-
- #if JUCE_USE_FLAC
-
- #if HAVE_CONFIG_H
- # include <config.h>
- #endif
-
- /********* Start of inlined file: bitmath.h *********/
- #ifndef FLAC__PRIVATE__BITMATH_H
- #define FLAC__PRIVATE__BITMATH_H
-
- unsigned FLAC__bitmath_ilog2(FLAC__uint32 v);
- unsigned FLAC__bitmath_ilog2_wide(FLAC__uint64 v);
- unsigned FLAC__bitmath_silog2(int v);
- unsigned FLAC__bitmath_silog2_wide(FLAC__int64 v);
-
- #endif
- /********* End of inlined file: bitmath.h *********/
-
- /* An example of what FLAC__bitmath_ilog2() computes:
- *
- * ilog2( 0) = assertion failure
- * ilog2( 1) = 0
- * ilog2( 2) = 1
- * ilog2( 3) = 1
- * ilog2( 4) = 2
- * ilog2( 5) = 2
- * ilog2( 6) = 2
- * ilog2( 7) = 2
- * ilog2( 8) = 3
- * ilog2( 9) = 3
- * ilog2(10) = 3
- * ilog2(11) = 3
- * ilog2(12) = 3
- * ilog2(13) = 3
- * ilog2(14) = 3
- * ilog2(15) = 3
- * ilog2(16) = 4
- * ilog2(17) = 4
- * ilog2(18) = 4
- */
- unsigned FLAC__bitmath_ilog2(FLAC__uint32 v)
- {
- unsigned l = 0;
- FLAC__ASSERT(v > 0);
- while(v >>= 1)
- l++;
- return l;
- }
-
- unsigned FLAC__bitmath_ilog2_wide(FLAC__uint64 v)
- {
- unsigned l = 0;
- FLAC__ASSERT(v > 0);
- while(v >>= 1)
- l++;
- return l;
- }
-
- /* An example of what FLAC__bitmath_silog2() computes:
- *
- * silog2(-10) = 5
- * silog2(- 9) = 5
- * silog2(- 8) = 4
- * silog2(- 7) = 4
- * silog2(- 6) = 4
- * silog2(- 5) = 4
- * silog2(- 4) = 3
- * silog2(- 3) = 3
- * silog2(- 2) = 2
- * silog2(- 1) = 2
- * silog2( 0) = 0
- * silog2( 1) = 2
- * silog2( 2) = 3
- * silog2( 3) = 3
- * silog2( 4) = 4
- * silog2( 5) = 4
- * silog2( 6) = 4
- * silog2( 7) = 4
- * silog2( 8) = 5
- * silog2( 9) = 5
- * silog2( 10) = 5
- */
- unsigned FLAC__bitmath_silog2(int v)
- {
- while(1) {
- if(v == 0) {
- return 0;
- }
- else if(v > 0) {
- unsigned l = 0;
- while(v) {
- l++;
- v >>= 1;
- }
- return l+1;
- }
- else if(v == -1) {
- return 2;
- }
- else {
- v++;
- v = -v;
- }
- }
- }
-
- unsigned FLAC__bitmath_silog2_wide(FLAC__int64 v)
- {
- while(1) {
- if(v == 0) {
- return 0;
- }
- else if(v > 0) {
- unsigned l = 0;
- while(v) {
- l++;
- v >>= 1;
- }
- return l+1;
- }
- else if(v == -1) {
- return 2;
- }
- else {
- v++;
- v = -v;
- }
- }
- }
-
- #endif
- /********* End of inlined file: bitmath.c *********/
-
- /********* Start of inlined file: bitreader.c *********/
-
- /********* Start of inlined file: juce_FlacHeader.h *********/
- // This file is included at the start of each FLAC .c file, just to do a few housekeeping
- // tasks..
-
- #define VERSION "1.2.1"
-
- #define FLAC__NO_DLL 1
-
- #ifdef _MSC_VER
- #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4312)
- #endif
-
- #if ! (defined (_WIN32) || defined (_WIN64) || defined (LINUX))
- #define FLAC__SYS_DARWIN 1
- #endif
- /********* End of inlined file: juce_FlacHeader.h *********/
-
- #if JUCE_USE_FLAC
-
- #if HAVE_CONFIG_H
- # include <config.h>
- #endif
-
- #include <stdlib.h> /* for malloc() */
- #include <string.h> /* for memcpy(), memset() */
- #ifdef _MSC_VER
- #include <winsock.h> /* for ntohl() */
- #elif defined FLAC__SYS_DARWIN
- #include <machine/endian.h> /* for ntohl() */
- #elif defined __MINGW32__
- #include <winsock.h> /* for ntohl() */
- #else
- #include <netinet/in.h> /* for ntohl() */
- #endif
-
- /********* Start of inlined file: bitreader.h *********/
- #ifndef FLAC__PRIVATE__BITREADER_H
- #define FLAC__PRIVATE__BITREADER_H
-
- #include <stdio.h> /* for FILE */
-
- /********* Start of inlined file: cpu.h *********/
- #ifndef FLAC__PRIVATE__CPU_H
- #define FLAC__PRIVATE__CPU_H
-
- #ifdef HAVE_CONFIG_H
- #include <config.h>
- #endif
-
- typedef enum {
- FLAC__CPUINFO_TYPE_IA32,
- FLAC__CPUINFO_TYPE_PPC,
- FLAC__CPUINFO_TYPE_UNKNOWN
- } FLAC__CPUInfo_Type;
-
- typedef struct {
- FLAC__bool cpuid;
- FLAC__bool bswap;
- FLAC__bool cmov;
- FLAC__bool mmx;
- FLAC__bool fxsr;
- FLAC__bool sse;
- FLAC__bool sse2;
- FLAC__bool sse3;
- FLAC__bool ssse3;
- FLAC__bool _3dnow;
- FLAC__bool ext3dnow;
- FLAC__bool extmmx;
- } FLAC__CPUInfo_IA32;
-
- typedef struct {
- FLAC__bool altivec;
- FLAC__bool ppc64;
- } FLAC__CPUInfo_PPC;
-
- typedef struct {
- FLAC__bool use_asm;
- FLAC__CPUInfo_Type type;
- union {
- FLAC__CPUInfo_IA32 ia32;
- FLAC__CPUInfo_PPC ppc;
- } data;
- } FLAC__CPUInfo;
-
- void FLAC__cpu_info(FLAC__CPUInfo *info);
-
- #ifndef FLAC__NO_ASM
- #ifdef FLAC__CPU_IA32
- #ifdef FLAC__HAS_NASM
- FLAC__uint32 FLAC__cpu_have_cpuid_asm_ia32(void);
- void FLAC__cpu_info_asm_ia32(FLAC__uint32 *flags_edx, FLAC__uint32 *flags_ecx);
- FLAC__uint32 FLAC__cpu_info_extended_amd_asm_ia32(void);
- #endif
- #endif
- #endif
-
- #endif
- /********* End of inlined file: cpu.h *********/
-
- /*
- * opaque structure definition
- */
- struct FLAC__BitReader;
- typedef struct FLAC__BitReader FLAC__BitReader;
-
- typedef FLAC__bool (*FLAC__BitReaderReadCallback)(FLAC__byte buffer[], size_t *bytes, void *client_data);
-
- /*
- * construction, deletion, initialization, etc functions
- */
- FLAC__BitReader *FLAC__bitreader_new(void);
- void FLAC__bitreader_delete(FLAC__BitReader *br);
- FLAC__bool FLAC__bitreader_init(FLAC__BitReader *br, FLAC__CPUInfo cpu, FLAC__BitReaderReadCallback rcb, void *cd);
- void FLAC__bitreader_free(FLAC__BitReader *br); /* does not 'free(br)' */
- FLAC__bool FLAC__bitreader_clear(FLAC__BitReader *br);
- void FLAC__bitreader_dump(const FLAC__BitReader *br, FILE *out);
-
- /*
- * CRC functions
- */
- void FLAC__bitreader_reset_read_crc16(FLAC__BitReader *br, FLAC__uint16 seed);
- FLAC__uint16 FLAC__bitreader_get_read_crc16(FLAC__BitReader *br);
-
- /*
- * info functions
- */
- FLAC__bool FLAC__bitreader_is_consumed_byte_aligned(const FLAC__BitReader *br);
- unsigned FLAC__bitreader_bits_left_for_byte_alignment(const FLAC__BitReader *br);
- unsigned FLAC__bitreader_get_input_bits_unconsumed(const FLAC__BitReader *br);
-
- /*
- * read functions
- */
-
- FLAC__bool FLAC__bitreader_read_raw_uint32(FLAC__BitReader *br, FLAC__uint32 *val, unsigned bits);
- FLAC__bool FLAC__bitreader_read_raw_int32(FLAC__BitReader *br, FLAC__int32 *val, unsigned bits);
- FLAC__bool FLAC__bitreader_read_raw_uint64(FLAC__BitReader *br, FLAC__uint64 *val, unsigned bits);
- FLAC__bool FLAC__bitreader_read_uint32_little_endian(FLAC__BitReader *br, FLAC__uint32 *val); /*only for bits=32*/
- FLAC__bool FLAC__bitreader_skip_bits_no_crc(FLAC__BitReader *br, unsigned bits); /* WATCHOUT: does not CRC the skipped data! */ /*@@@@ add to unit tests */
- FLAC__bool FLAC__bitreader_skip_byte_block_aligned_no_crc(FLAC__BitReader *br, unsigned nvals); /* WATCHOUT: does not CRC the read data! */
- FLAC__bool FLAC__bitreader_read_byte_block_aligned_no_crc(FLAC__BitReader *br, FLAC__byte *val, unsigned nvals); /* WATCHOUT: does not CRC the read data! */
- FLAC__bool FLAC__bitreader_read_unary_unsigned(FLAC__BitReader *br, unsigned *val);
- FLAC__bool FLAC__bitreader_read_rice_signed(FLAC__BitReader *br, int *val, unsigned parameter);
- FLAC__bool FLAC__bitreader_read_rice_signed_block(FLAC__BitReader *br, int vals[], unsigned nvals, unsigned parameter);
- #ifndef FLAC__NO_ASM
- # ifdef FLAC__CPU_IA32
- # ifdef FLAC__HAS_NASM
- FLAC__bool FLAC__bitreader_read_rice_signed_block_asm_ia32_bswap(FLAC__BitReader *br, int vals[], unsigned nvals, unsigned parameter);
- # endif
- # endif
- #endif
- #if 0 /* UNUSED */
- FLAC__bool FLAC__bitreader_read_golomb_signed(FLAC__BitReader *br, int *val, unsigned parameter);
- FLAC__bool FLAC__bitreader_read_golomb_unsigned(FLAC__BitReader *br, unsigned *val, unsigned parameter);
- #endif
- FLAC__bool FLAC__bitreader_read_utf8_uint32(FLAC__BitReader *br, FLAC__uint32 *val, FLAC__byte *raw, unsigned *rawlen);
- FLAC__bool FLAC__bitreader_read_utf8_uint64(FLAC__BitReader *br, FLAC__uint64 *val, FLAC__byte *raw, unsigned *rawlen);
-
- FLAC__bool bitreader_read_from_client_(FLAC__BitReader *br);
- #endif
- /********* End of inlined file: bitreader.h *********/
-
- /********* Start of inlined file: crc.h *********/
- #ifndef FLAC__PRIVATE__CRC_H
- #define FLAC__PRIVATE__CRC_H
-
- /* 8 bit CRC generator, MSB shifted first
- ** polynomial = x^8 + x^2 + x^1 + x^0
- ** init = 0
- */
- extern FLAC__byte const FLAC__crc8_table[256];
- #define FLAC__CRC8_UPDATE(data, crc) (crc) = FLAC__crc8_table[(crc) ^ (data)];
- void FLAC__crc8_update(const FLAC__byte data, FLAC__uint8 *crc);
- void FLAC__crc8_update_block(const FLAC__byte *data, unsigned len, FLAC__uint8 *crc);
- FLAC__uint8 FLAC__crc8(const FLAC__byte *data, unsigned len);
-
- /* 16 bit CRC generator, MSB shifted first
- ** polynomial = x^16 + x^15 + x^2 + x^0
- ** init = 0
- */
- extern unsigned FLAC__crc16_table[256];
-
- #define FLAC__CRC16_UPDATE(data, crc) (((((crc)<<8) & 0xffff) ^ FLAC__crc16_table[((crc)>>8) ^ (data)]))
- /* this alternate may be faster on some systems/compilers */
- #if 0
- #define FLAC__CRC16_UPDATE(data, crc) ((((crc)<<8) ^ FLAC__crc16_table[((crc)>>8) ^ (data)]) & 0xffff)
- #endif
-
- unsigned FLAC__crc16(const FLAC__byte *data, unsigned len);
-
- #endif
- /********* End of inlined file: crc.h *********/
-
- /* Things should be fastest when this matches the machine word size */
- /* WATCHOUT: if you change this you must also change the following #defines down to COUNT_ZERO_MSBS below to match */
- /* WATCHOUT: there are a few places where the code will not work unless brword is >= 32 bits wide */
- /* also, some sections currently only have fast versions for 4 or 8 bytes per word */
- typedef FLAC__uint32 brword;
- #define FLAC__BYTES_PER_WORD 4
- #define FLAC__BITS_PER_WORD 32
- #define FLAC__WORD_ALL_ONES ((FLAC__uint32)0xffffffff)
- /* SWAP_BE_WORD_TO_HOST swaps bytes in a brword (which is always big-endian) if necessary to match host byte order */
- #if WORDS_BIGENDIAN
- #define SWAP_BE_WORD_TO_HOST(x) (x)
- #else
- #if defined (_MSC_VER) && defined (_X86_)
- #define SWAP_BE_WORD_TO_HOST(x) local_swap32_(x)
- #else
- #define SWAP_BE_WORD_TO_HOST(x) ntohl(x)
- #endif
- #endif
- /* counts the # of zero MSBs in a word */
- #define COUNT_ZERO_MSBS(word) ( \
- (word) <= 0xffff ? \
- ( (word) <= 0xff? byte_to_unary_table[word] + 24 : byte_to_unary_table[(word) >> 8] + 16 ) : \
- ( (word) <= 0xffffff? byte_to_unary_table[word >> 16] + 8 : byte_to_unary_table[(word) >> 24] ) \
- )
- /* this alternate might be slightly faster on some systems/compilers: */
- #define COUNT_ZERO_MSBS2(word) ( (word) <= 0xff ? byte_to_unary_table[word] + 24 : ((word) <= 0xffff ? byte_to_unary_table[(word) >> 8] + 16 : ((word) <= 0xffffff ? byte_to_unary_table[(word) >> 16] + 8 : byte_to_unary_table[(word) >> 24])) )
-
- /*
- * This should be at least twice as large as the largest number of words
- * required to represent any 'number' (in any encoding) you are going to
- * read. With FLAC this is on the order of maybe a few hundred bits.
- * If the buffer is smaller than that, the decoder won't be able to read
- * in a whole number that is in a variable length encoding (e.g. Rice).
- * But to be practical it should be at least 1K bytes.
- *
- * Increase this number to decrease the number of read callbacks, at the
- * expense of using more memory. Or decrease for the reverse effect,
- * keeping in mind the limit from the first paragraph. The optimal size
- * also depends on the CPU cache size and other factors; some twiddling
- * may be necessary to squeeze out the best performance.
- */
- static const unsigned FLAC__BITREADER_DEFAULT_CAPACITY = 65536u / FLAC__BITS_PER_WORD; /* in words */
-
- static const unsigned char byte_to_unary_table[] = {
- 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
- 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,
- 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,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- };
-
- #ifdef min
- #undef min
- #endif
- #define min(x,y) ((x)<(y)?(x):(y))
- #ifdef max
- #undef max
- #endif
- #define max(x,y) ((x)>(y)?(x):(y))
-
- /* adjust for compilers that can't understand using LLU suffix for uint64_t literals */
- #ifdef _MSC_VER
- #define FLAC__U64L(x) x
- #else
- #define FLAC__U64L(x) x##LLU
- #endif
-
- #ifndef FLaC__INLINE
- #define FLaC__INLINE
- #endif
-
- /* WATCHOUT: assembly routines rely on the order in which these fields are declared */
- struct FLAC__BitReader {
- /* any partially-consumed word at the head will stay right-justified as bits are consumed from the left */
- /* any incomplete word at the tail will be left-justified, and bytes from the read callback are added on the right */
- brword *buffer;
- unsigned capacity; /* in words */
- unsigned words; /* # of completed words in buffer */
- unsigned bytes; /* # of bytes in incomplete word at buffer[words] */
- unsigned consumed_words; /* #words ... */
- unsigned consumed_bits; /* ... + (#bits of head word) already consumed from the front of buffer */
- unsigned read_crc16; /* the running frame CRC */
- unsigned crc16_align; /* the number of bits in the current consumed word that should not be CRC'd */
- FLAC__BitReaderReadCallback read_callback;
- void *client_data;
- FLAC__CPUInfo cpu_info;
- };
-
- static FLaC__INLINE void crc16_update_word_(FLAC__BitReader *br, brword word)
- {
- register unsigned crc = br->read_crc16;
- #if FLAC__BYTES_PER_WORD == 4
- switch(br->crc16_align) {
- case 0: crc = FLAC__CRC16_UPDATE((unsigned)(word >> 24), crc);
- case 8: crc = FLAC__CRC16_UPDATE((unsigned)((word >> 16) & 0xff), crc);
- case 16: crc = FLAC__CRC16_UPDATE((unsigned)((word >> 8) & 0xff), crc);
- case 24: br->read_crc16 = FLAC__CRC16_UPDATE((unsigned)(word & 0xff), crc);
- }
- #elif FLAC__BYTES_PER_WORD == 8
- switch(br->crc16_align) {
- case 0: crc = FLAC__CRC16_UPDATE((unsigned)(word >> 56), crc);
- case 8: crc = FLAC__CRC16_UPDATE((unsigned)((word >> 48) & 0xff), crc);
- case 16: crc = FLAC__CRC16_UPDATE((unsigned)((word >> 40) & 0xff), crc);
- case 24: crc = FLAC__CRC16_UPDATE((unsigned)((word >> 32) & 0xff), crc);
- case 32: crc = FLAC__CRC16_UPDATE((unsigned)((word >> 24) & 0xff), crc);
- case 40: crc = FLAC__CRC16_UPDATE((unsigned)((word >> 16) & 0xff), crc);
- case 48: crc = FLAC__CRC16_UPDATE((unsigned)((word >> 8) & 0xff), crc);
- case 56: br->read_crc16 = FLAC__CRC16_UPDATE((unsigned)(word & 0xff), crc);
- }
- #else
- for( ; br->crc16_align < FLAC__BITS_PER_WORD; br->crc16_align += 8)
- crc = FLAC__CRC16_UPDATE((unsigned)((word >> (FLAC__BITS_PER_WORD-8-br->crc16_align)) & 0xff), crc);
- br->read_crc16 = crc;
- #endif
- br->crc16_align = 0;
- }
-
- /* would be static except it needs to be called by asm routines */
- FLAC__bool bitreader_read_from_client_(FLAC__BitReader *br)
- {
- unsigned start, end;
- size_t bytes;
- FLAC__byte *target;
-
- /* first shift the unconsumed buffer data toward the front as much as possible */
- if(br->consumed_words > 0) {
- start = br->consumed_words;
- end = br->words + (br->bytes? 1:0);
- memmove(br->buffer, br->buffer+start, FLAC__BYTES_PER_WORD * (end - start));
-
- br->words -= start;
- br->consumed_words = 0;
- }
-
- /*
- * set the target for reading, taking into account word alignment and endianness
- */
- bytes = (br->capacity - br->words) * FLAC__BYTES_PER_WORD - br->bytes;
- if(bytes == 0)
- return false; /* no space left, buffer is too small; see note for FLAC__BITREADER_DEFAULT_CAPACITY */
- target = ((FLAC__byte*)(br->buffer+br->words)) + br->bytes;
-
- /* before reading, if the existing reader looks like this (say brword is 32 bits wide)
- * bitstream : 11 22 33 44 55 br->words=1 br->bytes=1 (partial tail word is left-justified)
- * buffer[BE]: 11 22 33 44 55 ?? ?? ?? (shown layed out as bytes sequentially in memory)
- * buffer[LE]: 44 33 22 11 ?? ?? ?? 55 (?? being don't-care)
- * ^^-------target, bytes=3
- * on LE machines, have to byteswap the odd tail word so nothing is
- * overwritten:
- */
- #if WORDS_BIGENDIAN
- #else
- if(br->bytes)
- br->buffer[br->words] = SWAP_BE_WORD_TO_HOST(br->buffer[br->words]);
- #endif
-
- /* now it looks like:
- * bitstream : 11 22 33 44 55 br->words=1 br->bytes=1
- * buffer[BE]: 11 22 33 44 55 ?? ?? ??
- * buffer[LE]: 44 33 22 11 55 ?? ?? ??
- * ^^-------target, bytes=3
- */
-
- /* read in the data; note that the callback may return a smaller number of bytes */
- if(!br->read_callback(target, &bytes, br->client_data))
- return false;
-
- /* after reading bytes 66 77 88 99 AA BB CC DD EE FF from the client:
- * bitstream : 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF
- * buffer[BE]: 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF ??
- * buffer[LE]: 44 33 22 11 55 66 77 88 99 AA BB CC DD EE FF ??
- * now have to byteswap on LE machines:
- */
- #if WORDS_BIGENDIAN
- #else
- end = (br->words*FLAC__BYTES_PER_WORD + br->bytes + bytes + (FLAC__BYTES_PER_WORD-1)) / FLAC__BYTES_PER_WORD;
- # if defined(_MSC_VER) && defined (_X86_) && (FLAC__BYTES_PER_WORD == 4)
- if(br->cpu_info.type == FLAC__CPUINFO_TYPE_IA32 && br->cpu_info.data.ia32.bswap) {
- start = br->words;
- local_swap32_block_(br->buffer + start, end - start);
- }
- else
- # endif
- for(start = br->words; start < end; start++)
- br->buffer[start] = SWAP_BE_WORD_TO_HOST(br->buffer[start]);
- #endif
-
- /* now it looks like:
- * bitstream : 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF
- * buffer[BE]: 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF ??
- * buffer[LE]: 44 33 22 11 88 77 66 55 CC BB AA 99 ?? FF EE DD
- * finally we'll update the reader values:
- */
- end = br->words*FLAC__BYTES_PER_WORD + br->bytes + bytes;
- br->words = end / FLAC__BYTES_PER_WORD;
- br->bytes = end % FLAC__BYTES_PER_WORD;
-
- return true;
- }
-
- /***********************************************************************
- *
- * Class constructor/destructor
- *
- ***********************************************************************/
-
- FLAC__BitReader *FLAC__bitreader_new(void)
- {
- FLAC__BitReader *br = (FLAC__BitReader*)calloc(1, sizeof(FLAC__BitReader));
-
- /* calloc() implies:
- memset(br, 0, sizeof(FLAC__BitReader));
- br->buffer = 0;
- br->capacity = 0;
- br->words = br->bytes = 0;
- br->consumed_words = br->consumed_bits = 0;
- br->read_callback = 0;
- br->client_data = 0;
- */
- return br;
- }
-
- void FLAC__bitreader_delete(FLAC__BitReader *br)
- {
- FLAC__ASSERT(0 != br);
-
- FLAC__bitreader_free(br);
- free(br);
- }
-
- /***********************************************************************
- *
- * Public class methods
- *
- ***********************************************************************/
-
- FLAC__bool FLAC__bitreader_init(FLAC__BitReader *br, FLAC__CPUInfo cpu, FLAC__BitReaderReadCallback rcb, void *cd)
- {
- FLAC__ASSERT(0 != br);
-
- br->words = br->bytes = 0;
- br->consumed_words = br->consumed_bits = 0;
- br->capacity = FLAC__BITREADER_DEFAULT_CAPACITY;
- br->buffer = (brword*)malloc(sizeof(brword) * br->capacity);
- if(br->buffer == 0)
- return false;
- br->read_callback = rcb;
- br->client_data = cd;
- br->cpu_info = cpu;
-
- return true;
- }
-
- void FLAC__bitreader_free(FLAC__BitReader *br)
- {
- FLAC__ASSERT(0 != br);
-
- if(0 != br->buffer)
- free(br->buffer);
- br->buffer = 0;
- br->capacity = 0;
- br->words = br->bytes = 0;
- br->consumed_words = br->consumed_bits = 0;
- br->read_callback = 0;
- br->client_data = 0;
- }
-
- FLAC__bool FLAC__bitreader_clear(FLAC__BitReader *br)
- {
- br->words = br->bytes = 0;
- br->consumed_words = br->consumed_bits = 0;
- return true;
- }
-
- void FLAC__bitreader_dump(const FLAC__BitReader *br, FILE *out)
- {
- unsigned i, j;
- if(br == 0) {
- fprintf(out, "bitreader is NULL\n");
- }
- else {
- fprintf(out, "bitreader: capacity=%u words=%u bytes=%u consumed: words=%u, bits=%u\n", br->capacity, br->words, br->bytes, br->consumed_words, br->consumed_bits);
-
- for(i = 0; i < br->words; i++) {
- fprintf(out, "%08X: ", i);
- for(j = 0; j < FLAC__BITS_PER_WORD; j++)
- if(i < br->consumed_words || (i == br->consumed_words && j < br->consumed_bits))
- fprintf(out, ".");
- else
- fprintf(out, "%01u", br->buffer[i] & (1 << (FLAC__BITS_PER_WORD-j-1)) ? 1:0);
- fprintf(out, "\n");
- }
- if(br->bytes > 0) {
- fprintf(out, "%08X: ", i);
- for(j = 0; j < br->bytes*8; j++)
- if(i < br->consumed_words || (i == br->consumed_words && j < br->consumed_bits))
- fprintf(out, ".");
- else
- fprintf(out, "%01u", br->buffer[i] & (1 << (br->bytes*8-j-1)) ? 1:0);
- fprintf(out, "\n");
- }
- }
- }
-
- void FLAC__bitreader_reset_read_crc16(FLAC__BitReader *br, FLAC__uint16 seed)
- {
- FLAC__ASSERT(0 != br);
- FLAC__ASSERT(0 != br->buffer);
- FLAC__ASSERT((br->consumed_bits & 7) == 0);
-
- br->read_crc16 = (unsigned)seed;
- br->crc16_align = br->consumed_bits;
- }
-
- FLAC__uint16 FLAC__bitreader_get_read_crc16(FLAC__BitReader *br)
- {
- FLAC__ASSERT(0 != br);
- FLAC__ASSERT(0 != br->buffer);
- FLAC__ASSERT((br->consumed_bits & 7) == 0);
- FLAC__ASSERT(br->crc16_align <= br->consumed_bits);
-
- /* CRC any tail bytes in a partially-consumed word */
- if(br->consumed_bits) {
- const brword tail = br->buffer[br->consumed_words];
- for( ; br->crc16_align < br->consumed_bits; br->crc16_align += 8)
- br->read_crc16 = FLAC__CRC16_UPDATE((unsigned)((tail >> (FLAC__BITS_PER_WORD-8-br->crc16_align)) & 0xff), br->read_crc16);
- }
- return br->read_crc16;
- }
-
- FLaC__INLINE FLAC__bool FLAC__bitreader_is_consumed_byte_aligned(const FLAC__BitReader *br)
- {
- return ((br->consumed_bits & 7) == 0);
- }
-
- FLaC__INLINE unsigned FLAC__bitreader_bits_left_for_byte_alignment(const FLAC__BitReader *br)
- {
- return 8 - (br->consumed_bits & 7);
- }
-
- FLaC__INLINE unsigned FLAC__bitreader_get_input_bits_unconsumed(const FLAC__BitReader *br)
- {
- return (br->words-br->consumed_words)*FLAC__BITS_PER_WORD + br->bytes*8 - br->consumed_bits;
- }
-
- FLaC__INLINE FLAC__bool FLAC__bitreader_read_raw_uint32(FLAC__BitReader *br, FLAC__uint32 *val, unsigned bits)
- {
- FLAC__ASSERT(0 != br);
- FLAC__ASSERT(0 != br->buffer);
-
- FLAC__ASSERT(bits <= 32);
- FLAC__ASSERT((br->capacity*FLAC__BITS_PER_WORD) * 2 >= bits);
- FLAC__ASSERT(br->consumed_words <= br->words);
-
- /* WATCHOUT: code does not work with <32bit words; we can make things much faster with this assertion */
- FLAC__ASSERT(FLAC__BITS_PER_WORD >= 32);
-
- if(bits == 0) { /* OPT: investigate if this can ever happen, maybe change to assertion */
- *val = 0;
- return true;
- }
-
- while((br->words-br->consumed_words)*FLAC__BITS_PER_WORD + br->bytes*8 - br->consumed_bits < bits) {
- if(!bitreader_read_from_client_(br))
- return false;
- }
- if(br->consumed_words < br->words) { /* if we've not consumed up to a partial tail word... */
- /* OPT: taking out the consumed_bits==0 "else" case below might make things faster if less code allows the compiler to inline this function */
- if(br->consumed_bits) {
- /* this also works when consumed_bits==0, it's just a little slower than necessary for that case */
- const unsigned n = FLAC__BITS_PER_WORD - br->consumed_bits;
- const brword word = br->buffer[br->consumed_words];
- if(bits < n) {
- *val = (word & (FLAC__WORD_ALL_ONES >> br->consumed_bits)) >> (n-bits);
- br->consumed_bits += bits;
- return true;
- }
- *val = word & (FLAC__WORD_ALL_ONES >> br->consumed_bits);
- bits -= n;
- crc16_update_word_(br, word);
- br->consumed_words++;
- br->consumed_bits = 0;
- if(bits) { /* if there are still bits left to read, there have to be less than 32 so they will all be in the next word */
- *val <<= bits;
- *val |= (br->buffer[br->consumed_words] >> (FLAC__BITS_PER_WORD-bits));
- br->consumed_bits = bits;
- }
- return true;
- }
- else {
- const brword word = br->buffer[br->consumed_words];
- if(bits < FLAC__BITS_PER_WORD) {
- *val = word >> (FLAC__BITS_PER_WORD-bits);
- br->consumed_bits = bits;
- return true;
- }
- /* at this point 'bits' must be == FLAC__BITS_PER_WORD; because of previous assertions, it can't be larger */
- *val = word;
- crc16_update_word_(br, word);
- br->consumed_words++;
- return true;
- }
- }
- else {
- /* in this case we're starting our read at a partial tail word;
- * the reader has guaranteed that we have at least 'bits' bits
- * available to read, which makes this case simpler.
- */
- /* OPT: taking out the consumed_bits==0 "else" case below might make things faster if less code allows the compiler to inline this function */
- if(br->consumed_bits) {
- /* this also works when consumed_bits==0, it's just a little slower than necessary for that case */
- FLAC__ASSERT(br->consumed_bits + bits <= br->bytes*8);
- *val = (br->buffer[br->consumed_words] & (FLAC__WORD_ALL_ONES >> br->consumed_bits)) >> (FLAC__BITS_PER_WORD-br->consumed_bits-bits);
- br->consumed_bits += bits;
- return true;
- }
- else {
- *val = br->buffer[br->consumed_words] >> (FLAC__BITS_PER_WORD-bits);
- br->consumed_bits += bits;
- return true;
- }
- }
- }
-
- FLAC__bool FLAC__bitreader_read_raw_int32(FLAC__BitReader *br, FLAC__int32 *val, unsigned bits)
- {
- /* OPT: inline raw uint32 code here, or make into a macro if possible in the .h file */
- if(!FLAC__bitreader_read_raw_uint32(br, (FLAC__uint32*)val, bits))
- return false;
- /* sign-extend: */
- *val <<= (32-bits);
- *val >>= (32-bits);
- return true;
- }
-
- FLAC__bool FLAC__bitreader_read_raw_uint64(FLAC__BitReader *br, FLAC__uint64 *val, unsigned bits)
- {
- FLAC__uint32 hi, lo;
-
- if(bits > 32) {
- if(!FLAC__bitreader_read_raw_uint32(br, &hi, bits-32))
- return false;
- if(!FLAC__bitreader_read_raw_uint32(br, &lo, 32))
- return false;
- *val = hi;
- *val <<= 32;
- *val |= lo;
- }
- else {
- if(!FLAC__bitreader_read_raw_uint32(br, &lo, bits))
- return false;
- *val = lo;
- }
- return true;
- }
-
- FLaC__INLINE FLAC__bool FLAC__bitreader_read_uint32_little_endian(FLAC__BitReader *br, FLAC__uint32 *val)
- {
- FLAC__uint32 x8, x32 = 0;
-
- /* this doesn't need to be that fast as currently it is only used for vorbis comments */
-
- if(!FLAC__bitreader_read_raw_uint32(br, &x32, 8))
- return false;
-
- if(!FLAC__bitreader_read_raw_uint32(br, &x8, 8))
- return false;
- x32 |= (x8 << 8);
-
- if(!FLAC__bitreader_read_raw_uint32(br, &x8, 8))
- return false;
- x32 |= (x8 << 16);
-
- if(!FLAC__bitreader_read_raw_uint32(br, &x8, 8))
- return false;
- x32 |= (x8 << 24);
-
- *val = x32;
- return true;
- }
-
- FLAC__bool FLAC__bitreader_skip_bits_no_crc(FLAC__BitReader *br, unsigned bits)
- {
- /*
- * OPT: a faster implementation is possible but probably not that useful
- * since this is only called a couple of times in the metadata readers.
- */
- FLAC__ASSERT(0 != br);
- FLAC__ASSERT(0 != br->buffer);
-
- if(bits > 0) {
- const unsigned n = br->consumed_bits & 7;
- unsigned m;
- FLAC__uint32 x;
-
- if(n != 0) {
- m = min(8-n, bits);
- if(!FLAC__bitreader_read_raw_uint32(br, &x, m))
- return false;
- bits -= m;
- }
- m = bits / 8;
- if(m > 0) {
- if(!FLAC__bitreader_skip_byte_block_aligned_no_crc(br, m))
- return false;
- bits %= 8;
- }
- if(bits > 0) {
- if(!FLAC__bitreader_read_raw_uint32(br, &x, bits))
- return false;
- }
- }
-
- return true;
- }
-
- FLAC__bool FLAC__bitreader_skip_byte_block_aligned_no_crc(FLAC__BitReader *br, unsigned nvals)
- {
- FLAC__uint32 x;
-
- FLAC__ASSERT(0 != br);
- FLAC__ASSERT(0 != br->buffer);
- FLAC__ASSERT(FLAC__bitreader_is_consumed_byte_aligned(br));
-
- /* step 1: skip over partial head word to get word aligned */
- while(nvals && br->consumed_bits) { /* i.e. run until we read 'nvals' bytes or we hit the end of the head word */
- if(!FLAC__bitreader_read_raw_uint32(br, &x, 8))
- return false;
- nvals--;
- }
- if(0 == nvals)
- return true;
- /* step 2: skip whole words in chunks */
- while(nvals >= FLAC__BYTES_PER_WORD) {
- if(br->consumed_words < br->words) {
- br->consumed_words++;
- nvals -= FLAC__BYTES_PER_WORD;
- }
- else if(!bitreader_read_from_client_(br))
- return false;
- }
- /* step 3: skip any remainder from partial tail bytes */
- while(nvals) {
- if(!FLAC__bitreader_read_raw_uint32(br, &x, 8))
- return false;
- nvals--;
- }
-
- return true;
- }
-
- FLAC__bool FLAC__bitreader_read_byte_block_aligned_no_crc(FLAC__BitReader *br, FLAC__byte *val, unsigned nvals)
- {
- FLAC__uint32 x;
-
- FLAC__ASSERT(0 != br);
- FLAC__ASSERT(0 != br->buffer);
- FLAC__ASSERT(FLAC__bitreader_is_consumed_byte_aligned(br));
-
- /* step 1: read from partial head word to get word aligned */
- while(nvals && br->consumed_bits) { /* i.e. run until we read 'nvals' bytes or we hit the end of the head word */
- if(!FLAC__bitreader_read_raw_uint32(br, &x, 8))
- return false;
- *val++ = (FLAC__byte)x;
- nvals--;
- }
- if(0 == nvals)
- return true;
- /* step 2: read whole words in chunks */
- while(nvals >= FLAC__BYTES_PER_WORD) {
- if(br->consumed_words < br->words) {
- const brword word = br->buffer[br->consumed_words++];
- #if FLAC__BYTES_PER_WORD == 4
- val[0] = (FLAC__byte)(word >> 24);
- val[1] = (FLAC__byte)(word >> 16);
- val[2] = (FLAC__byte)(word >> 8);
- val[3] = (FLAC__byte)word;
- #elif FLAC__BYTES_PER_WORD == 8
- val[0] = (FLAC__byte)(word >> 56);
- val[1] = (FLAC__byte)(word >> 48);
- val[2] = (FLAC__byte)(word >> 40);
- val[3] = (FLAC__byte)(word >> 32);
- val[4] = (FLAC__byte)(word >> 24);
- val[5] = (FLAC__byte)(word >> 16);
- val[6] = (FLAC__byte)(word >> 8);
- val[7] = (FLAC__byte)word;
- #else
- for(x = 0; x < FLAC__BYTES_PER_WORD; x++)
- val[x] = (FLAC__byte)(word >> (8*(FLAC__BYTES_PER_WORD-x-1)));
- #endif
- val += FLAC__BYTES_PER_WORD;
- nvals -= FLAC__BYTES_PER_WORD;
- }
- else if(!bitreader_read_from_client_(br))
- return false;
- }
- /* step 3: read any remainder from partial tail bytes */
- while(nvals) {
- if(!FLAC__bitreader_read_raw_uint32(br, &x, 8))
- return false;
- *val++ = (FLAC__byte)x;
- nvals--;
- }
-
- return true;
- }
-
- FLaC__INLINE FLAC__bool FLAC__bitreader_read_unary_unsigned(FLAC__BitReader *br, unsigned *val)
- #if 0 /* slow but readable version */
- {
- unsigned bit;
-
- FLAC__ASSERT(0 != br);
- FLAC__ASSERT(0 != br->buffer);
-
- *val = 0;
- while(1) {
- if(!FLAC__bitreader_read_bit(br, &bit))
- return false;
- if(bit)
- break;
- else
- *val++;
- }
- return true;
- }
- #else
- {
- unsigned i;
-
- FLAC__ASSERT(0 != br);
- FLAC__ASSERT(0 != br->buffer);
-
- *val = 0;
- while(1) {
- while(br->consumed_words < br->words) { /* if we've not consumed up to a partial tail word... */
- brword b = br->buffer[br->consumed_words] << br->consumed_bits;
- if(b) {
- i = COUNT_ZERO_MSBS(b);
- *val += i;
- i++;
- br->consumed_bits += i;
- if(br->consumed_bits >= FLAC__BITS_PER_WORD) { /* faster way of testing if(br->consumed_bits == FLAC__BITS_PER_WORD) */
- crc16_update_word_(br, br->buffer[br->consumed_words]);
- br->consumed_words++;
- br->consumed_bits = 0;
- }
- return true;
- }
- else {
- *val += FLAC__BITS_PER_WORD - br->consumed_bits;
- crc16_update_word_(br, br->buffer[br->consumed_words]);
- br->consumed_words++;
- br->consumed_bits = 0;
- /* didn't find stop bit yet, have to keep going... */
- }
- }
- /* at this point we've eaten up all the whole words; have to try
- * reading through any tail bytes before calling the read callback.
- * this is a repeat of the above logic adjusted for the fact we
- * don't have a whole word. note though if the client is feeding
- * us data a byte at a time (unlikely), br->consumed_bits may not
- * be zero.
- */
- if(br->bytes) {
- const unsigned end = br->bytes * 8;
- brword b = (br->buffer[br->consumed_words] & (FLAC__WORD_ALL_ONES << (FLAC__BITS_PER_WORD-end))) << br->consumed_bits;
- if(b) {
- i = COUNT_ZERO_MSBS(b);
- *val += i;
- i++;
- br->consumed_bits += i;
- FLAC__ASSERT(br->consumed_bits < FLAC__BITS_PER_WORD);
- return true;
- }
- else {
- *val += end - br->consumed_bits;
- br->consumed_bits += end;
- FLAC__ASSERT(br->consumed_bits < FLAC__BITS_PER_WORD);
- /* didn't find stop bit yet, have to keep going... */
- }
- }
- if(!bitreader_read_from_client_(br))
- return false;
- }
- }
- #endif
-
- FLAC__bool FLAC__bitreader_read_rice_signed(FLAC__BitReader *br, int *val, unsigned parameter)
- {
- FLAC__uint32 lsbs = 0, msbs = 0;
- unsigned uval;
-
- FLAC__ASSERT(0 != br);
- FLAC__ASSERT(0 != br->buffer);
- FLAC__ASSERT(parameter <= 31);
-
- /* read the unary MSBs and end bit */
- if(!FLAC__bitreader_read_unary_unsigned(br, (unsigned int*) &msbs))
- return false;
-
- /* read the binary LSBs */
- if(!FLAC__bitreader_read_raw_uint32(br, &lsbs, parameter))
- return false;
-
- /* compose the value */
- uval = (msbs << parameter) | lsbs;
- if(uval & 1)
- *val = -((int)(uval >> 1)) - 1;
- else
- *val = (int)(uval >> 1);
-
- return true;
- }
-
- /* this is by far the most heavily used reader call. it ain't pretty but it's fast */
- /* a lot of the logic is copied, then adapted, from FLAC__bitreader_read_unary_unsigned() and FLAC__bitreader_read_raw_uint32() */
- FLAC__bool FLAC__bitreader_read_rice_signed_block(FLAC__BitReader *br, int vals[], unsigned nvals, unsigned parameter)
- /* OPT: possibly faster version for use with MSVC */
- #ifdef _MSC_VER
- {
- unsigned i;
- unsigned uval = 0;
- unsigned bits; /* the # of binary LSBs left to read to finish a rice codeword */
-
- /* try and get br->consumed_words and br->consumed_bits into register;
- * must remember to flush them back to *br before calling other
- * bitwriter functions that use them, and before returning */
- register unsigned cwords;
- register unsigned cbits;
-
- FLAC__ASSERT(0 != br);
- FLAC__ASSERT(0 != br->buffer);
- /* WATCHOUT: code does not work with <32bit words; we can make things much faster with this assertion */
- FLAC__ASSERT(FLAC__BITS_PER_WORD >= 32);
- FLAC__ASSERT(parameter < 32);
- /* the above two asserts also guarantee that the binary part never straddles more that 2 words, so we don't have to loop to read it */
-
- if(nvals == 0)
- return true;
-
- cbits = br->consumed_bits;
- cwords = br->consumed_words;
-
- while(1) {
-
- /* read unary part */
- while(1) {
- while(cwords < br->words) { /* if we've not consumed up to a partial tail word... */
- brword b = br->buffer[cwords] << cbits;
- if(b) {
- #if 0 /* slower, probably due to bad register allocation... */ && defined FLAC__CPU_IA32 && !defined FLAC__NO_ASM && FLAC__BITS_PER_WORD == 32
- __asm {
- bsr eax, b
- not eax
- and eax, 31
- mov i, eax
- }
- #else
- i = COUNT_ZERO_MSBS(b);
- #endif
- uval += i;
- bits = parameter;
- i++;
- cbits += i;
- if(cbits == FLAC__BITS_PER_WORD) {
- crc16_update_word_(br, br->buffer[cwords]);
- cwords++;
- cbits = 0;
- }
- goto break1;
- }
- else {
- uval += FLAC__BITS_PER_WORD - cbits;
- crc16_update_word_(br, br->buffer[cwords]);
- cwords++;
- cbits = 0;
- /* didn't find stop bit yet, have to keep going... */
- }
- }
- /* at this point we've eaten up all the whole words; have to try
- * reading through any tail bytes before calling the read callback.
- * this is a repeat of the above logic adjusted for the fact we
- * don't have a whole word. note though if the client is feeding
- * us data a byte at a time (unlikely), br->consumed_bits may not
- * be zero.
- */
- if(br->bytes) {
- const unsigned end = br->bytes * 8;
- brword b = (br->buffer[cwords] & (FLAC__WORD_ALL_ONES << (FLAC__BITS_PER_WORD-end))) << cbits;
- if(b) {
- i = COUNT_ZERO_MSBS(b);
- uval += i;
- bits = parameter;
- i++;
- cbits += i;
- FLAC__ASSERT(cbits < FLAC__BITS_PER_WORD);
- goto break1;
- }
- else {
- uval += end - cbits;
- cbits += end;
- FLAC__ASSERT(cbits < FLAC__BITS_PER_WORD);
- /* didn't find stop bit yet, have to keep going... */
- }
- }
- /* flush registers and read; bitreader_read_from_client_() does
- * not touch br->consumed_bits at all but we still need to set
- * it in case it fails and we have to return false.
- */
- br->consumed_bits = cbits;
- br->consumed_words = cwords;
- if(!bitreader_read_from_client_(br))
- return false;
- cwords = br->consumed_words;
- }
- break1:
- /* read binary part */
- FLAC__ASSERT(cwords <= br->words);
-
- if(bits) {
- while((br->words-cwords)*FLAC__BITS_PER_WORD + br->bytes*8 - cbits < bits) {
- /* flush registers and read; bitreader_read_from_client_() does
- * not touch br->consumed_bits at all but we still need to set
- * it in case it fails and we have to return false.
- */
- br->consumed_bits = cbits;
- br->consumed_words = cwords;
- if(!bitreader_read_from_client_(br))
- return false;
- cwords = br->consumed_words;
- }
- if(cwords < br->words) { /* if we've not consumed up to a partial tail word... */
- if(cbits) {
- /* this also works when consumed_bits==0, it's just a little slower than necessary for that case */
- const unsigned n = FLAC__BITS_PER_WORD - cbits;
- const brword word = br->buffer[cwords];
- if(bits < n) {
- uval <<= bits;
- uval |= (word & (FLAC__WORD_ALL_ONES >> cbits)) >> (n-bits);
- cbits += bits;
- goto break2;
- }
- uval <<= n;
- uval |= word & (FLAC__WORD_ALL_ONES >> cbits);
- bits -= n;
- crc16_update_word_(br, word);
- cwords++;
- cbits = 0;
- if(bits) { /* if there are still bits left to read, there have to be less than 32 so they will all be in the next word */
- uval <<= bits;
- uval |= (br->buffer[cwords] >> (FLAC__BITS_PER_WORD-bits));
- cbits = bits;
- }
- goto break2;
- }
- else {
- FLAC__ASSERT(bits < FLAC__BITS_PER_WORD);
- uval <<= bits;
- uval |= br->buffer[cwords] >> (FLAC__BITS_PER_WORD-bits);
- cbits = bits;
- goto break2;
- }
- }
- else {
- /* in this case we're starting our read at a partial tail word;
- * the reader has guaranteed that we have at least 'bits' bits
- * available to read, which makes this case simpler.
- */
- uval <<= bits;
- if(cbits) {
- /* this also works when consumed_bits==0, it's just a little slower than necessary for that case */
- FLAC__ASSERT(cbits + bits <= br->bytes*8);
- uval |= (br->buffer[cwords] & (FLAC__WORD_ALL_ONES >> cbits)) >> (FLAC__BITS_PER_WORD-cbits-bits);
- cbits += bits;
- goto break2;
- }
- else {
- uval |= br->buffer[cwords] >> (FLAC__BITS_PER_WORD-bits);
- cbits += bits;
- goto break2;
- }
- }
- }
- break2:
- /* compose the value */
- *vals = (int)(uval >> 1 ^ -(int)(uval & 1));
-
- /* are we done? */
- --nvals;
- if(nvals == 0) {
- br->consumed_bits = cbits;
- br->consumed_words = cwords;
- return true;
- }
-
- uval = 0;
- ++vals;
-
- }
- }
- #else
- {
- unsigned i;
- unsigned uval = 0;
-
- /* try and get br->consumed_words and br->consumed_bits into register;
- * must remember to flush them back to *br before calling other
- * bitwriter functions that use them, and before returning */
- register unsigned cwords;
- register unsigned cbits;
- unsigned ucbits; /* keep track of the number of unconsumed bits in the buffer */
-
- FLAC__ASSERT(0 != br);
- FLAC__ASSERT(0 != br->buffer);
- /* WATCHOUT: code does not work with <32bit words; we can make things much faster with this assertion */
- FLAC__ASSERT(FLAC__BITS_PER_WORD >= 32);
- FLAC__ASSERT(parameter < 32);
- /* the above two asserts also guarantee that the binary part never straddles more than 2 words, so we don't have to loop to read it */
-
- if(nvals == 0)
- return true;
-
- cbits = br->consumed_bits;
- cwords = br->consumed_words;
- ucbits = (br->words-cwords)*FLAC__BITS_PER_WORD + br->bytes*8 - cbits;
-
- while(1) {
-
- /* read unary part */
- while(1) {
- while(cwords < br->words) { /* if we've not consumed up to a partial tail word... */
- brword b = br->buffer[cwords] << cbits;
- if(b) {
- #if 0 /* is not discernably faster... */ && defined FLAC__CPU_IA32 && !defined FLAC__NO_ASM && FLAC__BITS_PER_WORD == 32 && defined __GNUC__
- asm volatile (
- "bsrl %1, %0;"
- "notl %0;"
- "andl $31, %0;"
- : "=r"(i)
- : "r"(b)
- );
- #else
- i = COUNT_ZERO_MSBS(b);
- #endif
- uval += i;
- cbits += i;
- cbits++; /* skip over stop bit */
- if(cbits >= FLAC__BITS_PER_WORD) { /* faster way of testing if(cbits == FLAC__BITS_PER_WORD) */
- crc16_update_word_(br, br->buffer[cwords]);
- cwords++;
- cbits = 0;
- }
- goto break1;
- }
- else {
- uval += FLAC__BITS_PER_WORD - cbits;
- crc16_update_word_(br, br->buffer[cwords]);
- cwords++;
- cbits = 0;
- /* didn't find stop bit yet, have to keep going... */
- }
- }
- /* at this point we've eaten up all the whole words; have to try
- * reading through any tail bytes before calling the read callback.
- * this is a repeat of the above logic adjusted for the fact we
- * don't have a whole word. note though if the client is feeding
- * us data a byte at a time (unlikely), br->consumed_bits may not
- * be zero.
- */
- if(br->bytes) {
- const unsigned end = br->bytes * 8;
- brword b = (br->buffer[cwords] & ~(FLAC__WORD_ALL_ONES >> end)) << cbits;
- if(b) {
- i = COUNT_ZERO_MSBS(b);
- uval += i;
- cbits += i;
- cbits++; /* skip over stop bit */
- FLAC__ASSERT(cbits < FLAC__BITS_PER_WORD);
- goto break1;
- }
- else {
- uval += end - cbits;
- cbits += end;
- FLAC__ASSERT(cbits < FLAC__BITS_PER_WORD);
- /* didn't find stop bit yet, have to keep going... */
- }
- }
- /* flush registers and read; bitreader_read_from_client_() does
- * not touch br->consumed_bits at all but we still need to set
- * it in case it fails and we have to return false.
- */
- br->consumed_bits = cbits;
- br->consumed_words = cwords;
- if(!bitreader_read_from_client_(br))
- return false;
- cwords = br->consumed_words;
- ucbits = (br->words-cwords)*FLAC__BITS_PER_WORD + br->bytes*8 - cbits + uval;
- /* + uval to offset our count by the # of unary bits already
- * consumed before the read, because we will add these back
- * in all at once at break1
- */
- }
- break1:
- ucbits -= uval;
- ucbits--; /* account for stop bit */
-
- /* read binary part */
- FLAC__ASSERT(cwords <= br->words);
-
- if(parameter) {
- while(ucbits < parameter) {
- /* flush registers and read; bitreader_read_from_client_() does
- * not touch br->consumed_bits at all but we still need to set
- * it in case it fails and we have to return false.
- */
- br->consumed_bits = cbits;
- br->consumed_words = cwords;
- if(!bitreader_read_from_client_(br))
- return false;
- cwords = br->consumed_words;
- ucbits = (br->words-cwords)*FLAC__BITS_PER_WORD + br->bytes*8 - cbits;
- }
- if(cwords < br->words) { /* if we've not consumed up to a partial tail word... */
- if(cbits) {
- /* this also works when consumed_bits==0, it's just slower than necessary for that case */
- const unsigned n = FLAC__BITS_PER_WORD - cbits;
- const brword word = br->buffer[cwords];
- if(parameter < n) {
- uval <<= parameter;
- uval |= (word & (FLAC__WORD_ALL_ONES >> cbits)) >> (n-parameter);
- cbits += parameter;
- }
- else {
- uval <<= n;
- uval |= word & (FLAC__WORD_ALL_ONES >> cbits);
- crc16_update_word_(br, word);
- cwords++;
- cbits = parameter - n;
- if(cbits) { /* parameter > n, i.e. if there are still bits left to read, there have to be less than 32 so they will all be in the next word */
- uval <<= cbits;
- uval |= (br->buffer[cwords] >> (FLAC__BITS_PER_WORD-cbits));
- }
- }
- }
- else {
- cbits = parameter;
- uval <<= parameter;
- uval |= br->buffer[cwords] >> (FLAC__BITS_PER_WORD-cbits);
- }
- }
- else {
- /* in this case we're starting our read at a partial tail word;
- * the reader has guaranteed that we have at least 'parameter'
- * bits available to read, which makes this case simpler.
- */
- uval <<= parameter;
- if(cbits) {
- /* this also works when consumed_bits==0, it's just a little slower than necessary for that case */
- FLAC__ASSERT(cbits + parameter <= br->bytes*8);
- uval |= (br->buffer[cwords] & (FLAC__WORD_ALL_ONES >> cbits)) >> (FLAC__BITS_PER_WORD-cbits-parameter);
- cbits += parameter;
- }
- else {
- cbits = parameter;
- uval |= br->buffer[cwords] >> (FLAC__BITS_PER_WORD-cbits);
- }
- }
- }
-
- ucbits -= parameter;
-
- /* compose the value */
- *vals = (int)(uval >> 1 ^ -(int)(uval & 1));
-
- /* are we done? */
- --nvals;
- if(nvals == 0) {
- br->consumed_bits = cbits;
- br->consumed_words = cwords;
- return true;
- }
-
- uval = 0;
- ++vals;
-
- }
- }
- #endif
-
- #if 0 /* UNUSED */
- FLAC__bool FLAC__bitreader_read_golomb_signed(FLAC__BitReader *br, int *val, unsigned parameter)
- {
- FLAC__uint32 lsbs = 0, msbs = 0;
- unsigned bit, uval, k;
-
- FLAC__ASSERT(0 != br);
- FLAC__ASSERT(0 != br->buffer);
-
- k = FLAC__bitmath_ilog2(parameter);
-
- /* read the unary MSBs and end bit */
- if(!FLAC__bitreader_read_unary_unsigned(br, &msbs))
- return false;
-
- /* read the binary LSBs */
- if(!FLAC__bitreader_read_raw_uint32(br, &lsbs, k))
- return false;
-
- if(parameter == 1u<<k) {
- /* compose the value */
- uval = (msbs << k) | lsbs;
- }
- else {
- unsigned d = (1 << (k+1)) - parameter;
- if(lsbs >= d) {
- if(!FLAC__bitreader_read_bit(br, &bit))
- return false;
- lsbs <<= 1;
- lsbs |= bit;
- lsbs -= d;
- }
- /* compose the value */
- uval = msbs * parameter + lsbs;
- }
-
- /* unfold unsigned to signed */
- if(uval & 1)
- *val = -((int)(uval >> 1)) - 1;
- else
- *val = (int)(uval >> 1);
-
- return true;
- }
-
- FLAC__bool FLAC__bitreader_read_golomb_unsigned(FLAC__BitReader *br, unsigned *val, unsigned parameter)
- {
- FLAC__uint32 lsbs, msbs = 0;
- unsigned bit, k;
-
- FLAC__ASSERT(0 != br);
- FLAC__ASSERT(0 != br->buffer);
-
- k = FLAC__bitmath_ilog2(parameter);
-
- /* read the unary MSBs and end bit */
- if(!FLAC__bitreader_read_unary_unsigned(br, &msbs))
- return false;
-
- /* read the binary LSBs */
- if(!FLAC__bitreader_read_raw_uint32(br, &lsbs, k))
- return false;
-
- if(parameter == 1u<<k) {
- /* compose the value */
- *val = (msbs << k) | lsbs;
- }
- else {
- unsigned d = (1 << (k+1)) - parameter;
- if(lsbs >= d) {
- if(!FLAC__bitreader_read_bit(br, &bit))
- return false;
- lsbs <<= 1;
- lsbs |= bit;
- lsbs -= d;
- }
- /* compose the value */
- *val = msbs * parameter + lsbs;
- }
-
- return true;
- }
- #endif /* UNUSED */
-
- /* on return, if *val == 0xffffffff then the utf-8 sequence was invalid, but the return value will be true */
- FLAC__bool FLAC__bitreader_read_utf8_uint32(FLAC__BitReader *br, FLAC__uint32 *val, FLAC__byte *raw, unsigned *rawlen)
- {
- FLAC__uint32 v = 0;
- FLAC__uint32 x;
- unsigned i;
-
- if(!FLAC__bitreader_read_raw_uint32(br, &x, 8))
- return false;
- if(raw)
- raw[(*rawlen)++] = (FLAC__byte)x;
- if(!(x & 0x80)) { /* 0xxxxxxx */
- v = x;
- i = 0;
- }
- else if(x & 0xC0 && !(x & 0x20)) { /* 110xxxxx */
- v = x & 0x1F;
- i = 1;
- }
- else if(x & 0xE0 && !(x & 0x10)) { /* 1110xxxx */
- v = x & 0x0F;
- i = 2;
- }
- else if(x & 0xF0 && !(x & 0x08)) { /* 11110xxx */
- v = x & 0x07;
- i = 3;
- }
- else if(x & 0xF8 && !(x & 0x04)) { /* 111110xx */
- v = x & 0x03;
- i = 4;
- }
- else if(x & 0xFC && !(x & 0x02)) { /* 1111110x */
- v = x & 0x01;
- i = 5;
- }
- else {
- *val = 0xffffffff;
- return true;
- }
- for( ; i; i--) {
- if(!FLAC__bitreader_read_raw_uint32(br, &x, 8))
- return false;
- if(raw)
- raw[(*rawlen)++] = (FLAC__byte)x;
- if(!(x & 0x80) || (x & 0x40)) { /* 10xxxxxx */
- *val = 0xffffffff;
- return true;
- }
- v <<= 6;
- v |= (x & 0x3F);
- }
- *val = v;
- return true;
- }
-
- /* on return, if *val == 0xffffffffffffffff then the utf-8 sequence was invalid, but the return value will be true */
- FLAC__bool FLAC__bitreader_read_utf8_uint64(FLAC__BitReader *br, FLAC__uint64 *val, FLAC__byte *raw, unsigned *rawlen)
- {
- FLAC__uint64 v = 0;
- FLAC__uint32 x;
- unsigned i;
-
- if(!FLAC__bitreader_read_raw_uint32(br, &x, 8))
- return false;
- if(raw)
- raw[(*rawlen)++] = (FLAC__byte)x;
- if(!(x & 0x80)) { /* 0xxxxxxx */
- v = x;
- i = 0;
- }
- else if(x & 0xC0 && !(x & 0x20)) { /* 110xxxxx */
- v = x & 0x1F;
- i = 1;
- }
- else if(x & 0xE0 && !(x & 0x10)) { /* 1110xxxx */
- v = x & 0x0F;
- i = 2;
- }
- else if(x & 0xF0 && !(x & 0x08)) { /* 11110xxx */
- v = x & 0x07;
- i = 3;
- }
- else if(x & 0xF8 && !(x & 0x04)) { /* 111110xx */
- v = x & 0x03;
- i = 4;
- }
- else if(x & 0xFC && !(x & 0x02)) { /* 1111110x */
- v = x & 0x01;
- i = 5;
- }
- else if(x & 0xFE && !(x & 0x01)) { /* 11111110 */
- v = 0;
- i = 6;
- }
- else {
- *val = FLAC__U64L(0xffffffffffffffff);
- return true;
- }
- for( ; i; i--) {
- if(!FLAC__bitreader_read_raw_uint32(br, &x, 8))
- return false;
- if(raw)
- raw[(*rawlen)++] = (FLAC__byte)x;
- if(!(x & 0x80) || (x & 0x40)) { /* 10xxxxxx */
- *val = FLAC__U64L(0xffffffffffffffff);
- return true;
- }
- v <<= 6;
- v |= (x & 0x3F);
- }
- *val = v;
- return true;
- }
-
- #endif
- /********* End of inlined file: bitreader.c *********/
-
- /********* Start of inlined file: bitwriter.c *********/
-
- /********* Start of inlined file: juce_FlacHeader.h *********/
- // This file is included at the start of each FLAC .c file, just to do a few housekeeping
- // tasks..
-
- #define VERSION "1.2.1"
-
- #define FLAC__NO_DLL 1
-
- #ifdef _MSC_VER
- #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4312)
- #endif
-
- #if ! (defined (_WIN32) || defined (_WIN64) || defined (LINUX))
- #define FLAC__SYS_DARWIN 1
- #endif
- /********* End of inlined file: juce_FlacHeader.h *********/
-
- #if JUCE_USE_FLAC
-
- #if HAVE_CONFIG_H
- # include <config.h>
- #endif
-
- #include <stdlib.h> /* for malloc() */
- #include <string.h> /* for memcpy(), memset() */
- #ifdef _MSC_VER
- #include <winsock.h> /* for ntohl() */
- #elif defined FLAC__SYS_DARWIN
- #include <machine/endian.h> /* for ntohl() */
- #elif defined __MINGW32__
- #include <winsock.h> /* for ntohl() */
- #else
- #include <netinet/in.h> /* for ntohl() */
- #endif
- #if 0 /* UNUSED */
-
- #endif
-
- /********* Start of inlined file: bitwriter.h *********/
- #ifndef FLAC__PRIVATE__BITWRITER_H
- #define FLAC__PRIVATE__BITWRITER_H
-
- #include <stdio.h> /* for FILE */
-
- /*
- * opaque structure definition
- */
- struct FLAC__BitWriter;
- typedef struct FLAC__BitWriter FLAC__BitWriter;
-
- /*
- * construction, deletion, initialization, etc functions
- */
- FLAC__BitWriter *FLAC__bitwriter_new(void);
- void FLAC__bitwriter_delete(FLAC__BitWriter *bw);
- FLAC__bool FLAC__bitwriter_init(FLAC__BitWriter *bw);
- void FLAC__bitwriter_free(FLAC__BitWriter *bw); /* does not 'free(buffer)' */
- void FLAC__bitwriter_clear(FLAC__BitWriter *bw);
- void FLAC__bitwriter_dump(const FLAC__BitWriter *bw, FILE *out);
-
- /*
- * CRC functions
- *
- * non-const *bw because they have to cal FLAC__bitwriter_get_buffer()
- */
- FLAC__bool FLAC__bitwriter_get_write_crc16(FLAC__BitWriter *bw, FLAC__uint16 *crc);
- FLAC__bool FLAC__bitwriter_get_write_crc8(FLAC__BitWriter *bw, FLAC__byte *crc);
-
- /*
- * info functions
- */
- FLAC__bool FLAC__bitwriter_is_byte_aligned(const FLAC__BitWriter *bw);
- unsigned FLAC__bitwriter_get_input_bits_unconsumed(const FLAC__BitWriter *bw); /* can be called anytime, returns total # of bits unconsumed */
-
- /*
- * direct buffer access
- *
- * there may be no calls on the bitwriter between get and release.
- * the bitwriter continues to own the returned buffer.
- * before get, bitwriter MUST be byte aligned: check with FLAC__bitwriter_is_byte_aligned()
- */
- FLAC__bool FLAC__bitwriter_get_buffer(FLAC__BitWriter *bw, const FLAC__byte **buffer, size_t *bytes);
- void FLAC__bitwriter_release_buffer(FLAC__BitWriter *bw);
-
- /*
- * write functions
- */
- FLAC__bool FLAC__bitwriter_write_zeroes(FLAC__BitWriter *bw, unsigned bits);
- FLAC__bool FLAC__bitwriter_write_raw_uint32(FLAC__BitWriter *bw, FLAC__uint32 val, unsigned bits);
- FLAC__bool FLAC__bitwriter_write_raw_int32(FLAC__BitWriter *bw, FLAC__int32 val, unsigned bits);
- FLAC__bool FLAC__bitwriter_write_raw_uint64(FLAC__BitWriter *bw, FLAC__uint64 val, unsigned bits);
- FLAC__bool FLAC__bitwriter_write_raw_uint32_little_endian(FLAC__BitWriter *bw, FLAC__uint32 val); /*only for bits=32*/
- FLAC__bool FLAC__bitwriter_write_byte_block(FLAC__BitWriter *bw, const FLAC__byte vals[], unsigned nvals);
- FLAC__bool FLAC__bitwriter_write_unary_unsigned(FLAC__BitWriter *bw, unsigned val);
- unsigned FLAC__bitwriter_rice_bits(FLAC__int32 val, unsigned parameter);
- #if 0 /* UNUSED */
- unsigned FLAC__bitwriter_golomb_bits_signed(int val, unsigned parameter);
- unsigned FLAC__bitwriter_golomb_bits_unsigned(unsigned val, unsigned parameter);
- #endif
- FLAC__bool FLAC__bitwriter_write_rice_signed(FLAC__BitWriter *bw, FLAC__int32 val, unsigned parameter);
- FLAC__bool FLAC__bitwriter_write_rice_signed_block(FLAC__BitWriter *bw, const FLAC__int32 *vals, unsigned nvals, unsigned parameter);
- #if 0 /* UNUSED */
- FLAC__bool FLAC__bitwriter_write_golomb_signed(FLAC__BitWriter *bw, int val, unsigned parameter);
- FLAC__bool FLAC__bitwriter_write_golomb_unsigned(FLAC__BitWriter *bw, unsigned val, unsigned parameter);
- #endif
- FLAC__bool FLAC__bitwriter_write_utf8_uint32(FLAC__BitWriter *bw, FLAC__uint32 val);
- FLAC__bool FLAC__bitwriter_write_utf8_uint64(FLAC__BitWriter *bw, FLAC__uint64 val);
- FLAC__bool FLAC__bitwriter_zero_pad_to_byte_boundary(FLAC__BitWriter *bw);
-
- #endif
- /********* End of inlined file: bitwriter.h *********/
-
- /********* Start of inlined file: alloc.h *********/
- #ifndef FLAC__SHARE__ALLOC_H
- #define FLAC__SHARE__ALLOC_H
-
- #if HAVE_CONFIG_H
- # include <config.h>
- #endif
-
- /* WATCHOUT: for c++ you may have to #define __STDC_LIMIT_MACROS 1 real early
- * before #including this file, otherwise SIZE_MAX might not be defined
- */
-
- #include <limits.h> /* for SIZE_MAX */
- #if !defined _MSC_VER && !defined __MINGW32__ && !defined __EMX__
- #include <stdint.h> /* for SIZE_MAX in case limits.h didn't get it */
- #endif
- #include <stdlib.h> /* for size_t, malloc(), etc */
-
- #ifndef SIZE_MAX
- # ifndef SIZE_T_MAX
- # ifdef _MSC_VER
- # define SIZE_T_MAX UINT_MAX
- # else
- # error
- # endif
- # endif
- # define SIZE_MAX SIZE_T_MAX
- #endif
-
- #ifndef FLaC__INLINE
- #define FLaC__INLINE
- #endif
-
- /* avoid malloc()ing 0 bytes, see:
- * https://www.securecoding.cert.org/confluence/display/seccode/MEM04-A.+Do+not+make+assumptions+about+the+result+of+allocating+0+bytes?focusedCommentId=5407003
- */
- static FLaC__INLINE void *safe_malloc_(size_t size)
- {
- /* malloc(0) is undefined; FLAC src convention is to always allocate */
- if(!size)
- size++;
- return malloc(size);
- }
-
- static FLaC__INLINE void *safe_calloc_(size_t nmemb, size_t size)
- {
- if(!nmemb || !size)
- return malloc(1); /* malloc(0) is undefined; FLAC src convention is to always allocate */
- return calloc(nmemb, size);
- }
-
- /*@@@@ there's probably a better way to prevent overflows when allocating untrusted sums but this works for now */
-
- static FLaC__INLINE void *safe_malloc_add_2op_(size_t size1, size_t size2)
- {
- size2 += size1;
- if(size2 < size1)
- return 0;
- return safe_malloc_(size2);
- }
-
- static FLaC__INLINE void *safe_malloc_add_3op_(size_t size1, size_t size2, size_t size3)
- {
- size2 += size1;
- if(size2 < size1)
- return 0;
- size3 += size2;
- if(size3 < size2)
- return 0;
- return safe_malloc_(size3);
- }
-
- static FLaC__INLINE void *safe_malloc_add_4op_(size_t size1, size_t size2, size_t size3, size_t size4)
- {
- size2 += size1;
- if(size2 < size1)
- return 0;
- size3 += size2;
- if(size3 < size2)
- return 0;
- size4 += size3;
- if(size4 < size3)
- return 0;
- return safe_malloc_(size4);
- }
-
- static FLaC__INLINE void *safe_malloc_mul_2op_(size_t size1, size_t size2)
- #if 0
- needs support for cases where sizeof(size_t) != 4
- {
- /* could be faster #ifdef'ing off SIZEOF_SIZE_T */
- if(sizeof(size_t) == 4) {
- if ((double)size1 * (double)size2 < 4294967296.0)
- return malloc(size1*size2);
- }
- return 0;
- }
- #else
- /* better? */
- {
- if(!size1 || !size2)
- return malloc(1); /* malloc(0) is undefined; FLAC src convention is to always allocate */
- if(size1 > SIZE_MAX / size2)
- return 0;
- return malloc(size1*size2);
- }
- #endif
-
- static FLaC__INLINE void *safe_malloc_mul_3op_(size_t size1, size_t size2, size_t size3)
- {
- if(!size1 || !size2 || !size3)
- return malloc(1); /* malloc(0) is undefined; FLAC src convention is to always allocate */
- if(size1 > SIZE_MAX / size2)
- return 0;
- size1 *= size2;
- if(size1 > SIZE_MAX / size3)
- return 0;
- return malloc(size1*size3);
- }
-
- /* size1*size2 + size3 */
- static FLaC__INLINE void *safe_malloc_mul2add_(size_t size1, size_t size2, size_t size3)
- {
- if(!size1 || !size2)
- return safe_malloc_(size3);
- if(size1 > SIZE_MAX / size2)
- return 0;
- return safe_malloc_add_2op_(size1*size2, size3);
- }
-
- /* size1 * (size2 + size3) */
- static FLaC__INLINE void *safe_malloc_muladd2_(size_t size1, size_t size2, size_t size3)
- {
- if(!size1 || (!size2 && !size3))
- return malloc(1); /* malloc(0) is undefined; FLAC src convention is to always allocate */
- size2 += size3;
- if(size2 < size3)
- return 0;
- return safe_malloc_mul_2op_(size1, size2);
- }
-
- static FLaC__INLINE void *safe_realloc_add_2op_(void *ptr, size_t size1, size_t size2)
- {
- size2 += size1;
- if(size2 < size1)
- return 0;
- return realloc(ptr, size2);
- }
-
- static FLaC__INLINE void *safe_realloc_add_3op_(void *ptr, size_t size1, size_t size2, size_t size3)
- {
- size2 += size1;
- if(size2 < size1)
- return 0;
- size3 += size2;
- if(size3 < size2)
- return 0;
- return realloc(ptr, size3);
- }
-
- static FLaC__INLINE void *safe_realloc_add_4op_(void *ptr, size_t size1, size_t size2, size_t size3, size_t size4)
- {
- size2 += size1;
- if(size2 < size1)
- return 0;
- size3 += size2;
- if(size3 < size2)
- return 0;
- size4 += size3;
- if(size4 < size3)
- return 0;
- return realloc(ptr, size4);
- }
-
- static FLaC__INLINE void *safe_realloc_mul_2op_(void *ptr, size_t size1, size_t size2)
- {
- if(!size1 || !size2)
- return realloc(ptr, 0); /* preserve POSIX realloc(ptr, 0) semantics */
- if(size1 > SIZE_MAX / size2)
- return 0;
- return realloc(ptr, size1*size2);
- }
-
- /* size1 * (size2 + size3) */
- static FLaC__INLINE void *safe_realloc_muladd2_(void *ptr, size_t size1, size_t size2, size_t size3)
- {
- if(!size1 || (!size2 && !size3))
- return realloc(ptr, 0); /* preserve POSIX realloc(ptr, 0) semantics */
- size2 += size3;
- if(size2 < size3)
- return 0;
- return safe_realloc_mul_2op_(ptr, size1, size2);
- }
-
- #endif
- /********* End of inlined file: alloc.h *********/
-
- /* Things should be fastest when this matches the machine word size */
- /* WATCHOUT: if you change this you must also change the following #defines down to SWAP_BE_WORD_TO_HOST below to match */
- /* WATCHOUT: there are a few places where the code will not work unless bwword is >= 32 bits wide */
- typedef FLAC__uint32 bwword;
- #define FLAC__BYTES_PER_WORD 4
- #define FLAC__BITS_PER_WORD 32
- #define FLAC__WORD_ALL_ONES ((FLAC__uint32)0xffffffff)
- /* SWAP_BE_WORD_TO_HOST swaps bytes in a bwword (which is always big-endian) if necessary to match host byte order */
- #if WORDS_BIGENDIAN
- #define SWAP_BE_WORD_TO_HOST(x) (x)
- #else
- #ifdef _MSC_VER
- #define SWAP_BE_WORD_TO_HOST(x) local_swap32_(x)
- #else
- #define SWAP_BE_WORD_TO_HOST(x) ntohl(x)
- #endif
- #endif
-
- /*
- * The default capacity here doesn't matter too much. The buffer always grows
- * to hold whatever is written to it. Usually the encoder will stop adding at
- * a frame or metadata block, then write that out and clear the buffer for the
- * next one.
- */
- static const unsigned FLAC__BITWRITER_DEFAULT_CAPACITY = 32768u / sizeof(bwword); /* size in words */
- /* When growing, increment 4K at a time */
- static const unsigned FLAC__BITWRITER_DEFAULT_INCREMENT = 4096u / sizeof(bwword); /* size in words */
-
- #define FLAC__WORDS_TO_BITS(words) ((words) * FLAC__BITS_PER_WORD)
- #define FLAC__TOTAL_BITS(bw) (FLAC__WORDS_TO_BITS((bw)->words) + (bw)->bits)
-
- #ifdef min
- #undef min
- #endif
- #define min(x,y) ((x)<(y)?(x):(y))
-
- /* adjust for compilers that can't understand using LLU suffix for uint64_t literals */
- #ifdef _MSC_VER
- #define FLAC__U64L(x) x
- #else
- #define FLAC__U64L(x) x##LLU
- #endif
-
- #ifndef FLaC__INLINE
- #define FLaC__INLINE
- #endif
-
- struct FLAC__BitWriter {
- bwword *buffer;
- bwword accum; /* accumulator; bits are right-justified; when full, accum is appended to buffer */
- unsigned capacity; /* capacity of buffer in words */
- unsigned words; /* # of complete words in buffer */
- unsigned bits; /* # of used bits in accum */
- };
-
- /* * WATCHOUT: The current implementation only grows the buffer. */
- static FLAC__bool bitwriter_grow_(FLAC__BitWriter *bw, unsigned bits_to_add)
- {
- unsigned new_capacity;
- bwword *new_buffer;
-
- FLAC__ASSERT(0 != bw);
- FLAC__ASSERT(0 != bw->buffer);
-
- /* calculate total words needed to store 'bits_to_add' additional bits */
- new_capacity = bw->words + ((bw->bits + bits_to_add + FLAC__BITS_PER_WORD - 1) / FLAC__BITS_PER_WORD);
-
- /* it's possible (due to pessimism in the growth estimation that
- * leads to this call) that we don't actually need to grow
- */
- if(bw->capacity >= new_capacity)
- return true;
-
- /* round up capacity increase to the nearest FLAC__BITWRITER_DEFAULT_INCREMENT */
- if((new_capacity - bw->capacity) % FLAC__BITWRITER_DEFAULT_INCREMENT)
- new_capacity += FLAC__BITWRITER_DEFAULT_INCREMENT - ((new_capacity - bw->capacity) % FLAC__BITWRITER_DEFAULT_INCREMENT);
- /* make sure we got everything right */
- FLAC__ASSERT(0 == (new_capacity - bw->capacity) % FLAC__BITWRITER_DEFAULT_INCREMENT);
- FLAC__ASSERT(new_capacity > bw->capacity);
- FLAC__ASSERT(new_capacity >= bw->words + ((bw->bits + bits_to_add + FLAC__BITS_PER_WORD - 1) / FLAC__BITS_PER_WORD));
-
- new_buffer = (bwword*)safe_realloc_mul_2op_(bw->buffer, sizeof(bwword), /*times*/new_capacity);
- if(new_buffer == 0)
- return false;
- bw->buffer = new_buffer;
- bw->capacity = new_capacity;
- return true;
- }
-
- /***********************************************************************
- *
- * Class constructor/destructor
- *
- ***********************************************************************/
-
- FLAC__BitWriter *FLAC__bitwriter_new(void)
- {
- FLAC__BitWriter *bw = (FLAC__BitWriter*)calloc(1, sizeof(FLAC__BitWriter));
- /* note that calloc() sets all members to 0 for us */
- return bw;
- }
-
- void FLAC__bitwriter_delete(FLAC__BitWriter *bw)
- {
- FLAC__ASSERT(0 != bw);
-
- FLAC__bitwriter_free(bw);
- free(bw);
- }
-
- /***********************************************************************
- *
- * Public class methods
- *
- ***********************************************************************/
-
- FLAC__bool FLAC__bitwriter_init(FLAC__BitWriter *bw)
- {
- FLAC__ASSERT(0 != bw);
-
- bw->words = bw->bits = 0;
- bw->capacity = FLAC__BITWRITER_DEFAULT_CAPACITY;
- bw->buffer = (bwword*)malloc(sizeof(bwword) * bw->capacity);
- if(bw->buffer == 0)
- return false;
-
- return true;
- }
-
- void FLAC__bitwriter_free(FLAC__BitWriter *bw)
- {
- FLAC__ASSERT(0 != bw);
-
- if(0 != bw->buffer)
- free(bw->buffer);
- bw->buffer = 0;
- bw->capacity = 0;
- bw->words = bw->bits = 0;
- }
-
- void FLAC__bitwriter_clear(FLAC__BitWriter *bw)
- {
- bw->words = bw->bits = 0;
- }
-
- void FLAC__bitwriter_dump(const FLAC__BitWriter *bw, FILE *out)
- {
- unsigned i, j;
- if(bw == 0) {
- fprintf(out, "bitwriter is NULL\n");
- }
- else {
- fprintf(out, "bitwriter: capacity=%u words=%u bits=%u total_bits=%u\n", bw->capacity, bw->words, bw->bits, FLAC__TOTAL_BITS(bw));
-
- for(i = 0; i < bw->words; i++) {
- fprintf(out, "%08X: ", i);
- for(j = 0; j < FLAC__BITS_PER_WORD; j++)
- fprintf(out, "%01u", bw->buffer[i] & (1 << (FLAC__BITS_PER_WORD-j-1)) ? 1:0);
- fprintf(out, "\n");
- }
- if(bw->bits > 0) {
- fprintf(out, "%08X: ", i);
- for(j = 0; j < bw->bits; j++)
- fprintf(out, "%01u", bw->accum & (1 << (bw->bits-j-1)) ? 1:0);
- fprintf(out, "\n");
- }
- }
- }
-
- FLAC__bool FLAC__bitwriter_get_write_crc16(FLAC__BitWriter *bw, FLAC__uint16 *crc)
- {
- const FLAC__byte *buffer;
- size_t bytes;
-
- FLAC__ASSERT((bw->bits & 7) == 0); /* assert that we're byte-aligned */
-
- if(!FLAC__bitwriter_get_buffer(bw, &buffer, &bytes))
- return false;
-
- *crc = (FLAC__uint16)FLAC__crc16(buffer, bytes);
- FLAC__bitwriter_release_buffer(bw);
- return true;
- }
-
- FLAC__bool FLAC__bitwriter_get_write_crc8(FLAC__BitWriter *bw, FLAC__byte *crc)
- {
- const FLAC__byte *buffer;
- size_t bytes;
-
- FLAC__ASSERT((bw->bits & 7) == 0); /* assert that we're byte-aligned */
-
- if(!FLAC__bitwriter_get_buffer(bw, &buffer, &bytes))
- return false;
-
- *crc = FLAC__crc8(buffer, bytes);
- FLAC__bitwriter_release_buffer(bw);
- return true;
- }
-
- FLAC__bool FLAC__bitwriter_is_byte_aligned(const FLAC__BitWriter *bw)
- {
- return ((bw->bits & 7) == 0);
- }
-
- unsigned FLAC__bitwriter_get_input_bits_unconsumed(const FLAC__BitWriter *bw)
- {
- return FLAC__TOTAL_BITS(bw);
- }
-
- FLAC__bool FLAC__bitwriter_get_buffer(FLAC__BitWriter *bw, const FLAC__byte **buffer, size_t *bytes)
- {
- FLAC__ASSERT((bw->bits & 7) == 0);
- /* double protection */
- if(bw->bits & 7)
- return false;
- /* if we have bits in the accumulator we have to flush those to the buffer first */
- if(bw->bits) {
- FLAC__ASSERT(bw->words <= bw->capacity);
- if(bw->words == bw->capacity && !bitwriter_grow_(bw, FLAC__BITS_PER_WORD))
- return false;
- /* append bits as complete word to buffer, but don't change bw->accum or bw->bits */
- bw->buffer[bw->words] = SWAP_BE_WORD_TO_HOST(bw->accum << (FLAC__BITS_PER_WORD-bw->bits));
- }
- /* now we can just return what we have */
- *buffer = (FLAC__byte*)bw->buffer;
- *bytes = (FLAC__BYTES_PER_WORD * bw->words) + (bw->bits >> 3);
- return true;
- }
-
- void FLAC__bitwriter_release_buffer(FLAC__BitWriter *bw)
- {
- /* nothing to do. in the future, strict checking of a 'writer-is-in-
- * get-mode' flag could be added everywhere and then cleared here
- */
- (void)bw;
- }
-
- FLaC__INLINE FLAC__bool FLAC__bitwriter_write_zeroes(FLAC__BitWriter *bw, unsigned bits)
- {
- unsigned n;
-
- FLAC__ASSERT(0 != bw);
- FLAC__ASSERT(0 != bw->buffer);
-
- if(bits == 0)
- return true;
- /* slightly pessimistic size check but faster than "<= bw->words + (bw->bits+bits+FLAC__BITS_PER_WORD-1)/FLAC__BITS_PER_WORD" */
- if(bw->capacity <= bw->words + bits && !bitwriter_grow_(bw, bits))
- return false;
- /* first part gets to word alignment */
- if(bw->bits) {
- n = min(FLAC__BITS_PER_WORD - bw->bits, bits);
- bw->accum <<= n;
- bits -= n;
- bw->bits += n;
- if(bw->bits == FLAC__BITS_PER_WORD) {
- bw->buffer[bw->words++] = SWAP_BE_WORD_TO_HOST(bw->accum);
- bw->bits = 0;
- }
- else
- return true;
- }
- /* do whole words */
- while(bits >= FLAC__BITS_PER_WORD) {
- bw->buffer[bw->words++] = 0;
- bits -= FLAC__BITS_PER_WORD;
- }
- /* do any leftovers */
- if(bits > 0) {
- bw->accum = 0;
- bw->bits = bits;
- }
- return true;
- }
-
- FLaC__INLINE FLAC__bool FLAC__bitwriter_write_raw_uint32(FLAC__BitWriter *bw, FLAC__uint32 val, unsigned bits)
- {
- register unsigned left;
-
- /* WATCHOUT: code does not work with <32bit words; we can make things much faster with this assertion */
- FLAC__ASSERT(FLAC__BITS_PER_WORD >= 32);
-
- FLAC__ASSERT(0 != bw);
- FLAC__ASSERT(0 != bw->buffer);
-
- FLAC__ASSERT(bits <= 32);
- if(bits == 0)
- return true;
-
- /* slightly pessimistic size check but faster than "<= bw->words + (bw->bits+bits+FLAC__BITS_PER_WORD-1)/FLAC__BITS_PER_WORD" */
- if(bw->capacity <= bw->words + bits && !bitwriter_grow_(bw, bits))
- return false;
-
- left = FLAC__BITS_PER_WORD - bw->bits;
- if(bits < left) {
- bw->accum <<= bits;
- bw->accum |= val;
- bw->bits += bits;
- }
- else if(bw->bits) { /* WATCHOUT: if bw->bits == 0, left==FLAC__BITS_PER_WORD and bw->accum<<=left is a NOP instead of setting to 0 */
- bw->accum <<= left;
- bw->accum |= val >> (bw->bits = bits - left);
- bw->buffer[bw->words++] = SWAP_BE_WORD_TO_HOST(bw->accum);
- bw->accum = val;
- }
- else {
- bw->accum = val;
- bw->bits = 0;
- bw->buffer[bw->words++] = SWAP_BE_WORD_TO_HOST(val);
- }
-
- return true;
- }
-
- FLaC__INLINE FLAC__bool FLAC__bitwriter_write_raw_int32(FLAC__BitWriter *bw, FLAC__int32 val, unsigned bits)
- {
- /* zero-out unused bits */
- if(bits < 32)
- val &= (~(0xffffffff << bits));
-
- return FLAC__bitwriter_write_raw_uint32(bw, (FLAC__uint32)val, bits);
- }
-
- FLaC__INLINE FLAC__bool FLAC__bitwriter_write_raw_uint64(FLAC__BitWriter *bw, FLAC__uint64 val, unsigned bits)
- {
- /* this could be a little faster but it's not used for much */
- if(bits > 32) {
- return
- FLAC__bitwriter_write_raw_uint32(bw, (FLAC__uint32)(val>>32), bits-32) &&
- FLAC__bitwriter_write_raw_uint32(bw, (FLAC__uint32)val, 32);
- }
- else
- return FLAC__bitwriter_write_raw_uint32(bw, (FLAC__uint32)val, bits);
- }
-
- FLaC__INLINE FLAC__bool FLAC__bitwriter_write_raw_uint32_little_endian(FLAC__BitWriter *bw, FLAC__uint32 val)
- {
- /* this doesn't need to be that fast as currently it is only used for vorbis comments */
-
- if(!FLAC__bitwriter_write_raw_uint32(bw, val & 0xff, 8))
- return false;
- if(!FLAC__bitwriter_write_raw_uint32(bw, (val>>8) & 0xff, 8))
- return false;
- if(!FLAC__bitwriter_write_raw_uint32(bw, (val>>16) & 0xff, 8))
- return false;
- if(!FLAC__bitwriter_write_raw_uint32(bw, val>>24, 8))
- return false;
-
- return true;
- }
-
- FLaC__INLINE FLAC__bool FLAC__bitwriter_write_byte_block(FLAC__BitWriter *bw, const FLAC__byte vals[], unsigned nvals)
- {
- unsigned i;
-
- /* this could be faster but currently we don't need it to be since it's only used for writing metadata */
- for(i = 0; i < nvals; i++) {
- if(!FLAC__bitwriter_write_raw_uint32(bw, (FLAC__uint32)(vals[i]), 8))
- return false;
- }
-
- return true;
- }
-
- FLAC__bool FLAC__bitwriter_write_unary_unsigned(FLAC__BitWriter *bw, unsigned val)
- {
- if(val < 32)
- return FLAC__bitwriter_write_raw_uint32(bw, 1, ++val);
- else
- return
- FLAC__bitwriter_write_zeroes(bw, val) &&
- FLAC__bitwriter_write_raw_uint32(bw, 1, 1);
- }
-
- unsigned FLAC__bitwriter_rice_bits(FLAC__int32 val, unsigned parameter)
- {
- FLAC__uint32 uval;
-
- FLAC__ASSERT(parameter < sizeof(unsigned)*8);
-
- /* fold signed to unsigned; actual formula is: negative(v)? -2v-1 : 2v */
- uval = (val<<1) ^ (val>>31);
-
- return 1 + parameter + (uval >> parameter);
- }
-
- #if 0 /* UNUSED */
- unsigned FLAC__bitwriter_golomb_bits_signed(int val, unsigned parameter)
- {
- unsigned bits, msbs, uval;
- unsigned k;
-
- FLAC__ASSERT(parameter > 0);
-
- /* fold signed to unsigned */
- if(val < 0)
- uval = (unsigned)(((-(++val)) << 1) + 1);
- else
- uval = (unsigned)(val << 1);
-
- k = FLAC__bitmath_ilog2(parameter);
- if(parameter == 1u<<k) {
- FLAC__ASSERT(k <= 30);
-
- msbs = uval >> k;
- bits = 1 + k + msbs;
- }
- else {
- unsigned q, r, d;
-
- d = (1 << (k+1)) - parameter;
- q = uval / parameter;
- r = uval - (q * parameter);
-
- bits = 1 + q + k;
- if(r >= d)
- bits++;
- }
- return bits;
- }
-
- unsigned FLAC__bitwriter_golomb_bits_unsigned(unsigned uval, unsigned parameter)
- {
- unsigned bits, msbs;
- unsigned k;
-
- FLAC__ASSERT(parameter > 0);
-
- k = FLAC__bitmath_ilog2(parameter);
- if(parameter == 1u<<k) {
- FLAC__ASSERT(k <= 30);
-
- msbs = uval >> k;
- bits = 1 + k + msbs;
- }
- else {
- unsigned q, r, d;
-
- d = (1 << (k+1)) - parameter;
- q = uval / parameter;
- r = uval - (q * parameter);
-
- bits = 1 + q + k;
- if(r >= d)
- bits++;
- }
- return bits;
- }
- #endif /* UNUSED */
-
- FLAC__bool FLAC__bitwriter_write_rice_signed(FLAC__BitWriter *bw, FLAC__int32 val, unsigned parameter)
- {
- unsigned total_bits, interesting_bits, msbs;
- FLAC__uint32 uval, pattern;
-
- FLAC__ASSERT(0 != bw);
- FLAC__ASSERT(0 != bw->buffer);
- FLAC__ASSERT(parameter < 8*sizeof(uval));
-
- /* fold signed to unsigned; actual formula is: negative(v)? -2v-1 : 2v */
- uval = (val<<1) ^ (val>>31);
-
- msbs = uval >> parameter;
- interesting_bits = 1 + parameter;
- total_bits = interesting_bits + msbs;
- pattern = 1 << parameter; /* the unary end bit */
- pattern |= (uval & ((1<<parameter)-1)); /* the binary LSBs */
-
- if(total_bits <= 32)
- return FLAC__bitwriter_write_raw_uint32(bw, pattern, total_bits);
- else
- return
- FLAC__bitwriter_write_zeroes(bw, msbs) && /* write the unary MSBs */
- FLAC__bitwriter_write_raw_uint32(bw, pattern, interesting_bits); /* write the unary end bit and binary LSBs */
- }
-
- FLAC__bool FLAC__bitwriter_write_rice_signed_block(FLAC__BitWriter *bw, const FLAC__int32 *vals, unsigned nvals, unsigned parameter)
- {
- const FLAC__uint32 mask1 = FLAC__WORD_ALL_ONES << parameter; /* we val|=mask1 to set the stop bit above it... */
- const FLAC__uint32 mask2 = FLAC__WORD_ALL_ONES >> (31-parameter); /* ...then mask off the bits above the stop bit with val&=mask2*/
- FLAC__uint32 uval;
- unsigned left;
- const unsigned lsbits = 1 + parameter;
- unsigned msbits;
-
- FLAC__ASSERT(0 != bw);
- FLAC__ASSERT(0 != bw->buffer);
- FLAC__ASSERT(parameter < 8*sizeof(bwword)-1);
- /* WATCHOUT: code does not work with <32bit words; we can make things much faster with this assertion */
- FLAC__ASSERT(FLAC__BITS_PER_WORD >= 32);
-
- while(nvals) {
- /* fold signed to unsigned; actual formula is: negative(v)? -2v-1 : 2v */
- uval = (*vals<<1) ^ (*vals>>31);
-
- msbits = uval >> parameter;
-
- #if 0 /* OPT: can remove this special case if it doesn't make up for the extra compare (doesn't make a statistically significant difference with msvc or gcc/x86) */
- if(bw->bits && bw->bits + msbits + lsbits <= FLAC__BITS_PER_WORD) { /* i.e. if the whole thing fits in the current bwword */
- /* ^^^ if bw->bits is 0 then we may have filled the buffer and have no free bwword to work in */
- bw->bits = bw->bits + msbits + lsbits;
- uval |= mask1; /* set stop bit */
- uval &= mask2; /* mask off unused top bits */
- /* NOT: bw->accum <<= msbits + lsbits because msbits+lsbits could be 32, then the shift would be a NOP */
- bw->accum <<= msbits;
- bw->accum <<= lsbits;
- bw->accum |= uval;
- if(bw->bits == FLAC__BITS_PER_WORD) {
- bw->buffer[bw->words++] = SWAP_BE_WORD_TO_HOST(bw->accum);
- bw->bits = 0;
- /* burying the capacity check down here means we have to grow the buffer a little if there are more vals to do */
- if(bw->capacity <= bw->words && nvals > 1 && !bitwriter_grow_(bw, 1)) {
- FLAC__ASSERT(bw->capacity == bw->words);
- return false;
- }
- }
- }
- else {
- #elif 1 /*@@@@@@ OPT: try this version with MSVC6 to see if better, not much difference for gcc-4 */
- if(bw->bits && bw->bits + msbits + lsbits < FLAC__BITS_PER_WORD) { /* i.e. if the whole thing fits in the current bwword */
- /* ^^^ if bw->bits is 0 then we may have filled the buffer and have no free bwword to work in */
- bw->bits = bw->bits + msbits + lsbits;
- uval |= mask1; /* set stop bit */
- uval &= mask2; /* mask off unused top bits */
- bw->accum <<= msbits + lsbits;
- bw->accum |= uval;
- }
- else {
- #endif
- /* slightly pessimistic size check but faster than "<= bw->words + (bw->bits+msbits+lsbits+FLAC__BITS_PER_WORD-1)/FLAC__BITS_PER_WORD" */
- /* OPT: pessimism may cause flurry of false calls to grow_ which eat up all savings before it */
- if(bw->capacity <= bw->words + bw->bits + msbits + 1/*lsbits always fit in 1 bwword*/ && !bitwriter_grow_(bw, msbits+lsbits))
- return false;
-
- if(msbits) {
- /* first part gets to word alignment */
- if(bw->bits) {
- left = FLAC__BITS_PER_WORD - bw->bits;
- if(msbits < left) {
- bw->accum <<= msbits;
- bw->bits += msbits;
- goto break1;
- }
- else {
- bw->accum <<= left;
- msbits -= left;
- bw->buffer[bw->words++] = SWAP_BE_WORD_TO_HOST(bw->accum);
- bw->bits = 0;
- }
- }
- /* do whole words */
- while(msbits >= FLAC__BITS_PER_WORD) {
- bw->buffer[bw->words++] = 0;
- msbits -= FLAC__BITS_PER_WORD;
- }
- /* do any leftovers */
- if(msbits > 0) {
- bw->accum = 0;
- bw->bits = msbits;
- }
- }
- break1:
- uval |= mask1; /* set stop bit */
- uval &= mask2; /* mask off unused top bits */
-
- left = FLAC__BITS_PER_WORD - bw->bits;
- if(lsbits < left) {
- bw->accum <<= lsbits;
- bw->accum |= uval;
- bw->bits += lsbits;
- }
- else {
- /* if bw->bits == 0, left==FLAC__BITS_PER_WORD which will always
- * be > lsbits (because of previous assertions) so it would have
- * triggered the (lsbits<left) case above.
- */
- FLAC__ASSERT(bw->bits);
- FLAC__ASSERT(left < FLAC__BITS_PER_WORD);
- bw->accum <<= left;
- bw->accum |= uval >> (bw->bits = lsbits - left);
- bw->buffer[bw->words++] = SWAP_BE_WORD_TO_HOST(bw->accum);
- bw->accum = uval;
- }
- #if 1
- }
- #endif
- vals++;
- nvals--;
- }
- return true;
- }
-
- #if 0 /* UNUSED */
- FLAC__bool FLAC__bitwriter_write_golomb_signed(FLAC__BitWriter *bw, int val, unsigned parameter)
- {
- unsigned total_bits, msbs, uval;
- unsigned k;
-
- FLAC__ASSERT(0 != bw);
- FLAC__ASSERT(0 != bw->buffer);
- FLAC__ASSERT(parameter > 0);
-
- /* fold signed to unsigned */
- if(val < 0)
- uval = (unsigned)(((-(++val)) << 1) + 1);
- else
- uval = (unsigned)(val << 1);
-
- k = FLAC__bitmath_ilog2(parameter);
- if(parameter == 1u<<k) {
- unsigned pattern;
-
- FLAC__ASSERT(k <= 30);
-
- msbs = uval >> k;
- total_bits = 1 + k + msbs;
- pattern = 1 << k; /* the unary end bit */
- pattern |= (uval & ((1u<<k)-1)); /* the binary LSBs */
-
- if(total_bits <= 32) {
- if(!FLAC__bitwriter_write_raw_uint32(bw, pattern, total_bits))
- return false;
- }
- else {
- /* write the unary MSBs */
- if(!FLAC__bitwriter_write_zeroes(bw, msbs))
- return false;
- /* write the unary end bit and binary LSBs */
- if(!FLAC__bitwriter_write_raw_uint32(bw, pattern, k+1))
- return false;
- }
- }
- else {
- unsigned q, r, d;
-
- d = (1 << (k+1)) - parameter;
- q = uval / parameter;
- r = uval - (q * parameter);
- /* write the unary MSBs */
- if(!FLAC__bitwriter_write_zeroes(bw, q))
- return false;
- /* write the unary end bit */
- if(!FLAC__bitwriter_write_raw_uint32(bw, 1, 1))
- return false;
- /* write the binary LSBs */
- if(r >= d) {
- if(!FLAC__bitwriter_write_raw_uint32(bw, r+d, k+1))
- return false;
- }
- else {
- if(!FLAC__bitwriter_write_raw_uint32(bw, r, k))
- return false;
- }
- }
- return true;
- }
-
- FLAC__bool FLAC__bitwriter_write_golomb_unsigned(FLAC__BitWriter *bw, unsigned uval, unsigned parameter)
- {
- unsigned total_bits, msbs;
- unsigned k;
-
- FLAC__ASSERT(0 != bw);
- FLAC__ASSERT(0 != bw->buffer);
- FLAC__ASSERT(parameter > 0);
-
- k = FLAC__bitmath_ilog2(parameter);
- if(parameter == 1u<<k) {
- unsigned pattern;
-
- FLAC__ASSERT(k <= 30);
-
- msbs = uval >> k;
- total_bits = 1 + k + msbs;
- pattern = 1 << k; /* the unary end bit */
- pattern |= (uval & ((1u<<k)-1)); /* the binary LSBs */
-
- if(total_bits <= 32) {
- if(!FLAC__bitwriter_write_raw_uint32(bw, pattern, total_bits))
- return false;
- }
- else {
- /* write the unary MSBs */
- if(!FLAC__bitwriter_write_zeroes(bw, msbs))
- return false;
- /* write the unary end bit and binary LSBs */
- if(!FLAC__bitwriter_write_raw_uint32(bw, pattern, k+1))
- return false;
- }
- }
- else {
- unsigned q, r, d;
-
- d = (1 << (k+1)) - parameter;
- q = uval / parameter;
- r = uval - (q * parameter);
- /* write the unary MSBs */
- if(!FLAC__bitwriter_write_zeroes(bw, q))
- return false;
- /* write the unary end bit */
- if(!FLAC__bitwriter_write_raw_uint32(bw, 1, 1))
- return false;
- /* write the binary LSBs */
- if(r >= d) {
- if(!FLAC__bitwriter_write_raw_uint32(bw, r+d, k+1))
- return false;
- }
- else {
- if(!FLAC__bitwriter_write_raw_uint32(bw, r, k))
- return false;
- }
- }
- return true;
- }
- #endif /* UNUSED */
-
- FLAC__bool FLAC__bitwriter_write_utf8_uint32(FLAC__BitWriter *bw, FLAC__uint32 val)
- {
- FLAC__bool ok = 1;
-
- FLAC__ASSERT(0 != bw);
- FLAC__ASSERT(0 != bw->buffer);
-
- FLAC__ASSERT(!(val & 0x80000000)); /* this version only handles 31 bits */
-
- if(val < 0x80) {
- return FLAC__bitwriter_write_raw_uint32(bw, val, 8);
- }
- else if(val < 0x800) {
- ok &= FLAC__bitwriter_write_raw_uint32(bw, 0xC0 | (val>>6), 8);
- ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (val&0x3F), 8);
- }
- else if(val < 0x10000) {
- ok &= FLAC__bitwriter_write_raw_uint32(bw, 0xE0 | (val>>12), 8);
- ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | ((val>>6)&0x3F), 8);
- ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (val&0x3F), 8);
- }
- else if(val < 0x200000) {
- ok &= FLAC__bitwriter_write_raw_uint32(bw, 0xF0 | (val>>18), 8);
- ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | ((val>>12)&0x3F), 8);
- ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | ((val>>6)&0x3F), 8);
- ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (val&0x3F), 8);
- }
- else if(val < 0x4000000) {
- ok &= FLAC__bitwriter_write_raw_uint32(bw, 0xF8 | (val>>24), 8);
- ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | ((val>>18)&0x3F), 8);
- ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | ((val>>12)&0x3F), 8);
- ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | ((val>>6)&0x3F), 8);
- ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (val&0x3F), 8);
- }
- else {
- ok &= FLAC__bitwriter_write_raw_uint32(bw, 0xFC | (val>>30), 8);
- ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | ((val>>24)&0x3F), 8);
- ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | ((val>>18)&0x3F), 8);
- ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | ((val>>12)&0x3F), 8);
- ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | ((val>>6)&0x3F), 8);
- ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (val&0x3F), 8);
- }
-
- return ok;
- }
-
- FLAC__bool FLAC__bitwriter_write_utf8_uint64(FLAC__BitWriter *bw, FLAC__uint64 val)
- {
- FLAC__bool ok = 1;
-
- FLAC__ASSERT(0 != bw);
- FLAC__ASSERT(0 != bw->buffer);
-
- FLAC__ASSERT(!(val & FLAC__U64L(0xFFFFFFF000000000))); /* this version only handles 36 bits */
-
- if(val < 0x80) {
- return FLAC__bitwriter_write_raw_uint32(bw, (FLAC__uint32)val, 8);
- }
- else if(val < 0x800) {
- ok &= FLAC__bitwriter_write_raw_uint32(bw, 0xC0 | (FLAC__uint32)(val>>6), 8);
- ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (FLAC__uint32)(val&0x3F), 8);
- }
- else if(val < 0x10000) {
- ok &= FLAC__bitwriter_write_raw_uint32(bw, 0xE0 | (FLAC__uint32)(val>>12), 8);
- ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (FLAC__uint32)((val>>6)&0x3F), 8);
- ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (FLAC__uint32)(val&0x3F), 8);
- }
- else if(val < 0x200000) {
- ok &= FLAC__bitwriter_write_raw_uint32(bw, 0xF0 | (FLAC__uint32)(val>>18), 8);
- ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (FLAC__uint32)((val>>12)&0x3F), 8);
- ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (FLAC__uint32)((val>>6)&0x3F), 8);
- ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (FLAC__uint32)(val&0x3F), 8);
- }
- else if(val < 0x4000000) {
- ok &= FLAC__bitwriter_write_raw_uint32(bw, 0xF8 | (FLAC__uint32)(val>>24), 8);
- ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (FLAC__uint32)((val>>18)&0x3F), 8);
- ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (FLAC__uint32)((val>>12)&0x3F), 8);
- ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (FLAC__uint32)((val>>6)&0x3F), 8);
- ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (FLAC__uint32)(val&0x3F), 8);
- }
- else if(val < 0x80000000) {
- ok &= FLAC__bitwriter_write_raw_uint32(bw, 0xFC | (FLAC__uint32)(val>>30), 8);
- ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (FLAC__uint32)((val>>24)&0x3F), 8);
- ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (FLAC__uint32)((val>>18)&0x3F), 8);
- ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (FLAC__uint32)((val>>12)&0x3F), 8);
- ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (FLAC__uint32)((val>>6)&0x3F), 8);
- ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (FLAC__uint32)(val&0x3F), 8);
- }
- else {
- ok &= FLAC__bitwriter_write_raw_uint32(bw, 0xFE, 8);
- ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (FLAC__uint32)((val>>30)&0x3F), 8);
- ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (FLAC__uint32)((val>>24)&0x3F), 8);
- ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (FLAC__uint32)((val>>18)&0x3F), 8);
- ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (FLAC__uint32)((val>>12)&0x3F), 8);
- ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (FLAC__uint32)((val>>6)&0x3F), 8);
- ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (FLAC__uint32)(val&0x3F), 8);
- }
-
- return ok;
- }
-
- FLAC__bool FLAC__bitwriter_zero_pad_to_byte_boundary(FLAC__BitWriter *bw)
- {
- /* 0-pad to byte boundary */
- if(bw->bits & 7u)
- return FLAC__bitwriter_write_zeroes(bw, 8 - (bw->bits & 7u));
- else
- return true;
- }
-
- #endif
- /********* End of inlined file: bitwriter.c *********/
-
- /********* Start of inlined file: cpu.c *********/
-
- /********* Start of inlined file: juce_FlacHeader.h *********/
- // This file is included at the start of each FLAC .c file, just to do a few housekeeping
- // tasks..
-
- #define VERSION "1.2.1"
-
- #define FLAC__NO_DLL 1
-
- #ifdef _MSC_VER
- #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4312)
- #endif
-
- #if ! (defined (_WIN32) || defined (_WIN64) || defined (LINUX))
- #define FLAC__SYS_DARWIN 1
- #endif
- /********* End of inlined file: juce_FlacHeader.h *********/
-
- #if JUCE_USE_FLAC
-
- #if HAVE_CONFIG_H
- # include <config.h>
- #endif
-
- #include <stdlib.h>
- #include <stdio.h>
-
- #if defined FLAC__CPU_IA32
- # include <signal.h>
- #elif defined FLAC__CPU_PPC
- # if !defined FLAC__NO_ASM
- # if defined FLAC__SYS_DARWIN
- # include <sys/sysctl.h>
- # include <mach/mach.h>
- # include <mach/mach_host.h>
- # include <mach/host_info.h>
- # include <mach/machine.h>
- # ifndef CPU_SUBTYPE_POWERPC_970
- # define CPU_SUBTYPE_POWERPC_970 ((cpu_subtype_t) 100)
- # endif
- # else /* FLAC__SYS_DARWIN */
-
- # include <signal.h>
- # include <setjmp.h>
-
- static sigjmp_buf jmpbuf;
- static volatile sig_atomic_t canjump = 0;
-
- static void sigill_handler (int sig)
- {
- if (!canjump) {
- signal (sig, SIG_DFL);
- raise (sig);
- }
- canjump = 0;
- siglongjmp (jmpbuf, 1);
- }
- # endif /* FLAC__SYS_DARWIN */
- # endif /* FLAC__NO_ASM */
- #endif /* FLAC__CPU_PPC */
-
- #if defined (__NetBSD__) || defined(__OpenBSD__)
- #include <sys/param.h>
- #include <sys/sysctl.h>
- #include <machine/cpu.h>
- #endif
-
- #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
- #include <sys/types.h>
- #include <sys/sysctl.h>
- #endif
-
- #if defined(__APPLE__)
- /* how to get sysctlbyname()? */
- #endif
-
- /* these are flags in EDX of CPUID AX=00000001 */
- static const unsigned FLAC__CPUINFO_IA32_CPUID_CMOV = 0x00008000;
- static const unsigned FLAC__CPUINFO_IA32_CPUID_MMX = 0x00800000;
- static const unsigned FLAC__CPUINFO_IA32_CPUID_FXSR = 0x01000000;
- static const unsigned FLAC__CPUINFO_IA32_CPUID_SSE = 0x02000000;
- static const unsigned FLAC__CPUINFO_IA32_CPUID_SSE2 = 0x04000000;
- /* these are flags in ECX of CPUID AX=00000001 */
- static const unsigned FLAC__CPUINFO_IA32_CPUID_SSE3 = 0x00000001;
- static const unsigned FLAC__CPUINFO_IA32_CPUID_SSSE3 = 0x00000200;
- /* these are flags in EDX of CPUID AX=80000001 */
- static const unsigned FLAC__CPUINFO_IA32_CPUID_EXTENDED_AMD_3DNOW = 0x80000000;
- static const unsigned FLAC__CPUINFO_IA32_CPUID_EXTENDED_AMD_EXT3DNOW = 0x40000000;
- static const unsigned FLAC__CPUINFO_IA32_CPUID_EXTENDED_AMD_EXTMMX = 0x00400000;
-
- /*
- * Extra stuff needed for detection of OS support for SSE on IA-32
- */
- #if defined(FLAC__CPU_IA32) && !defined FLAC__NO_ASM && defined FLAC__HAS_NASM && !defined FLAC__NO_SSE_OS && !defined FLAC__SSE_OS
- # if defined(__linux__)
- /*
- * If the OS doesn't support SSE, we will get here with a SIGILL. We
- * modify the return address to jump over the offending SSE instruction
- * and also the operation following it that indicates the instruction
- * executed successfully. In this way we use no global variables and
- * stay thread-safe.
- *
- * 3 + 3 + 6:
- * 3 bytes for "xorps xmm0,xmm0"
- * 3 bytes for estimate of how long the follwing "inc var" instruction is
- * 6 bytes extra in case our estimate is wrong
- * 12 bytes puts us in the NOP "landing zone"
- */
- # undef USE_OBSOLETE_SIGCONTEXT_FLAVOR /* #define this to use the older signal handler method */
- # ifdef USE_OBSOLETE_SIGCONTEXT_FLAVOR
- static void sigill_handler_sse_os(int signal, struct sigcontext sc)
- {
- (void)signal;
- sc.eip += 3 + 3 + 6;
- }
- # else
- # include <sys/ucontext.h>
- static void sigill_handler_sse_os(int signal, siginfo_t *si, void *uc)
- {
- (void)signal, (void)si;
- ((ucontext_t*)uc)->uc_mcontext.gregs[14/*REG_EIP*/] += 3 + 3 + 6;
- }
- # endif
- # elif defined(_MSC_VER)
- # include <windows.h>
- # undef USE_TRY_CATCH_FLAVOR /* #define this to use the try/catch method for catching illegal opcode exception */
- # ifdef USE_TRY_CATCH_FLAVOR
- # else
- LONG CALLBACK sigill_handler_sse_os(EXCEPTION_POINTERS *ep)
- {
- if(ep->ExceptionRecord->ExceptionCode == EXCEPTION_ILLEGAL_INSTRUCTION) {
- ep->ContextRecord->Eip += 3 + 3 + 6;
- return EXCEPTION_CONTINUE_EXECUTION;
- }
- return EXCEPTION_CONTINUE_SEARCH;
- }
- # endif
- # endif
- #endif
-
- void FLAC__cpu_info(FLAC__CPUInfo *info)
- {
- /*
- * IA32-specific
- */
- #ifdef FLAC__CPU_IA32
- info->type = FLAC__CPUINFO_TYPE_IA32;
- #if !defined FLAC__NO_ASM && defined FLAC__HAS_NASM
- info->use_asm = true; /* we assume a minimum of 80386 with FLAC__CPU_IA32 */
- info->data.ia32.cpuid = FLAC__cpu_have_cpuid_asm_ia32()? true : false;
- info->data.ia32.bswap = info->data.ia32.cpuid; /* CPUID => BSWAP since it came after */
- info->data.ia32.cmov = false;
- info->data.ia32.mmx = false;
- info->data.ia32.fxsr = false;
- info->data.ia32.sse = false;
- info->data.ia32.sse2 = false;
- info->data.ia32.sse3 = false;
- info->data.ia32.ssse3 = false;
- info->data.ia32._3dnow = false;
- info->data.ia32.ext3dnow = false;
- info->data.ia32.extmmx = false;
- if(info->data.ia32.cpuid) {
- /* http://www.sandpile.org/ia32/cpuid.htm */
- FLAC__uint32 flags_edx, flags_ecx;
- FLAC__cpu_info_asm_ia32(&flags_edx, &flags_ecx);
- info->data.ia32.cmov = (flags_edx & FLAC__CPUINFO_IA32_CPUID_CMOV )? true : false;
- info->data.ia32.mmx = (flags_edx & FLAC__CPUINFO_IA32_CPUID_MMX )? true : false;
- info->data.ia32.fxsr = (flags_edx & FLAC__CPUINFO_IA32_CPUID_FXSR )? true : false;
- info->data.ia32.sse = (flags_edx & FLAC__CPUINFO_IA32_CPUID_SSE )? true : false;
- info->data.ia32.sse2 = (flags_edx & FLAC__CPUINFO_IA32_CPUID_SSE2 )? true : false;
- info->data.ia32.sse3 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSE3 )? true : false;
- info->data.ia32.ssse3 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSSE3)? true : false;
-
- #ifdef FLAC__USE_3DNOW
- flags_edx = FLAC__cpu_info_extended_amd_asm_ia32();
- info->data.ia32._3dnow = (flags_edx & FLAC__CPUINFO_IA32_CPUID_EXTENDED_AMD_3DNOW )? true : false;
- info->data.ia32.ext3dnow = (flags_edx & FLAC__CPUINFO_IA32_CPUID_EXTENDED_AMD_EXT3DNOW)? true : false;
- info->data.ia32.extmmx = (flags_edx & FLAC__CPUINFO_IA32_CPUID_EXTENDED_AMD_EXTMMX )? true : false;
- #else
- info->data.ia32._3dnow = info->data.ia32.ext3dnow = info->data.ia32.extmmx = false;
- #endif
-
- #ifdef DEBUG
- fprintf(stderr, "CPU info (IA-32):\n");
- fprintf(stderr, " CPUID ...... %c\n", info->data.ia32.cpuid ? 'Y' : 'n');
- fprintf(stderr, " BSWAP ...... %c\n", info->data.ia32.bswap ? 'Y' : 'n');
- fprintf(stderr, " CMOV ....... %c\n", info->data.ia32.cmov ? 'Y' : 'n');
- fprintf(stderr, " MMX ........ %c\n", info->data.ia32.mmx ? 'Y' : 'n');
- fprintf(stderr, " FXSR ....... %c\n", info->data.ia32.fxsr ? 'Y' : 'n');
- fprintf(stderr, " SSE ........ %c\n", info->data.ia32.sse ? 'Y' : 'n');
- fprintf(stderr, " SSE2 ....... %c\n", info->data.ia32.sse2 ? 'Y' : 'n');
- fprintf(stderr, " SSE3 ....... %c\n", info->data.ia32.sse3 ? 'Y' : 'n');
- fprintf(stderr, " SSSE3 ...... %c\n", info->data.ia32.ssse3 ? 'Y' : 'n');
- fprintf(stderr, " 3DNow! ..... %c\n", info->data.ia32._3dnow ? 'Y' : 'n');
- fprintf(stderr, " 3DNow!-ext . %c\n", info->data.ia32.ext3dnow? 'Y' : 'n');
- fprintf(stderr, " 3DNow!-MMX . %c\n", info->data.ia32.extmmx ? 'Y' : 'n');
- #endif
-
- /*
- * now have to check for OS support of SSE/SSE2
- */
- if(info->data.ia32.fxsr || info->data.ia32.sse || info->data.ia32.sse2) {
- #if defined FLAC__NO_SSE_OS
- /* assume user knows better than us; turn it off */
- info->data.ia32.fxsr = info->data.ia32.sse = info->data.ia32.sse2 = info->data.ia32.sse3 = info->data.ia32.ssse3 = false;
- #elif defined FLAC__SSE_OS
- /* assume user knows better than us; leave as detected above */
- #elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) || defined(__APPLE__)
- int sse = 0;
- size_t len;
- /* at least one of these must work: */
- len = sizeof(sse); sse = sse || (sysctlbyname("hw.instruction_sse", &sse, &len, NULL, 0) == 0 && sse);
- len = sizeof(sse); sse = sse || (sysctlbyname("hw.optional.sse" , &sse, &len, NULL, 0) == 0 && sse); /* __APPLE__ ? */
- if(!sse)
- info->data.ia32.fxsr = info->data.ia32.sse = info->data.ia32.sse2 = info->data.ia32.sse3 = info->data.ia32.ssse3 = false;
- #elif defined(__NetBSD__) || defined (__OpenBSD__)
- # if __NetBSD_Version__ >= 105250000 || (defined __OpenBSD__)
- int val = 0, mib[2] = { CTL_MACHDEP, CPU_SSE };
- size_t len = sizeof(val);
- if(sysctl(mib, 2, &val, &len, NULL, 0) < 0 || !val)
- info->data.ia32.fxsr = info->data.ia32.sse = info->data.ia32.sse2 = info->data.ia32.sse3 = info->data.ia32.ssse3 = false;
- else { /* double-check SSE2 */
- mib[1] = CPU_SSE2;
- len = sizeof(val);
- if(sysctl(mib, 2, &val, &len, NULL, 0) < 0 || !val)
- info->data.ia32.sse2 = info->data.ia32.sse3 = info->data.ia32.ssse3 = false;
- }
- # else
- info->data.ia32.fxsr = info->data.ia32.sse = info->data.ia32.sse2 = info->data.ia32.sse3 = info->data.ia32.ssse3 = false;
- # endif
- #elif defined(__linux__)
- int sse = 0;
- struct sigaction sigill_save;
- #ifdef USE_OBSOLETE_SIGCONTEXT_FLAVOR
- if(0 == sigaction(SIGILL, NULL, &sigill_save) && signal(SIGILL, (void (*)(int))sigill_handler_sse_os) != SIG_ERR)
- #else
- struct sigaction sigill_sse;
- sigill_sse.sa_sigaction = sigill_handler_sse_os;
- __sigemptyset(&sigill_sse.sa_mask);
- sigill_sse.sa_flags = SA_SIGINFO | SA_RESETHAND; /* SA_RESETHAND just in case our SIGILL return jump breaks, so we don't get stuck in a loop */
- if(0 == sigaction(SIGILL, &sigill_sse, &sigill_save))
- #endif
- {
- /* http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html */
- /* see sigill_handler_sse_os() for an explanation of the following: */
- asm volatile (
- "xorl %0,%0\n\t" /* for some reason, still need to do this to clear 'sse' var */
- "xorps %%xmm0,%%xmm0\n\t" /* will cause SIGILL if unsupported by OS */
- "incl %0\n\t" /* SIGILL handler will jump over this */
- /* landing zone */
- "nop\n\t" /* SIGILL jump lands here if "inc" is 9 bytes */
- "nop\n\t"
- "nop\n\t"
- "nop\n\t"
- "nop\n\t"
- "nop\n\t"
- "nop\n\t" /* SIGILL jump lands here if "inc" is 3 bytes (expected) */
- "nop\n\t"
- "nop" /* SIGILL jump lands here if "inc" is 1 byte */
- : "=r"(sse)
- : "r"(sse)
- );
-
- sigaction(SIGILL, &sigill_save, NULL);
- }
-
- if(!sse)
- info->data.ia32.fxsr = info->data.ia32.sse = info->data.ia32.sse2 = info->data.ia32.sse3 = info->data.ia32.ssse3 = false;
- #elif defined(_MSC_VER)
- # ifdef USE_TRY_CATCH_FLAVOR
- _try {
- __asm {
- # if _MSC_VER <= 1200
- /* VC6 assembler doesn't know SSE, have to emit bytecode instead */
- _emit 0x0F
- _emit 0x57
- _emit 0xC0
- # else
- xorps xmm0,xmm0
- # endif
- }
- }
- _except(EXCEPTION_EXECUTE_HANDLER) {
- if (_exception_code() == STATUS_ILLEGAL_INSTRUCTION)
- info->data.ia32.fxsr = info->data.ia32.sse = info->data.ia32.sse2 = info->data.ia32.sse3 = info->data.ia32.ssse3 = false;
- }
- # else
- int sse = 0;
- LPTOP_LEVEL_EXCEPTION_FILTER save = SetUnhandledExceptionFilter(sigill_handler_sse_os);
- /* see GCC version above for explanation */
- /* http://msdn2.microsoft.com/en-us/library/4ks26t93.aspx */
- /* http://www.codeproject.com/cpp/gccasm.asp */
- /* http://www.hick.org/~mmiller/msvc_inline_asm.html */
- __asm {
- # if _MSC_VER <= 1200
- /* VC6 assembler doesn't know SSE, have to emit bytecode instead */
- _emit 0x0F
- _emit 0x57
- _emit 0xC0
- # else
- xorps xmm0,xmm0
- # endif
- inc sse
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- }
- SetUnhandledExceptionFilter(save);
- if(!sse)
- info->data.ia32.fxsr = info->data.ia32.sse = info->data.ia32.sse2 = info->data.ia32.sse3 = info->data.ia32.ssse3 = false;
- # endif
- #else
- /* no way to test, disable to be safe */
- info->data.ia32.fxsr = info->data.ia32.sse = info->data.ia32.sse2 = info->data.ia32.sse3 = info->data.ia32.ssse3 = false;
- #endif
- #ifdef DEBUG
- fprintf(stderr, " SSE OS sup . %c\n", info->data.ia32.sse ? 'Y' : 'n');
- #endif
-
- }
- }
- #else
- info->use_asm = false;
- #endif
-
- /*
- * PPC-specific
- */
- #elif defined FLAC__CPU_PPC
- info->type = FLAC__CPUINFO_TYPE_PPC;
- # if !defined FLAC__NO_ASM
- info->use_asm = true;
- # ifdef FLAC__USE_ALTIVEC
- # if defined FLAC__SYS_DARWIN
- {
- int val = 0, mib[2] = { CTL_HW, HW_VECTORUNIT };
- size_t len = sizeof(val);
- info->data.ppc.altivec = !(sysctl(mib, 2, &val, &len, NULL, 0) || !val);
- }
- {
- host_basic_info_data_t hostInfo;
- mach_msg_type_number_t infoCount;
-
- infoCount = HOST_BASIC_INFO_COUNT;
- host_info(mach_host_self(), HOST_BASIC_INFO, (host_info_t)&hostInfo, &infoCount);
-
- info->data.ppc.ppc64 = (hostInfo.cpu_type == CPU_TYPE_POWERPC) && (hostInfo.cpu_subtype == CPU_SUBTYPE_POWERPC_970);
- }
- # else /* FLAC__USE_ALTIVEC && !FLAC__SYS_DARWIN */
- {
- /* no Darwin, do it the brute-force way */
- /* @@@@@@ this is not thread-safe; replace with SSE OS method above or remove */
- info->data.ppc.altivec = 0;
- info->data.ppc.ppc64 = 0;
-
- signal (SIGILL, sigill_handler);
- canjump = 0;
- if (!sigsetjmp (jmpbuf, 1)) {
- canjump = 1;
-
- asm volatile (
- "mtspr 256, %0\n\t"
- "vand %%v0, %%v0, %%v0"
- :
- : "r" (-1)
- );
-
- info->data.ppc.altivec = 1;
- }
- canjump = 0;
- if (!sigsetjmp (jmpbuf, 1)) {
- int x = 0;
- canjump = 1;
-
- /* PPC64 hardware implements the cntlzd instruction */
- asm volatile ("cntlzd %0, %1" : "=r" (x) : "r" (x) );
-
- info->data.ppc.ppc64 = 1;
- }
- signal (SIGILL, SIG_DFL); /*@@@@@@ should save and restore old signal */
- }
- # endif
- # else /* !FLAC__USE_ALTIVEC */
- info->data.ppc.altivec = 0;
- info->data.ppc.ppc64 = 0;
- # endif
- # else
- info->use_asm = false;
- # endif
-
- /*
- * unknown CPI
- */
- #else
- info->type = FLAC__CPUINFO_TYPE_UNKNOWN;
- info->use_asm = false;
- #endif
- }
-
- #endif
- /********* End of inlined file: cpu.c *********/
-
- /********* Start of inlined file: crc.c *********/
-
- /********* Start of inlined file: juce_FlacHeader.h *********/
- // This file is included at the start of each FLAC .c file, just to do a few housekeeping
- // tasks..
-
- #define VERSION "1.2.1"
-
- #define FLAC__NO_DLL 1
-
- #ifdef _MSC_VER
- #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4312)
- #endif
-
- #if ! (defined (_WIN32) || defined (_WIN64) || defined (LINUX))
- #define FLAC__SYS_DARWIN 1
- #endif
- /********* End of inlined file: juce_FlacHeader.h *********/
-
- #if JUCE_USE_FLAC
-
- #if HAVE_CONFIG_H
- # include <config.h>
- #endif
-
- /* CRC-8, poly = x^8 + x^2 + x^1 + x^0, init = 0 */
-
- FLAC__byte const FLAC__crc8_table[256] = {
- 0x00, 0x07, 0x0E, 0x09, 0x1C, 0x1B, 0x12, 0x15,
- 0x38, 0x3F, 0x36, 0x31, 0x24, 0x23, 0x2A, 0x2D,
- 0x70, 0x77, 0x7E, 0x79, 0x6C, 0x6B, 0x62, 0x65,
- 0x48, 0x4F, 0x46, 0x41, 0x54, 0x53, 0x5A, 0x5D,
- 0xE0, 0xE7, 0xEE, 0xE9, 0xFC, 0xFB, 0xF2, 0xF5,
- 0xD8, 0xDF, 0xD6, 0xD1, 0xC4, 0xC3, 0xCA, 0xCD,
- 0x90, 0x97, 0x9E, 0x99, 0x8C, 0x8B, 0x82, 0x85,
- 0xA8, 0xAF, 0xA6, 0xA1, 0xB4, 0xB3, 0xBA, 0xBD,
- 0xC7, 0xC0, 0xC9, 0xCE, 0xDB, 0xDC, 0xD5, 0xD2,
- 0xFF, 0xF8, 0xF1, 0xF6, 0xE3, 0xE4, 0xED, 0xEA,
- 0xB7, 0xB0, 0xB9, 0xBE, 0xAB, 0xAC, 0xA5, 0xA2,
- 0x8F, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9D, 0x9A,
- 0x27, 0x20, 0x29, 0x2E, 0x3B, 0x3C, 0x35, 0x32,
- 0x1F, 0x18, 0x11, 0x16, 0x03, 0x04, 0x0D, 0x0A,
- 0x57, 0x50, 0x59, 0x5E, 0x4B, 0x4C, 0x45, 0x42,
- 0x6F, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7D, 0x7A,
- 0x89, 0x8E, 0x87, 0x80, 0x95, 0x92, 0x9B, 0x9C,
- 0xB1, 0xB6, 0xBF, 0xB8, 0xAD, 0xAA, 0xA3, 0xA4,
- 0xF9, 0xFE, 0xF7, 0xF0, 0xE5, 0xE2, 0xEB, 0xEC,
- 0xC1, 0xC6, 0xCF, 0xC8, 0xDD, 0xDA, 0xD3, 0xD4,
- 0x69, 0x6E, 0x67, 0x60, 0x75, 0x72, 0x7B, 0x7C,
- 0x51, 0x56, 0x5F, 0x58, 0x4D, 0x4A, 0x43, 0x44,
- 0x19, 0x1E, 0x17, 0x10, 0x05, 0x02, 0x0B, 0x0C,
- 0x21, 0x26, 0x2F, 0x28, 0x3D, 0x3A, 0x33, 0x34,
- 0x4E, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5C, 0x5B,
- 0x76, 0x71, 0x78, 0x7F, 0x6A, 0x6D, 0x64, 0x63,
- 0x3E, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2C, 0x2B,
- 0x06, 0x01, 0x08, 0x0F, 0x1A, 0x1D, 0x14, 0x13,
- 0xAE, 0xA9, 0xA0, 0xA7, 0xB2, 0xB5, 0xBC, 0xBB,
- 0x96, 0x91, 0x98, 0x9F, 0x8A, 0x8D, 0x84, 0x83,
- 0xDE, 0xD9, 0xD0, 0xD7, 0xC2, 0xC5, 0xCC, 0xCB,
- 0xE6, 0xE1, 0xE8, 0xEF, 0xFA, 0xFD, 0xF4, 0xF3
- };
-
- /* CRC-16, poly = x^16 + x^15 + x^2 + x^0, init = 0 */
-
- unsigned FLAC__crc16_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
- };
-
- void FLAC__crc8_update(const FLAC__byte data, FLAC__uint8 *crc)
- {
- *crc = FLAC__crc8_table[*crc ^ data];
- }
-
- void FLAC__crc8_update_block(const FLAC__byte *data, unsigned len, FLAC__uint8 *crc)
- {
- while(len--)
- *crc = FLAC__crc8_table[*crc ^ *data++];
- }
-
- FLAC__uint8 FLAC__crc8(const FLAC__byte *data, unsigned len)
- {
- FLAC__uint8 crc = 0;
-
- while(len--)
- crc = FLAC__crc8_table[crc ^ *data++];
-
- return crc;
- }
-
- unsigned FLAC__crc16(const FLAC__byte *data, unsigned len)
- {
- unsigned crc = 0;
-
- while(len--)
- crc = ((crc<<8) ^ FLAC__crc16_table[(crc>>8) ^ *data++]) & 0xffff;
-
- return crc;
- }
-
- #endif
- /********* End of inlined file: crc.c *********/
-
- /********* Start of inlined file: fixed.c *********/
-
- /********* Start of inlined file: juce_FlacHeader.h *********/
- // This file is included at the start of each FLAC .c file, just to do a few housekeeping
- // tasks..
-
- #define VERSION "1.2.1"
-
- #define FLAC__NO_DLL 1
-
- #ifdef _MSC_VER
- #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4312)
- #endif
-
- #if ! (defined (_WIN32) || defined (_WIN64) || defined (LINUX))
- #define FLAC__SYS_DARWIN 1
- #endif
- /********* End of inlined file: juce_FlacHeader.h *********/
-
- #if JUCE_USE_FLAC
-
- #if HAVE_CONFIG_H
- # include <config.h>
- #endif
-
- #include <math.h>
- #include <string.h>
-
- /********* Start of inlined file: fixed.h *********/
- #ifndef FLAC__PRIVATE__FIXED_H
- #define FLAC__PRIVATE__FIXED_H
-
- #ifdef HAVE_CONFIG_H
- #include <config.h>
- #endif
-
- /********* Start of inlined file: float.h *********/
- #ifndef FLAC__PRIVATE__FLOAT_H
- #define FLAC__PRIVATE__FLOAT_H
-
- #ifdef HAVE_CONFIG_H
- #include <config.h>
- #endif
-
- /*
- * These typedefs make it easier to ensure that integer versions of
- * the library really only contain integer operations. All the code
- * in libFLAC should use FLAC__float and FLAC__double in place of
- * float and double, and be protected by checks of the macro
- * FLAC__INTEGER_ONLY_LIBRARY.
- *
- * FLAC__real is the basic floating point type used in LPC analysis.
- */
- #ifndef FLAC__INTEGER_ONLY_LIBRARY
- typedef double FLAC__double;
- typedef float FLAC__float;
- /*
- * WATCHOUT: changing FLAC__real will change the signatures of many
- * functions that have assembly language equivalents and break them.
- */
- typedef float FLAC__real;
- #else
- /*
- * The convention for FLAC__fixedpoint is to use the upper 16 bits
- * for the integer part and lower 16 bits for the fractional part.
- */
- typedef FLAC__int32 FLAC__fixedpoint;
- extern const FLAC__fixedpoint FLAC__FP_ZERO;
- extern const FLAC__fixedpoint FLAC__FP_ONE_HALF;
- extern const FLAC__fixedpoint FLAC__FP_ONE;
- extern const FLAC__fixedpoint FLAC__FP_LN2;
- extern const FLAC__fixedpoint FLAC__FP_E;
-
- #define FLAC__fixedpoint_trunc(x) ((x)>>16)
-
- #define FLAC__fixedpoint_mul(x, y) ( (FLAC__fixedpoint) ( ((FLAC__int64)(x)*(FLAC__int64)(y)) >> 16 ) )
-
- #define FLAC__fixedpoint_div(x, y) ( (FLAC__fixedpoint) ( ( ((FLAC__int64)(x)<<32) / (FLAC__int64)(y) ) >> 16 ) )
-
- /*
- * FLAC__fixedpoint_log2()
- * --------------------------------------------------------------------
- * Returns the base-2 logarithm of the fixed-point number 'x' using an
- * algorithm by Knuth for x >= 1.0
- *
- * 'fracbits' is the number of fractional bits of 'x'. 'fracbits' must
- * be < 32 and evenly divisible by 4 (0 is OK but not very precise).
- *
- * 'precision' roughly limits the number of iterations that are done;
- * use (unsigned)(-1) for maximum precision.
- *
- * If 'x' is less than one -- that is, x < (1<<fracbits) -- then this
- * function will punt and return 0.
- *
- * The return value will also have 'fracbits' fractional bits.
- */
- FLAC__uint32 FLAC__fixedpoint_log2(FLAC__uint32 x, unsigned fracbits, unsigned precision);
-
- #endif
-
- #endif
- /********* End of inlined file: float.h *********/
-
- /********* Start of inlined file: format.h *********/
- #ifndef FLAC__PRIVATE__FORMAT_H
- #define FLAC__PRIVATE__FORMAT_H
-
- unsigned FLAC__format_get_max_rice_partition_order(unsigned blocksize, unsigned predictor_order);
- unsigned FLAC__format_get_max_rice_partition_order_from_blocksize(unsigned blocksize);
- unsigned FLAC__format_get_max_rice_partition_order_from_blocksize_limited_max_and_predictor_order(unsigned limit, unsigned blocksize, unsigned predictor_order);
- void FLAC__format_entropy_coding_method_partitioned_rice_contents_init(FLAC__EntropyCodingMethod_PartitionedRiceContents *object);
- void FLAC__format_entropy_coding_method_partitioned_rice_contents_clear(FLAC__EntropyCodingMethod_PartitionedRiceContents *object);
- FLAC__bool FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(FLAC__EntropyCodingMethod_PartitionedRiceContents *object, unsigned max_partition_order);
-
- #endif
- /********* End of inlined file: format.h *********/
-
- /*
- * FLAC__fixed_compute_best_predictor()
- * --------------------------------------------------------------------
- * Compute the best fixed predictor and the expected bits-per-sample
- * of the residual signal for each order. The _wide() version uses
- * 64-bit integers which is statistically necessary when bits-per-
- * sample + log2(blocksize) > 30
- *
- * IN data[0,data_len-1]
- * IN data_len
- * OUT residual_bits_per_sample[0,FLAC__MAX_FIXED_ORDER]
- */
- #ifndef FLAC__INTEGER_ONLY_LIBRARY
- unsigned FLAC__fixed_compute_best_predictor(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]);
- # ifndef FLAC__NO_ASM
- # ifdef FLAC__CPU_IA32
- # ifdef FLAC__HAS_NASM
- unsigned FLAC__fixed_compute_best_predictor_asm_ia32_mmx_cmov(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]);
- # endif
- # endif
- # endif
- unsigned FLAC__fixed_compute_best_predictor_wide(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]);
- #else
- unsigned FLAC__fixed_compute_best_predictor(const FLAC__int32 data[], unsigned data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]);
- unsigned FLAC__fixed_compute_best_predictor_wide(const FLAC__int32 data[], unsigned data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]);
- #endif
-
- /*
- * FLAC__fixed_compute_residual()
- * --------------------------------------------------------------------
- * Compute the residual signal obtained from sutracting the predicted
- * signal from the original.
- *
- * IN data[-order,data_len-1] original signal (NOTE THE INDICES!)
- * IN data_len length of original signal
- * IN order <= FLAC__MAX_FIXED_ORDER fixed-predictor order
- * OUT residual[0,data_len-1] residual signal
- */
- void FLAC__fixed_compute_residual(const FLAC__int32 data[], unsigned data_len, unsigned order, FLAC__int32 residual[]);
-
- /*
- * FLAC__fixed_restore_signal()
- * --------------------------------------------------------------------
- * Restore the original signal by summing the residual and the
- * predictor.
- *
- * IN residual[0,data_len-1] residual signal
- * IN data_len length of original signal
- * IN order <= FLAC__MAX_FIXED_ORDER fixed-predictor order
- * *** IMPORTANT: the caller must pass in the historical samples:
- * IN data[-order,-1] previously-reconstructed historical samples
- * OUT data[0,data_len-1] original signal
- */
- void FLAC__fixed_restore_signal(const FLAC__int32 residual[], unsigned data_len, unsigned order, FLAC__int32 data[]);
-
- #endif
- /********* End of inlined file: fixed.h *********/
-
- #ifndef M_LN2
- /* math.h in VC++ doesn't seem to have this (how Microsoft is that?) */
- #define M_LN2 0.69314718055994530942
- #endif
-
- #ifdef min
- #undef min
- #endif
- #define min(x,y) ((x) < (y)? (x) : (y))
-
- #ifdef local_abs
- #undef local_abs
- #endif
- #define local_abs(x) ((unsigned)((x)<0? -(x) : (x)))
-
- #ifdef FLAC__INTEGER_ONLY_LIBRARY
- /* rbps stands for residual bits per sample
- *
- * (ln(2) * err)
- * rbps = log (-----------)
- * 2 ( n )
- */
- static FLAC__fixedpoint local__compute_rbps_integerized(FLAC__uint32 err, FLAC__uint32 n)
- {
- FLAC__uint32 rbps;
- unsigned bits; /* the number of bits required to represent a number */
- int fracbits; /* the number of bits of rbps that comprise the fractional part */
-
- FLAC__ASSERT(sizeof(rbps) == sizeof(FLAC__fixedpoint));
- FLAC__ASSERT(err > 0);
- FLAC__ASSERT(n > 0);
-
- FLAC__ASSERT(n <= FLAC__MAX_BLOCK_SIZE);
- if(err <= n)
- return 0;
- /*
- * The above two things tell us 1) n fits in 16 bits; 2) err/n > 1.
- * These allow us later to know we won't lose too much precision in the
- * fixed-point division (err<<fracbits)/n.
- */
-
- fracbits = (8*sizeof(err)) - (FLAC__bitmath_ilog2(err)+1);
-
- err <<= fracbits;
- err /= n;
- /* err now holds err/n with fracbits fractional bits */
-
- /*
- * Whittle err down to 16 bits max. 16 significant bits is enough for
- * our purposes.
- */
- FLAC__ASSERT(err > 0);
- bits = FLAC__bitmath_ilog2(err)+1;
- if(bits > 16) {
- err >>= (bits-16);
- fracbits -= (bits-16);
- }
- rbps = (FLAC__uint32)err;
-
- /* Multiply by fixed-point version of ln(2), with 16 fractional bits */
- rbps *= FLAC__FP_LN2;
- fracbits += 16;
- FLAC__ASSERT(fracbits >= 0);
-
- /* FLAC__fixedpoint_log2 requires fracbits%4 to be 0 */
- {
- const int f = fracbits & 3;
- if(f) {
- rbps >>= f;
- fracbits -= f;
- }
- }
-
- rbps = FLAC__fixedpoint_log2(rbps, fracbits, (unsigned)(-1));
-
- if(rbps == 0)
- return 0;
-
- /*
- * The return value must have 16 fractional bits. Since the whole part
- * of the base-2 log of a 32 bit number must fit in 5 bits, and fracbits
- * must be >= -3, these assertion allows us to be able to shift rbps
- * left if necessary to get 16 fracbits without losing any bits of the
- * whole part of rbps.
- *
- * There is a slight chance due to accumulated error that the whole part
- * will require 6 bits, so we use 6 in the assertion. Really though as
- * long as it fits in 13 bits (32 - (16 - (-3))) we are fine.
- */
- FLAC__ASSERT((int)FLAC__bitmath_ilog2(rbps)+1 <= fracbits + 6);
- FLAC__ASSERT(fracbits >= -3);
-
- /* now shift the decimal point into place */
- if(fracbits < 16)
- return rbps << (16-fracbits);
- else if(fracbits > 16)
- return rbps >> (fracbits-16);
- else
- return rbps;
- }
-
- static FLAC__fixedpoint local__compute_rbps_wide_integerized(FLAC__uint64 err, FLAC__uint32 n)
- {
- FLAC__uint32 rbps;
- unsigned bits; /* the number of bits required to represent a number */
- int fracbits; /* the number of bits of rbps that comprise the fractional part */
-
- FLAC__ASSERT(sizeof(rbps) == sizeof(FLAC__fixedpoint));
- FLAC__ASSERT(err > 0);
- FLAC__ASSERT(n > 0);
-
- FLAC__ASSERT(n <= FLAC__MAX_BLOCK_SIZE);
- if(err <= n)
- return 0;
- /*
- * The above two things tell us 1) n fits in 16 bits; 2) err/n > 1.
- * These allow us later to know we won't lose too much precision in the
- * fixed-point division (err<<fracbits)/n.
- */
-
- fracbits = (8*sizeof(err)) - (FLAC__bitmath_ilog2_wide(err)+1);
-
- err <<= fracbits;
- err /= n;
- /* err now holds err/n with fracbits fractional bits */
-
- /*
- * Whittle err down to 16 bits max. 16 significant bits is enough for
- * our purposes.
- */
- FLAC__ASSERT(err > 0);
- bits = FLAC__bitmath_ilog2_wide(err)+1;
- if(bits > 16) {
- err >>= (bits-16);
- fracbits -= (bits-16);
- }
- rbps = (FLAC__uint32)err;
-
- /* Multiply by fixed-point version of ln(2), with 16 fractional bits */
- rbps *= FLAC__FP_LN2;
- fracbits += 16;
- FLAC__ASSERT(fracbits >= 0);
-
- /* FLAC__fixedpoint_log2 requires fracbits%4 to be 0 */
- {
- const int f = fracbits & 3;
- if(f) {
- rbps >>= f;
- fracbits -= f;
- }
- }
-
- rbps = FLAC__fixedpoint_log2(rbps, fracbits, (unsigned)(-1));
-
- if(rbps == 0)
- return 0;
-
- /*
- * The return value must have 16 fractional bits. Since the whole part
- * of the base-2 log of a 32 bit number must fit in 5 bits, and fracbits
- * must be >= -3, these assertion allows us to be able to shift rbps
- * left if necessary to get 16 fracbits without losing any bits of the
- * whole part of rbps.
- *
- * There is a slight chance due to accumulated error that the whole part
- * will require 6 bits, so we use 6 in the assertion. Really though as
- * long as it fits in 13 bits (32 - (16 - (-3))) we are fine.
- */
- FLAC__ASSERT((int)FLAC__bitmath_ilog2(rbps)+1 <= fracbits + 6);
- FLAC__ASSERT(fracbits >= -3);
-
- /* now shift the decimal point into place */
- if(fracbits < 16)
- return rbps << (16-fracbits);
- else if(fracbits > 16)
- return rbps >> (fracbits-16);
- else
- return rbps;
- }
- #endif
-
- #ifndef FLAC__INTEGER_ONLY_LIBRARY
- unsigned FLAC__fixed_compute_best_predictor(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1])
- #else
- unsigned FLAC__fixed_compute_best_predictor(const FLAC__int32 data[], unsigned data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1])
- #endif
- {
- FLAC__int32 last_error_0 = data[-1];
- FLAC__int32 last_error_1 = data[-1] - data[-2];
- FLAC__int32 last_error_2 = last_error_1 - (data[-2] - data[-3]);
- FLAC__int32 last_error_3 = last_error_2 - (data[-2] - 2*data[-3] + data[-4]);
- FLAC__int32 error, save;
- FLAC__uint32 total_error_0 = 0, total_error_1 = 0, total_error_2 = 0, total_error_3 = 0, total_error_4 = 0;
- unsigned i, order;
-
- for(i = 0; i < data_len; i++) {
- error = data[i] ; total_error_0 += local_abs(error); save = error;
- error -= last_error_0; total_error_1 += local_abs(error); last_error_0 = save; save = error;
- error -= last_error_1; total_error_2 += local_abs(error); last_error_1 = save; save = error;
- error -= last_error_2; total_error_3 += local_abs(error); last_error_2 = save; save = error;
- error -= last_error_3; total_error_4 += local_abs(error); last_error_3 = save;
- }
-
- if(total_error_0 < min(min(min(total_error_1, total_error_2), total_error_3), total_error_4))
- order = 0;
- else if(total_error_1 < min(min(total_error_2, total_error_3), total_error_4))
- order = 1;
- else if(total_error_2 < min(total_error_3, total_error_4))
- order = 2;
- else if(total_error_3 < total_error_4)
- order = 3;
- else
- order = 4;
-
- /* Estimate the expected number of bits per residual signal sample. */
- /* 'total_error*' is linearly related to the variance of the residual */
- /* signal, so we use it directly to compute E(|x|) */
- FLAC__ASSERT(data_len > 0 || total_error_0 == 0);
- FLAC__ASSERT(data_len > 0 || total_error_1 == 0);
- FLAC__ASSERT(data_len > 0 || total_error_2 == 0);
- FLAC__ASSERT(data_len > 0 || total_error_3 == 0);
- FLAC__ASSERT(data_len > 0 || total_error_4 == 0);
- #ifndef FLAC__INTEGER_ONLY_LIBRARY
- residual_bits_per_sample[0] = (FLAC__float)((total_error_0 > 0) ? log(M_LN2 * (FLAC__double)total_error_0 / (FLAC__double)data_len) / M_LN2 : 0.0);
- residual_bits_per_sample[1] = (FLAC__float)((total_error_1 > 0) ? log(M_LN2 * (FLAC__double)total_error_1 / (FLAC__double)data_len) / M_LN2 : 0.0);
- residual_bits_per_sample[2] = (FLAC__float)((total_error_2 > 0) ? log(M_LN2 * (FLAC__double)total_error_2 / (FLAC__double)data_len) / M_LN2 : 0.0);
- residual_bits_per_sample[3] = (FLAC__float)((total_error_3 > 0) ? log(M_LN2 * (FLAC__double)total_error_3 / (FLAC__double)data_len) / M_LN2 : 0.0);
- residual_bits_per_sample[4] = (FLAC__float)((total_error_4 > 0) ? log(M_LN2 * (FLAC__double)total_error_4 / (FLAC__double)data_len) / M_LN2 : 0.0);
- #else
- residual_bits_per_sample[0] = (total_error_0 > 0) ? local__compute_rbps_integerized(total_error_0, data_len) : 0;
- residual_bits_per_sample[1] = (total_error_1 > 0) ? local__compute_rbps_integerized(total_error_1, data_len) : 0;
- residual_bits_per_sample[2] = (total_error_2 > 0) ? local__compute_rbps_integerized(total_error_2, data_len) : 0;
- residual_bits_per_sample[3] = (total_error_3 > 0) ? local__compute_rbps_integerized(total_error_3, data_len) : 0;
- residual_bits_per_sample[4] = (total_error_4 > 0) ? local__compute_rbps_integerized(total_error_4, data_len) : 0;
- #endif
-
- return order;
- }
-
- #ifndef FLAC__INTEGER_ONLY_LIBRARY
- unsigned FLAC__fixed_compute_best_predictor_wide(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1])
- #else
- unsigned FLAC__fixed_compute_best_predictor_wide(const FLAC__int32 data[], unsigned data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1])
- #endif
- {
- FLAC__int32 last_error_0 = data[-1];
- FLAC__int32 last_error_1 = data[-1] - data[-2];
- FLAC__int32 last_error_2 = last_error_1 - (data[-2] - data[-3]);
- FLAC__int32 last_error_3 = last_error_2 - (data[-2] - 2*data[-3] + data[-4]);
- FLAC__int32 error, save;
- /* total_error_* are 64-bits to avoid overflow when encoding
- * erratic signals when the bits-per-sample and blocksize are
- * large.
- */
- FLAC__uint64 total_error_0 = 0, total_error_1 = 0, total_error_2 = 0, total_error_3 = 0, total_error_4 = 0;
- unsigned i, order;
-
- for(i = 0; i < data_len; i++) {
- error = data[i] ; total_error_0 += local_abs(error); save = error;
- error -= last_error_0; total_error_1 += local_abs(error); last_error_0 = save; save = error;
- error -= last_error_1; total_error_2 += local_abs(error); last_error_1 = save; save = error;
- error -= last_error_2; total_error_3 += local_abs(error); last_error_2 = save; save = error;
- error -= last_error_3; total_error_4 += local_abs(error); last_error_3 = save;
- }
-
- if(total_error_0 < min(min(min(total_error_1, total_error_2), total_error_3), total_error_4))
- order = 0;
- else if(total_error_1 < min(min(total_error_2, total_error_3), total_error_4))
- order = 1;
- else if(total_error_2 < min(total_error_3, total_error_4))
- order = 2;
- else if(total_error_3 < total_error_4)
- order = 3;
- else
- order = 4;
-
- /* Estimate the expected number of bits per residual signal sample. */
- /* 'total_error*' is linearly related to the variance of the residual */
- /* signal, so we use it directly to compute E(|x|) */
- FLAC__ASSERT(data_len > 0 || total_error_0 == 0);
- FLAC__ASSERT(data_len > 0 || total_error_1 == 0);
- FLAC__ASSERT(data_len > 0 || total_error_2 == 0);
- FLAC__ASSERT(data_len > 0 || total_error_3 == 0);
- FLAC__ASSERT(data_len > 0 || total_error_4 == 0);
- #ifndef FLAC__INTEGER_ONLY_LIBRARY
- #if defined _MSC_VER || defined __MINGW32__
- /* with MSVC you have to spoon feed it the casting */
- residual_bits_per_sample[0] = (FLAC__float)((total_error_0 > 0) ? log(M_LN2 * (FLAC__double)(FLAC__int64)total_error_0 / (FLAC__double)data_len) / M_LN2 : 0.0);
- residual_bits_per_sample[1] = (FLAC__float)((total_error_1 > 0) ? log(M_LN2 * (FLAC__double)(FLAC__int64)total_error_1 / (FLAC__double)data_len) / M_LN2 : 0.0);
- residual_bits_per_sample[2] = (FLAC__float)((total_error_2 > 0) ? log(M_LN2 * (FLAC__double)(FLAC__int64)total_error_2 / (FLAC__double)data_len) / M_LN2 : 0.0);
- residual_bits_per_sample[3] = (FLAC__float)((total_error_3 > 0) ? log(M_LN2 * (FLAC__double)(FLAC__int64)total_error_3 / (FLAC__double)data_len) / M_LN2 : 0.0);
- residual_bits_per_sample[4] = (FLAC__float)((total_error_4 > 0) ? log(M_LN2 * (FLAC__double)(FLAC__int64)total_error_4 / (FLAC__double)data_len) / M_LN2 : 0.0);
- #else
- residual_bits_per_sample[0] = (FLAC__float)((total_error_0 > 0) ? log(M_LN2 * (FLAC__double)total_error_0 / (FLAC__double)data_len) / M_LN2 : 0.0);
- residual_bits_per_sample[1] = (FLAC__float)((total_error_1 > 0) ? log(M_LN2 * (FLAC__double)total_error_1 / (FLAC__double)data_len) / M_LN2 : 0.0);
- residual_bits_per_sample[2] = (FLAC__float)((total_error_2 > 0) ? log(M_LN2 * (FLAC__double)total_error_2 / (FLAC__double)data_len) / M_LN2 : 0.0);
- residual_bits_per_sample[3] = (FLAC__float)((total_error_3 > 0) ? log(M_LN2 * (FLAC__double)total_error_3 / (FLAC__double)data_len) / M_LN2 : 0.0);
- residual_bits_per_sample[4] = (FLAC__float)((total_error_4 > 0) ? log(M_LN2 * (FLAC__double)total_error_4 / (FLAC__double)data_len) / M_LN2 : 0.0);
- #endif
- #else
- residual_bits_per_sample[0] = (total_error_0 > 0) ? local__compute_rbps_wide_integerized(total_error_0, data_len) : 0;
- residual_bits_per_sample[1] = (total_error_1 > 0) ? local__compute_rbps_wide_integerized(total_error_1, data_len) : 0;
- residual_bits_per_sample[2] = (total_error_2 > 0) ? local__compute_rbps_wide_integerized(total_error_2, data_len) : 0;
- residual_bits_per_sample[3] = (total_error_3 > 0) ? local__compute_rbps_wide_integerized(total_error_3, data_len) : 0;
- residual_bits_per_sample[4] = (total_error_4 > 0) ? local__compute_rbps_wide_integerized(total_error_4, data_len) : 0;
- #endif
-
- return order;
- }
-
- void FLAC__fixed_compute_residual(const FLAC__int32 data[], unsigned data_len, unsigned order, FLAC__int32 residual[])
- {
- const int idata_len = (int)data_len;
- int i;
-
- switch(order) {
- case 0:
- FLAC__ASSERT(sizeof(residual[0]) == sizeof(data[0]));
- memcpy(residual, data, sizeof(residual[0])*data_len);
- break;
- case 1:
- for(i = 0; i < idata_len; i++)
- residual[i] = data[i] - data[i-1];
- break;
- case 2:
- for(i = 0; i < idata_len; i++)
- #if 1 /* OPT: may be faster with some compilers on some systems */
- residual[i] = data[i] - (data[i-1] << 1) + data[i-2];
- #else
- residual[i] = data[i] - 2*data[i-1] + data[i-2];
- #endif
- break;
- case 3:
- for(i = 0; i < idata_len; i++)
- #if 1 /* OPT: may be faster with some compilers on some systems */
- residual[i] = data[i] - (((data[i-1]-data[i-2])<<1) + (data[i-1]-data[i-2])) - data[i-3];
- #else
- residual[i] = data[i] - 3*data[i-1] + 3*data[i-2] - data[i-3];
- #endif
- break;
- case 4:
- for(i = 0; i < idata_len; i++)
- #if 1 /* OPT: may be faster with some compilers on some systems */
- residual[i] = data[i] - ((data[i-1]+data[i-3])<<2) + ((data[i-2]<<2) + (data[i-2]<<1)) + data[i-4];
- #else
- residual[i] = data[i] - 4*data[i-1] + 6*data[i-2] - 4*data[i-3] + data[i-4];
- #endif
- break;
- default:
- FLAC__ASSERT(0);
- }
- }
-
- void FLAC__fixed_restore_signal(const FLAC__int32 residual[], unsigned data_len, unsigned order, FLAC__int32 data[])
- {
- int i, idata_len = (int)data_len;
-
- switch(order) {
- case 0:
- FLAC__ASSERT(sizeof(residual[0]) == sizeof(data[0]));
- memcpy(data, residual, sizeof(residual[0])*data_len);
- break;
- case 1:
- for(i = 0; i < idata_len; i++)
- data[i] = residual[i] + data[i-1];
- break;
- case 2:
- for(i = 0; i < idata_len; i++)
- #if 1 /* OPT: may be faster with some compilers on some systems */
- data[i] = residual[i] + (data[i-1]<<1) - data[i-2];
- #else
- data[i] = residual[i] + 2*data[i-1] - data[i-2];
- #endif
- break;
- case 3:
- for(i = 0; i < idata_len; i++)
- #if 1 /* OPT: may be faster with some compilers on some systems */
- data[i] = residual[i] + (((data[i-1]-data[i-2])<<1) + (data[i-1]-data[i-2])) + data[i-3];
- #else
- data[i] = residual[i] + 3*data[i-1] - 3*data[i-2] + data[i-3];
- #endif
- break;
- case 4:
- for(i = 0; i < idata_len; i++)
- #if 1 /* OPT: may be faster with some compilers on some systems */
- data[i] = residual[i] + ((data[i-1]+data[i-3])<<2) - ((data[i-2]<<2) + (data[i-2]<<1)) - data[i-4];
- #else
- data[i] = residual[i] + 4*data[i-1] - 6*data[i-2] + 4*data[i-3] - data[i-4];
- #endif
- break;
- default:
- FLAC__ASSERT(0);
- }
- }
-
- #endif
- /********* End of inlined file: fixed.c *********/
-
- /********* Start of inlined file: float.c *********/
-
- /********* Start of inlined file: juce_FlacHeader.h *********/
- // This file is included at the start of each FLAC .c file, just to do a few housekeeping
- // tasks..
-
- #define VERSION "1.2.1"
-
- #define FLAC__NO_DLL 1
-
- #ifdef _MSC_VER
- #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4312)
- #endif
-
- #if ! (defined (_WIN32) || defined (_WIN64) || defined (LINUX))
- #define FLAC__SYS_DARWIN 1
- #endif
- /********* End of inlined file: juce_FlacHeader.h *********/
-
- #if JUCE_USE_FLAC
-
- #if HAVE_CONFIG_H
- # include <config.h>
- #endif
-
- #ifdef FLAC__INTEGER_ONLY_LIBRARY
-
- /* adjust for compilers that can't understand using LLU suffix for uint64_t literals */
- #ifdef _MSC_VER
- #define FLAC__U64L(x) x
- #else
- #define FLAC__U64L(x) x##LLU
- #endif
-
- const FLAC__fixedpoint FLAC__FP_ZERO = 0;
- const FLAC__fixedpoint FLAC__FP_ONE_HALF = 0x00008000;
- const FLAC__fixedpoint FLAC__FP_ONE = 0x00010000;
- const FLAC__fixedpoint FLAC__FP_LN2 = 45426;
- const FLAC__fixedpoint FLAC__FP_E = 178145;
-
- /* Lookup tables for Knuth's logarithm algorithm */
- #define LOG2_LOOKUP_PRECISION 16
- static const FLAC__uint32 log2_lookup[][LOG2_LOOKUP_PRECISION] = {
- {
- /*
- * 0 fraction bits
- */
- /* undefined */ 0x00000000,
- /* lg(2/1) = */ 0x00000001,
- /* lg(4/3) = */ 0x00000000,
- /* lg(8/7) = */ 0x00000000,
- /* lg(16/15) = */ 0x00000000,
- /* lg(32/31) = */ 0x00000000,
- /* lg(64/63) = */ 0x00000000,
- /* lg(128/127) = */ 0x00000000,
- /* lg(256/255) = */ 0x00000000,
- /* lg(512/511) = */ 0x00000000,
- /* lg(1024/1023) = */ 0x00000000,
- /* lg(2048/2047) = */ 0x00000000,
- /* lg(4096/4095) = */ 0x00000000,
- /* lg(8192/8191) = */ 0x00000000,
- /* lg(16384/16383) = */ 0x00000000,
- /* lg(32768/32767) = */ 0x00000000
- },
- {
- /*
- * 4 fraction bits
- */
- /* undefined */ 0x00000000,
- /* lg(2/1) = */ 0x00000010,
- /* lg(4/3) = */ 0x00000007,
- /* lg(8/7) = */ 0x00000003,
- /* lg(16/15) = */ 0x00000001,
- /* lg(32/31) = */ 0x00000001,
- /* lg(64/63) = */ 0x00000000,
- /* lg(128/127) = */ 0x00000000,
- /* lg(256/255) = */ 0x00000000,
- /* lg(512/511) = */ 0x00000000,
- /* lg(1024/1023) = */ 0x00000000,
- /* lg(2048/2047) = */ 0x00000000,
- /* lg(4096/4095) = */ 0x00000000,
- /* lg(8192/8191) = */ 0x00000000,
- /* lg(16384/16383) = */ 0x00000000,
- /* lg(32768/32767) = */ 0x00000000
- },
- {
- /*
- * 8 fraction bits
- */
- /* undefined */ 0x00000000,
- /* lg(2/1) = */ 0x00000100,
- /* lg(4/3) = */ 0x0000006a,
- /* lg(8/7) = */ 0x00000031,
- /* lg(16/15) = */ 0x00000018,
- /* lg(32/31) = */ 0x0000000c,
- /* lg(64/63) = */ 0x00000006,
- /* lg(128/127) = */ 0x00000003,
- /* lg(256/255) = */ 0x00000001,
- /* lg(512/511) = */ 0x00000001,
- /* lg(1024/1023) = */ 0x00000000,
- /* lg(2048/2047) = */ 0x00000000,
- /* lg(4096/4095) = */ 0x00000000,
- /* lg(8192/8191) = */ 0x00000000,
- /* lg(16384/16383) = */ 0x00000000,
- /* lg(32768/32767) = */ 0x00000000
- },
- {
- /*
- * 12 fraction bits
- */
- /* undefined */ 0x00000000,
- /* lg(2/1) = */ 0x00001000,
- /* lg(4/3) = */ 0x000006a4,
- /* lg(8/7) = */ 0x00000315,
- /* lg(16/15) = */ 0x0000017d,
- /* lg(32/31) = */ 0x000000bc,
- /* lg(64/63) = */ 0x0000005d,
- /* lg(128/127) = */ 0x0000002e,
- /* lg(256/255) = */ 0x00000017,
- /* lg(512/511) = */ 0x0000000c,
- /* lg(1024/1023) = */ 0x00000006,
- /* lg(2048/2047) = */ 0x00000003,
- /* lg(4096/4095) = */ 0x00000001,
- /* lg(8192/8191) = */ 0x00000001,
- /* lg(16384/16383) = */ 0x00000000,
- /* lg(32768/32767) = */ 0x00000000
- },
- {
- /*
- * 16 fraction bits
- */
- /* undefined */ 0x00000000,
- /* lg(2/1) = */ 0x00010000,
- /* lg(4/3) = */ 0x00006a40,
- /* lg(8/7) = */ 0x00003151,
- /* lg(16/15) = */ 0x000017d6,
- /* lg(32/31) = */ 0x00000bba,
- /* lg(64/63) = */ 0x000005d1,
- /* lg(128/127) = */ 0x000002e6,
- /* lg(256/255) = */ 0x00000172,
- /* lg(512/511) = */ 0x000000b9,
- /* lg(1024/1023) = */ 0x0000005c,
- /* lg(2048/2047) = */ 0x0000002e,
- /* lg(4096/4095) = */ 0x00000017,
- /* lg(8192/8191) = */ 0x0000000c,
- /* lg(16384/16383) = */ 0x00000006,
- /* lg(32768/32767) = */ 0x00000003
- },
- {
- /*
- * 20 fraction bits
- */
- /* undefined */ 0x00000000,
- /* lg(2/1) = */ 0x00100000,
- /* lg(4/3) = */ 0x0006a3fe,
- /* lg(8/7) = */ 0x00031513,
- /* lg(16/15) = */ 0x00017d60,
- /* lg(32/31) = */ 0x0000bb9d,
- /* lg(64/63) = */ 0x00005d10,
- /* lg(128/127) = */ 0x00002e59,
- /* lg(256/255) = */ 0x00001721,
- /* lg(512/511) = */ 0x00000b8e,
- /* lg(1024/1023) = */ 0x000005c6,
- /* lg(2048/2047) = */ 0x000002e3,
- /* lg(4096/4095) = */ 0x00000171,
- /* lg(8192/8191) = */ 0x000000b9,
- /* lg(16384/16383) = */ 0x0000005c,
- /* lg(32768/32767) = */ 0x0000002e
- },
- {
- /*
- * 24 fraction bits
- */
- /* undefined */ 0x00000000,
- /* lg(2/1) = */ 0x01000000,
- /* lg(4/3) = */ 0x006a3fe6,
- /* lg(8/7) = */ 0x00315130,
- /* lg(16/15) = */ 0x0017d605,
- /* lg(32/31) = */ 0x000bb9ca,
- /* lg(64/63) = */ 0x0005d0fc,
- /* lg(128/127) = */ 0x0002e58f,
- /* lg(256/255) = */ 0x0001720e,
- /* lg(512/511) = */ 0x0000b8d8,
- /* lg(1024/1023) = */ 0x00005c61,
- /* lg(2048/2047) = */ 0x00002e2d,
- /* lg(4096/4095) = */ 0x00001716,
- /* lg(8192/8191) = */ 0x00000b8b,
- /* lg(16384/16383) = */ 0x000005c5,
- /* lg(32768/32767) = */ 0x000002e3
- },
- {
- /*
- * 28 fraction bits
- */
- /* undefined */ 0x00000000,
- /* lg(2/1) = */ 0x10000000,
- /* lg(4/3) = */ 0x06a3fe5c,
- /* lg(8/7) = */ 0x03151301,
- /* lg(16/15) = */ 0x017d6049,
- /* lg(32/31) = */ 0x00bb9ca6,
- /* lg(64/63) = */ 0x005d0fba,
- /* lg(128/127) = */ 0x002e58f7,
- /* lg(256/255) = */ 0x001720da,
- /* lg(512/511) = */ 0x000b8d87,
- /* lg(1024/1023) = */ 0x0005c60b,
- /* lg(2048/2047) = */ 0x0002e2d7,
- /* lg(4096/4095) = */ 0x00017160,
- /* lg(8192/8191) = */ 0x0000b8ad,
- /* lg(16384/16383) = */ 0x00005c56,
- /* lg(32768/32767) = */ 0x00002e2b
- }
- };
-
- #if 0
- static const FLAC__uint64 log2_lookup_wide[] = {
- {
- /*
- * 32 fraction bits
- */
- /* undefined */ 0x00000000,
- /* lg(2/1) = */ FLAC__U64L(0x100000000),
- /* lg(4/3) = */ FLAC__U64L(0x6a3fe5c6),
- /* lg(8/7) = */ FLAC__U64L(0x31513015),
- /* lg(16/15) = */ FLAC__U64L(0x17d60497),
- /* lg(32/31) = */ FLAC__U64L(0x0bb9ca65),
- /* lg(64/63) = */ FLAC__U64L(0x05d0fba2),
- /* lg(128/127) = */ FLAC__U64L(0x02e58f74),
- /* lg(256/255) = */ FLAC__U64L(0x01720d9c),
- /* lg(512/511) = */ FLAC__U64L(0x00b8d875),
- /* lg(1024/1023) = */ FLAC__U64L(0x005c60aa),
- /* lg(2048/2047) = */ FLAC__U64L(0x002e2d72),
- /* lg(4096/4095) = */ FLAC__U64L(0x00171600),
- /* lg(8192/8191) = */ FLAC__U64L(0x000b8ad2),
- /* lg(16384/16383) = */ FLAC__U64L(0x0005c55d),
- /* lg(32768/32767) = */ FLAC__U64L(0x0002e2ac)
- },
- {
- /*
- * 48 fraction bits
- */
- /* undefined */ 0x00000000,
- /* lg(2/1) = */ FLAC__U64L(0x1000000000000),
- /* lg(4/3) = */ FLAC__U64L(0x6a3fe5c60429),
- /* lg(8/7) = */ FLAC__U64L(0x315130157f7a),
- /* lg(16/15) = */ FLAC__U64L(0x17d60496cfbb),
- /* lg(32/31) = */ FLAC__U64L(0xbb9ca64ecac),
- /* lg(64/63) = */ FLAC__U64L(0x5d0fba187cd),
- /* lg(128/127) = */ FLAC__U64L(0x2e58f7441ee),
- /* lg(256/255) = */ FLAC__U64L(0x1720d9c06a8),
- /* lg(512/511) = */ FLAC__U64L(0xb8d8752173),
- /* lg(1024/1023) = */ FLAC__U64L(0x5c60aa252e),
- /* lg(2048/2047) = */ FLAC__U64L(0x2e2d71b0d8),
- /* lg(4096/4095) = */ FLAC__U64L(0x1716001719),
- /* lg(8192/8191) = */ FLAC__U64L(0xb8ad1de1b),
- /* lg(16384/16383) = */ FLAC__U64L(0x5c55d640d),
- /* lg(32768/32767) = */ FLAC__U64L(0x2e2abcf52)
- }
- };
- #endif
-
- FLAC__uint32 FLAC__fixedpoint_log2(FLAC__uint32 x, unsigned fracbits, unsigned precision)
- {
- const FLAC__uint32 ONE = (1u << fracbits);
- const FLAC__uint32 *table = log2_lookup[fracbits >> 2];
-
- FLAC__ASSERT(fracbits < 32);
- FLAC__ASSERT((fracbits & 0x3) == 0);
-
- if(x < ONE)
- return 0;
-
- if(precision > LOG2_LOOKUP_PRECISION)
- precision = LOG2_LOOKUP_PRECISION;
-
- /* Knuth's algorithm for computing logarithms, optimized for base-2 with lookup tables */
- {
- FLAC__uint32 y = 0;
- FLAC__uint32 z = x >> 1, k = 1;
- while (x > ONE && k < precision) {
- if (x - z >= ONE) {
- x -= z;
- z = x >> k;
- y += table[k];
- }
- else {
- z >>= 1;
- k++;
- }
- }
- return y;
- }
- }
-
- #endif /* defined FLAC__INTEGER_ONLY_LIBRARY */
-
- #endif
- /********* End of inlined file: float.c *********/
-
- /********* Start of inlined file: format.c *********/
-
- /********* Start of inlined file: juce_FlacHeader.h *********/
- // This file is included at the start of each FLAC .c file, just to do a few housekeeping
- // tasks..
-
- #define VERSION "1.2.1"
-
- #define FLAC__NO_DLL 1
-
- #ifdef _MSC_VER
- #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4312)
- #endif
-
- #if ! (defined (_WIN32) || defined (_WIN64) || defined (LINUX))
- #define FLAC__SYS_DARWIN 1
- #endif
- /********* End of inlined file: juce_FlacHeader.h *********/
-
- #if JUCE_USE_FLAC
-
- #if HAVE_CONFIG_H
- # include <config.h>
- #endif
-
- #include <stdio.h>
- #include <stdlib.h> /* for qsort() */
- #include <string.h> /* for memset() */
-
- #ifndef FLaC__INLINE
- #define FLaC__INLINE
- #endif
-
- #ifdef min
- #undef min
- #endif
- #define min(a,b) ((a)<(b)?(a):(b))
-
- /* adjust for compilers that can't understand using LLU suffix for uint64_t literals */
- #ifdef _MSC_VER
- #define FLAC__U64L(x) x
- #else
- #define FLAC__U64L(x) x##LLU
- #endif
-
- /* VERSION should come from configure */
- FLAC_API const char *FLAC__VERSION_STRING = VERSION
-
- ;
-
- #if defined _MSC_VER || defined __BORLANDC__ || defined __MINW32__
- /* yet one more hack because of MSVC6: */
- FLAC_API const char *FLAC__VENDOR_STRING = "reference libFLAC 1.2.1 20070917";
- #else
- FLAC_API const char *FLAC__VENDOR_STRING = "reference libFLAC " VERSION " 20070917";
- #endif
-
- FLAC_API const FLAC__byte FLAC__STREAM_SYNC_STRING[4] = { 'f','L','a','C' };
- FLAC_API const unsigned FLAC__STREAM_SYNC = 0x664C6143;
- FLAC_API const unsigned FLAC__STREAM_SYNC_LEN = 32; /* bits */
-
- FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN = 16; /* bits */
- FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN = 16; /* bits */
- FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN = 24; /* bits */
- FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN = 24; /* bits */
- FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN = 20; /* bits */
- FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN = 3; /* bits */
- FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN = 5; /* bits */
- FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN = 36; /* bits */
- FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MD5SUM_LEN = 128; /* bits */
-
- FLAC_API const unsigned FLAC__STREAM_METADATA_APPLICATION_ID_LEN = 32; /* bits */
-
- FLAC_API const unsigned FLAC__STREAM_METADATA_SEEKPOINT_SAMPLE_NUMBER_LEN = 64; /* bits */
- FLAC_API const unsigned FLAC__STREAM_METADATA_SEEKPOINT_STREAM_OFFSET_LEN = 64; /* bits */
- FLAC_API const unsigned FLAC__STREAM_METADATA_SEEKPOINT_FRAME_SAMPLES_LEN = 16; /* bits */
-
- FLAC_API const FLAC__uint64 FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER = FLAC__U64L(0xffffffffffffffff);
-
- FLAC_API const unsigned FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN = 32; /* bits */
- FLAC_API const unsigned FLAC__STREAM_METADATA_VORBIS_COMMENT_NUM_COMMENTS_LEN = 32; /* bits */
-
- FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_INDEX_OFFSET_LEN = 64; /* bits */
- FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_INDEX_NUMBER_LEN = 8; /* bits */
- FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN = 3*8; /* bits */
-
- FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_OFFSET_LEN = 64; /* bits */
- FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_NUMBER_LEN = 8; /* bits */
- FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN = 12*8; /* bits */
- FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_TYPE_LEN = 1; /* bit */
- FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_PRE_EMPHASIS_LEN = 1; /* bit */
- FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_RESERVED_LEN = 6+13*8; /* bits */
- FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_NUM_INDICES_LEN = 8; /* bits */
-
- FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_MEDIA_CATALOG_NUMBER_LEN = 128*8; /* bits */
- FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_LEAD_IN_LEN = 64; /* bits */
- FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_IS_CD_LEN = 1; /* bit */
- FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_RESERVED_LEN = 7+258*8; /* bits */
- FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_NUM_TRACKS_LEN = 8; /* bits */
-
- FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_TYPE_LEN = 32; /* bits */
- FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_MIME_TYPE_LENGTH_LEN = 32; /* bits */
- FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_DESCRIPTION_LENGTH_LEN = 32; /* bits */
- FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_WIDTH_LEN = 32; /* bits */
- FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_HEIGHT_LEN = 32; /* bits */
- FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_DEPTH_LEN = 32; /* bits */
- FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_COLORS_LEN = 32; /* bits */
- FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_DATA_LENGTH_LEN = 32; /* bits */
-
- FLAC_API const unsigned FLAC__STREAM_METADATA_IS_LAST_LEN = 1; /* bits */
- FLAC_API const unsigned FLAC__STREAM_METADATA_TYPE_LEN = 7; /* bits */
- FLAC_API const unsigned FLAC__STREAM_METADATA_LENGTH_LEN = 24; /* bits */
-
- FLAC_API const unsigned FLAC__FRAME_HEADER_SYNC = 0x3ffe;
- FLAC_API const unsigned FLAC__FRAME_HEADER_SYNC_LEN = 14; /* bits */
- FLAC_API const unsigned FLAC__FRAME_HEADER_RESERVED_LEN = 1; /* bits */
- FLAC_API const unsigned FLAC__FRAME_HEADER_BLOCKING_STRATEGY_LEN = 1; /* bits */
- FLAC_API const unsigned FLAC__FRAME_HEADER_BLOCK_SIZE_LEN = 4; /* bits */
- FLAC_API const unsigned FLAC__FRAME_HEADER_SAMPLE_RATE_LEN = 4; /* bits */
- FLAC_API const unsigned FLAC__FRAME_HEADER_CHANNEL_ASSIGNMENT_LEN = 4; /* bits */
- FLAC_API const unsigned FLAC__FRAME_HEADER_BITS_PER_SAMPLE_LEN = 3; /* bits */
- FLAC_API const unsigned FLAC__FRAME_HEADER_ZERO_PAD_LEN = 1; /* bits */
- FLAC_API const unsigned FLAC__FRAME_HEADER_CRC_LEN = 8; /* bits */
-
- FLAC_API const unsigned FLAC__FRAME_FOOTER_CRC_LEN = 16; /* bits */
-
- FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_TYPE_LEN = 2; /* bits */
- FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN = 4; /* bits */
- FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN = 4; /* bits */
- FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN = 5; /* bits */
- FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN = 5; /* bits */
-
- FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER = 15; /* == (1<<FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN)-1 */
- FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_ESCAPE_PARAMETER = 31; /* == (1<<FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN)-1 */
-
- FLAC_API const char * const FLAC__EntropyCodingMethodTypeString[] = {
- "PARTITIONED_RICE",
- "PARTITIONED_RICE2"
- };
-
- FLAC_API const unsigned FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN = 4; /* bits */
- FLAC_API const unsigned FLAC__SUBFRAME_LPC_QLP_SHIFT_LEN = 5; /* bits */
-
- FLAC_API const unsigned FLAC__SUBFRAME_ZERO_PAD_LEN = 1; /* bits */
- FLAC_API const unsigned FLAC__SUBFRAME_TYPE_LEN = 6; /* bits */
- FLAC_API const unsigned FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN = 1; /* bits */
-
- FLAC_API const unsigned FLAC__SUBFRAME_TYPE_CONSTANT_BYTE_ALIGNED_MASK = 0x00;
- FLAC_API const unsigned FLAC__SUBFRAME_TYPE_VERBATIM_BYTE_ALIGNED_MASK = 0x02;
- FLAC_API const unsigned FLAC__SUBFRAME_TYPE_FIXED_BYTE_ALIGNED_MASK = 0x10;
- FLAC_API const unsigned FLAC__SUBFRAME_TYPE_LPC_BYTE_ALIGNED_MASK = 0x40;
-
- FLAC_API const char * const FLAC__SubframeTypeString[] = {
- "CONSTANT",
- "VERBATIM",
- "FIXED",
- "LPC"
- };
-
- FLAC_API const char * const FLAC__ChannelAssignmentString[] = {
- "INDEPENDENT",
- "LEFT_SIDE",
- "RIGHT_SIDE",
- "MID_SIDE"
- };
-
- FLAC_API const char * const FLAC__FrameNumberTypeString[] = {
- "FRAME_NUMBER_TYPE_FRAME_NUMBER",
- "FRAME_NUMBER_TYPE_SAMPLE_NUMBER"
- };
-
- FLAC_API const char * const FLAC__MetadataTypeString[] = {
- "STREAMINFO",
- "PADDING",
- "APPLICATION",
- "SEEKTABLE",
- "VORBIS_COMMENT",
- "CUESHEET",
- "PICTURE"
- };
-
- FLAC_API const char * const FLAC__StreamMetadata_Picture_TypeString[] = {
- "Other",
- "32x32 pixels 'file icon' (PNG only)",
- "Other file icon",
- "Cover (front)",
- "Cover (back)",
- "Leaflet page",
- "Media (e.g. label side of CD)",
- "Lead artist/lead performer/soloist",
- "Artist/performer",
- "Conductor",
- "Band/Orchestra",
- "Composer",
- "Lyricist/text writer",
- "Recording Location",
- "During recording",
- "During performance",
- "Movie/video screen capture",
- "A bright coloured fish",
- "Illustration",
- "Band/artist logotype",
- "Publisher/Studio logotype"
- };
-
- FLAC_API FLAC__bool FLAC__format_sample_rate_is_valid(unsigned sample_rate)
- {
- if(sample_rate == 0 || sample_rate > FLAC__MAX_SAMPLE_RATE) {
- return false;
- }
- else
- return true;
- }
-
- FLAC_API FLAC__bool FLAC__format_sample_rate_is_subset(unsigned sample_rate)
- {
- if(
- !FLAC__format_sample_rate_is_valid(sample_rate) ||
- (
- sample_rate >= (1u << 16) &&
- !(sample_rate % 1000 == 0 || sample_rate % 10 == 0)
- )
- ) {
- return false;
- }
- else
- return true;
- }
-
- /* @@@@ add to unit tests; it is already indirectly tested by the metadata_object tests */
- FLAC_API FLAC__bool FLAC__format_seektable_is_legal(const FLAC__StreamMetadata_SeekTable *seek_table)
- {
- unsigned i;
- FLAC__uint64 prev_sample_number = 0;
- FLAC__bool got_prev = false;
-
- FLAC__ASSERT(0 != seek_table);
-
- for(i = 0; i < seek_table->num_points; i++) {
- if(got_prev) {
- if(
- seek_table->points[i].sample_number != FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER &&
- seek_table->points[i].sample_number <= prev_sample_number
- )
- return false;
- }
- prev_sample_number = seek_table->points[i].sample_number;
- got_prev = true;
- }
-
- return true;
- }
-
- /* used as the sort predicate for qsort() */
- static int seekpoint_compare_(const FLAC__StreamMetadata_SeekPoint *l, const FLAC__StreamMetadata_SeekPoint *r)
- {
- /* we don't just 'return l->sample_number - r->sample_number' since the result (FLAC__int64) might overflow an 'int' */
- if(l->sample_number == r->sample_number)
- return 0;
- else if(l->sample_number < r->sample_number)
- return -1;
- else
- return 1;
- }
-
- /* @@@@ add to unit tests; it is already indirectly tested by the metadata_object tests */
- FLAC_API unsigned FLAC__format_seektable_sort(FLAC__StreamMetadata_SeekTable *seek_table)
- {
- unsigned i, j;
- FLAC__bool first;
-
- FLAC__ASSERT(0 != seek_table);
-
- /* sort the seekpoints */
- qsort(seek_table->points, seek_table->num_points, sizeof(FLAC__StreamMetadata_SeekPoint), (int (*)(const void *, const void *))seekpoint_compare_);
-
- /* uniquify the seekpoints */
- first = true;
- for(i = j = 0; i < seek_table->num_points; i++) {
- if(seek_table->points[i].sample_number != FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER) {
- if(!first) {
- if(seek_table->points[i].sample_number == seek_table->points[j-1].sample_number)
- continue;
- }
- }
- first = false;
- seek_table->points[j++] = seek_table->points[i];
- }
-
- for(i = j; i < seek_table->num_points; i++) {
- seek_table->points[i].sample_number = FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER;
- seek_table->points[i].stream_offset = 0;
- seek_table->points[i].frame_samples = 0;
- }
-
- return j;
- }
-
- /*
- * also disallows non-shortest-form encodings, c.f.
- * http://www.unicode.org/versions/corrigendum1.html
- * and a more clear explanation at the end of this section:
- * http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
- */
- static FLaC__INLINE unsigned utf8len_(const FLAC__byte *utf8)
- {
- FLAC__ASSERT(0 != utf8);
- if ((utf8[0] & 0x80) == 0) {
- return 1;
- }
- else if ((utf8[0] & 0xE0) == 0xC0 && (utf8[1] & 0xC0) == 0x80) {
- if ((utf8[0] & 0xFE) == 0xC0) /* overlong sequence check */
- return 0;
- return 2;
- }
- else if ((utf8[0] & 0xF0) == 0xE0 && (utf8[1] & 0xC0) == 0x80 && (utf8[2] & 0xC0) == 0x80) {
- if (utf8[0] == 0xE0 && (utf8[1] & 0xE0) == 0x80) /* overlong sequence check */
- return 0;
- /* illegal surrogates check (U+D800...U+DFFF and U+FFFE...U+FFFF) */
- if (utf8[0] == 0xED && (utf8[1] & 0xE0) == 0xA0) /* D800-DFFF */
- return 0;
- if (utf8[0] == 0xEF && utf8[1] == 0xBF && (utf8[2] & 0xFE) == 0xBE) /* FFFE-FFFF */
- return 0;
- return 3;
- }
- else if ((utf8[0] & 0xF8) == 0xF0 && (utf8[1] & 0xC0) == 0x80 && (utf8[2] & 0xC0) == 0x80 && (utf8[3] & 0xC0) == 0x80) {
- if (utf8[0] == 0xF0 && (utf8[1] & 0xF0) == 0x80) /* overlong sequence check */
- return 0;
- return 4;
- }
- else if ((utf8[0] & 0xFC) == 0xF8 && (utf8[1] & 0xC0) == 0x80 && (utf8[2] & 0xC0) == 0x80 && (utf8[3] & 0xC0) == 0x80 && (utf8[4] & 0xC0) == 0x80) {
- if (utf8[0] == 0xF8 && (utf8[1] & 0xF8) == 0x80) /* overlong sequence check */
- return 0;
- return 5;
- }
- else if ((utf8[0] & 0xFE) == 0xFC && (utf8[1] & 0xC0) == 0x80 && (utf8[2] & 0xC0) == 0x80 && (utf8[3] & 0xC0) == 0x80 && (utf8[4] & 0xC0) == 0x80 && (utf8[5] & 0xC0) == 0x80) {
- if (utf8[0] == 0xFC && (utf8[1] & 0xFC) == 0x80) /* overlong sequence check */
- return 0;
- return 6;
- }
- else {
- return 0;
- }
- }
-
- FLAC_API FLAC__bool FLAC__format_vorbiscomment_entry_name_is_legal(const char *name)
- {
- char c;
- for(c = *name; c; c = *(++name))
- if(c < 0x20 || c == 0x3d || c > 0x7d)
- return false;
- return true;
- }
-
- FLAC_API FLAC__bool FLAC__format_vorbiscomment_entry_value_is_legal(const FLAC__byte *value, unsigned length)
- {
- if(length == (unsigned)(-1)) {
- while(*value) {
- unsigned n = utf8len_(value);
- if(n == 0)
- return false;
- value += n;
- }
- }
- else {
- const FLAC__byte *end = value + length;
- while(value < end) {
- unsigned n = utf8len_(value);
- if(n == 0)
- return false;
- value += n;
- }
- if(value != end)
- return false;
- }
- return true;
- }
-
- FLAC_API FLAC__bool FLAC__format_vorbiscomment_entry_is_legal(const FLAC__byte *entry, unsigned length)
- {
- const FLAC__byte *s, *end;
-
- for(s = entry, end = s + length; s < end && *s != '='; s++) {
- if(*s < 0x20 || *s > 0x7D)
- return false;
- }
- if(s == end)
- return false;
-
- s++; /* skip '=' */
-
- while(s < end) {
- unsigned n = utf8len_(s);
- if(n == 0)
- return false;
- s += n;
- }
- if(s != end)
- return false;
-
- return true;
- }
-
- /* @@@@ add to unit tests; it is already indirectly tested by the metadata_object tests */
- FLAC_API FLAC__bool FLAC__format_cuesheet_is_legal(const FLAC__StreamMetadata_CueSheet *cue_sheet, FLAC__bool check_cd_da_subset, const char **violation)
- {
- unsigned i, j;
-
- if(check_cd_da_subset) {
- if(cue_sheet->lead_in < 2 * 44100) {
- if(violation) *violation = "CD-DA cue sheet must have a lead-in length of at least 2 seconds";
- return false;
- }
- if(cue_sheet->lead_in % 588 != 0) {
- if(violation) *violation = "CD-DA cue sheet lead-in length must be evenly divisible by 588 samples";
- return false;
- }
- }
-
- if(cue_sheet->num_tracks == 0) {
- if(violation) *violation = "cue sheet must have at least one track (the lead-out)";
- return false;
- }
-
- if(check_cd_da_subset && cue_sheet->tracks[cue_sheet->num_tracks-1].number != 170) {
- if(violation) *violation = "CD-DA cue sheet must have a lead-out track number 170 (0xAA)";
- return false;
- }
-
- for(i = 0; i < cue_sheet->num_tracks; i++) {
- if(cue_sheet->tracks[i].number == 0) {
- if(violation) *violation = "cue sheet may not have a track number 0";
- return false;
- }
-
- if(check_cd_da_subset) {
- if(!((cue_sheet->tracks[i].number >= 1 && cue_sheet->tracks[i].number <= 99) || cue_sheet->tracks[i].number == 170)) {
- if(violation) *violation = "CD-DA cue sheet track number must be 1-99 or 170";
- return false;
- }
- }
-
- if(check_cd_da_subset && cue_sheet->tracks[i].offset % 588 != 0) {
- if(violation) {
- if(i == cue_sheet->num_tracks-1) /* the lead-out track... */
- *violation = "CD-DA cue sheet lead-out offset must be evenly divisible by 588 samples";
- else
- *violation = "CD-DA cue sheet track offset must be evenly divisible by 588 samples";
- }
- return false;
- }
-
- if(i < cue_sheet->num_tracks - 1) {
- if(cue_sheet->tracks[i].num_indices == 0) {
- if(violation) *violation = "cue sheet track must have at least one index point";
- return false;
- }
-
- if(cue_sheet->tracks[i].indices[0].number > 1) {
- if(violation) *violation = "cue sheet track's first index number must be 0 or 1";
- return false;
- }
- }
-
- for(j = 0; j < cue_sheet->tracks[i].num_indices; j++) {
- if(check_cd_da_subset && cue_sheet->tracks[i].indices[j].offset % 588 != 0) {
- if(violation) *violation = "CD-DA cue sheet track index offset must be evenly divisible by 588 samples";
- return false;
- }
-
- if(j > 0) {
- if(cue_sheet->tracks[i].indices[j].number != cue_sheet->tracks[i].indices[j-1].number + 1) {
- if(violation) *violation = "cue sheet track index numbers must increase by 1";
- return false;
- }
- }
- }
- }
-
- return true;
- }
-
- /* @@@@ add to unit tests; it is already indirectly tested by the metadata_object tests */
- FLAC_API FLAC__bool FLAC__format_picture_is_legal(const FLAC__StreamMetadata_Picture *picture, const char **violation)
- {
- char *p;
- FLAC__byte *b;
-
- for(p = picture->mime_type; *p; p++) {
- if(*p < 0x20 || *p > 0x7e) {
- if(violation) *violation = "MIME type string must contain only printable ASCII characters (0x20-0x7e)";
- return false;
- }
- }
-
- for(b = picture->description; *b; ) {
- unsigned n = utf8len_(b);
- if(n == 0) {
- if(violation) *violation = "description string must be valid UTF-8";
- return false;
- }
- b += n;
- }
-
- return true;
- }
-
- /*
- * These routines are private to libFLAC
- */
- unsigned FLAC__format_get_max_rice_partition_order(unsigned blocksize, unsigned predictor_order)
- {
- return
- FLAC__format_get_max_rice_partition_order_from_blocksize_limited_max_and_predictor_order(
- FLAC__format_get_max_rice_partition_order_from_blocksize(blocksize),
- blocksize,
- predictor_order
- );
- }
-
- unsigned FLAC__format_get_max_rice_partition_order_from_blocksize(unsigned blocksize)
- {
- unsigned max_rice_partition_order = 0;
- while(!(blocksize & 1)) {
- max_rice_partition_order++;
- blocksize >>= 1;
- }
- return min(FLAC__MAX_RICE_PARTITION_ORDER, max_rice_partition_order);
- }
-
- unsigned FLAC__format_get_max_rice_partition_order_from_blocksize_limited_max_and_predictor_order(unsigned limit, unsigned blocksize, unsigned predictor_order)
- {
- unsigned max_rice_partition_order = limit;
-
- while(max_rice_partition_order > 0 && (blocksize >> max_rice_partition_order) <= predictor_order)
- max_rice_partition_order--;
-
- FLAC__ASSERT(
- (max_rice_partition_order == 0 && blocksize >= predictor_order) ||
- (max_rice_partition_order > 0 && blocksize >> max_rice_partition_order > predictor_order)
- );
-
- return max_rice_partition_order;
- }
-
- void FLAC__format_entropy_coding_method_partitioned_rice_contents_init(FLAC__EntropyCodingMethod_PartitionedRiceContents *object)
- {
- FLAC__ASSERT(0 != object);
-
- object->parameters = 0;
- object->raw_bits = 0;
- object->capacity_by_order = 0;
- }
-
- void FLAC__format_entropy_coding_method_partitioned_rice_contents_clear(FLAC__EntropyCodingMethod_PartitionedRiceContents *object)
- {
- FLAC__ASSERT(0 != object);
-
- if(0 != object->parameters)
- free(object->parameters);
- if(0 != object->raw_bits)
- free(object->raw_bits);
- FLAC__format_entropy_coding_method_partitioned_rice_contents_init(object);
- }
-
- FLAC__bool FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(FLAC__EntropyCodingMethod_PartitionedRiceContents *object, unsigned max_partition_order)
- {
- FLAC__ASSERT(0 != object);
-
- FLAC__ASSERT(object->capacity_by_order > 0 || (0 == object->parameters && 0 == object->raw_bits));
-
- if(object->capacity_by_order < max_partition_order) {
- if(0 == (object->parameters = (unsigned*)realloc(object->parameters, sizeof(unsigned)*(1 << max_partition_order))))
- return false;
- if(0 == (object->raw_bits = (unsigned*)realloc(object->raw_bits, sizeof(unsigned)*(1 << max_partition_order))))
- return false;
- memset(object->raw_bits, 0, sizeof(unsigned)*(1 << max_partition_order));
- object->capacity_by_order = max_partition_order;
- }
-
- return true;
- }
-
- #endif
- /********* End of inlined file: format.c *********/
-
- /********* Start of inlined file: lpc_flac.c *********/
-
- /********* Start of inlined file: juce_FlacHeader.h *********/
- // This file is included at the start of each FLAC .c file, just to do a few housekeeping
- // tasks..
-
- #define VERSION "1.2.1"
-
- #define FLAC__NO_DLL 1
-
- #ifdef _MSC_VER
- #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4312)
- #endif
-
- #if ! (defined (_WIN32) || defined (_WIN64) || defined (LINUX))
- #define FLAC__SYS_DARWIN 1
- #endif
- /********* End of inlined file: juce_FlacHeader.h *********/
-
- #if JUCE_USE_FLAC
-
- #if HAVE_CONFIG_H
- # include <config.h>
- #endif
-
- #include <math.h>
-
- /********* Start of inlined file: lpc.h *********/
- #ifndef FLAC__PRIVATE__LPC_H
- #define FLAC__PRIVATE__LPC_H
-
- #ifdef HAVE_CONFIG_H
- #include <config.h>
- #endif
-
- #ifndef FLAC__INTEGER_ONLY_LIBRARY
-
- /*
- * FLAC__lpc_window_data()
- * --------------------------------------------------------------------
- * Applies the given window to the data.
- * OPT: asm implementation
- *
- * IN in[0,data_len-1]
- * IN window[0,data_len-1]
- * OUT out[0,lag-1]
- * IN data_len
- */
- void FLAC__lpc_window_data(const FLAC__int32 in[], const FLAC__real window[], FLAC__real out[], unsigned data_len);
-
- /*
- * FLAC__lpc_compute_autocorrelation()
- * --------------------------------------------------------------------
- * Compute the autocorrelation for lags between 0 and lag-1.
- * Assumes data[] outside of [0,data_len-1] == 0.
- * Asserts that lag > 0.
- *
- * IN data[0,data_len-1]
- * IN data_len
- * IN 0 < lag <= data_len
- * OUT autoc[0,lag-1]
- */
- void FLAC__lpc_compute_autocorrelation(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]);
- #ifndef FLAC__NO_ASM
- # ifdef FLAC__CPU_IA32
- # ifdef FLAC__HAS_NASM
- void FLAC__lpc_compute_autocorrelation_asm_ia32(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]);
- void FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_4(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]);
- void FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_8(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]);
- void FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_12(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]);
- void FLAC__lpc_compute_autocorrelation_asm_ia32_3dnow(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]);
- # endif
- # endif
- #endif
-
- /*
- * FLAC__lpc_compute_lp_coefficients()
- * --------------------------------------------------------------------
- * Computes LP coefficients for orders 1..max_order.
- * Do not call if autoc[0] == 0.0. This means the signal is zero
- * and there is no point in calculating a predictor.
- *
- * IN autoc[0,max_order] autocorrelation values
- * IN 0 < max_order <= FLAC__MAX_LPC_ORDER max LP order to compute
- * OUT lp_coeff[0,max_order-1][0,max_order-1] LP coefficients for each order
- * *** IMPORTANT:
- * *** lp_coeff[0,max_order-1][max_order,FLAC__MAX_LPC_ORDER-1] are untouched
- * OUT error[0,max_order-1] error for each order (more
- * specifically, the variance of
- * the error signal times # of
- * samples in the signal)
- *
- * Example: if max_order is 9, the LP coefficients for order 9 will be
- * in lp_coeff[8][0,8], the LP coefficients for order 8 will be
- * in lp_coeff[7][0,7], etc.
- */
- void FLAC__lpc_compute_lp_coefficients(const FLAC__real autoc[], unsigned *max_order, FLAC__real lp_coeff[][FLAC__MAX_LPC_ORDER], FLAC__double error[]);
-
- /*
- * FLAC__lpc_quantize_coefficients()
- * --------------------------------------------------------------------
- * Quantizes the LP coefficients. NOTE: precision + bits_per_sample
- * must be less than 32 (sizeof(FLAC__int32)*8).
- *
- * IN lp_coeff[0,order-1] LP coefficients
- * IN order LP order
- * IN FLAC__MIN_QLP_COEFF_PRECISION < precision
- * desired precision (in bits, including sign
- * bit) of largest coefficient
- * OUT qlp_coeff[0,order-1] quantized coefficients
- * OUT shift # of bits to shift right to get approximated
- * LP coefficients. NOTE: could be negative.
- * RETURN 0 => quantization OK
- * 1 => coefficients require too much shifting for *shift to
- * fit in the LPC subframe header. 'shift' is unset.
- * 2 => coefficients are all zero, which is bad. 'shift' is
- * unset.
- */
- int FLAC__lpc_quantize_coefficients(const FLAC__real lp_coeff[], unsigned order, unsigned precision, FLAC__int32 qlp_coeff[], int *shift);
-
- /*
- * FLAC__lpc_compute_residual_from_qlp_coefficients()
- * --------------------------------------------------------------------
- * Compute the residual signal obtained from sutracting the predicted
- * signal from the original.
- *
- * IN data[-order,data_len-1] original signal (NOTE THE INDICES!)
- * IN data_len length of original signal
- * IN qlp_coeff[0,order-1] quantized LP coefficients
- * IN order > 0 LP order
- * IN lp_quantization quantization of LP coefficients in bits
- * OUT residual[0,data_len-1] residual signal
- */
- void FLAC__lpc_compute_residual_from_qlp_coefficients(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]);
- void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]);
- #ifndef FLAC__NO_ASM
- # ifdef FLAC__CPU_IA32
- # ifdef FLAC__HAS_NASM
- void FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]);
- void FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32_mmx(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]);
- # endif
- # endif
- #endif
-
- #endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */
-
- /*
- * FLAC__lpc_restore_signal()
- * --------------------------------------------------------------------
- * Restore the original signal by summing the residual and the
- * predictor.
- *
- * IN residual[0,data_len-1] residual signal
- * IN data_len length of original signal
- * IN qlp_coeff[0,order-1] quantized LP coefficients
- * IN order > 0 LP order
- * IN lp_quantization quantization of LP coefficients in bits
- * *** IMPORTANT: the caller must pass in the historical samples:
- * IN data[-order,-1] previously-reconstructed historical samples
- * OUT data[0,data_len-1] original signal
- */
- void FLAC__lpc_restore_signal(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]);
- void FLAC__lpc_restore_signal_wide(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]);
- #ifndef FLAC__NO_ASM
- # ifdef FLAC__CPU_IA32
- # ifdef FLAC__HAS_NASM
- void FLAC__lpc_restore_signal_asm_ia32(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]);
- void FLAC__lpc_restore_signal_asm_ia32_mmx(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]);
- # endif /* FLAC__HAS_NASM */
- # elif defined FLAC__CPU_PPC
- void FLAC__lpc_restore_signal_asm_ppc_altivec_16(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]);
- void FLAC__lpc_restore_signal_asm_ppc_altivec_16_order8(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]);
- # endif/* FLAC__CPU_IA32 || FLAC__CPU_PPC */
- #endif /* FLAC__NO_ASM */
-
- #ifndef FLAC__INTEGER_ONLY_LIBRARY
-
- /*
- * FLAC__lpc_compute_expected_bits_per_residual_sample()
- * --------------------------------------------------------------------
- * Compute the expected number of bits per residual signal sample
- * based on the LP error (which is related to the residual variance).
- *
- * IN lpc_error >= 0.0 error returned from calculating LP coefficients
- * IN total_samples > 0 # of samples in residual signal
- * RETURN expected bits per sample
- */
- FLAC__double FLAC__lpc_compute_expected_bits_per_residual_sample(FLAC__double lpc_error, unsigned total_samples);
- FLAC__double FLAC__lpc_compute_expected_bits_per_residual_sample_with_error_scale(FLAC__double lpc_error, FLAC__double error_scale);
-
- /*
- * FLAC__lpc_compute_best_order()
- * --------------------------------------------------------------------
- * Compute the best order from the array of signal errors returned
- * during coefficient computation.
- *
- * IN lpc_error[0,max_order-1] >= 0.0 error returned from calculating LP coefficients
- * IN max_order > 0 max LP order
- * IN total_samples > 0 # of samples in residual signal
- * IN overhead_bits_per_order # of bits overhead for each increased LP order
- * (includes warmup sample size and quantized LP coefficient)
- * RETURN [1,max_order] best order
- */
- unsigned FLAC__lpc_compute_best_order(const FLAC__double lpc_error[], unsigned max_order, unsigned total_samples, unsigned overhead_bits_per_order);
-
- #endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */
-
- #endif
- /********* End of inlined file: lpc.h *********/
-
- #if defined DEBUG || defined FLAC__OVERFLOW_DETECT || defined FLAC__OVERFLOW_DETECT_VERBOSE
- #include <stdio.h>
- #endif
-
- #ifndef FLAC__INTEGER_ONLY_LIBRARY
-
- #ifndef M_LN2
- /* math.h in VC++ doesn't seem to have this (how Microsoft is that?) */
- #define M_LN2 0.69314718055994530942
- #endif
-
- /* OPT: #undef'ing this may improve the speed on some architectures */
- #define FLAC__LPC_UNROLLED_FILTER_LOOPS
-
- void FLAC__lpc_window_data(const FLAC__int32 in[], const FLAC__real window[], FLAC__real out[], unsigned data_len)
- {
- unsigned i;
- for(i = 0; i < data_len; i++)
- out[i] = in[i] * window[i];
- }
-
- void FLAC__lpc_compute_autocorrelation(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[])
- {
- /* a readable, but slower, version */
- #if 0
- FLAC__real d;
- unsigned i;
-
- FLAC__ASSERT(lag > 0);
- FLAC__ASSERT(lag <= data_len);
-
- /*
- * Technically we should subtract the mean first like so:
- * for(i = 0; i < data_len; i++)
- * data[i] -= mean;
- * but it appears not to make enough of a difference to matter, and
- * most signals are already closely centered around zero
- */
- while(lag--) {
- for(i = lag, d = 0.0; i < data_len; i++)
- d += data[i] * data[i - lag];
- autoc[lag] = d;
- }
- #endif
-
- /*
- * this version tends to run faster because of better data locality
- * ('data_len' is usually much larger than 'lag')
- */
- FLAC__real d;
- unsigned sample, coeff;
- const unsigned limit = data_len - lag;
-
- FLAC__ASSERT(lag > 0);
- FLAC__ASSERT(lag <= data_len);
-
- for(coeff = 0; coeff < lag; coeff++)
- autoc[coeff] = 0.0;
- for(sample = 0; sample <= limit; sample++) {
- d = data[sample];
- for(coeff = 0; coeff < lag; coeff++)
- autoc[coeff] += d * data[sample+coeff];
- }
- for(; sample < data_len; sample++) {
- d = data[sample];
- for(coeff = 0; coeff < data_len - sample; coeff++)
- autoc[coeff] += d * data[sample+coeff];
- }
- }
-
- void FLAC__lpc_compute_lp_coefficients(const FLAC__real autoc[], unsigned *max_order, FLAC__real lp_coeff[][FLAC__MAX_LPC_ORDER], FLAC__double error[])
- {
- unsigned i, j;
- FLAC__double r, err, ref[FLAC__MAX_LPC_ORDER], lpc[FLAC__MAX_LPC_ORDER];
-
- FLAC__ASSERT(0 != max_order);
- FLAC__ASSERT(0 < *max_order);
- FLAC__ASSERT(*max_order <= FLAC__MAX_LPC_ORDER);
- FLAC__ASSERT(autoc[0] != 0.0);
-
- err = autoc[0];
-
- for(i = 0; i < *max_order; i++) {
- /* Sum up this iteration's reflection coefficient. */
- r = -autoc[i+1];
- for(j = 0; j < i; j++)
- r -= lpc[j] * autoc[i-j];
- ref[i] = (r/=err);
-
- /* Update LPC coefficients and total error. */
- lpc[i]=r;
- for(j = 0; j < (i>>1); j++) {
- FLAC__double tmp = lpc[j];
- lpc[j] += r * lpc[i-1-j];
- lpc[i-1-j] += r * tmp;
- }
- if(i & 1)
- lpc[j] += lpc[j] * r;
-
- err *= (1.0 - r * r);
-
- /* save this order */
- for(j = 0; j <= i; j++)
- lp_coeff[i][j] = (FLAC__real)(-lpc[j]); /* negate FIR filter coeff to get predictor coeff */
- error[i] = err;
-
- /* see SF bug #1601812 http://sourceforge.net/tracker/index.php?func=detail&aid=1601812&group_id=13478&atid=113478 */
- if(err == 0.0) {
- *max_order = i+1;
- return;
- }
- }
- }
-
- int FLAC__lpc_quantize_coefficients(const FLAC__real lp_coeff[], unsigned order, unsigned precision, FLAC__int32 qlp_coeff[], int *shift)
- {
- unsigned i;
- FLAC__double cmax;
- FLAC__int32 qmax, qmin;
-
- FLAC__ASSERT(precision > 0);
- FLAC__ASSERT(precision >= FLAC__MIN_QLP_COEFF_PRECISION);
-
- /* drop one bit for the sign; from here on out we consider only |lp_coeff[i]| */
- precision--;
- qmax = 1 << precision;
- qmin = -qmax;
- qmax--;
-
- /* calc cmax = max( |lp_coeff[i]| ) */
- cmax = 0.0;
- for(i = 0; i < order; i++) {
- const FLAC__double d = fabs(lp_coeff[i]);
- if(d > cmax)
- cmax = d;
- }
-
- if(cmax <= 0.0) {
- /* => coefficients are all 0, which means our constant-detect didn't work */
- return 2;
- }
- else {
- const int max_shiftlimit = (1 << (FLAC__SUBFRAME_LPC_QLP_SHIFT_LEN-1)) - 1;
- const int min_shiftlimit = -max_shiftlimit - 1;
- int log2cmax;
-
- (void)frexp(cmax, &log2cmax);
- log2cmax--;
- *shift = (int)precision - log2cmax - 1;
-
- if(*shift > max_shiftlimit)
- *shift = max_shiftlimit;
- else if(*shift < min_shiftlimit)
- return 1;
- }
-
- if(*shift >= 0) {
- FLAC__double error = 0.0;
- FLAC__int32 q;
- for(i = 0; i < order; i++) {
- error += lp_coeff[i] * (1 << *shift);
- #if 1 /* unfortunately lround() is C99 */
- if(error >= 0.0)
- q = (FLAC__int32)(error + 0.5);
- else
- q = (FLAC__int32)(error - 0.5);
- #else
- q = lround(error);
- #endif
- #ifdef FLAC__OVERFLOW_DETECT
- if(q > qmax+1) /* we expect q==qmax+1 occasionally due to rounding */
- fprintf(stderr,"FLAC__lpc_quantize_coefficients: quantizer overflow: q>qmax %d>%d shift=%d cmax=%f precision=%u lpc[%u]=%f\n",q,qmax,*shift,cmax,precision+1,i,lp_coeff[i]);
- else if(q < qmin)
- fprintf(stderr,"FLAC__lpc_quantize_coefficients: quantizer overflow: q<qmin %d<%d shift=%d cmax=%f precision=%u lpc[%u]=%f\n",q,qmin,*shift,cmax,precision+1,i,lp_coeff[i]);
- #endif
- if(q > qmax)
- q = qmax;
- else if(q < qmin)
- q = qmin;
- error -= q;
- qlp_coeff[i] = q;
- }
- }
- /* negative shift is very rare but due to design flaw, negative shift is
- * a NOP in the decoder, so it must be handled specially by scaling down
- * coeffs
- */
- else {
- const int nshift = -(*shift);
- FLAC__double error = 0.0;
- FLAC__int32 q;
- #ifdef DEBUG
- fprintf(stderr,"FLAC__lpc_quantize_coefficients: negative shift=%d order=%u cmax=%f\n", *shift, order, cmax);
- #endif
- for(i = 0; i < order; i++) {
- error += lp_coeff[i] / (1 << nshift);
- #if 1 /* unfortunately lround() is C99 */
- if(error >= 0.0)
- q = (FLAC__int32)(error + 0.5);
- else
- q = (FLAC__int32)(error - 0.5);
- #else
- q = lround(error);
- #endif
- #ifdef FLAC__OVERFLOW_DETECT
- if(q > qmax+1) /* we expect q==qmax+1 occasionally due to rounding */
- fprintf(stderr,"FLAC__lpc_quantize_coefficients: quantizer overflow: q>qmax %d>%d shift=%d cmax=%f precision=%u lpc[%u]=%f\n",q,qmax,*shift,cmax,precision+1,i,lp_coeff[i]);
- else if(q < qmin)
- fprintf(stderr,"FLAC__lpc_quantize_coefficients: quantizer overflow: q<qmin %d<%d shift=%d cmax=%f precision=%u lpc[%u]=%f\n",q,qmin,*shift,cmax,precision+1,i,lp_coeff[i]);
- #endif
- if(q > qmax)
- q = qmax;
- else if(q < qmin)
- q = qmin;
- error -= q;
- qlp_coeff[i] = q;
- }
- *shift = 0;
- }
-
- return 0;
- }
-
- void FLAC__lpc_compute_residual_from_qlp_coefficients(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[])
- #if defined(FLAC__OVERFLOW_DETECT) || !defined(FLAC__LPC_UNROLLED_FILTER_LOOPS)
- {
- FLAC__int64 sumo;
- unsigned i, j;
- FLAC__int32 sum;
- const FLAC__int32 *history;
-
- #ifdef FLAC__OVERFLOW_DETECT_VERBOSE
- fprintf(stderr,"FLAC__lpc_compute_residual_from_qlp_coefficients: data_len=%d, order=%u, lpq=%d",data_len,order,lp_quantization);
- for(i=0;i<order;i++)
- fprintf(stderr,", q[%u]=%d",i,qlp_coeff[i]);
- fprintf(stderr,"\n");
- #endif
- FLAC__ASSERT(order > 0);
-
- for(i = 0; i < data_len; i++) {
- sumo = 0;
- sum = 0;
- history = data;
- for(j = 0; j < order; j++) {
- sum += qlp_coeff[j] * (*(--history));
- sumo += (FLAC__int64)qlp_coeff[j] * (FLAC__int64)(*history);
- #if defined _MSC_VER
- if(sumo > 2147483647I64 || sumo < -2147483648I64)
- fprintf(stderr,"FLAC__lpc_compute_residual_from_qlp_coefficients: OVERFLOW, i=%u, j=%u, c=%d, d=%d, sumo=%I64d\n",i,j,qlp_coeff[j],*history,sumo);
- #else
- if(sumo > 2147483647ll || sumo < -2147483648ll)
- fprintf(stderr,"FLAC__lpc_compute_residual_from_qlp_coefficients: OVERFLOW, i=%u, j=%u, c=%d, d=%d, sumo=%lld\n",i,j,qlp_coeff[j],*history,(long long)sumo);
- #endif
- }
- *(residual++) = *(data++) - (sum >> lp_quantization);
- }
-
- /* Here's a slower but clearer version:
- for(i = 0; i < data_len; i++) {
- sum = 0;
- for(j = 0; j < order; j++)
- sum += qlp_coeff[j] * data[i-j-1];
- residual[i] = data[i] - (sum >> lp_quantization);
- }
- */
- }
- #else /* fully unrolled version for normal use */
- {
- int i;
- FLAC__int32 sum;
-
- FLAC__ASSERT(order > 0);
- FLAC__ASSERT(order <= 32);
-
- /*
- * We do unique versions up to 12th order since that's the subset limit.
- * Also they are roughly ordered to match frequency of occurrence to
- * minimize branching.
- */
- if(order <= 12) {
- if(order > 8) {
- if(order > 10) {
- if(order == 12) {
- for(i = 0; i < (int)data_len; i++) {
- sum = 0;
- sum += qlp_coeff[11] * data[i-12];
- sum += qlp_coeff[10] * data[i-11];
- sum += qlp_coeff[9] * data[i-10];
- sum += qlp_coeff[8] * data[i-9];
- sum += qlp_coeff[7] * data[i-8];
- sum += qlp_coeff[6] * data[i-7];
- sum += qlp_coeff[5] * data[i-6];
- sum += qlp_coeff[4] * data[i-5];
- sum += qlp_coeff[3] * data[i-4];
- sum += qlp_coeff[2] * data[i-3];
- sum += qlp_coeff[1] * data[i-2];
- sum += qlp_coeff[0] * data[i-1];
- residual[i] = data[i] - (sum >> lp_quantization);
- }
- }
- else { /* order == 11 */
- for(i = 0; i < (int)data_len; i++) {
- sum = 0;
- sum += qlp_coeff[10] * data[i-11];
- sum += qlp_coeff[9] * data[i-10];
- sum += qlp_coeff[8] * data[i-9];
- sum += qlp_coeff[7] * data[i-8];
- sum += qlp_coeff[6] * data[i-7];
- sum += qlp_coeff[5] * data[i-6];
- sum += qlp_coeff[4] * data[i-5];
- sum += qlp_coeff[3] * data[i-4];
- sum += qlp_coeff[2] * data[i-3];
- sum += qlp_coeff[1] * data[i-2];
- sum += qlp_coeff[0] * data[i-1];
- residual[i] = data[i] - (sum >> lp_quantization);
- }
- }
- }
- else {
- if(order == 10) {
- for(i = 0; i < (int)data_len; i++) {
- sum = 0;
- sum += qlp_coeff[9] * data[i-10];
- sum += qlp_coeff[8] * data[i-9];
- sum += qlp_coeff[7] * data[i-8];
- sum += qlp_coeff[6] * data[i-7];
- sum += qlp_coeff[5] * data[i-6];
- sum += qlp_coeff[4] * data[i-5];
- sum += qlp_coeff[3] * data[i-4];
- sum += qlp_coeff[2] * data[i-3];
- sum += qlp_coeff[1] * data[i-2];
- sum += qlp_coeff[0] * data[i-1];
- residual[i] = data[i] - (sum >> lp_quantization);
- }
- }
- else { /* order == 9 */
- for(i = 0; i < (int)data_len; i++) {
- sum = 0;
- sum += qlp_coeff[8] * data[i-9];
- sum += qlp_coeff[7] * data[i-8];
- sum += qlp_coeff[6] * data[i-7];
- sum += qlp_coeff[5] * data[i-6];
- sum += qlp_coeff[4] * data[i-5];
- sum += qlp_coeff[3] * data[i-4];
- sum += qlp_coeff[2] * data[i-3];
- sum += qlp_coeff[1] * data[i-2];
- sum += qlp_coeff[0] * data[i-1];
- residual[i] = data[i] - (sum >> lp_quantization);
- }
- }
- }
- }
- else if(order > 4) {
- if(order > 6) {
- if(order == 8) {
- for(i = 0; i < (int)data_len; i++) {
- sum = 0;
- sum += qlp_coeff[7] * data[i-8];
- sum += qlp_coeff[6] * data[i-7];
- sum += qlp_coeff[5] * data[i-6];
- sum += qlp_coeff[4] * data[i-5];
- sum += qlp_coeff[3] * data[i-4];
- sum += qlp_coeff[2] * data[i-3];
- sum += qlp_coeff[1] * data[i-2];
- sum += qlp_coeff[0] * data[i-1];
- residual[i] = data[i] - (sum >> lp_quantization);
- }
- }
- else { /* order == 7 */
- for(i = 0; i < (int)data_len; i++) {
- sum = 0;
- sum += qlp_coeff[6] * data[i-7];
- sum += qlp_coeff[5] * data[i-6];
- sum += qlp_coeff[4] * data[i-5];
- sum += qlp_coeff[3] * data[i-4];
- sum += qlp_coeff[2] * data[i-3];
- sum += qlp_coeff[1] * data[i-2];
- sum += qlp_coeff[0] * data[i-1];
- residual[i] = data[i] - (sum >> lp_quantization);
- }
- }
- }
- else {
- if(order == 6) {
- for(i = 0; i < (int)data_len; i++) {
- sum = 0;
- sum += qlp_coeff[5] * data[i-6];
- sum += qlp_coeff[4] * data[i-5];
- sum += qlp_coeff[3] * data[i-4];
- sum += qlp_coeff[2] * data[i-3];
- sum += qlp_coeff[1] * data[i-2];
- sum += qlp_coeff[0] * data[i-1];
- residual[i] = data[i] - (sum >> lp_quantization);
- }
- }
- else { /* order == 5 */
- for(i = 0; i < (int)data_len; i++) {
- sum = 0;
- sum += qlp_coeff[4] * data[i-5];
- sum += qlp_coeff[3] * data[i-4];
- sum += qlp_coeff[2] * data[i-3];
- sum += qlp_coeff[1] * data[i-2];
- sum += qlp_coeff[0] * data[i-1];
- residual[i] = data[i] - (sum >> lp_quantization);
- }
- }
- }
- }
- else {
- if(order > 2) {
- if(order == 4) {
- for(i = 0; i < (int)data_len; i++) {
- sum = 0;
- sum += qlp_coeff[3] * data[i-4];
- sum += qlp_coeff[2] * data[i-3];
- sum += qlp_coeff[1] * data[i-2];
- sum += qlp_coeff[0] * data[i-1];
- residual[i] = data[i] - (sum >> lp_quantization);
- }
- }
- else { /* order == 3 */
- for(i = 0; i < (int)data_len; i++) {
- sum = 0;
- sum += qlp_coeff[2] * data[i-3];
- sum += qlp_coeff[1] * data[i-2];
- sum += qlp_coeff[0] * data[i-1];
- residual[i] = data[i] - (sum >> lp_quantization);
- }
- }
- }
- else {
- if(order == 2) {
- for(i = 0; i < (int)data_len; i++) {
- sum = 0;
- sum += qlp_coeff[1] * data[i-2];
- sum += qlp_coeff[0] * data[i-1];
- residual[i] = data[i] - (sum >> lp_quantization);
- }
- }
- else { /* order == 1 */
- for(i = 0; i < (int)data_len; i++)
- residual[i] = data[i] - ((qlp_coeff[0] * data[i-1]) >> lp_quantization);
- }
- }
- }
- }
- else { /* order > 12 */
- for(i = 0; i < (int)data_len; i++) {
- sum = 0;
- switch(order) {
- case 32: sum += qlp_coeff[31] * data[i-32];
- case 31: sum += qlp_coeff[30] * data[i-31];
- case 30: sum += qlp_coeff[29] * data[i-30];
- case 29: sum += qlp_coeff[28] * data[i-29];
- case 28: sum += qlp_coeff[27] * data[i-28];
- case 27: sum += qlp_coeff[26] * data[i-27];
- case 26: sum += qlp_coeff[25] * data[i-26];
- case 25: sum += qlp_coeff[24] * data[i-25];
- case 24: sum += qlp_coeff[23] * data[i-24];
- case 23: sum += qlp_coeff[22] * data[i-23];
- case 22: sum += qlp_coeff[21] * data[i-22];
- case 21: sum += qlp_coeff[20] * data[i-21];
- case 20: sum += qlp_coeff[19] * data[i-20];
- case 19: sum += qlp_coeff[18] * data[i-19];
- case 18: sum += qlp_coeff[17] * data[i-18];
- case 17: sum += qlp_coeff[16] * data[i-17];
- case 16: sum += qlp_coeff[15] * data[i-16];
- case 15: sum += qlp_coeff[14] * data[i-15];
- case 14: sum += qlp_coeff[13] * data[i-14];
- case 13: sum += qlp_coeff[12] * data[i-13];
- sum += qlp_coeff[11] * data[i-12];
- sum += qlp_coeff[10] * data[i-11];
- sum += qlp_coeff[ 9] * data[i-10];
- sum += qlp_coeff[ 8] * data[i- 9];
- sum += qlp_coeff[ 7] * data[i- 8];
- sum += qlp_coeff[ 6] * data[i- 7];
- sum += qlp_coeff[ 5] * data[i- 6];
- sum += qlp_coeff[ 4] * data[i- 5];
- sum += qlp_coeff[ 3] * data[i- 4];
- sum += qlp_coeff[ 2] * data[i- 3];
- sum += qlp_coeff[ 1] * data[i- 2];
- sum += qlp_coeff[ 0] * data[i- 1];
- }
- residual[i] = data[i] - (sum >> lp_quantization);
- }
- }
- }
- #endif
-
- void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[])
- #if defined(FLAC__OVERFLOW_DETECT) || !defined(FLAC__LPC_UNROLLED_FILTER_LOOPS)
- {
- unsigned i, j;
- FLAC__int64 sum;
- const FLAC__int32 *history;
-
- #ifdef FLAC__OVERFLOW_DETECT_VERBOSE
- fprintf(stderr,"FLAC__lpc_compute_residual_from_qlp_coefficients_wide: data_len=%d, order=%u, lpq=%d",data_len,order,lp_quantization);
- for(i=0;i<order;i++)
- fprintf(stderr,", q[%u]=%d",i,qlp_coeff[i]);
- fprintf(stderr,"\n");
- #endif
- FLAC__ASSERT(order > 0);
-
- for(i = 0; i < data_len; i++) {
- sum = 0;
- history = data;
- for(j = 0; j < order; j++)
- sum += (FLAC__int64)qlp_coeff[j] * (FLAC__int64)(*(--history));
- if(FLAC__bitmath_silog2_wide(sum >> lp_quantization) > 32) {
- #if defined _MSC_VER
- fprintf(stderr,"FLAC__lpc_compute_residual_from_qlp_coefficients_wide: OVERFLOW, i=%u, sum=%I64d\n", i, sum >> lp_quantization);
- #else
- fprintf(stderr,"FLAC__lpc_compute_residual_from_qlp_coefficients_wide: OVERFLOW, i=%u, sum=%lld\n", i, (long long)(sum >> lp_quantization));
- #endif
- break;
- }
- if(FLAC__bitmath_silog2_wide((FLAC__int64)(*data) - (sum >> lp_quantization)) > 32) {
- #if defined _MSC_VER
- fprintf(stderr,"FLAC__lpc_compute_residual_from_qlp_coefficients_wide: OVERFLOW, i=%u, data=%d, sum=%I64d, residual=%I64d\n", i, *data, sum >> lp_quantization, (FLAC__int64)(*data) - (sum >> lp_quantization));
- #else
- fprintf(stderr,"FLAC__lpc_compute_residual_from_qlp_coefficients_wide: OVERFLOW, i=%u, data=%d, sum=%lld, residual=%lld\n", i, *data, (long long)(sum >> lp_quantization), (long long)((FLAC__int64)(*data) - (sum >> lp_quantization)));
- #endif
- break;
- }
- *(residual++) = *(data++) - (FLAC__int32)(sum >> lp_quantization);
- }
- }
- #else /* fully unrolled version for normal use */
- {
- int i;
- FLAC__int64 sum;
-
- FLAC__ASSERT(order > 0);
- FLAC__ASSERT(order <= 32);
-
- /*
- * We do unique versions up to 12th order since that's the subset limit.
- * Also they are roughly ordered to match frequency of occurrence to
- * minimize branching.
- */
- if(order <= 12) {
- if(order > 8) {
- if(order > 10) {
- if(order == 12) {
- for(i = 0; i < (int)data_len; i++) {
- sum = 0;
- sum += qlp_coeff[11] * (FLAC__int64)data[i-12];
- sum += qlp_coeff[10] * (FLAC__int64)data[i-11];
- sum += qlp_coeff[9] * (FLAC__int64)data[i-10];
- sum += qlp_coeff[8] * (FLAC__int64)data[i-9];
- sum += qlp_coeff[7] * (FLAC__int64)data[i-8];
- sum += qlp_coeff[6] * (FLAC__int64)data[i-7];
- sum += qlp_coeff[5] * (FLAC__int64)data[i-6];
- sum += qlp_coeff[4] * (FLAC__int64)data[i-5];
- sum += qlp_coeff[3] * (FLAC__int64)data[i-4];
- sum += qlp_coeff[2] * (FLAC__int64)data[i-3];
- sum += qlp_coeff[1] * (FLAC__int64)data[i-2];
- sum += qlp_coeff[0] * (FLAC__int64)data[i-1];
- residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization);
- }
- }
- else { /* order == 11 */
- for(i = 0; i < (int)data_len; i++) {
- sum = 0;
- sum += qlp_coeff[10] * (FLAC__int64)data[i-11];
- sum += qlp_coeff[9] * (FLAC__int64)data[i-10];
- sum += qlp_coeff[8] * (FLAC__int64)data[i-9];
- sum += qlp_coeff[7] * (FLAC__int64)data[i-8];
- sum += qlp_coeff[6] * (FLAC__int64)data[i-7];
- sum += qlp_coeff[5] * (FLAC__int64)data[i-6];
- sum += qlp_coeff[4] * (FLAC__int64)data[i-5];
- sum += qlp_coeff[3] * (FLAC__int64)data[i-4];
- sum += qlp_coeff[2] * (FLAC__int64)data[i-3];
- sum += qlp_coeff[1] * (FLAC__int64)data[i-2];
- sum += qlp_coeff[0] * (FLAC__int64)data[i-1];
- residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization);
- }
- }
- }
- else {
- if(order == 10) {
- for(i = 0; i < (int)data_len; i++) {
- sum = 0;
- sum += qlp_coeff[9] * (FLAC__int64)data[i-10];
- sum += qlp_coeff[8] * (FLAC__int64)data[i-9];
- sum += qlp_coeff[7] * (FLAC__int64)data[i-8];
- sum += qlp_coeff[6] * (FLAC__int64)data[i-7];
- sum += qlp_coeff[5] * (FLAC__int64)data[i-6];
- sum += qlp_coeff[4] * (FLAC__int64)data[i-5];
- sum += qlp_coeff[3] * (FLAC__int64)data[i-4];
- sum += qlp_coeff[2] * (FLAC__int64)data[i-3];
- sum += qlp_coeff[1] * (FLAC__int64)data[i-2];
- sum += qlp_coeff[0] * (FLAC__int64)data[i-1];
- residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization);
- }
- }
- else { /* order == 9 */
- for(i = 0; i < (int)data_len; i++) {
- sum = 0;
- sum += qlp_coeff[8] * (FLAC__int64)data[i-9];
- sum += qlp_coeff[7] * (FLAC__int64)data[i-8];
- sum += qlp_coeff[6] * (FLAC__int64)data[i-7];
- sum += qlp_coeff[5] * (FLAC__int64)data[i-6];
- sum += qlp_coeff[4] * (FLAC__int64)data[i-5];
- sum += qlp_coeff[3] * (FLAC__int64)data[i-4];
- sum += qlp_coeff[2] * (FLAC__int64)data[i-3];
- sum += qlp_coeff[1] * (FLAC__int64)data[i-2];
- sum += qlp_coeff[0] * (FLAC__int64)data[i-1];
- residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization);
- }
- }
- }
- }
- else if(order > 4) {
- if(order > 6) {
- if(order == 8) {
- for(i = 0; i < (int)data_len; i++) {
- sum = 0;
- sum += qlp_coeff[7] * (FLAC__int64)data[i-8];
- sum += qlp_coeff[6] * (FLAC__int64)data[i-7];
- sum += qlp_coeff[5] * (FLAC__int64)data[i-6];
- sum += qlp_coeff[4] * (FLAC__int64)data[i-5];
- sum += qlp_coeff[3] * (FLAC__int64)data[i-4];
- sum += qlp_coeff[2] * (FLAC__int64)data[i-3];
- sum += qlp_coeff[1] * (FLAC__int64)data[i-2];
- sum += qlp_coeff[0] * (FLAC__int64)data[i-1];
- residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization);
- }
- }
- else { /* order == 7 */
- for(i = 0; i < (int)data_len; i++) {
- sum = 0;
- sum += qlp_coeff[6] * (FLAC__int64)data[i-7];
- sum += qlp_coeff[5] * (FLAC__int64)data[i-6];
- sum += qlp_coeff[4] * (FLAC__int64)data[i-5];
- sum += qlp_coeff[3] * (FLAC__int64)data[i-4];
- sum += qlp_coeff[2] * (FLAC__int64)data[i-3];
- sum += qlp_coeff[1] * (FLAC__int64)data[i-2];
- sum += qlp_coeff[0] * (FLAC__int64)data[i-1];
- residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization);
- }
- }
- }
- else {
- if(order == 6) {
- for(i = 0; i < (int)data_len; i++) {
- sum = 0;
- sum += qlp_coeff[5] * (FLAC__int64)data[i-6];
- sum += qlp_coeff[4] * (FLAC__int64)data[i-5];
- sum += qlp_coeff[3] * (FLAC__int64)data[i-4];
- sum += qlp_coeff[2] * (FLAC__int64)data[i-3];
- sum += qlp_coeff[1] * (FLAC__int64)data[i-2];
- sum += qlp_coeff[0] * (FLAC__int64)data[i-1];
- residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization);
- }
- }
- else { /* order == 5 */
- for(i = 0; i < (int)data_len; i++) {
- sum = 0;
- sum += qlp_coeff[4] * (FLAC__int64)data[i-5];
- sum += qlp_coeff[3] * (FLAC__int64)data[i-4];
- sum += qlp_coeff[2] * (FLAC__int64)data[i-3];
- sum += qlp_coeff[1] * (FLAC__int64)data[i-2];
- sum += qlp_coeff[0] * (FLAC__int64)data[i-1];
- residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization);
- }
- }
- }
- }
- else {
- if(order > 2) {
- if(order == 4) {
- for(i = 0; i < (int)data_len; i++) {
- sum = 0;
- sum += qlp_coeff[3] * (FLAC__int64)data[i-4];
- sum += qlp_coeff[2] * (FLAC__int64)data[i-3];
- sum += qlp_coeff[1] * (FLAC__int64)data[i-2];
- sum += qlp_coeff[0] * (FLAC__int64)data[i-1];
- residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization);
- }
- }
- else { /* order == 3 */
- for(i = 0; i < (int)data_len; i++) {
- sum = 0;
- sum += qlp_coeff[2] * (FLAC__int64)data[i-3];
- sum += qlp_coeff[1] * (FLAC__int64)data[i-2];
- sum += qlp_coeff[0] * (FLAC__int64)data[i-1];
- residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization);
- }
- }
- }
- else {
- if(order == 2) {
- for(i = 0; i < (int)data_len; i++) {
- sum = 0;
- sum += qlp_coeff[1] * (FLAC__int64)data[i-2];
- sum += qlp_coeff[0] * (FLAC__int64)data[i-1];
- residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization);
- }
- }
- else { /* order == 1 */
- for(i = 0; i < (int)data_len; i++)
- residual[i] = data[i] - (FLAC__int32)((qlp_coeff[0] * (FLAC__int64)data[i-1]) >> lp_quantization);
- }
- }
- }
- }
- else { /* order > 12 */
- for(i = 0; i < (int)data_len; i++) {
- sum = 0;
- switch(order) {
- case 32: sum += qlp_coeff[31] * (FLAC__int64)data[i-32];
- case 31: sum += qlp_coeff[30] * (FLAC__int64)data[i-31];
- case 30: sum += qlp_coeff[29] * (FLAC__int64)data[i-30];
- case 29: sum += qlp_coeff[28] * (FLAC__int64)data[i-29];
- case 28: sum += qlp_coeff[27] * (FLAC__int64)data[i-28];
- case 27: sum += qlp_coeff[26] * (FLAC__int64)data[i-27];
- case 26: sum += qlp_coeff[25] * (FLAC__int64)data[i-26];
- case 25: sum += qlp_coeff[24] * (FLAC__int64)data[i-25];
- case 24: sum += qlp_coeff[23] * (FLAC__int64)data[i-24];
- case 23: sum += qlp_coeff[22] * (FLAC__int64)data[i-23];
- case 22: sum += qlp_coeff[21] * (FLAC__int64)data[i-22];
- case 21: sum += qlp_coeff[20] * (FLAC__int64)data[i-21];
- case 20: sum += qlp_coeff[19] * (FLAC__int64)data[i-20];
- case 19: sum += qlp_coeff[18] * (FLAC__int64)data[i-19];
- case 18: sum += qlp_coeff[17] * (FLAC__int64)data[i-18];
- case 17: sum += qlp_coeff[16] * (FLAC__int64)data[i-17];
- case 16: sum += qlp_coeff[15] * (FLAC__int64)data[i-16];
- case 15: sum += qlp_coeff[14] * (FLAC__int64)data[i-15];
- case 14: sum += qlp_coeff[13] * (FLAC__int64)data[i-14];
- case 13: sum += qlp_coeff[12] * (FLAC__int64)data[i-13];
- sum += qlp_coeff[11] * (FLAC__int64)data[i-12];
- sum += qlp_coeff[10] * (FLAC__int64)data[i-11];
- sum += qlp_coeff[ 9] * (FLAC__int64)data[i-10];
- sum += qlp_coeff[ 8] * (FLAC__int64)data[i- 9];
- sum += qlp_coeff[ 7] * (FLAC__int64)data[i- 8];
- sum += qlp_coeff[ 6] * (FLAC__int64)data[i- 7];
- sum += qlp_coeff[ 5] * (FLAC__int64)data[i- 6];
- sum += qlp_coeff[ 4] * (FLAC__int64)data[i- 5];
- sum += qlp_coeff[ 3] * (FLAC__int64)data[i- 4];
- sum += qlp_coeff[ 2] * (FLAC__int64)data[i- 3];
- sum += qlp_coeff[ 1] * (FLAC__int64)data[i- 2];
- sum += qlp_coeff[ 0] * (FLAC__int64)data[i- 1];
- }
- residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization);
- }
- }
- }
- #endif
-
- #endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */
-
- void FLAC__lpc_restore_signal(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[])
- #if defined(FLAC__OVERFLOW_DETECT) || !defined(FLAC__LPC_UNROLLED_FILTER_LOOPS)
- {
- FLAC__int64 sumo;
- unsigned i, j;
- FLAC__int32 sum;
- const FLAC__int32 *r = residual, *history;
-
- #ifdef FLAC__OVERFLOW_DETECT_VERBOSE
- fprintf(stderr,"FLAC__lpc_restore_signal: data_len=%d, order=%u, lpq=%d",data_len,order,lp_quantization);
- for(i=0;i<order;i++)
- fprintf(stderr,", q[%u]=%d",i,qlp_coeff[i]);
- fprintf(stderr,"\n");
- #endif
- FLAC__ASSERT(order > 0);
-
- for(i = 0; i < data_len; i++) {
- sumo = 0;
- sum = 0;
- history = data;
- for(j = 0; j < order; j++) {
- sum += qlp_coeff[j] * (*(--history));
- sumo += (FLAC__int64)qlp_coeff[j] * (FLAC__int64)(*history);
- #if defined _MSC_VER
- if(sumo > 2147483647I64 || sumo < -2147483648I64)
- fprintf(stderr,"FLAC__lpc_restore_signal: OVERFLOW, i=%u, j=%u, c=%d, d=%d, sumo=%I64d\n",i,j,qlp_coeff[j],*history,sumo);
- #else
- if(sumo > 2147483647ll || sumo < -2147483648ll)
- fprintf(stderr,"FLAC__lpc_restore_signal: OVERFLOW, i=%u, j=%u, c=%d, d=%d, sumo=%lld\n",i,j,qlp_coeff[j],*history,(long long)sumo);
- #endif
- }
- *(data++) = *(r++) + (sum >> lp_quantization);
- }
-
- /* Here's a slower but clearer version:
- for(i = 0; i < data_len; i++) {
- sum = 0;
- for(j = 0; j < order; j++)
- sum += qlp_coeff[j] * data[i-j-1];
- data[i] = residual[i] + (sum >> lp_quantization);
- }
- */
- }
- #else /* fully unrolled version for normal use */
- {
- int i;
- FLAC__int32 sum;
-
- FLAC__ASSERT(order > 0);
- FLAC__ASSERT(order <= 32);
-
- /*
- * We do unique versions up to 12th order since that's the subset limit.
- * Also they are roughly ordered to match frequency of occurrence to
- * minimize branching.
- */
- if(order <= 12) {
- if(order > 8) {
- if(order > 10) {
- if(order == 12) {
- for(i = 0; i < (int)data_len; i++) {
- sum = 0;
- sum += qlp_coeff[11] * data[i-12];
- sum += qlp_coeff[10] * data[i-11];
- sum += qlp_coeff[9] * data[i-10];
- sum += qlp_coeff[8] * data[i-9];
- sum += qlp_coeff[7] * data[i-8];
- sum += qlp_coeff[6] * data[i-7];
- sum += qlp_coeff[5] * data[i-6];
- sum += qlp_coeff[4] * data[i-5];
- sum += qlp_coeff[3] * data[i-4];
- sum += qlp_coeff[2] * data[i-3];
- sum += qlp_coeff[1] * data[i-2];
- sum += qlp_coeff[0] * data[i-1];
- data[i] = residual[i] + (sum >> lp_quantization);
- }
- }
- else { /* order == 11 */
- for(i = 0; i < (int)data_len; i++) {
- sum = 0;
- sum += qlp_coeff[10] * data[i-11];
- sum += qlp_coeff[9] * data[i-10];
- sum += qlp_coeff[8] * data[i-9];
- sum += qlp_coeff[7] * data[i-8];
- sum += qlp_coeff[6] * data[i-7];
- sum += qlp_coeff[5] * data[i-6];
- sum += qlp_coeff[4] * data[i-5];
- sum += qlp_coeff[3] * data[i-4];
- sum += qlp_coeff[2] * data[i-3];
- sum += qlp_coeff[1] * data[i-2];
- sum += qlp_coeff[0] * data[i-1];
- data[i] = residual[i] + (sum >> lp_quantization);
- }
- }
- }
- else {
- if(order == 10) {
- for(i = 0; i < (int)data_len; i++) {
- sum = 0;
- sum += qlp_coeff[9] * data[i-10];
- sum += qlp_coeff[8] * data[i-9];
- sum += qlp_coeff[7] * data[i-8];
- sum += qlp_coeff[6] * data[i-7];
- sum += qlp_coeff[5] * data[i-6];
- sum += qlp_coeff[4] * data[i-5];
- sum += qlp_coeff[3] * data[i-4];
- sum += qlp_coeff[2] * data[i-3];
- sum += qlp_coeff[1] * data[i-2];
- sum += qlp_coeff[0] * data[i-1];
- data[i] = residual[i] + (sum >> lp_quantization);
- }
- }
- else { /* order == 9 */
- for(i = 0; i < (int)data_len; i++) {
- sum = 0;
- sum += qlp_coeff[8] * data[i-9];
- sum += qlp_coeff[7] * data[i-8];
- sum += qlp_coeff[6] * data[i-7];
- sum += qlp_coeff[5] * data[i-6];
- sum += qlp_coeff[4] * data[i-5];
- sum += qlp_coeff[3] * data[i-4];
- sum += qlp_coeff[2] * data[i-3];
- sum += qlp_coeff[1] * data[i-2];
- sum += qlp_coeff[0] * data[i-1];
- data[i] = residual[i] + (sum >> lp_quantization);
- }
- }
- }
- }
- else if(order > 4) {
- if(order > 6) {
- if(order == 8) {
- for(i = 0; i < (int)data_len; i++) {
- sum = 0;
- sum += qlp_coeff[7] * data[i-8];
- sum += qlp_coeff[6] * data[i-7];
- sum += qlp_coeff[5] * data[i-6];
- sum += qlp_coeff[4] * data[i-5];
- sum += qlp_coeff[3] * data[i-4];
- sum += qlp_coeff[2] * data[i-3];
- sum += qlp_coeff[1] * data[i-2];
- sum += qlp_coeff[0] * data[i-1];
- data[i] = residual[i] + (sum >> lp_quantization);
- }
- }
- else { /* order == 7 */
- for(i = 0; i < (int)data_len; i++) {
- sum = 0;
- sum += qlp_coeff[6] * data[i-7];
- sum += qlp_coeff[5] * data[i-6];
- sum += qlp_coeff[4] * data[i-5];
- sum += qlp_coeff[3] * data[i-4];
- sum += qlp_coeff[2] * data[i-3];
- sum += qlp_coeff[1] * data[i-2];
- sum += qlp_coeff[0] * data[i-1];
- data[i] = residual[i] + (sum >> lp_quantization);
- }
- }
- }
- else {
- if(order == 6) {
- for(i = 0; i < (int)data_len; i++) {
- sum = 0;
- sum += qlp_coeff[5] * data[i-6];
- sum += qlp_coeff[4] * data[i-5];
- sum += qlp_coeff[3] * data[i-4];
- sum += qlp_coeff[2] * data[i-3];
- sum += qlp_coeff[1] * data[i-2];
- sum += qlp_coeff[0] * data[i-1];
- data[i] = residual[i] + (sum >> lp_quantization);
- }
- }
- else { /* order == 5 */
- for(i = 0; i < (int)data_len; i++) {
- sum = 0;
- sum += qlp_coeff[4] * data[i-5];
- sum += qlp_coeff[3] * data[i-4];
- sum += qlp_coeff[2] * data[i-3];
- sum += qlp_coeff[1] * data[i-2];
- sum += qlp_coeff[0] * data[i-1];
- data[i] = residual[i] + (sum >> lp_quantization);
- }
- }
- }
- }
- else {
- if(order > 2) {
- if(order == 4) {
- for(i = 0; i < (int)data_len; i++) {
- sum = 0;
- sum += qlp_coeff[3] * data[i-4];
- sum += qlp_coeff[2] * data[i-3];
- sum += qlp_coeff[1] * data[i-2];
- sum += qlp_coeff[0] * data[i-1];
- data[i] = residual[i] + (sum >> lp_quantization);
- }
- }
- else { /* order == 3 */
- for(i = 0; i < (int)data_len; i++) {
- sum = 0;
- sum += qlp_coeff[2] * data[i-3];
- sum += qlp_coeff[1] * data[i-2];
- sum += qlp_coeff[0] * data[i-1];
- data[i] = residual[i] + (sum >> lp_quantization);
- }
- }
- }
- else {
- if(order == 2) {
- for(i = 0; i < (int)data_len; i++) {
- sum = 0;
- sum += qlp_coeff[1] * data[i-2];
- sum += qlp_coeff[0] * data[i-1];
- data[i] = residual[i] + (sum >> lp_quantization);
- }
- }
- else { /* order == 1 */
- for(i = 0; i < (int)data_len; i++)
- data[i] = residual[i] + ((qlp_coeff[0] * data[i-1]) >> lp_quantization);
- }
- }
- }
- }
- else { /* order > 12 */
- for(i = 0; i < (int)data_len; i++) {
- sum = 0;
- switch(order) {
- case 32: sum += qlp_coeff[31] * data[i-32];
- case 31: sum += qlp_coeff[30] * data[i-31];
- case 30: sum += qlp_coeff[29] * data[i-30];
- case 29: sum += qlp_coeff[28] * data[i-29];
- case 28: sum += qlp_coeff[27] * data[i-28];
- case 27: sum += qlp_coeff[26] * data[i-27];
- case 26: sum += qlp_coeff[25] * data[i-26];
- case 25: sum += qlp_coeff[24] * data[i-25];
- case 24: sum += qlp_coeff[23] * data[i-24];
- case 23: sum += qlp_coeff[22] * data[i-23];
- case 22: sum += qlp_coeff[21] * data[i-22];
- case 21: sum += qlp_coeff[20] * data[i-21];
- case 20: sum += qlp_coeff[19] * data[i-20];
- case 19: sum += qlp_coeff[18] * data[i-19];
- case 18: sum += qlp_coeff[17] * data[i-18];
- case 17: sum += qlp_coeff[16] * data[i-17];
- case 16: sum += qlp_coeff[15] * data[i-16];
- case 15: sum += qlp_coeff[14] * data[i-15];
- case 14: sum += qlp_coeff[13] * data[i-14];
- case 13: sum += qlp_coeff[12] * data[i-13];
- sum += qlp_coeff[11] * data[i-12];
- sum += qlp_coeff[10] * data[i-11];
- sum += qlp_coeff[ 9] * data[i-10];
- sum += qlp_coeff[ 8] * data[i- 9];
- sum += qlp_coeff[ 7] * data[i- 8];
- sum += qlp_coeff[ 6] * data[i- 7];
- sum += qlp_coeff[ 5] * data[i- 6];
- sum += qlp_coeff[ 4] * data[i- 5];
- sum += qlp_coeff[ 3] * data[i- 4];
- sum += qlp_coeff[ 2] * data[i- 3];
- sum += qlp_coeff[ 1] * data[i- 2];
- sum += qlp_coeff[ 0] * data[i- 1];
- }
- data[i] = residual[i] + (sum >> lp_quantization);
- }
- }
- }
- #endif
-
- void FLAC__lpc_restore_signal_wide(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[])
- #if defined(FLAC__OVERFLOW_DETECT) || !defined(FLAC__LPC_UNROLLED_FILTER_LOOPS)
- {
- unsigned i, j;
- FLAC__int64 sum;
- const FLAC__int32 *r = residual, *history;
-
- #ifdef FLAC__OVERFLOW_DETECT_VERBOSE
- fprintf(stderr,"FLAC__lpc_restore_signal_wide: data_len=%d, order=%u, lpq=%d",data_len,order,lp_quantization);
- for(i=0;i<order;i++)
- fprintf(stderr,", q[%u]=%d",i,qlp_coeff[i]);
- fprintf(stderr,"\n");
- #endif
- FLAC__ASSERT(order > 0);
-
- for(i = 0; i < data_len; i++) {
- sum = 0;
- history = data;
- for(j = 0; j < order; j++)
- sum += (FLAC__int64)qlp_coeff[j] * (FLAC__int64)(*(--history));
- if(FLAC__bitmath_silog2_wide(sum >> lp_quantization) > 32) {
- #ifdef _MSC_VER
- fprintf(stderr,"FLAC__lpc_restore_signal_wide: OVERFLOW, i=%u, sum=%I64d\n", i, sum >> lp_quantization);
- #else
- fprintf(stderr,"FLAC__lpc_restore_signal_wide: OVERFLOW, i=%u, sum=%lld\n", i, (long long)(sum >> lp_quantization));
- #endif
- break;
- }
- if(FLAC__bitmath_silog2_wide((FLAC__int64)(*r) + (sum >> lp_quantization)) > 32) {
- #ifdef _MSC_VER
- fprintf(stderr,"FLAC__lpc_restore_signal_wide: OVERFLOW, i=%u, residual=%d, sum=%I64d, data=%I64d\n", i, *r, sum >> lp_quantization, (FLAC__int64)(*r) + (sum >> lp_quantization));
- #else
- fprintf(stderr,"FLAC__lpc_restore_signal_wide: OVERFLOW, i=%u, residual=%d, sum=%lld, data=%lld\n", i, *r, (long long)(sum >> lp_quantization), (long long)((FLAC__int64)(*r) + (sum >> lp_quantization)));
- #endif
- break;
- }
- *(data++) = *(r++) + (FLAC__int32)(sum >> lp_quantization);
- }
- }
- #else /* fully unrolled version for normal use */
- {
- int i;
- FLAC__int64 sum;
-
- FLAC__ASSERT(order > 0);
- FLAC__ASSERT(order <= 32);
-
- /*
- * We do unique versions up to 12th order since that's the subset limit.
- * Also they are roughly ordered to match frequency of occurrence to
- * minimize branching.
- */
- if(order <= 12) {
- if(order > 8) {
- if(order > 10) {
- if(order == 12) {
- for(i = 0; i < (int)data_len; i++) {
- sum = 0;
- sum += qlp_coeff[11] * (FLAC__int64)data[i-12];
- sum += qlp_coeff[10] * (FLAC__int64)data[i-11];
- sum += qlp_coeff[9] * (FLAC__int64)data[i-10];
- sum += qlp_coeff[8] * (FLAC__int64)data[i-9];
- sum += qlp_coeff[7] * (FLAC__int64)data[i-8];
- sum += qlp_coeff[6] * (FLAC__int64)data[i-7];
- sum += qlp_coeff[5] * (FLAC__int64)data[i-6];
- sum += qlp_coeff[4] * (FLAC__int64)data[i-5];
- sum += qlp_coeff[3] * (FLAC__int64)data[i-4];
- sum += qlp_coeff[2] * (FLAC__int64)data[i-3];
- sum += qlp_coeff[1] * (FLAC__int64)data[i-2];
- sum += qlp_coeff[0] * (FLAC__int64)data[i-1];
- data[i] = residual[i] + (FLAC__int32)(sum >> lp_quantization);
- }
- }
- else { /* order == 11 */
- for(i = 0; i < (int)data_len; i++) {
- sum = 0;
- sum += qlp_coeff[10] * (FLAC__int64)data[i-11];
- sum += qlp_coeff[9] * (FLAC__int64)data[i-10];
- sum += qlp_coeff[8] * (FLAC__int64)data[i-9];
- sum += qlp_coeff[7] * (FLAC__int64)data[i-8];
- sum += qlp_coeff[6] * (FLAC__int64)data[i-7];
- sum += qlp_coeff[5] * (FLAC__int64)data[i-6];
- sum += qlp_coeff[4] * (FLAC__int64)data[i-5];
- sum += qlp_coeff[3] * (FLAC__int64)data[i-4];
- sum += qlp_coeff[2] * (FLAC__int64)data[i-3];
- sum += qlp_coeff[1] * (FLAC__int64)data[i-2];
- sum += qlp_coeff[0] * (FLAC__int64)data[i-1];
- data[i] = residual[i] + (FLAC__int32)(sum >> lp_quantization);
- }
- }
- }
- else {
- if(order == 10) {
- for(i = 0; i < (int)data_len; i++) {
- sum = 0;
- sum += qlp_coeff[9] * (FLAC__int64)data[i-10];
- sum += qlp_coeff[8] * (FLAC__int64)data[i-9];
- sum += qlp_coeff[7] * (FLAC__int64)data[i-8];
- sum += qlp_coeff[6] * (FLAC__int64)data[i-7];
- sum += qlp_coeff[5] * (FLAC__int64)data[i-6];
- sum += qlp_coeff[4] * (FLAC__int64)data[i-5];
- sum += qlp_coeff[3] * (FLAC__int64)data[i-4];
- sum += qlp_coeff[2] * (FLAC__int64)data[i-3];
- sum += qlp_coeff[1] * (FLAC__int64)data[i-2];
- sum += qlp_coeff[0] * (FLAC__int64)data[i-1];
- data[i] = residual[i] + (FLAC__int32)(sum >> lp_quantization);
- }
- }
- else { /* order == 9 */
- for(i = 0; i < (int)data_len; i++) {
- sum = 0;
- sum += qlp_coeff[8] * (FLAC__int64)data[i-9];
- sum += qlp_coeff[7] * (FLAC__int64)data[i-8];
- sum += qlp_coeff[6] * (FLAC__int64)data[i-7];
- sum += qlp_coeff[5] * (FLAC__int64)data[i-6];
- sum += qlp_coeff[4] * (FLAC__int64)data[i-5];
- sum += qlp_coeff[3] * (FLAC__int64)data[i-4];
- sum += qlp_coeff[2] * (FLAC__int64)data[i-3];
- sum += qlp_coeff[1] * (FLAC__int64)data[i-2];
- sum += qlp_coeff[0] * (FLAC__int64)data[i-1];
- data[i] = residual[i] + (FLAC__int32)(sum >> lp_quantization);
- }
- }
- }
- }
- else if(order > 4) {
- if(order > 6) {
- if(order == 8) {
- for(i = 0; i < (int)data_len; i++) {
- sum = 0;
- sum += qlp_coeff[7] * (FLAC__int64)data[i-8];
- sum += qlp_coeff[6] * (FLAC__int64)data[i-7];
- sum += qlp_coeff[5] * (FLAC__int64)data[i-6];
- sum += qlp_coeff[4] * (FLAC__int64)data[i-5];
- sum += qlp_coeff[3] * (FLAC__int64)data[i-4];
- sum += qlp_coeff[2] * (FLAC__int64)data[i-3];
- sum += qlp_coeff[1] * (FLAC__int64)data[i-2];
- sum += qlp_coeff[0] * (FLAC__int64)data[i-1];
- data[i] = residual[i] + (FLAC__int32)(sum >> lp_quantization);
- }
- }
- else { /* order == 7 */
- for(i = 0; i < (int)data_len; i++) {
- sum = 0;
- sum += qlp_coeff[6] * (FLAC__int64)data[i-7];
- sum += qlp_coeff[5] * (FLAC__int64)data[i-6];
- sum += qlp_coeff[4] * (FLAC__int64)data[i-5];
- sum += qlp_coeff[3] * (FLAC__int64)data[i-4];
- sum += qlp_coeff[2] * (FLAC__int64)data[i-3];
- sum += qlp_coeff[1] * (FLAC__int64)data[i-2];
- sum += qlp_coeff[0] * (FLAC__int64)data[i-1];
- data[i] = residual[i] + (FLAC__int32)(sum >> lp_quantization);
- }
- }
- }
- else {
- if(order == 6) {
- for(i = 0; i < (int)data_len; i++) {
- sum = 0;
- sum += qlp_coeff[5] * (FLAC__int64)data[i-6];
- sum += qlp_coeff[4] * (FLAC__int64)data[i-5];
- sum += qlp_coeff[3] * (FLAC__int64)data[i-4];
- sum += qlp_coeff[2] * (FLAC__int64)data[i-3];
- sum += qlp_coeff[1] * (FLAC__int64)data[i-2];
- sum += qlp_coeff[0] * (FLAC__int64)data[i-1];
- data[i] = residual[i] + (FLAC__int32)(sum >> lp_quantization);
- }
- }
- else { /* order == 5 */
- for(i = 0; i < (int)data_len; i++) {
- sum = 0;
- sum += qlp_coeff[4] * (FLAC__int64)data[i-5];
- sum += qlp_coeff[3] * (FLAC__int64)data[i-4];
- sum += qlp_coeff[2] * (FLAC__int64)data[i-3];
- sum += qlp_coeff[1] * (FLAC__int64)data[i-2];
- sum += qlp_coeff[0] * (FLAC__int64)data[i-1];
- data[i] = residual[i] + (FLAC__int32)(sum >> lp_quantization);
- }
- }
- }
- }
- else {
- if(order > 2) {
- if(order == 4) {
- for(i = 0; i < (int)data_len; i++) {
- sum = 0;
- sum += qlp_coeff[3] * (FLAC__int64)data[i-4];
- sum += qlp_coeff[2] * (FLAC__int64)data[i-3];
- sum += qlp_coeff[1] * (FLAC__int64)data[i-2];
- sum += qlp_coeff[0] * (FLAC__int64)data[i-1];
- data[i] = residual[i] + (FLAC__int32)(sum >> lp_quantization);
- }
- }
- else { /* order == 3 */
- for(i = 0; i < (int)data_len; i++) {
- sum = 0;
- sum += qlp_coeff[2] * (FLAC__int64)data[i-3];
- sum += qlp_coeff[1] * (FLAC__int64)data[i-2];
- sum += qlp_coeff[0] * (FLAC__int64)data[i-1];
- data[i] = residual[i] + (FLAC__int32)(sum >> lp_quantization);
- }
- }
- }
- else {
- if(order == 2) {
- for(i = 0; i < (int)data_len; i++) {
- sum = 0;
- sum += qlp_coeff[1] * (FLAC__int64)data[i-2];
- sum += qlp_coeff[0] * (FLAC__int64)data[i-1];
- data[i] = residual[i] + (FLAC__int32)(sum >> lp_quantization);
- }
- }
- else { /* order == 1 */
- for(i = 0; i < (int)data_len; i++)
- data[i] = residual[i] + (FLAC__int32)((qlp_coeff[0] * (FLAC__int64)data[i-1]) >> lp_quantization);
- }
- }
- }
- }
- else { /* order > 12 */
- for(i = 0; i < (int)data_len; i++) {
- sum = 0;
- switch(order) {
- case 32: sum += qlp_coeff[31] * (FLAC__int64)data[i-32];
- case 31: sum += qlp_coeff[30] * (FLAC__int64)data[i-31];
- case 30: sum += qlp_coeff[29] * (FLAC__int64)data[i-30];
- case 29: sum += qlp_coeff[28] * (FLAC__int64)data[i-29];
- case 28: sum += qlp_coeff[27] * (FLAC__int64)data[i-28];
- case 27: sum += qlp_coeff[26] * (FLAC__int64)data[i-27];
- case 26: sum += qlp_coeff[25] * (FLAC__int64)data[i-26];
- case 25: sum += qlp_coeff[24] * (FLAC__int64)data[i-25];
- case 24: sum += qlp_coeff[23] * (FLAC__int64)data[i-24];
- case 23: sum += qlp_coeff[22] * (FLAC__int64)data[i-23];
- case 22: sum += qlp_coeff[21] * (FLAC__int64)data[i-22];
- case 21: sum += qlp_coeff[20] * (FLAC__int64)data[i-21];
- case 20: sum += qlp_coeff[19] * (FLAC__int64)data[i-20];
- case 19: sum += qlp_coeff[18] * (FLAC__int64)data[i-19];
- case 18: sum += qlp_coeff[17] * (FLAC__int64)data[i-18];
- case 17: sum += qlp_coeff[16] * (FLAC__int64)data[i-17];
- case 16: sum += qlp_coeff[15] * (FLAC__int64)data[i-16];
- case 15: sum += qlp_coeff[14] * (FLAC__int64)data[i-15];
- case 14: sum += qlp_coeff[13] * (FLAC__int64)data[i-14];
- case 13: sum += qlp_coeff[12] * (FLAC__int64)data[i-13];
- sum += qlp_coeff[11] * (FLAC__int64)data[i-12];
- sum += qlp_coeff[10] * (FLAC__int64)data[i-11];
- sum += qlp_coeff[ 9] * (FLAC__int64)data[i-10];
- sum += qlp_coeff[ 8] * (FLAC__int64)data[i- 9];
- sum += qlp_coeff[ 7] * (FLAC__int64)data[i- 8];
- sum += qlp_coeff[ 6] * (FLAC__int64)data[i- 7];
- sum += qlp_coeff[ 5] * (FLAC__int64)data[i- 6];
- sum += qlp_coeff[ 4] * (FLAC__int64)data[i- 5];
- sum += qlp_coeff[ 3] * (FLAC__int64)data[i- 4];
- sum += qlp_coeff[ 2] * (FLAC__int64)data[i- 3];
- sum += qlp_coeff[ 1] * (FLAC__int64)data[i- 2];
- sum += qlp_coeff[ 0] * (FLAC__int64)data[i- 1];
- }
- data[i] = residual[i] + (FLAC__int32)(sum >> lp_quantization);
- }
- }
- }
- #endif
-
- #ifndef FLAC__INTEGER_ONLY_LIBRARY
-
- FLAC__double FLAC__lpc_compute_expected_bits_per_residual_sample(FLAC__double lpc_error, unsigned total_samples)
- {
- FLAC__double error_scale;
-
- FLAC__ASSERT(total_samples > 0);
-
- error_scale = 0.5 * M_LN2 * M_LN2 / (FLAC__double)total_samples;
-
- return FLAC__lpc_compute_expected_bits_per_residual_sample_with_error_scale(lpc_error, error_scale);
- }
-
- FLAC__double FLAC__lpc_compute_expected_bits_per_residual_sample_with_error_scale(FLAC__double lpc_error, FLAC__double error_scale)
- {
- if(lpc_error > 0.0) {
- FLAC__double bps = (FLAC__double)0.5 * log(error_scale * lpc_error) / M_LN2;
- if(bps >= 0.0)
- return bps;
- else
- return 0.0;
- }
- else if(lpc_error < 0.0) { /* error should not be negative but can happen due to inadequate floating-point resolution */
- return 1e32;
- }
- else {
- return 0.0;
- }
- }
-
- unsigned FLAC__lpc_compute_best_order(const FLAC__double lpc_error[], unsigned max_order, unsigned total_samples, unsigned overhead_bits_per_order)
- {
- unsigned order, index, best_index; /* 'index' the index into lpc_error; index==order-1 since lpc_error[0] is for order==1, lpc_error[1] is for order==2, etc */
- FLAC__double bits, best_bits, error_scale;
-
- FLAC__ASSERT(max_order > 0);
- FLAC__ASSERT(total_samples > 0);
-
- error_scale = 0.5 * M_LN2 * M_LN2 / (FLAC__double)total_samples;
-
- best_index = 0;
- best_bits = (unsigned)(-1);
-
- for(index = 0, order = 1; index < max_order; index++, order++) {
- bits = FLAC__lpc_compute_expected_bits_per_residual_sample_with_error_scale(lpc_error[index], error_scale) * (FLAC__double)(total_samples - order) + (FLAC__double)(order * overhead_bits_per_order);
- if(bits < best_bits) {
- best_index = index;
- best_bits = bits;
- }
- }
-
- return best_index+1; /* +1 since index of lpc_error[] is order-1 */
- }
-
- #endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */
-
- #endif
- /********* End of inlined file: lpc_flac.c *********/
-
- /********* Start of inlined file: md5.c *********/
-
- /********* Start of inlined file: juce_FlacHeader.h *********/
- // This file is included at the start of each FLAC .c file, just to do a few housekeeping
- // tasks..
-
- #define VERSION "1.2.1"
-
- #define FLAC__NO_DLL 1
-
- #ifdef _MSC_VER
- #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4312)
- #endif
-
- #if ! (defined (_WIN32) || defined (_WIN64) || defined (LINUX))
- #define FLAC__SYS_DARWIN 1
- #endif
- /********* End of inlined file: juce_FlacHeader.h *********/
-
- #if JUCE_USE_FLAC
-
- #if HAVE_CONFIG_H
- # include <config.h>
- #endif
-
- #include <stdlib.h> /* for malloc() */
- #include <string.h> /* for memcpy() */
-
- /********* Start of inlined file: md5.h *********/
- #ifndef FLAC__PRIVATE__MD5_H
- #define FLAC__PRIVATE__MD5_H
-
- /*
- * This is the header file for the MD5 message-digest algorithm.
- * The algorithm is due to Ron Rivest. This code was
- * written by Colin Plumb in 1993, no copyright is claimed.
- * This code is in the public domain; do with it what you wish.
- *
- * Equivalent code is available from RSA Data Security, Inc.
- * This code has been tested against that, and is equivalent,
- * except that you don't need to include two pages of legalese
- * with every copy.
- *
- * To compute the message digest of a chunk of bytes, declare an
- * MD5Context structure, pass it to MD5Init, call MD5Update as
- * needed on buffers full of bytes, and then call MD5Final, which
- * will fill a supplied 16-byte array with the digest.
- *
- * Changed so as no longer to depend on Colin Plumb's `usual.h'
- * header definitions; now uses stuff from dpkg's config.h
- * - Ian Jackson <ijackson@nyx.cs.du.edu>.
- * Still in the public domain.
- *
- * Josh Coalson: made some changes to integrate with libFLAC.
- * Still in the public domain, with no warranty.
- */
-
- typedef struct {
- FLAC__uint32 in[16];
- FLAC__uint32 buf[4];
- FLAC__uint32 bytes[2];
- FLAC__byte *internal_buf;
- size_t capacity;
- } FLAC__MD5Context;
-
- void FLAC__MD5Init(FLAC__MD5Context *context);
- void FLAC__MD5Final(FLAC__byte digest[16], FLAC__MD5Context *context);
-
- FLAC__bool FLAC__MD5Accumulate(FLAC__MD5Context *ctx, const FLAC__int32 * const signal[], unsigned channels, unsigned samples, unsigned bytes_per_sample);
-
- #endif
- /********* End of inlined file: md5.h *********/
-
- #ifndef FLaC__INLINE
- #define FLaC__INLINE
- #endif
-
- /*
- * This code implements the MD5 message-digest algorithm.
- * The algorithm is due to Ron Rivest. This code was
- * written by Colin Plumb in 1993, no copyright is claimed.
- * This code is in the public domain; do with it what you wish.
- *
- * Equivalent code is available from RSA Data Security, Inc.
- * This code has been tested against that, and is equivalent,
- * except that you don't need to include two pages of legalese
- * with every copy.
- *
- * To compute the message digest of a chunk of bytes, declare an
- * MD5Context structure, pass it to MD5Init, call MD5Update as
- * needed on buffers full of bytes, and then call MD5Final, which
- * will fill a supplied 16-byte array with the digest.
- *
- * Changed so as no longer to depend on Colin Plumb's `usual.h' header
- * definitions; now uses stuff from dpkg's config.h.
- * - Ian Jackson <ijackson@nyx.cs.du.edu>.
- * Still in the public domain.
- *
- * Josh Coalson: made some changes to integrate with libFLAC.
- * Still in the public domain.
- */
-
- /* The four core functions - F1 is optimized somewhat */
-
- /* #define F1(x, y, z) (x & y | ~x & z) */
- #define F1(x, y, z) (z ^ (x & (y ^ z)))
- #define F2(x, y, z) F1(z, x, y)
- #define F3(x, y, z) (x ^ y ^ z)
- #define F4(x, y, z) (y ^ (x | ~z))
-
- /* This is the central step in the MD5 algorithm. */
- #define MD5STEP(f,w,x,y,z,in,s) \
- (w += f(x,y,z) + in, w = (w<<s | w>>(32-s)) + x)
-
- /*
- * The core of the MD5 algorithm, this alters an existing MD5 hash to
- * reflect the addition of 16 longwords of new data. MD5Update blocks
- * the data and converts bytes into longwords for this routine.
- */
- static void FLAC__MD5Transform(FLAC__uint32 buf[4], FLAC__uint32 const in[16])
- {
- register FLAC__uint32 a, b, c, d;
-
- a = buf[0];
- b = buf[1];
- c = buf[2];
- d = buf[3];
-
- MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
- MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
- MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
- MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
- MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
- MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
- MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
- MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
- MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
- MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
- MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
- MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
- MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
- MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
- MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
- MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
-
- MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
- MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
- MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
- MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
- MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
- MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
- MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
- MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
- MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
- MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
- MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
- MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
- MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
- MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
- MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
- MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
-
- MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
- MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
- MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
- MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
- MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
- MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
- MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
- MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
- MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
- MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
- MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
- MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
- MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
- MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
- MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
- MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
-
- MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
- MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
- MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
- MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
- MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
- MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
- MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
- MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
- MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
- MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
- MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
- MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
- MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
- MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
- MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
- MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
-
- buf[0] += a;
- buf[1] += b;
- buf[2] += c;
- buf[3] += d;
- }
-
- #if WORDS_BIGENDIAN
- //@@@@@@ OPT: use bswap/intrinsics
- static void byteSwap(FLAC__uint32 *buf, unsigned words)
- {
- register FLAC__uint32 x;
- do {
- x = *buf;
- x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff);
- *buf++ = (x >> 16) | (x << 16);
- } while (--words);
- }
- static void byteSwapX16(FLAC__uint32 *buf)
- {
- register FLAC__uint32 x;
-
- x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16);
- x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16);
- x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16);
- x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16);
- x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16);
- x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16);
- x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16);
- x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16);
- x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16);
- x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16);
- x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16);
- x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16);
- x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16);
- x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16);
- x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16);
- x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf = (x >> 16) | (x << 16);
- }
- #else
- #define byteSwap(buf, words)
- #define byteSwapX16(buf)
- #endif
-
- /*
- * Update context to reflect the concatenation of another buffer full
- * of bytes.
- */
- static void FLAC__MD5Update(FLAC__MD5Context *ctx, FLAC__byte const *buf, unsigned len)
- {
- FLAC__uint32 t;
-
- /* Update byte count */
-
- t = ctx->bytes[0];
- if ((ctx->bytes[0] = t + len) < t)
- ctx->bytes[1]++; /* Carry from low to high */
-
- t = 64 - (t & 0x3f); /* Space available in ctx->in (at least 1) */
- if (t > len) {
- memcpy((FLAC__byte *)ctx->in + 64 - t, buf, len);
- return;
- }
- /* First chunk is an odd size */
- memcpy((FLAC__byte *)ctx->in + 64 - t, buf, t);
- byteSwapX16(ctx->in);
- FLAC__MD5Transform(ctx->buf, ctx->in);
- buf += t;
- len -= t;
-
- /* Process data in 64-byte chunks */
- while (len >= 64) {
- memcpy(ctx->in, buf, 64);
- byteSwapX16(ctx->in);
- FLAC__MD5Transform(ctx->buf, ctx->in);
- buf += 64;
- len -= 64;
- }
-
- /* Handle any remaining bytes of data. */
- memcpy(ctx->in, buf, len);
- }
-
- /*
- * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
- * initialization constants.
- */
- void FLAC__MD5Init(FLAC__MD5Context *ctx)
- {
- ctx->buf[0] = 0x67452301;
- ctx->buf[1] = 0xefcdab89;
- ctx->buf[2] = 0x98badcfe;
- ctx->buf[3] = 0x10325476;
-
- ctx->bytes[0] = 0;
- ctx->bytes[1] = 0;
-
- ctx->internal_buf = 0;
- ctx->capacity = 0;
- }
-
- /*
- * Final wrapup - pad to 64-byte boundary with the bit pattern
- * 1 0* (64-bit count of bits processed, MSB-first)
- */
- void FLAC__MD5Final(FLAC__byte digest[16], FLAC__MD5Context *ctx)
- {
- int count = ctx->bytes[0] & 0x3f; /* Number of bytes in ctx->in */
- FLAC__byte *p = (FLAC__byte *)ctx->in + count;
-
- /* Set the first char of padding to 0x80. There is always room. */
- *p++ = 0x80;
-
- /* Bytes of padding needed to make 56 bytes (-8..55) */
- count = 56 - 1 - count;
-
- if (count < 0) { /* Padding forces an extra block */
- memset(p, 0, count + 8);
- byteSwapX16(ctx->in);
- FLAC__MD5Transform(ctx->buf, ctx->in);
- p = (FLAC__byte *)ctx->in;
- count = 56;
- }
- memset(p, 0, count);
- byteSwap(ctx->in, 14);
-
- /* Append length in bits and transform */
- ctx->in[14] = ctx->bytes[0] << 3;
- ctx->in[15] = ctx->bytes[1] << 3 | ctx->bytes[0] >> 29;
- FLAC__MD5Transform(ctx->buf, ctx->in);
-
- byteSwap(ctx->buf, 4);
- memcpy(digest, ctx->buf, 16);
- memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */
- if(0 != ctx->internal_buf) {
- free(ctx->internal_buf);
- ctx->internal_buf = 0;
- ctx->capacity = 0;
- }
- }
-
- /*
- * Convert the incoming audio signal to a byte stream
- */
- static void format_input_(FLAC__byte *buf, const FLAC__int32 * const signal[], unsigned channels, unsigned samples, unsigned bytes_per_sample)
- {
- unsigned channel, sample;
- register FLAC__int32 a_word;
- register FLAC__byte *buf_ = buf;
-
- #if WORDS_BIGENDIAN
- #else
- if(channels == 2 && bytes_per_sample == 2) {
- FLAC__int16 *buf1_ = ((FLAC__int16*)buf_) + 1;
- memcpy(buf_, signal[0], sizeof(FLAC__int32) * samples);
- for(sample = 0; sample < samples; sample++, buf1_+=2)
- *buf1_ = (FLAC__int16)signal[1][sample];
- }
- else if(channels == 1 && bytes_per_sample == 2) {
- FLAC__int16 *buf1_ = (FLAC__int16*)buf_;
- for(sample = 0; sample < samples; sample++)
- *buf1_++ = (FLAC__int16)signal[0][sample];
- }
- else
- #endif
- if(bytes_per_sample == 2) {
- if(channels == 2) {
- for(sample = 0; sample < samples; sample++) {
- a_word = signal[0][sample];
- *buf_++ = (FLAC__byte)a_word; a_word >>= 8;
- *buf_++ = (FLAC__byte)a_word;
- a_word = signal[1][sample];
- *buf_++ = (FLAC__byte)a_word; a_word >>= 8;
- *buf_++ = (FLAC__byte)a_word;
- }
- }
- else if(channels == 1) {
- for(sample = 0; sample < samples; sample++) {
- a_word = signal[0][sample];
- *buf_++ = (FLAC__byte)a_word; a_word >>= 8;
- *buf_++ = (FLAC__byte)a_word;
- }
- }
- else {
- for(sample = 0; sample < samples; sample++) {
- for(channel = 0; channel < channels; channel++) {
- a_word = signal[channel][sample];
- *buf_++ = (FLAC__byte)a_word; a_word >>= 8;
- *buf_++ = (FLAC__byte)a_word;
- }
- }
- }
- }
- else if(bytes_per_sample == 3) {
- if(channels == 2) {
- for(sample = 0; sample < samples; sample++) {
- a_word = signal[0][sample];
- *buf_++ = (FLAC__byte)a_word; a_word >>= 8;
- *buf_++ = (FLAC__byte)a_word; a_word >>= 8;
- *buf_++ = (FLAC__byte)a_word;
- a_word = signal[1][sample];
- *buf_++ = (FLAC__byte)a_word; a_word >>= 8;
- *buf_++ = (FLAC__byte)a_word; a_word >>= 8;
- *buf_++ = (FLAC__byte)a_word;
- }
- }
- else if(channels == 1) {
- for(sample = 0; sample < samples; sample++) {
- a_word = signal[0][sample];
- *buf_++ = (FLAC__byte)a_word; a_word >>= 8;
- *buf_++ = (FLAC__byte)a_word; a_word >>= 8;
- *buf_++ = (FLAC__byte)a_word;
- }
- }
- else {
- for(sample = 0; sample < samples; sample++) {
- for(channel = 0; channel < channels; channel++) {
- a_word = signal[channel][sample];
- *buf_++ = (FLAC__byte)a_word; a_word >>= 8;
- *buf_++ = (FLAC__byte)a_word; a_word >>= 8;
- *buf_++ = (FLAC__byte)a_word;
- }
- }
- }
- }
- else if(bytes_per_sample == 1) {
- if(channels == 2) {
- for(sample = 0; sample < samples; sample++) {
- a_word = signal[0][sample];
- *buf_++ = (FLAC__byte)a_word;
- a_word = signal[1][sample];
- *buf_++ = (FLAC__byte)a_word;
- }
- }
- else if(channels == 1) {
- for(sample = 0; sample < samples; sample++) {
- a_word = signal[0][sample];
- *buf_++ = (FLAC__byte)a_word;
- }
- }
- else {
- for(sample = 0; sample < samples; sample++) {
- for(channel = 0; channel < channels; channel++) {
- a_word = signal[channel][sample];
- *buf_++ = (FLAC__byte)a_word;
- }
- }
- }
- }
- else { /* bytes_per_sample == 4, maybe optimize more later */
- for(sample = 0; sample < samples; sample++) {
- for(channel = 0; channel < channels; channel++) {
- a_word = signal[channel][sample];
- *buf_++ = (FLAC__byte)a_word; a_word >>= 8;
- *buf_++ = (FLAC__byte)a_word; a_word >>= 8;
- *buf_++ = (FLAC__byte)a_word; a_word >>= 8;
- *buf_++ = (FLAC__byte)a_word;
- }
- }
- }
- }
-
- /*
- * Convert the incoming audio signal to a byte stream and FLAC__MD5Update it.
- */
- FLAC__bool FLAC__MD5Accumulate(FLAC__MD5Context *ctx, const FLAC__int32 * const signal[], unsigned channels, unsigned samples, unsigned bytes_per_sample)
- {
- const size_t bytes_needed = (size_t)channels * (size_t)samples * (size_t)bytes_per_sample;
-
- /* overflow check */
- if((size_t)channels > SIZE_MAX / (size_t)bytes_per_sample)
- return false;
- if((size_t)channels * (size_t)bytes_per_sample > SIZE_MAX / (size_t)samples)
- return false;
-
- if(ctx->capacity < bytes_needed) {
- FLAC__byte *tmp = (FLAC__byte*)realloc(ctx->internal_buf, bytes_needed);
- if(0 == tmp) {
- free(ctx->internal_buf);
- if(0 == (ctx->internal_buf = (FLAC__byte*)safe_malloc_(bytes_needed)))
- return false;
- }
- ctx->internal_buf = tmp;
- ctx->capacity = bytes_needed;
- }
-
- format_input_(ctx->internal_buf, signal, channels, samples, bytes_per_sample);
-
- FLAC__MD5Update(ctx, ctx->internal_buf, bytes_needed);
-
- return true;
- }
-
- #endif
- /********* End of inlined file: md5.c *********/
-
- /********* Start of inlined file: memory.c *********/
-
- /********* Start of inlined file: juce_FlacHeader.h *********/
- // This file is included at the start of each FLAC .c file, just to do a few housekeeping
- // tasks..
-
- #define VERSION "1.2.1"
-
- #define FLAC__NO_DLL 1
-
- #ifdef _MSC_VER
- #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4312)
- #endif
-
- #if ! (defined (_WIN32) || defined (_WIN64) || defined (LINUX))
- #define FLAC__SYS_DARWIN 1
- #endif
- /********* End of inlined file: juce_FlacHeader.h *********/
-
- #if JUCE_USE_FLAC
-
- #if HAVE_CONFIG_H
- # include <config.h>
- #endif
-
- /********* Start of inlined file: memory.h *********/
- #ifndef FLAC__PRIVATE__MEMORY_H
- #define FLAC__PRIVATE__MEMORY_H
-
- #ifdef HAVE_CONFIG_H
- #include <config.h>
- #endif
-
- #include <stdlib.h> /* for size_t */
-
- /* Returns the unaligned address returned by malloc.
- * Use free() on this address to deallocate.
- */
- void *FLAC__memory_alloc_aligned(size_t bytes, void **aligned_address);
- FLAC__bool FLAC__memory_alloc_aligned_int32_array(unsigned elements, FLAC__int32 **unaligned_pointer, FLAC__int32 **aligned_pointer);
- FLAC__bool FLAC__memory_alloc_aligned_uint32_array(unsigned elements, FLAC__uint32 **unaligned_pointer, FLAC__uint32 **aligned_pointer);
- FLAC__bool FLAC__memory_alloc_aligned_uint64_array(unsigned elements, FLAC__uint64 **unaligned_pointer, FLAC__uint64 **aligned_pointer);
- FLAC__bool FLAC__memory_alloc_aligned_unsigned_array(unsigned elements, unsigned **unaligned_pointer, unsigned **aligned_pointer);
- #ifndef FLAC__INTEGER_ONLY_LIBRARY
- FLAC__bool FLAC__memory_alloc_aligned_real_array(unsigned elements, FLAC__real **unaligned_pointer, FLAC__real **aligned_pointer);
- #endif
-
- #endif
- /********* End of inlined file: memory.h *********/
-
- void *FLAC__memory_alloc_aligned(size_t bytes, void **aligned_address)
- {
- void *x;
-
- FLAC__ASSERT(0 != aligned_address);
-
- #ifdef FLAC__ALIGN_MALLOC_DATA
- /* align on 32-byte (256-bit) boundary */
- x = safe_malloc_add_2op_(bytes, /*+*/31);
- #ifdef SIZEOF_VOIDP
- #if SIZEOF_VOIDP == 4
- /* could do *aligned_address = x + ((unsigned) (32 - (((unsigned)x) & 31))) & 31; */
- *aligned_address = (void*)(((unsigned)x + 31) & -32);
- #elif SIZEOF_VOIDP == 8
- *aligned_address = (void*)(((FLAC__uint64)x + 31) & (FLAC__uint64)(-((FLAC__int64)32)));
- #else
- # error Unsupported sizeof(void*)
- #endif
- #else
- /* there's got to be a better way to do this right for all archs */
- if(sizeof(void*) == sizeof(unsigned))
- *aligned_address = (void*)(((unsigned)x + 31) & -32);
- else if(sizeof(void*) == sizeof(FLAC__uint64))
- *aligned_address = (void*)(((FLAC__uint64)x + 31) & (FLAC__uint64)(-((FLAC__int64)32)));
- else
- return 0;
- #endif
- #else
- x = safe_malloc_(bytes);
- *aligned_address = x;
- #endif
- return x;
- }
-
- FLAC__bool FLAC__memory_alloc_aligned_int32_array(unsigned elements, FLAC__int32 **unaligned_pointer, FLAC__int32 **aligned_pointer)
- {
- FLAC__int32 *pu; /* unaligned pointer */
- union { /* union needed to comply with C99 pointer aliasing rules */
- FLAC__int32 *pa; /* aligned pointer */
- void *pv; /* aligned pointer alias */
- } u;
-
- FLAC__ASSERT(elements > 0);
- FLAC__ASSERT(0 != unaligned_pointer);
- FLAC__ASSERT(0 != aligned_pointer);
- FLAC__ASSERT(unaligned_pointer != aligned_pointer);
-
- if((size_t)elements > SIZE_MAX / sizeof(*pu)) /* overflow check */
- return false;
-
- pu = (FLAC__int32*)FLAC__memory_alloc_aligned(sizeof(*pu) * (size_t)elements, &u.pv);
- if(0 == pu) {
- return false;
- }
- else {
- if(*unaligned_pointer != 0)
- free(*unaligned_pointer);
- *unaligned_pointer = pu;
- *aligned_pointer = u.pa;
- return true;
- }
- }
-
- FLAC__bool FLAC__memory_alloc_aligned_uint32_array(unsigned elements, FLAC__uint32 **unaligned_pointer, FLAC__uint32 **aligned_pointer)
- {
- FLAC__uint32 *pu; /* unaligned pointer */
- union { /* union needed to comply with C99 pointer aliasing rules */
- FLAC__uint32 *pa; /* aligned pointer */
- void *pv; /* aligned pointer alias */
- } u;
-
- FLAC__ASSERT(elements > 0);
- FLAC__ASSERT(0 != unaligned_pointer);
- FLAC__ASSERT(0 != aligned_pointer);
- FLAC__ASSERT(unaligned_pointer != aligned_pointer);
-
- if((size_t)elements > SIZE_MAX / sizeof(*pu)) /* overflow check */
- return false;
-
- pu = (FLAC__uint32*)FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv);
- if(0 == pu) {
- return false;
- }
- else {
- if(*unaligned_pointer != 0)
- free(*unaligned_pointer);
- *unaligned_pointer = pu;
- *aligned_pointer = u.pa;
- return true;
- }
- }
-
- FLAC__bool FLAC__memory_alloc_aligned_uint64_array(unsigned elements, FLAC__uint64 **unaligned_pointer, FLAC__uint64 **aligned_pointer)
- {
- FLAC__uint64 *pu; /* unaligned pointer */
- union { /* union needed to comply with C99 pointer aliasing rules */
- FLAC__uint64 *pa; /* aligned pointer */
- void *pv; /* aligned pointer alias */
- } u;
-
- FLAC__ASSERT(elements > 0);
- FLAC__ASSERT(0 != unaligned_pointer);
- FLAC__ASSERT(0 != aligned_pointer);
- FLAC__ASSERT(unaligned_pointer != aligned_pointer);
-
- if((size_t)elements > SIZE_MAX / sizeof(*pu)) /* overflow check */
- return false;
-
- pu = (FLAC__uint64*)FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv);
- if(0 == pu) {
- return false;
- }
- else {
- if(*unaligned_pointer != 0)
- free(*unaligned_pointer);
- *unaligned_pointer = pu;
- *aligned_pointer = u.pa;
- return true;
- }
- }
-
- FLAC__bool FLAC__memory_alloc_aligned_unsigned_array(unsigned elements, unsigned **unaligned_pointer, unsigned **aligned_pointer)
- {
- unsigned *pu; /* unaligned pointer */
- union { /* union needed to comply with C99 pointer aliasing rules */
- unsigned *pa; /* aligned pointer */
- void *pv; /* aligned pointer alias */
- } u;
-
- FLAC__ASSERT(elements > 0);
- FLAC__ASSERT(0 != unaligned_pointer);
- FLAC__ASSERT(0 != aligned_pointer);
- FLAC__ASSERT(unaligned_pointer != aligned_pointer);
-
- if((size_t)elements > SIZE_MAX / sizeof(*pu)) /* overflow check */
- return false;
-
- pu = (unsigned*)FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv);
- if(0 == pu) {
- return false;
- }
- else {
- if(*unaligned_pointer != 0)
- free(*unaligned_pointer);
- *unaligned_pointer = pu;
- *aligned_pointer = u.pa;
- return true;
- }
- }
-
- #ifndef FLAC__INTEGER_ONLY_LIBRARY
-
- FLAC__bool FLAC__memory_alloc_aligned_real_array(unsigned elements, FLAC__real **unaligned_pointer, FLAC__real **aligned_pointer)
- {
- FLAC__real *pu; /* unaligned pointer */
- union { /* union needed to comply with C99 pointer aliasing rules */
- FLAC__real *pa; /* aligned pointer */
- void *pv; /* aligned pointer alias */
- } u;
-
- FLAC__ASSERT(elements > 0);
- FLAC__ASSERT(0 != unaligned_pointer);
- FLAC__ASSERT(0 != aligned_pointer);
- FLAC__ASSERT(unaligned_pointer != aligned_pointer);
-
- if((size_t)elements > SIZE_MAX / sizeof(*pu)) /* overflow check */
- return false;
-
- pu = (FLAC__real*)FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv);
- if(0 == pu) {
- return false;
- }
- else {
- if(*unaligned_pointer != 0)
- free(*unaligned_pointer);
- *unaligned_pointer = pu;
- *aligned_pointer = u.pa;
- return true;
- }
- }
-
- #endif
-
- #endif
- /********* End of inlined file: memory.c *********/
-
- /********* Start of inlined file: stream_decoder.c *********/
-
- /********* Start of inlined file: juce_FlacHeader.h *********/
- // This file is included at the start of each FLAC .c file, just to do a few housekeeping
- // tasks..
-
- #define VERSION "1.2.1"
-
- #define FLAC__NO_DLL 1
-
- #ifdef _MSC_VER
- #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4312)
- #endif
-
- #if ! (defined (_WIN32) || defined (_WIN64) || defined (LINUX))
- #define FLAC__SYS_DARWIN 1
- #endif
- /********* End of inlined file: juce_FlacHeader.h *********/
-
- #if JUCE_USE_FLAC
-
- #if HAVE_CONFIG_H
- # include <config.h>
- #endif
-
- #if defined _MSC_VER || defined __MINGW32__
- #include <io.h> /* for _setmode() */
- #include <fcntl.h> /* for _O_BINARY */
- #endif
- #if defined __CYGWIN__ || defined __EMX__
- #include <io.h> /* for setmode(), O_BINARY */
- #include <fcntl.h> /* for _O_BINARY */
- #endif
- #include <stdio.h>
- #include <stdlib.h> /* for malloc() */
- #include <string.h> /* for memset/memcpy() */
- #include <sys/stat.h> /* for stat() */
- #include <sys/types.h> /* for off_t */
- #if defined _MSC_VER || defined __BORLANDC__ || defined __MINGW32__
- #if _MSC_VER <= 1600 || defined __BORLANDC__ /* @@@ [2G limit] */
- #define fseeko fseek
- #define ftello ftell
- #endif
- #endif
-
- /********* Start of inlined file: stream_decoder.h *********/
- #ifndef FLAC__PROTECTED__STREAM_DECODER_H
- #define FLAC__PROTECTED__STREAM_DECODER_H
-
- #if FLAC__HAS_OGG
- #include "include/private/ogg_decoder_aspect.h"
- #endif
-
- typedef struct FLAC__StreamDecoderProtected {
- FLAC__StreamDecoderState state;
- unsigned channels;
- FLAC__ChannelAssignment channel_assignment;
- unsigned bits_per_sample;
- unsigned sample_rate; /* in Hz */
- unsigned blocksize; /* in samples (per channel) */
- FLAC__bool md5_checking; /* if true, generate MD5 signature of decoded data and compare against signature in the STREAMINFO metadata block */
- #if FLAC__HAS_OGG
- FLAC__OggDecoderAspect ogg_decoder_aspect;
- #endif
- } FLAC__StreamDecoderProtected;
-
- /*
- * return the number of input bytes consumed
- */
- unsigned FLAC__stream_decoder_get_input_bytes_unconsumed(const FLAC__StreamDecoder *decoder);
-
- #endif
- /********* End of inlined file: stream_decoder.h *********/
-
- #ifdef max
- #undef max
- #endif
- #define max(a,b) ((a)>(b)?(a):(b))
-
- /* adjust for compilers that can't understand using LLU suffix for uint64_t literals */
- #ifdef _MSC_VER
- #define FLAC__U64L(x) x
- #else
- #define FLAC__U64L(x) x##LLU
- #endif
-
- /* technically this should be in an "export.c" but this is convenient enough */
- FLAC_API int FLAC_API_SUPPORTS_OGG_FLAC =
- #if FLAC__HAS_OGG
- 1
- #else
- 0
- #endif
- ;
-
- /***********************************************************************
- *
- * Private static data
- *
- ***********************************************************************/
-
- static FLAC__byte ID3V2_TAG_[3] = { 'I', 'D', '3' };
-
- /***********************************************************************
- *
- * Private class method prototypes
- *
- ***********************************************************************/
-
- static void set_defaults_dec(FLAC__StreamDecoder *decoder);
- static FILE *get_binary_stdin_(void);
- static FLAC__bool allocate_output_(FLAC__StreamDecoder *decoder, unsigned size, unsigned channels);
- static FLAC__bool has_id_filtered_(FLAC__StreamDecoder *decoder, FLAC__byte *id);
- static FLAC__bool find_metadata_(FLAC__StreamDecoder *decoder);
- static FLAC__bool read_metadata_(FLAC__StreamDecoder *decoder);
- static FLAC__bool read_metadata_streaminfo_(FLAC__StreamDecoder *decoder, FLAC__bool is_last, unsigned length);
- static FLAC__bool read_metadata_seektable_(FLAC__StreamDecoder *decoder, FLAC__bool is_last, unsigned length);
- static FLAC__bool read_metadata_vorbiscomment_(FLAC__StreamDecoder *decoder, FLAC__StreamMetadata_VorbisComment *obj);
- static FLAC__bool read_metadata_cuesheet_(FLAC__StreamDecoder *decoder, FLAC__StreamMetadata_CueSheet *obj);
- static FLAC__bool read_metadata_picture_(FLAC__StreamDecoder *decoder, FLAC__StreamMetadata_Picture *obj);
- static FLAC__bool skip_id3v2_tag_(FLAC__StreamDecoder *decoder);
- static FLAC__bool frame_sync_(FLAC__StreamDecoder *decoder);
- static FLAC__bool read_frame_(FLAC__StreamDecoder *decoder, FLAC__bool *got_a_frame, FLAC__bool do_full_decode);
- static FLAC__bool read_frame_header_(FLAC__StreamDecoder *decoder);
- static FLAC__bool read_subframe_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps, FLAC__bool do_full_decode);
- static FLAC__bool read_subframe_constant_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps, FLAC__bool do_full_decode);
- static FLAC__bool read_subframe_fixed_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps, const unsigned order, FLAC__bool do_full_decode);
- static FLAC__bool read_subframe_lpc_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps, const unsigned order, FLAC__bool do_full_decode);
- static FLAC__bool read_subframe_verbatim_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps, FLAC__bool do_full_decode);
- static FLAC__bool read_residual_partitioned_rice_(FLAC__StreamDecoder *decoder, unsigned predictor_order, unsigned partition_order, FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents, FLAC__int32 *residual, FLAC__bool is_extended);
- static FLAC__bool read_zero_padding_(FLAC__StreamDecoder *decoder);
- static FLAC__bool read_callback_(FLAC__byte buffer[], size_t *bytes, void *client_data);
- #if FLAC__HAS_OGG
- static FLAC__StreamDecoderReadStatus read_callback_ogg_aspect_(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes);
- static FLAC__OggDecoderAspectReadStatus read_callback_proxy_(const void *void_decoder, FLAC__byte buffer[], size_t *bytes, void *client_data);
- #endif
- static FLAC__StreamDecoderWriteStatus write_audio_frame_to_client_(FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[]);
- static void send_error_to_client_(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status);
- static FLAC__bool seek_to_absolute_sample_(FLAC__StreamDecoder *decoder, FLAC__uint64 stream_length, FLAC__uint64 target_sample);
- #if FLAC__HAS_OGG
- static FLAC__bool seek_to_absolute_sample_ogg_(FLAC__StreamDecoder *decoder, FLAC__uint64 stream_length, FLAC__uint64 target_sample);
- #endif
- static FLAC__StreamDecoderReadStatus file_read_callback_dec (const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data);
- static FLAC__StreamDecoderSeekStatus file_seek_callback_dec (const FLAC__StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data);
- static FLAC__StreamDecoderTellStatus file_tell_callback_dec (const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data);
- static FLAC__StreamDecoderLengthStatus file_length_callback_(const FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data);
- static FLAC__bool file_eof_callback_(const FLAC__StreamDecoder *decoder, void *client_data);
-
- /***********************************************************************
- *
- * Private class data
- *
- ***********************************************************************/
-
- typedef struct FLAC__StreamDecoderPrivate {
- #if FLAC__HAS_OGG
- FLAC__bool is_ogg;
- #endif
- FLAC__StreamDecoderReadCallback read_callback;
- FLAC__StreamDecoderSeekCallback seek_callback;
- FLAC__StreamDecoderTellCallback tell_callback;
- FLAC__StreamDecoderLengthCallback length_callback;
- FLAC__StreamDecoderEofCallback eof_callback;
- FLAC__StreamDecoderWriteCallback write_callback;
- FLAC__StreamDecoderMetadataCallback metadata_callback;
- FLAC__StreamDecoderErrorCallback error_callback;
- /* generic 32-bit datapath: */
- void (*local_lpc_restore_signal)(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]);
- /* generic 64-bit datapath: */
- void (*local_lpc_restore_signal_64bit)(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]);
- /* for use when the signal is <= 16 bits-per-sample, or <= 15 bits-per-sample on a side channel (which requires 1 extra bit): */
- void (*local_lpc_restore_signal_16bit)(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]);
- /* for use when the signal is <= 16 bits-per-sample, or <= 15 bits-per-sample on a side channel (which requires 1 extra bit), AND order <= 8: */
- void (*local_lpc_restore_signal_16bit_order8)(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]);
- FLAC__bool (*local_bitreader_read_rice_signed_block)(FLAC__BitReader *br, int* vals, unsigned nvals, unsigned parameter);
- void *client_data;
- FILE *file; /* only used if FLAC__stream_decoder_init_file()/FLAC__stream_decoder_init_file() called, else NULL */
- FLAC__BitReader *input;
- FLAC__int32 *output[FLAC__MAX_CHANNELS];
- FLAC__int32 *residual[FLAC__MAX_CHANNELS]; /* WATCHOUT: these are the aligned pointers; the real pointers that should be free()'d are residual_unaligned[] below */
- FLAC__EntropyCodingMethod_PartitionedRiceContents partitioned_rice_contents[FLAC__MAX_CHANNELS];
- unsigned output_capacity, output_channels;
- FLAC__uint32 fixed_block_size, next_fixed_block_size;
- FLAC__uint64 samples_decoded;
- FLAC__bool has_stream_info, has_seek_table;
- FLAC__StreamMetadata stream_info;
- FLAC__StreamMetadata seek_table;
- FLAC__bool metadata_filter[128]; /* MAGIC number 128 == total number of metadata block types == 1 << 7 */
- FLAC__byte *metadata_filter_ids;
- size_t metadata_filter_ids_count, metadata_filter_ids_capacity; /* units for both are IDs, not bytes */
- FLAC__Frame frame;
- FLAC__bool cached; /* true if there is a byte in lookahead */
- FLAC__CPUInfo cpuinfo;
- FLAC__byte header_warmup[2]; /* contains the sync code and reserved bits */
- FLAC__byte lookahead; /* temp storage when we need to look ahead one byte in the stream */
- /* unaligned (original) pointers to allocated data */
- FLAC__int32 *residual_unaligned[FLAC__MAX_CHANNELS];
- FLAC__bool do_md5_checking; /* initially gets protected_->md5_checking but is turned off after a seek or if the metadata has a zero MD5 */
- FLAC__bool internal_reset_hack; /* used only during init() so we can call reset to set up the decoder without rewinding the input */
- FLAC__bool is_seeking;
- FLAC__MD5Context md5context;
- FLAC__byte computed_md5sum[16]; /* this is the sum we computed from the decoded data */
- /* (the rest of these are only used for seeking) */
- FLAC__Frame last_frame; /* holds the info of the last frame we seeked to */
- FLAC__uint64 first_frame_offset; /* hint to the seek routine of where in the stream the first audio frame starts */
- FLAC__uint64 target_sample;
- unsigned unparseable_frame_count; /* used to tell whether we're decoding a future version of FLAC or just got a bad sync */
- #if FLAC__HAS_OGG
- FLAC__bool got_a_frame; /* hack needed in Ogg FLAC seek routine to check when process_single() actually writes a frame */
- #endif
- } FLAC__StreamDecoderPrivate;
-
- /***********************************************************************
- *
- * Public static class data
- *
- ***********************************************************************/
-
- FLAC_API const char * const FLAC__StreamDecoderStateString[] = {
- "FLAC__STREAM_DECODER_SEARCH_FOR_METADATA",
- "FLAC__STREAM_DECODER_READ_METADATA",
- "FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC",
- "FLAC__STREAM_DECODER_READ_FRAME",
- "FLAC__STREAM_DECODER_END_OF_STREAM",
- "FLAC__STREAM_DECODER_OGG_ERROR",
- "FLAC__STREAM_DECODER_SEEK_ERROR",
- "FLAC__STREAM_DECODER_ABORTED",
- "FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR",
- "FLAC__STREAM_DECODER_UNINITIALIZED"
- };
-
- FLAC_API const char * const FLAC__StreamDecoderInitStatusString[] = {
- "FLAC__STREAM_DECODER_INIT_STATUS_OK",
- "FLAC__STREAM_DECODER_INIT_STATUS_UNSUPPORTED_CONTAINER",
- "FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS",
- "FLAC__STREAM_DECODER_INIT_STATUS_MEMORY_ALLOCATION_ERROR",
- "FLAC__STREAM_DECODER_INIT_STATUS_ERROR_OPENING_FILE",
- "FLAC__STREAM_DECODER_INIT_STATUS_ALREADY_INITIALIZED"
- };
-
- FLAC_API const char * const FLAC__StreamDecoderReadStatusString[] = {
- "FLAC__STREAM_DECODER_READ_STATUS_CONTINUE",
- "FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM",
- "FLAC__STREAM_DECODER_READ_STATUS_ABORT"
- };
-
- FLAC_API const char * const FLAC__StreamDecoderSeekStatusString[] = {
- "FLAC__STREAM_DECODER_SEEK_STATUS_OK",
- "FLAC__STREAM_DECODER_SEEK_STATUS_ERROR",
- "FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED"
- };
-
- FLAC_API const char * const FLAC__StreamDecoderTellStatusString[] = {
- "FLAC__STREAM_DECODER_TELL_STATUS_OK",
- "FLAC__STREAM_DECODER_TELL_STATUS_ERROR",
- "FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED"
- };
-
- FLAC_API const char * const FLAC__StreamDecoderLengthStatusString[] = {
- "FLAC__STREAM_DECODER_LENGTH_STATUS_OK",
- "FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR",
- "FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED"
- };
-
- FLAC_API const char * const FLAC__StreamDecoderWriteStatusString[] = {
- "FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE",
- "FLAC__STREAM_DECODER_WRITE_STATUS_ABORT"
- };
-
- FLAC_API const char * const FLAC__StreamDecoderErrorStatusString[] = {
- "FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC",
- "FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER",
- "FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH",
- "FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM"
- };
-
- /***********************************************************************
- *
- * Class constructor/destructor
- *
- ***********************************************************************/
- FLAC_API FLAC__StreamDecoder *FLAC__stream_decoder_new(void)
- {
- FLAC__StreamDecoder *decoder;
- unsigned i;
-
- FLAC__ASSERT(sizeof(int) >= 4); /* we want to die right away if this is not true */
-
- decoder = (FLAC__StreamDecoder*)calloc(1, sizeof(FLAC__StreamDecoder));
- if(decoder == 0) {
- return 0;
- }
-
- decoder->protected_ = (FLAC__StreamDecoderProtected*)calloc(1, sizeof(FLAC__StreamDecoderProtected));
- if(decoder->protected_ == 0) {
- free(decoder);
- return 0;
- }
-
- decoder->private_ = (FLAC__StreamDecoderPrivate*)calloc(1, sizeof(FLAC__StreamDecoderPrivate));
- if(decoder->private_ == 0) {
- free(decoder->protected_);
- free(decoder);
- return 0;
- }
-
- decoder->private_->input = FLAC__bitreader_new();
- if(decoder->private_->input == 0) {
- free(decoder->private_);
- free(decoder->protected_);
- free(decoder);
- return 0;
- }
-
- decoder->private_->metadata_filter_ids_capacity = 16;
- if(0 == (decoder->private_->metadata_filter_ids = (FLAC__byte*)malloc((FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8) * decoder->private_->metadata_filter_ids_capacity))) {
- FLAC__bitreader_delete(decoder->private_->input);
- free(decoder->private_);
- free(decoder->protected_);
- free(decoder);
- return 0;
- }
-
- for(i = 0; i < FLAC__MAX_CHANNELS; i++) {
- decoder->private_->output[i] = 0;
- decoder->private_->residual_unaligned[i] = decoder->private_->residual[i] = 0;
- }
-
- decoder->private_->output_capacity = 0;
- decoder->private_->output_channels = 0;
- decoder->private_->has_seek_table = false;
-
- for(i = 0; i < FLAC__MAX_CHANNELS; i++)
- FLAC__format_entropy_coding_method_partitioned_rice_contents_init(&decoder->private_->partitioned_rice_contents[i]);
-
- decoder->private_->file = 0;
-
- set_defaults_dec(decoder);
-
- decoder->protected_->state = FLAC__STREAM_DECODER_UNINITIALIZED;
-
- return decoder;
- }
-
- FLAC_API void FLAC__stream_decoder_delete(FLAC__StreamDecoder *decoder)
- {
- unsigned i;
-
- FLAC__ASSERT(0 != decoder);
- FLAC__ASSERT(0 != decoder->protected_);
- FLAC__ASSERT(0 != decoder->private_);
- FLAC__ASSERT(0 != decoder->private_->input);
-
- (void)FLAC__stream_decoder_finish(decoder);
-
- if(0 != decoder->private_->metadata_filter_ids)
- free(decoder->private_->metadata_filter_ids);
-
- FLAC__bitreader_delete(decoder->private_->input);
-
- for(i = 0; i < FLAC__MAX_CHANNELS; i++)
- FLAC__format_entropy_coding_method_partitioned_rice_contents_clear(&decoder->private_->partitioned_rice_contents[i]);
-
- free(decoder->private_);
- free(decoder->protected_);
- free(decoder);
- }
-
- /***********************************************************************
- *
- * Public class methods
- *
- ***********************************************************************/
-
- static FLAC__StreamDecoderInitStatus init_stream_internal_dec(
- FLAC__StreamDecoder *decoder,
- FLAC__StreamDecoderReadCallback read_callback,
- FLAC__StreamDecoderSeekCallback seek_callback,
- FLAC__StreamDecoderTellCallback tell_callback,
- FLAC__StreamDecoderLengthCallback length_callback,
- FLAC__StreamDecoderEofCallback eof_callback,
- FLAC__StreamDecoderWriteCallback write_callback,
- FLAC__StreamDecoderMetadataCallback metadata_callback,
- FLAC__StreamDecoderErrorCallback error_callback,
- void *client_data,
- FLAC__bool is_ogg
- )
- {
- FLAC__ASSERT(0 != decoder);
-
- if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED)
- return FLAC__STREAM_DECODER_INIT_STATUS_ALREADY_INITIALIZED;
-
- #if !FLAC__HAS_OGG
- if(is_ogg)
- return FLAC__STREAM_DECODER_INIT_STATUS_UNSUPPORTED_CONTAINER;
- #endif
-
- if(
- 0 == read_callback ||
- 0 == write_callback ||
- 0 == error_callback ||
- (seek_callback && (0 == tell_callback || 0 == length_callback || 0 == eof_callback))
- )
- return FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS;
-
- #if FLAC__HAS_OGG
- decoder->private_->is_ogg = is_ogg;
- if(is_ogg && !FLAC__ogg_decoder_aspect_init(&decoder->protected_->ogg_decoder_aspect))
- return decoder->protected_->state = FLAC__STREAM_DECODER_OGG_ERROR;
- #endif
-
- /*
- * get the CPU info and set the function pointers
- */
- FLAC__cpu_info(&decoder->private_->cpuinfo);
- /* first default to the non-asm routines */
- decoder->private_->local_lpc_restore_signal = FLAC__lpc_restore_signal;
- decoder->private_->local_lpc_restore_signal_64bit = FLAC__lpc_restore_signal_wide;
- decoder->private_->local_lpc_restore_signal_16bit = FLAC__lpc_restore_signal;
- decoder->private_->local_lpc_restore_signal_16bit_order8 = FLAC__lpc_restore_signal;
- decoder->private_->local_bitreader_read_rice_signed_block = FLAC__bitreader_read_rice_signed_block;
- /* now override with asm where appropriate */
- #ifndef FLAC__NO_ASM
- if(decoder->private_->cpuinfo.use_asm) {
- #ifdef FLAC__CPU_IA32
- FLAC__ASSERT(decoder->private_->cpuinfo.type == FLAC__CPUINFO_TYPE_IA32);
- #ifdef FLAC__HAS_NASM
- #if 1 /*@@@@@@ OPT: not clearly faster, needs more testing */
- if(decoder->private_->cpuinfo.data.ia32.bswap)
- decoder->private_->local_bitreader_read_rice_signed_block = FLAC__bitreader_read_rice_signed_block_asm_ia32_bswap;
- #endif
- if(decoder->private_->cpuinfo.data.ia32.mmx) {
- decoder->private_->local_lpc_restore_signal = FLAC__lpc_restore_signal_asm_ia32;
- decoder->private_->local_lpc_restore_signal_16bit = FLAC__lpc_restore_signal_asm_ia32_mmx;
- decoder->private_->local_lpc_restore_signal_16bit_order8 = FLAC__lpc_restore_signal_asm_ia32_mmx;
- }
- else {
- decoder->private_->local_lpc_restore_signal = FLAC__lpc_restore_signal_asm_ia32;
- decoder->private_->local_lpc_restore_signal_16bit = FLAC__lpc_restore_signal_asm_ia32;
- decoder->private_->local_lpc_restore_signal_16bit_order8 = FLAC__lpc_restore_signal_asm_ia32;
- }
- #endif
- #elif defined FLAC__CPU_PPC
- FLAC__ASSERT(decoder->private_->cpuinfo.type == FLAC__CPUINFO_TYPE_PPC);
- if(decoder->private_->cpuinfo.data.ppc.altivec) {
- decoder->private_->local_lpc_restore_signal_16bit = FLAC__lpc_restore_signal_asm_ppc_altivec_16;
- decoder->private_->local_lpc_restore_signal_16bit_order8 = FLAC__lpc_restore_signal_asm_ppc_altivec_16_order8;
- }
- #endif
- }
- #endif
-
- /* from here on, errors are fatal */
-
- if(!FLAC__bitreader_init(decoder->private_->input, decoder->private_->cpuinfo, read_callback_, decoder)) {
- decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
- return FLAC__STREAM_DECODER_INIT_STATUS_MEMORY_ALLOCATION_ERROR;
- }
-
- decoder->private_->read_callback = read_callback;
- decoder->private_->seek_callback = seek_callback;
- decoder->private_->tell_callback = tell_callback;
- decoder->private_->length_callback = length_callback;
- decoder->private_->eof_callback = eof_callback;
- decoder->private_->write_callback = write_callback;
- decoder->private_->metadata_callback = metadata_callback;
- decoder->private_->error_callback = error_callback;
- decoder->private_->client_data = client_data;
- decoder->private_->fixed_block_size = decoder->private_->next_fixed_block_size = 0;
- decoder->private_->samples_decoded = 0;
- decoder->private_->has_stream_info = false;
- decoder->private_->cached = false;
-
- decoder->private_->do_md5_checking = decoder->protected_->md5_checking;
- decoder->private_->is_seeking = false;
-
- decoder->private_->internal_reset_hack = true; /* so the following reset does not try to rewind the input */
- if(!FLAC__stream_decoder_reset(decoder)) {
- /* above call sets the state for us */
- return FLAC__STREAM_DECODER_INIT_STATUS_MEMORY_ALLOCATION_ERROR;
- }
-
- return FLAC__STREAM_DECODER_INIT_STATUS_OK;
- }
-
- FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_stream(
- FLAC__StreamDecoder *decoder,
- FLAC__StreamDecoderReadCallback read_callback,
- FLAC__StreamDecoderSeekCallback seek_callback,
- FLAC__StreamDecoderTellCallback tell_callback,
- FLAC__StreamDecoderLengthCallback length_callback,
- FLAC__StreamDecoderEofCallback eof_callback,
- FLAC__StreamDecoderWriteCallback write_callback,
- FLAC__StreamDecoderMetadataCallback metadata_callback,
- FLAC__StreamDecoderErrorCallback error_callback,
- void *client_data
- )
- {
- return init_stream_internal_dec(
- decoder,
- read_callback,
- seek_callback,
- tell_callback,
- length_callback,
- eof_callback,
- write_callback,
- metadata_callback,
- error_callback,
- client_data,
- /*is_ogg=*/false
- );
- }
-
- FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_ogg_stream(
- FLAC__StreamDecoder *decoder,
- FLAC__StreamDecoderReadCallback read_callback,
- FLAC__StreamDecoderSeekCallback seek_callback,
- FLAC__StreamDecoderTellCallback tell_callback,
- FLAC__StreamDecoderLengthCallback length_callback,
- FLAC__StreamDecoderEofCallback eof_callback,
- FLAC__StreamDecoderWriteCallback write_callback,
- FLAC__StreamDecoderMetadataCallback metadata_callback,
- FLAC__StreamDecoderErrorCallback error_callback,
- void *client_data
- )
- {
- return init_stream_internal_dec(
- decoder,
- read_callback,
- seek_callback,
- tell_callback,
- length_callback,
- eof_callback,
- write_callback,
- metadata_callback,
- error_callback,
- client_data,
- /*is_ogg=*/true
- );
- }
-
- static FLAC__StreamDecoderInitStatus init_FILE_internal_(
- FLAC__StreamDecoder *decoder,
- FILE *file,
- FLAC__StreamDecoderWriteCallback write_callback,
- FLAC__StreamDecoderMetadataCallback metadata_callback,
- FLAC__StreamDecoderErrorCallback error_callback,
- void *client_data,
- FLAC__bool is_ogg
- )
- {
- FLAC__ASSERT(0 != decoder);
- FLAC__ASSERT(0 != file);
-
- if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED)
- return (FLAC__StreamDecoderInitStatus) (decoder->protected_->state = (FLAC__StreamDecoderState) FLAC__STREAM_DECODER_INIT_STATUS_ALREADY_INITIALIZED);
-
- if(0 == write_callback || 0 == error_callback)
- return (FLAC__StreamDecoderInitStatus) (decoder->protected_->state = (FLAC__StreamDecoderState) FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS);
-
- /*
- * To make sure that our file does not go unclosed after an error, we
- * must assign the FILE pointer before any further error can occur in
- * this routine.
- */
- if(file == stdin)
- file = get_binary_stdin_(); /* just to be safe */
-
- decoder->private_->file = file;
-
- return init_stream_internal_dec(
- decoder,
- file_read_callback_dec,
- decoder->private_->file == stdin? 0: file_seek_callback_dec,
- decoder->private_->file == stdin? 0: file_tell_callback_dec,
- decoder->private_->file == stdin? 0: file_length_callback_,
- file_eof_callback_,
- write_callback,
- metadata_callback,
- error_callback,
- client_data,
- is_ogg
- );
- }
-
- FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_FILE(
- FLAC__StreamDecoder *decoder,
- FILE *file,
- FLAC__StreamDecoderWriteCallback write_callback,
- FLAC__StreamDecoderMetadataCallback metadata_callback,
- FLAC__StreamDecoderErrorCallback error_callback,
- void *client_data
- )
- {
- return init_FILE_internal_(decoder, file, write_callback, metadata_callback, error_callback, client_data, /*is_ogg=*/false);
- }
-
- FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_ogg_FILE(
- FLAC__StreamDecoder *decoder,
- FILE *file,
- FLAC__StreamDecoderWriteCallback write_callback,
- FLAC__StreamDecoderMetadataCallback metadata_callback,
- FLAC__StreamDecoderErrorCallback error_callback,
- void *client_data
- )
- {
- return init_FILE_internal_(decoder, file, write_callback, metadata_callback, error_callback, client_data, /*is_ogg=*/true);
- }
-
- static FLAC__StreamDecoderInitStatus init_file_internal_(
- FLAC__StreamDecoder *decoder,
- const char *filename,
- FLAC__StreamDecoderWriteCallback write_callback,
- FLAC__StreamDecoderMetadataCallback metadata_callback,
- FLAC__StreamDecoderErrorCallback error_callback,
- void *client_data,
- FLAC__bool is_ogg
- )
- {
- FILE *file;
-
- FLAC__ASSERT(0 != decoder);
-
- /*
- * To make sure that our file does not go unclosed after an error, we
- * have to do the same entrance checks here that are later performed
- * in FLAC__stream_decoder_init_FILE() before the FILE* is assigned.
- */
- if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED)
- return (FLAC__StreamDecoderInitStatus) (decoder->protected_->state = (FLAC__StreamDecoderState) FLAC__STREAM_DECODER_INIT_STATUS_ALREADY_INITIALIZED);
-
- if(0 == write_callback || 0 == error_callback)
- return (FLAC__StreamDecoderInitStatus) (decoder->protected_->state = (FLAC__StreamDecoderState) FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS);
-
- file = filename? fopen(filename, "rb") : stdin;
-
- if(0 == file)
- return FLAC__STREAM_DECODER_INIT_STATUS_ERROR_OPENING_FILE;
-
- return init_FILE_internal_(decoder, file, write_callback, metadata_callback, error_callback, client_data, is_ogg);
- }
-
- FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_file(
- FLAC__StreamDecoder *decoder,
- const char *filename,
- FLAC__StreamDecoderWriteCallback write_callback,
- FLAC__StreamDecoderMetadataCallback metadata_callback,
- FLAC__StreamDecoderErrorCallback error_callback,
- void *client_data
- )
- {
- return init_file_internal_(decoder, filename, write_callback, metadata_callback, error_callback, client_data, /*is_ogg=*/false);
- }
-
- FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_ogg_file(
- FLAC__StreamDecoder *decoder,
- const char *filename,
- FLAC__StreamDecoderWriteCallback write_callback,
- FLAC__StreamDecoderMetadataCallback metadata_callback,
- FLAC__StreamDecoderErrorCallback error_callback,
- void *client_data
- )
- {
- return init_file_internal_(decoder, filename, write_callback, metadata_callback, error_callback, client_data, /*is_ogg=*/true);
- }
-
- FLAC_API FLAC__bool FLAC__stream_decoder_finish(FLAC__StreamDecoder *decoder)
- {
- FLAC__bool md5_failed = false;
- unsigned i;
-
- FLAC__ASSERT(0 != decoder);
- FLAC__ASSERT(0 != decoder->private_);
- FLAC__ASSERT(0 != decoder->protected_);
-
- if(decoder->protected_->state == FLAC__STREAM_DECODER_UNINITIALIZED)
- return true;
-
- /* see the comment in FLAC__seekable_stream_decoder_reset() as to why we
- * always call FLAC__MD5Final()
- */
- FLAC__MD5Final(decoder->private_->computed_md5sum, &decoder->private_->md5context);
-
- if(decoder->private_->has_seek_table && 0 != decoder->private_->seek_table.data.seek_table.points) {
- free(decoder->private_->seek_table.data.seek_table.points);
- decoder->private_->seek_table.data.seek_table.points = 0;
- decoder->private_->has_seek_table = false;
- }
- FLAC__bitreader_free(decoder->private_->input);
- for(i = 0; i < FLAC__MAX_CHANNELS; i++) {
- /* WATCHOUT:
- * FLAC__lpc_restore_signal_asm_ia32_mmx() requires that the
- * output arrays have a buffer of up to 3 zeroes in front
- * (at negative indices) for alignment purposes; we use 4
- * to keep the data well-aligned.
- */
- if(0 != decoder->private_->output[i]) {
- free(decoder->private_->output[i]-4);
- decoder->private_->output[i] = 0;
- }
- if(0 != decoder->private_->residual_unaligned[i]) {
- free(decoder->private_->residual_unaligned[i]);
- decoder->private_->residual_unaligned[i] = decoder->private_->residual[i] = 0;
- }
- }
- decoder->private_->output_capacity = 0;
- decoder->private_->output_channels = 0;
-
- #if FLAC__HAS_OGG
- if(decoder->private_->is_ogg)
- FLAC__ogg_decoder_aspect_finish(&decoder->protected_->ogg_decoder_aspect);
- #endif
-
- if(0 != decoder->private_->file) {
- if(decoder->private_->file != stdin)
- fclose(decoder->private_->file);
- decoder->private_->file = 0;
- }
-
- if(decoder->private_->do_md5_checking) {
- if(memcmp(decoder->private_->stream_info.data.stream_info.md5sum, decoder->private_->computed_md5sum, 16))
- md5_failed = true;
- }
- decoder->private_->is_seeking = false;
-
- set_defaults_dec(decoder);
-
- decoder->protected_->state = FLAC__STREAM_DECODER_UNINITIALIZED;
-
- return !md5_failed;
- }
-
- FLAC_API FLAC__bool FLAC__stream_decoder_set_ogg_serial_number(FLAC__StreamDecoder *decoder, long value)
- {
- FLAC__ASSERT(0 != decoder);
- FLAC__ASSERT(0 != decoder->private_);
- FLAC__ASSERT(0 != decoder->protected_);
- if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED)
- return false;
- #if FLAC__HAS_OGG
- /* can't check decoder->private_->is_ogg since that's not set until init time */
- FLAC__ogg_decoder_aspect_set_serial_number(&decoder->protected_->ogg_decoder_aspect, value);
- return true;
- #else
- (void)value;
- return false;
- #endif
- }
-
- FLAC_API FLAC__bool FLAC__stream_decoder_set_md5_checking(FLAC__StreamDecoder *decoder, FLAC__bool value)
- {
- FLAC__ASSERT(0 != decoder);
- FLAC__ASSERT(0 != decoder->protected_);
- if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED)
- return false;
- decoder->protected_->md5_checking = value;
- return true;
- }
-
- FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_respond(FLAC__StreamDecoder *decoder, FLAC__MetadataType type)
- {
- FLAC__ASSERT(0 != decoder);
- FLAC__ASSERT(0 != decoder->private_);
- FLAC__ASSERT(0 != decoder->protected_);
- FLAC__ASSERT((unsigned)type <= FLAC__MAX_METADATA_TYPE_CODE);
- /* double protection */
- if((unsigned)type > FLAC__MAX_METADATA_TYPE_CODE)
- return false;
- if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED)
- return false;
- decoder->private_->metadata_filter[type] = true;
- if(type == FLAC__METADATA_TYPE_APPLICATION)
- decoder->private_->metadata_filter_ids_count = 0;
- return true;
- }
-
- FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_respond_application(FLAC__StreamDecoder *decoder, const FLAC__byte id[4])
- {
- FLAC__ASSERT(0 != decoder);
- FLAC__ASSERT(0 != decoder->private_);
- FLAC__ASSERT(0 != decoder->protected_);
- FLAC__ASSERT(0 != id);
- if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED)
- return false;
-
- if(decoder->private_->metadata_filter[FLAC__METADATA_TYPE_APPLICATION])
- return true;
-
- FLAC__ASSERT(0 != decoder->private_->metadata_filter_ids);
-
- if(decoder->private_->metadata_filter_ids_count == decoder->private_->metadata_filter_ids_capacity) {
- if(0 == (decoder->private_->metadata_filter_ids = (FLAC__byte*)safe_realloc_mul_2op_(decoder->private_->metadata_filter_ids, decoder->private_->metadata_filter_ids_capacity, /*times*/2))) {
- decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
- return false;
- }
- decoder->private_->metadata_filter_ids_capacity *= 2;
- }
-
- memcpy(decoder->private_->metadata_filter_ids + decoder->private_->metadata_filter_ids_count * (FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8), id, (FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8));
- decoder->private_->metadata_filter_ids_count++;
-
- return true;
- }
-
- FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_respond_all(FLAC__StreamDecoder *decoder)
- {
- unsigned i;
- FLAC__ASSERT(0 != decoder);
- FLAC__ASSERT(0 != decoder->private_);
- FLAC__ASSERT(0 != decoder->protected_);
- if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED)
- return false;
- for(i = 0; i < sizeof(decoder->private_->metadata_filter) / sizeof(decoder->private_->metadata_filter[0]); i++)
- decoder->private_->metadata_filter[i] = true;
- decoder->private_->metadata_filter_ids_count = 0;
- return true;
- }
-
- FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_ignore(FLAC__StreamDecoder *decoder, FLAC__MetadataType type)
- {
- FLAC__ASSERT(0 != decoder);
- FLAC__ASSERT(0 != decoder->private_);
- FLAC__ASSERT(0 != decoder->protected_);
- FLAC__ASSERT((unsigned)type <= FLAC__MAX_METADATA_TYPE_CODE);
- /* double protection */
- if((unsigned)type > FLAC__MAX_METADATA_TYPE_CODE)
- return false;
- if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED)
- return false;
- decoder->private_->metadata_filter[type] = false;
- if(type == FLAC__METADATA_TYPE_APPLICATION)
- decoder->private_->metadata_filter_ids_count = 0;
- return true;
- }
-
- FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_ignore_application(FLAC__StreamDecoder *decoder, const FLAC__byte id[4])
- {
- FLAC__ASSERT(0 != decoder);
- FLAC__ASSERT(0 != decoder->private_);
- FLAC__ASSERT(0 != decoder->protected_);
- FLAC__ASSERT(0 != id);
- if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED)
- return false;
-
- if(!decoder->private_->metadata_filter[FLAC__METADATA_TYPE_APPLICATION])
- return true;
-
- FLAC__ASSERT(0 != decoder->private_->metadata_filter_ids);
-
- if(decoder->private_->metadata_filter_ids_count == decoder->private_->metadata_filter_ids_capacity) {
- if(0 == (decoder->private_->metadata_filter_ids = (FLAC__byte*)safe_realloc_mul_2op_(decoder->private_->metadata_filter_ids, decoder->private_->metadata_filter_ids_capacity, /*times*/2))) {
- decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
- return false;
- }
- decoder->private_->metadata_filter_ids_capacity *= 2;
- }
-
- memcpy(decoder->private_->metadata_filter_ids + decoder->private_->metadata_filter_ids_count * (FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8), id, (FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8));
- decoder->private_->metadata_filter_ids_count++;
-
- return true;
- }
-
- FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_ignore_all(FLAC__StreamDecoder *decoder)
- {
- FLAC__ASSERT(0 != decoder);
- FLAC__ASSERT(0 != decoder->private_);
- FLAC__ASSERT(0 != decoder->protected_);
- if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED)
- return false;
- memset(decoder->private_->metadata_filter, 0, sizeof(decoder->private_->metadata_filter));
- decoder->private_->metadata_filter_ids_count = 0;
- return true;
- }
-
- FLAC_API FLAC__StreamDecoderState FLAC__stream_decoder_get_state(const FLAC__StreamDecoder *decoder)
- {
- FLAC__ASSERT(0 != decoder);
- FLAC__ASSERT(0 != decoder->protected_);
- return decoder->protected_->state;
- }
-
- FLAC_API const char *FLAC__stream_decoder_get_resolved_state_string(const FLAC__StreamDecoder *decoder)
- {
- return FLAC__StreamDecoderStateString[decoder->protected_->state];
- }
-
- FLAC_API FLAC__bool FLAC__stream_decoder_get_md5_checking(const FLAC__StreamDecoder *decoder)
- {
- FLAC__ASSERT(0 != decoder);
- FLAC__ASSERT(0 != decoder->protected_);
- return decoder->protected_->md5_checking;
- }
-
- FLAC_API FLAC__uint64 FLAC__stream_decoder_get_total_samples(const FLAC__StreamDecoder *decoder)
- {
- FLAC__ASSERT(0 != decoder);
- FLAC__ASSERT(0 != decoder->protected_);
- return decoder->private_->has_stream_info? decoder->private_->stream_info.data.stream_info.total_samples : 0;
- }
-
- FLAC_API unsigned FLAC__stream_decoder_get_channels(const FLAC__StreamDecoder *decoder)
- {
- FLAC__ASSERT(0 != decoder);
- FLAC__ASSERT(0 != decoder->protected_);
- return decoder->protected_->channels;
- }
-
- FLAC_API FLAC__ChannelAssignment FLAC__stream_decoder_get_channel_assignment(const FLAC__StreamDecoder *decoder)
- {
- FLAC__ASSERT(0 != decoder);
- FLAC__ASSERT(0 != decoder->protected_);
- return decoder->protected_->channel_assignment;
- }
-
- FLAC_API unsigned FLAC__stream_decoder_get_bits_per_sample(const FLAC__StreamDecoder *decoder)
- {
- FLAC__ASSERT(0 != decoder);
- FLAC__ASSERT(0 != decoder->protected_);
- return decoder->protected_->bits_per_sample;
- }
-
- FLAC_API unsigned FLAC__stream_decoder_get_sample_rate(const FLAC__StreamDecoder *decoder)
- {
- FLAC__ASSERT(0 != decoder);
- FLAC__ASSERT(0 != decoder->protected_);
- return decoder->protected_->sample_rate;
- }
-
- FLAC_API unsigned FLAC__stream_decoder_get_blocksize(const FLAC__StreamDecoder *decoder)
- {
- FLAC__ASSERT(0 != decoder);
- FLAC__ASSERT(0 != decoder->protected_);
- return decoder->protected_->blocksize;
- }
-
- FLAC_API FLAC__bool FLAC__stream_decoder_get_decode_position(const FLAC__StreamDecoder *decoder, FLAC__uint64 *position)
- {
- FLAC__ASSERT(0 != decoder);
- FLAC__ASSERT(0 != decoder->private_);
- FLAC__ASSERT(0 != position);
-
- #if FLAC__HAS_OGG
- if(decoder->private_->is_ogg)
- return false;
- #endif
- if(0 == decoder->private_->tell_callback)
- return false;
- if(decoder->private_->tell_callback(decoder, position, decoder->private_->client_data) != FLAC__STREAM_DECODER_TELL_STATUS_OK)
- return false;
- /* should never happen since all FLAC frames and metadata blocks are byte aligned, but check just in case */
- if(!FLAC__bitreader_is_consumed_byte_aligned(decoder->private_->input))
- return false;
- FLAC__ASSERT(*position >= FLAC__stream_decoder_get_input_bytes_unconsumed(decoder));
- *position -= FLAC__stream_decoder_get_input_bytes_unconsumed(decoder);
- return true;
- }
-
- FLAC_API FLAC__bool FLAC__stream_decoder_flush(FLAC__StreamDecoder *decoder)
- {
- FLAC__ASSERT(0 != decoder);
- FLAC__ASSERT(0 != decoder->private_);
- FLAC__ASSERT(0 != decoder->protected_);
-
- decoder->private_->samples_decoded = 0;
- decoder->private_->do_md5_checking = false;
-
- #if FLAC__HAS_OGG
- if(decoder->private_->is_ogg)
- FLAC__ogg_decoder_aspect_flush(&decoder->protected_->ogg_decoder_aspect);
- #endif
-
- if(!FLAC__bitreader_clear(decoder->private_->input)) {
- decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
- return false;
- }
- decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
-
- return true;
- }
-
- FLAC_API FLAC__bool FLAC__stream_decoder_reset(FLAC__StreamDecoder *decoder)
- {
- FLAC__ASSERT(0 != decoder);
- FLAC__ASSERT(0 != decoder->private_);
- FLAC__ASSERT(0 != decoder->protected_);
-
- if(!FLAC__stream_decoder_flush(decoder)) {
- /* above call sets the state for us */
- return false;
- }
-
- #if FLAC__HAS_OGG
- /*@@@ could go in !internal_reset_hack block below */
- if(decoder->private_->is_ogg)
- FLAC__ogg_decoder_aspect_reset(&decoder->protected_->ogg_decoder_aspect);
- #endif
-
- /* Rewind if necessary. If FLAC__stream_decoder_init() is calling us,
- * (internal_reset_hack) don't try to rewind since we are already at
- * the beginning of the stream and don't want to fail if the input is
- * not seekable.
- */
- if(!decoder->private_->internal_reset_hack) {
- if(decoder->private_->file == stdin)
- return false; /* can't rewind stdin, reset fails */
- if(decoder->private_->seek_callback && decoder->private_->seek_callback(decoder, 0, decoder->private_->client_data) == FLAC__STREAM_DECODER_SEEK_STATUS_ERROR)
- return false; /* seekable and seek fails, reset fails */
- }
- else
- decoder->private_->internal_reset_hack = false;
-
- decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_METADATA;
-
- decoder->private_->has_stream_info = false;
- if(decoder->private_->has_seek_table && 0 != decoder->private_->seek_table.data.seek_table.points) {
- free(decoder->private_->seek_table.data.seek_table.points);
- decoder->private_->seek_table.data.seek_table.points = 0;
- decoder->private_->has_seek_table = false;
- }
- decoder->private_->do_md5_checking = decoder->protected_->md5_checking;
- /*
- * This goes in reset() and not flush() because according to the spec, a
- * fixed-blocksize stream must stay that way through the whole stream.
- */
- decoder->private_->fixed_block_size = decoder->private_->next_fixed_block_size = 0;
-
- /* We initialize the FLAC__MD5Context even though we may never use it. This
- * is because md5 checking may be turned on to start and then turned off if
- * a seek occurs. So we init the context here and finalize it in
- * FLAC__stream_decoder_finish() to make sure things are always cleaned up
- * properly.
- */
- FLAC__MD5Init(&decoder->private_->md5context);
-
- decoder->private_->first_frame_offset = 0;
- decoder->private_->unparseable_frame_count = 0;
-
- return true;
- }
-
- FLAC_API FLAC__bool FLAC__stream_decoder_process_single(FLAC__StreamDecoder *decoder)
- {
- FLAC__bool got_a_frame;
- FLAC__ASSERT(0 != decoder);
- FLAC__ASSERT(0 != decoder->protected_);
-
- while(1) {
- switch(decoder->protected_->state) {
- case FLAC__STREAM_DECODER_SEARCH_FOR_METADATA:
- if(!find_metadata_(decoder))
- return false; /* above function sets the status for us */
- break;
- case FLAC__STREAM_DECODER_READ_METADATA:
- if(!read_metadata_(decoder))
- return false; /* above function sets the status for us */
- else
- return true;
- case FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC:
- if(!frame_sync_(decoder))
- return true; /* above function sets the status for us */
- break;
- case FLAC__STREAM_DECODER_READ_FRAME:
- if(!read_frame_(decoder, &got_a_frame, /*do_full_decode=*/true))
- return false; /* above function sets the status for us */
- if(got_a_frame)
- return true; /* above function sets the status for us */
- break;
- case FLAC__STREAM_DECODER_END_OF_STREAM:
- case FLAC__STREAM_DECODER_ABORTED:
- return true;
- default:
- FLAC__ASSERT(0);
- return false;
- }
- }
- }
-
- FLAC_API FLAC__bool FLAC__stream_decoder_process_until_end_of_metadata(FLAC__StreamDecoder *decoder)
- {
- FLAC__ASSERT(0 != decoder);
- FLAC__ASSERT(0 != decoder->protected_);
-
- while(1) {
- switch(decoder->protected_->state) {
- case FLAC__STREAM_DECODER_SEARCH_FOR_METADATA:
- if(!find_metadata_(decoder))
- return false; /* above function sets the status for us */
- break;
- case FLAC__STREAM_DECODER_READ_METADATA:
- if(!read_metadata_(decoder))
- return false; /* above function sets the status for us */
- break;
- case FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC:
- case FLAC__STREAM_DECODER_READ_FRAME:
- case FLAC__STREAM_DECODER_END_OF_STREAM:
- case FLAC__STREAM_DECODER_ABORTED:
- return true;
- default:
- FLAC__ASSERT(0);
- return false;
- }
- }
- }
-
- FLAC_API FLAC__bool FLAC__stream_decoder_process_until_end_of_stream(FLAC__StreamDecoder *decoder)
- {
- FLAC__bool dummy;
- FLAC__ASSERT(0 != decoder);
- FLAC__ASSERT(0 != decoder->protected_);
-
- while(1) {
- switch(decoder->protected_->state) {
- case FLAC__STREAM_DECODER_SEARCH_FOR_METADATA:
- if(!find_metadata_(decoder))
- return false; /* above function sets the status for us */
- break;
- case FLAC__STREAM_DECODER_READ_METADATA:
- if(!read_metadata_(decoder))
- return false; /* above function sets the status for us */
- break;
- case FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC:
- if(!frame_sync_(decoder))
- return true; /* above function sets the status for us */
- break;
- case FLAC__STREAM_DECODER_READ_FRAME:
- if(!read_frame_(decoder, &dummy, /*do_full_decode=*/true))
- return false; /* above function sets the status for us */
- break;
- case FLAC__STREAM_DECODER_END_OF_STREAM:
- case FLAC__STREAM_DECODER_ABORTED:
- return true;
- default:
- FLAC__ASSERT(0);
- return false;
- }
- }
- }
-
- FLAC_API FLAC__bool FLAC__stream_decoder_skip_single_frame(FLAC__StreamDecoder *decoder)
- {
- FLAC__bool got_a_frame;
- FLAC__ASSERT(0 != decoder);
- FLAC__ASSERT(0 != decoder->protected_);
-
- while(1) {
- switch(decoder->protected_->state) {
- case FLAC__STREAM_DECODER_SEARCH_FOR_METADATA:
- case FLAC__STREAM_DECODER_READ_METADATA:
- return false; /* above function sets the status for us */
- case FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC:
- if(!frame_sync_(decoder))
- return true; /* above function sets the status for us */
- break;
- case FLAC__STREAM_DECODER_READ_FRAME:
- if(!read_frame_(decoder, &got_a_frame, /*do_full_decode=*/false))
- return false; /* above function sets the status for us */
- if(got_a_frame)
- return true; /* above function sets the status for us */
- break;
- case FLAC__STREAM_DECODER_END_OF_STREAM:
- case FLAC__STREAM_DECODER_ABORTED:
- return true;
- default:
- FLAC__ASSERT(0);
- return false;
- }
- }
- }
-
- FLAC_API FLAC__bool FLAC__stream_decoder_seek_absolute(FLAC__StreamDecoder *decoder, FLAC__uint64 sample)
- {
- FLAC__uint64 length;
-
- FLAC__ASSERT(0 != decoder);
-
- if(
- decoder->protected_->state != FLAC__STREAM_DECODER_SEARCH_FOR_METADATA &&
- decoder->protected_->state != FLAC__STREAM_DECODER_READ_METADATA &&
- decoder->protected_->state != FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC &&
- decoder->protected_->state != FLAC__STREAM_DECODER_READ_FRAME &&
- decoder->protected_->state != FLAC__STREAM_DECODER_END_OF_STREAM
- )
- return false;
-
- if(0 == decoder->private_->seek_callback)
- return false;
-
- FLAC__ASSERT(decoder->private_->seek_callback);
- FLAC__ASSERT(decoder->private_->tell_callback);
- FLAC__ASSERT(decoder->private_->length_callback);
- FLAC__ASSERT(decoder->private_->eof_callback);
-
- if(FLAC__stream_decoder_get_total_samples(decoder) > 0 && sample >= FLAC__stream_decoder_get_total_samples(decoder))
- return false;
-
- decoder->private_->is_seeking = true;
-
- /* turn off md5 checking if a seek is attempted */
- decoder->private_->do_md5_checking = false;
-
- /* get the file length (currently our algorithm needs to know the length so it's also an error to get FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED) */
- if(decoder->private_->length_callback(decoder, &length, decoder->private_->client_data) != FLAC__STREAM_DECODER_LENGTH_STATUS_OK) {
- decoder->private_->is_seeking = false;
- return false;
- }
-
- /* if we haven't finished processing the metadata yet, do that so we have the STREAMINFO, SEEK_TABLE, and first_frame_offset */
- if(
- decoder->protected_->state == FLAC__STREAM_DECODER_SEARCH_FOR_METADATA ||
- decoder->protected_->state == FLAC__STREAM_DECODER_READ_METADATA
- ) {
- if(!FLAC__stream_decoder_process_until_end_of_metadata(decoder)) {
- /* above call sets the state for us */
- decoder->private_->is_seeking = false;
- return false;
- }
- /* check this again in case we didn't know total_samples the first time */
- if(FLAC__stream_decoder_get_total_samples(decoder) > 0 && sample >= FLAC__stream_decoder_get_total_samples(decoder)) {
- decoder->private_->is_seeking = false;
- return false;
- }
- }
-
- {
- const FLAC__bool ok =
- #if FLAC__HAS_OGG
- decoder->private_->is_ogg?
- seek_to_absolute_sample_ogg_(decoder, length, sample) :
- #endif
- seek_to_absolute_sample_(decoder, length, sample)
- ;
- decoder->private_->is_seeking = false;
- return ok;
- }
- }
-
- /***********************************************************************
- *
- * Protected class methods
- *
- ***********************************************************************/
-
- unsigned FLAC__stream_decoder_get_input_bytes_unconsumed(const FLAC__StreamDecoder *decoder)
- {
- FLAC__ASSERT(0 != decoder);
- FLAC__ASSERT(FLAC__bitreader_is_consumed_byte_aligned(decoder->private_->input));
- FLAC__ASSERT(!(FLAC__bitreader_get_input_bits_unconsumed(decoder->private_->input) & 7));
- return FLAC__bitreader_get_input_bits_unconsumed(decoder->private_->input) / 8;
- }
-
- /***********************************************************************
- *
- * Private class methods
- *
- ***********************************************************************/
-
- void set_defaults_dec(FLAC__StreamDecoder *decoder)
- {
- #if FLAC__HAS_OGG
- decoder->private_->is_ogg = false;
- #endif
- decoder->private_->read_callback = 0;
- decoder->private_->seek_callback = 0;
- decoder->private_->tell_callback = 0;
- decoder->private_->length_callback = 0;
- decoder->private_->eof_callback = 0;
- decoder->private_->write_callback = 0;
- decoder->private_->metadata_callback = 0;
- decoder->private_->error_callback = 0;
- decoder->private_->client_data = 0;
-
- memset(decoder->private_->metadata_filter, 0, sizeof(decoder->private_->metadata_filter));
- decoder->private_->metadata_filter[FLAC__METADATA_TYPE_STREAMINFO] = true;
- decoder->private_->metadata_filter_ids_count = 0;
-
- decoder->protected_->md5_checking = false;
-
- #if FLAC__HAS_OGG
- FLAC__ogg_decoder_aspect_set_defaults(&decoder->protected_->ogg_decoder_aspect);
- #endif
- }
-
- /*
- * This will forcibly set stdin to binary mode (for OSes that require it)
- */
- FILE *get_binary_stdin_(void)
- {
- /* if something breaks here it is probably due to the presence or
- * absence of an underscore before the identifiers 'setmode',
- * 'fileno', and/or 'O_BINARY'; check your system header files.
- */
- #if defined _MSC_VER || defined __MINGW32__
- _setmode(_fileno(stdin), _O_BINARY);
- #elif defined __CYGWIN__
- /* almost certainly not needed for any modern Cygwin, but let's be safe... */
- setmode(_fileno(stdin), _O_BINARY);
- #elif defined __EMX__
- setmode(fileno(stdin), O_BINARY);
- #endif
-
- return stdin;
- }
-
- FLAC__bool allocate_output_(FLAC__StreamDecoder *decoder, unsigned size, unsigned channels)
- {
- unsigned i;
- FLAC__int32 *tmp;
-
- if(size <= decoder->private_->output_capacity && channels <= decoder->private_->output_channels)
- return true;
-
- /* simply using realloc() is not practical because the number of channels may change mid-stream */
-
- for(i = 0; i < FLAC__MAX_CHANNELS; i++) {
- if(0 != decoder->private_->output[i]) {
- free(decoder->private_->output[i]-4);
- decoder->private_->output[i] = 0;
- }
- if(0 != decoder->private_->residual_unaligned[i]) {
- free(decoder->private_->residual_unaligned[i]);
- decoder->private_->residual_unaligned[i] = decoder->private_->residual[i] = 0;
- }
- }
-
- for(i = 0; i < channels; i++) {
- /* WATCHOUT:
- * FLAC__lpc_restore_signal_asm_ia32_mmx() requires that the
- * output arrays have a buffer of up to 3 zeroes in front
- * (at negative indices) for alignment purposes; we use 4
- * to keep the data well-aligned.
- */
- tmp = (FLAC__int32*)safe_malloc_muladd2_(sizeof(FLAC__int32), /*times (*/size, /*+*/4/*)*/);
- if(tmp == 0) {
- decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
- return false;
- }
- memset(tmp, 0, sizeof(FLAC__int32)*4);
- decoder->private_->output[i] = tmp + 4;
-
- /* WATCHOUT:
- * minimum of quadword alignment for PPC vector optimizations is REQUIRED:
- */
- if(!FLAC__memory_alloc_aligned_int32_array(size, &decoder->private_->residual_unaligned[i], &decoder->private_->residual[i])) {
- decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
- return false;
- }
- }
-
- decoder->private_->output_capacity = size;
- decoder->private_->output_channels = channels;
-
- return true;
- }
-
- FLAC__bool has_id_filtered_(FLAC__StreamDecoder *decoder, FLAC__byte *id)
- {
- size_t i;
-
- FLAC__ASSERT(0 != decoder);
- FLAC__ASSERT(0 != decoder->private_);
-
- for(i = 0; i < decoder->private_->metadata_filter_ids_count; i++)
- if(0 == memcmp(decoder->private_->metadata_filter_ids + i * (FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8), id, (FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8)))
- return true;
-
- return false;
- }
-
- FLAC__bool find_metadata_(FLAC__StreamDecoder *decoder)
- {
- FLAC__uint32 x;
- unsigned i, id_;
- FLAC__bool first = true;
-
- FLAC__ASSERT(FLAC__bitreader_is_consumed_byte_aligned(decoder->private_->input));
-
- for(i = id_ = 0; i < 4; ) {
- if(decoder->private_->cached) {
- x = (FLAC__uint32)decoder->private_->lookahead;
- decoder->private_->cached = false;
- }
- else {
- if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, 8))
- return false; /* read_callback_ sets the state for us */
- }
- if(x == FLAC__STREAM_SYNC_STRING[i]) {
- first = true;
- i++;
- id_ = 0;
- continue;
- }
- if(x == ID3V2_TAG_[id_]) {
- id_++;
- i = 0;
- if(id_ == 3) {
- if(!skip_id3v2_tag_(decoder))
- return false; /* skip_id3v2_tag_ sets the state for us */
- }
- continue;
- }
- id_ = 0;
- if(x == 0xff) { /* MAGIC NUMBER for the first 8 frame sync bits */
- decoder->private_->header_warmup[0] = (FLAC__byte)x;
- if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, 8))
- return false; /* read_callback_ sets the state for us */
-
- /* we have to check if we just read two 0xff's in a row; the second may actually be the beginning of the sync code */
- /* else we have to check if the second byte is the end of a sync code */
- if(x == 0xff) { /* MAGIC NUMBER for the first 8 frame sync bits */
- decoder->private_->lookahead = (FLAC__byte)x;
- decoder->private_->cached = true;
- }
- else if(x >> 2 == 0x3e) { /* MAGIC NUMBER for the last 6 sync bits */
- decoder->private_->header_warmup[1] = (FLAC__byte)x;
- decoder->protected_->state = FLAC__STREAM_DECODER_READ_FRAME;
- return true;
- }
- }
- i = 0;
- if(first) {
- send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC);
- first = false;
- }
- }
-
- decoder->protected_->state = FLAC__STREAM_DECODER_READ_METADATA;
- return true;
- }
-
- FLAC__bool read_metadata_(FLAC__StreamDecoder *decoder)
- {
- FLAC__bool is_last;
- FLAC__uint32 i, x, type, length;
-
- FLAC__ASSERT(FLAC__bitreader_is_consumed_byte_aligned(decoder->private_->input));
-
- if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_IS_LAST_LEN))
- return false; /* read_callback_ sets the state for us */
- is_last = x? true : false;
-
- if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &type, FLAC__STREAM_METADATA_TYPE_LEN))
- return false; /* read_callback_ sets the state for us */
-
- if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &length, FLAC__STREAM_METADATA_LENGTH_LEN))
- return false; /* read_callback_ sets the state for us */
-
- if(type == FLAC__METADATA_TYPE_STREAMINFO) {
- if(!read_metadata_streaminfo_(decoder, is_last, length))
- return false;
-
- decoder->private_->has_stream_info = true;
- if(0 == memcmp(decoder->private_->stream_info.data.stream_info.md5sum, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 16))
- decoder->private_->do_md5_checking = false;
- if(!decoder->private_->is_seeking && decoder->private_->metadata_filter[FLAC__METADATA_TYPE_STREAMINFO] && decoder->private_->metadata_callback)
- decoder->private_->metadata_callback(decoder, &decoder->private_->stream_info, decoder->private_->client_data);
- }
- else if(type == FLAC__METADATA_TYPE_SEEKTABLE) {
- if(!read_metadata_seektable_(decoder, is_last, length))
- return false;
-
- decoder->private_->has_seek_table = true;
- if(!decoder->private_->is_seeking && decoder->private_->metadata_filter[FLAC__METADATA_TYPE_SEEKTABLE] && decoder->private_->metadata_callback)
- decoder->private_->metadata_callback(decoder, &decoder->private_->seek_table, decoder->private_->client_data);
- }
- else {
- FLAC__bool skip_it = !decoder->private_->metadata_filter[type];
- unsigned real_length = length;
- FLAC__StreamMetadata block;
-
- block.is_last = is_last;
- block.type = (FLAC__MetadataType)type;
- block.length = length;
-
- if(type == FLAC__METADATA_TYPE_APPLICATION) {
- if(!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, block.data.application.id, FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8))
- return false; /* read_callback_ sets the state for us */
-
- if(real_length < FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8) { /* underflow check */
- decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;/*@@@@@@ maybe wrong error? need to resync?*/
- return false;
- }
-
- real_length -= FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8;
-
- if(decoder->private_->metadata_filter_ids_count > 0 && has_id_filtered_(decoder, block.data.application.id))
- skip_it = !skip_it;
- }
-
- if(skip_it) {
- if(!FLAC__bitreader_skip_byte_block_aligned_no_crc(decoder->private_->input, real_length))
- return false; /* read_callback_ sets the state for us */
- }
- else {
- switch(type) {
- case FLAC__METADATA_TYPE_PADDING:
- /* skip the padding bytes */
- if(!FLAC__bitreader_skip_byte_block_aligned_no_crc(decoder->private_->input, real_length))
- return false; /* read_callback_ sets the state for us */
- break;
- case FLAC__METADATA_TYPE_APPLICATION:
- /* remember, we read the ID already */
- if(real_length > 0) {
- if(0 == (block.data.application.data = (FLAC__byte*)malloc(real_length))) {
- decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
- return false;
- }
- if(!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, block.data.application.data, real_length))
- return false; /* read_callback_ sets the state for us */
- }
- else
- block.data.application.data = 0;
- break;
- case FLAC__METADATA_TYPE_VORBIS_COMMENT:
- if(!read_metadata_vorbiscomment_(decoder, &block.data.vorbis_comment))
- return false;
- break;
- case FLAC__METADATA_TYPE_CUESHEET:
- if(!read_metadata_cuesheet_(decoder, &block.data.cue_sheet))
- return false;
- break;
- case FLAC__METADATA_TYPE_PICTURE:
- if(!read_metadata_picture_(decoder, &block.data.picture))
- return false;
- break;
- case FLAC__METADATA_TYPE_STREAMINFO:
- case FLAC__METADATA_TYPE_SEEKTABLE:
- FLAC__ASSERT(0);
- break;
- default:
- if(real_length > 0) {
- if(0 == (block.data.unknown.data = (FLAC__byte*)malloc(real_length))) {
- decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
- return false;
- }
- if(!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, block.data.unknown.data, real_length))
- return false; /* read_callback_ sets the state for us */
- }
- else
- block.data.unknown.data = 0;
- break;
- }
- if(!decoder->private_->is_seeking && decoder->private_->metadata_callback)
- decoder->private_->metadata_callback(decoder, &block, decoder->private_->client_data);
-
- /* now we have to free any malloc()ed data in the block */
- switch(type) {
- case FLAC__METADATA_TYPE_PADDING:
- break;
- case FLAC__METADATA_TYPE_APPLICATION:
- if(0 != block.data.application.data)
- free(block.data.application.data);
- break;
- case FLAC__METADATA_TYPE_VORBIS_COMMENT:
- if(0 != block.data.vorbis_comment.vendor_string.entry)
- free(block.data.vorbis_comment.vendor_string.entry);
- if(block.data.vorbis_comment.num_comments > 0)
- for(i = 0; i < block.data.vorbis_comment.num_comments; i++)
- if(0 != block.data.vorbis_comment.comments[i].entry)
- free(block.data.vorbis_comment.comments[i].entry);
- if(0 != block.data.vorbis_comment.comments)
- free(block.data.vorbis_comment.comments);
- break;
- case FLAC__METADATA_TYPE_CUESHEET:
- if(block.data.cue_sheet.num_tracks > 0)
- for(i = 0; i < block.data.cue_sheet.num_tracks; i++)
- if(0 != block.data.cue_sheet.tracks[i].indices)
- free(block.data.cue_sheet.tracks[i].indices);
- if(0 != block.data.cue_sheet.tracks)
- free(block.data.cue_sheet.tracks);
- break;
- case FLAC__METADATA_TYPE_PICTURE:
- if(0 != block.data.picture.mime_type)
- free(block.data.picture.mime_type);
- if(0 != block.data.picture.description)
- free(block.data.picture.description);
- if(0 != block.data.picture.data)
- free(block.data.picture.data);
- break;
- case FLAC__METADATA_TYPE_STREAMINFO:
- case FLAC__METADATA_TYPE_SEEKTABLE:
- FLAC__ASSERT(0);
- default:
- if(0 != block.data.unknown.data)
- free(block.data.unknown.data);
- break;
- }
- }
- }
-
- if(is_last) {
- /* if this fails, it's OK, it's just a hint for the seek routine */
- if(!FLAC__stream_decoder_get_decode_position(decoder, &decoder->private_->first_frame_offset))
- decoder->private_->first_frame_offset = 0;
- decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
- }
-
- return true;
- }
-
- FLAC__bool read_metadata_streaminfo_(FLAC__StreamDecoder *decoder, FLAC__bool is_last, unsigned length)
- {
- FLAC__uint32 x;
- unsigned bits, used_bits = 0;
-
- FLAC__ASSERT(FLAC__bitreader_is_consumed_byte_aligned(decoder->private_->input));
-
- decoder->private_->stream_info.type = FLAC__METADATA_TYPE_STREAMINFO;
- decoder->private_->stream_info.is_last = is_last;
- decoder->private_->stream_info.length = length;
-
- bits = FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN;
- if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, bits))
- return false; /* read_callback_ sets the state for us */
- decoder->private_->stream_info.data.stream_info.min_blocksize = x;
- used_bits += bits;
-
- bits = FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN;
- if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN))
- return false; /* read_callback_ sets the state for us */
- decoder->private_->stream_info.data.stream_info.max_blocksize = x;
- used_bits += bits;
-
- bits = FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN;
- if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN))
- return false; /* read_callback_ sets the state for us */
- decoder->private_->stream_info.data.stream_info.min_framesize = x;
- used_bits += bits;
-
- bits = FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN;
- if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN))
- return false; /* read_callback_ sets the state for us */
- decoder->private_->stream_info.data.stream_info.max_framesize = x;
- used_bits += bits;
-
- bits = FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN;
- if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN))
- return false; /* read_callback_ sets the state for us */
- decoder->private_->stream_info.data.stream_info.sample_rate = x;
- used_bits += bits;
-
- bits = FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN;
- if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN))
- return false; /* read_callback_ sets the state for us */
- decoder->private_->stream_info.data.stream_info.channels = x+1;
- used_bits += bits;
-
- bits = FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN;
- if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN))
- return false; /* read_callback_ sets the state for us */
- decoder->private_->stream_info.data.stream_info.bits_per_sample = x+1;
- used_bits += bits;
-
- bits = FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN;
- if(!FLAC__bitreader_read_raw_uint64(decoder->private_->input, &decoder->private_->stream_info.data.stream_info.total_samples, FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN))
- return false; /* read_callback_ sets the state for us */
- used_bits += bits;
-
- if(!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, decoder->private_->stream_info.data.stream_info.md5sum, 16))
- return false; /* read_callback_ sets the state for us */
- used_bits += 16*8;
-
- /* skip the rest of the block */
- FLAC__ASSERT(used_bits % 8 == 0);
- length -= (used_bits / 8);
- if(!FLAC__bitreader_skip_byte_block_aligned_no_crc(decoder->private_->input, length))
- return false; /* read_callback_ sets the state for us */
-
- return true;
- }
-
- FLAC__bool read_metadata_seektable_(FLAC__StreamDecoder *decoder, FLAC__bool is_last, unsigned length)
- {
- FLAC__uint32 i, x;
- FLAC__uint64 xx;
-
- FLAC__ASSERT(FLAC__bitreader_is_consumed_byte_aligned(decoder->private_->input));
-
- decoder->private_->seek_table.type = FLAC__METADATA_TYPE_SEEKTABLE;
- decoder->private_->seek_table.is_last = is_last;
- decoder->private_->seek_table.length = length;
-
- decoder->private_->seek_table.data.seek_table.num_points = length / FLAC__STREAM_METADATA_SEEKPOINT_LENGTH;
-
- /* use realloc since we may pass through here several times (e.g. after seeking) */
- if(0 == (decoder->private_->seek_table.data.seek_table.points = (FLAC__StreamMetadata_SeekPoint*)safe_realloc_mul_2op_(decoder->private_->seek_table.data.seek_table.points, decoder->private_->seek_table.data.seek_table.num_points, /*times*/sizeof(FLAC__StreamMetadata_SeekPoint)))) {
- decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
- return false;
- }
- for(i = 0; i < decoder->private_->seek_table.data.seek_table.num_points; i++) {
- if(!FLAC__bitreader_read_raw_uint64(decoder->private_->input, &xx, FLAC__STREAM_METADATA_SEEKPOINT_SAMPLE_NUMBER_LEN))
- return false; /* read_callback_ sets the state for us */
- decoder->private_->seek_table.data.seek_table.points[i].sample_number = xx;
-
- if(!FLAC__bitreader_read_raw_uint64(decoder->private_->input, &xx, FLAC__STREAM_METADATA_SEEKPOINT_STREAM_OFFSET_LEN))
- return false; /* read_callback_ sets the state for us */
- decoder->private_->seek_table.data.seek_table.points[i].stream_offset = xx;
-
- if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_SEEKPOINT_FRAME_SAMPLES_LEN))
- return false; /* read_callback_ sets the state for us */
- decoder->private_->seek_table.data.seek_table.points[i].frame_samples = x;
- }
- length -= (decoder->private_->seek_table.data.seek_table.num_points * FLAC__STREAM_METADATA_SEEKPOINT_LENGTH);
- /* if there is a partial point left, skip over it */
- if(length > 0) {
- /*@@@ do a send_error_to_client_() here? there's an argument for either way */
- if(!FLAC__bitreader_skip_byte_block_aligned_no_crc(decoder->private_->input, length))
- return false; /* read_callback_ sets the state for us */
- }
-
- return true;
- }
-
- FLAC__bool read_metadata_vorbiscomment_(FLAC__StreamDecoder *decoder, FLAC__StreamMetadata_VorbisComment *obj)
- {
- FLAC__uint32 i;
-
- FLAC__ASSERT(FLAC__bitreader_is_consumed_byte_aligned(decoder->private_->input));
-
- /* read vendor string */
- FLAC__ASSERT(FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN == 32);
- if(!FLAC__bitreader_read_uint32_little_endian(decoder->private_->input, &obj->vendor_string.length))
- return false; /* read_callback_ sets the state for us */
- if(obj->vendor_string.length > 0) {
- if(0 == (obj->vendor_string.entry = (FLAC__byte*)safe_malloc_add_2op_(obj->vendor_string.length, /*+*/1))) {
- decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
- return false;
- }
- if(!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, obj->vendor_string.entry, obj->vendor_string.length))
- return false; /* read_callback_ sets the state for us */
- obj->vendor_string.entry[obj->vendor_string.length] = '\0';
- }
- else
- obj->vendor_string.entry = 0;
-
- /* read num comments */
- FLAC__ASSERT(FLAC__STREAM_METADATA_VORBIS_COMMENT_NUM_COMMENTS_LEN == 32);
- if(!FLAC__bitreader_read_uint32_little_endian(decoder->private_->input, &obj->num_comments))
- return false; /* read_callback_ sets the state for us */
-
- /* read comments */
- if(obj->num_comments > 0) {
- if(0 == (obj->comments = (FLAC__StreamMetadata_VorbisComment_Entry*)safe_malloc_mul_2op_(obj->num_comments, /*times*/sizeof(FLAC__StreamMetadata_VorbisComment_Entry)))) {
- decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
- return false;
- }
- for(i = 0; i < obj->num_comments; i++) {
- FLAC__ASSERT(FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN == 32);
- if(!FLAC__bitreader_read_uint32_little_endian(decoder->private_->input, &obj->comments[i].length))
- return false; /* read_callback_ sets the state for us */
- if(obj->comments[i].length > 0) {
- if(0 == (obj->comments[i].entry = (FLAC__byte*)safe_malloc_add_2op_(obj->comments[i].length, /*+*/1))) {
- decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
- return false;
- }
- if(!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, obj->comments[i].entry, obj->comments[i].length))
- return false; /* read_callback_ sets the state for us */
- obj->comments[i].entry[obj->comments[i].length] = '\0';
- }
- else
- obj->comments[i].entry = 0;
- }
- }
- else {
- obj->comments = 0;
- }
-
- return true;
- }
-
- FLAC__bool read_metadata_cuesheet_(FLAC__StreamDecoder *decoder, FLAC__StreamMetadata_CueSheet *obj)
- {
- FLAC__uint32 i, j, x;
-
- FLAC__ASSERT(FLAC__bitreader_is_consumed_byte_aligned(decoder->private_->input));
-
- memset(obj, 0, sizeof(FLAC__StreamMetadata_CueSheet));
-
- FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_MEDIA_CATALOG_NUMBER_LEN % 8 == 0);
- if(!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, (FLAC__byte*)obj->media_catalog_number, FLAC__STREAM_METADATA_CUESHEET_MEDIA_CATALOG_NUMBER_LEN/8))
- return false; /* read_callback_ sets the state for us */
-
- if(!FLAC__bitreader_read_raw_uint64(decoder->private_->input, &obj->lead_in, FLAC__STREAM_METADATA_CUESHEET_LEAD_IN_LEN))
- return false; /* read_callback_ sets the state for us */
-
- if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_CUESHEET_IS_CD_LEN))
- return false; /* read_callback_ sets the state for us */
- obj->is_cd = x? true : false;
-
- if(!FLAC__bitreader_skip_bits_no_crc(decoder->private_->input, FLAC__STREAM_METADATA_CUESHEET_RESERVED_LEN))
- return false; /* read_callback_ sets the state for us */
-
- if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_CUESHEET_NUM_TRACKS_LEN))
- return false; /* read_callback_ sets the state for us */
- obj->num_tracks = x;
-
- if(obj->num_tracks > 0) {
- if(0 == (obj->tracks = (FLAC__StreamMetadata_CueSheet_Track*)safe_calloc_(obj->num_tracks, sizeof(FLAC__StreamMetadata_CueSheet_Track)))) {
- decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
- return false;
- }
- for(i = 0; i < obj->num_tracks; i++) {
- FLAC__StreamMetadata_CueSheet_Track *track = &obj->tracks[i];
- if(!FLAC__bitreader_read_raw_uint64(decoder->private_->input, &track->offset, FLAC__STREAM_METADATA_CUESHEET_TRACK_OFFSET_LEN))
- return false; /* read_callback_ sets the state for us */
-
- if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_CUESHEET_TRACK_NUMBER_LEN))
- return false; /* read_callback_ sets the state for us */
- track->number = (FLAC__byte)x;
-
- FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN % 8 == 0);
- if(!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, (FLAC__byte*)track->isrc, FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN/8))
- return false; /* read_callback_ sets the state for us */
-
- if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_CUESHEET_TRACK_TYPE_LEN))
- return false; /* read_callback_ sets the state for us */
- track->type = x;
-
- if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_CUESHEET_TRACK_PRE_EMPHASIS_LEN))
- return false; /* read_callback_ sets the state for us */
- track->pre_emphasis = x;
-
- if(!FLAC__bitreader_skip_bits_no_crc(decoder->private_->input, FLAC__STREAM_METADATA_CUESHEET_TRACK_RESERVED_LEN))
- return false; /* read_callback_ sets the state for us */
-
- if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_CUESHEET_TRACK_NUM_INDICES_LEN))
- return false; /* read_callback_ sets the state for us */
- track->num_indices = (FLAC__byte)x;
-
- if(track->num_indices > 0) {
- if(0 == (track->indices = (FLAC__StreamMetadata_CueSheet_Index*)safe_calloc_(track->num_indices, sizeof(FLAC__StreamMetadata_CueSheet_Index)))) {
- decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
- return false;
- }
- for(j = 0; j < track->num_indices; j++) {
- FLAC__StreamMetadata_CueSheet_Index *index = &track->indices[j];
- if(!FLAC__bitreader_read_raw_uint64(decoder->private_->input, &index->offset, FLAC__STREAM_METADATA_CUESHEET_INDEX_OFFSET_LEN))
- return false; /* read_callback_ sets the state for us */
-
- if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_CUESHEET_INDEX_NUMBER_LEN))
- return false; /* read_callback_ sets the state for us */
- index->number = (FLAC__byte)x;
-
- if(!FLAC__bitreader_skip_bits_no_crc(decoder->private_->input, FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN))
- return false; /* read_callback_ sets the state for us */
- }
- }
- }
- }
-
- return true;
- }
-
- FLAC__bool read_metadata_picture_(FLAC__StreamDecoder *decoder, FLAC__StreamMetadata_Picture *obj)
- {
- FLAC__uint32 x;
-
- FLAC__ASSERT(FLAC__bitreader_is_consumed_byte_aligned(decoder->private_->input));
-
- /* read type */
- if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_PICTURE_TYPE_LEN))
- return false; /* read_callback_ sets the state for us */
- obj->type = (FLAC__StreamMetadata_Picture_Type) x;
-
- /* read MIME type */
- if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_PICTURE_MIME_TYPE_LENGTH_LEN))
- return false; /* read_callback_ sets the state for us */
- if(0 == (obj->mime_type = (char*)safe_malloc_add_2op_(x, /*+*/1))) {
- decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
- return false;
- }
- if(x > 0) {
- if(!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, (FLAC__byte*)obj->mime_type, x))
- return false; /* read_callback_ sets the state for us */
- }
- obj->mime_type[x] = '\0';
-
- /* read description */
- if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_PICTURE_DESCRIPTION_LENGTH_LEN))
- return false; /* read_callback_ sets the state for us */
- if(0 == (obj->description = (FLAC__byte*)safe_malloc_add_2op_(x, /*+*/1))) {
- decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
- return false;
- }
- if(x > 0) {
- if(!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, obj->description, x))
- return false; /* read_callback_ sets the state for us */
- }
- obj->description[x] = '\0';
-
- /* read width */
- if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &obj->width, FLAC__STREAM_METADATA_PICTURE_WIDTH_LEN))
- return false; /* read_callback_ sets the state for us */
-
- /* read height */
- if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &obj->height, FLAC__STREAM_METADATA_PICTURE_HEIGHT_LEN))
- return false; /* read_callback_ sets the state for us */
-
- /* read depth */
- if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &obj->depth, FLAC__STREAM_METADATA_PICTURE_DEPTH_LEN))
- return false; /* read_callback_ sets the state for us */
-
- /* read colors */
- if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &obj->colors, FLAC__STREAM_METADATA_PICTURE_COLORS_LEN))
- return false; /* read_callback_ sets the state for us */
-
- /* read data */
- if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &(obj->data_length), FLAC__STREAM_METADATA_PICTURE_DATA_LENGTH_LEN))
- return false; /* read_callback_ sets the state for us */
- if(0 == (obj->data = (FLAC__byte*)safe_malloc_(obj->data_length))) {
- decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
- return false;
- }
- if(obj->data_length > 0) {
- if(!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, obj->data, obj->data_length))
- return false; /* read_callback_ sets the state for us */
- }
-
- return true;
- }
-
- FLAC__bool skip_id3v2_tag_(FLAC__StreamDecoder *decoder)
- {
- FLAC__uint32 x;
- unsigned i, skip;
-
- /* skip the version and flags bytes */
- if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, 24))
- return false; /* read_callback_ sets the state for us */
- /* get the size (in bytes) to skip */
- skip = 0;
- for(i = 0; i < 4; i++) {
- if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, 8))
- return false; /* read_callback_ sets the state for us */
- skip <<= 7;
- skip |= (x & 0x7f);
- }
- /* skip the rest of the tag */
- if(!FLAC__bitreader_skip_byte_block_aligned_no_crc(decoder->private_->input, skip))
- return false; /* read_callback_ sets the state for us */
- return true;
- }
-
- FLAC__bool frame_sync_(FLAC__StreamDecoder *decoder)
- {
- FLAC__uint32 x;
- FLAC__bool first = true;
-
- /* If we know the total number of samples in the stream, stop if we've read that many. */
- /* This will stop us, for example, from wasting time trying to sync on an ID3V1 tag. */
- if(FLAC__stream_decoder_get_total_samples(decoder) > 0) {
- if(decoder->private_->samples_decoded >= FLAC__stream_decoder_get_total_samples(decoder)) {
- decoder->protected_->state = FLAC__STREAM_DECODER_END_OF_STREAM;
- return true;
- }
- }
-
- /* make sure we're byte aligned */
- if(!FLAC__bitreader_is_consumed_byte_aligned(decoder->private_->input)) {
- if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__bitreader_bits_left_for_byte_alignment(decoder->private_->input)))
- return false; /* read_callback_ sets the state for us */
- }
-
- while(1) {
- if(decoder->private_->cached) {
- x = (FLAC__uint32)decoder->private_->lookahead;
- decoder->private_->cached = false;
- }
- else {
- if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, 8))
- return false; /* read_callback_ sets the state for us */
- }
- if(x == 0xff) { /* MAGIC NUMBER for the first 8 frame sync bits */
- decoder->private_->header_warmup[0] = (FLAC__byte)x;
- if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, 8))
- return false; /* read_callback_ sets the state for us */
-
- /* we have to check if we just read two 0xff's in a row; the second may actually be the beginning of the sync code */
- /* else we have to check if the second byte is the end of a sync code */
- if(x == 0xff) { /* MAGIC NUMBER for the first 8 frame sync bits */
- decoder->private_->lookahead = (FLAC__byte)x;
- decoder->private_->cached = true;
- }
- else if(x >> 2 == 0x3e) { /* MAGIC NUMBER for the last 6 sync bits */
- decoder->private_->header_warmup[1] = (FLAC__byte)x;
- decoder->protected_->state = FLAC__STREAM_DECODER_READ_FRAME;
- return true;
- }
- }
- if(first) {
- send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC);
- first = false;
- }
- }
-
- return true;
- }
-
- FLAC__bool read_frame_(FLAC__StreamDecoder *decoder, FLAC__bool *got_a_frame, FLAC__bool do_full_decode)
- {
- unsigned channel;
- unsigned i;
- FLAC__int32 mid, side;
- unsigned frame_crc; /* the one we calculate from the input stream */
- FLAC__uint32 x;
-
- *got_a_frame = false;
-
- /* init the CRC */
- frame_crc = 0;
- frame_crc = FLAC__CRC16_UPDATE(decoder->private_->header_warmup[0], frame_crc);
- frame_crc = FLAC__CRC16_UPDATE(decoder->private_->header_warmup[1], frame_crc);
- FLAC__bitreader_reset_read_crc16(decoder->private_->input, (FLAC__uint16)frame_crc);
-
- if(!read_frame_header_(decoder))
- return false;
- if(decoder->protected_->state == FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC) /* means we didn't sync on a valid header */
- return true;
- if(!allocate_output_(decoder, decoder->private_->frame.header.blocksize, decoder->private_->frame.header.channels))
- return false;
- for(channel = 0; channel < decoder->private_->frame.header.channels; channel++) {
- /*
- * first figure the correct bits-per-sample of the subframe
- */
- unsigned bps = decoder->private_->frame.header.bits_per_sample;
- switch(decoder->private_->frame.header.channel_assignment) {
- case FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT:
- /* no adjustment needed */
- break;
- case FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE:
- FLAC__ASSERT(decoder->private_->frame.header.channels == 2);
- if(channel == 1)
- bps++;
- break;
- case FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE:
- FLAC__ASSERT(decoder->private_->frame.header.channels == 2);
- if(channel == 0)
- bps++;
- break;
- case FLAC__CHANNEL_ASSIGNMENT_MID_SIDE:
- FLAC__ASSERT(decoder->private_->frame.header.channels == 2);
- if(channel == 1)
- bps++;
- break;
- default:
- FLAC__ASSERT(0);
- }
- /*
- * now read it
- */
- if(!read_subframe_(decoder, channel, bps, do_full_decode))
- return false;
- if(decoder->protected_->state == FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC) /* means bad sync or got corruption */
- return true;
- }
- if(!read_zero_padding_(decoder))
- return false;
- if(decoder->protected_->state == FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC) /* means bad sync or got corruption (i.e. "zero bits" were not all zeroes) */
- return true;
-
- /*
- * Read the frame CRC-16 from the footer and check
- */
- frame_crc = FLAC__bitreader_get_read_crc16(decoder->private_->input);
- if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__FRAME_FOOTER_CRC_LEN))
- return false; /* read_callback_ sets the state for us */
- if(frame_crc == x) {
- if(do_full_decode) {
- /* Undo any special channel coding */
- switch(decoder->private_->frame.header.channel_assignment) {
- case FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT:
- /* do nothing */
- break;
- case FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE:
- FLAC__ASSERT(decoder->private_->frame.header.channels == 2);
- for(i = 0; i < decoder->private_->frame.header.blocksize; i++)
- decoder->private_->output[1][i] = decoder->private_->output[0][i] - decoder->private_->output[1][i];
- break;
- case FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE:
- FLAC__ASSERT(decoder->private_->frame.header.channels == 2);
- for(i = 0; i < decoder->private_->frame.header.blocksize; i++)
- decoder->private_->output[0][i] += decoder->private_->output[1][i];
- break;
- case FLAC__CHANNEL_ASSIGNMENT_MID_SIDE:
- FLAC__ASSERT(decoder->private_->frame.header.channels == 2);
- for(i = 0; i < decoder->private_->frame.header.blocksize; i++) {
- #if 1
- mid = decoder->private_->output[0][i];
- side = decoder->private_->output[1][i];
- mid <<= 1;
- mid |= (side & 1); /* i.e. if 'side' is odd... */
- decoder->private_->output[0][i] = (mid + side) >> 1;
- decoder->private_->output[1][i] = (mid - side) >> 1;
- #else
- /* OPT: without 'side' temp variable */
- mid = (decoder->private_->output[0][i] << 1) | (decoder->private_->output[1][i] & 1); /* i.e. if 'side' is odd... */
- decoder->private_->output[0][i] = (mid + decoder->private_->output[1][i]) >> 1;
- decoder->private_->output[1][i] = (mid - decoder->private_->output[1][i]) >> 1;
- #endif
- }
- break;
- default:
- FLAC__ASSERT(0);
- break;
- }
- }
- }
- else {
- /* Bad frame, emit error and zero the output signal */
- send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH);
- if(do_full_decode) {
- for(channel = 0; channel < decoder->private_->frame.header.channels; channel++) {
- memset(decoder->private_->output[channel], 0, sizeof(FLAC__int32) * decoder->private_->frame.header.blocksize);
- }
- }
- }
-
- *got_a_frame = true;
-
- /* we wait to update fixed_block_size until here, when we're sure we've got a proper frame and hence a correct blocksize */
- if(decoder->private_->next_fixed_block_size)
- decoder->private_->fixed_block_size = decoder->private_->next_fixed_block_size;
-
- /* put the latest values into the public section of the decoder instance */
- decoder->protected_->channels = decoder->private_->frame.header.channels;
- decoder->protected_->channel_assignment = decoder->private_->frame.header.channel_assignment;
- decoder->protected_->bits_per_sample = decoder->private_->frame.header.bits_per_sample;
- decoder->protected_->sample_rate = decoder->private_->frame.header.sample_rate;
- decoder->protected_->blocksize = decoder->private_->frame.header.blocksize;
-
- FLAC__ASSERT(decoder->private_->frame.header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER);
- decoder->private_->samples_decoded = decoder->private_->frame.header.number.sample_number + decoder->private_->frame.header.blocksize;
-
- /* write it */
- if(do_full_decode) {
- if(write_audio_frame_to_client_(decoder, &decoder->private_->frame, (const FLAC__int32 * const *)decoder->private_->output) != FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE)
- return false;
- }
-
- decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
- return true;
- }
-
- FLAC__bool read_frame_header_(FLAC__StreamDecoder *decoder)
- {
- FLAC__uint32 x;
- FLAC__uint64 xx;
- unsigned i, blocksize_hint = 0, sample_rate_hint = 0;
- FLAC__byte crc8, raw_header[16]; /* MAGIC NUMBER based on the maximum frame header size, including CRC */
- unsigned raw_header_len;
- FLAC__bool is_unparseable = false;
-
- FLAC__ASSERT(FLAC__bitreader_is_consumed_byte_aligned(decoder->private_->input));
-
- /* init the raw header with the saved bits from synchronization */
- raw_header[0] = decoder->private_->header_warmup[0];
- raw_header[1] = decoder->private_->header_warmup[1];
- raw_header_len = 2;
-
- /* check to make sure that reserved bit is 0 */
- if(raw_header[1] & 0x02) /* MAGIC NUMBER */
- is_unparseable = true;
-
- /*
- * Note that along the way as we read the header, we look for a sync
- * code inside. If we find one it would indicate that our original
- * sync was bad since there cannot be a sync code in a valid header.
- *
- * Three kinds of things can go wrong when reading the frame header:
- * 1) We may have sync'ed incorrectly and not landed on a frame header.
- * If we don't find a sync code, it can end up looking like we read
- * a valid but unparseable header, until getting to the frame header
- * CRC. Even then we could get a false positive on the CRC.
- * 2) We may have sync'ed correctly but on an unparseable frame (from a
- * future encoder).
- * 3) We may be on a damaged frame which appears valid but unparseable.
- *
- * For all these reasons, we try and read a complete frame header as
- * long as it seems valid, even if unparseable, up until the frame
- * header CRC.
- */
-
- /*
- * read in the raw header as bytes so we can CRC it, and parse it on the way
- */
- for(i = 0; i < 2; i++) {
- if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, 8))
- return false; /* read_callback_ sets the state for us */
- if(x == 0xff) { /* MAGIC NUMBER for the first 8 frame sync bits */
- /* if we get here it means our original sync was erroneous since the sync code cannot appear in the header */
- decoder->private_->lookahead = (FLAC__byte)x;
- decoder->private_->cached = true;
- send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER);
- decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
- return true;
- }
- raw_header[raw_header_len++] = (FLAC__byte)x;
- }
-
- switch(x = raw_header[2] >> 4) {
- case 0:
- is_unparseable = true;
- break;
- case 1:
- decoder->private_->frame.header.blocksize = 192;
- break;
- case 2:
- case 3:
- case 4:
- case 5:
- decoder->private_->frame.header.blocksize = 576 << (x-2);
- break;
- case 6:
- case 7:
- blocksize_hint = x;
- break;
- case 8:
- case 9:
- case 10:
- case 11:
- case 12:
- case 13:
- case 14:
- case 15:
- decoder->private_->frame.header.blocksize = 256 << (x-8);
- break;
- default:
- FLAC__ASSERT(0);
- break;
- }
-
- switch(x = raw_header[2] & 0x0f) {
- case 0:
- if(decoder->private_->has_stream_info)
- decoder->private_->frame.header.sample_rate = decoder->private_->stream_info.data.stream_info.sample_rate;
- else
- is_unparseable = true;
- break;
- case 1:
- decoder->private_->frame.header.sample_rate = 88200;
- break;
- case 2:
- decoder->private_->frame.header.sample_rate = 176400;
- break;
- case 3:
- decoder->private_->frame.header.sample_rate = 192000;
- break;
- case 4:
- decoder->private_->frame.header.sample_rate = 8000;
- break;
- case 5:
- decoder->private_->frame.header.sample_rate = 16000;
- break;
- case 6:
- decoder->private_->frame.header.sample_rate = 22050;
- break;
- case 7:
- decoder->private_->frame.header.sample_rate = 24000;
- break;
- case 8:
- decoder->private_->frame.header.sample_rate = 32000;
- break;
- case 9:
- decoder->private_->frame.header.sample_rate = 44100;
- break;
- case 10:
- decoder->private_->frame.header.sample_rate = 48000;
- break;
- case 11:
- decoder->private_->frame.header.sample_rate = 96000;
- break;
- case 12:
- case 13:
- case 14:
- sample_rate_hint = x;
- break;
- case 15:
- send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER);
- decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
- return true;
- default:
- FLAC__ASSERT(0);
- }
-
- x = (unsigned)(raw_header[3] >> 4);
- if(x & 8) {
- decoder->private_->frame.header.channels = 2;
- switch(x & 7) {
- case 0:
- decoder->private_->frame.header.channel_assignment = FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE;
- break;
- case 1:
- decoder->private_->frame.header.channel_assignment = FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE;
- break;
- case 2:
- decoder->private_->frame.header.channel_assignment = FLAC__CHANNEL_ASSIGNMENT_MID_SIDE;
- break;
- default:
- is_unparseable = true;
- break;
- }
- }
- else {
- decoder->private_->frame.header.channels = (unsigned)x + 1;
- decoder->private_->frame.header.channel_assignment = FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT;
- }
-
- switch(x = (unsigned)(raw_header[3] & 0x0e) >> 1) {
- case 0:
- if(decoder->private_->has_stream_info)
- decoder->private_->frame.header.bits_per_sample = decoder->private_->stream_info.data.stream_info.bits_per_sample;
- else
- is_unparseable = true;
- break;
- case 1:
- decoder->private_->frame.header.bits_per_sample = 8;
- break;
- case 2:
- decoder->private_->frame.header.bits_per_sample = 12;
- break;
- case 4:
- decoder->private_->frame.header.bits_per_sample = 16;
- break;
- case 5:
- decoder->private_->frame.header.bits_per_sample = 20;
- break;
- case 6:
- decoder->private_->frame.header.bits_per_sample = 24;
- break;
- case 3:
- case 7:
- is_unparseable = true;
- break;
- default:
- FLAC__ASSERT(0);
- break;
- }
-
- /* check to make sure that reserved bit is 0 */
- if(raw_header[3] & 0x01) /* MAGIC NUMBER */
- is_unparseable = true;
-
- /* read the frame's starting sample number (or frame number as the case may be) */
- if(
- raw_header[1] & 0x01 ||
- /*@@@ this clause is a concession to the old way of doing variable blocksize; the only known implementation is flake and can probably be removed without inconveniencing anyone */
- (decoder->private_->has_stream_info && decoder->private_->stream_info.data.stream_info.min_blocksize != decoder->private_->stream_info.data.stream_info.max_blocksize)
- ) { /* variable blocksize */
- if(!FLAC__bitreader_read_utf8_uint64(decoder->private_->input, &xx, raw_header, &raw_header_len))
- return false; /* read_callback_ sets the state for us */
- if(xx == FLAC__U64L(0xffffffffffffffff)) { /* i.e. non-UTF8 code... */
- decoder->private_->lookahead = raw_header[raw_header_len-1]; /* back up as much as we can */
- decoder->private_->cached = true;
- send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER);
- decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
- return true;
- }
- decoder->private_->frame.header.number_type = FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER;
- decoder->private_->frame.header.number.sample_number = xx;
- }
- else { /* fixed blocksize */
- if(!FLAC__bitreader_read_utf8_uint32(decoder->private_->input, &x, raw_header, &raw_header_len))
- return false; /* read_callback_ sets the state for us */
- if(x == 0xffffffff) { /* i.e. non-UTF8 code... */
- decoder->private_->lookahead = raw_header[raw_header_len-1]; /* back up as much as we can */
- decoder->private_->cached = true;
- send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER);
- decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
- return true;
- }
- decoder->private_->frame.header.number_type = FLAC__FRAME_NUMBER_TYPE_FRAME_NUMBER;
- decoder->private_->frame.header.number.frame_number = x;
- }
-
- if(blocksize_hint) {
- if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, 8))
- return false; /* read_callback_ sets the state for us */
- raw_header[raw_header_len++] = (FLAC__byte)x;
- if(blocksize_hint == 7) {
- FLAC__uint32 _x;
- if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &_x, 8))
- return false; /* read_callback_ sets the state for us */
- raw_header[raw_header_len++] = (FLAC__byte)_x;
- x = (x << 8) | _x;
- }
- decoder->private_->frame.header.blocksize = x+1;
- }
-
- if(sample_rate_hint) {
- if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, 8))
- return false; /* read_callback_ sets the state for us */
- raw_header[raw_header_len++] = (FLAC__byte)x;
- if(sample_rate_hint != 12) {
- FLAC__uint32 _x;
- if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &_x, 8))
- return false; /* read_callback_ sets the state for us */
- raw_header[raw_header_len++] = (FLAC__byte)_x;
- x = (x << 8) | _x;
- }
- if(sample_rate_hint == 12)
- decoder->private_->frame.header.sample_rate = x*1000;
- else if(sample_rate_hint == 13)
- decoder->private_->frame.header.sample_rate = x;
- else
- decoder->private_->frame.header.sample_rate = x*10;
- }
-
- /* read the CRC-8 byte */
- if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, 8))
- return false; /* read_callback_ sets the state for us */
- crc8 = (FLAC__byte)x;
-
- if(FLAC__crc8(raw_header, raw_header_len) != crc8) {
- send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER);
- decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
- return true;
- }
-
- /* calculate the sample number from the frame number if needed */
- decoder->private_->next_fixed_block_size = 0;
- if(decoder->private_->frame.header.number_type == FLAC__FRAME_NUMBER_TYPE_FRAME_NUMBER) {
- x = decoder->private_->frame.header.number.frame_number;
- decoder->private_->frame.header.number_type = FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER;
- if(decoder->private_->fixed_block_size)
- decoder->private_->frame.header.number.sample_number = (FLAC__uint64)decoder->private_->fixed_block_size * (FLAC__uint64)x;
- else if(decoder->private_->has_stream_info) {
- if(decoder->private_->stream_info.data.stream_info.min_blocksize == decoder->private_->stream_info.data.stream_info.max_blocksize) {
- decoder->private_->frame.header.number.sample_number = (FLAC__uint64)decoder->private_->stream_info.data.stream_info.min_blocksize * (FLAC__uint64)x;
- decoder->private_->next_fixed_block_size = decoder->private_->stream_info.data.stream_info.max_blocksize;
- }
- else
- is_unparseable = true;
- }
- else if(x == 0) {
- decoder->private_->frame.header.number.sample_number = 0;
- decoder->private_->next_fixed_block_size = decoder->private_->frame.header.blocksize;
- }
- else {
- /* can only get here if the stream has invalid frame numbering and no STREAMINFO, so assume it's not the last (possibly short) frame */
- decoder->private_->frame.header.number.sample_number = (FLAC__uint64)decoder->private_->frame.header.blocksize * (FLAC__uint64)x;
- }
- }
-
- if(is_unparseable) {
- send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM);
- decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
- return true;
- }
-
- return true;
- }
-
- FLAC__bool read_subframe_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps, FLAC__bool do_full_decode)
- {
- FLAC__uint32 x;
- FLAC__bool wasted_bits;
- unsigned i;
-
- if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, 8)) /* MAGIC NUMBER */
- return false; /* read_callback_ sets the state for us */
-
- wasted_bits = (x & 1);
- x &= 0xfe;
-
- if(wasted_bits) {
- unsigned u;
- if(!FLAC__bitreader_read_unary_unsigned(decoder->private_->input, &u))
- return false; /* read_callback_ sets the state for us */
- decoder->private_->frame.subframes[channel].wasted_bits = u+1;
- bps -= decoder->private_->frame.subframes[channel].wasted_bits;
- }
- else
- decoder->private_->frame.subframes[channel].wasted_bits = 0;
-
- /*
- * Lots of magic numbers here
- */
- if(x & 0x80) {
- send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC);
- decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
- return true;
- }
- else if(x == 0) {
- if(!read_subframe_constant_(decoder, channel, bps, do_full_decode))
- return false;
- }
- else if(x == 2) {
- if(!read_subframe_verbatim_(decoder, channel, bps, do_full_decode))
- return false;
- }
- else if(x < 16) {
- send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM);
- decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
- return true;
- }
- else if(x <= 24) {
- if(!read_subframe_fixed_(decoder, channel, bps, (x>>1)&7, do_full_decode))
- return false;
- if(decoder->protected_->state == FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC) /* means bad sync or got corruption */
- return true;
- }
- else if(x < 64) {
- send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM);
- decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
- return true;
- }
- else {
- if(!read_subframe_lpc_(decoder, channel, bps, ((x>>1)&31)+1, do_full_decode))
- return false;
- if(decoder->protected_->state == FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC) /* means bad sync or got corruption */
- return true;
- }
-
- if(wasted_bits && do_full_decode) {
- x = decoder->private_->frame.subframes[channel].wasted_bits;
- for(i = 0; i < decoder->private_->frame.header.blocksize; i++)
- decoder->private_->output[channel][i] <<= x;
- }
-
- return true;
- }
-
- FLAC__bool read_subframe_constant_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps, FLAC__bool do_full_decode)
- {
- FLAC__Subframe_Constant *subframe = &decoder->private_->frame.subframes[channel].data.constant;
- FLAC__int32 x;
- unsigned i;
- FLAC__int32 *output = decoder->private_->output[channel];
-
- decoder->private_->frame.subframes[channel].type = FLAC__SUBFRAME_TYPE_CONSTANT;
-
- if(!FLAC__bitreader_read_raw_int32(decoder->private_->input, &x, bps))
- return false; /* read_callback_ sets the state for us */
-
- subframe->value = x;
-
- /* decode the subframe */
- if(do_full_decode) {
- for(i = 0; i < decoder->private_->frame.header.blocksize; i++)
- output[i] = x;
- }
-
- return true;
- }
-
- FLAC__bool read_subframe_fixed_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps, const unsigned order, FLAC__bool do_full_decode)
- {
- FLAC__Subframe_Fixed *subframe = &decoder->private_->frame.subframes[channel].data.fixed;
- FLAC__int32 i32;
- FLAC__uint32 u32;
- unsigned u;
-
- decoder->private_->frame.subframes[channel].type = FLAC__SUBFRAME_TYPE_FIXED;
-
- subframe->residual = decoder->private_->residual[channel];
- subframe->order = order;
-
- /* read warm-up samples */
- for(u = 0; u < order; u++) {
- if(!FLAC__bitreader_read_raw_int32(decoder->private_->input, &i32, bps))
- return false; /* read_callback_ sets the state for us */
- subframe->warmup[u] = i32;
- }
-
- /* read entropy coding method info */
- if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &u32, FLAC__ENTROPY_CODING_METHOD_TYPE_LEN))
- return false; /* read_callback_ sets the state for us */
- subframe->entropy_coding_method.type = (FLAC__EntropyCodingMethodType)u32;
- switch(subframe->entropy_coding_method.type) {
- case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE:
- case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2:
- if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &u32, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN))
- return false; /* read_callback_ sets the state for us */
- subframe->entropy_coding_method.data.partitioned_rice.order = u32;
- subframe->entropy_coding_method.data.partitioned_rice.contents = &decoder->private_->partitioned_rice_contents[channel];
- break;
- default:
- send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM);
- decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
- return true;
- }
-
- /* read residual */
- switch(subframe->entropy_coding_method.type) {
- case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE:
- case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2:
- if(!read_residual_partitioned_rice_(decoder, order, subframe->entropy_coding_method.data.partitioned_rice.order, &decoder->private_->partitioned_rice_contents[channel], decoder->private_->residual[channel], /*is_extended=*/subframe->entropy_coding_method.type == FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2))
- return false;
- break;
- default:
- FLAC__ASSERT(0);
- }
-
- /* decode the subframe */
- if(do_full_decode) {
- memcpy(decoder->private_->output[channel], subframe->warmup, sizeof(FLAC__int32) * order);
- FLAC__fixed_restore_signal(decoder->private_->residual[channel], decoder->private_->frame.header.blocksize-order, order, decoder->private_->output[channel]+order);
- }
-
- return true;
- }
-
- FLAC__bool read_subframe_lpc_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps, const unsigned order, FLAC__bool do_full_decode)
- {
- FLAC__Subframe_LPC *subframe = &decoder->private_->frame.subframes[channel].data.lpc;
- FLAC__int32 i32;
- FLAC__uint32 u32;
- unsigned u;
-
- decoder->private_->frame.subframes[channel].type = FLAC__SUBFRAME_TYPE_LPC;
-
- subframe->residual = decoder->private_->residual[channel];
- subframe->order = order;
-
- /* read warm-up samples */
- for(u = 0; u < order; u++) {
- if(!FLAC__bitreader_read_raw_int32(decoder->private_->input, &i32, bps))
- return false; /* read_callback_ sets the state for us */
- subframe->warmup[u] = i32;
- }
-
- /* read qlp coeff precision */
- if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &u32, FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN))
- return false; /* read_callback_ sets the state for us */
- if(u32 == (1u << FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN) - 1) {
- send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC);
- decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
- return true;
- }
- subframe->qlp_coeff_precision = u32+1;
-
- /* read qlp shift */
- if(!FLAC__bitreader_read_raw_int32(decoder->private_->input, &i32, FLAC__SUBFRAME_LPC_QLP_SHIFT_LEN))
- return false; /* read_callback_ sets the state for us */
- subframe->quantization_level = i32;
-
- /* read quantized lp coefficiencts */
- for(u = 0; u < order; u++) {
- if(!FLAC__bitreader_read_raw_int32(decoder->private_->input, &i32, subframe->qlp_coeff_precision))
- return false; /* read_callback_ sets the state for us */
- subframe->qlp_coeff[u] = i32;
- }
-
- /* read entropy coding method info */
- if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &u32, FLAC__ENTROPY_CODING_METHOD_TYPE_LEN))
- return false; /* read_callback_ sets the state for us */
- subframe->entropy_coding_method.type = (FLAC__EntropyCodingMethodType)u32;
- switch(subframe->entropy_coding_method.type) {
- case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE:
- case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2:
- if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &u32, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN))
- return false; /* read_callback_ sets the state for us */
- subframe->entropy_coding_method.data.partitioned_rice.order = u32;
- subframe->entropy_coding_method.data.partitioned_rice.contents = &decoder->private_->partitioned_rice_contents[channel];
- break;
- default:
- send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM);
- decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
- return true;
- }
-
- /* read residual */
- switch(subframe->entropy_coding_method.type) {
- case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE:
- case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2:
- if(!read_residual_partitioned_rice_(decoder, order, subframe->entropy_coding_method.data.partitioned_rice.order, &decoder->private_->partitioned_rice_contents[channel], decoder->private_->residual[channel], /*is_extended=*/subframe->entropy_coding_method.type == FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2))
- return false;
- break;
- default:
- FLAC__ASSERT(0);
- }
-
- /* decode the subframe */
- if(do_full_decode) {
- memcpy(decoder->private_->output[channel], subframe->warmup, sizeof(FLAC__int32) * order);
- /*@@@@@@ technically not pessimistic enough, should be more like
- if( (FLAC__uint64)order * ((((FLAC__uint64)1)<<bps)-1) * ((1<<subframe->qlp_coeff_precision)-1) < (((FLAC__uint64)-1) << 32) )
- */
- if(bps + subframe->qlp_coeff_precision + FLAC__bitmath_ilog2(order) <= 32)
- if(bps <= 16 && subframe->qlp_coeff_precision <= 16) {
- if(order <= 8)
- decoder->private_->local_lpc_restore_signal_16bit_order8(decoder->private_->residual[channel], decoder->private_->frame.header.blocksize-order, subframe->qlp_coeff, order, subframe->quantization_level, decoder->private_->output[channel]+order);
- else
- decoder->private_->local_lpc_restore_signal_16bit(decoder->private_->residual[channel], decoder->private_->frame.header.blocksize-order, subframe->qlp_coeff, order, subframe->quantization_level, decoder->private_->output[channel]+order);
- }
- else
- decoder->private_->local_lpc_restore_signal(decoder->private_->residual[channel], decoder->private_->frame.header.blocksize-order, subframe->qlp_coeff, order, subframe->quantization_level, decoder->private_->output[channel]+order);
- else
- decoder->private_->local_lpc_restore_signal_64bit(decoder->private_->residual[channel], decoder->private_->frame.header.blocksize-order, subframe->qlp_coeff, order, subframe->quantization_level, decoder->private_->output[channel]+order);
- }
-
- return true;
- }
-
- FLAC__bool read_subframe_verbatim_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps, FLAC__bool do_full_decode)
- {
- FLAC__Subframe_Verbatim *subframe = &decoder->private_->frame.subframes[channel].data.verbatim;
- FLAC__int32 x, *residual = decoder->private_->residual[channel];
- unsigned i;
-
- decoder->private_->frame.subframes[channel].type = FLAC__SUBFRAME_TYPE_VERBATIM;
-
- subframe->data = residual;
-
- for(i = 0; i < decoder->private_->frame.header.blocksize; i++) {
- if(!FLAC__bitreader_read_raw_int32(decoder->private_->input, &x, bps))
- return false; /* read_callback_ sets the state for us */
- residual[i] = x;
- }
-
- /* decode the subframe */
- if(do_full_decode)
- memcpy(decoder->private_->output[channel], subframe->data, sizeof(FLAC__int32) * decoder->private_->frame.header.blocksize);
-
- return true;
- }
-
- FLAC__bool read_residual_partitioned_rice_(FLAC__StreamDecoder *decoder, unsigned predictor_order, unsigned partition_order, FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents, FLAC__int32 *residual, FLAC__bool is_extended)
- {
- FLAC__uint32 rice_parameter;
- int i;
- unsigned partition, sample, u;
- const unsigned partitions = 1u << partition_order;
- const unsigned partition_samples = partition_order > 0? decoder->private_->frame.header.blocksize >> partition_order : decoder->private_->frame.header.blocksize - predictor_order;
- const unsigned plen = is_extended? FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN : FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN;
- const unsigned pesc = is_extended? FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_ESCAPE_PARAMETER : FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER;
-
- /* sanity checks */
- if(partition_order == 0) {
- if(decoder->private_->frame.header.blocksize < predictor_order) {
- send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC);
- decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
- return true;
- }
- }
- else {
- if(partition_samples < predictor_order) {
- send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC);
- decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
- return true;
- }
- }
-
- if(!FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(partitioned_rice_contents, max(6, partition_order))) {
- decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
- return false;
- }
-
- sample = 0;
- for(partition = 0; partition < partitions; partition++) {
- if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &rice_parameter, plen))
- return false; /* read_callback_ sets the state for us */
- partitioned_rice_contents->parameters[partition] = rice_parameter;
- if(rice_parameter < pesc) {
- partitioned_rice_contents->raw_bits[partition] = 0;
- u = (partition_order == 0 || partition > 0)? partition_samples : partition_samples - predictor_order;
- if(!decoder->private_->local_bitreader_read_rice_signed_block(decoder->private_->input, (int*) residual + sample, u, rice_parameter))
- return false; /* read_callback_ sets the state for us */
- sample += u;
- }
- else {
- if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &rice_parameter, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN))
- return false; /* read_callback_ sets the state for us */
- partitioned_rice_contents->raw_bits[partition] = rice_parameter;
- for(u = (partition_order == 0 || partition > 0)? 0 : predictor_order; u < partition_samples; u++, sample++) {
- if(!FLAC__bitreader_read_raw_int32(decoder->private_->input, (FLAC__int32*) &i, rice_parameter))
- return false; /* read_callback_ sets the state for us */
- residual[sample] = i;
- }
- }
- }
-
- return true;
- }
-
- FLAC__bool read_zero_padding_(FLAC__StreamDecoder *decoder)
- {
- if(!FLAC__bitreader_is_consumed_byte_aligned(decoder->private_->input)) {
- FLAC__uint32 zero = 0;
- if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &zero, FLAC__bitreader_bits_left_for_byte_alignment(decoder->private_->input)))
- return false; /* read_callback_ sets the state for us */
- if(zero != 0) {
- send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC);
- decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
- }
- }
- return true;
- }
-
- FLAC__bool read_callback_(FLAC__byte buffer[], size_t *bytes, void *client_data)
- {
- FLAC__StreamDecoder *decoder = (FLAC__StreamDecoder *)client_data;
-
- if(
- #if FLAC__HAS_OGG
- /* see [1] HACK NOTE below for why we don't call the eof_callback when decoding Ogg FLAC */
- !decoder->private_->is_ogg &&
- #endif
- decoder->private_->eof_callback && decoder->private_->eof_callback(decoder, decoder->private_->client_data)
- ) {
- *bytes = 0;
- decoder->protected_->state = FLAC__STREAM_DECODER_END_OF_STREAM;
- return false;
- }
- else if(*bytes > 0) {
- /* While seeking, it is possible for our seek to land in the
- * middle of audio data that looks exactly like a frame header
- * from a future version of an encoder. When that happens, our
- * error callback will get an
- * FLAC__STREAM_DECODER_UNPARSEABLE_STREAM and increment its
- * unparseable_frame_count. But there is a remote possibility
- * that it is properly synced at such a "future-codec frame",
- * so to make sure, we wait to see many "unparseable" errors in
- * a row before bailing out.
- */
- if(decoder->private_->is_seeking && decoder->private_->unparseable_frame_count > 20) {
- decoder->protected_->state = FLAC__STREAM_DECODER_ABORTED;
- return false;
- }
- else {
- const FLAC__StreamDecoderReadStatus status =
- #if FLAC__HAS_OGG
- decoder->private_->is_ogg?
- read_callback_ogg_aspect_(decoder, buffer, bytes) :
- #endif
- decoder->private_->read_callback(decoder, buffer, bytes, decoder->private_->client_data)
- ;
- if(status == FLAC__STREAM_DECODER_READ_STATUS_ABORT) {
- decoder->protected_->state = FLAC__STREAM_DECODER_ABORTED;
- return false;
- }
- else if(*bytes == 0) {
- if(
- status == FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM ||
- (
- #if FLAC__HAS_OGG
- /* see [1] HACK NOTE below for why we don't call the eof_callback when decoding Ogg FLAC */
- !decoder->private_->is_ogg &&
- #endif
- decoder->private_->eof_callback && decoder->private_->eof_callback(decoder, decoder->private_->client_data)
- )
- ) {
- decoder->protected_->state = FLAC__STREAM_DECODER_END_OF_STREAM;
- return false;
- }
- else
- return true;
- }
- else
- return true;
- }
- }
- else {
- /* abort to avoid a deadlock */
- decoder->protected_->state = FLAC__STREAM_DECODER_ABORTED;
- return false;
- }
- /* [1] @@@ HACK NOTE: The end-of-stream checking has to be hacked around
- * for Ogg FLAC. This is because the ogg decoder aspect can lose sync
- * and at the same time hit the end of the stream (for example, seeking
- * to a point that is after the beginning of the last Ogg page). There
- * is no way to report an Ogg sync loss through the callbacks (see note
- * in read_callback_ogg_aspect_()) so it returns CONTINUE with *bytes==0.
- * So to keep the decoder from stopping at this point we gate the call
- * to the eof_callback and let the Ogg decoder aspect set the
- * end-of-stream state when it is needed.
- */
- }
-
- #if FLAC__HAS_OGG
- FLAC__StreamDecoderReadStatus read_callback_ogg_aspect_(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes)
- {
- switch(FLAC__ogg_decoder_aspect_read_callback_wrapper(&decoder->protected_->ogg_decoder_aspect, buffer, bytes, read_callback_proxy_, decoder, decoder->private_->client_data)) {
- case FLAC__OGG_DECODER_ASPECT_READ_STATUS_OK:
- return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
- /* we don't really have a way to handle lost sync via read
- * callback so we'll let it pass and let the underlying
- * FLAC decoder catch the error
- */
- case FLAC__OGG_DECODER_ASPECT_READ_STATUS_LOST_SYNC:
- return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
- case FLAC__OGG_DECODER_ASPECT_READ_STATUS_END_OF_STREAM:
- return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
- case FLAC__OGG_DECODER_ASPECT_READ_STATUS_NOT_FLAC:
- case FLAC__OGG_DECODER_ASPECT_READ_STATUS_UNSUPPORTED_MAPPING_VERSION:
- case FLAC__OGG_DECODER_ASPECT_READ_STATUS_ABORT:
- case FLAC__OGG_DECODER_ASPECT_READ_STATUS_ERROR:
- case FLAC__OGG_DECODER_ASPECT_READ_STATUS_MEMORY_ALLOCATION_ERROR:
- return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
- default:
- FLAC__ASSERT(0);
- /* double protection */
- return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
- }
- }
-
- FLAC__OggDecoderAspectReadStatus read_callback_proxy_(const void *void_decoder, FLAC__byte buffer[], size_t *bytes, void *client_data)
- {
- FLAC__StreamDecoder *decoder = (FLAC__StreamDecoder*)void_decoder;
-
- switch(decoder->private_->read_callback(decoder, buffer, bytes, client_data)) {
- case FLAC__STREAM_DECODER_READ_STATUS_CONTINUE:
- return FLAC__OGG_DECODER_ASPECT_READ_STATUS_OK;
- case FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM:
- return FLAC__OGG_DECODER_ASPECT_READ_STATUS_END_OF_STREAM;
- case FLAC__STREAM_DECODER_READ_STATUS_ABORT:
- return FLAC__OGG_DECODER_ASPECT_READ_STATUS_ABORT;
- default:
- /* double protection: */
- FLAC__ASSERT(0);
- return FLAC__OGG_DECODER_ASPECT_READ_STATUS_ABORT;
- }
- }
- #endif
-
- FLAC__StreamDecoderWriteStatus write_audio_frame_to_client_(FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[])
- {
- if(decoder->private_->is_seeking) {
- FLAC__uint64 this_frame_sample = frame->header.number.sample_number;
- FLAC__uint64 next_frame_sample = this_frame_sample + (FLAC__uint64)frame->header.blocksize;
- FLAC__uint64 target_sample = decoder->private_->target_sample;
-
- FLAC__ASSERT(frame->header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER);
-
- #if FLAC__HAS_OGG
- decoder->private_->got_a_frame = true;
- #endif
- decoder->private_->last_frame = *frame; /* save the frame */
- if(this_frame_sample <= target_sample && target_sample < next_frame_sample) { /* we hit our target frame */
- unsigned delta = (unsigned)(target_sample - this_frame_sample);
- /* kick out of seek mode */
- decoder->private_->is_seeking = false;
- /* shift out the samples before target_sample */
- if(delta > 0) {
- unsigned channel;
- const FLAC__int32 *newbuffer[FLAC__MAX_CHANNELS];
- for(channel = 0; channel < frame->header.channels; channel++)
- newbuffer[channel] = buffer[channel] + delta;
- decoder->private_->last_frame.header.blocksize -= delta;
- decoder->private_->last_frame.header.number.sample_number += (FLAC__uint64)delta;
- /* write the relevant samples */
- return decoder->private_->write_callback(decoder, &decoder->private_->last_frame, newbuffer, decoder->private_->client_data);
- }
- else {
- /* write the relevant samples */
- return decoder->private_->write_callback(decoder, frame, buffer, decoder->private_->client_data);
- }
- }
- else {
- return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
- }
- }
- else {
- /*
- * If we never got STREAMINFO, turn off MD5 checking to save
- * cycles since we don't have a sum to compare to anyway
- */
- if(!decoder->private_->has_stream_info)
- decoder->private_->do_md5_checking = false;
- if(decoder->private_->do_md5_checking) {
- if(!FLAC__MD5Accumulate(&decoder->private_->md5context, buffer, frame->header.channels, frame->header.blocksize, (frame->header.bits_per_sample+7) / 8))
- return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
- }
- return decoder->private_->write_callback(decoder, frame, buffer, decoder->private_->client_data);
- }
- }
-
- void send_error_to_client_(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status)
- {
- if(!decoder->private_->is_seeking)
- decoder->private_->error_callback(decoder, status, decoder->private_->client_data);
- else if(status == FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM)
- decoder->private_->unparseable_frame_count++;
- }
-
- FLAC__bool seek_to_absolute_sample_(FLAC__StreamDecoder *decoder, FLAC__uint64 stream_length, FLAC__uint64 target_sample)
- {
- FLAC__uint64 first_frame_offset = decoder->private_->first_frame_offset, lower_bound, upper_bound, lower_bound_sample, upper_bound_sample, this_frame_sample;
- FLAC__int64 pos = -1;
- int i;
- unsigned approx_bytes_per_frame;
- FLAC__bool first_seek = true;
- const FLAC__uint64 total_samples = FLAC__stream_decoder_get_total_samples(decoder);
- const unsigned min_blocksize = decoder->private_->stream_info.data.stream_info.min_blocksize;
- const unsigned max_blocksize = decoder->private_->stream_info.data.stream_info.max_blocksize;
- const unsigned max_framesize = decoder->private_->stream_info.data.stream_info.max_framesize;
- const unsigned min_framesize = decoder->private_->stream_info.data.stream_info.min_framesize;
- /* take these from the current frame in case they've changed mid-stream */
- unsigned channels = FLAC__stream_decoder_get_channels(decoder);
- unsigned bps = FLAC__stream_decoder_get_bits_per_sample(decoder);
- const FLAC__StreamMetadata_SeekTable *seek_table = decoder->private_->has_seek_table? &decoder->private_->seek_table.data.seek_table : 0;
-
- /* use values from stream info if we didn't decode a frame */
- if(channels == 0)
- channels = decoder->private_->stream_info.data.stream_info.channels;
- if(bps == 0)
- bps = decoder->private_->stream_info.data.stream_info.bits_per_sample;
-
- /* we are just guessing here */
- if(max_framesize > 0)
- approx_bytes_per_frame = (max_framesize + min_framesize) / 2 + 1;
- /*
- * Check if it's a known fixed-blocksize stream. Note that though
- * the spec doesn't allow zeroes in the STREAMINFO block, we may
- * never get a STREAMINFO block when decoding so the value of
- * min_blocksize might be zero.
- */
- else if(min_blocksize == max_blocksize && min_blocksize > 0) {
- /* note there are no () around 'bps/8' to keep precision up since it's an integer calulation */
- approx_bytes_per_frame = min_blocksize * channels * bps/8 + 64;
- }
- else
- approx_bytes_per_frame = 4096 * channels * bps/8 + 64;
-
- /*
- * First, we set an upper and lower bound on where in the
- * stream we will search. For now we assume the worst case
- * scenario, which is our best guess at the beginning of
- * the first frame and end of the stream.
- */
- lower_bound = first_frame_offset;
- lower_bound_sample = 0;
- upper_bound = stream_length;
- upper_bound_sample = total_samples > 0 ? total_samples : target_sample /*estimate it*/;
-
- /*
- * Now we refine the bounds if we have a seektable with
- * suitable points. Note that according to the spec they
- * must be ordered by ascending sample number.
- *
- * Note: to protect against invalid seek tables we will ignore points
- * that have frame_samples==0 or sample_number>=total_samples
- */
- if(seek_table) {
- FLAC__uint64 new_lower_bound = lower_bound;
- FLAC__uint64 new_upper_bound = upper_bound;
- FLAC__uint64 new_lower_bound_sample = lower_bound_sample;
- FLAC__uint64 new_upper_bound_sample = upper_bound_sample;
-
- /* find the closest seek point <= target_sample, if it exists */
- for(i = (int)seek_table->num_points - 1; i >= 0; i--) {
- if(
- seek_table->points[i].sample_number != FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER &&
- seek_table->points[i].frame_samples > 0 && /* defense against bad seekpoints */
- (total_samples <= 0 || seek_table->points[i].sample_number < total_samples) && /* defense against bad seekpoints */
- seek_table->points[i].sample_number <= target_sample
- )
- break;
- }
- if(i >= 0) { /* i.e. we found a suitable seek point... */
- new_lower_bound = first_frame_offset + seek_table->points[i].stream_offset;
- new_lower_bound_sample = seek_table->points[i].sample_number;
- }
-
- /* find the closest seek point > target_sample, if it exists */
- for(i = 0; i < (int)seek_table->num_points; i++) {
- if(
- seek_table->points[i].sample_number != FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER &&
- seek_table->points[i].frame_samples > 0 && /* defense against bad seekpoints */
- (total_samples <= 0 || seek_table->points[i].sample_number < total_samples) && /* defense against bad seekpoints */
- seek_table->points[i].sample_number > target_sample
- )
- break;
- }
- if(i < (int)seek_table->num_points) { /* i.e. we found a suitable seek point... */
- new_upper_bound = first_frame_offset + seek_table->points[i].stream_offset;
- new_upper_bound_sample = seek_table->points[i].sample_number;
- }
- /* final protection against unsorted seek tables; keep original values if bogus */
- if(new_upper_bound >= new_lower_bound) {
- lower_bound = new_lower_bound;
- upper_bound = new_upper_bound;
- lower_bound_sample = new_lower_bound_sample;
- upper_bound_sample = new_upper_bound_sample;
- }
- }
-
- FLAC__ASSERT(upper_bound_sample >= lower_bound_sample);
- /* there are 2 insidious ways that the following equality occurs, which
- * we need to fix:
- * 1) total_samples is 0 (unknown) and target_sample is 0
- * 2) total_samples is 0 (unknown) and target_sample happens to be
- * exactly equal to the last seek point in the seek table; this
- * means there is no seek point above it, and upper_bound_samples
- * remains equal to the estimate (of target_samples) we made above
- * in either case it does not hurt to move upper_bound_sample up by 1
- */
- if(upper_bound_sample == lower_bound_sample)
- upper_bound_sample++;
-
- decoder->private_->target_sample = target_sample;
- while(1) {
- /* check if the bounds are still ok */
- if (lower_bound_sample >= upper_bound_sample || lower_bound > upper_bound) {
- decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR;
- return false;
- }
- #ifndef FLAC__INTEGER_ONLY_LIBRARY
- #if defined _MSC_VER || defined __MINGW32__
- /* with VC++ you have to spoon feed it the casting */
- pos = (FLAC__int64)lower_bound + (FLAC__int64)((FLAC__double)(FLAC__int64)(target_sample - lower_bound_sample) / (FLAC__double)(FLAC__int64)(upper_bound_sample - lower_bound_sample) * (FLAC__double)(FLAC__int64)(upper_bound - lower_bound)) - approx_bytes_per_frame;
- #else
- pos = (FLAC__int64)lower_bound + (FLAC__int64)((FLAC__double)(target_sample - lower_bound_sample) / (FLAC__double)(upper_bound_sample - lower_bound_sample) * (FLAC__double)(upper_bound - lower_bound)) - approx_bytes_per_frame;
- #endif
- #else
- /* a little less accurate: */
- if(upper_bound - lower_bound < 0xffffffff)
- pos = (FLAC__int64)lower_bound + (FLAC__int64)(((target_sample - lower_bound_sample) * (upper_bound - lower_bound)) / (upper_bound_sample - lower_bound_sample)) - approx_bytes_per_frame;
- else /* @@@ WATCHOUT, ~2TB limit */
- pos = (FLAC__int64)lower_bound + (FLAC__int64)((((target_sample - lower_bound_sample)>>8) * ((upper_bound - lower_bound)>>8)) / ((upper_bound_sample - lower_bound_sample)>>16)) - approx_bytes_per_frame;
- #endif
- if(pos >= (FLAC__int64)upper_bound)
- pos = (FLAC__int64)upper_bound - 1;
- if(pos < (FLAC__int64)lower_bound)
- pos = (FLAC__int64)lower_bound;
- if(decoder->private_->seek_callback(decoder, (FLAC__uint64)pos, decoder->private_->client_data) != FLAC__STREAM_DECODER_SEEK_STATUS_OK) {
- decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR;
- return false;
- }
- if(!FLAC__stream_decoder_flush(decoder)) {
- /* above call sets the state for us */
- return false;
- }
- /* Now we need to get a frame. First we need to reset our
- * unparseable_frame_count; if we get too many unparseable
- * frames in a row, the read callback will return
- * FLAC__STREAM_DECODER_READ_STATUS_ABORT, causing
- * FLAC__stream_decoder_process_single() to return false.
- */
- decoder->private_->unparseable_frame_count = 0;
- if(!FLAC__stream_decoder_process_single(decoder)) {
- decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR;
- return false;
- }
- /* our write callback will change the state when it gets to the target frame */
- /* actually, we could have got_a_frame if our decoder is at FLAC__STREAM_DECODER_END_OF_STREAM so we need to check for that also */
- #if 0
- /*@@@@@@ used to be the following; not clear if the check for end of stream is needed anymore */
- if(decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_SEEKING && decoder->protected_->state != FLAC__STREAM_DECODER_END_OF_STREAM)
- break;
- #endif
- if(!decoder->private_->is_seeking)
- break;
-
- FLAC__ASSERT(decoder->private_->last_frame.header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER);
- this_frame_sample = decoder->private_->last_frame.header.number.sample_number;
-
- if (0 == decoder->private_->samples_decoded || (this_frame_sample + decoder->private_->last_frame.header.blocksize >= upper_bound_sample && !first_seek)) {
- if (pos == (FLAC__int64)lower_bound) {
- /* can't move back any more than the first frame, something is fatally wrong */
- decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR;
- return false;
- }
- /* our last move backwards wasn't big enough, try again */
- approx_bytes_per_frame = approx_bytes_per_frame? approx_bytes_per_frame * 2 : 16;
- continue;
- }
- /* allow one seek over upper bound, so we can get a correct upper_bound_sample for streams with unknown total_samples */
- first_seek = false;
-
- /* make sure we are not seeking in corrupted stream */
- if (this_frame_sample < lower_bound_sample) {
- decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR;
- return false;
- }
-
- /* we need to narrow the search */
- if(target_sample < this_frame_sample) {
- upper_bound_sample = this_frame_sample + decoder->private_->last_frame.header.blocksize;
- /*@@@@@@ what will decode position be if at end of stream? */
- if(!FLAC__stream_decoder_get_decode_position(decoder, &upper_bound)) {
- decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR;
- return false;
- }
- approx_bytes_per_frame = (unsigned)(2 * (upper_bound - pos) / 3 + 16);
- }
- else { /* target_sample >= this_frame_sample + this frame's blocksize */
- lower_bound_sample = this_frame_sample + decoder->private_->last_frame.header.blocksize;
- if(!FLAC__stream_decoder_get_decode_position(decoder, &lower_bound)) {
- decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR;
- return false;
- }
- approx_bytes_per_frame = (unsigned)(2 * (lower_bound - pos) / 3 + 16);
- }
- }
-
- return true;
- }
-
- #if FLAC__HAS_OGG
- FLAC__bool seek_to_absolute_sample_ogg_(FLAC__StreamDecoder *decoder, FLAC__uint64 stream_length, FLAC__uint64 target_sample)
- {
- FLAC__uint64 left_pos = 0, right_pos = stream_length;
- FLAC__uint64 left_sample = 0, right_sample = FLAC__stream_decoder_get_total_samples(decoder);
- FLAC__uint64 this_frame_sample = (FLAC__uint64)0 - 1;
- FLAC__uint64 pos = 0; /* only initialized to avoid compiler warning */
- FLAC__bool did_a_seek;
- unsigned iteration = 0;
-
- /* In the first iterations, we will calculate the target byte position
- * by the distance from the target sample to left_sample and
- * right_sample (let's call it "proportional search"). After that, we
- * will switch to binary search.
- */
- unsigned BINARY_SEARCH_AFTER_ITERATION = 2;
-
- /* We will switch to a linear search once our current sample is less
- * than this number of samples ahead of the target sample
- */
- static const FLAC__uint64 LINEAR_SEARCH_WITHIN_SAMPLES = FLAC__MAX_BLOCK_SIZE * 2;
-
- /* If the total number of samples is unknown, use a large value, and
- * force binary search immediately.
- */
- if(right_sample == 0) {
- right_sample = (FLAC__uint64)(-1);
- BINARY_SEARCH_AFTER_ITERATION = 0;
- }
-
- decoder->private_->target_sample = target_sample;
- for( ; ; iteration++) {
- if (iteration == 0 || this_frame_sample > target_sample || target_sample - this_frame_sample > LINEAR_SEARCH_WITHIN_SAMPLES) {
- if (iteration >= BINARY_SEARCH_AFTER_ITERATION) {
- pos = (right_pos + left_pos) / 2;
- }
- else {
- #ifndef FLAC__INTEGER_ONLY_LIBRARY
- #if defined _MSC_VER || defined __MINGW32__
- /* with MSVC you have to spoon feed it the casting */
- pos = (FLAC__uint64)((FLAC__double)(FLAC__int64)(target_sample - left_sample) / (FLAC__double)(FLAC__int64)(right_sample - left_sample) * (FLAC__double)(FLAC__int64)(right_pos - left_pos));
- #else
- pos = (FLAC__uint64)((FLAC__double)(target_sample - left_sample) / (FLAC__double)(right_sample - left_sample) * (FLAC__double)(right_pos - left_pos));
- #endif
- #else
- /* a little less accurate: */
- if ((target_sample-left_sample <= 0xffffffff) && (right_pos-left_pos <= 0xffffffff))
- pos = (FLAC__int64)(((target_sample-left_sample) * (right_pos-left_pos)) / (right_sample-left_sample));
- else /* @@@ WATCHOUT, ~2TB limit */
- pos = (FLAC__int64)((((target_sample-left_sample)>>8) * ((right_pos-left_pos)>>8)) / ((right_sample-left_sample)>>16));
- #endif
- /* @@@ TODO: might want to limit pos to some distance
- * before EOF, to make sure we land before the last frame,
- * thereby getting a this_frame_sample and so having a better
- * estimate.
- */
- }
-
- /* physical seek */
- if(decoder->private_->seek_callback((FLAC__StreamDecoder*)decoder, (FLAC__uint64)pos, decoder->private_->client_data) != FLAC__STREAM_DECODER_SEEK_STATUS_OK) {
- decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR;
- return false;
- }
- if(!FLAC__stream_decoder_flush(decoder)) {
- /* above call sets the state for us */
- return false;
- }
- did_a_seek = true;
- }
- else
- did_a_seek = false;
-
- decoder->private_->got_a_frame = false;
- if(!FLAC__stream_decoder_process_single(decoder)) {
- decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR;
- return false;
- }
- if(!decoder->private_->got_a_frame) {
- if(did_a_seek) {
- /* this can happen if we seek to a point after the last frame; we drop
- * to binary search right away in this case to avoid any wasted
- * iterations of proportional search.
- */
- right_pos = pos;
- BINARY_SEARCH_AFTER_ITERATION = 0;
- }
- else {
- /* this can probably only happen if total_samples is unknown and the
- * target_sample is past the end of the stream
- */
- decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR;
- return false;
- }
- }
- /* our write callback will change the state when it gets to the target frame */
- else if(!decoder->private_->is_seeking) {
- break;
- }
- else {
- this_frame_sample = decoder->private_->last_frame.header.number.sample_number;
- FLAC__ASSERT(decoder->private_->last_frame.header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER);
-
- if (did_a_seek) {
- if (this_frame_sample <= target_sample) {
- /* The 'equal' case should not happen, since
- * FLAC__stream_decoder_process_single()
- * should recognize that it has hit the
- * target sample and we would exit through
- * the 'break' above.
- */
- FLAC__ASSERT(this_frame_sample != target_sample);
-
- left_sample = this_frame_sample;
- /* sanity check to avoid infinite loop */
- if (left_pos == pos) {
- decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR;
- return false;
- }
- left_pos = pos;
- }
- else if(this_frame_sample > target_sample) {
- right_sample = this_frame_sample;
- /* sanity check to avoid infinite loop */
- if (right_pos == pos) {
- decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR;
- return false;
- }
- right_pos = pos;
- }
- }
- }
- }
-
- return true;
- }
- #endif
-
- FLAC__StreamDecoderReadStatus file_read_callback_dec(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data)
- {
- (void)client_data;
-
- if(*bytes > 0) {
- *bytes = fread(buffer, sizeof(FLAC__byte), *bytes, decoder->private_->file);
- if(ferror(decoder->private_->file))
- return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
- else if(*bytes == 0)
- return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
- else
- return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
- }
- else
- return FLAC__STREAM_DECODER_READ_STATUS_ABORT; /* abort to avoid a deadlock */
- }
-
- FLAC__StreamDecoderSeekStatus file_seek_callback_dec(const FLAC__StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data)
- {
- (void)client_data;
-
- if(decoder->private_->file == stdin)
- return FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED;
- else if(fseeko(decoder->private_->file, (off_t)absolute_byte_offset, SEEK_SET) < 0)
- return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR;
- else
- return FLAC__STREAM_DECODER_SEEK_STATUS_OK;
- }
-
- FLAC__StreamDecoderTellStatus file_tell_callback_dec(const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
- {
- off_t pos;
- (void)client_data;
-
- if(decoder->private_->file == stdin)
- return FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED;
- else if((pos = ftello(decoder->private_->file)) < 0)
- return FLAC__STREAM_DECODER_TELL_STATUS_ERROR;
- else {
- *absolute_byte_offset = (FLAC__uint64)pos;
- return FLAC__STREAM_DECODER_TELL_STATUS_OK;
- }
- }
-
- FLAC__StreamDecoderLengthStatus file_length_callback_(const FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data)
- {
- struct stat filestats;
- (void)client_data;
-
- if(decoder->private_->file == stdin)
- return FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED;
- else if(fstat(fileno(decoder->private_->file), &filestats) != 0)
- return FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR;
- else {
- *stream_length = (FLAC__uint64)filestats.st_size;
- return FLAC__STREAM_DECODER_LENGTH_STATUS_OK;
- }
- }
-
- FLAC__bool file_eof_callback_(const FLAC__StreamDecoder *decoder, void *client_data)
- {
- (void)client_data;
-
- return feof(decoder->private_->file)? true : false;
- }
-
- #endif
- /********* End of inlined file: stream_decoder.c *********/
-
- /********* Start of inlined file: stream_encoder.c *********/
-
- /********* Start of inlined file: juce_FlacHeader.h *********/
- // This file is included at the start of each FLAC .c file, just to do a few housekeeping
- // tasks..
-
- #define VERSION "1.2.1"
-
- #define FLAC__NO_DLL 1
-
- #ifdef _MSC_VER
- #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4312)
- #endif
-
- #if ! (defined (_WIN32) || defined (_WIN64) || defined (LINUX))
- #define FLAC__SYS_DARWIN 1
- #endif
- /********* End of inlined file: juce_FlacHeader.h *********/
-
- #if JUCE_USE_FLAC
-
- #if HAVE_CONFIG_H
- # include <config.h>
- #endif
-
- #if defined _MSC_VER || defined __MINGW32__
- #include <io.h> /* for _setmode() */
- #include <fcntl.h> /* for _O_BINARY */
- #endif
- #if defined __CYGWIN__ || defined __EMX__
- #include <io.h> /* for setmode(), O_BINARY */
- #include <fcntl.h> /* for _O_BINARY */
- #endif
- #include <limits.h>
- #include <stdio.h>
- #include <stdlib.h> /* for malloc() */
- #include <string.h> /* for memcpy() */
- #include <sys/types.h> /* for off_t */
- #if defined _MSC_VER || defined __BORLANDC__ || defined __MINGW32__
- #if _MSC_VER <= 1600 || defined __BORLANDC__ /* @@@ [2G limit] */
- #define fseeko fseek
- #define ftello ftell
- #endif
- #endif
-
- /********* Start of inlined file: stream_encoder.h *********/
- #ifndef FLAC__PROTECTED__STREAM_ENCODER_H
- #define FLAC__PROTECTED__STREAM_ENCODER_H
-
- #if FLAC__HAS_OGG
- #include "private/ogg_encoder_aspect.h"
- #endif
-
- #ifndef FLAC__INTEGER_ONLY_LIBRARY
-
- #define FLAC__MAX_APODIZATION_FUNCTIONS 32
-
- typedef enum {
- FLAC__APODIZATION_BARTLETT,
- FLAC__APODIZATION_BARTLETT_HANN,
- FLAC__APODIZATION_BLACKMAN,
- FLAC__APODIZATION_BLACKMAN_HARRIS_4TERM_92DB_SIDELOBE,
- FLAC__APODIZATION_CONNES,
- FLAC__APODIZATION_FLATTOP,
- FLAC__APODIZATION_GAUSS,
- FLAC__APODIZATION_HAMMING,
- FLAC__APODIZATION_HANN,
- FLAC__APODIZATION_KAISER_BESSEL,
- FLAC__APODIZATION_NUTTALL,
- FLAC__APODIZATION_RECTANGLE,
- FLAC__APODIZATION_TRIANGLE,
- FLAC__APODIZATION_TUKEY,
- FLAC__APODIZATION_WELCH
- } FLAC__ApodizationFunction;
-
- typedef struct {
- FLAC__ApodizationFunction type;
- union {
- struct {
- FLAC__real stddev;
- } gauss;
- struct {
- FLAC__real p;
- } tukey;
- } parameters;
- } FLAC__ApodizationSpecification;
-
- #endif // #ifndef FLAC__INTEGER_ONLY_LIBRARY
-
- typedef struct FLAC__StreamEncoderProtected {
- FLAC__StreamEncoderState state;
- FLAC__bool verify;
- FLAC__bool streamable_subset;
- FLAC__bool do_md5;
- FLAC__bool do_mid_side_stereo;
- FLAC__bool loose_mid_side_stereo;
- unsigned channels;
- unsigned bits_per_sample;
- unsigned sample_rate;
- unsigned blocksize;
- #ifndef FLAC__INTEGER_ONLY_LIBRARY
- unsigned num_apodizations;
- FLAC__ApodizationSpecification apodizations[FLAC__MAX_APODIZATION_FUNCTIONS];
- #endif
- unsigned max_lpc_order;
- unsigned qlp_coeff_precision;
- FLAC__bool do_qlp_coeff_prec_search;
- FLAC__bool do_exhaustive_model_search;
- FLAC__bool do_escape_coding;
- unsigned min_residual_partition_order;
- unsigned max_residual_partition_order;
- unsigned rice_parameter_search_dist;
- FLAC__uint64 total_samples_estimate;
- FLAC__StreamMetadata **metadata;
- unsigned num_metadata_blocks;
- FLAC__uint64 streaminfo_offset, seektable_offset, audio_offset;
- #if FLAC__HAS_OGG
- FLAC__OggEncoderAspect ogg_encoder_aspect;
- #endif
- } FLAC__StreamEncoderProtected;
-
- #endif
- /********* End of inlined file: stream_encoder.h *********/
-
- #if FLAC__HAS_OGG
- #include "include/private/ogg_helper.h"
- #include "include/private/ogg_mapping.h"
- #endif
-
- /********* Start of inlined file: stream_encoder_framing.h *********/
- #ifndef FLAC__PRIVATE__STREAM_ENCODER_FRAMING_H
- #define FLAC__PRIVATE__STREAM_ENCODER_FRAMING_H
-
- FLAC__bool FLAC__add_metadata_block(const FLAC__StreamMetadata *metadata, FLAC__BitWriter *bw);
- FLAC__bool FLAC__frame_add_header(const FLAC__FrameHeader *header, FLAC__BitWriter *bw);
- FLAC__bool FLAC__subframe_add_constant(const FLAC__Subframe_Constant *subframe, unsigned subframe_bps, unsigned wasted_bits, FLAC__BitWriter *bw);
- FLAC__bool FLAC__subframe_add_fixed(const FLAC__Subframe_Fixed *subframe, unsigned residual_samples, unsigned subframe_bps, unsigned wasted_bits, FLAC__BitWriter *bw);
- FLAC__bool FLAC__subframe_add_lpc(const FLAC__Subframe_LPC *subframe, unsigned residual_samples, unsigned subframe_bps, unsigned wasted_bits, FLAC__BitWriter *bw);
- FLAC__bool FLAC__subframe_add_verbatim(const FLAC__Subframe_Verbatim *subframe, unsigned samples, unsigned subframe_bps, unsigned wasted_bits, FLAC__BitWriter *bw);
-
- #endif
- /********* End of inlined file: stream_encoder_framing.h *********/
-
- /********* Start of inlined file: window.h *********/
- #ifndef FLAC__PRIVATE__WINDOW_H
- #define FLAC__PRIVATE__WINDOW_H
-
- #ifdef HAVE_CONFIG_H
- #include <config.h>
- #endif
-
- #ifndef FLAC__INTEGER_ONLY_LIBRARY
-
- /*
- * FLAC__window_*()
- * --------------------------------------------------------------------
- * Calculates window coefficients according to different apodization
- * functions.
- *
- * OUT window[0,L-1]
- * IN L (number of points in window)
- */
- void FLAC__window_bartlett(FLAC__real *window, const FLAC__int32 L);
- void FLAC__window_bartlett_hann(FLAC__real *window, const FLAC__int32 L);
- void FLAC__window_blackman(FLAC__real *window, const FLAC__int32 L);
- void FLAC__window_blackman_harris_4term_92db_sidelobe(FLAC__real *window, const FLAC__int32 L);
- void FLAC__window_connes(FLAC__real *window, const FLAC__int32 L);
- void FLAC__window_flattop(FLAC__real *window, const FLAC__int32 L);
- void FLAC__window_gauss(FLAC__real *window, const FLAC__int32 L, const FLAC__real stddev); /* 0.0 < stddev <= 0.5 */
- void FLAC__window_hamming(FLAC__real *window, const FLAC__int32 L);
- void FLAC__window_hann(FLAC__real *window, const FLAC__int32 L);
- void FLAC__window_kaiser_bessel(FLAC__real *window, const FLAC__int32 L);
- void FLAC__window_nuttall(FLAC__real *window, const FLAC__int32 L);
- void FLAC__window_rectangle(FLAC__real *window, const FLAC__int32 L);
- void FLAC__window_triangle(FLAC__real *window, const FLAC__int32 L);
- void FLAC__window_tukey(FLAC__real *window, const FLAC__int32 L, const FLAC__real p);
- void FLAC__window_welch(FLAC__real *window, const FLAC__int32 L);
-
- #endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */
-
- #endif
- /********* End of inlined file: window.h *********/
-
- #ifndef FLaC__INLINE
- #define FLaC__INLINE
- #endif
-
- #ifdef min
- #undef min
- #endif
- #define min(x,y) ((x)<(y)?(x):(y))
-
- #ifdef max
- #undef max
- #endif
- #define max(x,y) ((x)>(y)?(x):(y))
-
- /* Exact Rice codeword length calculation is off by default. The simple
- * (and fast) estimation (of how many bits a residual value will be
- * encoded with) in this encoder is very good, almost always yielding
- * compression within 0.1% of exact calculation.
- */
- #undef EXACT_RICE_BITS_CALCULATION
- /* Rice parameter searching is off by default. The simple (and fast)
- * parameter estimation in this encoder is very good, almost always
- * yielding compression within 0.1% of the optimal parameters.
- */
- #undef ENABLE_RICE_PARAMETER_SEARCH
-
- typedef struct {
- FLAC__int32 *data[FLAC__MAX_CHANNELS];
- unsigned size; /* of each data[] in samples */
- unsigned tail;
- } verify_input_fifo;
-
- typedef struct {
- const FLAC__byte *data;
- unsigned capacity;
- unsigned bytes;
- } verify_output;
-
- typedef enum {
- ENCODER_IN_MAGIC = 0,
- ENCODER_IN_METADATA = 1,
- ENCODER_IN_AUDIO = 2
- } EncoderStateHint;
-
- static struct CompressionLevels {
- FLAC__bool do_mid_side_stereo;
- FLAC__bool loose_mid_side_stereo;
- unsigned max_lpc_order;
- unsigned qlp_coeff_precision;
- FLAC__bool do_qlp_coeff_prec_search;
- FLAC__bool do_escape_coding;
- FLAC__bool do_exhaustive_model_search;
- unsigned min_residual_partition_order;
- unsigned max_residual_partition_order;
- unsigned rice_parameter_search_dist;
- } compression_levels_[] = {
- { false, false, 0, 0, false, false, false, 0, 3, 0 },
- { true , true , 0, 0, false, false, false, 0, 3, 0 },
- { true , false, 0, 0, false, false, false, 0, 3, 0 },
- { false, false, 6, 0, false, false, false, 0, 4, 0 },
- { true , true , 8, 0, false, false, false, 0, 4, 0 },
- { true , false, 8, 0, false, false, false, 0, 5, 0 },
- { true , false, 8, 0, false, false, false, 0, 6, 0 },
- { true , false, 8, 0, false, false, true , 0, 6, 0 },
- { true , false, 12, 0, false, false, true , 0, 6, 0 }
- };
-
- /***********************************************************************
- *
- * Private class method prototypes
- *
- ***********************************************************************/
-
- static void set_defaults_enc(FLAC__StreamEncoder *encoder);
- static void free_(FLAC__StreamEncoder *encoder);
- static FLAC__bool resize_buffers_(FLAC__StreamEncoder *encoder, unsigned new_blocksize);
- static FLAC__bool write_bitbuffer_(FLAC__StreamEncoder *encoder, unsigned samples, FLAC__bool is_last_block);
- static FLAC__StreamEncoderWriteStatus write_frame_(FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], size_t bytes, unsigned samples, FLAC__bool is_last_block);
- static void update_metadata_(const FLAC__StreamEncoder *encoder);
- #if FLAC__HAS_OGG
- static void update_ogg_metadata_(FLAC__StreamEncoder *encoder);
- #endif
- static FLAC__bool process_frame_(FLAC__StreamEncoder *encoder, FLAC__bool is_fractional_block, FLAC__bool is_last_block);
- static FLAC__bool process_subframes_(FLAC__StreamEncoder *encoder, FLAC__bool is_fractional_block);
-
- static FLAC__bool process_subframe_(
- FLAC__StreamEncoder *encoder,
- unsigned min_partition_order,
- unsigned max_partition_order,
- const FLAC__FrameHeader *frame_header,
- unsigned subframe_bps,
- const FLAC__int32 integer_signal[],
- FLAC__Subframe *subframe[2],
- FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents[2],
- FLAC__int32 *residual[2],
- unsigned *best_subframe,
- unsigned *best_bits
- );
-
- static FLAC__bool add_subframe_(
- FLAC__StreamEncoder *encoder,
- unsigned blocksize,
- unsigned subframe_bps,
- const FLAC__Subframe *subframe,
- FLAC__BitWriter *frame
- );
-
- static unsigned evaluate_constant_subframe_(
- FLAC__StreamEncoder *encoder,
- const FLAC__int32 signal,
- unsigned blocksize,
- unsigned subframe_bps,
- FLAC__Subframe *subframe
- );
-
- static unsigned evaluate_fixed_subframe_(
- FLAC__StreamEncoder *encoder,
- const FLAC__int32 signal[],
- FLAC__int32 residual[],
- FLAC__uint64 abs_residual_partition_sums[],
- unsigned raw_bits_per_partition[],
- unsigned blocksize,
- unsigned subframe_bps,
- unsigned order,
- unsigned rice_parameter,
- unsigned rice_parameter_limit,
- unsigned min_partition_order,
- unsigned max_partition_order,
- FLAC__bool do_escape_coding,
- unsigned rice_parameter_search_dist,
- FLAC__Subframe *subframe,
- FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents
- );
-
- #ifndef FLAC__INTEGER_ONLY_LIBRARY
- static unsigned evaluate_lpc_subframe_(
- FLAC__StreamEncoder *encoder,
- const FLAC__int32 signal[],
- FLAC__int32 residual[],
- FLAC__uint64 abs_residual_partition_sums[],
- unsigned raw_bits_per_partition[],
- const FLAC__real lp_coeff[],
- unsigned blocksize,
- unsigned subframe_bps,
- unsigned order,
- unsigned qlp_coeff_precision,
- unsigned rice_parameter,
- unsigned rice_parameter_limit,
- unsigned min_partition_order,
- unsigned max_partition_order,
- FLAC__bool do_escape_coding,
- unsigned rice_parameter_search_dist,
- FLAC__Subframe *subframe,
- FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents
- );
- #endif
-
- static unsigned evaluate_verbatim_subframe_(
- FLAC__StreamEncoder *encoder,
- const FLAC__int32 signal[],
- unsigned blocksize,
- unsigned subframe_bps,
- FLAC__Subframe *subframe
- );
-
- static unsigned find_best_partition_order_(
- struct FLAC__StreamEncoderPrivate *private_,
- const FLAC__int32 residual[],
- FLAC__uint64 abs_residual_partition_sums[],
- unsigned raw_bits_per_partition[],
- unsigned residual_samples,
- unsigned predictor_order,
- unsigned rice_parameter,
- unsigned rice_parameter_limit,
- unsigned min_partition_order,
- unsigned max_partition_order,
- unsigned bps,
- FLAC__bool do_escape_coding,
- unsigned rice_parameter_search_dist,
- FLAC__EntropyCodingMethod *best_ecm
- );
-
- static void precompute_partition_info_sums_(
- const FLAC__int32 residual[],
- FLAC__uint64 abs_residual_partition_sums[],
- unsigned residual_samples,
- unsigned predictor_order,
- unsigned min_partition_order,
- unsigned max_partition_order,
- unsigned bps
- );
-
- static void precompute_partition_info_escapes_(
- const FLAC__int32 residual[],
- unsigned raw_bits_per_partition[],
- unsigned residual_samples,
- unsigned predictor_order,
- unsigned min_partition_order,
- unsigned max_partition_order
- );
-
- static FLAC__bool set_partitioned_rice_(
- #ifdef EXACT_RICE_BITS_CALCULATION
- const FLAC__int32 residual[],
- #endif
- const FLAC__uint64 abs_residual_partition_sums[],
- const unsigned raw_bits_per_partition[],
- const unsigned residual_samples,
- const unsigned predictor_order,
- const unsigned suggested_rice_parameter,
- const unsigned rice_parameter_limit,
- const unsigned rice_parameter_search_dist,
- const unsigned partition_order,
- const FLAC__bool search_for_escapes,
- FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents,
- unsigned *bits
- );
-
- static unsigned get_wasted_bits_(FLAC__int32 signal[], unsigned samples);
-
- /* verify-related routines: */
- static void append_to_verify_fifo_(
- verify_input_fifo *fifo,
- const FLAC__int32 * const input[],
- unsigned input_offset,
- unsigned channels,
- unsigned wide_samples
- );
-
- static void append_to_verify_fifo_interleaved_(
- verify_input_fifo *fifo,
- const FLAC__int32 input[],
- unsigned input_offset,
- unsigned channels,
- unsigned wide_samples
- );
-
- static FLAC__StreamDecoderReadStatus verify_read_callback_(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data);
- static FLAC__StreamDecoderWriteStatus verify_write_callback_(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data);
- static void verify_metadata_callback_(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data);
- static void verify_error_callback_(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);
-
- static FLAC__StreamEncoderReadStatus file_read_callback_enc(const FLAC__StreamEncoder *encoder, FLAC__byte buffer[], size_t *bytes, void *client_data);
- static FLAC__StreamEncoderSeekStatus file_seek_callback_enc(const FLAC__StreamEncoder *encoder, FLAC__uint64 absolute_byte_offset, void *client_data);
- static FLAC__StreamEncoderTellStatus file_tell_callback_enc(const FLAC__StreamEncoder *encoder, FLAC__uint64 *absolute_byte_offset, void *client_data);
- static FLAC__StreamEncoderWriteStatus file_write_callback_(const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], size_t bytes, unsigned samples, unsigned current_frame, void *client_data);
- static FILE *get_binary_stdout_(void);
-
- /***********************************************************************
- *
- * Private class data
- *
- ***********************************************************************/
-
- typedef struct FLAC__StreamEncoderPrivate {
- unsigned input_capacity; /* current size (in samples) of the signal and residual buffers */
- FLAC__int32 *integer_signal[FLAC__MAX_CHANNELS]; /* the integer version of the input signal */
- FLAC__int32 *integer_signal_mid_side[2]; /* the integer version of the mid-side input signal (stereo only) */
- #ifndef FLAC__INTEGER_ONLY_LIBRARY
- FLAC__real *real_signal[FLAC__MAX_CHANNELS]; /* (@@@ currently unused) the floating-point version of the input signal */
- FLAC__real *real_signal_mid_side[2]; /* (@@@ currently unused) the floating-point version of the mid-side input signal (stereo only) */
- FLAC__real *window[FLAC__MAX_APODIZATION_FUNCTIONS]; /* the pre-computed floating-point window for each apodization function */
- FLAC__real *windowed_signal; /* the integer_signal[] * current window[] */
- #endif
- unsigned subframe_bps[FLAC__MAX_CHANNELS]; /* the effective bits per sample of the input signal (stream bps - wasted bits) */
- unsigned subframe_bps_mid_side[2]; /* the effective bits per sample of the mid-side input signal (stream bps - wasted bits + 0/1) */
- FLAC__int32 *residual_workspace[FLAC__MAX_CHANNELS][2]; /* each channel has a candidate and best workspace where the subframe residual signals will be stored */
- FLAC__int32 *residual_workspace_mid_side[2][2];
- FLAC__Subframe subframe_workspace[FLAC__MAX_CHANNELS][2];
- FLAC__Subframe subframe_workspace_mid_side[2][2];
- FLAC__Subframe *subframe_workspace_ptr[FLAC__MAX_CHANNELS][2];
- FLAC__Subframe *subframe_workspace_ptr_mid_side[2][2];
- FLAC__EntropyCodingMethod_PartitionedRiceContents partitioned_rice_contents_workspace[FLAC__MAX_CHANNELS][2];
- FLAC__EntropyCodingMethod_PartitionedRiceContents partitioned_rice_contents_workspace_mid_side[FLAC__MAX_CHANNELS][2];
- FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents_workspace_ptr[FLAC__MAX_CHANNELS][2];
- FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents_workspace_ptr_mid_side[FLAC__MAX_CHANNELS][2];
- unsigned best_subframe[FLAC__MAX_CHANNELS]; /* index (0 or 1) into 2nd dimension of the above workspaces */
- unsigned best_subframe_mid_side[2];
- unsigned best_subframe_bits[FLAC__MAX_CHANNELS]; /* size in bits of the best subframe for each channel */
- unsigned best_subframe_bits_mid_side[2];
- FLAC__uint64 *abs_residual_partition_sums; /* workspace where the sum of abs(candidate residual) for each partition is stored */
- unsigned *raw_bits_per_partition; /* workspace where the sum of silog2(candidate residual) for each partition is stored */
- FLAC__BitWriter *frame; /* the current frame being worked on */
- unsigned loose_mid_side_stereo_frames; /* rounded number of frames the encoder will use before trying both independent and mid/side frames again */
- unsigned loose_mid_side_stereo_frame_count; /* number of frames using the current channel assignment */
- FLAC__ChannelAssignment last_channel_assignment;
- FLAC__StreamMetadata streaminfo; /* scratchpad for STREAMINFO as it is built */
- FLAC__StreamMetadata_SeekTable *seek_table; /* pointer into encoder->protected_->metadata_ where the seek table is */
- unsigned current_sample_number;
- unsigned current_frame_number;
- FLAC__MD5Context md5context;
- FLAC__CPUInfo cpuinfo;
- #ifndef FLAC__INTEGER_ONLY_LIBRARY
- unsigned (*local_fixed_compute_best_predictor)(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]);
- #else
- unsigned (*local_fixed_compute_best_predictor)(const FLAC__int32 data[], unsigned data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]);
- #endif
- #ifndef FLAC__INTEGER_ONLY_LIBRARY
- void (*local_lpc_compute_autocorrelation)(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]);
- void (*local_lpc_compute_residual_from_qlp_coefficients)(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]);
- void (*local_lpc_compute_residual_from_qlp_coefficients_64bit)(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]);
- void (*local_lpc_compute_residual_from_qlp_coefficients_16bit)(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]);
- #endif
- FLAC__bool use_wide_by_block; /* use slow 64-bit versions of some functions because of the block size */
- FLAC__bool use_wide_by_partition; /* use slow 64-bit versions of some functions because of the min partition order and blocksize */
- FLAC__bool use_wide_by_order; /* use slow 64-bit versions of some functions because of the lpc order */
- FLAC__bool disable_constant_subframes;
- FLAC__bool disable_fixed_subframes;
- FLAC__bool disable_verbatim_subframes;
- #if FLAC__HAS_OGG
- FLAC__bool is_ogg;
- #endif
- FLAC__StreamEncoderReadCallback read_callback; /* currently only needed for Ogg FLAC */
- FLAC__StreamEncoderSeekCallback seek_callback;
- FLAC__StreamEncoderTellCallback tell_callback;
- FLAC__StreamEncoderWriteCallback write_callback;
- FLAC__StreamEncoderMetadataCallback metadata_callback;
- FLAC__StreamEncoderProgressCallback progress_callback;
- void *client_data;
- unsigned first_seekpoint_to_check;
- FILE *file; /* only used when encoding to a file */
- FLAC__uint64 bytes_written;
- FLAC__uint64 samples_written;
- unsigned frames_written;
- unsigned total_frames_estimate;
- /* unaligned (original) pointers to allocated data */
- FLAC__int32 *integer_signal_unaligned[FLAC__MAX_CHANNELS];
- FLAC__int32 *integer_signal_mid_side_unaligned[2];
- #ifndef FLAC__INTEGER_ONLY_LIBRARY
- FLAC__real *real_signal_unaligned[FLAC__MAX_CHANNELS]; /* (@@@ currently unused) */
- FLAC__real *real_signal_mid_side_unaligned[2]; /* (@@@ currently unused) */
- FLAC__real *window_unaligned[FLAC__MAX_APODIZATION_FUNCTIONS];
- FLAC__real *windowed_signal_unaligned;
- #endif
- FLAC__int32 *residual_workspace_unaligned[FLAC__MAX_CHANNELS][2];
- FLAC__int32 *residual_workspace_mid_side_unaligned[2][2];
- FLAC__uint64 *abs_residual_partition_sums_unaligned;
- unsigned *raw_bits_per_partition_unaligned;
- /*
- * These fields have been moved here from private function local
- * declarations merely to save stack space during encoding.
- */
- #ifndef FLAC__INTEGER_ONLY_LIBRARY
- FLAC__real lp_coeff[FLAC__MAX_LPC_ORDER][FLAC__MAX_LPC_ORDER]; /* from process_subframe_() */
- #endif
- FLAC__EntropyCodingMethod_PartitionedRiceContents partitioned_rice_contents_extra[2]; /* from find_best_partition_order_() */
- /*
- * The data for the verify section
- */
- struct {
- FLAC__StreamDecoder *decoder;
- EncoderStateHint state_hint;
- FLAC__bool needs_magic_hack;
- verify_input_fifo input_fifo;
- verify_output output;
- struct {
- FLAC__uint64 absolute_sample;
- unsigned frame_number;
- unsigned channel;
- unsigned sample;
- FLAC__int32 expected;
- FLAC__int32 got;
- } error_stats;
- } verify;
- FLAC__bool is_being_deleted; /* if true, call to ..._finish() from ..._delete() will not call the callbacks */
- } FLAC__StreamEncoderPrivate;
-
- /***********************************************************************
- *
- * Public static class data
- *
- ***********************************************************************/
-
- FLAC_API const char * const FLAC__StreamEncoderStateString[] = {
- "FLAC__STREAM_ENCODER_OK",
- "FLAC__STREAM_ENCODER_UNINITIALIZED",
- "FLAC__STREAM_ENCODER_OGG_ERROR",
- "FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR",
- "FLAC__STREAM_ENCODER_VERIFY_MISMATCH_IN_AUDIO_DATA",
- "FLAC__STREAM_ENCODER_CLIENT_ERROR",
- "FLAC__STREAM_ENCODER_IO_ERROR",
- "FLAC__STREAM_ENCODER_FRAMING_ERROR",
- "FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR"
- };
-
- FLAC_API const char * const FLAC__StreamEncoderInitStatusString[] = {
- "FLAC__STREAM_ENCODER_INIT_STATUS_OK",
- "FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR",
- "FLAC__STREAM_ENCODER_INIT_STATUS_UNSUPPORTED_CONTAINER",
- "FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_CALLBACKS",
- "FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_NUMBER_OF_CHANNELS",
- "FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_BITS_PER_SAMPLE",
- "FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_SAMPLE_RATE",
- "FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_BLOCK_SIZE",
- "FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_MAX_LPC_ORDER",
- "FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_QLP_COEFF_PRECISION",
- "FLAC__STREAM_ENCODER_INIT_STATUS_BLOCK_SIZE_TOO_SMALL_FOR_LPC_ORDER",
- "FLAC__STREAM_ENCODER_INIT_STATUS_NOT_STREAMABLE",
- "FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_METADATA",
- "FLAC__STREAM_ENCODER_INIT_STATUS_ALREADY_INITIALIZED"
- };
-
- FLAC_API const char * const FLAC__treamEncoderReadStatusString[] = {
- "FLAC__STREAM_ENCODER_READ_STATUS_CONTINUE",
- "FLAC__STREAM_ENCODER_READ_STATUS_END_OF_STREAM",
- "FLAC__STREAM_ENCODER_READ_STATUS_ABORT",
- "FLAC__STREAM_ENCODER_READ_STATUS_UNSUPPORTED"
- };
-
- FLAC_API const char * const FLAC__StreamEncoderWriteStatusString[] = {
- "FLAC__STREAM_ENCODER_WRITE_STATUS_OK",
- "FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR"
- };
-
- FLAC_API const char * const FLAC__StreamEncoderSeekStatusString[] = {
- "FLAC__STREAM_ENCODER_SEEK_STATUS_OK",
- "FLAC__STREAM_ENCODER_SEEK_STATUS_ERROR",
- "FLAC__STREAM_ENCODER_SEEK_STATUS_UNSUPPORTED"
- };
-
- FLAC_API const char * const FLAC__StreamEncoderTellStatusString[] = {
- "FLAC__STREAM_ENCODER_TELL_STATUS_OK",
- "FLAC__STREAM_ENCODER_TELL_STATUS_ERROR",
- "FLAC__STREAM_ENCODER_TELL_STATUS_UNSUPPORTED"
- };
-
- /* Number of samples that will be overread to watch for end of stream. By
- * 'overread', we mean that the FLAC__stream_encoder_process*() calls will
- * always try to read blocksize+1 samples before encoding a block, so that
- * even if the stream has a total sample count that is an integral multiple
- * of the blocksize, we will still notice when we are encoding the last
- * block. This is needed, for example, to correctly set the end-of-stream
- * marker in Ogg FLAC.
- *
- * WATCHOUT: some parts of the code assert that OVERREAD_ == 1 and there's
- * not really any reason to change it.
- */
- static const unsigned OVERREAD_ = 1;
-
- /***********************************************************************
- *
- * Class constructor/destructor
- *
- */
- FLAC_API FLAC__StreamEncoder *FLAC__stream_encoder_new(void)
- {
- FLAC__StreamEncoder *encoder;
- unsigned i;
-
- FLAC__ASSERT(sizeof(int) >= 4); /* we want to die right away if this is not true */
-
- encoder = (FLAC__StreamEncoder*)calloc(1, sizeof(FLAC__StreamEncoder));
- if(encoder == 0) {
- return 0;
- }
-
- encoder->protected_ = (FLAC__StreamEncoderProtected*)calloc(1, sizeof(FLAC__StreamEncoderProtected));
- if(encoder->protected_ == 0) {
- free(encoder);
- return 0;
- }
-
- encoder->private_ = (FLAC__StreamEncoderPrivate*)calloc(1, sizeof(FLAC__StreamEncoderPrivate));
- if(encoder->private_ == 0) {
- free(encoder->protected_);
- free(encoder);
- return 0;
- }
-
- encoder->private_->frame = FLAC__bitwriter_new();
- if(encoder->private_->frame == 0) {
- free(encoder->private_);
- free(encoder->protected_);
- free(encoder);
- return 0;
- }
-
- encoder->private_->file = 0;
-
- set_defaults_enc(encoder);
-
- encoder->private_->is_being_deleted = false;
-
- for(i = 0; i < FLAC__MAX_CHANNELS; i++) {
- encoder->private_->subframe_workspace_ptr[i][0] = &encoder->private_->subframe_workspace[i][0];
- encoder->private_->subframe_workspace_ptr[i][1] = &encoder->private_->subframe_workspace[i][1];
- }
- for(i = 0; i < 2; i++) {
- encoder->private_->subframe_workspace_ptr_mid_side[i][0] = &encoder->private_->subframe_workspace_mid_side[i][0];
- encoder->private_->subframe_workspace_ptr_mid_side[i][1] = &encoder->private_->subframe_workspace_mid_side[i][1];
- }
- for(i = 0; i < FLAC__MAX_CHANNELS; i++) {
- encoder->private_->partitioned_rice_contents_workspace_ptr[i][0] = &encoder->private_->partitioned_rice_contents_workspace[i][0];
- encoder->private_->partitioned_rice_contents_workspace_ptr[i][1] = &encoder->private_->partitioned_rice_contents_workspace[i][1];
- }
- for(i = 0; i < 2; i++) {
- encoder->private_->partitioned_rice_contents_workspace_ptr_mid_side[i][0] = &encoder->private_->partitioned_rice_contents_workspace_mid_side[i][0];
- encoder->private_->partitioned_rice_contents_workspace_ptr_mid_side[i][1] = &encoder->private_->partitioned_rice_contents_workspace_mid_side[i][1];
- }
-
- for(i = 0; i < FLAC__MAX_CHANNELS; i++) {
- FLAC__format_entropy_coding_method_partitioned_rice_contents_init(&encoder->private_->partitioned_rice_contents_workspace[i][0]);
- FLAC__format_entropy_coding_method_partitioned_rice_contents_init(&encoder->private_->partitioned_rice_contents_workspace[i][1]);
- }
- for(i = 0; i < 2; i++) {
- FLAC__format_entropy_coding_method_partitioned_rice_contents_init(&encoder->private_->partitioned_rice_contents_workspace_mid_side[i][0]);
- FLAC__format_entropy_coding_method_partitioned_rice_contents_init(&encoder->private_->partitioned_rice_contents_workspace_mid_side[i][1]);
- }
- for(i = 0; i < 2; i++)
- FLAC__format_entropy_coding_method_partitioned_rice_contents_init(&encoder->private_->partitioned_rice_contents_extra[i]);
-
- encoder->protected_->state = FLAC__STREAM_ENCODER_UNINITIALIZED;
-
- return encoder;
- }
-
- FLAC_API void FLAC__stream_encoder_delete(FLAC__StreamEncoder *encoder)
- {
- unsigned i;
-
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->private_->frame);
-
- encoder->private_->is_being_deleted = true;
-
- (void)FLAC__stream_encoder_finish(encoder);
-
- if(0 != encoder->private_->verify.decoder)
- FLAC__stream_decoder_delete(encoder->private_->verify.decoder);
-
- for(i = 0; i < FLAC__MAX_CHANNELS; i++) {
- FLAC__format_entropy_coding_method_partitioned_rice_contents_clear(&encoder->private_->partitioned_rice_contents_workspace[i][0]);
- FLAC__format_entropy_coding_method_partitioned_rice_contents_clear(&encoder->private_->partitioned_rice_contents_workspace[i][1]);
- }
- for(i = 0; i < 2; i++) {
- FLAC__format_entropy_coding_method_partitioned_rice_contents_clear(&encoder->private_->partitioned_rice_contents_workspace_mid_side[i][0]);
- FLAC__format_entropy_coding_method_partitioned_rice_contents_clear(&encoder->private_->partitioned_rice_contents_workspace_mid_side[i][1]);
- }
- for(i = 0; i < 2; i++)
- FLAC__format_entropy_coding_method_partitioned_rice_contents_clear(&encoder->private_->partitioned_rice_contents_extra[i]);
-
- FLAC__bitwriter_delete(encoder->private_->frame);
- free(encoder->private_);
- free(encoder->protected_);
- free(encoder);
- }
-
- /***********************************************************************
- *
- * Public class methods
- *
- ***********************************************************************/
-
- static FLAC__StreamEncoderInitStatus init_stream_internal_enc(
- FLAC__StreamEncoder *encoder,
- FLAC__StreamEncoderReadCallback read_callback,
- FLAC__StreamEncoderWriteCallback write_callback,
- FLAC__StreamEncoderSeekCallback seek_callback,
- FLAC__StreamEncoderTellCallback tell_callback,
- FLAC__StreamEncoderMetadataCallback metadata_callback,
- void *client_data,
- FLAC__bool is_ogg
- )
- {
- unsigned i;
- FLAC__bool metadata_has_seektable, metadata_has_vorbis_comment, metadata_picture_has_type1, metadata_picture_has_type2;
-
- FLAC__ASSERT(0 != encoder);
-
- if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED)
- return FLAC__STREAM_ENCODER_INIT_STATUS_ALREADY_INITIALIZED;
-
- #if !FLAC__HAS_OGG
- if(is_ogg)
- return FLAC__STREAM_ENCODER_INIT_STATUS_UNSUPPORTED_CONTAINER;
- #endif
-
- if(0 == write_callback || (seek_callback && 0 == tell_callback))
- return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_CALLBACKS;
-
- if(encoder->protected_->channels == 0 || encoder->protected_->channels > FLAC__MAX_CHANNELS)
- return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_NUMBER_OF_CHANNELS;
-
- if(encoder->protected_->channels != 2) {
- encoder->protected_->do_mid_side_stereo = false;
- encoder->protected_->loose_mid_side_stereo = false;
- }
- else if(!encoder->protected_->do_mid_side_stereo)
- encoder->protected_->loose_mid_side_stereo = false;
-
- if(encoder->protected_->bits_per_sample >= 32)
- encoder->protected_->do_mid_side_stereo = false; /* since we currenty do 32-bit math, the side channel would have 33 bps and overflow */
-
- if(encoder->protected_->bits_per_sample < FLAC__MIN_BITS_PER_SAMPLE || encoder->protected_->bits_per_sample > FLAC__REFERENCE_CODEC_MAX_BITS_PER_SAMPLE)
- return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_BITS_PER_SAMPLE;
-
- if(!FLAC__format_sample_rate_is_valid(encoder->protected_->sample_rate))
- return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_SAMPLE_RATE;
-
- if(encoder->protected_->blocksize == 0) {
- if(encoder->protected_->max_lpc_order == 0)
- encoder->protected_->blocksize = 1152;
- else
- encoder->protected_->blocksize = 4096;
- }
-
- if(encoder->protected_->blocksize < FLAC__MIN_BLOCK_SIZE || encoder->protected_->blocksize > FLAC__MAX_BLOCK_SIZE)
- return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_BLOCK_SIZE;
-
- if(encoder->protected_->max_lpc_order > FLAC__MAX_LPC_ORDER)
- return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_MAX_LPC_ORDER;
-
- if(encoder->protected_->blocksize < encoder->protected_->max_lpc_order)
- return FLAC__STREAM_ENCODER_INIT_STATUS_BLOCK_SIZE_TOO_SMALL_FOR_LPC_ORDER;
-
- if(encoder->protected_->qlp_coeff_precision == 0) {
- if(encoder->protected_->bits_per_sample < 16) {
- /* @@@ need some data about how to set this here w.r.t. blocksize and sample rate */
- /* @@@ until then we'll make a guess */
- encoder->protected_->qlp_coeff_precision = max(FLAC__MIN_QLP_COEFF_PRECISION, 2 + encoder->protected_->bits_per_sample / 2);
- }
- else if(encoder->protected_->bits_per_sample == 16) {
- if(encoder->protected_->blocksize <= 192)
- encoder->protected_->qlp_coeff_precision = 7;
- else if(encoder->protected_->blocksize <= 384)
- encoder->protected_->qlp_coeff_precision = 8;
- else if(encoder->protected_->blocksize <= 576)
- encoder->protected_->qlp_coeff_precision = 9;
- else if(encoder->protected_->blocksize <= 1152)
- encoder->protected_->qlp_coeff_precision = 10;
- else if(encoder->protected_->blocksize <= 2304)
- encoder->protected_->qlp_coeff_precision = 11;
- else if(encoder->protected_->blocksize <= 4608)
- encoder->protected_->qlp_coeff_precision = 12;
- else
- encoder->protected_->qlp_coeff_precision = 13;
- }
- else {
- if(encoder->protected_->blocksize <= 384)
- encoder->protected_->qlp_coeff_precision = FLAC__MAX_QLP_COEFF_PRECISION-2;
- else if(encoder->protected_->blocksize <= 1152)
- encoder->protected_->qlp_coeff_precision = FLAC__MAX_QLP_COEFF_PRECISION-1;
- else
- encoder->protected_->qlp_coeff_precision = FLAC__MAX_QLP_COEFF_PRECISION;
- }
- FLAC__ASSERT(encoder->protected_->qlp_coeff_precision <= FLAC__MAX_QLP_COEFF_PRECISION);
- }
- else if(encoder->protected_->qlp_coeff_precision < FLAC__MIN_QLP_COEFF_PRECISION || encoder->protected_->qlp_coeff_precision > FLAC__MAX_QLP_COEFF_PRECISION)
- return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_QLP_COEFF_PRECISION;
-
- if(encoder->protected_->streamable_subset) {
- if(
- encoder->protected_->blocksize != 192 &&
- encoder->protected_->blocksize != 576 &&
- encoder->protected_->blocksize != 1152 &&
- encoder->protected_->blocksize != 2304 &&
- encoder->protected_->blocksize != 4608 &&
- encoder->protected_->blocksize != 256 &&
- encoder->protected_->blocksize != 512 &&
- encoder->protected_->blocksize != 1024 &&
- encoder->protected_->blocksize != 2048 &&
- encoder->protected_->blocksize != 4096 &&
- encoder->protected_->blocksize != 8192 &&
- encoder->protected_->blocksize != 16384
- )
- return FLAC__STREAM_ENCODER_INIT_STATUS_NOT_STREAMABLE;
- if(!FLAC__format_sample_rate_is_subset(encoder->protected_->sample_rate))
- return FLAC__STREAM_ENCODER_INIT_STATUS_NOT_STREAMABLE;
- if(
- encoder->protected_->bits_per_sample != 8 &&
- encoder->protected_->bits_per_sample != 12 &&
- encoder->protected_->bits_per_sample != 16 &&
- encoder->protected_->bits_per_sample != 20 &&
- encoder->protected_->bits_per_sample != 24
- )
- return FLAC__STREAM_ENCODER_INIT_STATUS_NOT_STREAMABLE;
- if(encoder->protected_->max_residual_partition_order > FLAC__SUBSET_MAX_RICE_PARTITION_ORDER)
- return FLAC__STREAM_ENCODER_INIT_STATUS_NOT_STREAMABLE;
- if(
- encoder->protected_->sample_rate <= 48000 &&
- (
- encoder->protected_->blocksize > FLAC__SUBSET_MAX_BLOCK_SIZE_48000HZ ||
- encoder->protected_->max_lpc_order > FLAC__SUBSET_MAX_LPC_ORDER_48000HZ
- )
- ) {
- return FLAC__STREAM_ENCODER_INIT_STATUS_NOT_STREAMABLE;
- }
- }
-
- if(encoder->protected_->max_residual_partition_order >= (1u << FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN))
- encoder->protected_->max_residual_partition_order = (1u << FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN) - 1;
- if(encoder->protected_->min_residual_partition_order >= encoder->protected_->max_residual_partition_order)
- encoder->protected_->min_residual_partition_order = encoder->protected_->max_residual_partition_order;
-
- #if FLAC__HAS_OGG
- /* reorder metadata if necessary to ensure that any VORBIS_COMMENT is the first, according to the mapping spec */
- if(is_ogg && 0 != encoder->protected_->metadata && encoder->protected_->num_metadata_blocks > 1) {
- unsigned i;
- for(i = 1; i < encoder->protected_->num_metadata_blocks; i++) {
- if(0 != encoder->protected_->metadata[i] && encoder->protected_->metadata[i]->type == FLAC__METADATA_TYPE_VORBIS_COMMENT) {
- FLAC__StreamMetadata *vc = encoder->protected_->metadata[i];
- for( ; i > 0; i--)
- encoder->protected_->metadata[i] = encoder->protected_->metadata[i-1];
- encoder->protected_->metadata[0] = vc;
- break;
- }
- }
- }
- #endif
- /* keep track of any SEEKTABLE block */
- if(0 != encoder->protected_->metadata && encoder->protected_->num_metadata_blocks > 0) {
- unsigned i;
- for(i = 0; i < encoder->protected_->num_metadata_blocks; i++) {
- if(0 != encoder->protected_->metadata[i] && encoder->protected_->metadata[i]->type == FLAC__METADATA_TYPE_SEEKTABLE) {
- encoder->private_->seek_table = &encoder->protected_->metadata[i]->data.seek_table;
- break; /* take only the first one */
- }
- }
- }
-
- /* validate metadata */
- if(0 == encoder->protected_->metadata && encoder->protected_->num_metadata_blocks > 0)
- return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_METADATA;
- metadata_has_seektable = false;
- metadata_has_vorbis_comment = false;
- metadata_picture_has_type1 = false;
- metadata_picture_has_type2 = false;
- for(i = 0; i < encoder->protected_->num_metadata_blocks; i++) {
- const FLAC__StreamMetadata *m = encoder->protected_->metadata[i];
- if(m->type == FLAC__METADATA_TYPE_STREAMINFO)
- return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_METADATA;
- else if(m->type == FLAC__METADATA_TYPE_SEEKTABLE) {
- if(metadata_has_seektable) /* only one is allowed */
- return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_METADATA;
- metadata_has_seektable = true;
- if(!FLAC__format_seektable_is_legal(&m->data.seek_table))
- return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_METADATA;
- }
- else if(m->type == FLAC__METADATA_TYPE_VORBIS_COMMENT) {
- if(metadata_has_vorbis_comment) /* only one is allowed */
- return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_METADATA;
- metadata_has_vorbis_comment = true;
- }
- else if(m->type == FLAC__METADATA_TYPE_CUESHEET) {
- if(!FLAC__format_cuesheet_is_legal(&m->data.cue_sheet, m->data.cue_sheet.is_cd, /*violation=*/0))
- return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_METADATA;
- }
- else if(m->type == FLAC__METADATA_TYPE_PICTURE) {
- if(!FLAC__format_picture_is_legal(&m->data.picture, /*violation=*/0))
- return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_METADATA;
- if(m->data.picture.type == FLAC__STREAM_METADATA_PICTURE_TYPE_FILE_ICON_STANDARD) {
- if(metadata_picture_has_type1) /* there should only be 1 per stream */
- return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_METADATA;
- metadata_picture_has_type1 = true;
- /* standard icon must be 32x32 pixel PNG */
- if(
- m->data.picture.type == FLAC__STREAM_METADATA_PICTURE_TYPE_FILE_ICON_STANDARD &&
- (
- (strcmp(m->data.picture.mime_type, "image/png") && strcmp(m->data.picture.mime_type, "-->")) ||
- m->data.picture.width != 32 ||
- m->data.picture.height != 32
- )
- )
- return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_METADATA;
- }
- else if(m->data.picture.type == FLAC__STREAM_METADATA_PICTURE_TYPE_FILE_ICON) {
- if(metadata_picture_has_type2) /* there should only be 1 per stream */
- return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_METADATA;
- metadata_picture_has_type2 = true;
- }
- }
- }
-
- encoder->private_->input_capacity = 0;
- for(i = 0; i < encoder->protected_->channels; i++) {
- encoder->private_->integer_signal_unaligned[i] = encoder->private_->integer_signal[i] = 0;
- #ifndef FLAC__INTEGER_ONLY_LIBRARY
- encoder->private_->real_signal_unaligned[i] = encoder->private_->real_signal[i] = 0;
- #endif
- }
- for(i = 0; i < 2; i++) {
- encoder->private_->integer_signal_mid_side_unaligned[i] = encoder->private_->integer_signal_mid_side[i] = 0;
- #ifndef FLAC__INTEGER_ONLY_LIBRARY
- encoder->private_->real_signal_mid_side_unaligned[i] = encoder->private_->real_signal_mid_side[i] = 0;
- #endif
- }
- #ifndef FLAC__INTEGER_ONLY_LIBRARY
- for(i = 0; i < encoder->protected_->num_apodizations; i++)
- encoder->private_->window_unaligned[i] = encoder->private_->window[i] = 0;
- encoder->private_->windowed_signal_unaligned = encoder->private_->windowed_signal = 0;
- #endif
- for(i = 0; i < encoder->protected_->channels; i++) {
- encoder->private_->residual_workspace_unaligned[i][0] = encoder->private_->residual_workspace[i][0] = 0;
- encoder->private_->residual_workspace_unaligned[i][1] = encoder->private_->residual_workspace[i][1] = 0;
- encoder->private_->best_subframe[i] = 0;
- }
- for(i = 0; i < 2; i++) {
- encoder->private_->residual_workspace_mid_side_unaligned[i][0] = encoder->private_->residual_workspace_mid_side[i][0] = 0;
- encoder->private_->residual_workspace_mid_side_unaligned[i][1] = encoder->private_->residual_workspace_mid_side[i][1] = 0;
- encoder->private_->best_subframe_mid_side[i] = 0;
- }
- encoder->private_->abs_residual_partition_sums_unaligned = encoder->private_->abs_residual_partition_sums = 0;
- encoder->private_->raw_bits_per_partition_unaligned = encoder->private_->raw_bits_per_partition = 0;
- #ifndef FLAC__INTEGER_ONLY_LIBRARY
- encoder->private_->loose_mid_side_stereo_frames = (unsigned)((FLAC__double)encoder->protected_->sample_rate * 0.4 / (FLAC__double)encoder->protected_->blocksize + 0.5);
- #else
- /* 26214 is the approximate fixed-point equivalent to 0.4 (0.4 * 2^16) */
- /* sample rate can be up to 655350 Hz, and thus use 20 bits, so we do the multiply÷ by hand */
- FLAC__ASSERT(FLAC__MAX_SAMPLE_RATE <= 655350);
- FLAC__ASSERT(FLAC__MAX_BLOCK_SIZE <= 65535);
- FLAC__ASSERT(encoder->protected_->sample_rate <= 655350);
- FLAC__ASSERT(encoder->protected_->blocksize <= 65535);
- encoder->private_->loose_mid_side_stereo_frames = (unsigned)FLAC__fixedpoint_trunc((((FLAC__uint64)(encoder->protected_->sample_rate) * (FLAC__uint64)(26214)) << 16) / (encoder->protected_->blocksize<<16) + FLAC__FP_ONE_HALF);
- #endif
- if(encoder->private_->loose_mid_side_stereo_frames == 0)
- encoder->private_->loose_mid_side_stereo_frames = 1;
- encoder->private_->loose_mid_side_stereo_frame_count = 0;
- encoder->private_->current_sample_number = 0;
- encoder->private_->current_frame_number = 0;
-
- encoder->private_->use_wide_by_block = (encoder->protected_->bits_per_sample + FLAC__bitmath_ilog2(encoder->protected_->blocksize)+1 > 30);
- encoder->private_->use_wide_by_order = (encoder->protected_->bits_per_sample + FLAC__bitmath_ilog2(max(encoder->protected_->max_lpc_order, FLAC__MAX_FIXED_ORDER))+1 > 30); /*@@@ need to use this? */
- encoder->private_->use_wide_by_partition = (false); /*@@@ need to set this */
-
- /*
- * get the CPU info and set the function pointers
- */
- FLAC__cpu_info(&encoder->private_->cpuinfo);
- /* first default to the non-asm routines */
- #ifndef FLAC__INTEGER_ONLY_LIBRARY
- encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation;
- #endif
- encoder->private_->local_fixed_compute_best_predictor = FLAC__fixed_compute_best_predictor;
- #ifndef FLAC__INTEGER_ONLY_LIBRARY
- encoder->private_->local_lpc_compute_residual_from_qlp_coefficients = FLAC__lpc_compute_residual_from_qlp_coefficients;
- encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_64bit = FLAC__lpc_compute_residual_from_qlp_coefficients_wide;
- encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_16bit = FLAC__lpc_compute_residual_from_qlp_coefficients;
- #endif
- /* now override with asm where appropriate */
- #ifndef FLAC__INTEGER_ONLY_LIBRARY
- # ifndef FLAC__NO_ASM
- if(encoder->private_->cpuinfo.use_asm) {
- # ifdef FLAC__CPU_IA32
- FLAC__ASSERT(encoder->private_->cpuinfo.type == FLAC__CPUINFO_TYPE_IA32);
- # ifdef FLAC__HAS_NASM
- if(encoder->private_->cpuinfo.data.ia32.sse) {
- if(encoder->protected_->max_lpc_order < 4)
- encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_4;
- else if(encoder->protected_->max_lpc_order < 8)
- encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_8;
- else if(encoder->protected_->max_lpc_order < 12)
- encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_12;
- else
- encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_asm_ia32;
- }
- else if(encoder->private_->cpuinfo.data.ia32._3dnow)
- encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_asm_ia32_3dnow;
- else
- encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_asm_ia32;
- if(encoder->private_->cpuinfo.data.ia32.mmx) {
- encoder->private_->local_lpc_compute_residual_from_qlp_coefficients = FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32;
- encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_16bit = FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32_mmx;
- }
- else {
- encoder->private_->local_lpc_compute_residual_from_qlp_coefficients = FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32;
- encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_16bit = FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32;
- }
- if(encoder->private_->cpuinfo.data.ia32.mmx && encoder->private_->cpuinfo.data.ia32.cmov)
- encoder->private_->local_fixed_compute_best_predictor = FLAC__fixed_compute_best_predictor_asm_ia32_mmx_cmov;
- # endif /* FLAC__HAS_NASM */
- # endif /* FLAC__CPU_IA32 */
- }
- # endif /* !FLAC__NO_ASM */
- #endif /* !FLAC__INTEGER_ONLY_LIBRARY */
- /* finally override based on wide-ness if necessary */
- if(encoder->private_->use_wide_by_block) {
- encoder->private_->local_fixed_compute_best_predictor = FLAC__fixed_compute_best_predictor_wide;
- }
-
- /* set state to OK; from here on, errors are fatal and we'll override the state then */
- encoder->protected_->state = FLAC__STREAM_ENCODER_OK;
-
- #if FLAC__HAS_OGG
- encoder->private_->is_ogg = is_ogg;
- if(is_ogg && !FLAC__ogg_encoder_aspect_init(&encoder->protected_->ogg_encoder_aspect)) {
- encoder->protected_->state = FLAC__STREAM_ENCODER_OGG_ERROR;
- return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR;
- }
- #endif
-
- encoder->private_->read_callback = read_callback;
- encoder->private_->write_callback = write_callback;
- encoder->private_->seek_callback = seek_callback;
- encoder->private_->tell_callback = tell_callback;
- encoder->private_->metadata_callback = metadata_callback;
- encoder->private_->client_data = client_data;
-
- if(!resize_buffers_(encoder, encoder->protected_->blocksize)) {
- /* the above function sets the state for us in case of an error */
- return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR;
- }
-
- if(!FLAC__bitwriter_init(encoder->private_->frame)) {
- encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR;
- return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR;
- }
-
- /*
- * Set up the verify stuff if necessary
- */
- if(encoder->protected_->verify) {
- /*
- * First, set up the fifo which will hold the
- * original signal to compare against
- */
- encoder->private_->verify.input_fifo.size = encoder->protected_->blocksize+OVERREAD_;
- for(i = 0; i < encoder->protected_->channels; i++) {
- if(0 == (encoder->private_->verify.input_fifo.data[i] = (FLAC__int32*)safe_malloc_mul_2op_(sizeof(FLAC__int32), /*times*/encoder->private_->verify.input_fifo.size))) {
- encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR;
- return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR;
- }
- }
- encoder->private_->verify.input_fifo.tail = 0;
-
- /*
- * Now set up a stream decoder for verification
- */
- encoder->private_->verify.decoder = FLAC__stream_decoder_new();
- if(0 == encoder->private_->verify.decoder) {
- encoder->protected_->state = FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR;
- return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR;
- }
-
- if(FLAC__stream_decoder_init_stream(encoder->private_->verify.decoder, verify_read_callback_, /*seek_callback=*/0, /*tell_callback=*/0, /*length_callback=*/0, /*eof_callback=*/0, verify_write_callback_, verify_metadata_callback_, verify_error_callback_, /*client_data=*/encoder) != FLAC__STREAM_DECODER_INIT_STATUS_OK) {
- encoder->protected_->state = FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR;
- return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR;
- }
- }
- encoder->private_->verify.error_stats.absolute_sample = 0;
- encoder->private_->verify.error_stats.frame_number = 0;
- encoder->private_->verify.error_stats.channel = 0;
- encoder->private_->verify.error_stats.sample = 0;
- encoder->private_->verify.error_stats.expected = 0;
- encoder->private_->verify.error_stats.got = 0;
-
- /*
- * These must be done before we write any metadata, because that
- * calls the write_callback, which uses these values.
- */
- encoder->private_->first_seekpoint_to_check = 0;
- encoder->private_->samples_written = 0;
- encoder->protected_->streaminfo_offset = 0;
- encoder->protected_->seektable_offset = 0;
- encoder->protected_->audio_offset = 0;
-
- /*
- * write the stream header
- */
- if(encoder->protected_->verify)
- encoder->private_->verify.state_hint = ENCODER_IN_MAGIC;
- if(!FLAC__bitwriter_write_raw_uint32(encoder->private_->frame, FLAC__STREAM_SYNC, FLAC__STREAM_SYNC_LEN)) {
- encoder->protected_->state = FLAC__STREAM_ENCODER_FRAMING_ERROR;
- return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR;
- }
- if(!write_bitbuffer_(encoder, 0, /*is_last_block=*/false)) {
- /* the above function sets the state for us in case of an error */
- return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR;
- }
-
- /*
- * write the STREAMINFO metadata block
- */
- if(encoder->protected_->verify)
- encoder->private_->verify.state_hint = ENCODER_IN_METADATA;
- encoder->private_->streaminfo.type = FLAC__METADATA_TYPE_STREAMINFO;
- encoder->private_->streaminfo.is_last = false; /* we will have at a minimum a VORBIS_COMMENT afterwards */
- encoder->private_->streaminfo.length = FLAC__STREAM_METADATA_STREAMINFO_LENGTH;
- encoder->private_->streaminfo.data.stream_info.min_blocksize = encoder->protected_->blocksize; /* this encoder uses the same blocksize for the whole stream */
- encoder->private_->streaminfo.data.stream_info.max_blocksize = encoder->protected_->blocksize;
- encoder->private_->streaminfo.data.stream_info.min_framesize = 0; /* we don't know this yet; have to fill it in later */
- encoder->private_->streaminfo.data.stream_info.max_framesize = 0; /* we don't know this yet; have to fill it in later */
- encoder->private_->streaminfo.data.stream_info.sample_rate = encoder->protected_->sample_rate;
- encoder->private_->streaminfo.data.stream_info.channels = encoder->protected_->channels;
- encoder->private_->streaminfo.data.stream_info.bits_per_sample = encoder->protected_->bits_per_sample;
- encoder->private_->streaminfo.data.stream_info.total_samples = encoder->protected_->total_samples_estimate; /* we will replace this later with the real total */
- memset(encoder->private_->streaminfo.data.stream_info.md5sum, 0, 16); /* we don't know this yet; have to fill it in later */
- if(encoder->protected_->do_md5)
- FLAC__MD5Init(&encoder->private_->md5context);
- if(!FLAC__add_metadata_block(&encoder->private_->streaminfo, encoder->private_->frame)) {
- encoder->protected_->state = FLAC__STREAM_ENCODER_FRAMING_ERROR;
- return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR;
- }
- if(!write_bitbuffer_(encoder, 0, /*is_last_block=*/false)) {
- /* the above function sets the state for us in case of an error */
- return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR;
- }
-
- /*
- * Now that the STREAMINFO block is written, we can init this to an
- * absurdly-high value...
- */
- encoder->private_->streaminfo.data.stream_info.min_framesize = (1u << FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN) - 1;
- /* ... and clear this to 0 */
- encoder->private_->streaminfo.data.stream_info.total_samples = 0;
-
- /*
- * Check to see if the supplied metadata contains a VORBIS_COMMENT;
- * if not, we will write an empty one (FLAC__add_metadata_block()
- * automatically supplies the vendor string).
- *
- * WATCHOUT: the Ogg FLAC mapping requires us to write this block after
- * the STREAMINFO. (In the case that metadata_has_vorbis_comment is
- * true it will have already insured that the metadata list is properly
- * ordered.)
- */
- if(!metadata_has_vorbis_comment) {
- FLAC__StreamMetadata vorbis_comment;
- vorbis_comment.type = FLAC__METADATA_TYPE_VORBIS_COMMENT;
- vorbis_comment.is_last = (encoder->protected_->num_metadata_blocks == 0);
- vorbis_comment.length = 4 + 4; /* MAGIC NUMBER */
- vorbis_comment.data.vorbis_comment.vendor_string.length = 0;
- vorbis_comment.data.vorbis_comment.vendor_string.entry = 0;
- vorbis_comment.data.vorbis_comment.num_comments = 0;
- vorbis_comment.data.vorbis_comment.comments = 0;
- if(!FLAC__add_metadata_block(&vorbis_comment, encoder->private_->frame)) {
- encoder->protected_->state = FLAC__STREAM_ENCODER_FRAMING_ERROR;
- return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR;
- }
- if(!write_bitbuffer_(encoder, 0, /*is_last_block=*/false)) {
- /* the above function sets the state for us in case of an error */
- return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR;
- }
- }
-
- /*
- * write the user's metadata blocks
- */
- for(i = 0; i < encoder->protected_->num_metadata_blocks; i++) {
- encoder->protected_->metadata[i]->is_last = (i == encoder->protected_->num_metadata_blocks - 1);
- if(!FLAC__add_metadata_block(encoder->protected_->metadata[i], encoder->private_->frame)) {
- encoder->protected_->state = FLAC__STREAM_ENCODER_FRAMING_ERROR;
- return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR;
- }
- if(!write_bitbuffer_(encoder, 0, /*is_last_block=*/false)) {
- /* the above function sets the state for us in case of an error */
- return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR;
- }
- }
-
- /* now that all the metadata is written, we save the stream offset */
- if(encoder->private_->tell_callback && encoder->private_->tell_callback(encoder, &encoder->protected_->audio_offset, encoder->private_->client_data) == FLAC__STREAM_ENCODER_TELL_STATUS_ERROR) { /* FLAC__STREAM_ENCODER_TELL_STATUS_UNSUPPORTED just means we didn't get the offset; no error */
- encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR;
- return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR;
- }
-
- if(encoder->protected_->verify)
- encoder->private_->verify.state_hint = ENCODER_IN_AUDIO;
-
- return FLAC__STREAM_ENCODER_INIT_STATUS_OK;
- }
-
- FLAC_API FLAC__StreamEncoderInitStatus FLAC__stream_encoder_init_stream(
- FLAC__StreamEncoder *encoder,
- FLAC__StreamEncoderWriteCallback write_callback,
- FLAC__StreamEncoderSeekCallback seek_callback,
- FLAC__StreamEncoderTellCallback tell_callback,
- FLAC__StreamEncoderMetadataCallback metadata_callback,
- void *client_data
- )
- {
- return init_stream_internal_enc(
- encoder,
- /*read_callback=*/0,
- write_callback,
- seek_callback,
- tell_callback,
- metadata_callback,
- client_data,
- /*is_ogg=*/false
- );
- }
-
- FLAC_API FLAC__StreamEncoderInitStatus FLAC__stream_encoder_init_ogg_stream(
- FLAC__StreamEncoder *encoder,
- FLAC__StreamEncoderReadCallback read_callback,
- FLAC__StreamEncoderWriteCallback write_callback,
- FLAC__StreamEncoderSeekCallback seek_callback,
- FLAC__StreamEncoderTellCallback tell_callback,
- FLAC__StreamEncoderMetadataCallback metadata_callback,
- void *client_data
- )
- {
- return init_stream_internal_enc(
- encoder,
- read_callback,
- write_callback,
- seek_callback,
- tell_callback,
- metadata_callback,
- client_data,
- /*is_ogg=*/true
- );
- }
-
- static FLAC__StreamEncoderInitStatus init_FILE_internal_enc(
- FLAC__StreamEncoder *encoder,
- FILE *file,
- FLAC__StreamEncoderProgressCallback progress_callback,
- void *client_data,
- FLAC__bool is_ogg
- )
- {
- FLAC__StreamEncoderInitStatus init_status;
-
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != file);
-
- if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED)
- return FLAC__STREAM_ENCODER_INIT_STATUS_ALREADY_INITIALIZED;
-
- /* double protection */
- if(file == 0) {
- encoder->protected_->state = FLAC__STREAM_ENCODER_IO_ERROR;
- return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR;
- }
-
- /*
- * To make sure that our file does not go unclosed after an error, we
- * must assign the FILE pointer before any further error can occur in
- * this routine.
- */
- if(file == stdout)
- file = get_binary_stdout_(); /* just to be safe */
-
- encoder->private_->file = file;
-
- encoder->private_->progress_callback = progress_callback;
- encoder->private_->bytes_written = 0;
- encoder->private_->samples_written = 0;
- encoder->private_->frames_written = 0;
-
- init_status = init_stream_internal_enc(
- encoder,
- encoder->private_->file == stdout? 0 : is_ogg? file_read_callback_enc : 0,
- file_write_callback_,
- encoder->private_->file == stdout? 0 : file_seek_callback_enc,
- encoder->private_->file == stdout? 0 : file_tell_callback_enc,
- /*metadata_callback=*/0,
- client_data,
- is_ogg
- );
- if(init_status != FLAC__STREAM_ENCODER_INIT_STATUS_OK) {
- /* the above function sets the state for us in case of an error */
- return init_status;
- }
-
- {
- unsigned blocksize = FLAC__stream_encoder_get_blocksize(encoder);
-
- FLAC__ASSERT(blocksize != 0);
- encoder->private_->total_frames_estimate = (unsigned)((FLAC__stream_encoder_get_total_samples_estimate(encoder) + blocksize - 1) / blocksize);
- }
-
- return init_status;
- }
-
- FLAC_API FLAC__StreamEncoderInitStatus FLAC__stream_encoder_init_FILE(
- FLAC__StreamEncoder *encoder,
- FILE *file,
- FLAC__StreamEncoderProgressCallback progress_callback,
- void *client_data
- )
- {
- return init_FILE_internal_enc(encoder, file, progress_callback, client_data, /*is_ogg=*/false);
- }
-
- FLAC_API FLAC__StreamEncoderInitStatus FLAC__stream_encoder_init_ogg_FILE(
- FLAC__StreamEncoder *encoder,
- FILE *file,
- FLAC__StreamEncoderProgressCallback progress_callback,
- void *client_data
- )
- {
- return init_FILE_internal_enc(encoder, file, progress_callback, client_data, /*is_ogg=*/true);
- }
-
- static FLAC__StreamEncoderInitStatus init_file_internal_enc(
- FLAC__StreamEncoder *encoder,
- const char *filename,
- FLAC__StreamEncoderProgressCallback progress_callback,
- void *client_data,
- FLAC__bool is_ogg
- )
- {
- FILE *file;
-
- FLAC__ASSERT(0 != encoder);
-
- /*
- * To make sure that our file does not go unclosed after an error, we
- * have to do the same entrance checks here that are later performed
- * in FLAC__stream_encoder_init_FILE() before the FILE* is assigned.
- */
- if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED)
- return FLAC__STREAM_ENCODER_INIT_STATUS_ALREADY_INITIALIZED;
-
- file = filename? fopen(filename, "w+b") : stdout;
-
- if(file == 0) {
- encoder->protected_->state = FLAC__STREAM_ENCODER_IO_ERROR;
- return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR;
- }
-
- return init_FILE_internal_enc(encoder, file, progress_callback, client_data, is_ogg);
- }
-
- FLAC_API FLAC__StreamEncoderInitStatus FLAC__stream_encoder_init_file(
- FLAC__StreamEncoder *encoder,
- const char *filename,
- FLAC__StreamEncoderProgressCallback progress_callback,
- void *client_data
- )
- {
- return init_file_internal_enc(encoder, filename, progress_callback, client_data, /*is_ogg=*/false);
- }
-
- FLAC_API FLAC__StreamEncoderInitStatus FLAC__stream_encoder_init_ogg_file(
- FLAC__StreamEncoder *encoder,
- const char *filename,
- FLAC__StreamEncoderProgressCallback progress_callback,
- void *client_data
- )
- {
- return init_file_internal_enc(encoder, filename, progress_callback, client_data, /*is_ogg=*/true);
- }
-
- FLAC_API FLAC__bool FLAC__stream_encoder_finish(FLAC__StreamEncoder *encoder)
- {
- FLAC__bool error = false;
-
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
-
- if(encoder->protected_->state == FLAC__STREAM_ENCODER_UNINITIALIZED)
- return true;
-
- if(encoder->protected_->state == FLAC__STREAM_ENCODER_OK && !encoder->private_->is_being_deleted) {
- if(encoder->private_->current_sample_number != 0) {
- const FLAC__bool is_fractional_block = encoder->protected_->blocksize != encoder->private_->current_sample_number;
- encoder->protected_->blocksize = encoder->private_->current_sample_number;
- if(!process_frame_(encoder, is_fractional_block, /*is_last_block=*/true))
- error = true;
- }
- }
-
- if(encoder->protected_->do_md5)
- FLAC__MD5Final(encoder->private_->streaminfo.data.stream_info.md5sum, &encoder->private_->md5context);
-
- if(!encoder->private_->is_being_deleted) {
- if(encoder->protected_->state == FLAC__STREAM_ENCODER_OK) {
- if(encoder->private_->seek_callback) {
- #if FLAC__HAS_OGG
- if(encoder->private_->is_ogg)
- update_ogg_metadata_(encoder);
- else
- #endif
- update_metadata_(encoder);
-
- /* check if an error occurred while updating metadata */
- if(encoder->protected_->state != FLAC__STREAM_ENCODER_OK)
- error = true;
- }
- if(encoder->private_->metadata_callback)
- encoder->private_->metadata_callback(encoder, &encoder->private_->streaminfo, encoder->private_->client_data);
- }
-
- if(encoder->protected_->verify && 0 != encoder->private_->verify.decoder && !FLAC__stream_decoder_finish(encoder->private_->verify.decoder)) {
- if(!error)
- encoder->protected_->state = FLAC__STREAM_ENCODER_VERIFY_MISMATCH_IN_AUDIO_DATA;
- error = true;
- }
- }
-
- if(0 != encoder->private_->file) {
- if(encoder->private_->file != stdout)
- fclose(encoder->private_->file);
- encoder->private_->file = 0;
- }
-
- #if FLAC__HAS_OGG
- if(encoder->private_->is_ogg)
- FLAC__ogg_encoder_aspect_finish(&encoder->protected_->ogg_encoder_aspect);
- #endif
-
- free_(encoder);
- set_defaults_enc(encoder);
-
- if(!error)
- encoder->protected_->state = FLAC__STREAM_ENCODER_UNINITIALIZED;
-
- return !error;
- }
-
- FLAC_API FLAC__bool FLAC__stream_encoder_set_ogg_serial_number(FLAC__StreamEncoder *encoder, long value)
- {
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED)
- return false;
- #if FLAC__HAS_OGG
- /* can't check encoder->private_->is_ogg since that's not set until init time */
- FLAC__ogg_encoder_aspect_set_serial_number(&encoder->protected_->ogg_encoder_aspect, value);
- return true;
- #else
- (void)value;
- return false;
- #endif
- }
-
- FLAC_API FLAC__bool FLAC__stream_encoder_set_verify(FLAC__StreamEncoder *encoder, FLAC__bool value)
- {
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED)
- return false;
- #ifndef FLAC__MANDATORY_VERIFY_WHILE_ENCODING
- encoder->protected_->verify = value;
- #endif
- return true;
- }
-
- FLAC_API FLAC__bool FLAC__stream_encoder_set_streamable_subset(FLAC__StreamEncoder *encoder, FLAC__bool value)
- {
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED)
- return false;
- encoder->protected_->streamable_subset = value;
- return true;
- }
-
- FLAC_API FLAC__bool FLAC__stream_encoder_set_do_md5(FLAC__StreamEncoder *encoder, FLAC__bool value)
- {
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED)
- return false;
- encoder->protected_->do_md5 = value;
- return true;
- }
-
- FLAC_API FLAC__bool FLAC__stream_encoder_set_channels(FLAC__StreamEncoder *encoder, unsigned value)
- {
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED)
- return false;
- encoder->protected_->channels = value;
- return true;
- }
-
- FLAC_API FLAC__bool FLAC__stream_encoder_set_bits_per_sample(FLAC__StreamEncoder *encoder, unsigned value)
- {
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED)
- return false;
- encoder->protected_->bits_per_sample = value;
- return true;
- }
-
- FLAC_API FLAC__bool FLAC__stream_encoder_set_sample_rate(FLAC__StreamEncoder *encoder, unsigned value)
- {
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED)
- return false;
- encoder->protected_->sample_rate = value;
- return true;
- }
-
- FLAC_API FLAC__bool FLAC__stream_encoder_set_compression_level(FLAC__StreamEncoder *encoder, unsigned value)
- {
- FLAC__bool ok = true;
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED)
- return false;
- if(value >= sizeof(compression_levels_)/sizeof(compression_levels_[0]))
- value = sizeof(compression_levels_)/sizeof(compression_levels_[0]) - 1;
- ok &= FLAC__stream_encoder_set_do_mid_side_stereo (encoder, compression_levels_[value].do_mid_side_stereo);
- ok &= FLAC__stream_encoder_set_loose_mid_side_stereo (encoder, compression_levels_[value].loose_mid_side_stereo);
- #ifndef FLAC__INTEGER_ONLY_LIBRARY
- #if 0
- /* was: */
- ok &= FLAC__stream_encoder_set_apodization (encoder, compression_levels_[value].apodization);
- /* but it's too hard to specify the string in a locale-specific way */
- #else
- encoder->protected_->num_apodizations = 1;
- encoder->protected_->apodizations[0].type = FLAC__APODIZATION_TUKEY;
- encoder->protected_->apodizations[0].parameters.tukey.p = 0.5;
- #endif
- #endif
- ok &= FLAC__stream_encoder_set_max_lpc_order (encoder, compression_levels_[value].max_lpc_order);
- ok &= FLAC__stream_encoder_set_qlp_coeff_precision (encoder, compression_levels_[value].qlp_coeff_precision);
- ok &= FLAC__stream_encoder_set_do_qlp_coeff_prec_search (encoder, compression_levels_[value].do_qlp_coeff_prec_search);
- ok &= FLAC__stream_encoder_set_do_escape_coding (encoder, compression_levels_[value].do_escape_coding);
- ok &= FLAC__stream_encoder_set_do_exhaustive_model_search (encoder, compression_levels_[value].do_exhaustive_model_search);
- ok &= FLAC__stream_encoder_set_min_residual_partition_order(encoder, compression_levels_[value].min_residual_partition_order);
- ok &= FLAC__stream_encoder_set_max_residual_partition_order(encoder, compression_levels_[value].max_residual_partition_order);
- ok &= FLAC__stream_encoder_set_rice_parameter_search_dist (encoder, compression_levels_[value].rice_parameter_search_dist);
- return ok;
- }
-
- FLAC_API FLAC__bool FLAC__stream_encoder_set_blocksize(FLAC__StreamEncoder *encoder, unsigned value)
- {
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED)
- return false;
- encoder->protected_->blocksize = value;
- return true;
- }
-
- FLAC_API FLAC__bool FLAC__stream_encoder_set_do_mid_side_stereo(FLAC__StreamEncoder *encoder, FLAC__bool value)
- {
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED)
- return false;
- encoder->protected_->do_mid_side_stereo = value;
- return true;
- }
-
- FLAC_API FLAC__bool FLAC__stream_encoder_set_loose_mid_side_stereo(FLAC__StreamEncoder *encoder, FLAC__bool value)
- {
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED)
- return false;
- encoder->protected_->loose_mid_side_stereo = value;
- return true;
- }
-
- /*@@@@add to tests*/
- FLAC_API FLAC__bool FLAC__stream_encoder_set_apodization(FLAC__StreamEncoder *encoder, const char *specification)
- {
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != specification);
- if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED)
- return false;
- #ifdef FLAC__INTEGER_ONLY_LIBRARY
- (void)specification; /* silently ignore since we haven't integerized; will always use a rectangular window */
- #else
- encoder->protected_->num_apodizations = 0;
- while(1) {
- const char *s = strchr(specification, ';');
- const size_t n = s? (size_t)(s - specification) : strlen(specification);
- if (n==8 && 0 == strncmp("bartlett" , specification, n))
- encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_BARTLETT;
- else if(n==13 && 0 == strncmp("bartlett_hann", specification, n))
- encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_BARTLETT_HANN;
- else if(n==8 && 0 == strncmp("blackman" , specification, n))
- encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_BLACKMAN;
- else if(n==26 && 0 == strncmp("blackman_harris_4term_92db", specification, n))
- encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_BLACKMAN_HARRIS_4TERM_92DB_SIDELOBE;
- else if(n==6 && 0 == strncmp("connes" , specification, n))
- encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_CONNES;
- else if(n==7 && 0 == strncmp("flattop" , specification, n))
- encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_FLATTOP;
- else if(n>7 && 0 == strncmp("gauss(" , specification, 6)) {
- FLAC__real stddev = (FLAC__real)strtod(specification+6, 0);
- if (stddev > 0.0 && stddev <= 0.5) {
- encoder->protected_->apodizations[encoder->protected_->num_apodizations].parameters.gauss.stddev = stddev;
- encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_GAUSS;
- }
- }
- else if(n==7 && 0 == strncmp("hamming" , specification, n))
- encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_HAMMING;
- else if(n==4 && 0 == strncmp("hann" , specification, n))
- encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_HANN;
- else if(n==13 && 0 == strncmp("kaiser_bessel", specification, n))
- encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_KAISER_BESSEL;
- else if(n==7 && 0 == strncmp("nuttall" , specification, n))
- encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_NUTTALL;
- else if(n==9 && 0 == strncmp("rectangle" , specification, n))
- encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_RECTANGLE;
- else if(n==8 && 0 == strncmp("triangle" , specification, n))
- encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_TRIANGLE;
- else if(n>7 && 0 == strncmp("tukey(" , specification, 6)) {
- FLAC__real p = (FLAC__real)strtod(specification+6, 0);
- if (p >= 0.0 && p <= 1.0) {
- encoder->protected_->apodizations[encoder->protected_->num_apodizations].parameters.tukey.p = p;
- encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_TUKEY;
- }
- }
- else if(n==5 && 0 == strncmp("welch" , specification, n))
- encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_WELCH;
- if (encoder->protected_->num_apodizations == 32)
- break;
- if (s)
- specification = s+1;
- else
- break;
- }
- if(encoder->protected_->num_apodizations == 0) {
- encoder->protected_->num_apodizations = 1;
- encoder->protected_->apodizations[0].type = FLAC__APODIZATION_TUKEY;
- encoder->protected_->apodizations[0].parameters.tukey.p = 0.5;
- }
- #endif
- return true;
- }
-
- FLAC_API FLAC__bool FLAC__stream_encoder_set_max_lpc_order(FLAC__StreamEncoder *encoder, unsigned value)
- {
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED)
- return false;
- encoder->protected_->max_lpc_order = value;
- return true;
- }
-
- FLAC_API FLAC__bool FLAC__stream_encoder_set_qlp_coeff_precision(FLAC__StreamEncoder *encoder, unsigned value)
- {
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED)
- return false;
- encoder->protected_->qlp_coeff_precision = value;
- return true;
- }
-
- FLAC_API FLAC__bool FLAC__stream_encoder_set_do_qlp_coeff_prec_search(FLAC__StreamEncoder *encoder, FLAC__bool value)
- {
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED)
- return false;
- encoder->protected_->do_qlp_coeff_prec_search = value;
- return true;
- }
-
- FLAC_API FLAC__bool FLAC__stream_encoder_set_do_escape_coding(FLAC__StreamEncoder *encoder, FLAC__bool value)
- {
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED)
- return false;
- #if 0
- /*@@@ deprecated: */
- encoder->protected_->do_escape_coding = value;
- #else
- (void)value;
- #endif
- return true;
- }
-
- FLAC_API FLAC__bool FLAC__stream_encoder_set_do_exhaustive_model_search(FLAC__StreamEncoder *encoder, FLAC__bool value)
- {
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED)
- return false;
- encoder->protected_->do_exhaustive_model_search = value;
- return true;
- }
-
- FLAC_API FLAC__bool FLAC__stream_encoder_set_min_residual_partition_order(FLAC__StreamEncoder *encoder, unsigned value)
- {
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED)
- return false;
- encoder->protected_->min_residual_partition_order = value;
- return true;
- }
-
- FLAC_API FLAC__bool FLAC__stream_encoder_set_max_residual_partition_order(FLAC__StreamEncoder *encoder, unsigned value)
- {
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED)
- return false;
- encoder->protected_->max_residual_partition_order = value;
- return true;
- }
-
- FLAC_API FLAC__bool FLAC__stream_encoder_set_rice_parameter_search_dist(FLAC__StreamEncoder *encoder, unsigned value)
- {
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED)
- return false;
- #if 0
- /*@@@ deprecated: */
- encoder->protected_->rice_parameter_search_dist = value;
- #else
- (void)value;
- #endif
- return true;
- }
-
- FLAC_API FLAC__bool FLAC__stream_encoder_set_total_samples_estimate(FLAC__StreamEncoder *encoder, FLAC__uint64 value)
- {
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED)
- return false;
- encoder->protected_->total_samples_estimate = value;
- return true;
- }
-
- FLAC_API FLAC__bool FLAC__stream_encoder_set_metadata(FLAC__StreamEncoder *encoder, FLAC__StreamMetadata **metadata, unsigned num_blocks)
- {
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED)
- return false;
- if(0 == metadata)
- num_blocks = 0;
- if(0 == num_blocks)
- metadata = 0;
- /* realloc() does not do exactly what we want so... */
- if(encoder->protected_->metadata) {
- free(encoder->protected_->metadata);
- encoder->protected_->metadata = 0;
- encoder->protected_->num_metadata_blocks = 0;
- }
- if(num_blocks) {
- FLAC__StreamMetadata **m;
- if(0 == (m = (FLAC__StreamMetadata**)safe_malloc_mul_2op_(sizeof(m[0]), /*times*/num_blocks)))
- return false;
- memcpy(m, metadata, sizeof(m[0]) * num_blocks);
- encoder->protected_->metadata = m;
- encoder->protected_->num_metadata_blocks = num_blocks;
- }
- #if FLAC__HAS_OGG
- if(!FLAC__ogg_encoder_aspect_set_num_metadata(&encoder->protected_->ogg_encoder_aspect, num_blocks))
- return false;
- #endif
- return true;
- }
-
- /*
- * These three functions are not static, but not publically exposed in
- * include/FLAC/ either. They are used by the test suite.
- */
- FLAC_API FLAC__bool FLAC__stream_encoder_disable_constant_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value)
- {
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED)
- return false;
- encoder->private_->disable_constant_subframes = value;
- return true;
- }
-
- FLAC_API FLAC__bool FLAC__stream_encoder_disable_fixed_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value)
- {
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED)
- return false;
- encoder->private_->disable_fixed_subframes = value;
- return true;
- }
-
- FLAC_API FLAC__bool FLAC__stream_encoder_disable_verbatim_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value)
- {
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED)
- return false;
- encoder->private_->disable_verbatim_subframes = value;
- return true;
- }
-
- FLAC_API FLAC__StreamEncoderState FLAC__stream_encoder_get_state(const FLAC__StreamEncoder *encoder)
- {
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- return encoder->protected_->state;
- }
-
- FLAC_API FLAC__StreamDecoderState FLAC__stream_encoder_get_verify_decoder_state(const FLAC__StreamEncoder *encoder)
- {
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- if(encoder->protected_->verify)
- return FLAC__stream_decoder_get_state(encoder->private_->verify.decoder);
- else
- return FLAC__STREAM_DECODER_UNINITIALIZED;
- }
-
- FLAC_API const char *FLAC__stream_encoder_get_resolved_state_string(const FLAC__StreamEncoder *encoder)
- {
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- if(encoder->protected_->state != FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR)
- return FLAC__StreamEncoderStateString[encoder->protected_->state];
- else
- return FLAC__stream_decoder_get_resolved_state_string(encoder->private_->verify.decoder);
- }
-
- FLAC_API void FLAC__stream_encoder_get_verify_decoder_error_stats(const FLAC__StreamEncoder *encoder, FLAC__uint64 *absolute_sample, unsigned *frame_number, unsigned *channel, unsigned *sample, FLAC__int32 *expected, FLAC__int32 *got)
- {
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- if(0 != absolute_sample)
- *absolute_sample = encoder->private_->verify.error_stats.absolute_sample;
- if(0 != frame_number)
- *frame_number = encoder->private_->verify.error_stats.frame_number;
- if(0 != channel)
- *channel = encoder->private_->verify.error_stats.channel;
- if(0 != sample)
- *sample = encoder->private_->verify.error_stats.sample;
- if(0 != expected)
- *expected = encoder->private_->verify.error_stats.expected;
- if(0 != got)
- *got = encoder->private_->verify.error_stats.got;
- }
-
- FLAC_API FLAC__bool FLAC__stream_encoder_get_verify(const FLAC__StreamEncoder *encoder)
- {
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- return encoder->protected_->verify;
- }
-
- FLAC_API FLAC__bool FLAC__stream_encoder_get_streamable_subset(const FLAC__StreamEncoder *encoder)
- {
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- return encoder->protected_->streamable_subset;
- }
-
- FLAC_API FLAC__bool FLAC__stream_encoder_get_do_md5(const FLAC__StreamEncoder *encoder)
- {
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- return encoder->protected_->do_md5;
- }
-
- FLAC_API unsigned FLAC__stream_encoder_get_channels(const FLAC__StreamEncoder *encoder)
- {
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- return encoder->protected_->channels;
- }
-
- FLAC_API unsigned FLAC__stream_encoder_get_bits_per_sample(const FLAC__StreamEncoder *encoder)
- {
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- return encoder->protected_->bits_per_sample;
- }
-
- FLAC_API unsigned FLAC__stream_encoder_get_sample_rate(const FLAC__StreamEncoder *encoder)
- {
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- return encoder->protected_->sample_rate;
- }
-
- FLAC_API unsigned FLAC__stream_encoder_get_blocksize(const FLAC__StreamEncoder *encoder)
- {
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- return encoder->protected_->blocksize;
- }
-
- FLAC_API FLAC__bool FLAC__stream_encoder_get_do_mid_side_stereo(const FLAC__StreamEncoder *encoder)
- {
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- return encoder->protected_->do_mid_side_stereo;
- }
-
- FLAC_API FLAC__bool FLAC__stream_encoder_get_loose_mid_side_stereo(const FLAC__StreamEncoder *encoder)
- {
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- return encoder->protected_->loose_mid_side_stereo;
- }
-
- FLAC_API unsigned FLAC__stream_encoder_get_max_lpc_order(const FLAC__StreamEncoder *encoder)
- {
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- return encoder->protected_->max_lpc_order;
- }
-
- FLAC_API unsigned FLAC__stream_encoder_get_qlp_coeff_precision(const FLAC__StreamEncoder *encoder)
- {
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- return encoder->protected_->qlp_coeff_precision;
- }
-
- FLAC_API FLAC__bool FLAC__stream_encoder_get_do_qlp_coeff_prec_search(const FLAC__StreamEncoder *encoder)
- {
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- return encoder->protected_->do_qlp_coeff_prec_search;
- }
-
- FLAC_API FLAC__bool FLAC__stream_encoder_get_do_escape_coding(const FLAC__StreamEncoder *encoder)
- {
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- return encoder->protected_->do_escape_coding;
- }
-
- FLAC_API FLAC__bool FLAC__stream_encoder_get_do_exhaustive_model_search(const FLAC__StreamEncoder *encoder)
- {
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- return encoder->protected_->do_exhaustive_model_search;
- }
-
- FLAC_API unsigned FLAC__stream_encoder_get_min_residual_partition_order(const FLAC__StreamEncoder *encoder)
- {
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- return encoder->protected_->min_residual_partition_order;
- }
-
- FLAC_API unsigned FLAC__stream_encoder_get_max_residual_partition_order(const FLAC__StreamEncoder *encoder)
- {
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- return encoder->protected_->max_residual_partition_order;
- }
-
- FLAC_API unsigned FLAC__stream_encoder_get_rice_parameter_search_dist(const FLAC__StreamEncoder *encoder)
- {
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- return encoder->protected_->rice_parameter_search_dist;
- }
-
- FLAC_API FLAC__uint64 FLAC__stream_encoder_get_total_samples_estimate(const FLAC__StreamEncoder *encoder)
- {
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- return encoder->protected_->total_samples_estimate;
- }
-
- FLAC_API FLAC__bool FLAC__stream_encoder_process(FLAC__StreamEncoder *encoder, const FLAC__int32 * const buffer[], unsigned samples)
- {
- unsigned i, j = 0, channel;
- const unsigned channels = encoder->protected_->channels, blocksize = encoder->protected_->blocksize;
-
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(encoder->protected_->state == FLAC__STREAM_ENCODER_OK);
-
- do {
- const unsigned n = min(blocksize+OVERREAD_-encoder->private_->current_sample_number, samples-j);
-
- if(encoder->protected_->verify)
- append_to_verify_fifo_(&encoder->private_->verify.input_fifo, buffer, j, channels, n);
-
- for(channel = 0; channel < channels; channel++)
- memcpy(&encoder->private_->integer_signal[channel][encoder->private_->current_sample_number], &buffer[channel][j], sizeof(buffer[channel][0]) * n);
-
- if(encoder->protected_->do_mid_side_stereo) {
- FLAC__ASSERT(channels == 2);
- /* "i <= blocksize" to overread 1 sample; see comment in OVERREAD_ decl */
- for(i = encoder->private_->current_sample_number; i <= blocksize && j < samples; i++, j++) {
- encoder->private_->integer_signal_mid_side[1][i] = buffer[0][j] - buffer[1][j];
- encoder->private_->integer_signal_mid_side[0][i] = (buffer[0][j] + buffer[1][j]) >> 1; /* NOTE: not the same as 'mid = (buffer[0][j] + buffer[1][j]) / 2' ! */
- }
- }
- else
- j += n;
-
- encoder->private_->current_sample_number += n;
-
- /* we only process if we have a full block + 1 extra sample; final block is always handled by FLAC__stream_encoder_finish() */
- if(encoder->private_->current_sample_number > blocksize) {
- FLAC__ASSERT(encoder->private_->current_sample_number == blocksize+OVERREAD_);
- FLAC__ASSERT(OVERREAD_ == 1); /* assert we only overread 1 sample which simplifies the rest of the code below */
- if(!process_frame_(encoder, /*is_fractional_block=*/false, /*is_last_block=*/false))
- return false;
- /* move unprocessed overread samples to beginnings of arrays */
- for(channel = 0; channel < channels; channel++)
- encoder->private_->integer_signal[channel][0] = encoder->private_->integer_signal[channel][blocksize];
- if(encoder->protected_->do_mid_side_stereo) {
- encoder->private_->integer_signal_mid_side[0][0] = encoder->private_->integer_signal_mid_side[0][blocksize];
- encoder->private_->integer_signal_mid_side[1][0] = encoder->private_->integer_signal_mid_side[1][blocksize];
- }
- encoder->private_->current_sample_number = 1;
- }
- } while(j < samples);
-
- return true;
- }
-
- FLAC_API FLAC__bool FLAC__stream_encoder_process_interleaved(FLAC__StreamEncoder *encoder, const FLAC__int32 buffer[], unsigned samples)
- {
- unsigned i, j, k, channel;
- FLAC__int32 x, mid, side;
- const unsigned channels = encoder->protected_->channels, blocksize = encoder->protected_->blocksize;
-
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(encoder->protected_->state == FLAC__STREAM_ENCODER_OK);
-
- j = k = 0;
- /*
- * we have several flavors of the same basic loop, optimized for
- * different conditions:
- */
- if(encoder->protected_->do_mid_side_stereo && channels == 2) {
- /*
- * stereo coding: unroll channel loop
- */
- do {
- if(encoder->protected_->verify)
- append_to_verify_fifo_interleaved_(&encoder->private_->verify.input_fifo, buffer, j, channels, min(blocksize+OVERREAD_-encoder->private_->current_sample_number, samples-j));
-
- /* "i <= blocksize" to overread 1 sample; see comment in OVERREAD_ decl */
- for(i = encoder->private_->current_sample_number; i <= blocksize && j < samples; i++, j++) {
- encoder->private_->integer_signal[0][i] = mid = side = buffer[k++];
- x = buffer[k++];
- encoder->private_->integer_signal[1][i] = x;
- mid += x;
- side -= x;
- mid >>= 1; /* NOTE: not the same as 'mid = (left + right) / 2' ! */
- encoder->private_->integer_signal_mid_side[1][i] = side;
- encoder->private_->integer_signal_mid_side[0][i] = mid;
- }
- encoder->private_->current_sample_number = i;
- /* we only process if we have a full block + 1 extra sample; final block is always handled by FLAC__stream_encoder_finish() */
- if(i > blocksize) {
- if(!process_frame_(encoder, /*is_fractional_block=*/false, /*is_last_block=*/false))
- return false;
- /* move unprocessed overread samples to beginnings of arrays */
- FLAC__ASSERT(i == blocksize+OVERREAD_);
- FLAC__ASSERT(OVERREAD_ == 1); /* assert we only overread 1 sample which simplifies the rest of the code below */
- encoder->private_->integer_signal[0][0] = encoder->private_->integer_signal[0][blocksize];
- encoder->private_->integer_signal[1][0] = encoder->private_->integer_signal[1][blocksize];
- encoder->private_->integer_signal_mid_side[0][0] = encoder->private_->integer_signal_mid_side[0][blocksize];
- encoder->private_->integer_signal_mid_side[1][0] = encoder->private_->integer_signal_mid_side[1][blocksize];
- encoder->private_->current_sample_number = 1;
- }
- } while(j < samples);
- }
- else {
- /*
- * independent channel coding: buffer each channel in inner loop
- */
- do {
- if(encoder->protected_->verify)
- append_to_verify_fifo_interleaved_(&encoder->private_->verify.input_fifo, buffer, j, channels, min(blocksize+OVERREAD_-encoder->private_->current_sample_number, samples-j));
-
- /* "i <= blocksize" to overread 1 sample; see comment in OVERREAD_ decl */
- for(i = encoder->private_->current_sample_number; i <= blocksize && j < samples; i++, j++) {
- for(channel = 0; channel < channels; channel++)
- encoder->private_->integer_signal[channel][i] = buffer[k++];
- }
- encoder->private_->current_sample_number = i;
- /* we only process if we have a full block + 1 extra sample; final block is always handled by FLAC__stream_encoder_finish() */
- if(i > blocksize) {
- if(!process_frame_(encoder, /*is_fractional_block=*/false, /*is_last_block=*/false))
- return false;
- /* move unprocessed overread samples to beginnings of arrays */
- FLAC__ASSERT(i == blocksize+OVERREAD_);
- FLAC__ASSERT(OVERREAD_ == 1); /* assert we only overread 1 sample which simplifies the rest of the code below */
- for(channel = 0; channel < channels; channel++)
- encoder->private_->integer_signal[channel][0] = encoder->private_->integer_signal[channel][blocksize];
- encoder->private_->current_sample_number = 1;
- }
- } while(j < samples);
- }
-
- return true;
- }
-
- /***********************************************************************
- *
- * Private class methods
- *
- ***********************************************************************/
-
- void set_defaults_enc(FLAC__StreamEncoder *encoder)
- {
- FLAC__ASSERT(0 != encoder);
-
- #ifdef FLAC__MANDATORY_VERIFY_WHILE_ENCODING
- encoder->protected_->verify = true;
- #else
- encoder->protected_->verify = false;
- #endif
- encoder->protected_->streamable_subset = true;
- encoder->protected_->do_md5 = true;
- encoder->protected_->do_mid_side_stereo = false;
- encoder->protected_->loose_mid_side_stereo = false;
- encoder->protected_->channels = 2;
- encoder->protected_->bits_per_sample = 16;
- encoder->protected_->sample_rate = 44100;
- encoder->protected_->blocksize = 0;
- #ifndef FLAC__INTEGER_ONLY_LIBRARY
- encoder->protected_->num_apodizations = 1;
- encoder->protected_->apodizations[0].type = FLAC__APODIZATION_TUKEY;
- encoder->protected_->apodizations[0].parameters.tukey.p = 0.5;
- #endif
- encoder->protected_->max_lpc_order = 0;
- encoder->protected_->qlp_coeff_precision = 0;
- encoder->protected_->do_qlp_coeff_prec_search = false;
- encoder->protected_->do_exhaustive_model_search = false;
- encoder->protected_->do_escape_coding = false;
- encoder->protected_->min_residual_partition_order = 0;
- encoder->protected_->max_residual_partition_order = 0;
- encoder->protected_->rice_parameter_search_dist = 0;
- encoder->protected_->total_samples_estimate = 0;
- encoder->protected_->metadata = 0;
- encoder->protected_->num_metadata_blocks = 0;
-
- encoder->private_->seek_table = 0;
- encoder->private_->disable_constant_subframes = false;
- encoder->private_->disable_fixed_subframes = false;
- encoder->private_->disable_verbatim_subframes = false;
- #if FLAC__HAS_OGG
- encoder->private_->is_ogg = false;
- #endif
- encoder->private_->read_callback = 0;
- encoder->private_->write_callback = 0;
- encoder->private_->seek_callback = 0;
- encoder->private_->tell_callback = 0;
- encoder->private_->metadata_callback = 0;
- encoder->private_->progress_callback = 0;
- encoder->private_->client_data = 0;
-
- #if FLAC__HAS_OGG
- FLAC__ogg_encoder_aspect_set_defaults(&encoder->protected_->ogg_encoder_aspect);
- #endif
- }
-
- void free_(FLAC__StreamEncoder *encoder)
- {
- unsigned i, channel;
-
- FLAC__ASSERT(0 != encoder);
- if(encoder->protected_->metadata) {
- free(encoder->protected_->metadata);
- encoder->protected_->metadata = 0;
- encoder->protected_->num_metadata_blocks = 0;
- }
- for(i = 0; i < encoder->protected_->channels; i++) {
- if(0 != encoder->private_->integer_signal_unaligned[i]) {
- free(encoder->private_->integer_signal_unaligned[i]);
- encoder->private_->integer_signal_unaligned[i] = 0;
- }
- #ifndef FLAC__INTEGER_ONLY_LIBRARY
- if(0 != encoder->private_->real_signal_unaligned[i]) {
- free(encoder->private_->real_signal_unaligned[i]);
- encoder->private_->real_signal_unaligned[i] = 0;
- }
- #endif
- }
- for(i = 0; i < 2; i++) {
- if(0 != encoder->private_->integer_signal_mid_side_unaligned[i]) {
- free(encoder->private_->integer_signal_mid_side_unaligned[i]);
- encoder->private_->integer_signal_mid_side_unaligned[i] = 0;
- }
- #ifndef FLAC__INTEGER_ONLY_LIBRARY
- if(0 != encoder->private_->real_signal_mid_side_unaligned[i]) {
- free(encoder->private_->real_signal_mid_side_unaligned[i]);
- encoder->private_->real_signal_mid_side_unaligned[i] = 0;
- }
- #endif
- }
- #ifndef FLAC__INTEGER_ONLY_LIBRARY
- for(i = 0; i < encoder->protected_->num_apodizations; i++) {
- if(0 != encoder->private_->window_unaligned[i]) {
- free(encoder->private_->window_unaligned[i]);
- encoder->private_->window_unaligned[i] = 0;
- }
- }
- if(0 != encoder->private_->windowed_signal_unaligned) {
- free(encoder->private_->windowed_signal_unaligned);
- encoder->private_->windowed_signal_unaligned = 0;
- }
- #endif
- for(channel = 0; channel < encoder->protected_->channels; channel++) {
- for(i = 0; i < 2; i++) {
- if(0 != encoder->private_->residual_workspace_unaligned[channel][i]) {
- free(encoder->private_->residual_workspace_unaligned[channel][i]);
- encoder->private_->residual_workspace_unaligned[channel][i] = 0;
- }
- }
- }
- for(channel = 0; channel < 2; channel++) {
- for(i = 0; i < 2; i++) {
- if(0 != encoder->private_->residual_workspace_mid_side_unaligned[channel][i]) {
- free(encoder->private_->residual_workspace_mid_side_unaligned[channel][i]);
- encoder->private_->residual_workspace_mid_side_unaligned[channel][i] = 0;
- }
- }
- }
- if(0 != encoder->private_->abs_residual_partition_sums_unaligned) {
- free(encoder->private_->abs_residual_partition_sums_unaligned);
- encoder->private_->abs_residual_partition_sums_unaligned = 0;
- }
- if(0 != encoder->private_->raw_bits_per_partition_unaligned) {
- free(encoder->private_->raw_bits_per_partition_unaligned);
- encoder->private_->raw_bits_per_partition_unaligned = 0;
- }
- if(encoder->protected_->verify) {
- for(i = 0; i < encoder->protected_->channels; i++) {
- if(0 != encoder->private_->verify.input_fifo.data[i]) {
- free(encoder->private_->verify.input_fifo.data[i]);
- encoder->private_->verify.input_fifo.data[i] = 0;
- }
- }
- }
- FLAC__bitwriter_free(encoder->private_->frame);
- }
-
- FLAC__bool resize_buffers_(FLAC__StreamEncoder *encoder, unsigned new_blocksize)
- {
- FLAC__bool ok;
- unsigned i, channel;
-
- FLAC__ASSERT(new_blocksize > 0);
- FLAC__ASSERT(encoder->protected_->state == FLAC__STREAM_ENCODER_OK);
- FLAC__ASSERT(encoder->private_->current_sample_number == 0);
-
- /* To avoid excessive malloc'ing, we only grow the buffer; no shrinking. */
- if(new_blocksize <= encoder->private_->input_capacity)
- return true;
-
- ok = true;
-
- /* WATCHOUT: FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32_mmx()
- * requires that the input arrays (in our case the integer signals)
- * have a buffer of up to 3 zeroes in front (at negative indices) for
- * alignment purposes; we use 4 in front to keep the data well-aligned.
- */
-
- for(i = 0; ok && i < encoder->protected_->channels; i++) {
- ok = ok && FLAC__memory_alloc_aligned_int32_array(new_blocksize+4+OVERREAD_, &encoder->private_->integer_signal_unaligned[i], &encoder->private_->integer_signal[i]);
- memset(encoder->private_->integer_signal[i], 0, sizeof(FLAC__int32)*4);
- encoder->private_->integer_signal[i] += 4;
- #ifndef FLAC__INTEGER_ONLY_LIBRARY
- #if 0 /* @@@ currently unused */
- if(encoder->protected_->max_lpc_order > 0)
- ok = ok && FLAC__memory_alloc_aligned_real_array(new_blocksize+OVERREAD_, &encoder->private_->real_signal_unaligned[i], &encoder->private_->real_signal[i]);
- #endif
- #endif
- }
- for(i = 0; ok && i < 2; i++) {
- ok = ok && FLAC__memory_alloc_aligned_int32_array(new_blocksize+4+OVERREAD_, &encoder->private_->integer_signal_mid_side_unaligned[i], &encoder->private_->integer_signal_mid_side[i]);
- memset(encoder->private_->integer_signal_mid_side[i], 0, sizeof(FLAC__int32)*4);
- encoder->private_->integer_signal_mid_side[i] += 4;
- #ifndef FLAC__INTEGER_ONLY_LIBRARY
- #if 0 /* @@@ currently unused */
- if(encoder->protected_->max_lpc_order > 0)
- ok = ok && FLAC__memory_alloc_aligned_real_array(new_blocksize+OVERREAD_, &encoder->private_->real_signal_mid_side_unaligned[i], &encoder->private_->real_signal_mid_side[i]);
- #endif
- #endif
- }
- #ifndef FLAC__INTEGER_ONLY_LIBRARY
- if(ok && encoder->protected_->max_lpc_order > 0) {
- for(i = 0; ok && i < encoder->protected_->num_apodizations; i++)
- ok = ok && FLAC__memory_alloc_aligned_real_array(new_blocksize, &encoder->private_->window_unaligned[i], &encoder->private_->window[i]);
- ok = ok && FLAC__memory_alloc_aligned_real_array(new_blocksize, &encoder->private_->windowed_signal_unaligned, &encoder->private_->windowed_signal);
- }
- #endif
- for(channel = 0; ok && channel < encoder->protected_->channels; channel++) {
- for(i = 0; ok && i < 2; i++) {
- ok = ok && FLAC__memory_alloc_aligned_int32_array(new_blocksize, &encoder->private_->residual_workspace_unaligned[channel][i], &encoder->private_->residual_workspace[channel][i]);
- }
- }
- for(channel = 0; ok && channel < 2; channel++) {
- for(i = 0; ok && i < 2; i++) {
- ok = ok && FLAC__memory_alloc_aligned_int32_array(new_blocksize, &encoder->private_->residual_workspace_mid_side_unaligned[channel][i], &encoder->private_->residual_workspace_mid_side[channel][i]);
- }
- }
- /* the *2 is an approximation to the series 1 + 1/2 + 1/4 + ... that sums tree occupies in a flat array */
- /*@@@ new_blocksize*2 is too pessimistic, but to fix, we need smarter logic because a smaller new_blocksize can actually increase the # of partitions; would require moving this out into a separate function, then checking its capacity against the need of the current blocksize&min/max_partition_order (and maybe predictor order) */
- ok = ok && FLAC__memory_alloc_aligned_uint64_array(new_blocksize * 2, &encoder->private_->abs_residual_partition_sums_unaligned, &encoder->private_->abs_residual_partition_sums);
- if(encoder->protected_->do_escape_coding)
- ok = ok && FLAC__memory_alloc_aligned_unsigned_array(new_blocksize * 2, &encoder->private_->raw_bits_per_partition_unaligned, &encoder->private_->raw_bits_per_partition);
-
- /* now adjust the windows if the blocksize has changed */
- #ifndef FLAC__INTEGER_ONLY_LIBRARY
- if(ok && new_blocksize != encoder->private_->input_capacity && encoder->protected_->max_lpc_order > 0) {
- for(i = 0; ok && i < encoder->protected_->num_apodizations; i++) {
- switch(encoder->protected_->apodizations[i].type) {
- case FLAC__APODIZATION_BARTLETT:
- FLAC__window_bartlett(encoder->private_->window[i], new_blocksize);
- break;
- case FLAC__APODIZATION_BARTLETT_HANN:
- FLAC__window_bartlett_hann(encoder->private_->window[i], new_blocksize);
- break;
- case FLAC__APODIZATION_BLACKMAN:
- FLAC__window_blackman(encoder->private_->window[i], new_blocksize);
- break;
- case FLAC__APODIZATION_BLACKMAN_HARRIS_4TERM_92DB_SIDELOBE:
- FLAC__window_blackman_harris_4term_92db_sidelobe(encoder->private_->window[i], new_blocksize);
- break;
- case FLAC__APODIZATION_CONNES:
- FLAC__window_connes(encoder->private_->window[i], new_blocksize);
- break;
- case FLAC__APODIZATION_FLATTOP:
- FLAC__window_flattop(encoder->private_->window[i], new_blocksize);
- break;
- case FLAC__APODIZATION_GAUSS:
- FLAC__window_gauss(encoder->private_->window[i], new_blocksize, encoder->protected_->apodizations[i].parameters.gauss.stddev);
- break;
- case FLAC__APODIZATION_HAMMING:
- FLAC__window_hamming(encoder->private_->window[i], new_blocksize);
- break;
- case FLAC__APODIZATION_HANN:
- FLAC__window_hann(encoder->private_->window[i], new_blocksize);
- break;
- case FLAC__APODIZATION_KAISER_BESSEL:
- FLAC__window_kaiser_bessel(encoder->private_->window[i], new_blocksize);
- break;
- case FLAC__APODIZATION_NUTTALL:
- FLAC__window_nuttall(encoder->private_->window[i], new_blocksize);
- break;
- case FLAC__APODIZATION_RECTANGLE:
- FLAC__window_rectangle(encoder->private_->window[i], new_blocksize);
- break;
- case FLAC__APODIZATION_TRIANGLE:
- FLAC__window_triangle(encoder->private_->window[i], new_blocksize);
- break;
- case FLAC__APODIZATION_TUKEY:
- FLAC__window_tukey(encoder->private_->window[i], new_blocksize, encoder->protected_->apodizations[i].parameters.tukey.p);
- break;
- case FLAC__APODIZATION_WELCH:
- FLAC__window_welch(encoder->private_->window[i], new_blocksize);
- break;
- default:
- FLAC__ASSERT(0);
- /* double protection */
- FLAC__window_hann(encoder->private_->window[i], new_blocksize);
- break;
- }
- }
- }
- #endif
-
- if(ok)
- encoder->private_->input_capacity = new_blocksize;
- else
- encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR;
-
- return ok;
- }
-
- FLAC__bool write_bitbuffer_(FLAC__StreamEncoder *encoder, unsigned samples, FLAC__bool is_last_block)
- {
- const FLAC__byte *buffer;
- size_t bytes;
-
- FLAC__ASSERT(FLAC__bitwriter_is_byte_aligned(encoder->private_->frame));
-
- if(!FLAC__bitwriter_get_buffer(encoder->private_->frame, &buffer, &bytes)) {
- encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR;
- return false;
- }
-
- if(encoder->protected_->verify) {
- encoder->private_->verify.output.data = buffer;
- encoder->private_->verify.output.bytes = bytes;
- if(encoder->private_->verify.state_hint == ENCODER_IN_MAGIC) {
- encoder->private_->verify.needs_magic_hack = true;
- }
- else {
- if(!FLAC__stream_decoder_process_single(encoder->private_->verify.decoder)) {
- FLAC__bitwriter_release_buffer(encoder->private_->frame);
- FLAC__bitwriter_clear(encoder->private_->frame);
- if(encoder->protected_->state != FLAC__STREAM_ENCODER_VERIFY_MISMATCH_IN_AUDIO_DATA)
- encoder->protected_->state = FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR;
- return false;
- }
- }
- }
-
- if(write_frame_(encoder, buffer, bytes, samples, is_last_block) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK) {
- FLAC__bitwriter_release_buffer(encoder->private_->frame);
- FLAC__bitwriter_clear(encoder->private_->frame);
- encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR;
- return false;
- }
-
- FLAC__bitwriter_release_buffer(encoder->private_->frame);
- FLAC__bitwriter_clear(encoder->private_->frame);
-
- if(samples > 0) {
- encoder->private_->streaminfo.data.stream_info.min_framesize = min(bytes, encoder->private_->streaminfo.data.stream_info.min_framesize);
- encoder->private_->streaminfo.data.stream_info.max_framesize = max(bytes, encoder->private_->streaminfo.data.stream_info.max_framesize);
- }
-
- return true;
- }
-
- FLAC__StreamEncoderWriteStatus write_frame_(FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], size_t bytes, unsigned samples, FLAC__bool is_last_block)
- {
- FLAC__StreamEncoderWriteStatus status;
- FLAC__uint64 output_position = 0;
-
- /* FLAC__STREAM_ENCODER_TELL_STATUS_UNSUPPORTED just means we didn't get the offset; no error */
- if(encoder->private_->tell_callback && encoder->private_->tell_callback(encoder, &output_position, encoder->private_->client_data) == FLAC__STREAM_ENCODER_TELL_STATUS_ERROR) {
- encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR;
- return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
- }
-
- /*
- * Watch for the STREAMINFO block and first SEEKTABLE block to go by and store their offsets.
- */
- if(samples == 0) {
- FLAC__MetadataType type = (FLAC__MetadataType) (buffer[0] & 0x7f);
- if(type == FLAC__METADATA_TYPE_STREAMINFO)
- encoder->protected_->streaminfo_offset = output_position;
- else if(type == FLAC__METADATA_TYPE_SEEKTABLE && encoder->protected_->seektable_offset == 0)
- encoder->protected_->seektable_offset = output_position;
- }
-
- /*
- * Mark the current seek point if hit (if audio_offset == 0 that
- * means we're still writing metadata and haven't hit the first
- * frame yet)
- */
- if(0 != encoder->private_->seek_table && encoder->protected_->audio_offset > 0 && encoder->private_->seek_table->num_points > 0) {
- const unsigned blocksize = FLAC__stream_encoder_get_blocksize(encoder);
- const FLAC__uint64 frame_first_sample = encoder->private_->samples_written;
- const FLAC__uint64 frame_last_sample = frame_first_sample + (FLAC__uint64)blocksize - 1;
- FLAC__uint64 test_sample;
- unsigned i;
- for(i = encoder->private_->first_seekpoint_to_check; i < encoder->private_->seek_table->num_points; i++) {
- test_sample = encoder->private_->seek_table->points[i].sample_number;
- if(test_sample > frame_last_sample) {
- break;
- }
- else if(test_sample >= frame_first_sample) {
- encoder->private_->seek_table->points[i].sample_number = frame_first_sample;
- encoder->private_->seek_table->points[i].stream_offset = output_position - encoder->protected_->audio_offset;
- encoder->private_->seek_table->points[i].frame_samples = blocksize;
- encoder->private_->first_seekpoint_to_check++;
- /* DO NOT: "break;" and here's why:
- * The seektable template may contain more than one target
- * sample for any given frame; we will keep looping, generating
- * duplicate seekpoints for them, and we'll clean it up later,
- * just before writing the seektable back to the metadata.
- */
- }
- else {
- encoder->private_->first_seekpoint_to_check++;
- }
- }
- }
-
- #if FLAC__HAS_OGG
- if(encoder->private_->is_ogg) {
- status = FLAC__ogg_encoder_aspect_write_callback_wrapper(
- &encoder->protected_->ogg_encoder_aspect,
- buffer,
- bytes,
- samples,
- encoder->private_->current_frame_number,
- is_last_block,
- (FLAC__OggEncoderAspectWriteCallbackProxy)encoder->private_->write_callback,
- encoder,
- encoder->private_->client_data
- );
- }
- else
- #endif
- status = encoder->private_->write_callback(encoder, buffer, bytes, samples, encoder->private_->current_frame_number, encoder->private_->client_data);
-
- if(status == FLAC__STREAM_ENCODER_WRITE_STATUS_OK) {
- encoder->private_->bytes_written += bytes;
- encoder->private_->samples_written += samples;
- /* we keep a high watermark on the number of frames written because
- * when the encoder goes back to write metadata, 'current_frame'
- * will drop back to 0.
- */
- encoder->private_->frames_written = max(encoder->private_->frames_written, encoder->private_->current_frame_number+1);
- }
- else
- encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR;
-
- return status;
- }
-
- /* Gets called when the encoding process has finished so that we can update the STREAMINFO and SEEKTABLE blocks. */
- void update_metadata_(const FLAC__StreamEncoder *encoder)
- {
- FLAC__byte b[max(6, FLAC__STREAM_METADATA_SEEKPOINT_LENGTH)];
- const FLAC__StreamMetadata *metadata = &encoder->private_->streaminfo;
- const FLAC__uint64 samples = metadata->data.stream_info.total_samples;
- const unsigned min_framesize = metadata->data.stream_info.min_framesize;
- const unsigned max_framesize = metadata->data.stream_info.max_framesize;
- const unsigned bps = metadata->data.stream_info.bits_per_sample;
- FLAC__StreamEncoderSeekStatus seek_status;
-
- FLAC__ASSERT(metadata->type == FLAC__METADATA_TYPE_STREAMINFO);
-
- /* All this is based on intimate knowledge of the stream header
- * layout, but a change to the header format that would break this
- * would also break all streams encoded in the previous format.
- */
-
- /*
- * Write MD5 signature
- */
- {
- const unsigned md5_offset =
- FLAC__STREAM_METADATA_HEADER_LENGTH +
- (
- FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN +
- FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN +
- FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN +
- FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN +
- FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN +
- FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN +
- FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN +
- FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN
- ) / 8;
-
- if((seek_status = encoder->private_->seek_callback(encoder, encoder->protected_->streaminfo_offset + md5_offset, encoder->private_->client_data)) != FLAC__STREAM_ENCODER_SEEK_STATUS_OK) {
- if(seek_status == FLAC__STREAM_ENCODER_SEEK_STATUS_ERROR)
- encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR;
- return;
- }
- if(encoder->private_->write_callback(encoder, metadata->data.stream_info.md5sum, 16, 0, 0, encoder->private_->client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK) {
- encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR;
- return;
- }
- }
-
- /*
- * Write total samples
- */
- {
- const unsigned total_samples_byte_offset =
- FLAC__STREAM_METADATA_HEADER_LENGTH +
- (
- FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN +
- FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN +
- FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN +
- FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN +
- FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN +
- FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN +
- FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN
- - 4
- ) / 8;
-
- b[0] = ((FLAC__byte)(bps-1) << 4) | (FLAC__byte)((samples >> 32) & 0x0F);
- b[1] = (FLAC__byte)((samples >> 24) & 0xFF);
- b[2] = (FLAC__byte)((samples >> 16) & 0xFF);
- b[3] = (FLAC__byte)((samples >> 8) & 0xFF);
- b[4] = (FLAC__byte)(samples & 0xFF);
- if((seek_status = encoder->private_->seek_callback(encoder, encoder->protected_->streaminfo_offset + total_samples_byte_offset, encoder->private_->client_data)) != FLAC__STREAM_ENCODER_SEEK_STATUS_OK) {
- if(seek_status == FLAC__STREAM_ENCODER_SEEK_STATUS_ERROR)
- encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR;
- return;
- }
- if(encoder->private_->write_callback(encoder, b, 5, 0, 0, encoder->private_->client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK) {
- encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR;
- return;
- }
- }
-
- /*
- * Write min/max framesize
- */
- {
- const unsigned min_framesize_offset =
- FLAC__STREAM_METADATA_HEADER_LENGTH +
- (
- FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN +
- FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN
- ) / 8;
-
- b[0] = (FLAC__byte)((min_framesize >> 16) & 0xFF);
- b[1] = (FLAC__byte)((min_framesize >> 8) & 0xFF);
- b[2] = (FLAC__byte)(min_framesize & 0xFF);
- b[3] = (FLAC__byte)((max_framesize >> 16) & 0xFF);
- b[4] = (FLAC__byte)((max_framesize >> 8) & 0xFF);
- b[5] = (FLAC__byte)(max_framesize & 0xFF);
- if((seek_status = encoder->private_->seek_callback(encoder, encoder->protected_->streaminfo_offset + min_framesize_offset, encoder->private_->client_data)) != FLAC__STREAM_ENCODER_SEEK_STATUS_OK) {
- if(seek_status == FLAC__STREAM_ENCODER_SEEK_STATUS_ERROR)
- encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR;
- return;
- }
- if(encoder->private_->write_callback(encoder, b, 6, 0, 0, encoder->private_->client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK) {
- encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR;
- return;
- }
- }
-
- /*
- * Write seektable
- */
- if(0 != encoder->private_->seek_table && encoder->private_->seek_table->num_points > 0 && encoder->protected_->seektable_offset > 0) {
- unsigned i;
-
- FLAC__format_seektable_sort(encoder->private_->seek_table);
-
- FLAC__ASSERT(FLAC__format_seektable_is_legal(encoder->private_->seek_table));
-
- if((seek_status = encoder->private_->seek_callback(encoder, encoder->protected_->seektable_offset + FLAC__STREAM_METADATA_HEADER_LENGTH, encoder->private_->client_data)) != FLAC__STREAM_ENCODER_SEEK_STATUS_OK) {
- if(seek_status == FLAC__STREAM_ENCODER_SEEK_STATUS_ERROR)
- encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR;
- return;
- }
-
- for(i = 0; i < encoder->private_->seek_table->num_points; i++) {
- FLAC__uint64 xx;
- unsigned x;
- xx = encoder->private_->seek_table->points[i].sample_number;
- b[7] = (FLAC__byte)xx; xx >>= 8;
- b[6] = (FLAC__byte)xx; xx >>= 8;
- b[5] = (FLAC__byte)xx; xx >>= 8;
- b[4] = (FLAC__byte)xx; xx >>= 8;
- b[3] = (FLAC__byte)xx; xx >>= 8;
- b[2] = (FLAC__byte)xx; xx >>= 8;
- b[1] = (FLAC__byte)xx; xx >>= 8;
- b[0] = (FLAC__byte)xx; xx >>= 8;
- xx = encoder->private_->seek_table->points[i].stream_offset;
- b[15] = (FLAC__byte)xx; xx >>= 8;
- b[14] = (FLAC__byte)xx; xx >>= 8;
- b[13] = (FLAC__byte)xx; xx >>= 8;
- b[12] = (FLAC__byte)xx; xx >>= 8;
- b[11] = (FLAC__byte)xx; xx >>= 8;
- b[10] = (FLAC__byte)xx; xx >>= 8;
- b[9] = (FLAC__byte)xx; xx >>= 8;
- b[8] = (FLAC__byte)xx; xx >>= 8;
- x = encoder->private_->seek_table->points[i].frame_samples;
- b[17] = (FLAC__byte)x; x >>= 8;
- b[16] = (FLAC__byte)x; x >>= 8;
- if(encoder->private_->write_callback(encoder, b, 18, 0, 0, encoder->private_->client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK) {
- encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR;
- return;
- }
- }
- }
- }
-
- #if FLAC__HAS_OGG
- /* Gets called when the encoding process has finished so that we can update the STREAMINFO and SEEKTABLE blocks. */
- void update_ogg_metadata_(FLAC__StreamEncoder *encoder)
- {
- /* the # of bytes in the 1st packet that precede the STREAMINFO */
- static const unsigned FIRST_OGG_PACKET_STREAMINFO_PREFIX_LENGTH =
- FLAC__OGG_MAPPING_PACKET_TYPE_LENGTH +
- FLAC__OGG_MAPPING_MAGIC_LENGTH +
- FLAC__OGG_MAPPING_VERSION_MAJOR_LENGTH +
- FLAC__OGG_MAPPING_VERSION_MINOR_LENGTH +
- FLAC__OGG_MAPPING_NUM_HEADERS_LENGTH +
- FLAC__STREAM_SYNC_LENGTH
- ;
- FLAC__byte b[max(6, FLAC__STREAM_METADATA_SEEKPOINT_LENGTH)];
- const FLAC__StreamMetadata *metadata = &encoder->private_->streaminfo;
- const FLAC__uint64 samples = metadata->data.stream_info.total_samples;
- const unsigned min_framesize = metadata->data.stream_info.min_framesize;
- const unsigned max_framesize = metadata->data.stream_info.max_framesize;
- ogg_page page;
-
- FLAC__ASSERT(metadata->type == FLAC__METADATA_TYPE_STREAMINFO);
- FLAC__ASSERT(0 != encoder->private_->seek_callback);
-
- /* Pre-check that client supports seeking, since we don't want the
- * ogg_helper code to ever have to deal with this condition.
- */
- if(encoder->private_->seek_callback(encoder, 0, encoder->private_->client_data) == FLAC__STREAM_ENCODER_SEEK_STATUS_UNSUPPORTED)
- return;
-
- /* All this is based on intimate knowledge of the stream header
- * layout, but a change to the header format that would break this
- * would also break all streams encoded in the previous format.
- */
-
- /**
- ** Write STREAMINFO stats
- **/
- simple_ogg_page__init(&page);
- if(!simple_ogg_page__get_at(encoder, encoder->protected_->streaminfo_offset, &page, encoder->private_->seek_callback, encoder->private_->read_callback, encoder->private_->client_data)) {
- simple_ogg_page__clear(&page);
- return; /* state already set */
- }
-
- /*
- * Write MD5 signature
- */
- {
- const unsigned md5_offset =
- FIRST_OGG_PACKET_STREAMINFO_PREFIX_LENGTH +
- FLAC__STREAM_METADATA_HEADER_LENGTH +
- (
- FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN +
- FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN +
- FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN +
- FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN +
- FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN +
- FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN +
- FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN +
- FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN
- ) / 8;
-
- if(md5_offset + 16 > (unsigned)page.body_len) {
- encoder->protected_->state = FLAC__STREAM_ENCODER_OGG_ERROR;
- simple_ogg_page__clear(&page);
- return;
- }
- memcpy(page.body + md5_offset, metadata->data.stream_info.md5sum, 16);
- }
-
- /*
- * Write total samples
- */
- {
- const unsigned total_samples_byte_offset =
- FIRST_OGG_PACKET_STREAMINFO_PREFIX_LENGTH +
- FLAC__STREAM_METADATA_HEADER_LENGTH +
- (
- FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN +
- FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN +
- FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN +
- FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN +
- FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN +
- FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN +
- FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN
- - 4
- ) / 8;
-
- if(total_samples_byte_offset + 5 > (unsigned)page.body_len) {
- encoder->protected_->state = FLAC__STREAM_ENCODER_OGG_ERROR;
- simple_ogg_page__clear(&page);
- return;
- }
- b[0] = (FLAC__byte)page.body[total_samples_byte_offset] & 0xF0;
- b[0] |= (FLAC__byte)((samples >> 32) & 0x0F);
- b[1] = (FLAC__byte)((samples >> 24) & 0xFF);
- b[2] = (FLAC__byte)((samples >> 16) & 0xFF);
- b[3] = (FLAC__byte)((samples >> 8) & 0xFF);
- b[4] = (FLAC__byte)(samples & 0xFF);
- memcpy(page.body + total_samples_byte_offset, b, 5);
- }
-
- /*
- * Write min/max framesize
- */
- {
- const unsigned min_framesize_offset =
- FIRST_OGG_PACKET_STREAMINFO_PREFIX_LENGTH +
- FLAC__STREAM_METADATA_HEADER_LENGTH +
- (
- FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN +
- FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN
- ) / 8;
-
- if(min_framesize_offset + 6 > (unsigned)page.body_len) {
- encoder->protected_->state = FLAC__STREAM_ENCODER_OGG_ERROR;
- simple_ogg_page__clear(&page);
- return;
- }
- b[0] = (FLAC__byte)((min_framesize >> 16) & 0xFF);
- b[1] = (FLAC__byte)((min_framesize >> 8) & 0xFF);
- b[2] = (FLAC__byte)(min_framesize & 0xFF);
- b[3] = (FLAC__byte)((max_framesize >> 16) & 0xFF);
- b[4] = (FLAC__byte)((max_framesize >> 8) & 0xFF);
- b[5] = (FLAC__byte)(max_framesize & 0xFF);
- memcpy(page.body + min_framesize_offset, b, 6);
- }
- if(!simple_ogg_page__set_at(encoder, encoder->protected_->streaminfo_offset, &page, encoder->private_->seek_callback, encoder->private_->write_callback, encoder->private_->client_data)) {
- simple_ogg_page__clear(&page);
- return; /* state already set */
- }
- simple_ogg_page__clear(&page);
-
- /*
- * Write seektable
- */
- if(0 != encoder->private_->seek_table && encoder->private_->seek_table->num_points > 0 && encoder->protected_->seektable_offset > 0) {
- unsigned i;
- FLAC__byte *p;
-
- FLAC__format_seektable_sort(encoder->private_->seek_table);
-
- FLAC__ASSERT(FLAC__format_seektable_is_legal(encoder->private_->seek_table));
-
- simple_ogg_page__init(&page);
- if(!simple_ogg_page__get_at(encoder, encoder->protected_->seektable_offset, &page, encoder->private_->seek_callback, encoder->private_->read_callback, encoder->private_->client_data)) {
- simple_ogg_page__clear(&page);
- return; /* state already set */
- }
-
- if((FLAC__STREAM_METADATA_HEADER_LENGTH + 18*encoder->private_->seek_table->num_points) != (unsigned)page.body_len) {
- encoder->protected_->state = FLAC__STREAM_ENCODER_OGG_ERROR;
- simple_ogg_page__clear(&page);
- return;
- }
-
- for(i = 0, p = page.body + FLAC__STREAM_METADATA_HEADER_LENGTH; i < encoder->private_->seek_table->num_points; i++, p += 18) {
- FLAC__uint64 xx;
- unsigned x;
- xx = encoder->private_->seek_table->points[i].sample_number;
- b[7] = (FLAC__byte)xx; xx >>= 8;
- b[6] = (FLAC__byte)xx; xx >>= 8;
- b[5] = (FLAC__byte)xx; xx >>= 8;
- b[4] = (FLAC__byte)xx; xx >>= 8;
- b[3] = (FLAC__byte)xx; xx >>= 8;
- b[2] = (FLAC__byte)xx; xx >>= 8;
- b[1] = (FLAC__byte)xx; xx >>= 8;
- b[0] = (FLAC__byte)xx; xx >>= 8;
- xx = encoder->private_->seek_table->points[i].stream_offset;
- b[15] = (FLAC__byte)xx; xx >>= 8;
- b[14] = (FLAC__byte)xx; xx >>= 8;
- b[13] = (FLAC__byte)xx; xx >>= 8;
- b[12] = (FLAC__byte)xx; xx >>= 8;
- b[11] = (FLAC__byte)xx; xx >>= 8;
- b[10] = (FLAC__byte)xx; xx >>= 8;
- b[9] = (FLAC__byte)xx; xx >>= 8;
- b[8] = (FLAC__byte)xx; xx >>= 8;
- x = encoder->private_->seek_table->points[i].frame_samples;
- b[17] = (FLAC__byte)x; x >>= 8;
- b[16] = (FLAC__byte)x; x >>= 8;
- memcpy(p, b, 18);
- }
-
- if(!simple_ogg_page__set_at(encoder, encoder->protected_->seektable_offset, &page, encoder->private_->seek_callback, encoder->private_->write_callback, encoder->private_->client_data)) {
- simple_ogg_page__clear(&page);
- return; /* state already set */
- }
- simple_ogg_page__clear(&page);
- }
- }
- #endif
-
- FLAC__bool process_frame_(FLAC__StreamEncoder *encoder, FLAC__bool is_fractional_block, FLAC__bool is_last_block)
- {
- FLAC__uint16 crc;
- FLAC__ASSERT(encoder->protected_->state == FLAC__STREAM_ENCODER_OK);
-
- /*
- * Accumulate raw signal to the MD5 signature
- */
- if(encoder->protected_->do_md5 && !FLAC__MD5Accumulate(&encoder->private_->md5context, (const FLAC__int32 * const *)encoder->private_->integer_signal, encoder->protected_->channels, encoder->protected_->blocksize, (encoder->protected_->bits_per_sample+7) / 8)) {
- encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR;
- return false;
- }
-
- /*
- * Process the frame header and subframes into the frame bitbuffer
- */
- if(!process_subframes_(encoder, is_fractional_block)) {
- /* the above function sets the state for us in case of an error */
- return false;
- }
-
- /*
- * Zero-pad the frame to a byte_boundary
- */
- if(!FLAC__bitwriter_zero_pad_to_byte_boundary(encoder->private_->frame)) {
- encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR;
- return false;
- }
-
- /*
- * CRC-16 the whole thing
- */
- FLAC__ASSERT(FLAC__bitwriter_is_byte_aligned(encoder->private_->frame));
- if(
- !FLAC__bitwriter_get_write_crc16(encoder->private_->frame, &crc) ||
- !FLAC__bitwriter_write_raw_uint32(encoder->private_->frame, crc, FLAC__FRAME_FOOTER_CRC_LEN)
- ) {
- encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR;
- return false;
- }
-
- /*
- * Write it
- */
- if(!write_bitbuffer_(encoder, encoder->protected_->blocksize, is_last_block)) {
- /* the above function sets the state for us in case of an error */
- return false;
- }
-
- /*
- * Get ready for the next frame
- */
- encoder->private_->current_sample_number = 0;
- encoder->private_->current_frame_number++;
- encoder->private_->streaminfo.data.stream_info.total_samples += (FLAC__uint64)encoder->protected_->blocksize;
-
- return true;
- }
-
- FLAC__bool process_subframes_(FLAC__StreamEncoder *encoder, FLAC__bool is_fractional_block)
- {
- FLAC__FrameHeader frame_header;
- unsigned channel, min_partition_order = encoder->protected_->min_residual_partition_order, max_partition_order;
- FLAC__bool do_independent, do_mid_side;
-
- /*
- * Calculate the min,max Rice partition orders
- */
- if(is_fractional_block) {
- max_partition_order = 0;
- }
- else {
- max_partition_order = FLAC__format_get_max_rice_partition_order_from_blocksize(encoder->protected_->blocksize);
- max_partition_order = min(max_partition_order, encoder->protected_->max_residual_partition_order);
- }
- min_partition_order = min(min_partition_order, max_partition_order);
-
- /*
- * Setup the frame
- */
- frame_header.blocksize = encoder->protected_->blocksize;
- frame_header.sample_rate = encoder->protected_->sample_rate;
- frame_header.channels = encoder->protected_->channels;
- frame_header.channel_assignment = FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT; /* the default unless the encoder determines otherwise */
- frame_header.bits_per_sample = encoder->protected_->bits_per_sample;
- frame_header.number_type = FLAC__FRAME_NUMBER_TYPE_FRAME_NUMBER;
- frame_header.number.frame_number = encoder->private_->current_frame_number;
-
- /*
- * Figure out what channel assignments to try
- */
- if(encoder->protected_->do_mid_side_stereo) {
- if(encoder->protected_->loose_mid_side_stereo) {
- if(encoder->private_->loose_mid_side_stereo_frame_count == 0) {
- do_independent = true;
- do_mid_side = true;
- }
- else {
- do_independent = (encoder->private_->last_channel_assignment == FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT);
- do_mid_side = !do_independent;
- }
- }
- else {
- do_independent = true;
- do_mid_side = true;
- }
- }
- else {
- do_independent = true;
- do_mid_side = false;
- }
-
- FLAC__ASSERT(do_independent || do_mid_side);
-
- /*
- * Check for wasted bits; set effective bps for each subframe
- */
- if(do_independent) {
- for(channel = 0; channel < encoder->protected_->channels; channel++) {
- const unsigned w = get_wasted_bits_(encoder->private_->integer_signal[channel], encoder->protected_->blocksize);
- encoder->private_->subframe_workspace[channel][0].wasted_bits = encoder->private_->subframe_workspace[channel][1].wasted_bits = w;
- encoder->private_->subframe_bps[channel] = encoder->protected_->bits_per_sample - w;
- }
- }
- if(do_mid_side) {
- FLAC__ASSERT(encoder->protected_->channels == 2);
- for(channel = 0; channel < 2; channel++) {
- const unsigned w = get_wasted_bits_(encoder->private_->integer_signal_mid_side[channel], encoder->protected_->blocksize);
- encoder->private_->subframe_workspace_mid_side[channel][0].wasted_bits = encoder->private_->subframe_workspace_mid_side[channel][1].wasted_bits = w;
- encoder->private_->subframe_bps_mid_side[channel] = encoder->protected_->bits_per_sample - w + (channel==0? 0:1);
- }
- }
-
- /*
- * First do a normal encoding pass of each independent channel
- */
- if(do_independent) {
- for(channel = 0; channel < encoder->protected_->channels; channel++) {
- if(!
- process_subframe_(
- encoder,
- min_partition_order,
- max_partition_order,
- &frame_header,
- encoder->private_->subframe_bps[channel],
- encoder->private_->integer_signal[channel],
- encoder->private_->subframe_workspace_ptr[channel],
- encoder->private_->partitioned_rice_contents_workspace_ptr[channel],
- encoder->private_->residual_workspace[channel],
- encoder->private_->best_subframe+channel,
- encoder->private_->best_subframe_bits+channel
- )
- )
- return false;
- }
- }
-
- /*
- * Now do mid and side channels if requested
- */
- if(do_mid_side) {
- FLAC__ASSERT(encoder->protected_->channels == 2);
-
- for(channel = 0; channel < 2; channel++) {
- if(!
- process_subframe_(
- encoder,
- min_partition_order,
- max_partition_order,
- &frame_header,
- encoder->private_->subframe_bps_mid_side[channel],
- encoder->private_->integer_signal_mid_side[channel],
- encoder->private_->subframe_workspace_ptr_mid_side[channel],
- encoder->private_->partitioned_rice_contents_workspace_ptr_mid_side[channel],
- encoder->private_->residual_workspace_mid_side[channel],
- encoder->private_->best_subframe_mid_side+channel,
- encoder->private_->best_subframe_bits_mid_side+channel
- )
- )
- return false;
- }
- }
-
- /*
- * Compose the frame bitbuffer
- */
- if(do_mid_side) {
- unsigned left_bps = 0, right_bps = 0; /* initialized only to prevent superfluous compiler warning */
- FLAC__Subframe *left_subframe = 0, *right_subframe = 0; /* initialized only to prevent superfluous compiler warning */
- FLAC__ChannelAssignment channel_assignment;
-
- FLAC__ASSERT(encoder->protected_->channels == 2);
-
- if(encoder->protected_->loose_mid_side_stereo && encoder->private_->loose_mid_side_stereo_frame_count > 0) {
- channel_assignment = (encoder->private_->last_channel_assignment == FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT? FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT : FLAC__CHANNEL_ASSIGNMENT_MID_SIDE);
- }
- else {
- unsigned bits[4]; /* WATCHOUT - indexed by FLAC__ChannelAssignment */
- unsigned min_bits;
- int ca;
-
- FLAC__ASSERT(FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT == 0);
- FLAC__ASSERT(FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE == 1);
- FLAC__ASSERT(FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE == 2);
- FLAC__ASSERT(FLAC__CHANNEL_ASSIGNMENT_MID_SIDE == 3);
- FLAC__ASSERT(do_independent && do_mid_side);
-
- /* We have to figure out which channel assignent results in the smallest frame */
- bits[FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT] = encoder->private_->best_subframe_bits [0] + encoder->private_->best_subframe_bits [1];
- bits[FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE ] = encoder->private_->best_subframe_bits [0] + encoder->private_->best_subframe_bits_mid_side[1];
- bits[FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE ] = encoder->private_->best_subframe_bits [1] + encoder->private_->best_subframe_bits_mid_side[1];
- bits[FLAC__CHANNEL_ASSIGNMENT_MID_SIDE ] = encoder->private_->best_subframe_bits_mid_side[0] + encoder->private_->best_subframe_bits_mid_side[1];
-
- channel_assignment = FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT;
- min_bits = bits[channel_assignment];
- for(ca = 1; ca <= 3; ca++) {
- if(bits[ca] < min_bits) {
- min_bits = bits[ca];
- channel_assignment = (FLAC__ChannelAssignment)ca;
- }
- }
- }
-
- frame_header.channel_assignment = channel_assignment;
-
- if(!FLAC__frame_add_header(&frame_header, encoder->private_->frame)) {
- encoder->protected_->state = FLAC__STREAM_ENCODER_FRAMING_ERROR;
- return false;
- }
-
- switch(channel_assignment) {
- case FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT:
- left_subframe = &encoder->private_->subframe_workspace [0][encoder->private_->best_subframe [0]];
- right_subframe = &encoder->private_->subframe_workspace [1][encoder->private_->best_subframe [1]];
- break;
- case FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE:
- left_subframe = &encoder->private_->subframe_workspace [0][encoder->private_->best_subframe [0]];
- right_subframe = &encoder->private_->subframe_workspace_mid_side[1][encoder->private_->best_subframe_mid_side[1]];
- break;
- case FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE:
- left_subframe = &encoder->private_->subframe_workspace_mid_side[1][encoder->private_->best_subframe_mid_side[1]];
- right_subframe = &encoder->private_->subframe_workspace [1][encoder->private_->best_subframe [1]];
- break;
- case FLAC__CHANNEL_ASSIGNMENT_MID_SIDE:
- left_subframe = &encoder->private_->subframe_workspace_mid_side[0][encoder->private_->best_subframe_mid_side[0]];
- right_subframe = &encoder->private_->subframe_workspace_mid_side[1][encoder->private_->best_subframe_mid_side[1]];
- break;
- default:
- FLAC__ASSERT(0);
- }
-
- switch(channel_assignment) {
- case FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT:
- left_bps = encoder->private_->subframe_bps [0];
- right_bps = encoder->private_->subframe_bps [1];
- break;
- case FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE:
- left_bps = encoder->private_->subframe_bps [0];
- right_bps = encoder->private_->subframe_bps_mid_side[1];
- break;
- case FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE:
- left_bps = encoder->private_->subframe_bps_mid_side[1];
- right_bps = encoder->private_->subframe_bps [1];
- break;
- case FLAC__CHANNEL_ASSIGNMENT_MID_SIDE:
- left_bps = encoder->private_->subframe_bps_mid_side[0];
- right_bps = encoder->private_->subframe_bps_mid_side[1];
- break;
- default:
- FLAC__ASSERT(0);
- }
-
- /* note that encoder_add_subframe_ sets the state for us in case of an error */
- if(!add_subframe_(encoder, frame_header.blocksize, left_bps , left_subframe , encoder->private_->frame))
- return false;
- if(!add_subframe_(encoder, frame_header.blocksize, right_bps, right_subframe, encoder->private_->frame))
- return false;
- }
- else {
- if(!FLAC__frame_add_header(&frame_header, encoder->private_->frame)) {
- encoder->protected_->state = FLAC__STREAM_ENCODER_FRAMING_ERROR;
- return false;
- }
-
- for(channel = 0; channel < encoder->protected_->channels; channel++) {
- if(!add_subframe_(encoder, frame_header.blocksize, encoder->private_->subframe_bps[channel], &encoder->private_->subframe_workspace[channel][encoder->private_->best_subframe[channel]], encoder->private_->frame)) {
- /* the above function sets the state for us in case of an error */
- return false;
- }
- }
- }
-
- if(encoder->protected_->loose_mid_side_stereo) {
- encoder->private_->loose_mid_side_stereo_frame_count++;
- if(encoder->private_->loose_mid_side_stereo_frame_count >= encoder->private_->loose_mid_side_stereo_frames)
- encoder->private_->loose_mid_side_stereo_frame_count = 0;
- }
-
- encoder->private_->last_channel_assignment = frame_header.channel_assignment;
-
- return true;
- }
-
- FLAC__bool process_subframe_(
- FLAC__StreamEncoder *encoder,
- unsigned min_partition_order,
- unsigned max_partition_order,
- const FLAC__FrameHeader *frame_header,
- unsigned subframe_bps,
- const FLAC__int32 integer_signal[],
- FLAC__Subframe *subframe[2],
- FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents[2],
- FLAC__int32 *residual[2],
- unsigned *best_subframe,
- unsigned *best_bits
- )
- {
- #ifndef FLAC__INTEGER_ONLY_LIBRARY
- FLAC__float fixed_residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1];
- #else
- FLAC__fixedpoint fixed_residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1];
- #endif
- #ifndef FLAC__INTEGER_ONLY_LIBRARY
- FLAC__double lpc_residual_bits_per_sample;
- FLAC__real autoc[FLAC__MAX_LPC_ORDER+1]; /* WATCHOUT: the size is important even though encoder->protected_->max_lpc_order might be less; some asm routines need all the space */
- FLAC__double lpc_error[FLAC__MAX_LPC_ORDER];
- unsigned min_lpc_order, max_lpc_order, lpc_order;
- unsigned min_qlp_coeff_precision, max_qlp_coeff_precision, qlp_coeff_precision;
- #endif
- unsigned min_fixed_order, max_fixed_order, guess_fixed_order, fixed_order;
- unsigned rice_parameter;
- unsigned _candidate_bits, _best_bits;
- unsigned _best_subframe;
- /* only use RICE2 partitions if stream bps > 16 */
- const unsigned rice_parameter_limit = FLAC__stream_encoder_get_bits_per_sample(encoder) > 16? FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_ESCAPE_PARAMETER : FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER;
-
- FLAC__ASSERT(frame_header->blocksize > 0);
-
- /* verbatim subframe is the baseline against which we measure other compressed subframes */
- _best_subframe = 0;
- if(encoder->private_->disable_verbatim_subframes && frame_header->blocksize >= FLAC__MAX_FIXED_ORDER)
- _best_bits = UINT_MAX;
- else
- _best_bits = evaluate_verbatim_subframe_(encoder, integer_signal, frame_header->blocksize, subframe_bps, subframe[_best_subframe]);
-
- if(frame_header->blocksize >= FLAC__MAX_FIXED_ORDER) {
- unsigned signal_is_constant = false;
- guess_fixed_order = encoder->private_->local_fixed_compute_best_predictor(integer_signal+FLAC__MAX_FIXED_ORDER, frame_header->blocksize-FLAC__MAX_FIXED_ORDER, fixed_residual_bits_per_sample);
- /* check for constant subframe */
- if(
- !encoder->private_->disable_constant_subframes &&
- #ifndef FLAC__INTEGER_ONLY_LIBRARY
- fixed_residual_bits_per_sample[1] == 0.0
- #else
- fixed_residual_bits_per_sample[1] == FLAC__FP_ZERO
- #endif
- ) {
- /* the above means it's possible all samples are the same value; now double-check it: */
- unsigned i;
- signal_is_constant = true;
- for(i = 1; i < frame_header->blocksize; i++) {
- if(integer_signal[0] != integer_signal[i]) {
- signal_is_constant = false;
- break;
- }
- }
- }
- if(signal_is_constant) {
- _candidate_bits = evaluate_constant_subframe_(encoder, integer_signal[0], frame_header->blocksize, subframe_bps, subframe[!_best_subframe]);
- if(_candidate_bits < _best_bits) {
- _best_subframe = !_best_subframe;
- _best_bits = _candidate_bits;
- }
- }
- else {
- if(!encoder->private_->disable_fixed_subframes || (encoder->protected_->max_lpc_order == 0 && _best_bits == UINT_MAX)) {
- /* encode fixed */
- if(encoder->protected_->do_exhaustive_model_search) {
- min_fixed_order = 0;
- max_fixed_order = FLAC__MAX_FIXED_ORDER;
- }
- else {
- min_fixed_order = max_fixed_order = guess_fixed_order;
- }
- if(max_fixed_order >= frame_header->blocksize)
- max_fixed_order = frame_header->blocksize - 1;
- for(fixed_order = min_fixed_order; fixed_order <= max_fixed_order; fixed_order++) {
- #ifndef FLAC__INTEGER_ONLY_LIBRARY
- if(fixed_residual_bits_per_sample[fixed_order] >= (FLAC__float)subframe_bps)
- continue; /* don't even try */
- rice_parameter = (fixed_residual_bits_per_sample[fixed_order] > 0.0)? (unsigned)(fixed_residual_bits_per_sample[fixed_order]+0.5) : 0; /* 0.5 is for rounding */
- #else
- if(FLAC__fixedpoint_trunc(fixed_residual_bits_per_sample[fixed_order]) >= (int)subframe_bps)
- continue; /* don't even try */
- rice_parameter = (fixed_residual_bits_per_sample[fixed_order] > FLAC__FP_ZERO)? (unsigned)FLAC__fixedpoint_trunc(fixed_residual_bits_per_sample[fixed_order]+FLAC__FP_ONE_HALF) : 0; /* 0.5 is for rounding */
- #endif
- rice_parameter++; /* to account for the signed->unsigned conversion during rice coding */
- if(rice_parameter >= rice_parameter_limit) {
- #ifdef DEBUG_VERBOSE
- fprintf(stderr, "clipping rice_parameter (%u -> %u) @0\n", rice_parameter, rice_parameter_limit - 1);
- #endif
- rice_parameter = rice_parameter_limit - 1;
- }
- _candidate_bits =
- evaluate_fixed_subframe_(
- encoder,
- integer_signal,
- residual[!_best_subframe],
- encoder->private_->abs_residual_partition_sums,
- encoder->private_->raw_bits_per_partition,
- frame_header->blocksize,
- subframe_bps,
- fixed_order,
- rice_parameter,
- rice_parameter_limit,
- min_partition_order,
- max_partition_order,
- encoder->protected_->do_escape_coding,
- encoder->protected_->rice_parameter_search_dist,
- subframe[!_best_subframe],
- partitioned_rice_contents[!_best_subframe]
- );
- if(_candidate_bits < _best_bits) {
- _best_subframe = !_best_subframe;
- _best_bits = _candidate_bits;
- }
- }
- }
-
- #ifndef FLAC__INTEGER_ONLY_LIBRARY
- /* encode lpc */
- if(encoder->protected_->max_lpc_order > 0) {
- if(encoder->protected_->max_lpc_order >= frame_header->blocksize)
- max_lpc_order = frame_header->blocksize-1;
- else
- max_lpc_order = encoder->protected_->max_lpc_order;
- if(max_lpc_order > 0) {
- unsigned a;
- for (a = 0; a < encoder->protected_->num_apodizations; a++) {
- FLAC__lpc_window_data(integer_signal, encoder->private_->window[a], encoder->private_->windowed_signal, frame_header->blocksize);
- encoder->private_->local_lpc_compute_autocorrelation(encoder->private_->windowed_signal, frame_header->blocksize, max_lpc_order+1, autoc);
- /* if autoc[0] == 0.0, the signal is constant and we usually won't get here, but it can happen */
- if(autoc[0] != 0.0) {
- FLAC__lpc_compute_lp_coefficients(autoc, &max_lpc_order, encoder->private_->lp_coeff, lpc_error);
- if(encoder->protected_->do_exhaustive_model_search) {
- min_lpc_order = 1;
- }
- else {
- const unsigned guess_lpc_order =
- FLAC__lpc_compute_best_order(
- lpc_error,
- max_lpc_order,
- frame_header->blocksize,
- subframe_bps + (
- encoder->protected_->do_qlp_coeff_prec_search?
- FLAC__MIN_QLP_COEFF_PRECISION : /* have to guess; use the min possible size to avoid accidentally favoring lower orders */
- encoder->protected_->qlp_coeff_precision
- )
- );
- min_lpc_order = max_lpc_order = guess_lpc_order;
- }
- if(max_lpc_order >= frame_header->blocksize)
- max_lpc_order = frame_header->blocksize - 1;
- for(lpc_order = min_lpc_order; lpc_order <= max_lpc_order; lpc_order++) {
- lpc_residual_bits_per_sample = FLAC__lpc_compute_expected_bits_per_residual_sample(lpc_error[lpc_order-1], frame_header->blocksize-lpc_order);
- if(lpc_residual_bits_per_sample >= (FLAC__double)subframe_bps)
- continue; /* don't even try */
- rice_parameter = (lpc_residual_bits_per_sample > 0.0)? (unsigned)(lpc_residual_bits_per_sample+0.5) : 0; /* 0.5 is for rounding */
- rice_parameter++; /* to account for the signed->unsigned conversion during rice coding */
- if(rice_parameter >= rice_parameter_limit) {
- #ifdef DEBUG_VERBOSE
- fprintf(stderr, "clipping rice_parameter (%u -> %u) @1\n", rice_parameter, rice_parameter_limit - 1);
- #endif
- rice_parameter = rice_parameter_limit - 1;
- }
- if(encoder->protected_->do_qlp_coeff_prec_search) {
- min_qlp_coeff_precision = FLAC__MIN_QLP_COEFF_PRECISION;
- /* try to ensure a 32-bit datapath throughout for 16bps(+1bps for side channel) or less */
- if(subframe_bps <= 17) {
- max_qlp_coeff_precision = min(32 - subframe_bps - lpc_order, FLAC__MAX_QLP_COEFF_PRECISION);
- max_qlp_coeff_precision = max(max_qlp_coeff_precision, min_qlp_coeff_precision);
- }
- else
- max_qlp_coeff_precision = FLAC__MAX_QLP_COEFF_PRECISION;
- }
- else {
- min_qlp_coeff_precision = max_qlp_coeff_precision = encoder->protected_->qlp_coeff_precision;
- }
- for(qlp_coeff_precision = min_qlp_coeff_precision; qlp_coeff_precision <= max_qlp_coeff_precision; qlp_coeff_precision++) {
- _candidate_bits =
- evaluate_lpc_subframe_(
- encoder,
- integer_signal,
- residual[!_best_subframe],
- encoder->private_->abs_residual_partition_sums,
- encoder->private_->raw_bits_per_partition,
- encoder->private_->lp_coeff[lpc_order-1],
- frame_header->blocksize,
- subframe_bps,
- lpc_order,
- qlp_coeff_precision,
- rice_parameter,
- rice_parameter_limit,
- min_partition_order,
- max_partition_order,
- encoder->protected_->do_escape_coding,
- encoder->protected_->rice_parameter_search_dist,
- subframe[!_best_subframe],
- partitioned_rice_contents[!_best_subframe]
- );
- if(_candidate_bits > 0) { /* if == 0, there was a problem quantizing the lpcoeffs */
- if(_candidate_bits < _best_bits) {
- _best_subframe = !_best_subframe;
- _best_bits = _candidate_bits;
- }
- }
- }
- }
- }
- }
- }
- }
- #endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */
- }
- }
-
- /* under rare circumstances this can happen when all but lpc subframe types are disabled: */
- if(_best_bits == UINT_MAX) {
- FLAC__ASSERT(_best_subframe == 0);
- _best_bits = evaluate_verbatim_subframe_(encoder, integer_signal, frame_header->blocksize, subframe_bps, subframe[_best_subframe]);
- }
-
- *best_subframe = _best_subframe;
- *best_bits = _best_bits;
-
- return true;
- }
-
- FLAC__bool add_subframe_(
- FLAC__StreamEncoder *encoder,
- unsigned blocksize,
- unsigned subframe_bps,
- const FLAC__Subframe *subframe,
- FLAC__BitWriter *frame
- )
- {
- switch(subframe->type) {
- case FLAC__SUBFRAME_TYPE_CONSTANT:
- if(!FLAC__subframe_add_constant(&(subframe->data.constant), subframe_bps, subframe->wasted_bits, frame)) {
- encoder->protected_->state = FLAC__STREAM_ENCODER_FRAMING_ERROR;
- return false;
- }
- break;
- case FLAC__SUBFRAME_TYPE_FIXED:
- if(!FLAC__subframe_add_fixed(&(subframe->data.fixed), blocksize - subframe->data.fixed.order, subframe_bps, subframe->wasted_bits, frame)) {
- encoder->protected_->state = FLAC__STREAM_ENCODER_FRAMING_ERROR;
- return false;
- }
- break;
- case FLAC__SUBFRAME_TYPE_LPC:
- if(!FLAC__subframe_add_lpc(&(subframe->data.lpc), blocksize - subframe->data.lpc.order, subframe_bps, subframe->wasted_bits, frame)) {
- encoder->protected_->state = FLAC__STREAM_ENCODER_FRAMING_ERROR;
- return false;
- }
- break;
- case FLAC__SUBFRAME_TYPE_VERBATIM:
- if(!FLAC__subframe_add_verbatim(&(subframe->data.verbatim), blocksize, subframe_bps, subframe->wasted_bits, frame)) {
- encoder->protected_->state = FLAC__STREAM_ENCODER_FRAMING_ERROR;
- return false;
- }
- break;
- default:
- FLAC__ASSERT(0);
- }
-
- return true;
- }
-
- #define SPOTCHECK_ESTIMATE 0
- #if SPOTCHECK_ESTIMATE
- static void spotcheck_subframe_estimate_(
- FLAC__StreamEncoder *encoder,
- unsigned blocksize,
- unsigned subframe_bps,
- const FLAC__Subframe *subframe,
- unsigned estimate
- )
- {
- FLAC__bool ret;
- FLAC__BitWriter *frame = FLAC__bitwriter_new();
- if(frame == 0) {
- fprintf(stderr, "EST: can't allocate frame\n");
- return;
- }
- if(!FLAC__bitwriter_init(frame)) {
- fprintf(stderr, "EST: can't init frame\n");
- return;
- }
- ret = add_subframe_(encoder, blocksize, subframe_bps, subframe, frame);
- FLAC__ASSERT(ret);
- {
- const unsigned actual = FLAC__bitwriter_get_input_bits_unconsumed(frame);
- if(estimate != actual)
- fprintf(stderr, "EST: bad, frame#%u sub#%%d type=%8s est=%u, actual=%u, delta=%d\n", encoder->private_->current_frame_number, FLAC__SubframeTypeString[subframe->type], estimate, actual, (int)actual-(int)estimate);
- }
- FLAC__bitwriter_delete(frame);
- }
- #endif
-
- unsigned evaluate_constant_subframe_(
- FLAC__StreamEncoder *encoder,
- const FLAC__int32 signal,
- unsigned blocksize,
- unsigned subframe_bps,
- FLAC__Subframe *subframe
- )
- {
- unsigned estimate;
- subframe->type = FLAC__SUBFRAME_TYPE_CONSTANT;
- subframe->data.constant.value = signal;
-
- estimate = FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN + subframe->wasted_bits + subframe_bps;
-
- #if SPOTCHECK_ESTIMATE
- spotcheck_subframe_estimate_(encoder, blocksize, subframe_bps, subframe, estimate);
- #else
- (void)encoder, (void)blocksize;
- #endif
-
- return estimate;
- }
-
- unsigned evaluate_fixed_subframe_(
- FLAC__StreamEncoder *encoder,
- const FLAC__int32 signal[],
- FLAC__int32 residual[],
- FLAC__uint64 abs_residual_partition_sums[],
- unsigned raw_bits_per_partition[],
- unsigned blocksize,
- unsigned subframe_bps,
- unsigned order,
- unsigned rice_parameter,
- unsigned rice_parameter_limit,
- unsigned min_partition_order,
- unsigned max_partition_order,
- FLAC__bool do_escape_coding,
- unsigned rice_parameter_search_dist,
- FLAC__Subframe *subframe,
- FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents
- )
- {
- unsigned i, residual_bits, estimate;
- const unsigned residual_samples = blocksize - order;
-
- FLAC__fixed_compute_residual(signal+order, residual_samples, order, residual);
-
- subframe->type = FLAC__SUBFRAME_TYPE_FIXED;
-
- subframe->data.fixed.entropy_coding_method.type = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE;
- subframe->data.fixed.entropy_coding_method.data.partitioned_rice.contents = partitioned_rice_contents;
- subframe->data.fixed.residual = residual;
-
- residual_bits =
- find_best_partition_order_(
- encoder->private_,
- residual,
- abs_residual_partition_sums,
- raw_bits_per_partition,
- residual_samples,
- order,
- rice_parameter,
- rice_parameter_limit,
- min_partition_order,
- max_partition_order,
- subframe_bps,
- do_escape_coding,
- rice_parameter_search_dist,
- &subframe->data.fixed.entropy_coding_method
- );
-
- subframe->data.fixed.order = order;
- for(i = 0; i < order; i++)
- subframe->data.fixed.warmup[i] = signal[i];
-
- estimate = FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN + subframe->wasted_bits + (order * subframe_bps) + residual_bits;
-
- #if SPOTCHECK_ESTIMATE
- spotcheck_subframe_estimate_(encoder, blocksize, subframe_bps, subframe, estimate);
- #endif
-
- return estimate;
- }
-
- #ifndef FLAC__INTEGER_ONLY_LIBRARY
- unsigned evaluate_lpc_subframe_(
- FLAC__StreamEncoder *encoder,
- const FLAC__int32 signal[],
- FLAC__int32 residual[],
- FLAC__uint64 abs_residual_partition_sums[],
- unsigned raw_bits_per_partition[],
- const FLAC__real lp_coeff[],
- unsigned blocksize,
- unsigned subframe_bps,
- unsigned order,
- unsigned qlp_coeff_precision,
- unsigned rice_parameter,
- unsigned rice_parameter_limit,
- unsigned min_partition_order,
- unsigned max_partition_order,
- FLAC__bool do_escape_coding,
- unsigned rice_parameter_search_dist,
- FLAC__Subframe *subframe,
- FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents
- )
- {
- FLAC__int32 qlp_coeff[FLAC__MAX_LPC_ORDER];
- unsigned i, residual_bits, estimate;
- int quantization, ret;
- const unsigned residual_samples = blocksize - order;
-
- /* try to keep qlp coeff precision such that only 32-bit math is required for decode of <=16bps streams */
- if(subframe_bps <= 16) {
- FLAC__ASSERT(order > 0);
- FLAC__ASSERT(order <= FLAC__MAX_LPC_ORDER);
- qlp_coeff_precision = min(qlp_coeff_precision, 32 - subframe_bps - FLAC__bitmath_ilog2(order));
- }
-
- ret = FLAC__lpc_quantize_coefficients(lp_coeff, order, qlp_coeff_precision, qlp_coeff, &quantization);
- if(ret != 0)
- return 0; /* this is a hack to indicate to the caller that we can't do lp at this order on this subframe */
-
- if(subframe_bps + qlp_coeff_precision + FLAC__bitmath_ilog2(order) <= 32)
- if(subframe_bps <= 16 && qlp_coeff_precision <= 16)
- encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_16bit(signal+order, residual_samples, qlp_coeff, order, quantization, residual);
- else
- encoder->private_->local_lpc_compute_residual_from_qlp_coefficients(signal+order, residual_samples, qlp_coeff, order, quantization, residual);
- else
- encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_64bit(signal+order, residual_samples, qlp_coeff, order, quantization, residual);
-
- subframe->type = FLAC__SUBFRAME_TYPE_LPC;
-
- subframe->data.lpc.entropy_coding_method.type = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE;
- subframe->data.lpc.entropy_coding_method.data.partitioned_rice.contents = partitioned_rice_contents;
- subframe->data.lpc.residual = residual;
-
- residual_bits =
- find_best_partition_order_(
- encoder->private_,
- residual,
- abs_residual_partition_sums,
- raw_bits_per_partition,
- residual_samples,
- order,
- rice_parameter,
- rice_parameter_limit,
- min_partition_order,
- max_partition_order,
- subframe_bps,
- do_escape_coding,
- rice_parameter_search_dist,
- &subframe->data.lpc.entropy_coding_method
- );
-
- subframe->data.lpc.order = order;
- subframe->data.lpc.qlp_coeff_precision = qlp_coeff_precision;
- subframe->data.lpc.quantization_level = quantization;
- memcpy(subframe->data.lpc.qlp_coeff, qlp_coeff, sizeof(FLAC__int32)*FLAC__MAX_LPC_ORDER);
- for(i = 0; i < order; i++)
- subframe->data.lpc.warmup[i] = signal[i];
-
- estimate = FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN + subframe->wasted_bits + FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN + FLAC__SUBFRAME_LPC_QLP_SHIFT_LEN + (order * (qlp_coeff_precision + subframe_bps)) + residual_bits;
-
- #if SPOTCHECK_ESTIMATE
- spotcheck_subframe_estimate_(encoder, blocksize, subframe_bps, subframe, estimate);
- #endif
-
- return estimate;
- }
- #endif
-
- unsigned evaluate_verbatim_subframe_(
- FLAC__StreamEncoder *encoder,
- const FLAC__int32 signal[],
- unsigned blocksize,
- unsigned subframe_bps,
- FLAC__Subframe *subframe
- )
- {
- unsigned estimate;
-
- subframe->type = FLAC__SUBFRAME_TYPE_VERBATIM;
-
- subframe->data.verbatim.data = signal;
-
- estimate = FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN + subframe->wasted_bits + (blocksize * subframe_bps);
-
- #if SPOTCHECK_ESTIMATE
- spotcheck_subframe_estimate_(encoder, blocksize, subframe_bps, subframe, estimate);
- #else
- (void)encoder;
- #endif
-
- return estimate;
- }
-
- unsigned find_best_partition_order_(
- FLAC__StreamEncoderPrivate *private_,
- const FLAC__int32 residual[],
- FLAC__uint64 abs_residual_partition_sums[],
- unsigned raw_bits_per_partition[],
- unsigned residual_samples,
- unsigned predictor_order,
- unsigned rice_parameter,
- unsigned rice_parameter_limit,
- unsigned min_partition_order,
- unsigned max_partition_order,
- unsigned bps,
- FLAC__bool do_escape_coding,
- unsigned rice_parameter_search_dist,
- FLAC__EntropyCodingMethod *best_ecm
- )
- {
- unsigned residual_bits, best_residual_bits = 0;
- unsigned best_parameters_index = 0;
- unsigned best_partition_order = 0;
- const unsigned blocksize = residual_samples + predictor_order;
-
- max_partition_order = FLAC__format_get_max_rice_partition_order_from_blocksize_limited_max_and_predictor_order(max_partition_order, blocksize, predictor_order);
- min_partition_order = min(min_partition_order, max_partition_order);
-
- precompute_partition_info_sums_(residual, abs_residual_partition_sums, residual_samples, predictor_order, min_partition_order, max_partition_order, bps);
-
- if(do_escape_coding)
- precompute_partition_info_escapes_(residual, raw_bits_per_partition, residual_samples, predictor_order, min_partition_order, max_partition_order);
-
- {
- int partition_order;
- unsigned sum;
-
- for(partition_order = (int)max_partition_order, sum = 0; partition_order >= (int)min_partition_order; partition_order--) {
- if(!
- set_partitioned_rice_(
- #ifdef EXACT_RICE_BITS_CALCULATION
- residual,
- #endif
- abs_residual_partition_sums+sum,
- raw_bits_per_partition+sum,
- residual_samples,
- predictor_order,
- rice_parameter,
- rice_parameter_limit,
- rice_parameter_search_dist,
- (unsigned)partition_order,
- do_escape_coding,
- &private_->partitioned_rice_contents_extra[!best_parameters_index],
- &residual_bits
- )
- )
- {
- FLAC__ASSERT(best_residual_bits != 0);
- break;
- }
- sum += 1u << partition_order;
- if(best_residual_bits == 0 || residual_bits < best_residual_bits) {
- best_residual_bits = residual_bits;
- best_parameters_index = !best_parameters_index;
- best_partition_order = partition_order;
- }
- }
- }
-
- best_ecm->data.partitioned_rice.order = best_partition_order;
-
- {
- /*
- * We are allowed to de-const the pointer based on our special
- * knowledge; it is const to the outside world.
- */
- FLAC__EntropyCodingMethod_PartitionedRiceContents* prc = (FLAC__EntropyCodingMethod_PartitionedRiceContents*)best_ecm->data.partitioned_rice.contents;
- unsigned partition;
-
- /* save best parameters and raw_bits */
- FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(prc, max(6, best_partition_order));
- memcpy(prc->parameters, private_->partitioned_rice_contents_extra[best_parameters_index].parameters, sizeof(unsigned)*(1<<(best_partition_order)));
- if(do_escape_coding)
- memcpy(prc->raw_bits, private_->partitioned_rice_contents_extra[best_parameters_index].raw_bits, sizeof(unsigned)*(1<<(best_partition_order)));
- /*
- * Now need to check if the type should be changed to
- * FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2 based on the
- * size of the rice parameters.
- */
- for(partition = 0; partition < (1u<<best_partition_order); partition++) {
- if(prc->parameters[partition] >= FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER) {
- best_ecm->type = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2;
- break;
- }
- }
- }
-
- return best_residual_bits;
- }
-
- #if defined(FLAC__CPU_IA32) && !defined FLAC__NO_ASM && defined FLAC__HAS_NASM
- extern void precompute_partition_info_sums_32bit_asm_ia32_(
- const FLAC__int32 residual[],
- FLAC__uint64 abs_residual_partition_sums[],
- unsigned blocksize,
- unsigned predictor_order,
- unsigned min_partition_order,
- unsigned max_partition_order
- );
- #endif
-
- void precompute_partition_info_sums_(
- const FLAC__int32 residual[],
- FLAC__uint64 abs_residual_partition_sums[],
- unsigned residual_samples,
- unsigned predictor_order,
- unsigned min_partition_order,
- unsigned max_partition_order,
- unsigned bps
- )
- {
- const unsigned default_partition_samples = (residual_samples + predictor_order) >> max_partition_order;
- unsigned partitions = 1u << max_partition_order;
-
- FLAC__ASSERT(default_partition_samples > predictor_order);
-
- #if defined(FLAC__CPU_IA32) && !defined FLAC__NO_ASM && defined FLAC__HAS_NASM
- /* slightly pessimistic but still catches all common cases */
- /* WATCHOUT: "+ bps" is an assumption that the average residual magnitude will not be more than "bps" bits */
- if(FLAC__bitmath_ilog2(default_partition_samples) + bps < 32) {
- precompute_partition_info_sums_32bit_asm_ia32_(residual, abs_residual_partition_sums, residual_samples + predictor_order, predictor_order, min_partition_order, max_partition_order);
- return;
- }
- #endif
-
- /* first do max_partition_order */
- {
- unsigned partition, residual_sample, end = (unsigned)(-(int)predictor_order);
- /* slightly pessimistic but still catches all common cases */
- /* WATCHOUT: "+ bps" is an assumption that the average residual magnitude will not be more than "bps" bits */
- if(FLAC__bitmath_ilog2(default_partition_samples) + bps < 32) {
- FLAC__uint32 abs_residual_partition_sum;
-
- for(partition = residual_sample = 0; partition < partitions; partition++) {
- end += default_partition_samples;
- abs_residual_partition_sum = 0;
- for( ; residual_sample < end; residual_sample++)
- abs_residual_partition_sum += abs(residual[residual_sample]); /* abs(INT_MIN) is undefined, but if the residual is INT_MIN we have bigger problems */
- abs_residual_partition_sums[partition] = abs_residual_partition_sum;
- }
- }
- else { /* have to pessimistically use 64 bits for accumulator */
- FLAC__uint64 abs_residual_partition_sum;
-
- for(partition = residual_sample = 0; partition < partitions; partition++) {
- end += default_partition_samples;
- abs_residual_partition_sum = 0;
- for( ; residual_sample < end; residual_sample++)
- abs_residual_partition_sum += abs(residual[residual_sample]); /* abs(INT_MIN) is undefined, but if the residual is INT_MIN we have bigger problems */
- abs_residual_partition_sums[partition] = abs_residual_partition_sum;
- }
- }
- }
-
- /* now merge partitions for lower orders */
- {
- unsigned from_partition = 0, to_partition = partitions;
- int partition_order;
- for(partition_order = (int)max_partition_order - 1; partition_order >= (int)min_partition_order; partition_order--) {
- unsigned i;
- partitions >>= 1;
- for(i = 0; i < partitions; i++) {
- abs_residual_partition_sums[to_partition++] =
- abs_residual_partition_sums[from_partition ] +
- abs_residual_partition_sums[from_partition+1];
- from_partition += 2;
- }
- }
- }
- }
-
- void precompute_partition_info_escapes_(
- const FLAC__int32 residual[],
- unsigned raw_bits_per_partition[],
- unsigned residual_samples,
- unsigned predictor_order,
- unsigned min_partition_order,
- unsigned max_partition_order
- )
- {
- int partition_order;
- unsigned from_partition, to_partition = 0;
- const unsigned blocksize = residual_samples + predictor_order;
-
- /* first do max_partition_order */
- for(partition_order = (int)max_partition_order; partition_order >= 0; partition_order--) {
- FLAC__int32 r;
- FLAC__uint32 rmax;
- unsigned partition, partition_sample, partition_samples, residual_sample;
- const unsigned partitions = 1u << partition_order;
- const unsigned default_partition_samples = blocksize >> partition_order;
-
- FLAC__ASSERT(default_partition_samples > predictor_order);
-
- for(partition = residual_sample = 0; partition < partitions; partition++) {
- partition_samples = default_partition_samples;
- if(partition == 0)
- partition_samples -= predictor_order;
- rmax = 0;
- for(partition_sample = 0; partition_sample < partition_samples; partition_sample++) {
- r = residual[residual_sample++];
- /* OPT: maybe faster: rmax |= r ^ (r>>31) */
- if(r < 0)
- rmax |= ~r;
- else
- rmax |= r;
- }
- /* now we know all residual values are in the range [-rmax-1,rmax] */
- raw_bits_per_partition[partition] = rmax? FLAC__bitmath_ilog2(rmax) + 2 : 1;
- }
- to_partition = partitions;
- break; /*@@@ yuck, should remove the 'for' loop instead */
- }
-
- /* now merge partitions for lower orders */
- for(from_partition = 0, --partition_order; partition_order >= (int)min_partition_order; partition_order--) {
- unsigned m;
- unsigned i;
- const unsigned partitions = 1u << partition_order;
- for(i = 0; i < partitions; i++) {
- m = raw_bits_per_partition[from_partition];
- from_partition++;
- raw_bits_per_partition[to_partition] = max(m, raw_bits_per_partition[from_partition]);
- from_partition++;
- to_partition++;
- }
- }
- }
-
- #ifdef EXACT_RICE_BITS_CALCULATION
- static FLaC__INLINE unsigned count_rice_bits_in_partition_(
- const unsigned rice_parameter,
- const unsigned partition_samples,
- const FLAC__int32 *residual
- )
- {
- unsigned i, partition_bits =
- FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN + /* actually could end up being FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN but err on side of 16bps */
- (1+rice_parameter) * partition_samples /* 1 for unary stop bit + rice_parameter for the binary portion */
- ;
- for(i = 0; i < partition_samples; i++)
- partition_bits += ( (FLAC__uint32)((residual[i]<<1)^(residual[i]>>31)) >> rice_parameter );
- return partition_bits;
- }
- #else
- static FLaC__INLINE unsigned count_rice_bits_in_partition_(
- const unsigned rice_parameter,
- const unsigned partition_samples,
- const FLAC__uint64 abs_residual_partition_sum
- )
- {
- return
- FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN + /* actually could end up being FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN but err on side of 16bps */
- (1+rice_parameter) * partition_samples + /* 1 for unary stop bit + rice_parameter for the binary portion */
- (
- rice_parameter?
- (unsigned)(abs_residual_partition_sum >> (rice_parameter-1)) /* rice_parameter-1 because the real coder sign-folds instead of using a sign bit */
- : (unsigned)(abs_residual_partition_sum << 1) /* can't shift by negative number, so reverse */
- )
- - (partition_samples >> 1)
- /* -(partition_samples>>1) to subtract out extra contributions to the abs_residual_partition_sum.
- * The actual number of bits used is closer to the sum(for all i in the partition) of abs(residual[i])>>(rice_parameter-1)
- * By using the abs_residual_partition sum, we also add in bits in the LSBs that would normally be shifted out.
- * So the subtraction term tries to guess how many extra bits were contributed.
- * If the LSBs are randomly distributed, this should average to 0.5 extra bits per sample.
- */
- ;
- }
- #endif
-
- FLAC__bool set_partitioned_rice_(
- #ifdef EXACT_RICE_BITS_CALCULATION
- const FLAC__int32 residual[],
- #endif
- const FLAC__uint64 abs_residual_partition_sums[],
- const unsigned raw_bits_per_partition[],
- const unsigned residual_samples,
- const unsigned predictor_order,
- const unsigned suggested_rice_parameter,
- const unsigned rice_parameter_limit,
- const unsigned rice_parameter_search_dist,
- const unsigned partition_order,
- const FLAC__bool search_for_escapes,
- FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents,
- unsigned *bits
- )
- {
- unsigned rice_parameter, partition_bits;
- unsigned best_partition_bits, best_rice_parameter = 0;
- unsigned bits_ = FLAC__ENTROPY_CODING_METHOD_TYPE_LEN + FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN;
- unsigned *parameters, *raw_bits;
- #ifdef ENABLE_RICE_PARAMETER_SEARCH
- unsigned min_rice_parameter, max_rice_parameter;
- #else
- (void)rice_parameter_search_dist;
- #endif
-
- FLAC__ASSERT(suggested_rice_parameter < FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_ESCAPE_PARAMETER);
- FLAC__ASSERT(rice_parameter_limit <= FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_ESCAPE_PARAMETER);
-
- FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(partitioned_rice_contents, max(6, partition_order));
- parameters = partitioned_rice_contents->parameters;
- raw_bits = partitioned_rice_contents->raw_bits;
-
- if(partition_order == 0) {
- best_partition_bits = (unsigned)(-1);
- #ifdef ENABLE_RICE_PARAMETER_SEARCH
- if(rice_parameter_search_dist) {
- if(suggested_rice_parameter < rice_parameter_search_dist)
- min_rice_parameter = 0;
- else
- min_rice_parameter = suggested_rice_parameter - rice_parameter_search_dist;
- max_rice_parameter = suggested_rice_parameter + rice_parameter_search_dist;
- if(max_rice_parameter >= rice_parameter_limit) {
- #ifdef DEBUG_VERBOSE
- fprintf(stderr, "clipping rice_parameter (%u -> %u) @5\n", max_rice_parameter, rice_parameter_limit - 1);
- #endif
- max_rice_parameter = rice_parameter_limit - 1;
- }
- }
- else
- min_rice_parameter = max_rice_parameter = suggested_rice_parameter;
-
- for(rice_parameter = min_rice_parameter; rice_parameter <= max_rice_parameter; rice_parameter++) {
- #else
- rice_parameter = suggested_rice_parameter;
- #endif
- #ifdef EXACT_RICE_BITS_CALCULATION
- partition_bits = count_rice_bits_in_partition_(rice_parameter, residual_samples, residual);
- #else
- partition_bits = count_rice_bits_in_partition_(rice_parameter, residual_samples, abs_residual_partition_sums[0]);
- #endif
- if(partition_bits < best_partition_bits) {
- best_rice_parameter = rice_parameter;
- best_partition_bits = partition_bits;
- }
- #ifdef ENABLE_RICE_PARAMETER_SEARCH
- }
- #endif
- if(search_for_escapes) {
- partition_bits = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN + FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN + raw_bits_per_partition[0] * residual_samples;
- if(partition_bits <= best_partition_bits) {
- raw_bits[0] = raw_bits_per_partition[0];
- best_rice_parameter = 0; /* will be converted to appropriate escape parameter later */
- best_partition_bits = partition_bits;
- }
- else
- raw_bits[0] = 0;
- }
- parameters[0] = best_rice_parameter;
- bits_ += best_partition_bits;
- }
- else {
- unsigned partition, residual_sample;
- unsigned partition_samples;
- FLAC__uint64 mean, k;
- const unsigned partitions = 1u << partition_order;
- for(partition = residual_sample = 0; partition < partitions; partition++) {
- partition_samples = (residual_samples+predictor_order) >> partition_order;
- if(partition == 0) {
- if(partition_samples <= predictor_order)
- return false;
- else
- partition_samples -= predictor_order;
- }
- mean = abs_residual_partition_sums[partition];
- /* we are basically calculating the size in bits of the
- * average residual magnitude in the partition:
- * rice_parameter = floor(log2(mean/partition_samples))
- * 'mean' is not a good name for the variable, it is
- * actually the sum of magnitudes of all residual values
- * in the partition, so the actual mean is
- * mean/partition_samples
- */
- for(rice_parameter = 0, k = partition_samples; k < mean; rice_parameter++, k <<= 1)
- ;
- if(rice_parameter >= rice_parameter_limit) {
- #ifdef DEBUG_VERBOSE
- fprintf(stderr, "clipping rice_parameter (%u -> %u) @6\n", rice_parameter, rice_parameter_limit - 1);
- #endif
- rice_parameter = rice_parameter_limit - 1;
- }
-
- best_partition_bits = (unsigned)(-1);
- #ifdef ENABLE_RICE_PARAMETER_SEARCH
- if(rice_parameter_search_dist) {
- if(rice_parameter < rice_parameter_search_dist)
- min_rice_parameter = 0;
- else
- min_rice_parameter = rice_parameter - rice_parameter_search_dist;
- max_rice_parameter = rice_parameter + rice_parameter_search_dist;
- if(max_rice_parameter >= rice_parameter_limit) {
- #ifdef DEBUG_VERBOSE
- fprintf(stderr, "clipping rice_parameter (%u -> %u) @7\n", max_rice_parameter, rice_parameter_limit - 1);
- #endif
- max_rice_parameter = rice_parameter_limit - 1;
- }
- }
- else
- min_rice_parameter = max_rice_parameter = rice_parameter;
-
- for(rice_parameter = min_rice_parameter; rice_parameter <= max_rice_parameter; rice_parameter++) {
- #endif
- #ifdef EXACT_RICE_BITS_CALCULATION
- partition_bits = count_rice_bits_in_partition_(rice_parameter, partition_samples, residual+residual_sample);
- #else
- partition_bits = count_rice_bits_in_partition_(rice_parameter, partition_samples, abs_residual_partition_sums[partition]);
- #endif
- if(partition_bits < best_partition_bits) {
- best_rice_parameter = rice_parameter;
- best_partition_bits = partition_bits;
- }
- #ifdef ENABLE_RICE_PARAMETER_SEARCH
- }
- #endif
- if(search_for_escapes) {
- partition_bits = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN + FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN + raw_bits_per_partition[partition] * partition_samples;
- if(partition_bits <= best_partition_bits) {
- raw_bits[partition] = raw_bits_per_partition[partition];
- best_rice_parameter = 0; /* will be converted to appropriate escape parameter later */
- best_partition_bits = partition_bits;
- }
- else
- raw_bits[partition] = 0;
- }
- parameters[partition] = best_rice_parameter;
- bits_ += best_partition_bits;
- residual_sample += partition_samples;
- }
- }
-
- *bits = bits_;
- return true;
- }
-
- unsigned get_wasted_bits_(FLAC__int32 signal[], unsigned samples)
- {
- unsigned i, shift;
- FLAC__int32 x = 0;
-
- for(i = 0; i < samples && !(x&1); i++)
- x |= signal[i];
-
- if(x == 0) {
- shift = 0;
- }
- else {
- for(shift = 0; !(x&1); shift++)
- x >>= 1;
- }
-
- if(shift > 0) {
- for(i = 0; i < samples; i++)
- signal[i] >>= shift;
- }
-
- return shift;
- }
-
- void append_to_verify_fifo_(verify_input_fifo *fifo, const FLAC__int32 * const input[], unsigned input_offset, unsigned channels, unsigned wide_samples)
- {
- unsigned channel;
-
- for(channel = 0; channel < channels; channel++)
- memcpy(&fifo->data[channel][fifo->tail], &input[channel][input_offset], sizeof(FLAC__int32) * wide_samples);
-
- fifo->tail += wide_samples;
-
- FLAC__ASSERT(fifo->tail <= fifo->size);
- }
-
- void append_to_verify_fifo_interleaved_(verify_input_fifo *fifo, const FLAC__int32 input[], unsigned input_offset, unsigned channels, unsigned wide_samples)
- {
- unsigned channel;
- unsigned sample, wide_sample;
- unsigned tail = fifo->tail;
-
- sample = input_offset * channels;
- for(wide_sample = 0; wide_sample < wide_samples; wide_sample++) {
- for(channel = 0; channel < channels; channel++)
- fifo->data[channel][tail] = input[sample++];
- tail++;
- }
- fifo->tail = tail;
-
- FLAC__ASSERT(fifo->tail <= fifo->size);
- }
-
- FLAC__StreamDecoderReadStatus verify_read_callback_(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data)
- {
- FLAC__StreamEncoder *encoder = (FLAC__StreamEncoder*)client_data;
- const size_t encoded_bytes = encoder->private_->verify.output.bytes;
- (void)decoder;
-
- if(encoder->private_->verify.needs_magic_hack) {
- FLAC__ASSERT(*bytes >= FLAC__STREAM_SYNC_LENGTH);
- *bytes = FLAC__STREAM_SYNC_LENGTH;
- memcpy(buffer, FLAC__STREAM_SYNC_STRING, *bytes);
- encoder->private_->verify.needs_magic_hack = false;
- }
- else {
- if(encoded_bytes == 0) {
- /*
- * If we get here, a FIFO underflow has occurred,
- * which means there is a bug somewhere.
- */
- FLAC__ASSERT(0);
- return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
- }
- else if(encoded_bytes < *bytes)
- *bytes = encoded_bytes;
- memcpy(buffer, encoder->private_->verify.output.data, *bytes);
- encoder->private_->verify.output.data += *bytes;
- encoder->private_->verify.output.bytes -= *bytes;
- }
-
- return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
- }
-
- FLAC__StreamDecoderWriteStatus verify_write_callback_(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
- {
- FLAC__StreamEncoder *encoder = (FLAC__StreamEncoder *)client_data;
- unsigned channel;
- const unsigned channels = frame->header.channels;
- const unsigned blocksize = frame->header.blocksize;
- const unsigned bytes_per_block = sizeof(FLAC__int32) * blocksize;
-
- (void)decoder;
-
- for(channel = 0; channel < channels; channel++) {
- if(0 != memcmp(buffer[channel], encoder->private_->verify.input_fifo.data[channel], bytes_per_block)) {
- unsigned i, sample = 0;
- FLAC__int32 expect = 0, got = 0;
-
- for(i = 0; i < blocksize; i++) {
- if(buffer[channel][i] != encoder->private_->verify.input_fifo.data[channel][i]) {
- sample = i;
- expect = (FLAC__int32)encoder->private_->verify.input_fifo.data[channel][i];
- got = (FLAC__int32)buffer[channel][i];
- break;
- }
- }
- FLAC__ASSERT(i < blocksize);
- FLAC__ASSERT(frame->header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER);
- encoder->private_->verify.error_stats.absolute_sample = frame->header.number.sample_number + sample;
- encoder->private_->verify.error_stats.frame_number = (unsigned)(frame->header.number.sample_number / blocksize);
- encoder->private_->verify.error_stats.channel = channel;
- encoder->private_->verify.error_stats.sample = sample;
- encoder->private_->verify.error_stats.expected = expect;
- encoder->private_->verify.error_stats.got = got;
- encoder->protected_->state = FLAC__STREAM_ENCODER_VERIFY_MISMATCH_IN_AUDIO_DATA;
- return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
- }
- }
- /* dequeue the frame from the fifo */
- encoder->private_->verify.input_fifo.tail -= blocksize;
- FLAC__ASSERT(encoder->private_->verify.input_fifo.tail <= OVERREAD_);
- for(channel = 0; channel < channels; channel++)
- memmove(&encoder->private_->verify.input_fifo.data[channel][0], &encoder->private_->verify.input_fifo.data[channel][blocksize], encoder->private_->verify.input_fifo.tail * sizeof(encoder->private_->verify.input_fifo.data[0][0]));
- return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
- }
-
- void verify_metadata_callback_(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data)
- {
- (void)decoder, (void)metadata, (void)client_data;
- }
-
- void verify_error_callback_(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
- {
- FLAC__StreamEncoder *encoder = (FLAC__StreamEncoder*)client_data;
- (void)decoder, (void)status;
- encoder->protected_->state = FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR;
- }
-
- FLAC__StreamEncoderReadStatus file_read_callback_enc(const FLAC__StreamEncoder *encoder, FLAC__byte buffer[], size_t *bytes, void *client_data)
- {
- (void)client_data;
-
- *bytes = fread(buffer, 1, *bytes, encoder->private_->file);
- if (*bytes == 0) {
- if (feof(encoder->private_->file))
- return FLAC__STREAM_ENCODER_READ_STATUS_END_OF_STREAM;
- else if (ferror(encoder->private_->file))
- return FLAC__STREAM_ENCODER_READ_STATUS_ABORT;
- }
- return FLAC__STREAM_ENCODER_READ_STATUS_CONTINUE;
- }
-
- FLAC__StreamEncoderSeekStatus file_seek_callback_enc(const FLAC__StreamEncoder *encoder, FLAC__uint64 absolute_byte_offset, void *client_data)
- {
- (void)client_data;
-
- if(fseeko(encoder->private_->file, (off_t)absolute_byte_offset, SEEK_SET) < 0)
- return FLAC__STREAM_ENCODER_SEEK_STATUS_ERROR;
- else
- return FLAC__STREAM_ENCODER_SEEK_STATUS_OK;
- }
-
- FLAC__StreamEncoderTellStatus file_tell_callback_enc(const FLAC__StreamEncoder *encoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
- {
- off_t offset;
-
- (void)client_data;
-
- offset = ftello(encoder->private_->file);
-
- if(offset < 0) {
- return FLAC__STREAM_ENCODER_TELL_STATUS_ERROR;
- }
- else {
- *absolute_byte_offset = (FLAC__uint64)offset;
- return FLAC__STREAM_ENCODER_TELL_STATUS_OK;
- }
- }
-
- #ifdef FLAC__VALGRIND_TESTING
- static size_t local__fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)
- {
- size_t ret = fwrite(ptr, size, nmemb, stream);
- if(!ferror(stream))
- fflush(stream);
- return ret;
- }
- #else
- #define local__fwrite fwrite
- #endif
-
- FLAC__StreamEncoderWriteStatus file_write_callback_(const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], size_t bytes, unsigned samples, unsigned current_frame, void *client_data)
- {
- (void)client_data, (void)current_frame;
-
- if(local__fwrite(buffer, sizeof(FLAC__byte), bytes, encoder->private_->file) == bytes) {
- FLAC__bool call_it = 0 != encoder->private_->progress_callback && (
- #if FLAC__HAS_OGG
- /* We would like to be able to use 'samples > 0' in the
- * clause here but currently because of the nature of our
- * Ogg writing implementation, 'samples' is always 0 (see
- * ogg_encoder_aspect.c). The downside is extra progress
- * callbacks.
- */
- encoder->private_->is_ogg? true :
- #endif
- samples > 0
- );
- if(call_it) {
- /* NOTE: We have to add +bytes, +samples, and +1 to the stats
- * because at this point in the callback chain, the stats
- * have not been updated. Only after we return and control
- * gets back to write_frame_() are the stats updated
- */
- encoder->private_->progress_callback(encoder, encoder->private_->bytes_written+bytes, encoder->private_->samples_written+samples, encoder->private_->frames_written+(samples?1:0), encoder->private_->total_frames_estimate, encoder->private_->client_data);
- }
- return FLAC__STREAM_ENCODER_WRITE_STATUS_OK;
- }
- else
- return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
- }
-
- /*
- * This will forcibly set stdout to binary mode (for OSes that require it)
- */
- FILE *get_binary_stdout_(void)
- {
- /* if something breaks here it is probably due to the presence or
- * absence of an underscore before the identifiers 'setmode',
- * 'fileno', and/or 'O_BINARY'; check your system header files.
- */
- #if defined _MSC_VER || defined __MINGW32__
- _setmode(_fileno(stdout), _O_BINARY);
- #elif defined __CYGWIN__
- /* almost certainly not needed for any modern Cygwin, but let's be safe... */
- setmode(_fileno(stdout), _O_BINARY);
- #elif defined __EMX__
- setmode(fileno(stdout), O_BINARY);
- #endif
-
- return stdout;
- }
-
- #endif
- /********* End of inlined file: stream_encoder.c *********/
-
- /********* Start of inlined file: stream_encoder_framing.c *********/
-
- /********* Start of inlined file: juce_FlacHeader.h *********/
- // This file is included at the start of each FLAC .c file, just to do a few housekeeping
- // tasks..
-
- #define VERSION "1.2.1"
-
- #define FLAC__NO_DLL 1
-
- #ifdef _MSC_VER
- #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4312)
- #endif
-
- #if ! (defined (_WIN32) || defined (_WIN64) || defined (LINUX))
- #define FLAC__SYS_DARWIN 1
- #endif
- /********* End of inlined file: juce_FlacHeader.h *********/
-
- #if JUCE_USE_FLAC
-
- #if HAVE_CONFIG_H
- # include <config.h>
- #endif
-
- #include <stdio.h>
- #include <string.h> /* for strlen() */
-
- #ifdef max
- #undef max
- #endif
- #define max(x,y) ((x)>(y)?(x):(y))
-
- static FLAC__bool add_entropy_coding_method_(FLAC__BitWriter *bw, const FLAC__EntropyCodingMethod *method);
- static FLAC__bool add_residual_partitioned_rice_(FLAC__BitWriter *bw, const FLAC__int32 residual[], const unsigned residual_samples, const unsigned predictor_order, const unsigned rice_parameters[], const unsigned raw_bits[], const unsigned partition_order, const FLAC__bool is_extended);
-
- FLAC__bool FLAC__add_metadata_block(const FLAC__StreamMetadata *metadata, FLAC__BitWriter *bw)
- {
- unsigned i, j;
- const unsigned vendor_string_length = (unsigned)strlen(FLAC__VENDOR_STRING);
-
- if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->is_last, FLAC__STREAM_METADATA_IS_LAST_LEN))
- return false;
-
- if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->type, FLAC__STREAM_METADATA_TYPE_LEN))
- return false;
-
- /*
- * First, for VORBIS_COMMENTs, adjust the length to reflect our vendor string
- */
- i = metadata->length;
- if(metadata->type == FLAC__METADATA_TYPE_VORBIS_COMMENT) {
- FLAC__ASSERT(metadata->data.vorbis_comment.vendor_string.length == 0 || 0 != metadata->data.vorbis_comment.vendor_string.entry);
- i -= metadata->data.vorbis_comment.vendor_string.length;
- i += vendor_string_length;
- }
- FLAC__ASSERT(i < (1u << FLAC__STREAM_METADATA_LENGTH_LEN));
- if(!FLAC__bitwriter_write_raw_uint32(bw, i, FLAC__STREAM_METADATA_LENGTH_LEN))
- return false;
-
- switch(metadata->type) {
- case FLAC__METADATA_TYPE_STREAMINFO:
- FLAC__ASSERT(metadata->data.stream_info.min_blocksize < (1u << FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN));
- if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.stream_info.min_blocksize, FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN))
- return false;
- FLAC__ASSERT(metadata->data.stream_info.max_blocksize < (1u << FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN));
- if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.stream_info.max_blocksize, FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN))
- return false;
- FLAC__ASSERT(metadata->data.stream_info.min_framesize < (1u << FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN));
- if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.stream_info.min_framesize, FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN))
- return false;
- FLAC__ASSERT(metadata->data.stream_info.max_framesize < (1u << FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN));
- if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.stream_info.max_framesize, FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN))
- return false;
- FLAC__ASSERT(FLAC__format_sample_rate_is_valid(metadata->data.stream_info.sample_rate));
- if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.stream_info.sample_rate, FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN))
- return false;
- FLAC__ASSERT(metadata->data.stream_info.channels > 0);
- FLAC__ASSERT(metadata->data.stream_info.channels <= (1u << FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN));
- if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.stream_info.channels-1, FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN))
- return false;
- FLAC__ASSERT(metadata->data.stream_info.bits_per_sample > 0);
- FLAC__ASSERT(metadata->data.stream_info.bits_per_sample <= (1u << FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN));
- if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.stream_info.bits_per_sample-1, FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN))
- return false;
- if(!FLAC__bitwriter_write_raw_uint64(bw, metadata->data.stream_info.total_samples, FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN))
- return false;
- if(!FLAC__bitwriter_write_byte_block(bw, metadata->data.stream_info.md5sum, 16))
- return false;
- break;
- case FLAC__METADATA_TYPE_PADDING:
- if(!FLAC__bitwriter_write_zeroes(bw, metadata->length * 8))
- return false;
- break;
- case FLAC__METADATA_TYPE_APPLICATION:
- if(!FLAC__bitwriter_write_byte_block(bw, metadata->data.application.id, FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8))
- return false;
- if(!FLAC__bitwriter_write_byte_block(bw, metadata->data.application.data, metadata->length - (FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8)))
- return false;
- break;
- case FLAC__METADATA_TYPE_SEEKTABLE:
- for(i = 0; i < metadata->data.seek_table.num_points; i++) {
- if(!FLAC__bitwriter_write_raw_uint64(bw, metadata->data.seek_table.points[i].sample_number, FLAC__STREAM_METADATA_SEEKPOINT_SAMPLE_NUMBER_LEN))
- return false;
- if(!FLAC__bitwriter_write_raw_uint64(bw, metadata->data.seek_table.points[i].stream_offset, FLAC__STREAM_METADATA_SEEKPOINT_STREAM_OFFSET_LEN))
- return false;
- if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.seek_table.points[i].frame_samples, FLAC__STREAM_METADATA_SEEKPOINT_FRAME_SAMPLES_LEN))
- return false;
- }
- break;
- case FLAC__METADATA_TYPE_VORBIS_COMMENT:
- if(!FLAC__bitwriter_write_raw_uint32_little_endian(bw, vendor_string_length))
- return false;
- if(!FLAC__bitwriter_write_byte_block(bw, (const FLAC__byte*)FLAC__VENDOR_STRING, vendor_string_length))
- return false;
- if(!FLAC__bitwriter_write_raw_uint32_little_endian(bw, metadata->data.vorbis_comment.num_comments))
- return false;
- for(i = 0; i < metadata->data.vorbis_comment.num_comments; i++) {
- if(!FLAC__bitwriter_write_raw_uint32_little_endian(bw, metadata->data.vorbis_comment.comments[i].length))
- return false;
- if(!FLAC__bitwriter_write_byte_block(bw, metadata->data.vorbis_comment.comments[i].entry, metadata->data.vorbis_comment.comments[i].length))
- return false;
- }
- break;
- case FLAC__METADATA_TYPE_CUESHEET:
- FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_MEDIA_CATALOG_NUMBER_LEN % 8 == 0);
- if(!FLAC__bitwriter_write_byte_block(bw, (const FLAC__byte*)metadata->data.cue_sheet.media_catalog_number, FLAC__STREAM_METADATA_CUESHEET_MEDIA_CATALOG_NUMBER_LEN/8))
- return false;
- if(!FLAC__bitwriter_write_raw_uint64(bw, metadata->data.cue_sheet.lead_in, FLAC__STREAM_METADATA_CUESHEET_LEAD_IN_LEN))
- return false;
- if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.cue_sheet.is_cd? 1 : 0, FLAC__STREAM_METADATA_CUESHEET_IS_CD_LEN))
- return false;
- if(!FLAC__bitwriter_write_zeroes(bw, FLAC__STREAM_METADATA_CUESHEET_RESERVED_LEN))
- return false;
- if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.cue_sheet.num_tracks, FLAC__STREAM_METADATA_CUESHEET_NUM_TRACKS_LEN))
- return false;
- for(i = 0; i < metadata->data.cue_sheet.num_tracks; i++) {
- const FLAC__StreamMetadata_CueSheet_Track *track = metadata->data.cue_sheet.tracks + i;
-
- if(!FLAC__bitwriter_write_raw_uint64(bw, track->offset, FLAC__STREAM_METADATA_CUESHEET_TRACK_OFFSET_LEN))
- return false;
- if(!FLAC__bitwriter_write_raw_uint32(bw, track->number, FLAC__STREAM_METADATA_CUESHEET_TRACK_NUMBER_LEN))
- return false;
- FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN % 8 == 0);
- if(!FLAC__bitwriter_write_byte_block(bw, (const FLAC__byte*)track->isrc, FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN/8))
- return false;
- if(!FLAC__bitwriter_write_raw_uint32(bw, track->type, FLAC__STREAM_METADATA_CUESHEET_TRACK_TYPE_LEN))
- return false;
- if(!FLAC__bitwriter_write_raw_uint32(bw, track->pre_emphasis, FLAC__STREAM_METADATA_CUESHEET_TRACK_PRE_EMPHASIS_LEN))
- return false;
- if(!FLAC__bitwriter_write_zeroes(bw, FLAC__STREAM_METADATA_CUESHEET_TRACK_RESERVED_LEN))
- return false;
- if(!FLAC__bitwriter_write_raw_uint32(bw, track->num_indices, FLAC__STREAM_METADATA_CUESHEET_TRACK_NUM_INDICES_LEN))
- return false;
- for(j = 0; j < track->num_indices; j++) {
- const FLAC__StreamMetadata_CueSheet_Index *index = track->indices + j;
-
- if(!FLAC__bitwriter_write_raw_uint64(bw, index->offset, FLAC__STREAM_METADATA_CUESHEET_INDEX_OFFSET_LEN))
- return false;
- if(!FLAC__bitwriter_write_raw_uint32(bw, index->number, FLAC__STREAM_METADATA_CUESHEET_INDEX_NUMBER_LEN))
- return false;
- if(!FLAC__bitwriter_write_zeroes(bw, FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN))
- return false;
- }
- }
- break;
- case FLAC__METADATA_TYPE_PICTURE:
- {
- size_t len;
- if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.picture.type, FLAC__STREAM_METADATA_PICTURE_TYPE_LEN))
- return false;
- len = strlen(metadata->data.picture.mime_type);
- if(!FLAC__bitwriter_write_raw_uint32(bw, len, FLAC__STREAM_METADATA_PICTURE_MIME_TYPE_LENGTH_LEN))
- return false;
- if(!FLAC__bitwriter_write_byte_block(bw, (const FLAC__byte*)metadata->data.picture.mime_type, len))
- return false;
- len = strlen((const char *)metadata->data.picture.description);
- if(!FLAC__bitwriter_write_raw_uint32(bw, len, FLAC__STREAM_METADATA_PICTURE_DESCRIPTION_LENGTH_LEN))
- return false;
- if(!FLAC__bitwriter_write_byte_block(bw, metadata->data.picture.description, len))
- return false;
- if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.picture.width, FLAC__STREAM_METADATA_PICTURE_WIDTH_LEN))
- return false;
- if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.picture.height, FLAC__STREAM_METADATA_PICTURE_HEIGHT_LEN))
- return false;
- if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.picture.depth, FLAC__STREAM_METADATA_PICTURE_DEPTH_LEN))
- return false;
- if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.picture.colors, FLAC__STREAM_METADATA_PICTURE_COLORS_LEN))
- return false;
- if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.picture.data_length, FLAC__STREAM_METADATA_PICTURE_DATA_LENGTH_LEN))
- return false;
- if(!FLAC__bitwriter_write_byte_block(bw, metadata->data.picture.data, metadata->data.picture.data_length))
- return false;
- }
- break;
- default:
- if(!FLAC__bitwriter_write_byte_block(bw, metadata->data.unknown.data, metadata->length))
- return false;
- break;
- }
-
- FLAC__ASSERT(FLAC__bitwriter_is_byte_aligned(bw));
- return true;
- }
-
- FLAC__bool FLAC__frame_add_header(const FLAC__FrameHeader *header, FLAC__BitWriter *bw)
- {
- unsigned u, blocksize_hint, sample_rate_hint;
- FLAC__byte crc;
-
- FLAC__ASSERT(FLAC__bitwriter_is_byte_aligned(bw));
-
- if(!FLAC__bitwriter_write_raw_uint32(bw, FLAC__FRAME_HEADER_SYNC, FLAC__FRAME_HEADER_SYNC_LEN))
- return false;
-
- if(!FLAC__bitwriter_write_raw_uint32(bw, 0, FLAC__FRAME_HEADER_RESERVED_LEN))
- return false;
-
- if(!FLAC__bitwriter_write_raw_uint32(bw, (header->number_type == FLAC__FRAME_NUMBER_TYPE_FRAME_NUMBER)? 0 : 1, FLAC__FRAME_HEADER_BLOCKING_STRATEGY_LEN))
- return false;
-
- FLAC__ASSERT(header->blocksize > 0 && header->blocksize <= FLAC__MAX_BLOCK_SIZE);
- /* when this assertion holds true, any legal blocksize can be expressed in the frame header */
- FLAC__ASSERT(FLAC__MAX_BLOCK_SIZE <= 65535u);
- blocksize_hint = 0;
- switch(header->blocksize) {
- case 192: u = 1; break;
- case 576: u = 2; break;
- case 1152: u = 3; break;
- case 2304: u = 4; break;
- case 4608: u = 5; break;
- case 256: u = 8; break;
- case 512: u = 9; break;
- case 1024: u = 10; break;
- case 2048: u = 11; break;
- case 4096: u = 12; break;
- case 8192: u = 13; break;
- case 16384: u = 14; break;
- case 32768: u = 15; break;
- default:
- if(header->blocksize <= 0x100)
- blocksize_hint = u = 6;
- else
- blocksize_hint = u = 7;
- break;
- }
- if(!FLAC__bitwriter_write_raw_uint32(bw, u, FLAC__FRAME_HEADER_BLOCK_SIZE_LEN))
- return false;
-
- FLAC__ASSERT(FLAC__format_sample_rate_is_valid(header->sample_rate));
- sample_rate_hint = 0;
- switch(header->sample_rate) {
- case 88200: u = 1; break;
- case 176400: u = 2; break;
- case 192000: u = 3; break;
- case 8000: u = 4; break;
- case 16000: u = 5; break;
- case 22050: u = 6; break;
- case 24000: u = 7; break;
- case 32000: u = 8; break;
- case 44100: u = 9; break;
- case 48000: u = 10; break;
- case 96000: u = 11; break;
- default:
- if(header->sample_rate <= 255000 && header->sample_rate % 1000 == 0)
- sample_rate_hint = u = 12;
- else if(header->sample_rate % 10 == 0)
- sample_rate_hint = u = 14;
- else if(header->sample_rate <= 0xffff)
- sample_rate_hint = u = 13;
- else
- u = 0;
- break;
- }
- if(!FLAC__bitwriter_write_raw_uint32(bw, u, FLAC__FRAME_HEADER_SAMPLE_RATE_LEN))
- return false;
-
- FLAC__ASSERT(header->channels > 0 && header->channels <= (1u << FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN) && header->channels <= FLAC__MAX_CHANNELS);
- switch(header->channel_assignment) {
- case FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT:
- u = header->channels - 1;
- break;
- case FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE:
- FLAC__ASSERT(header->channels == 2);
- u = 8;
- break;
- case FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE:
- FLAC__ASSERT(header->channels == 2);
- u = 9;
- break;
- case FLAC__CHANNEL_ASSIGNMENT_MID_SIDE:
- FLAC__ASSERT(header->channels == 2);
- u = 10;
- break;
- default:
- FLAC__ASSERT(0);
- }
- if(!FLAC__bitwriter_write_raw_uint32(bw, u, FLAC__FRAME_HEADER_CHANNEL_ASSIGNMENT_LEN))
- return false;
-
- FLAC__ASSERT(header->bits_per_sample > 0 && header->bits_per_sample <= (1u << FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN));
- switch(header->bits_per_sample) {
- case 8 : u = 1; break;
- case 12: u = 2; break;
- case 16: u = 4; break;
- case 20: u = 5; break;
- case 24: u = 6; break;
- default: u = 0; break;
- }
- if(!FLAC__bitwriter_write_raw_uint32(bw, u, FLAC__FRAME_HEADER_BITS_PER_SAMPLE_LEN))
- return false;
-
- if(!FLAC__bitwriter_write_raw_uint32(bw, 0, FLAC__FRAME_HEADER_ZERO_PAD_LEN))
- return false;
-
- if(header->number_type == FLAC__FRAME_NUMBER_TYPE_FRAME_NUMBER) {
- if(!FLAC__bitwriter_write_utf8_uint32(bw, header->number.frame_number))
- return false;
- }
- else {
- if(!FLAC__bitwriter_write_utf8_uint64(bw, header->number.sample_number))
- return false;
- }
-
- if(blocksize_hint)
- if(!FLAC__bitwriter_write_raw_uint32(bw, header->blocksize-1, (blocksize_hint==6)? 8:16))
- return false;
-
- switch(sample_rate_hint) {
- case 12:
- if(!FLAC__bitwriter_write_raw_uint32(bw, header->sample_rate / 1000, 8))
- return false;
- break;
- case 13:
- if(!FLAC__bitwriter_write_raw_uint32(bw, header->sample_rate, 16))
- return false;
- break;
- case 14:
- if(!FLAC__bitwriter_write_raw_uint32(bw, header->sample_rate / 10, 16))
- return false;
- break;
- }
-
- /* write the CRC */
- if(!FLAC__bitwriter_get_write_crc8(bw, &crc))
- return false;
- if(!FLAC__bitwriter_write_raw_uint32(bw, crc, FLAC__FRAME_HEADER_CRC_LEN))
- return false;
-
- return true;
- }
-
- FLAC__bool FLAC__subframe_add_constant(const FLAC__Subframe_Constant *subframe, unsigned subframe_bps, unsigned wasted_bits, FLAC__BitWriter *bw)
- {
- FLAC__bool ok;
-
- ok =
- FLAC__bitwriter_write_raw_uint32(bw, FLAC__SUBFRAME_TYPE_CONSTANT_BYTE_ALIGNED_MASK | (wasted_bits? 1:0), FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN) &&
- (wasted_bits? FLAC__bitwriter_write_unary_unsigned(bw, wasted_bits-1) : true) &&
- FLAC__bitwriter_write_raw_int32(bw, subframe->value, subframe_bps)
- ;
-
- return ok;
- }
-
- FLAC__bool FLAC__subframe_add_fixed(const FLAC__Subframe_Fixed *subframe, unsigned residual_samples, unsigned subframe_bps, unsigned wasted_bits, FLAC__BitWriter *bw)
- {
- unsigned i;
-
- if(!FLAC__bitwriter_write_raw_uint32(bw, FLAC__SUBFRAME_TYPE_FIXED_BYTE_ALIGNED_MASK | (subframe->order<<1) | (wasted_bits? 1:0), FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN))
- return false;
- if(wasted_bits)
- if(!FLAC__bitwriter_write_unary_unsigned(bw, wasted_bits-1))
- return false;
-
- for(i = 0; i < subframe->order; i++)
- if(!FLAC__bitwriter_write_raw_int32(bw, subframe->warmup[i], subframe_bps))
- return false;
-
- if(!add_entropy_coding_method_(bw, &subframe->entropy_coding_method))
- return false;
- switch(subframe->entropy_coding_method.type) {
- case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE:
- case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2:
- if(!add_residual_partitioned_rice_(
- bw,
- subframe->residual,
- residual_samples,
- subframe->order,
- subframe->entropy_coding_method.data.partitioned_rice.contents->parameters,
- subframe->entropy_coding_method.data.partitioned_rice.contents->raw_bits,
- subframe->entropy_coding_method.data.partitioned_rice.order,
- /*is_extended=*/subframe->entropy_coding_method.type == FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2
- ))
- return false;
- break;
- default:
- FLAC__ASSERT(0);
- }
-
- return true;
- }
-
- FLAC__bool FLAC__subframe_add_lpc(const FLAC__Subframe_LPC *subframe, unsigned residual_samples, unsigned subframe_bps, unsigned wasted_bits, FLAC__BitWriter *bw)
- {
- unsigned i;
-
- if(!FLAC__bitwriter_write_raw_uint32(bw, FLAC__SUBFRAME_TYPE_LPC_BYTE_ALIGNED_MASK | ((subframe->order-1)<<1) | (wasted_bits? 1:0), FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN))
- return false;
- if(wasted_bits)
- if(!FLAC__bitwriter_write_unary_unsigned(bw, wasted_bits-1))
- return false;
-
- for(i = 0; i < subframe->order; i++)
- if(!FLAC__bitwriter_write_raw_int32(bw, subframe->warmup[i], subframe_bps))
- return false;
-
- if(!FLAC__bitwriter_write_raw_uint32(bw, subframe->qlp_coeff_precision-1, FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN))
- return false;
- if(!FLAC__bitwriter_write_raw_int32(bw, subframe->quantization_level, FLAC__SUBFRAME_LPC_QLP_SHIFT_LEN))
- return false;
- for(i = 0; i < subframe->order; i++)
- if(!FLAC__bitwriter_write_raw_int32(bw, subframe->qlp_coeff[i], subframe->qlp_coeff_precision))
- return false;
-
- if(!add_entropy_coding_method_(bw, &subframe->entropy_coding_method))
- return false;
- switch(subframe->entropy_coding_method.type) {
- case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE:
- case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2:
- if(!add_residual_partitioned_rice_(
- bw,
- subframe->residual,
- residual_samples,
- subframe->order,
- subframe->entropy_coding_method.data.partitioned_rice.contents->parameters,
- subframe->entropy_coding_method.data.partitioned_rice.contents->raw_bits,
- subframe->entropy_coding_method.data.partitioned_rice.order,
- /*is_extended=*/subframe->entropy_coding_method.type == FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2
- ))
- return false;
- break;
- default:
- FLAC__ASSERT(0);
- }
-
- return true;
- }
-
- FLAC__bool FLAC__subframe_add_verbatim(const FLAC__Subframe_Verbatim *subframe, unsigned samples, unsigned subframe_bps, unsigned wasted_bits, FLAC__BitWriter *bw)
- {
- unsigned i;
- const FLAC__int32 *signal = subframe->data;
-
- if(!FLAC__bitwriter_write_raw_uint32(bw, FLAC__SUBFRAME_TYPE_VERBATIM_BYTE_ALIGNED_MASK | (wasted_bits? 1:0), FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN))
- return false;
- if(wasted_bits)
- if(!FLAC__bitwriter_write_unary_unsigned(bw, wasted_bits-1))
- return false;
-
- for(i = 0; i < samples; i++)
- if(!FLAC__bitwriter_write_raw_int32(bw, signal[i], subframe_bps))
- return false;
-
- return true;
- }
-
- FLAC__bool add_entropy_coding_method_(FLAC__BitWriter *bw, const FLAC__EntropyCodingMethod *method)
- {
- if(!FLAC__bitwriter_write_raw_uint32(bw, method->type, FLAC__ENTROPY_CODING_METHOD_TYPE_LEN))
- return false;
- switch(method->type) {
- case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE:
- case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2:
- if(!FLAC__bitwriter_write_raw_uint32(bw, method->data.partitioned_rice.order, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN))
- return false;
- break;
- default:
- FLAC__ASSERT(0);
- }
- return true;
- }
-
- FLAC__bool add_residual_partitioned_rice_(FLAC__BitWriter *bw, const FLAC__int32 residual[], const unsigned residual_samples, const unsigned predictor_order, const unsigned rice_parameters[], const unsigned raw_bits[], const unsigned partition_order, const FLAC__bool is_extended)
- {
- const unsigned plen = is_extended? FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN : FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN;
- const unsigned pesc = is_extended? FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_ESCAPE_PARAMETER : FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER;
-
- if(partition_order == 0) {
- unsigned i;
-
- if(raw_bits[0] == 0) {
- if(!FLAC__bitwriter_write_raw_uint32(bw, rice_parameters[0], plen))
- return false;
- if(!FLAC__bitwriter_write_rice_signed_block(bw, residual, residual_samples, rice_parameters[0]))
- return false;
- }
- else {
- FLAC__ASSERT(rice_parameters[0] == 0);
- if(!FLAC__bitwriter_write_raw_uint32(bw, pesc, plen))
- return false;
- if(!FLAC__bitwriter_write_raw_uint32(bw, raw_bits[0], FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN))
- return false;
- for(i = 0; i < residual_samples; i++) {
- if(!FLAC__bitwriter_write_raw_int32(bw, residual[i], raw_bits[0]))
- return false;
- }
- }
- return true;
- }
- else {
- unsigned i, j, k = 0, k_last = 0;
- unsigned partition_samples;
- const unsigned default_partition_samples = (residual_samples+predictor_order) >> partition_order;
- for(i = 0; i < (1u<<partition_order); i++) {
- partition_samples = default_partition_samples;
- if(i == 0)
- partition_samples -= predictor_order;
- k += partition_samples;
- if(raw_bits[i] == 0) {
- if(!FLAC__bitwriter_write_raw_uint32(bw, rice_parameters[i], plen))
- return false;
- if(!FLAC__bitwriter_write_rice_signed_block(bw, residual+k_last, k-k_last, rice_parameters[i]))
- return false;
- }
- else {
- if(!FLAC__bitwriter_write_raw_uint32(bw, pesc, plen))
- return false;
- if(!FLAC__bitwriter_write_raw_uint32(bw, raw_bits[i], FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN))
- return false;
- for(j = k_last; j < k; j++) {
- if(!FLAC__bitwriter_write_raw_int32(bw, residual[j], raw_bits[i]))
- return false;
- }
- }
- k_last = k;
- }
- return true;
- }
- }
-
- #endif
- /********* End of inlined file: stream_encoder_framing.c *********/
-
- /********* Start of inlined file: window_flac.c *********/
-
- /********* Start of inlined file: juce_FlacHeader.h *********/
- // This file is included at the start of each FLAC .c file, just to do a few housekeeping
- // tasks..
-
- #define VERSION "1.2.1"
-
- #define FLAC__NO_DLL 1
-
- #ifdef _MSC_VER
- #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4312)
- #endif
-
- #if ! (defined (_WIN32) || defined (_WIN64) || defined (LINUX))
- #define FLAC__SYS_DARWIN 1
- #endif
- /********* End of inlined file: juce_FlacHeader.h *********/
-
- #if JUCE_USE_FLAC
-
- #if HAVE_CONFIG_H
- # include <config.h>
- #endif
-
- #include <math.h>
-
- #ifndef FLAC__INTEGER_ONLY_LIBRARY
-
- #ifndef M_PI
- /* math.h in VC++ doesn't seem to have this (how Microsoft is that?) */
- #define M_PI 3.14159265358979323846
- #endif
-
- void FLAC__window_bartlett(FLAC__real *window, const FLAC__int32 L)
- {
- const FLAC__int32 N = L - 1;
- FLAC__int32 n;
-
- if (L & 1) {
- for (n = 0; n <= N/2; n++)
- window[n] = 2.0f * n / (float)N;
- for (; n <= N; n++)
- window[n] = 2.0f - 2.0f * n / (float)N;
- }
- else {
- for (n = 0; n <= L/2-1; n++)
- window[n] = 2.0f * n / (float)N;
- for (; n <= N; n++)
- window[n] = 2.0f - 2.0f * (N-n) / (float)N;
- }
- }
-
- void FLAC__window_bartlett_hann(FLAC__real *window, const FLAC__int32 L)
- {
- const FLAC__int32 N = L - 1;
- FLAC__int32 n;
-
- for (n = 0; n < L; n++)
- window[n] = (FLAC__real)(0.62f - 0.48f * fabs((float)n/(float)N+0.5f) + 0.38f * cos(2.0f * M_PI * ((float)n/(float)N+0.5f)));
- }
-
- void FLAC__window_blackman(FLAC__real *window, const FLAC__int32 L)
- {
- const FLAC__int32 N = L - 1;
- FLAC__int32 n;
-
- for (n = 0; n < L; n++)
- window[n] = (FLAC__real)(0.42f - 0.5f * cos(2.0f * M_PI * n / N) + 0.08f * cos(4.0f * M_PI * n / N));
- }
-
- /* 4-term -92dB side-lobe */
- void FLAC__window_blackman_harris_4term_92db_sidelobe(FLAC__real *window, const FLAC__int32 L)
- {
- const FLAC__int32 N = L - 1;
- FLAC__int32 n;
-
- for (n = 0; n <= N; n++)
- window[n] = (FLAC__real)(0.35875f - 0.48829f * cos(2.0f * M_PI * n / N) + 0.14128f * cos(4.0f * M_PI * n / N) - 0.01168f * cos(6.0f * M_PI * n / N));
- }
-
- void FLAC__window_connes(FLAC__real *window, const FLAC__int32 L)
- {
- const FLAC__int32 N = L - 1;
- const double N2 = (double)N / 2.;
- FLAC__int32 n;
-
- for (n = 0; n <= N; n++) {
- double k = ((double)n - N2) / N2;
- k = 1.0f - k * k;
- window[n] = (FLAC__real)(k * k);
- }
- }
-
- void FLAC__window_flattop(FLAC__real *window, const FLAC__int32 L)
- {
- const FLAC__int32 N = L - 1;
- FLAC__int32 n;
-
- for (n = 0; n < L; n++)
- window[n] = (FLAC__real)(1.0f - 1.93f * cos(2.0f * M_PI * n / N) + 1.29f * cos(4.0f * M_PI * n / N) - 0.388f * cos(6.0f * M_PI * n / N) + 0.0322f * cos(8.0f * M_PI * n / N));
- }
-
- void FLAC__window_gauss(FLAC__real *window, const FLAC__int32 L, const FLAC__real stddev)
- {
- const FLAC__int32 N = L - 1;
- const double N2 = (double)N / 2.;
- FLAC__int32 n;
-
- for (n = 0; n <= N; n++) {
- const double k = ((double)n - N2) / (stddev * N2);
- window[n] = (FLAC__real)exp(-0.5f * k * k);
- }
- }
-
- void FLAC__window_hamming(FLAC__real *window, const FLAC__int32 L)
- {
- const FLAC__int32 N = L - 1;
- FLAC__int32 n;
-
- for (n = 0; n < L; n++)
- window[n] = (FLAC__real)(0.54f - 0.46f * cos(2.0f * M_PI * n / N));
- }
-
- void FLAC__window_hann(FLAC__real *window, const FLAC__int32 L)
- {
- const FLAC__int32 N = L - 1;
- FLAC__int32 n;
-
- for (n = 0; n < L; n++)
- window[n] = (FLAC__real)(0.5f - 0.5f * cos(2.0f * M_PI * n / N));
- }
-
- void FLAC__window_kaiser_bessel(FLAC__real *window, const FLAC__int32 L)
- {
- const FLAC__int32 N = L - 1;
- FLAC__int32 n;
-
- for (n = 0; n < L; n++)
- window[n] = (FLAC__real)(0.402f - 0.498f * cos(2.0f * M_PI * n / N) + 0.098f * cos(4.0f * M_PI * n / N) - 0.001f * cos(6.0f * M_PI * n / N));
- }
-
- void FLAC__window_nuttall(FLAC__real *window, const FLAC__int32 L)
- {
- const FLAC__int32 N = L - 1;
- FLAC__int32 n;
-
- for (n = 0; n < L; n++)
- window[n] = (FLAC__real)(0.3635819f - 0.4891775f*cos(2.0f*M_PI*n/N) + 0.1365995f*cos(4.0f*M_PI*n/N) - 0.0106411f*cos(6.0f*M_PI*n/N));
- }
-
- void FLAC__window_rectangle(FLAC__real *window, const FLAC__int32 L)
- {
- FLAC__int32 n;
-
- for (n = 0; n < L; n++)
- window[n] = 1.0f;
- }
-
- void FLAC__window_triangle(FLAC__real *window, const FLAC__int32 L)
- {
- FLAC__int32 n;
-
- if (L & 1) {
- for (n = 1; n <= L+1/2; n++)
- window[n-1] = 2.0f * n / ((float)L + 1.0f);
- for (; n <= L; n++)
- window[n-1] = - (float)(2 * (L - n + 1)) / ((float)L + 1.0f);
- }
- else {
- for (n = 1; n <= L/2; n++)
- window[n-1] = 2.0f * n / (float)L;
- for (; n <= L; n++)
- window[n-1] = ((float)(2 * (L - n)) + 1.0f) / (float)L;
- }
- }
-
- void FLAC__window_tukey(FLAC__real *window, const FLAC__int32 L, const FLAC__real p)
- {
- if (p <= 0.0)
- FLAC__window_rectangle(window, L);
- else if (p >= 1.0)
- FLAC__window_hann(window, L);
- else {
- const FLAC__int32 Np = (FLAC__int32)(p / 2.0f * L) - 1;
- FLAC__int32 n;
- /* start with rectangle... */
- FLAC__window_rectangle(window, L);
- /* ...replace ends with hann */
- if (Np > 0) {
- for (n = 0; n <= Np; n++) {
- window[n] = (FLAC__real)(0.5f - 0.5f * cos(M_PI * n / Np));
- window[L-Np-1+n] = (FLAC__real)(0.5f - 0.5f * cos(M_PI * (n+Np) / Np));
- }
- }
- }
- }
-
- void FLAC__window_welch(FLAC__real *window, const FLAC__int32 L)
- {
- const FLAC__int32 N = L - 1;
- const double N2 = (double)N / 2.;
- FLAC__int32 n;
-
- for (n = 0; n <= N; n++) {
- const double k = ((double)n - N2) / N2;
- window[n] = (FLAC__real)(1.0f - k * k);
- }
- }
-
- #endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */
-
- #endif
- /********* End of inlined file: window_flac.c *********/
-
- }
-
- #ifdef _MSC_VER
- #pragma warning (pop)
- #endif
-
- BEGIN_JUCE_NAMESPACE
-
- using namespace FlacNamespace;
-
- #define flacFormatName TRANS("FLAC file")
- static const tchar* const flacExtensions[] = { T(".flac"), 0 };
-
- class FlacReader : public AudioFormatReader
- {
- FLAC__StreamDecoder* decoder;
- AudioSampleBuffer reservoir;
- int reservoirStart, samplesInReservoir;
- bool ok, scanningForLength;
-
- public:
-
- FlacReader (InputStream* const in)
- : AudioFormatReader (in, flacFormatName),
- reservoir (2, 0),
- reservoirStart (0),
- samplesInReservoir (0),
- scanningForLength (false)
- {
- using namespace FlacNamespace;
- lengthInSamples = 0;
-
- decoder = FLAC__stream_decoder_new();
-
- ok = FLAC__stream_decoder_init_stream (decoder,
- readCallback_, seekCallback_, tellCallback_, lengthCallback_,
- eofCallback_, writeCallback_, metadataCallback_, errorCallback_,
- (void*) this) == FLAC__STREAM_DECODER_INIT_STATUS_OK;
-
- if (ok)
- {
- FLAC__stream_decoder_process_until_end_of_metadata (decoder);
-
- if (lengthInSamples == 0 && sampleRate > 0)
- {
- // the length hasn't been stored in the metadata, so we'll need to
- // work it out the length the hard way, by scanning the whole file..
- scanningForLength = true;
- FLAC__stream_decoder_process_until_end_of_stream (decoder);
- scanningForLength = false;
- const int64 tempLength = lengthInSamples;
-
- FLAC__stream_decoder_reset (decoder);
- FLAC__stream_decoder_process_until_end_of_metadata (decoder);
- lengthInSamples = tempLength;
- }
- }
- }
-
- ~FlacReader()
- {
- FLAC__stream_decoder_delete (decoder);
- }
-
- void useMetadata (const FLAC__StreamMetadata_StreamInfo& info)
- {
- sampleRate = info.sample_rate;
- bitsPerSample = info.bits_per_sample;
- lengthInSamples = (unsigned int) info.total_samples;
- numChannels = info.channels;
-
- reservoir.setSize (numChannels, 2 * info.max_blocksize, false, false, true);
- }
-
- // returns the number of samples read
- bool read (int** destSamples,
- int64 startSampleInFile,
- int numSamples)
- {
- using namespace FlacNamespace;
-
- if (! ok)
- return false;
-
- int offset = 0;
-
- if (startSampleInFile < 0)
- {
- const int num = (int) jmin ((int64) numSamples, -startSampleInFile);
-
- int n = 0;
- while (destSamples[n] != 0)
- {
- zeromem (destSamples[n], sizeof (int) * num);
- ++n;
- }
-
- offset += num;
- startSampleInFile += num;
- numSamples -= num;
- }
-
- while (numSamples > 0)
- {
- if (startSampleInFile >= reservoirStart
- && startSampleInFile < reservoirStart + samplesInReservoir)
- {
- const int num = (int) jmin ((int64) numSamples,
- reservoirStart + samplesInReservoir - startSampleInFile);
-
- jassert (num > 0);
-
- int n = 0;
- while (destSamples[n] != 0)
- {
- memcpy (destSamples[n] + offset,
- reservoir.getSampleData (n, (int) (startSampleInFile - reservoirStart)),
- sizeof (int) * num);
- ++n;
- }
-
- offset += num;
- startSampleInFile += num;
- numSamples -= num;
- }
- else
- {
- if (startSampleInFile < reservoirStart
- || startSampleInFile > reservoirStart + jmax (samplesInReservoir, 511))
- {
- if (startSampleInFile >= (int) lengthInSamples)
- {
- samplesInReservoir = 0;
- break;
- }
-
- // had some problems with flac crashing if the read pos is aligned more
- // accurately than this. Probably fixed in newer versions of the library, though.
- reservoirStart = (int) (startSampleInFile & ~511);
- FLAC__stream_decoder_seek_absolute (decoder, (FLAC__uint64) reservoirStart);
- }
- else
- {
- reservoirStart += samplesInReservoir;
- }
-
- samplesInReservoir = 0;
-
- FLAC__stream_decoder_process_single (decoder);
-
- if (samplesInReservoir == 0)
- break;
- }
- }
-
- if (numSamples > 0)
- {
- int n = 0;
- while (destSamples[n] != 0)
- {
- zeromem (destSamples[n] + offset, sizeof (int) * numSamples);
- ++n;
- }
- }
-
- return true;
- }
-
- void useSamples (const FLAC__int32* const buffer[], int numSamples)
- {
- if (scanningForLength)
- {
- lengthInSamples += numSamples;
- }
- else
- {
- if (numSamples > reservoir.getNumSamples())
- reservoir.setSize (numChannels, numSamples, false, false, true);
-
- const int bitsToShift = 32 - bitsPerSample;
-
- for (int i = 0; i < (int) numChannels; ++i)
- {
- const FLAC__int32* src = buffer[i];
-
- int n = i;
- while (src == 0 && n > 0)
- src = buffer [--n];
-
- if (src != 0)
- {
- int* dest = (int*) reservoir.getSampleData(i);
-
- for (int j = 0; j < numSamples; ++j)
- dest[j] = src[j] << bitsToShift;
- }
- }
-
- samplesInReservoir = numSamples;
- }
- }
-
- static FLAC__StreamDecoderReadStatus readCallback_ (const FLAC__StreamDecoder*, FLAC__byte buffer[], size_t* bytes, void* client_data)
- {
- *bytes = (unsigned int) ((const FlacReader*) client_data)->input->read (buffer, (int) *bytes);
- return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
- }
-
- static FLAC__StreamDecoderSeekStatus seekCallback_ (const FLAC__StreamDecoder*, FLAC__uint64 absolute_byte_offset, void* client_data)
- {
- ((const FlacReader*) client_data)->input->setPosition ((int) absolute_byte_offset);
- return FLAC__STREAM_DECODER_SEEK_STATUS_OK;
- }
-
- static FLAC__StreamDecoderTellStatus tellCallback_ (const FLAC__StreamDecoder*, FLAC__uint64* absolute_byte_offset, void* client_data)
- {
- *absolute_byte_offset = ((const FlacReader*) client_data)->input->getPosition();
- return FLAC__STREAM_DECODER_TELL_STATUS_OK;
- }
-
- static FLAC__StreamDecoderLengthStatus lengthCallback_ (const FLAC__StreamDecoder*, FLAC__uint64* stream_length, void* client_data)
- {
- *stream_length = ((const FlacReader*) client_data)->input->getTotalLength();
- return FLAC__STREAM_DECODER_LENGTH_STATUS_OK;
- }
-
- static FLAC__bool eofCallback_ (const FLAC__StreamDecoder*, void* client_data)
- {
- return ((const FlacReader*) client_data)->input->isExhausted();
- }
-
- static FLAC__StreamDecoderWriteStatus writeCallback_ (const FLAC__StreamDecoder*,
- const FLAC__Frame* frame,
- const FLAC__int32* const buffer[],
- void* client_data)
- {
- ((FlacReader*) client_data)->useSamples (buffer, frame->header.blocksize);
- return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
- }
-
- static void metadataCallback_ (const FLAC__StreamDecoder*,
- const FLAC__StreamMetadata* metadata,
- void* client_data)
- {
- ((FlacReader*) client_data)->useMetadata (metadata->data.stream_info);
- }
-
- static void errorCallback_ (const FLAC__StreamDecoder*, FLAC__StreamDecoderErrorStatus, void*)
- {
- }
-
- juce_UseDebuggingNewOperator
- };
-
- class FlacWriter : public AudioFormatWriter
- {
- FLAC__StreamEncoder* encoder;
- MemoryBlock temp;
-
- public:
- bool ok;
-
- FlacWriter (OutputStream* const out,
- const double sampleRate,
- const int numChannels,
- const int bitsPerSample_)
- : AudioFormatWriter (out, flacFormatName,
- sampleRate,
- numChannels,
- bitsPerSample_)
- {
- using namespace FlacNamespace;
- encoder = FLAC__stream_encoder_new();
-
- FLAC__stream_encoder_set_do_mid_side_stereo (encoder, numChannels == 2);
- FLAC__stream_encoder_set_loose_mid_side_stereo (encoder, numChannels == 2);
- FLAC__stream_encoder_set_channels (encoder, numChannels);
- FLAC__stream_encoder_set_bits_per_sample (encoder, jmin (24, bitsPerSample));
- FLAC__stream_encoder_set_sample_rate (encoder, (unsigned int) sampleRate);
- FLAC__stream_encoder_set_blocksize (encoder, 2048);
- FLAC__stream_encoder_set_do_escape_coding (encoder, true);
-
- ok = FLAC__stream_encoder_init_stream (encoder,
- encodeWriteCallback, encodeSeekCallback,
- encodeTellCallback, encodeMetadataCallback,
- (void*) this) == FLAC__STREAM_ENCODER_INIT_STATUS_OK;
- }
-
- ~FlacWriter()
- {
- if (ok)
- {
- FLAC__stream_encoder_finish (encoder);
- output->flush();
- }
- else
- {
- output = 0; // to stop the base class deleting this, as it needs to be returned
- // to the caller of createWriter()
- }
-
- FLAC__stream_encoder_delete (encoder);
- }
-
- bool write (const int** samplesToWrite, int numSamples)
- {
- if (! ok)
- return false;
-
- int* buf[3];
- const int bitsToShift = 32 - bitsPerSample;
-
- if (bitsToShift > 0)
- {
- const int numChannels = (samplesToWrite[1] == 0) ? 1 : 2;
- temp.setSize (sizeof (int) * numSamples * numChannels);
-
- buf[0] = (int*) temp.getData();
- buf[1] = buf[0] + numSamples;
- buf[2] = 0;
-
- for (int i = numChannels; --i >= 0;)
- {
- if (samplesToWrite[i] != 0)
- {
- for (int j = 0; j < numSamples; ++j)
- buf [i][j] = (samplesToWrite [i][j] >> bitsToShift);
- }
- }
-
- samplesToWrite = (const int**) buf;
- }
-
- return FLAC__stream_encoder_process (encoder,
- (const FLAC__int32**) samplesToWrite,
- numSamples) != 0;
- }
-
- bool writeData (const void* const data, const int size) const
- {
- return output->write (data, size);
- }
-
- static void packUint32 (FLAC__uint32 val, FLAC__byte* b, const int bytes)
- {
- b += bytes;
-
- for (int i = 0; i < bytes; ++i)
- {
- *(--b) = (FLAC__byte) (val & 0xff);
- val >>= 8;
- }
- }
-
- void writeMetaData (const FLAC__StreamMetadata* metadata)
- {
- using namespace FlacNamespace;
- const FLAC__StreamMetadata_StreamInfo& info = metadata->data.stream_info;
-
- unsigned char buffer [FLAC__STREAM_METADATA_STREAMINFO_LENGTH];
- const unsigned int channelsMinus1 = info.channels - 1;
- const unsigned int bitsMinus1 = info.bits_per_sample - 1;
-
- packUint32 (info.min_blocksize, buffer, 2);
- packUint32 (info.max_blocksize, buffer + 2, 2);
- packUint32 (info.min_framesize, buffer + 4, 3);
- packUint32 (info.max_framesize, buffer + 7, 3);
- buffer[10] = (uint8) ((info.sample_rate >> 12) & 0xff);
- buffer[11] = (uint8) ((info.sample_rate >> 4) & 0xff);
- buffer[12] = (uint8) (((info.sample_rate & 0x0f) << 4) | (channelsMinus1 << 1) | (bitsMinus1 >> 4));
- buffer[13] = (FLAC__byte) (((bitsMinus1 & 0x0f) << 4) | (unsigned int) ((info.total_samples >> 32) & 0x0f));
- packUint32 ((FLAC__uint32) info.total_samples, buffer + 14, 4);
- memcpy (buffer + 18, info.md5sum, 16);
-
- const bool ok = output->setPosition (4);
- (void) ok;
-
- // if this fails, you've given it an output stream that can't seek! It needs
- // to be able to seek back to write the header
- jassert (ok);
-
- output->writeIntBigEndian (FLAC__STREAM_METADATA_STREAMINFO_LENGTH);
- output->write (buffer, FLAC__STREAM_METADATA_STREAMINFO_LENGTH);
- }
-
- static FLAC__StreamEncoderWriteStatus encodeWriteCallback (const FLAC__StreamEncoder*,
- const FLAC__byte buffer[],
- size_t bytes,
- unsigned int /*samples*/,
- unsigned int /*current_frame*/,
- void* client_data)
- {
- using namespace FlacNamespace;
- return ((FlacWriter*) client_data)->writeData (buffer, (int) bytes)
- ? FLAC__STREAM_ENCODER_WRITE_STATUS_OK
- : FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
- }
-
- static FLAC__StreamEncoderSeekStatus encodeSeekCallback (const FLAC__StreamEncoder*, FLAC__uint64, void*)
- {
- return FLAC__STREAM_ENCODER_SEEK_STATUS_UNSUPPORTED;
- }
-
- static FLAC__StreamEncoderTellStatus encodeTellCallback (const FLAC__StreamEncoder*, FLAC__uint64*, void*)
- {
- return FLAC__STREAM_ENCODER_TELL_STATUS_UNSUPPORTED;
- }
-
- static void encodeMetadataCallback (const FLAC__StreamEncoder*,
- const FLAC__StreamMetadata* metadata,
- void* client_data)
- {
- ((FlacWriter*) client_data)->writeMetaData (metadata);
- }
-
- juce_UseDebuggingNewOperator
- };
-
- FlacAudioFormat::FlacAudioFormat()
- : AudioFormat (flacFormatName, (const tchar**) flacExtensions)
- {
- }
-
- FlacAudioFormat::~FlacAudioFormat()
- {
- }
-
- const Array <int> FlacAudioFormat::getPossibleSampleRates()
- {
- const int rates[] = { 22050, 32000, 44100, 48000, 88200, 96000, 0 };
- return Array <int> (rates);
- }
-
- const Array <int> FlacAudioFormat::getPossibleBitDepths()
- {
- const int depths[] = { 16, 24, 0 };
- return Array <int> (depths);
- }
-
- bool FlacAudioFormat::canDoStereo()
- {
- return true;
- }
-
- bool FlacAudioFormat::canDoMono()
- {
- return true;
- }
-
- bool FlacAudioFormat::isCompressed()
- {
- return true;
- }
-
- AudioFormatReader* FlacAudioFormat::createReaderFor (InputStream* in,
- const bool deleteStreamIfOpeningFails)
- {
- FlacReader* r = new FlacReader (in);
-
- if (r->sampleRate == 0)
- {
- if (! deleteStreamIfOpeningFails)
- r->input = 0;
-
- deleteAndZero (r);
- }
-
- return r;
- }
-
- AudioFormatWriter* FlacAudioFormat::createWriterFor (OutputStream* out,
- double sampleRate,
- unsigned int numberOfChannels,
- int bitsPerSample,
- const StringPairArray& /*metadataValues*/,
- int /*qualityOptionIndex*/)
- {
- if (getPossibleBitDepths().contains (bitsPerSample))
- {
- FlacWriter* w = new FlacWriter (out,
- sampleRate,
- numberOfChannels,
- bitsPerSample);
-
- if (! w->ok)
- deleteAndZero (w);
-
- return w;
- }
-
- return 0;
- }
-
- END_JUCE_NAMESPACE
-
- #endif
- /********* End of inlined file: juce_FlacAudioFormat.cpp *********/
-
- /********* Start of inlined file: juce_OggVorbisAudioFormat.cpp *********/
-
- #if JUCE_USE_OGGVORBIS
-
- #if JUCE_MAC
- #define __MACOSX__ 1
- #endif
-
- namespace OggVorbisNamespace
- {
-
- /********* Start of inlined file: vorbisenc.h *********/
- #ifndef _OV_ENC_H_
- #define _OV_ENC_H_
-
- #ifdef __cplusplus
- extern "C"
- {
- #endif /* __cplusplus */
-
- /********* Start of inlined file: codec.h *********/
- #ifndef _vorbis_codec_h_
- #define _vorbis_codec_h_
-
- #ifdef __cplusplus
- extern "C"
- {
- #endif /* __cplusplus */
-
- /********* Start of inlined file: ogg.h *********/
- #ifndef _OGG_H
- #define _OGG_H
-
- #ifdef __cplusplus
- extern "C" {
- #endif
-
- /********* Start of inlined file: os_types.h *********/
- #ifndef _OS_TYPES_H
- #define _OS_TYPES_H
-
- /* make it easy on the folks that want to compile the libs with a
- different malloc than stdlib */
- #define _ogg_malloc malloc
- #define _ogg_calloc calloc
- #define _ogg_realloc realloc
- #define _ogg_free free
-
- #if defined(_WIN32)
-
- # if defined(__CYGWIN__)
- # include <_G_config.h>
- typedef _G_int64_t ogg_int64_t;
- typedef _G_int32_t ogg_int32_t;
- typedef _G_uint32_t ogg_uint32_t;
- typedef _G_int16_t ogg_int16_t;
- typedef _G_uint16_t ogg_uint16_t;
- # elif defined(__MINGW32__)
- typedef short ogg_int16_t;
- typedef unsigned short ogg_uint16_t;
- typedef int ogg_int32_t;
- typedef unsigned int ogg_uint32_t;
- typedef long long ogg_int64_t;
- typedef unsigned long long ogg_uint64_t;
- # elif defined(__MWERKS__)
- typedef long long ogg_int64_t;
- typedef int ogg_int32_t;
- typedef unsigned int ogg_uint32_t;
- typedef short ogg_int16_t;
- typedef unsigned short ogg_uint16_t;
- # else
- /* MSVC/Borland */
- typedef __int64 ogg_int64_t;
- typedef __int32 ogg_int32_t;
- typedef unsigned __int32 ogg_uint32_t;
- typedef __int16 ogg_int16_t;
- typedef unsigned __int16 ogg_uint16_t;
- # endif
-
- #elif defined(__MACOS__)
-
- # include <sys/types.h>
- typedef SInt16 ogg_int16_t;
- typedef UInt16 ogg_uint16_t;
- typedef SInt32 ogg_int32_t;
- typedef UInt32 ogg_uint32_t;
- typedef SInt64 ogg_int64_t;
-
- #elif defined(__MACOSX__) /* MacOS X Framework build */
-
- # include <sys/types.h>
- typedef int16_t ogg_int16_t;
- typedef u_int16_t ogg_uint16_t;
- typedef int32_t ogg_int32_t;
- typedef u_int32_t ogg_uint32_t;
- typedef int64_t ogg_int64_t;
-
- #elif defined(__BEOS__)
-
- /* Be */
- # include <inttypes.h>
- typedef int16_t ogg_int16_t;
- typedef u_int16_t ogg_uint16_t;
- typedef int32_t ogg_int32_t;
- typedef u_int32_t ogg_uint32_t;
- typedef int64_t ogg_int64_t;
-
- #elif defined (__EMX__)
-
- /* OS/2 GCC */
- typedef short ogg_int16_t;
- typedef unsigned short ogg_uint16_t;
- typedef int ogg_int32_t;
- typedef unsigned int ogg_uint32_t;
- typedef long long ogg_int64_t;
-
- #elif defined (DJGPP)
-
- /* DJGPP */
- typedef short ogg_int16_t;
- typedef int ogg_int32_t;
- typedef unsigned int ogg_uint32_t;
- typedef long long ogg_int64_t;
-
- #elif defined(R5900)
-
- /* PS2 EE */
- typedef long ogg_int64_t;
- typedef int ogg_int32_t;
- typedef unsigned ogg_uint32_t;
- typedef short ogg_int16_t;
-
- #elif defined(__SYMBIAN32__)
-
- /* Symbian GCC */
- typedef signed short ogg_int16_t;
- typedef unsigned short ogg_uint16_t;
- typedef signed int ogg_int32_t;
- typedef unsigned int ogg_uint32_t;
- typedef long long int ogg_int64_t;
-
- #else
-
- # include <sys/types.h>
-
- /********* Start of inlined file: config_types.h *********/
- #ifndef __CONFIG_TYPES_H__
- #define __CONFIG_TYPES_H__
-
- typedef int16_t ogg_int16_t;
- typedef unsigned short ogg_uint16_t;
- typedef int32_t ogg_int32_t;
- typedef unsigned int ogg_uint32_t;
- typedef int64_t ogg_int64_t;
-
- #endif
- /********* End of inlined file: config_types.h *********/
-
- #endif
-
- #endif /* _OS_TYPES_H */
- /********* End of inlined file: os_types.h *********/
-
- typedef struct {
- long endbyte;
- int endbit;
-
- unsigned char *buffer;
- unsigned char *ptr;
- long storage;
- } oggpack_buffer;
-
- /* ogg_page is used to encapsulate the data in one Ogg bitstream page *****/
-
- typedef struct {
- unsigned char *header;
- long header_len;
- unsigned char *body;
- long body_len;
- } ogg_page;
-
- ogg_uint32_t bitreverse(ogg_uint32_t x){
- x= ((x>>16)&0x0000ffffUL) | ((x<<16)&0xffff0000UL);
- x= ((x>> 8)&0x00ff00ffUL) | ((x<< 8)&0xff00ff00UL);
- x= ((x>> 4)&0x0f0f0f0fUL) | ((x<< 4)&0xf0f0f0f0UL);
- x= ((x>> 2)&0x33333333UL) | ((x<< 2)&0xccccccccUL);
- return((x>> 1)&0x55555555UL) | ((x<< 1)&0xaaaaaaaaUL);
- }
-
- /* ogg_stream_state contains the current encode/decode state of a logical
- Ogg bitstream **********************************************************/
-
- typedef struct {
- unsigned char *body_data; /* bytes from packet bodies */
- long body_storage; /* storage elements allocated */
- long body_fill; /* elements stored; fill mark */
- long body_returned; /* elements of fill returned */
-
- int *lacing_vals; /* The values that will go to the segment table */
- ogg_int64_t *granule_vals; /* granulepos values for headers. Not compact
- this way, but it is simple coupled to the
- lacing fifo */
- long lacing_storage;
- long lacing_fill;
- long lacing_packet;
- long lacing_returned;
-
- unsigned char header[282]; /* working space for header encode */
- int header_fill;
-
- int e_o_s; /* set when we have buffered the last packet in the
- logical bitstream */
- int b_o_s; /* set after we've written the initial page
- of a logical bitstream */
- long serialno;
- long pageno;
- ogg_int64_t packetno; /* sequence number for decode; the framing
- knows where there's a hole in the data,
- but we need coupling so that the codec
- (which is in a seperate abstraction
- layer) also knows about the gap */
- ogg_int64_t granulepos;
-
- } ogg_stream_state;
-
- /* ogg_packet is used to encapsulate the data and metadata belonging
- to a single raw Ogg/Vorbis packet *************************************/
-
- typedef struct {
- unsigned char *packet;
- long bytes;
- long b_o_s;
- long e_o_s;
-
- ogg_int64_t granulepos;
-
- ogg_int64_t packetno; /* sequence number for decode; the framing
- knows where there's a hole in the data,
- but we need coupling so that the codec
- (which is in a seperate abstraction
- layer) also knows about the gap */
- } ogg_packet;
-
- typedef struct {
- unsigned char *data;
- int storage;
- int fill;
- int returned;
-
- int unsynced;
- int headerbytes;
- int bodybytes;
- } ogg_sync_state;
-
- /* Ogg BITSTREAM PRIMITIVES: bitstream ************************/
-
- extern void oggpack_writeinit(oggpack_buffer *b);
- extern void oggpack_writetrunc(oggpack_buffer *b,long bits);
- extern void oggpack_writealign(oggpack_buffer *b);
- extern void oggpack_writecopy(oggpack_buffer *b,void *source,long bits);
- extern void oggpack_reset(oggpack_buffer *b);
- extern void oggpack_writeclear(oggpack_buffer *b);
- extern void oggpack_readinit(oggpack_buffer *b,unsigned char *buf,int bytes);
- extern void oggpack_write(oggpack_buffer *b,unsigned long value,int bits);
- extern long oggpack_look(oggpack_buffer *b,int bits);
- extern long oggpack_look1(oggpack_buffer *b);
- extern void oggpack_adv(oggpack_buffer *b,int bits);
- extern void oggpack_adv1(oggpack_buffer *b);
- extern long oggpack_read(oggpack_buffer *b,int bits);
- extern long oggpack_read1(oggpack_buffer *b);
- extern long oggpack_bytes(oggpack_buffer *b);
- extern long oggpack_bits(oggpack_buffer *b);
- extern unsigned char *oggpack_get_buffer(oggpack_buffer *b);
-
- extern void oggpackB_writeinit(oggpack_buffer *b);
- extern void oggpackB_writetrunc(oggpack_buffer *b,long bits);
- extern void oggpackB_writealign(oggpack_buffer *b);
- extern void oggpackB_writecopy(oggpack_buffer *b,void *source,long bits);
- extern void oggpackB_reset(oggpack_buffer *b);
- extern void oggpackB_writeclear(oggpack_buffer *b);
- extern void oggpackB_readinit(oggpack_buffer *b,unsigned char *buf,int bytes);
- extern void oggpackB_write(oggpack_buffer *b,unsigned long value,int bits);
- extern long oggpackB_look(oggpack_buffer *b,int bits);
- extern long oggpackB_look1(oggpack_buffer *b);
- extern void oggpackB_adv(oggpack_buffer *b,int bits);
- extern void oggpackB_adv1(oggpack_buffer *b);
- extern long oggpackB_read(oggpack_buffer *b,int bits);
- extern long oggpackB_read1(oggpack_buffer *b);
- extern long oggpackB_bytes(oggpack_buffer *b);
- extern long oggpackB_bits(oggpack_buffer *b);
- extern unsigned char *oggpackB_get_buffer(oggpack_buffer *b);
-
- /* Ogg BITSTREAM PRIMITIVES: encoding **************************/
-
- extern int ogg_stream_packetin(ogg_stream_state *os, ogg_packet *op);
- extern int ogg_stream_pageout(ogg_stream_state *os, ogg_page *og);
- extern int ogg_stream_flush(ogg_stream_state *os, ogg_page *og);
-
- /* Ogg BITSTREAM PRIMITIVES: decoding **************************/
-
- extern int ogg_sync_init(ogg_sync_state *oy);
- extern int ogg_sync_clear(ogg_sync_state *oy);
- extern int ogg_sync_reset(ogg_sync_state *oy);
- extern int ogg_sync_destroy(ogg_sync_state *oy);
-
- extern char *ogg_sync_buffer(ogg_sync_state *oy, long size);
- extern int ogg_sync_wrote(ogg_sync_state *oy, long bytes);
- extern long ogg_sync_pageseek(ogg_sync_state *oy,ogg_page *og);
- extern int ogg_sync_pageout(ogg_sync_state *oy, ogg_page *og);
- extern int ogg_stream_pagein(ogg_stream_state *os, ogg_page *og);
- extern int ogg_stream_packetout(ogg_stream_state *os,ogg_packet *op);
- extern int ogg_stream_packetpeek(ogg_stream_state *os,ogg_packet *op);
-
- /* Ogg BITSTREAM PRIMITIVES: general ***************************/
-
- extern int ogg_stream_init(ogg_stream_state *os,int serialno);
- extern int ogg_stream_clear(ogg_stream_state *os);
- extern int ogg_stream_reset(ogg_stream_state *os);
- extern int ogg_stream_reset_serialno(ogg_stream_state *os,int serialno);
- extern int ogg_stream_destroy(ogg_stream_state *os);
- extern int ogg_stream_eos(ogg_stream_state *os);
-
- extern void ogg_page_checksum_set(ogg_page *og);
-
- extern int ogg_page_version(ogg_page *og);
- extern int ogg_page_continued(ogg_page *og);
- extern int ogg_page_bos(ogg_page *og);
- extern int ogg_page_eos(ogg_page *og);
- extern ogg_int64_t ogg_page_granulepos(ogg_page *og);
- extern int ogg_page_serialno(ogg_page *og);
- extern long ogg_page_pageno(ogg_page *og);
- extern int ogg_page_packets(ogg_page *og);
-
- extern void ogg_packet_clear(ogg_packet *op);
-
- #ifdef __cplusplus
- }
- #endif
-
- #endif /* _OGG_H */
- /********* End of inlined file: ogg.h *********/
-
- typedef struct vorbis_info{
- int version;
- int channels;
- long rate;
-
- /* The below bitrate declarations are *hints*.
- Combinations of the three values carry the following implications:
-
- all three set to the same value:
- implies a fixed rate bitstream
- only nominal set:
- implies a VBR stream that averages the nominal bitrate. No hard
- upper/lower limit
- upper and or lower set:
- implies a VBR bitstream that obeys the bitrate limits. nominal
- may also be set to give a nominal rate.
- none set:
- the coder does not care to speculate.
- */
-
- long bitrate_upper;
- long bitrate_nominal;
- long bitrate_lower;
- long bitrate_window;
-
- void *codec_setup;
- } vorbis_info;
-
- /* vorbis_dsp_state buffers the current vorbis audio
- analysis/synthesis state. The DSP state belongs to a specific
- logical bitstream ****************************************************/
- typedef struct vorbis_dsp_state{
- int analysisp;
- vorbis_info *vi;
-
- float **pcm;
- float **pcmret;
- int pcm_storage;
- int pcm_current;
- int pcm_returned;
-
- int preextrapolate;
- int eofflag;
-
- long lW;
- long W;
- long nW;
- long centerW;
-
- ogg_int64_t granulepos;
- ogg_int64_t sequence;
-
- ogg_int64_t glue_bits;
- ogg_int64_t time_bits;
- ogg_int64_t floor_bits;
- ogg_int64_t res_bits;
-
- void *backend_state;
- } vorbis_dsp_state;
-
- typedef struct vorbis_block{
- /* necessary stream state for linking to the framing abstraction */
- float **pcm; /* this is a pointer into local storage */
- oggpack_buffer opb;
-
- long lW;
- long W;
- long nW;
- int pcmend;
- int mode;
-
- int eofflag;
- ogg_int64_t granulepos;
- ogg_int64_t sequence;
- vorbis_dsp_state *vd; /* For read-only access of configuration */
-
- /* local storage to avoid remallocing; it's up to the mapping to
- structure it */
- void *localstore;
- long localtop;
- long localalloc;
- long totaluse;
- struct alloc_chain *reap;
-
- /* bitmetrics for the frame */
- long glue_bits;
- long time_bits;
- long floor_bits;
- long res_bits;
-
- void *internal;
-
- } vorbis_block;
-
- /* vorbis_block is a single block of data to be processed as part of
- the analysis/synthesis stream; it belongs to a specific logical
- bitstream, but is independant from other vorbis_blocks belonging to
- that logical bitstream. *************************************************/
-
- struct alloc_chain{
- void *ptr;
- struct alloc_chain *next;
- };
-
- /* vorbis_info contains all the setup information specific to the
- specific compression/decompression mode in progress (eg,
- psychoacoustic settings, channel setup, options, codebook
- etc). vorbis_info and substructures are in backends.h.
- *********************************************************************/
-
- /* the comments are not part of vorbis_info so that vorbis_info can be
- static storage */
- typedef struct vorbis_comment{
- /* unlimited user comment fields. libvorbis writes 'libvorbis'
- whatever vendor is set to in encode */
- char **user_comments;
- int *comment_lengths;
- int comments;
- char *vendor;
-
- } vorbis_comment;
-
- /* libvorbis encodes in two abstraction layers; first we perform DSP
- and produce a packet (see docs/analysis.txt). The packet is then
- coded into a framed OggSquish bitstream by the second layer (see
- docs/framing.txt). Decode is the reverse process; we sync/frame
- the bitstream and extract individual packets, then decode the
- packet back into PCM audio.
-
- The extra framing/packetizing is used in streaming formats, such as
- files. Over the net (such as with UDP), the framing and
- packetization aren't necessary as they're provided by the transport
- and the streaming layer is not used */
-
- /* Vorbis PRIMITIVES: general ***************************************/
-
- extern void vorbis_info_init(vorbis_info *vi);
- extern void vorbis_info_clear(vorbis_info *vi);
- extern int vorbis_info_blocksize(vorbis_info *vi,int zo);
- extern void vorbis_comment_init(vorbis_comment *vc);
- extern void vorbis_comment_add(vorbis_comment *vc, char *comment);
- extern void vorbis_comment_add_tag(vorbis_comment *vc,
- char *tag, char *contents);
- extern char *vorbis_comment_query(vorbis_comment *vc, char *tag, int count);
- extern int vorbis_comment_query_count(vorbis_comment *vc, char *tag);
- extern void vorbis_comment_clear(vorbis_comment *vc);
-
- extern int vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb);
- extern int vorbis_block_clear(vorbis_block *vb);
- extern void vorbis_dsp_clear(vorbis_dsp_state *v);
- extern double vorbis_granule_time(vorbis_dsp_state *v,
- ogg_int64_t granulepos);
-
- /* Vorbis PRIMITIVES: analysis/DSP layer ****************************/
-
- extern int vorbis_analysis_init(vorbis_dsp_state *v,vorbis_info *vi);
- extern int vorbis_commentheader_out(vorbis_comment *vc, ogg_packet *op);
- extern int vorbis_analysis_headerout(vorbis_dsp_state *v,
- vorbis_comment *vc,
- ogg_packet *op,
- ogg_packet *op_comm,
- ogg_packet *op_code);
- extern float **vorbis_analysis_buffer(vorbis_dsp_state *v,int vals);
- extern int vorbis_analysis_wrote(vorbis_dsp_state *v,int vals);
- extern int vorbis_analysis_blockout(vorbis_dsp_state *v,vorbis_block *vb);
- extern int vorbis_analysis(vorbis_block *vb,ogg_packet *op);
-
- extern int vorbis_bitrate_addblock(vorbis_block *vb);
- extern int vorbis_bitrate_flushpacket(vorbis_dsp_state *vd,
- ogg_packet *op);
-
- /* Vorbis PRIMITIVES: synthesis layer *******************************/
- extern int vorbis_synthesis_headerin(vorbis_info *vi,vorbis_comment *vc,
- ogg_packet *op);
-
- extern int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi);
- extern int vorbis_synthesis_restart(vorbis_dsp_state *v);
- extern int vorbis_synthesis(vorbis_block *vb,ogg_packet *op);
- extern int vorbis_synthesis_trackonly(vorbis_block *vb,ogg_packet *op);
- extern int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb);
- extern int vorbis_synthesis_pcmout(vorbis_dsp_state *v,float ***pcm);
- extern int vorbis_synthesis_lapout(vorbis_dsp_state *v,float ***pcm);
- extern int vorbis_synthesis_read(vorbis_dsp_state *v,int samples);
- extern long vorbis_packet_blocksize(vorbis_info *vi,ogg_packet *op);
-
- extern int vorbis_synthesis_halfrate(vorbis_info *v,int flag);
- extern int vorbis_synthesis_halfrate_p(vorbis_info *v);
-
- /* Vorbis ERRORS and return codes ***********************************/
-
- #define OV_FALSE -1
- #define OV_EOF -2
- #define OV_HOLE -3
-
- #define OV_EREAD -128
- #define OV_EFAULT -129
- #define OV_EIMPL -130
- #define OV_EINVAL -131
- #define OV_ENOTVORBIS -132
- #define OV_EBADHEADER -133
- #define OV_EVERSION -134
- #define OV_ENOTAUDIO -135
- #define OV_EBADPACKET -136
- #define OV_EBADLINK -137
- #define OV_ENOSEEK -138
-
- #ifdef __cplusplus
- }
- #endif /* __cplusplus */
-
- #endif
- /********* End of inlined file: codec.h *********/
-
- extern int vorbis_encode_init(vorbis_info *vi,
- long channels,
- long rate,
-
- long max_bitrate,
- long nominal_bitrate,
- long min_bitrate);
-
- extern int vorbis_encode_setup_managed(vorbis_info *vi,
- long channels,
- long rate,
-
- long max_bitrate,
- long nominal_bitrate,
- long min_bitrate);
-
- extern int vorbis_encode_setup_vbr(vorbis_info *vi,
- long channels,
- long rate,
-
- float quality /* quality level from 0. (lo) to 1. (hi) */
- );
-
- extern int vorbis_encode_init_vbr(vorbis_info *vi,
- long channels,
- long rate,
-
- float base_quality /* quality level from 0. (lo) to 1. (hi) */
- );
-
- extern int vorbis_encode_setup_init(vorbis_info *vi);
-
- extern int vorbis_encode_ctl(vorbis_info *vi,int number,void *arg);
-
- /* deprecated rate management supported only for compatability */
- #define OV_ECTL_RATEMANAGE_GET 0x10
- #define OV_ECTL_RATEMANAGE_SET 0x11
- #define OV_ECTL_RATEMANAGE_AVG 0x12
- #define OV_ECTL_RATEMANAGE_HARD 0x13
-
- struct ovectl_ratemanage_arg {
- int management_active;
-
- long bitrate_hard_min;
- long bitrate_hard_max;
- double bitrate_hard_window;
-
- long bitrate_av_lo;
- long bitrate_av_hi;
- double bitrate_av_window;
- double bitrate_av_window_center;
- };
-
- /* new rate setup */
- #define OV_ECTL_RATEMANAGE2_GET 0x14
- #define OV_ECTL_RATEMANAGE2_SET 0x15
-
- struct ovectl_ratemanage2_arg {
- int management_active;
-
- long bitrate_limit_min_kbps;
- long bitrate_limit_max_kbps;
- long bitrate_limit_reservoir_bits;
- double bitrate_limit_reservoir_bias;
-
- long bitrate_average_kbps;
- double bitrate_average_damping;
- };
-
- #define OV_ECTL_LOWPASS_GET 0x20
- #define OV_ECTL_LOWPASS_SET 0x21
-
- #define OV_ECTL_IBLOCK_GET 0x30
- #define OV_ECTL_IBLOCK_SET 0x31
-
- #ifdef __cplusplus
- }
- #endif /* __cplusplus */
-
- #endif
- /********* End of inlined file: vorbisenc.h *********/
-
- /********* Start of inlined file: vorbisfile.h *********/
- #ifndef _OV_FILE_H_
- #define _OV_FILE_H_
-
- #ifdef __cplusplus
- extern "C"
- {
- #endif /* __cplusplus */
-
- #include <stdio.h>
-
- /* The function prototypes for the callbacks are basically the same as for
- * the stdio functions fread, fseek, fclose, ftell.
- * The one difference is that the FILE * arguments have been replaced with
- * a void * - this is to be used as a pointer to whatever internal data these
- * functions might need. In the stdio case, it's just a FILE * cast to a void *
- *
- * If you use other functions, check the docs for these functions and return
- * the right values. For seek_func(), you *MUST* return -1 if the stream is
- * unseekable
- */
- typedef struct {
- size_t (*read_func) (void *ptr, size_t size, size_t nmemb, void *datasource);
- int (*seek_func) (void *datasource, ogg_int64_t offset, int whence);
- int (*close_func) (void *datasource);
- long (*tell_func) (void *datasource);
- } ov_callbacks;
-
- #define NOTOPEN 0
- #define PARTOPEN 1
- #define OPENED 2
- #define STREAMSET 3
- #define INITSET 4
-
- typedef struct OggVorbis_File {
- void *datasource; /* Pointer to a FILE *, etc. */
- int seekable;
- ogg_int64_t offset;
- ogg_int64_t end;
- ogg_sync_state oy;
-
- /* If the FILE handle isn't seekable (eg, a pipe), only the current
- stream appears */
- int links;
- ogg_int64_t *offsets;
- ogg_int64_t *dataoffsets;
- long *serialnos;
- ogg_int64_t *pcmlengths; /* overloaded to maintain binary
- compatability; x2 size, stores both
- beginning and end values */
- vorbis_info *vi;
- vorbis_comment *vc;
-
- /* Decoding working state local storage */
- ogg_int64_t pcm_offset;
- int ready_state;
- long current_serialno;
- int current_link;
-
- double bittrack;
- double samptrack;
-
- ogg_stream_state os; /* take physical pages, weld into a logical
- stream of packets */
- vorbis_dsp_state vd; /* central working state for the packet->PCM decoder */
- vorbis_block vb; /* local working space for packet->PCM decode */
-
- ov_callbacks callbacks;
-
- } OggVorbis_File;
-
- extern int ov_clear(OggVorbis_File *vf);
- extern int ov_open(FILE *f,OggVorbis_File *vf,char *initial,long ibytes);
- extern int ov_open_callbacks(void *datasource, OggVorbis_File *vf,
- char *initial, long ibytes, ov_callbacks callbacks);
-
- extern int ov_test(FILE *f,OggVorbis_File *vf,char *initial,long ibytes);
- extern int ov_test_callbacks(void *datasource, OggVorbis_File *vf,
- char *initial, long ibytes, ov_callbacks callbacks);
- extern int ov_test_open(OggVorbis_File *vf);
-
- extern long ov_bitrate(OggVorbis_File *vf,int i);
- extern long ov_bitrate_instant(OggVorbis_File *vf);
- extern long ov_streams(OggVorbis_File *vf);
- extern long ov_seekable(OggVorbis_File *vf);
- extern long ov_serialnumber(OggVorbis_File *vf,int i);
-
- extern ogg_int64_t ov_raw_total(OggVorbis_File *vf,int i);
- extern ogg_int64_t ov_pcm_total(OggVorbis_File *vf,int i);
- extern double ov_time_total(OggVorbis_File *vf,int i);
-
- extern int ov_raw_seek(OggVorbis_File *vf,ogg_int64_t pos);
- extern int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos);
- extern int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos);
- extern int ov_time_seek(OggVorbis_File *vf,double pos);
- extern int ov_time_seek_page(OggVorbis_File *vf,double pos);
-
- extern int ov_raw_seek_lap(OggVorbis_File *vf,ogg_int64_t pos);
- extern int ov_pcm_seek_lap(OggVorbis_File *vf,ogg_int64_t pos);
- extern int ov_pcm_seek_page_lap(OggVorbis_File *vf,ogg_int64_t pos);
- extern int ov_time_seek_lap(OggVorbis_File *vf,double pos);
- extern int ov_time_seek_page_lap(OggVorbis_File *vf,double pos);
-
- extern ogg_int64_t ov_raw_tell(OggVorbis_File *vf);
- extern ogg_int64_t ov_pcm_tell(OggVorbis_File *vf);
- extern double ov_time_tell(OggVorbis_File *vf);
-
- extern vorbis_info *ov_info(OggVorbis_File *vf,int link);
- extern vorbis_comment *ov_comment(OggVorbis_File *vf,int link);
-
- extern long ov_read_float(OggVorbis_File *vf,float ***pcm_channels,int samples,
- int *bitstream);
- extern long ov_read(OggVorbis_File *vf,char *buffer,int length,
- int bigendianp,int word,int sgned,int *bitstream);
- extern int ov_crosslap(OggVorbis_File *vf1,OggVorbis_File *vf2);
-
- extern int ov_halfrate(OggVorbis_File *vf,int flag);
- extern int ov_halfrate_p(OggVorbis_File *vf);
-
- #ifdef __cplusplus
- }
- #endif /* __cplusplus */
-
- #endif
- /********* End of inlined file: vorbisfile.h *********/
-
- /********* Start of inlined file: bitwise.c *********/
- /* We're 'LSb' endian; if we write a word but read individual bits,
- then we'll read the lsb first */
-
- /********* Start of inlined file: juce_OggVorbisHeader.h *********/
- // This file is included at the start of each Ogg-Vorbis .c file, just to do a few housekeeping
- // tasks..
-
- #ifdef _MSC_VER
- #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4305 4189 4706)
- #endif
- /********* End of inlined file: juce_OggVorbisHeader.h *********/
-
- #if JUCE_USE_OGGVORBIS
-
- #include <string.h>
- #include <stdlib.h>
-
- #define BUFFER_INCREMENT 256
-
- static const unsigned long mask[]=
- {0x00000000,0x00000001,0x00000003,0x00000007,0x0000000f,
- 0x0000001f,0x0000003f,0x0000007f,0x000000ff,0x000001ff,
- 0x000003ff,0x000007ff,0x00000fff,0x00001fff,0x00003fff,
- 0x00007fff,0x0000ffff,0x0001ffff,0x0003ffff,0x0007ffff,
- 0x000fffff,0x001fffff,0x003fffff,0x007fffff,0x00ffffff,
- 0x01ffffff,0x03ffffff,0x07ffffff,0x0fffffff,0x1fffffff,
- 0x3fffffff,0x7fffffff,0xffffffff };
-
- static const unsigned int mask8B[]=
- {0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff};
-
- void oggpack_writeinit(oggpack_buffer *b){
- memset(b,0,sizeof(*b));
- b->ptr=b->buffer=(unsigned char*) _ogg_malloc(BUFFER_INCREMENT);
- b->buffer[0]='\0';
- b->storage=BUFFER_INCREMENT;
- }
-
- void oggpackB_writeinit(oggpack_buffer *b){
- oggpack_writeinit(b);
- }
-
- void oggpack_writetrunc(oggpack_buffer *b,long bits){
- long bytes=bits>>3;
- bits-=bytes*8;
- b->ptr=b->buffer+bytes;
- b->endbit=bits;
- b->endbyte=bytes;
- *b->ptr&=mask[bits];
- }
-
- void oggpackB_writetrunc(oggpack_buffer *b,long bits){
- long bytes=bits>>3;
- bits-=bytes*8;
- b->ptr=b->buffer+bytes;
- b->endbit=bits;
- b->endbyte=bytes;
- *b->ptr&=mask8B[bits];
- }
-
- /* Takes only up to 32 bits. */
- void oggpack_write(oggpack_buffer *b,unsigned long value,int bits){
- if(b->endbyte+4>=b->storage){
- b->buffer=(unsigned char*) _ogg_realloc(b->buffer,b->storage+BUFFER_INCREMENT);
- b->storage+=BUFFER_INCREMENT;
- b->ptr=b->buffer+b->endbyte;
- }
-
- value&=mask[bits];
- bits+=b->endbit;
-
- b->ptr[0]|=value<<b->endbit;
-
- if(bits>=8){
- b->ptr[1]=(unsigned char)(value>>(8-b->endbit));
- if(bits>=16){
- b->ptr[2]=(unsigned char)(value>>(16-b->endbit));
- if(bits>=24){
- b->ptr[3]=(unsigned char)(value>>(24-b->endbit));
- if(bits>=32){
- if(b->endbit)
- b->ptr[4]=(unsigned char)(value>>(32-b->endbit));
- else
- b->ptr[4]=0;
- }
- }
- }
- }
-
- b->endbyte+=bits/8;
- b->ptr+=bits/8;
- b->endbit=bits&7;
- }
-
- /* Takes only up to 32 bits. */
- void oggpackB_write(oggpack_buffer *b,unsigned long value,int bits){
- if(b->endbyte+4>=b->storage){
- b->buffer=(unsigned char*) _ogg_realloc(b->buffer,b->storage+BUFFER_INCREMENT);
- b->storage+=BUFFER_INCREMENT;
- b->ptr=b->buffer+b->endbyte;
- }
-
- value=(value&mask[bits])<<(32-bits);
- bits+=b->endbit;
-
- b->ptr[0]|=value>>(24+b->endbit);
-
- if(bits>=8){
- b->ptr[1]=(unsigned char)(value>>(16+b->endbit));
- if(bits>=16){
- b->ptr[2]=(unsigned char)(value>>(8+b->endbit));
- if(bits>=24){
- b->ptr[3]=(unsigned char)(value>>(b->endbit));
- if(bits>=32){
- if(b->endbit)
- b->ptr[4]=(unsigned char)(value<<(8-b->endbit));
- else
- b->ptr[4]=0;
- }
- }
- }
- }
-
- b->endbyte+=bits/8;
- b->ptr+=bits/8;
- b->endbit=bits&7;
- }
-
- void oggpack_writealign(oggpack_buffer *b){
- int bits=8-b->endbit;
- if(bits<8)
- oggpack_write(b,0,bits);
- }
-
- void oggpackB_writealign(oggpack_buffer *b){
- int bits=8-b->endbit;
- if(bits<8)
- oggpackB_write(b,0,bits);
- }
-
- static void oggpack_writecopy_helper(oggpack_buffer *b,
- void *source,
- long bits,
- void (*w)(oggpack_buffer *,
- unsigned long,
- int),
- int msb){
- unsigned char *ptr=(unsigned char *)source;
-
- long bytes=bits/8;
- bits-=bytes*8;
-
- if(b->endbit){
- int i;
- /* unaligned copy. Do it the hard way. */
- for(i=0;i<bytes;i++)
- w(b,(unsigned long)(ptr[i]),8);
- }else{
- /* aligned block copy */
- if(b->endbyte+bytes+1>=b->storage){
- b->storage=b->endbyte+bytes+BUFFER_INCREMENT;
- b->buffer=(unsigned char*) _ogg_realloc(b->buffer,b->storage);
- b->ptr=b->buffer+b->endbyte;
- }
-
- memmove(b->ptr,source,bytes);
- b->ptr+=bytes;
- b->endbyte+=bytes;
- *b->ptr=0;
-
- }
- if(bits){
- if(msb)
- w(b,(unsigned long)(ptr[bytes]>>(8-bits)),bits);
- else
- w(b,(unsigned long)(ptr[bytes]),bits);
- }
- }
-
- void oggpack_writecopy(oggpack_buffer *b,void *source,long bits){
- oggpack_writecopy_helper(b,source,bits,oggpack_write,0);
- }
-
- void oggpackB_writecopy(oggpack_buffer *b,void *source,long bits){
- oggpack_writecopy_helper(b,source,bits,oggpackB_write,1);
- }
-
- void oggpack_reset(oggpack_buffer *b){
- b->ptr=b->buffer;
- b->buffer[0]=0;
- b->endbit=b->endbyte=0;
- }
-
- void oggpackB_reset(oggpack_buffer *b){
- oggpack_reset(b);
- }
-
- void oggpack_writeclear(oggpack_buffer *b){
- _ogg_free(b->buffer);
- memset(b,0,sizeof(*b));
- }
-
- void oggpackB_writeclear(oggpack_buffer *b){
- oggpack_writeclear(b);
- }
-
- void oggpack_readinit(oggpack_buffer *b,unsigned char *buf,int bytes){
- memset(b,0,sizeof(*b));
- b->buffer=b->ptr=buf;
- b->storage=bytes;
- }
-
- void oggpackB_readinit(oggpack_buffer *b,unsigned char *buf,int bytes){
- oggpack_readinit(b,buf,bytes);
- }
-
- /* Read in bits without advancing the bitptr; bits <= 32 */
- long oggpack_look(oggpack_buffer *b,int bits){
- unsigned long ret;
- unsigned long m=mask[bits];
-
- bits+=b->endbit;
-
- if(b->endbyte+4>=b->storage){
- /* not the main path */
- if(b->endbyte*8+bits>b->storage*8)return(-1);
- }
-
- ret=b->ptr[0]>>b->endbit;
- if(bits>8){
- ret|=b->ptr[1]<<(8-b->endbit);
- if(bits>16){
- ret|=b->ptr[2]<<(16-b->endbit);
- if(bits>24){
- ret|=b->ptr[3]<<(24-b->endbit);
- if(bits>32 && b->endbit)
- ret|=b->ptr[4]<<(32-b->endbit);
- }
- }
- }
- return(m&ret);
- }
-
- /* Read in bits without advancing the bitptr; bits <= 32 */
- long oggpackB_look(oggpack_buffer *b,int bits){
- unsigned long ret;
- int m=32-bits;
-
- bits+=b->endbit;
-
- if(b->endbyte+4>=b->storage){
- /* not the main path */
- if(b->endbyte*8+bits>b->storage*8)return(-1);
- }
-
- ret=b->ptr[0]<<(24+b->endbit);
- if(bits>8){
- ret|=b->ptr[1]<<(16+b->endbit);
- if(bits>16){
- ret|=b->ptr[2]<<(8+b->endbit);
- if(bits>24){
- ret|=b->ptr[3]<<(b->endbit);
- if(bits>32 && b->endbit)
- ret|=b->ptr[4]>>(8-b->endbit);
- }
- }
- }
- return ((ret&0xffffffff)>>(m>>1))>>((m+1)>>1);
- }
-
- long oggpack_look1(oggpack_buffer *b){
- if(b->endbyte>=b->storage)return(-1);
- return((b->ptr[0]>>b->endbit)&1);
- }
-
- long oggpackB_look1(oggpack_buffer *b){
- if(b->endbyte>=b->storage)return(-1);
- return((b->ptr[0]>>(7-b->endbit))&1);
- }
-
- void oggpack_adv(oggpack_buffer *b,int bits){
- bits+=b->endbit;
- b->ptr+=bits/8;
- b->endbyte+=bits/8;
- b->endbit=bits&7;
- }
-
- void oggpackB_adv(oggpack_buffer *b,int bits){
- oggpack_adv(b,bits);
- }
-
- void oggpack_adv1(oggpack_buffer *b){
- if(++(b->endbit)>7){
- b->endbit=0;
- b->ptr++;
- b->endbyte++;
- }
- }
-
- void oggpackB_adv1(oggpack_buffer *b){
- oggpack_adv1(b);
- }
-
- /* bits <= 32 */
- long oggpack_read(oggpack_buffer *b,int bits){
- long ret;
- unsigned long m=mask[bits];
-
- bits+=b->endbit;
-
- if(b->endbyte+4>=b->storage){
- /* not the main path */
- ret=-1L;
- if(b->endbyte*8+bits>b->storage*8)goto overflow;
- }
-
- ret=b->ptr[0]>>b->endbit;
- if(bits>8){
- ret|=b->ptr[1]<<(8-b->endbit);
- if(bits>16){
- ret|=b->ptr[2]<<(16-b->endbit);
- if(bits>24){
- ret|=b->ptr[3]<<(24-b->endbit);
- if(bits>32 && b->endbit){
- ret|=b->ptr[4]<<(32-b->endbit);
- }
- }
- }
- }
- ret&=m;
-
- overflow:
-
- b->ptr+=bits/8;
- b->endbyte+=bits/8;
- b->endbit=bits&7;
- return(ret);
- }
-
- /* bits <= 32 */
- long oggpackB_read(oggpack_buffer *b,int bits){
- long ret;
- long m=32-bits;
-
- bits+=b->endbit;
-
- if(b->endbyte+4>=b->storage){
- /* not the main path */
- ret=-1L;
- if(b->endbyte*8+bits>b->storage*8)goto overflow;
- }
-
- ret=b->ptr[0]<<(24+b->endbit);
- if(bits>8){
- ret|=b->ptr[1]<<(16+b->endbit);
- if(bits>16){
- ret|=b->ptr[2]<<(8+b->endbit);
- if(bits>24){
- ret|=b->ptr[3]<<(b->endbit);
- if(bits>32 && b->endbit)
- ret|=b->ptr[4]>>(8-b->endbit);
- }
- }
- }
- ret=((ret&0xffffffffUL)>>(m>>1))>>((m+1)>>1);
-
- overflow:
-
- b->ptr+=bits/8;
- b->endbyte+=bits/8;
- b->endbit=bits&7;
- return(ret);
- }
-
- long oggpack_read1(oggpack_buffer *b){
- long ret;
-
- if(b->endbyte>=b->storage){
- /* not the main path */
- ret=-1L;
- goto overflow;
- }
-
- ret=(b->ptr[0]>>b->endbit)&1;
-
- overflow:
-
- b->endbit++;
- if(b->endbit>7){
- b->endbit=0;
- b->ptr++;
- b->endbyte++;
- }
- return(ret);
- }
-
- long oggpackB_read1(oggpack_buffer *b){
- long ret;
-
- if(b->endbyte>=b->storage){
- /* not the main path */
- ret=-1L;
- goto overflow;
- }
-
- ret=(b->ptr[0]>>(7-b->endbit))&1;
-
- overflow:
-
- b->endbit++;
- if(b->endbit>7){
- b->endbit=0;
- b->ptr++;
- b->endbyte++;
- }
- return(ret);
- }
-
- long oggpack_bytes(oggpack_buffer *b){
- return(b->endbyte+(b->endbit+7)/8);
- }
-
- long oggpack_bits(oggpack_buffer *b){
- return(b->endbyte*8+b->endbit);
- }
-
- long oggpackB_bytes(oggpack_buffer *b){
- return oggpack_bytes(b);
- }
-
- long oggpackB_bits(oggpack_buffer *b){
- return oggpack_bits(b);
- }
-
- unsigned char *oggpack_get_buffer(oggpack_buffer *b){
- return(b->buffer);
- }
-
- unsigned char *oggpackB_get_buffer(oggpack_buffer *b){
- return oggpack_get_buffer(b);
- }
-
- /* Self test of the bitwise routines; everything else is based on
- them, so they damned well better be solid. */
-
- #ifdef _V_SELFTEST
- #include <stdio.h>
-
- static int ilog(unsigned int v){
- int ret=0;
- while(v){
- ret++;
- v>>=1;
- }
- return(ret);
- }
-
- oggpack_buffer o;
- oggpack_buffer r;
-
- void report(char *in){
- fprintf(stderr,"%s",in);
- exit(1);
- }
-
- void cliptest(unsigned long *b,int vals,int bits,int *comp,int compsize){
- long bytes,i;
- unsigned char *buffer;
-
- oggpack_reset(&o);
- for(i=0;i<vals;i++)
- oggpack_write(&o,b[i],bits?bits:ilog(b[i]));
- buffer=oggpack_get_buffer(&o);
- bytes=oggpack_bytes(&o);
- if(bytes!=compsize)report("wrong number of bytes!\n");
- for(i=0;i<bytes;i++)if(buffer[i]!=comp[i]){
- for(i=0;i<bytes;i++)fprintf(stderr,"%x %x\n",(int)buffer[i],(int)comp[i]);
- report("wrote incorrect value!\n");
- }
- oggpack_readinit(&r,buffer,bytes);
- for(i=0;i<vals;i++){
- int tbit=bits?bits:ilog(b[i]);
- if(oggpack_look(&r,tbit)==-1)
- report("out of data!\n");
- if(oggpack_look(&r,tbit)!=(b[i]&mask[tbit]))
- report("looked at incorrect value!\n");
- if(tbit==1)
- if(oggpack_look1(&r)!=(b[i]&mask[tbit]))
- report("looked at single bit incorrect value!\n");
- if(tbit==1){
- if(oggpack_read1(&r)!=(b[i]&mask[tbit]))
- report("read incorrect single bit value!\n");
- }else{
- if(oggpack_read(&r,tbit)!=(b[i]&mask[tbit]))
- report("read incorrect value!\n");
- }
- }
- if(oggpack_bytes(&r)!=bytes)report("leftover bytes after read!\n");
- }
-
- void cliptestB(unsigned long *b,int vals,int bits,int *comp,int compsize){
- long bytes,i;
- unsigned char *buffer;
-
- oggpackB_reset(&o);
- for(i=0;i<vals;i++)
- oggpackB_write(&o,b[i],bits?bits:ilog(b[i]));
- buffer=oggpackB_get_buffer(&o);
- bytes=oggpackB_bytes(&o);
- if(bytes!=compsize)report("wrong number of bytes!\n");
- for(i=0;i<bytes;i++)if(buffer[i]!=comp[i]){
- for(i=0;i<bytes;i++)fprintf(stderr,"%x %x\n",(int)buffer[i],(int)comp[i]);
- report("wrote incorrect value!\n");
- }
- oggpackB_readinit(&r,buffer,bytes);
- for(i=0;i<vals;i++){
- int tbit=bits?bits:ilog(b[i]);
- if(oggpackB_look(&r,tbit)==-1)
- report("out of data!\n");
- if(oggpackB_look(&r,tbit)!=(b[i]&mask[tbit]))
- report("looked at incorrect value!\n");
- if(tbit==1)
- if(oggpackB_look1(&r)!=(b[i]&mask[tbit]))
- report("looked at single bit incorrect value!\n");
- if(tbit==1){
- if(oggpackB_read1(&r)!=(b[i]&mask[tbit]))
- report("read incorrect single bit value!\n");
- }else{
- if(oggpackB_read(&r,tbit)!=(b[i]&mask[tbit]))
- report("read incorrect value!\n");
- }
- }
- if(oggpackB_bytes(&r)!=bytes)report("leftover bytes after read!\n");
- }
-
- int main(void){
- unsigned char *buffer;
- long bytes,i;
- static unsigned long testbuffer1[]=
- {18,12,103948,4325,543,76,432,52,3,65,4,56,32,42,34,21,1,23,32,546,456,7,
- 567,56,8,8,55,3,52,342,341,4,265,7,67,86,2199,21,7,1,5,1,4};
- int test1size=43;
-
- static unsigned long testbuffer2[]=
- {216531625L,1237861823,56732452,131,3212421,12325343,34547562,12313212,
- 1233432,534,5,346435231,14436467,7869299,76326614,167548585,
- 85525151,0,12321,1,349528352};
- int test2size=21;
-
- static unsigned long testbuffer3[]=
- {1,0,14,0,1,0,12,0,1,0,0,0,1,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0,1,1,1,1,1,0,0,1,
- 0,1,30,1,1,1,0,0,1,0,0,0,12,0,11,0,1,0,0,1};
- int test3size=56;
-
- static unsigned long large[]=
- {2136531625L,2137861823,56732452,131,3212421,12325343,34547562,12313212,
- 1233432,534,5,2146435231,14436467,7869299,76326614,167548585,
- 85525151,0,12321,1,2146528352};
-
- int onesize=33;
- static int one[33]={146,25,44,151,195,15,153,176,233,131,196,65,85,172,47,40,
- 34,242,223,136,35,222,211,86,171,50,225,135,214,75,172,
- 223,4};
- static int oneB[33]={150,101,131,33,203,15,204,216,105,193,156,65,84,85,222,
- 8,139,145,227,126,34,55,244,171,85,100,39,195,173,18,
- 245,251,128};
-
- int twosize=6;
- static int two[6]={61,255,255,251,231,29};
- static int twoB[6]={247,63,255,253,249,120};
-
- int threesize=54;
- static int three[54]={169,2,232,252,91,132,156,36,89,13,123,176,144,32,254,
- 142,224,85,59,121,144,79,124,23,67,90,90,216,79,23,83,
- 58,135,196,61,55,129,183,54,101,100,170,37,127,126,10,
- 100,52,4,14,18,86,77,1};
- static int threeB[54]={206,128,42,153,57,8,183,251,13,89,36,30,32,144,183,
- 130,59,240,121,59,85,223,19,228,180,134,33,107,74,98,
- 233,253,196,135,63,2,110,114,50,155,90,127,37,170,104,
- 200,20,254,4,58,106,176,144,0};
-
- int foursize=38;
- static int four[38]={18,6,163,252,97,194,104,131,32,1,7,82,137,42,129,11,72,
- 132,60,220,112,8,196,109,64,179,86,9,137,195,208,122,169,
- 28,2,133,0,1};
- static int fourB[38]={36,48,102,83,243,24,52,7,4,35,132,10,145,21,2,93,2,41,
- 1,219,184,16,33,184,54,149,170,132,18,30,29,98,229,67,
- 129,10,4,32};
-
- int fivesize=45;
- static int five[45]={169,2,126,139,144,172,30,4,80,72,240,59,130,218,73,62,
- 241,24,210,44,4,20,0,248,116,49,135,100,110,130,181,169,
- 84,75,159,2,1,0,132,192,8,0,0,18,22};
- static int fiveB[45]={1,84,145,111,245,100,128,8,56,36,40,71,126,78,213,226,
- 124,105,12,0,133,128,0,162,233,242,67,152,77,205,77,
- 172,150,169,129,79,128,0,6,4,32,0,27,9,0};
-
- int sixsize=7;
- static int six[7]={17,177,170,242,169,19,148};
- static int sixB[7]={136,141,85,79,149,200,41};
-
- /* Test read/write together */
- /* Later we test against pregenerated bitstreams */
- oggpack_writeinit(&o);
-
- fprintf(stderr,"\nSmall preclipped packing (LSb): ");
- cliptest(testbuffer1,test1size,0,one,onesize);
- fprintf(stderr,"ok.");
-
- fprintf(stderr,"\nNull bit call (LSb): ");
- cliptest(testbuffer3,test3size,0,two,twosize);
- fprintf(stderr,"ok.");
-
- fprintf(stderr,"\nLarge preclipped packing (LSb): ");
- cliptest(testbuffer2,test2size,0,three,threesize);
- fprintf(stderr,"ok.");
-
- fprintf(stderr,"\n32 bit preclipped packing (LSb): ");
- oggpack_reset(&o);
- for(i=0;i<test2size;i++)
- oggpack_write(&o,large[i],32);
- buffer=oggpack_get_buffer(&o);
- bytes=oggpack_bytes(&o);
- oggpack_readinit(&r,buffer,bytes);
- for(i=0;i<test2size;i++){
- if(oggpack_look(&r,32)==-1)report("out of data. failed!");
- if(oggpack_look(&r,32)!=large[i]){
- fprintf(stderr,"%ld != %ld (%lx!=%lx):",oggpack_look(&r,32),large[i],
- oggpack_look(&r,32),large[i]);
- report("read incorrect value!\n");
- }
- oggpack_adv(&r,32);
- }
- if(oggpack_bytes(&r)!=bytes)report("leftover bytes after read!\n");
- fprintf(stderr,"ok.");
-
- fprintf(stderr,"\nSmall unclipped packing (LSb): ");
- cliptest(testbuffer1,test1size,7,four,foursize);
- fprintf(stderr,"ok.");
-
- fprintf(stderr,"\nLarge unclipped packing (LSb): ");
- cliptest(testbuffer2,test2size,17,five,fivesize);
- fprintf(stderr,"ok.");
-
- fprintf(stderr,"\nSingle bit unclipped packing (LSb): ");
- cliptest(testbuffer3,test3size,1,six,sixsize);
- fprintf(stderr,"ok.");
-
- fprintf(stderr,"\nTesting read past end (LSb): ");
- oggpack_readinit(&r,"\0\0\0\0\0\0\0\0",8);
- for(i=0;i<64;i++){
- if(oggpack_read(&r,1)!=0){
- fprintf(stderr,"failed; got -1 prematurely.\n");
- exit(1);
- }
- }
- if(oggpack_look(&r,1)!=-1 ||
- oggpack_read(&r,1)!=-1){
- fprintf(stderr,"failed; read past end without -1.\n");
- exit(1);
- }
- oggpack_readinit(&r,"\0\0\0\0\0\0\0\0",8);
- if(oggpack_read(&r,30)!=0 || oggpack_read(&r,16)!=0){
- fprintf(stderr,"failed 2; got -1 prematurely.\n");
- exit(1);
- }
-
- if(oggpack_look(&r,18)!=0 ||
- oggpack_look(&r,18)!=0){
- fprintf(stderr,"failed 3; got -1 prematurely.\n");
- exit(1);
- }
- if(oggpack_look(&r,19)!=-1 ||
- oggpack_look(&r,19)!=-1){
- fprintf(stderr,"failed; read past end without -1.\n");
- exit(1);
- }
- if(oggpack_look(&r,32)!=-1 ||
- oggpack_look(&r,32)!=-1){
- fprintf(stderr,"failed; read past end without -1.\n");
- exit(1);
- }
- oggpack_writeclear(&o);
- fprintf(stderr,"ok.\n");
-
- /********** lazy, cut-n-paste retest with MSb packing ***********/
-
- /* Test read/write together */
- /* Later we test against pregenerated bitstreams */
- oggpackB_writeinit(&o);
-
- fprintf(stderr,"\nSmall preclipped packing (MSb): ");
- cliptestB(testbuffer1,test1size,0,oneB,onesize);
- fprintf(stderr,"ok.");
-
- fprintf(stderr,"\nNull bit call (MSb): ");
- cliptestB(testbuffer3,test3size,0,twoB,twosize);
- fprintf(stderr,"ok.");
-
- fprintf(stderr,"\nLarge preclipped packing (MSb): ");
- cliptestB(testbuffer2,test2size,0,threeB,threesize);
- fprintf(stderr,"ok.");
-
- fprintf(stderr,"\n32 bit preclipped packing (MSb): ");
- oggpackB_reset(&o);
- for(i=0;i<test2size;i++)
- oggpackB_write(&o,large[i],32);
- buffer=oggpackB_get_buffer(&o);
- bytes=oggpackB_bytes(&o);
- oggpackB_readinit(&r,buffer,bytes);
- for(i=0;i<test2size;i++){
- if(oggpackB_look(&r,32)==-1)report("out of data. failed!");
- if(oggpackB_look(&r,32)!=large[i]){
- fprintf(stderr,"%ld != %ld (%lx!=%lx):",oggpackB_look(&r,32),large[i],
- oggpackB_look(&r,32),large[i]);
- report("read incorrect value!\n");
- }
- oggpackB_adv(&r,32);
- }
- if(oggpackB_bytes(&r)!=bytes)report("leftover bytes after read!\n");
- fprintf(stderr,"ok.");
-
- fprintf(stderr,"\nSmall unclipped packing (MSb): ");
- cliptestB(testbuffer1,test1size,7,fourB,foursize);
- fprintf(stderr,"ok.");
-
- fprintf(stderr,"\nLarge unclipped packing (MSb): ");
- cliptestB(testbuffer2,test2size,17,fiveB,fivesize);
- fprintf(stderr,"ok.");
-
- fprintf(stderr,"\nSingle bit unclipped packing (MSb): ");
- cliptestB(testbuffer3,test3size,1,sixB,sixsize);
- fprintf(stderr,"ok.");
-
- fprintf(stderr,"\nTesting read past end (MSb): ");
- oggpackB_readinit(&r,"\0\0\0\0\0\0\0\0",8);
- for(i=0;i<64;i++){
- if(oggpackB_read(&r,1)!=0){
- fprintf(stderr,"failed; got -1 prematurely.\n");
- exit(1);
- }
- }
- if(oggpackB_look(&r,1)!=-1 ||
- oggpackB_read(&r,1)!=-1){
- fprintf(stderr,"failed; read past end without -1.\n");
- exit(1);
- }
- oggpackB_readinit(&r,"\0\0\0\0\0\0\0\0",8);
- if(oggpackB_read(&r,30)!=0 || oggpackB_read(&r,16)!=0){
- fprintf(stderr,"failed 2; got -1 prematurely.\n");
- exit(1);
- }
-
- if(oggpackB_look(&r,18)!=0 ||
- oggpackB_look(&r,18)!=0){
- fprintf(stderr,"failed 3; got -1 prematurely.\n");
- exit(1);
- }
- if(oggpackB_look(&r,19)!=-1 ||
- oggpackB_look(&r,19)!=-1){
- fprintf(stderr,"failed; read past end without -1.\n");
- exit(1);
- }
- if(oggpackB_look(&r,32)!=-1 ||
- oggpackB_look(&r,32)!=-1){
- fprintf(stderr,"failed; read past end without -1.\n");
- exit(1);
- }
- oggpackB_writeclear(&o);
- fprintf(stderr,"ok.\n\n");
-
- return(0);
- }
- #endif /* _V_SELFTEST */
-
- #undef BUFFER_INCREMENT
-
- #endif
- /********* End of inlined file: bitwise.c *********/
-
- /********* Start of inlined file: framing.c *********/
-
- /********* Start of inlined file: juce_OggVorbisHeader.h *********/
- // This file is included at the start of each Ogg-Vorbis .c file, just to do a few housekeeping
- // tasks..
-
- #ifdef _MSC_VER
- #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4305 4189 4706)
- #endif
- /********* End of inlined file: juce_OggVorbisHeader.h *********/
-
- #if JUCE_USE_OGGVORBIS
-
- #include <stdlib.h>
- #include <string.h>
-
- /* A complete description of Ogg framing exists in docs/framing.html */
-
- int ogg_page_version(ogg_page *og){
- return((int)(og->header[4]));
- }
-
- int ogg_page_continued(ogg_page *og){
- return((int)(og->header[5]&0x01));
- }
-
- int ogg_page_bos(ogg_page *og){
- return((int)(og->header[5]&0x02));
- }
-
- int ogg_page_eos(ogg_page *og){
- return((int)(og->header[5]&0x04));
- }
-
- ogg_int64_t ogg_page_granulepos(ogg_page *og){
- unsigned char *page=og->header;
- ogg_int64_t granulepos=page[13]&(0xff);
- granulepos= (granulepos<<8)|(page[12]&0xff);
- granulepos= (granulepos<<8)|(page[11]&0xff);
- granulepos= (granulepos<<8)|(page[10]&0xff);
- granulepos= (granulepos<<8)|(page[9]&0xff);
- granulepos= (granulepos<<8)|(page[8]&0xff);
- granulepos= (granulepos<<8)|(page[7]&0xff);
- granulepos= (granulepos<<8)|(page[6]&0xff);
- return(granulepos);
- }
-
- int ogg_page_serialno(ogg_page *og){
- return(og->header[14] |
- (og->header[15]<<8) |
- (og->header[16]<<16) |
- (og->header[17]<<24));
- }
-
- long ogg_page_pageno(ogg_page *og){
- return(og->header[18] |
- (og->header[19]<<8) |
- (og->header[20]<<16) |
- (og->header[21]<<24));
- }
-
- /* returns the number of packets that are completed on this page (if
- the leading packet is begun on a previous page, but ends on this
- page, it's counted */
-
- /* NOTE:
- If a page consists of a packet begun on a previous page, and a new
- packet begun (but not completed) on this page, the return will be:
- ogg_page_packets(page) ==1,
- ogg_page_continued(page) !=0
-
- If a page happens to be a single packet that was begun on a
- previous page, and spans to the next page (in the case of a three or
- more page packet), the return will be:
- ogg_page_packets(page) ==0,
- ogg_page_continued(page) !=0
- */
-
- int ogg_page_packets(ogg_page *og){
- int i,n=og->header[26],count=0;
- for(i=0;i<n;i++)
- if(og->header[27+i]<255)count++;
- return(count);
- }
-
- #if 0
- /* helper to initialize lookup for direct-table CRC (illustrative; we
- use the static init below) */
-
- static ogg_uint32_t _ogg_crc_entry(unsigned long index){
- int i;
- unsigned long r;
-
- r = index << 24;
- for (i=0; i<8; i++)
- if (r & 0x80000000UL)
- r = (r << 1) ^ 0x04c11db7; /* The same as the ethernet generator
- polynomial, although we use an
- unreflected alg and an init/final
- of 0, not 0xffffffff */
- else
- r<<=1;
- return (r & 0xffffffffUL);
- }
- #endif
-
- static const ogg_uint32_t crc_lookup[256]={
- 0x00000000,0x04c11db7,0x09823b6e,0x0d4326d9,
- 0x130476dc,0x17c56b6b,0x1a864db2,0x1e475005,
- 0x2608edb8,0x22c9f00f,0x2f8ad6d6,0x2b4bcb61,
- 0x350c9b64,0x31cd86d3,0x3c8ea00a,0x384fbdbd,
- 0x4c11db70,0x48d0c6c7,0x4593e01e,0x4152fda9,
- 0x5f15adac,0x5bd4b01b,0x569796c2,0x52568b75,
- 0x6a1936c8,0x6ed82b7f,0x639b0da6,0x675a1011,
- 0x791d4014,0x7ddc5da3,0x709f7b7a,0x745e66cd,
- 0x9823b6e0,0x9ce2ab57,0x91a18d8e,0x95609039,
- 0x8b27c03c,0x8fe6dd8b,0x82a5fb52,0x8664e6e5,
- 0xbe2b5b58,0xbaea46ef,0xb7a96036,0xb3687d81,
- 0xad2f2d84,0xa9ee3033,0xa4ad16ea,0xa06c0b5d,
- 0xd4326d90,0xd0f37027,0xddb056fe,0xd9714b49,
- 0xc7361b4c,0xc3f706fb,0xceb42022,0xca753d95,
- 0xf23a8028,0xf6fb9d9f,0xfbb8bb46,0xff79a6f1,
- 0xe13ef6f4,0xe5ffeb43,0xe8bccd9a,0xec7dd02d,
- 0x34867077,0x30476dc0,0x3d044b19,0x39c556ae,
- 0x278206ab,0x23431b1c,0x2e003dc5,0x2ac12072,
- 0x128e9dcf,0x164f8078,0x1b0ca6a1,0x1fcdbb16,
- 0x018aeb13,0x054bf6a4,0x0808d07d,0x0cc9cdca,
- 0x7897ab07,0x7c56b6b0,0x71159069,0x75d48dde,
- 0x6b93dddb,0x6f52c06c,0x6211e6b5,0x66d0fb02,
- 0x5e9f46bf,0x5a5e5b08,0x571d7dd1,0x53dc6066,
- 0x4d9b3063,0x495a2dd4,0x44190b0d,0x40d816ba,
- 0xaca5c697,0xa864db20,0xa527fdf9,0xa1e6e04e,
- 0xbfa1b04b,0xbb60adfc,0xb6238b25,0xb2e29692,
- 0x8aad2b2f,0x8e6c3698,0x832f1041,0x87ee0df6,
- 0x99a95df3,0x9d684044,0x902b669d,0x94ea7b2a,
- 0xe0b41de7,0xe4750050,0xe9362689,0xedf73b3e,
- 0xf3b06b3b,0xf771768c,0xfa325055,0xfef34de2,
- 0xc6bcf05f,0xc27dede8,0xcf3ecb31,0xcbffd686,
- 0xd5b88683,0xd1799b34,0xdc3abded,0xd8fba05a,
- 0x690ce0ee,0x6dcdfd59,0x608edb80,0x644fc637,
- 0x7a089632,0x7ec98b85,0x738aad5c,0x774bb0eb,
- 0x4f040d56,0x4bc510e1,0x46863638,0x42472b8f,
- 0x5c007b8a,0x58c1663d,0x558240e4,0x51435d53,
- 0x251d3b9e,0x21dc2629,0x2c9f00f0,0x285e1d47,
- 0x36194d42,0x32d850f5,0x3f9b762c,0x3b5a6b9b,
- 0x0315d626,0x07d4cb91,0x0a97ed48,0x0e56f0ff,
- 0x1011a0fa,0x14d0bd4d,0x19939b94,0x1d528623,
- 0xf12f560e,0xf5ee4bb9,0xf8ad6d60,0xfc6c70d7,
- 0xe22b20d2,0xe6ea3d65,0xeba91bbc,0xef68060b,
- 0xd727bbb6,0xd3e6a601,0xdea580d8,0xda649d6f,
- 0xc423cd6a,0xc0e2d0dd,0xcda1f604,0xc960ebb3,
- 0xbd3e8d7e,0xb9ff90c9,0xb4bcb610,0xb07daba7,
- 0xae3afba2,0xaafbe615,0xa7b8c0cc,0xa379dd7b,
- 0x9b3660c6,0x9ff77d71,0x92b45ba8,0x9675461f,
- 0x8832161a,0x8cf30bad,0x81b02d74,0x857130c3,
- 0x5d8a9099,0x594b8d2e,0x5408abf7,0x50c9b640,
- 0x4e8ee645,0x4a4ffbf2,0x470cdd2b,0x43cdc09c,
- 0x7b827d21,0x7f436096,0x7200464f,0x76c15bf8,
- 0x68860bfd,0x6c47164a,0x61043093,0x65c52d24,
- 0x119b4be9,0x155a565e,0x18197087,0x1cd86d30,
- 0x029f3d35,0x065e2082,0x0b1d065b,0x0fdc1bec,
- 0x3793a651,0x3352bbe6,0x3e119d3f,0x3ad08088,
- 0x2497d08d,0x2056cd3a,0x2d15ebe3,0x29d4f654,
- 0xc5a92679,0xc1683bce,0xcc2b1d17,0xc8ea00a0,
- 0xd6ad50a5,0xd26c4d12,0xdf2f6bcb,0xdbee767c,
- 0xe3a1cbc1,0xe760d676,0xea23f0af,0xeee2ed18,
- 0xf0a5bd1d,0xf464a0aa,0xf9278673,0xfde69bc4,
- 0x89b8fd09,0x8d79e0be,0x803ac667,0x84fbdbd0,
- 0x9abc8bd5,0x9e7d9662,0x933eb0bb,0x97ffad0c,
- 0xafb010b1,0xab710d06,0xa6322bdf,0xa2f33668,
- 0xbcb4666d,0xb8757bda,0xb5365d03,0xb1f740b4};
-
- /* init the encode/decode logical stream state */
-
- int ogg_stream_init(ogg_stream_state *os,int serialno){
- if(os){
- memset(os,0,sizeof(*os));
- os->body_storage=16*1024;
- os->body_data=(unsigned char*) _ogg_malloc(os->body_storage*sizeof(*os->body_data));
-
- os->lacing_storage=1024;
- os->lacing_vals=(int*) _ogg_malloc(os->lacing_storage*sizeof(*os->lacing_vals));
- os->granule_vals=(ogg_int64_t*) _ogg_malloc(os->lacing_storage*sizeof(*os->granule_vals));
-
- os->serialno=serialno;
-
- return(0);
- }
- return(-1);
- }
-
- /* _clear does not free os, only the non-flat storage within */
- int ogg_stream_clear(ogg_stream_state *os){
- if(os){
- if(os->body_data)_ogg_free(os->body_data);
- if(os->lacing_vals)_ogg_free(os->lacing_vals);
- if(os->granule_vals)_ogg_free(os->granule_vals);
-
- memset(os,0,sizeof(*os));
- }
- return(0);
- }
-
- int ogg_stream_destroy(ogg_stream_state *os){
- if(os){
- ogg_stream_clear(os);
- _ogg_free(os);
- }
- return(0);
- }
-
- /* Helpers for ogg_stream_encode; this keeps the structure and
- what's happening fairly clear */
-
- static void _os_body_expand(ogg_stream_state *os,int needed){
- if(os->body_storage<=os->body_fill+needed){
- os->body_storage+=(needed+1024);
- os->body_data=(unsigned char*) _ogg_realloc(os->body_data,os->body_storage*sizeof(*os->body_data));
- }
- }
-
- static void _os_lacing_expand(ogg_stream_state *os,int needed){
- if(os->lacing_storage<=os->lacing_fill+needed){
- os->lacing_storage+=(needed+32);
- os->lacing_vals=(int*)_ogg_realloc(os->lacing_vals,os->lacing_storage*sizeof(*os->lacing_vals));
- os->granule_vals=(ogg_int64_t*)_ogg_realloc(os->granule_vals,os->lacing_storage*sizeof(*os->granule_vals));
- }
- }
-
- /* checksum the page */
- /* Direct table CRC; note that this will be faster in the future if we
- perform the checksum silmultaneously with other copies */
-
- void ogg_page_checksum_set(ogg_page *og){
- if(og){
- ogg_uint32_t crc_reg=0;
- int i;
-
- /* safety; needed for API behavior, but not framing code */
- og->header[22]=0;
- og->header[23]=0;
- og->header[24]=0;
- og->header[25]=0;
-
- for(i=0;i<og->header_len;i++)
- crc_reg=(crc_reg<<8)^crc_lookup[((crc_reg >> 24)&0xff)^og->header[i]];
- for(i=0;i<og->body_len;i++)
- crc_reg=(crc_reg<<8)^crc_lookup[((crc_reg >> 24)&0xff)^og->body[i]];
-
- og->header[22]=(unsigned char)(crc_reg&0xff);
- og->header[23]=(unsigned char)((crc_reg>>8)&0xff);
- og->header[24]=(unsigned char)((crc_reg>>16)&0xff);
- og->header[25]=(unsigned char)((crc_reg>>24)&0xff);
- }
- }
-
- /* submit data to the internal buffer of the framing engine */
- int ogg_stream_packetin(ogg_stream_state *os,ogg_packet *op){
- int lacing_vals=op->bytes/255+1,i;
-
- if(os->body_returned){
- /* advance packet data according to the body_returned pointer. We
- had to keep it around to return a pointer into the buffer last
- call */
-
- os->body_fill-=os->body_returned;
- if(os->body_fill)
- memmove(os->body_data,os->body_data+os->body_returned,
- os->body_fill);
- os->body_returned=0;
- }
-
- /* make sure we have the buffer storage */
- _os_body_expand(os,op->bytes);
- _os_lacing_expand(os,lacing_vals);
-
- /* Copy in the submitted packet. Yes, the copy is a waste; this is
- the liability of overly clean abstraction for the time being. It
- will actually be fairly easy to eliminate the extra copy in the
- future */
-
- memcpy(os->body_data+os->body_fill,op->packet,op->bytes);
- os->body_fill+=op->bytes;
-
- /* Store lacing vals for this packet */
- for(i=0;i<lacing_vals-1;i++){
- os->lacing_vals[os->lacing_fill+i]=255;
- os->granule_vals[os->lacing_fill+i]=os->granulepos;
- }
- os->lacing_vals[os->lacing_fill+i]=(op->bytes)%255;
- os->granulepos=os->granule_vals[os->lacing_fill+i]=op->granulepos;
-
- /* flag the first segment as the beginning of the packet */
- os->lacing_vals[os->lacing_fill]|= 0x100;
-
- os->lacing_fill+=lacing_vals;
-
- /* for the sake of completeness */
- os->packetno++;
-
- if(op->e_o_s)os->e_o_s=1;
-
- return(0);
- }
-
- /* This will flush remaining packets into a page (returning nonzero),
- even if there is not enough data to trigger a flush normally
- (undersized page). If there are no packets or partial packets to
- flush, ogg_stream_flush returns 0. Note that ogg_stream_flush will
- try to flush a normal sized page like ogg_stream_pageout; a call to
- ogg_stream_flush does not guarantee that all packets have flushed.
- Only a return value of 0 from ogg_stream_flush indicates all packet
- data is flushed into pages.
-
- since ogg_stream_flush will flush the last page in a stream even if
- it's undersized, you almost certainly want to use ogg_stream_pageout
- (and *not* ogg_stream_flush) unless you specifically need to flush
- an page regardless of size in the middle of a stream. */
-
- int ogg_stream_flush(ogg_stream_state *os,ogg_page *og){
- int i;
- int vals=0;
- int maxvals=(os->lacing_fill>255?255:os->lacing_fill);
- int bytes=0;
- long acc=0;
- ogg_int64_t granule_pos=-1;
-
- if(maxvals==0)return(0);
-
- /* construct a page */
- /* decide how many segments to include */
-
- /* If this is the initial header case, the first page must only include
- the initial header packet */
- if(os->b_o_s==0){ /* 'initial header page' case */
- granule_pos=0;
- for(vals=0;vals<maxvals;vals++){
- if((os->lacing_vals[vals]&0x0ff)<255){
- vals++;
- break;
- }
- }
- }else{
- for(vals=0;vals<maxvals;vals++){
- if(acc>4096)break;
- acc+=os->lacing_vals[vals]&0x0ff;
- if((os->lacing_vals[vals]&0xff)<255)
- granule_pos=os->granule_vals[vals];
- }
- }
-
- /* construct the header in temp storage */
- memcpy(os->header,"OggS",4);
-
- /* stream structure version */
- os->header[4]=0x00;
-
- /* continued packet flag? */
- os->header[5]=0x00;
- if((os->lacing_vals[0]&0x100)==0)os->header[5]|=0x01;
- /* first page flag? */
- if(os->b_o_s==0)os->header[5]|=0x02;
- /* last page flag? */
- if(os->e_o_s && os->lacing_fill==vals)os->header[5]|=0x04;
- os->b_o_s=1;
-
- /* 64 bits of PCM position */
- for(i=6;i<14;i++){
- os->header[i]=(unsigned char)(granule_pos&0xff);
- granule_pos>>=8;
- }
-
- /* 32 bits of stream serial number */
- {
- long serialno=os->serialno;
- for(i=14;i<18;i++){
- os->header[i]=(unsigned char)(serialno&0xff);
- serialno>>=8;
- }
- }
-
- /* 32 bits of page counter (we have both counter and page header
- because this val can roll over) */
- if(os->pageno==-1)os->pageno=0; /* because someone called
- stream_reset; this would be a
- strange thing to do in an
- encode stream, but it has
- plausible uses */
- {
- long pageno=os->pageno++;
- for(i=18;i<22;i++){
- os->header[i]=(unsigned char)(pageno&0xff);
- pageno>>=8;
- }
- }
-
- /* zero for computation; filled in later */
- os->header[22]=0;
- os->header[23]=0;
- os->header[24]=0;
- os->header[25]=0;
-
- /* segment table */
- os->header[26]=(unsigned char)(vals&0xff);
- for(i=0;i<vals;i++)
- bytes+=os->header[i+27]=(unsigned char)(os->lacing_vals[i]&0xff);
-
- /* set pointers in the ogg_page struct */
- og->header=os->header;
- og->header_len=os->header_fill=vals+27;
- og->body=os->body_data+os->body_returned;
- og->body_len=bytes;
-
- /* advance the lacing data and set the body_returned pointer */
-
- os->lacing_fill-=vals;
- memmove(os->lacing_vals,os->lacing_vals+vals,os->lacing_fill*sizeof(*os->lacing_vals));
- memmove(os->granule_vals,os->granule_vals+vals,os->lacing_fill*sizeof(*os->granule_vals));
- os->body_returned+=bytes;
-
- /* calculate the checksum */
-
- ogg_page_checksum_set(og);
-
- /* done */
- return(1);
- }
-
- /* This constructs pages from buffered packet segments. The pointers
- returned are to static buffers; do not free. The returned buffers are
- good only until the next call (using the same ogg_stream_state) */
-
- int ogg_stream_pageout(ogg_stream_state *os, ogg_page *og){
-
- if((os->e_o_s&&os->lacing_fill) || /* 'were done, now flush' case */
- os->body_fill-os->body_returned > 4096 ||/* 'page nominal size' case */
- os->lacing_fill>=255 || /* 'segment table full' case */
- (os->lacing_fill&&!os->b_o_s)){ /* 'initial header page' case */
-
- return(ogg_stream_flush(os,og));
- }
-
- /* not enough data to construct a page and not end of stream */
- return(0);
- }
-
- int ogg_stream_eos(ogg_stream_state *os){
- return os->e_o_s;
- }
-
- /* DECODING PRIMITIVES: packet streaming layer **********************/
-
- /* This has two layers to place more of the multi-serialno and paging
- control in the application's hands. First, we expose a data buffer
- using ogg_sync_buffer(). The app either copies into the
- buffer, or passes it directly to read(), etc. We then call
- ogg_sync_wrote() to tell how many bytes we just added.
-
- Pages are returned (pointers into the buffer in ogg_sync_state)
- by ogg_sync_pageout(). The page is then submitted to
- ogg_stream_pagein() along with the appropriate
- ogg_stream_state* (ie, matching serialno). We then get raw
- packets out calling ogg_stream_packetout() with a
- ogg_stream_state. */
-
- /* initialize the struct to a known state */
- int ogg_sync_init(ogg_sync_state *oy){
- if(oy){
- memset(oy,0,sizeof(*oy));
- }
- return(0);
- }
-
- /* clear non-flat storage within */
- int ogg_sync_clear(ogg_sync_state *oy){
- if(oy){
- if(oy->data)_ogg_free(oy->data);
- ogg_sync_init(oy);
- }
- return(0);
- }
-
- int ogg_sync_destroy(ogg_sync_state *oy){
- if(oy){
- ogg_sync_clear(oy);
- _ogg_free(oy);
- }
- return(0);
- }
-
- char *ogg_sync_buffer(ogg_sync_state *oy, long size){
-
- /* first, clear out any space that has been previously returned */
- if(oy->returned){
- oy->fill-=oy->returned;
- if(oy->fill>0)
- memmove(oy->data,oy->data+oy->returned,oy->fill);
- oy->returned=0;
- }
-
- if(size>oy->storage-oy->fill){
- /* We need to extend the internal buffer */
- long newsize=size+oy->fill+4096; /* an extra page to be nice */
-
- if(oy->data)
- oy->data=(unsigned char*) _ogg_realloc(oy->data,newsize);
- else
- oy->data=(unsigned char*) _ogg_malloc(newsize);
- oy->storage=newsize;
- }
-
- /* expose a segment at least as large as requested at the fill mark */
- return((char *)oy->data+oy->fill);
- }
-
- int ogg_sync_wrote(ogg_sync_state *oy, long bytes){
- if(oy->fill+bytes>oy->storage)return(-1);
- oy->fill+=bytes;
- return(0);
- }
-
- /* sync the stream. This is meant to be useful for finding page
- boundaries.
-
- return values for this:
- -n) skipped n bytes
- 0) page not ready; more data (no bytes skipped)
- n) page synced at current location; page length n bytes
-
- */
-
- long ogg_sync_pageseek(ogg_sync_state *oy,ogg_page *og){
- unsigned char *page=oy->data+oy->returned;
- unsigned char *next;
- long bytes=oy->fill-oy->returned;
-
- if(oy->headerbytes==0){
- int headerbytes,i;
- if(bytes<27)return(0); /* not enough for a header */
-
- /* verify capture pattern */
- if(memcmp(page,"OggS",4))goto sync_fail;
-
- headerbytes=page[26]+27;
- if(bytes<headerbytes)return(0); /* not enough for header + seg table */
-
- /* count up body length in the segment table */
-
- for(i=0;i<page[26];i++)
- oy->bodybytes+=page[27+i];
- oy->headerbytes=headerbytes;
- }
-
- if(oy->bodybytes+oy->headerbytes>bytes)return(0);
-
- /* The whole test page is buffered. Verify the checksum */
- {
- /* Grab the checksum bytes, set the header field to zero */
- char chksum[4];
- ogg_page log;
-
- memcpy(chksum,page+22,4);
- memset(page+22,0,4);
-
- /* set up a temp page struct and recompute the checksum */
- log.header=page;
- log.header_len=oy->headerbytes;
- log.body=page+oy->headerbytes;
- log.body_len=oy->bodybytes;
- ogg_page_checksum_set(&log);
-
- /* Compare */
- if(memcmp(chksum,page+22,4)){
- /* D'oh. Mismatch! Corrupt page (or miscapture and not a page
- at all) */
- /* replace the computed checksum with the one actually read in */
- memcpy(page+22,chksum,4);
-
- /* Bad checksum. Lose sync */
- goto sync_fail;
- }
- }
-
- /* yes, have a whole page all ready to go */
- {
- unsigned char *page=oy->data+oy->returned;
- long bytes;
-
- if(og){
- og->header=page;
- og->header_len=oy->headerbytes;
- og->body=page+oy->headerbytes;
- og->body_len=oy->bodybytes;
- }
-
- oy->unsynced=0;
- oy->returned+=(bytes=oy->headerbytes+oy->bodybytes);
- oy->headerbytes=0;
- oy->bodybytes=0;
- return(bytes);
- }
-
- sync_fail:
-
- oy->headerbytes=0;
- oy->bodybytes=0;
-
- /* search for possible capture */
- next=(unsigned char*)memchr(page+1,'O',bytes-1);
- if(!next)
- next=oy->data+oy->fill;
-
- oy->returned=next-oy->data;
- return(-(next-page));
- }
-
- /* sync the stream and get a page. Keep trying until we find a page.
- Supress 'sync errors' after reporting the first.
-
- return values:
- -1) recapture (hole in data)
- 0) need more data
- 1) page returned
-
- Returns pointers into buffered data; invalidated by next call to
- _stream, _clear, _init, or _buffer */
-
- int ogg_sync_pageout(ogg_sync_state *oy, ogg_page *og){
-
- /* all we need to do is verify a page at the head of the stream
- buffer. If it doesn't verify, we look for the next potential
- frame */
-
- for(;;){
- long ret=ogg_sync_pageseek(oy,og);
- if(ret>0){
- /* have a page */
- return(1);
- }
- if(ret==0){
- /* need more data */
- return(0);
- }
-
- /* head did not start a synced page... skipped some bytes */
- if(!oy->unsynced){
- oy->unsynced=1;
- return(-1);
- }
-
- /* loop. keep looking */
-
- }
- }
-
- /* add the incoming page to the stream state; we decompose the page
- into packet segments here as well. */
-
- int ogg_stream_pagein(ogg_stream_state *os, ogg_page *og){
- unsigned char *header=og->header;
- unsigned char *body=og->body;
- long bodysize=og->body_len;
- int segptr=0;
-
- int version=ogg_page_version(og);
- int continued=ogg_page_continued(og);
- int bos=ogg_page_bos(og);
- int eos=ogg_page_eos(og);
- ogg_int64_t granulepos=ogg_page_granulepos(og);
- int serialno=ogg_page_serialno(og);
- long pageno=ogg_page_pageno(og);
- int segments=header[26];
-
- /* clean up 'returned data' */
- {
- long lr=os->lacing_returned;
- long br=os->body_returned;
-
- /* body data */
- if(br){
- os->body_fill-=br;
- if(os->body_fill)
- memmove(os->body_data,os->body_data+br,os->body_fill);
- os->body_returned=0;
- }
-
- if(lr){
- /* segment table */
- if(os->lacing_fill-lr){
- memmove(os->lacing_vals,os->lacing_vals+lr,
- (os->lacing_fill-lr)*sizeof(*os->lacing_vals));
- memmove(os->granule_vals,os->granule_vals+lr,
- (os->lacing_fill-lr)*sizeof(*os->granule_vals));
- }
- os->lacing_fill-=lr;
- os->lacing_packet-=lr;
- os->lacing_returned=0;
- }
- }
-
- /* check the serial number */
- if(serialno!=os->serialno)return(-1);
- if(version>0)return(-1);
-
- _os_lacing_expand(os,segments+1);
-
- /* are we in sequence? */
- if(pageno!=os->pageno){
- int i;
-
- /* unroll previous partial packet (if any) */
- for(i=os->lacing_packet;i<os->lacing_fill;i++)
- os->body_fill-=os->lacing_vals[i]&0xff;
- os->lacing_fill=os->lacing_packet;
-
- /* make a note of dropped data in segment table */
- if(os->pageno!=-1){
- os->lacing_vals[os->lacing_fill++]=0x400;
- os->lacing_packet++;
- }
- }
-
- /* are we a 'continued packet' page? If so, we may need to skip
- some segments */
- if(continued){
- if(os->lacing_fill<1 ||
- os->lacing_vals[os->lacing_fill-1]==0x400){
- bos=0;
- for(;segptr<segments;segptr++){
- int val=header[27+segptr];
- body+=val;
- bodysize-=val;
- if(val<255){
- segptr++;
- break;
- }
- }
- }
- }
-
- if(bodysize){
- _os_body_expand(os,bodysize);
- memcpy(os->body_data+os->body_fill,body,bodysize);
- os->body_fill+=bodysize;
- }
-
- {
- int saved=-1;
- while(segptr<segments){
- int val=header[27+segptr];
- os->lacing_vals[os->lacing_fill]=val;
- os->granule_vals[os->lacing_fill]=-1;
-
- if(bos){
- os->lacing_vals[os->lacing_fill]|=0x100;
- bos=0;
- }
-
- if(val<255)saved=os->lacing_fill;
-
- os->lacing_fill++;
- segptr++;
-
- if(val<255)os->lacing_packet=os->lacing_fill;
- }
-
- /* set the granulepos on the last granuleval of the last full packet */
- if(saved!=-1){
- os->granule_vals[saved]=granulepos;
- }
-
- }
-
- if(eos){
- os->e_o_s=1;
- if(os->lacing_fill>0)
- os->lacing_vals[os->lacing_fill-1]|=0x200;
- }
-
- os->pageno=pageno+1;
-
- return(0);
- }
-
- /* clear things to an initial state. Good to call, eg, before seeking */
- int ogg_sync_reset(ogg_sync_state *oy){
- oy->fill=0;
- oy->returned=0;
- oy->unsynced=0;
- oy->headerbytes=0;
- oy->bodybytes=0;
- return(0);
- }
-
- int ogg_stream_reset(ogg_stream_state *os){
- os->body_fill=0;
- os->body_returned=0;
-
- os->lacing_fill=0;
- os->lacing_packet=0;
- os->lacing_returned=0;
-
- os->header_fill=0;
-
- os->e_o_s=0;
- os->b_o_s=0;
- os->pageno=-1;
- os->packetno=0;
- os->granulepos=0;
-
- return(0);
- }
-
- int ogg_stream_reset_serialno(ogg_stream_state *os,int serialno){
- ogg_stream_reset(os);
- os->serialno=serialno;
- return(0);
- }
-
- static int _packetout(ogg_stream_state *os,ogg_packet *op,int adv){
-
- /* The last part of decode. We have the stream broken into packet
- segments. Now we need to group them into packets (or return the
- out of sync markers) */
-
- int ptr=os->lacing_returned;
-
- if(os->lacing_packet<=ptr)return(0);
-
- if(os->lacing_vals[ptr]&0x400){
- /* we need to tell the codec there's a gap; it might need to
- handle previous packet dependencies. */
- os->lacing_returned++;
- os->packetno++;
- return(-1);
- }
-
- if(!op && !adv)return(1); /* just using peek as an inexpensive way
- to ask if there's a whole packet
- waiting */
-
- /* Gather the whole packet. We'll have no holes or a partial packet */
- {
- int size=os->lacing_vals[ptr]&0xff;
- int bytes=size;
- int eos=os->lacing_vals[ptr]&0x200; /* last packet of the stream? */
- int bos=os->lacing_vals[ptr]&0x100; /* first packet of the stream? */
-
- while(size==255){
- int val=os->lacing_vals[++ptr];
- size=val&0xff;
- if(val&0x200)eos=0x200;
- bytes+=size;
- }
-
- if(op){
- op->e_o_s=eos;
- op->b_o_s=bos;
- op->packet=os->body_data+os->body_returned;
- op->packetno=os->packetno;
- op->granulepos=os->granule_vals[ptr];
- op->bytes=bytes;
- }
-
- if(adv){
- os->body_returned+=bytes;
- os->lacing_returned=ptr+1;
- os->packetno++;
- }
- }
- return(1);
- }
-
- int ogg_stream_packetout(ogg_stream_state *os,ogg_packet *op){
- return _packetout(os,op,1);
- }
-
- int ogg_stream_packetpeek(ogg_stream_state *os,ogg_packet *op){
- return _packetout(os,op,0);
- }
-
- void ogg_packet_clear(ogg_packet *op) {
- _ogg_free(op->packet);
- memset(op, 0, sizeof(*op));
- }
-
- #ifdef _V_SELFTEST
- #include <stdio.h>
-
- ogg_stream_state os_en, os_de;
- ogg_sync_state oy;
-
- void checkpacket(ogg_packet *op,int len, int no, int pos){
- long j;
- static int sequence=0;
- static int lastno=0;
-
- if(op->bytes!=len){
- fprintf(stderr,"incorrect packet length!\n");
- exit(1);
- }
- if(op->granulepos!=pos){
- fprintf(stderr,"incorrect packet position!\n");
- exit(1);
- }
-
- /* packet number just follows sequence/gap; adjust the input number
- for that */
- if(no==0){
- sequence=0;
- }else{
- sequence++;
- if(no>lastno+1)
- sequence++;
- }
- lastno=no;
- if(op->packetno!=sequence){
- fprintf(stderr,"incorrect packet sequence %ld != %d\n",
- (long)(op->packetno),sequence);
- exit(1);
- }
-
- /* Test data */
- for(j=0;j<op->bytes;j++)
- if(op->packet[j]!=((j+no)&0xff)){
- fprintf(stderr,"body data mismatch (1) at pos %ld: %x!=%lx!\n\n",
- j,op->packet[j],(j+no)&0xff);
- exit(1);
- }
- }
-
- void check_page(unsigned char *data,const int *header,ogg_page *og){
- long j;
- /* Test data */
- for(j=0;j<og->body_len;j++)
- if(og->body[j]!=data[j]){
- fprintf(stderr,"body data mismatch (2) at pos %ld: %x!=%x!\n\n",
- j,data[j],og->body[j]);
- exit(1);
- }
-
- /* Test header */
- for(j=0;j<og->header_len;j++){
- if(og->header[j]!=header[j]){
- fprintf(stderr,"header content mismatch at pos %ld:\n",j);
- for(j=0;j<header[26]+27;j++)
- fprintf(stderr," (%ld)%02x:%02x",j,header[j],og->header[j]);
- fprintf(stderr,"\n");
- exit(1);
- }
- }
- if(og->header_len!=header[26]+27){
- fprintf(stderr,"header length incorrect! (%ld!=%d)\n",
- og->header_len,header[26]+27);
- exit(1);
- }
- }
-
- void print_header(ogg_page *og){
- int j;
- fprintf(stderr,"\nHEADER:\n");
- fprintf(stderr," capture: %c %c %c %c version: %d flags: %x\n",
- og->header[0],og->header[1],og->header[2],og->header[3],
- (int)og->header[4],(int)og->header[5]);
-
- fprintf(stderr," granulepos: %d serialno: %d pageno: %ld\n",
- (og->header[9]<<24)|(og->header[8]<<16)|
- (og->header[7]<<8)|og->header[6],
- (og->header[17]<<24)|(og->header[16]<<16)|
- (og->header[15]<<8)|og->header[14],
- ((long)(og->header[21])<<24)|(og->header[20]<<16)|
- (og->header[19]<<8)|og->header[18]);
-
- fprintf(stderr," checksum: %02x:%02x:%02x:%02x\n segments: %d (",
- (int)og->header[22],(int)og->header[23],
- (int)og->header[24],(int)og->header[25],
- (int)og->header[26]);
-
- for(j=27;j<og->header_len;j++)
- fprintf(stderr,"%d ",(int)og->header[j]);
- fprintf(stderr,")\n\n");
- }
-
- void copy_page(ogg_page *og){
- unsigned char *temp=_ogg_malloc(og->header_len);
- memcpy(temp,og->header,og->header_len);
- og->header=temp;
-
- temp=_ogg_malloc(og->body_len);
- memcpy(temp,og->body,og->body_len);
- og->body=temp;
- }
-
- void free_page(ogg_page *og){
- _ogg_free (og->header);
- _ogg_free (og->body);
- }
-
- void error(void){
- fprintf(stderr,"error!\n");
- exit(1);
- }
-
- /* 17 only */
- const int head1_0[] = {0x4f,0x67,0x67,0x53,0,0x06,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x01,0x02,0x03,0x04,0,0,0,0,
- 0x15,0xed,0xec,0x91,
- 1,
- 17};
-
- /* 17, 254, 255, 256, 500, 510, 600 byte, pad */
- const int head1_1[] = {0x4f,0x67,0x67,0x53,0,0x02,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x01,0x02,0x03,0x04,0,0,0,0,
- 0x59,0x10,0x6c,0x2c,
- 1,
- 17};
- const int head2_1[] = {0x4f,0x67,0x67,0x53,0,0x04,
- 0x07,0x18,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x01,0x02,0x03,0x04,1,0,0,0,
- 0x89,0x33,0x85,0xce,
- 13,
- 254,255,0,255,1,255,245,255,255,0,
- 255,255,90};
-
- /* nil packets; beginning,middle,end */
- const int head1_2[] = {0x4f,0x67,0x67,0x53,0,0x02,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x01,0x02,0x03,0x04,0,0,0,0,
- 0xff,0x7b,0x23,0x17,
- 1,
- 0};
- const int head2_2[] = {0x4f,0x67,0x67,0x53,0,0x04,
- 0x07,0x28,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x01,0x02,0x03,0x04,1,0,0,0,
- 0x5c,0x3f,0x66,0xcb,
- 17,
- 17,254,255,0,0,255,1,0,255,245,255,255,0,
- 255,255,90,0};
-
- /* large initial packet */
- const int head1_3[] = {0x4f,0x67,0x67,0x53,0,0x02,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x01,0x02,0x03,0x04,0,0,0,0,
- 0x01,0x27,0x31,0xaa,
- 18,
- 255,255,255,255,255,255,255,255,
- 255,255,255,255,255,255,255,255,255,10};
-
- const int head2_3[] = {0x4f,0x67,0x67,0x53,0,0x04,
- 0x07,0x08,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x01,0x02,0x03,0x04,1,0,0,0,
- 0x7f,0x4e,0x8a,0xd2,
- 4,
- 255,4,255,0};
-
- /* continuing packet test */
- const int head1_4[] = {0x4f,0x67,0x67,0x53,0,0x02,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x01,0x02,0x03,0x04,0,0,0,0,
- 0xff,0x7b,0x23,0x17,
- 1,
- 0};
-
- const int head2_4[] = {0x4f,0x67,0x67,0x53,0,0x00,
- 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
- 0x01,0x02,0x03,0x04,1,0,0,0,
- 0x54,0x05,0x51,0xc8,
- 17,
- 255,255,255,255,255,255,255,255,
- 255,255,255,255,255,255,255,255,255};
-
- const int head3_4[] = {0x4f,0x67,0x67,0x53,0,0x05,
- 0x07,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x01,0x02,0x03,0x04,2,0,0,0,
- 0xc8,0xc3,0xcb,0xed,
- 5,
- 10,255,4,255,0};
-
- /* page with the 255 segment limit */
- const int head1_5[] = {0x4f,0x67,0x67,0x53,0,0x02,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x01,0x02,0x03,0x04,0,0,0,0,
- 0xff,0x7b,0x23,0x17,
- 1,
- 0};
-
- const int head2_5[] = {0x4f,0x67,0x67,0x53,0,0x00,
- 0x07,0xfc,0x03,0x00,0x00,0x00,0x00,0x00,
- 0x01,0x02,0x03,0x04,1,0,0,0,
- 0xed,0x2a,0x2e,0xa7,
- 255,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10};
-
- const int head3_5[] = {0x4f,0x67,0x67,0x53,0,0x04,
- 0x07,0x00,0x04,0x00,0x00,0x00,0x00,0x00,
- 0x01,0x02,0x03,0x04,2,0,0,0,
- 0x6c,0x3b,0x82,0x3d,
- 1,
- 50};
-
- /* packet that overspans over an entire page */
- const int head1_6[] = {0x4f,0x67,0x67,0x53,0,0x02,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x01,0x02,0x03,0x04,0,0,0,0,
- 0xff,0x7b,0x23,0x17,
- 1,
- 0};
-
- const int head2_6[] = {0x4f,0x67,0x67,0x53,0,0x00,
- 0x07,0x04,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x01,0x02,0x03,0x04,1,0,0,0,
- 0x3c,0xd9,0x4d,0x3f,
- 17,
- 100,255,255,255,255,255,255,255,255,
- 255,255,255,255,255,255,255,255};
-
- const int head3_6[] = {0x4f,0x67,0x67,0x53,0,0x01,
- 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
- 0x01,0x02,0x03,0x04,2,0,0,0,
- 0x01,0xd2,0xe5,0xe5,
- 17,
- 255,255,255,255,255,255,255,255,
- 255,255,255,255,255,255,255,255,255};
-
- const int head4_6[] = {0x4f,0x67,0x67,0x53,0,0x05,
- 0x07,0x10,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x01,0x02,0x03,0x04,3,0,0,0,
- 0xef,0xdd,0x88,0xde,
- 7,
- 255,255,75,255,4,255,0};
-
- /* packet that overspans over an entire page */
- const int head1_7[] = {0x4f,0x67,0x67,0x53,0,0x02,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x01,0x02,0x03,0x04,0,0,0,0,
- 0xff,0x7b,0x23,0x17,
- 1,
- 0};
-
- const int head2_7[] = {0x4f,0x67,0x67,0x53,0,0x00,
- 0x07,0x04,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x01,0x02,0x03,0x04,1,0,0,0,
- 0x3c,0xd9,0x4d,0x3f,
- 17,
- 100,255,255,255,255,255,255,255,255,
- 255,255,255,255,255,255,255,255};
-
- const int head3_7[] = {0x4f,0x67,0x67,0x53,0,0x05,
- 0x07,0x08,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x01,0x02,0x03,0x04,2,0,0,0,
- 0xd4,0xe0,0x60,0xe5,
- 1,0};
-
- void test_pack(const int *pl, const int **headers, int byteskip,
- int pageskip, int packetskip){
- unsigned char *data=_ogg_malloc(1024*1024); /* for scripted test cases only */
- long inptr=0;
- long outptr=0;
- long deptr=0;
- long depacket=0;
- long granule_pos=7,pageno=0;
- int i,j,packets,pageout=pageskip;
- int eosflag=0;
- int bosflag=0;
-
- int byteskipcount=0;
-
- ogg_stream_reset(&os_en);
- ogg_stream_reset(&os_de);
- ogg_sync_reset(&oy);
-
- for(packets=0;packets<packetskip;packets++)
- depacket+=pl[packets];
-
- for(packets=0;;packets++)if(pl[packets]==-1)break;
-
- for(i=0;i<packets;i++){
- /* construct a test packet */
- ogg_packet op;
- int len=pl[i];
-
- op.packet=data+inptr;
- op.bytes=len;
- op.e_o_s=(pl[i+1]<0?1:0);
- op.granulepos=granule_pos;
-
- granule_pos+=1024;
-
- for(j=0;j<len;j++)data[inptr++]=i+j;
-
- /* submit the test packet */
- ogg_stream_packetin(&os_en,&op);
-
- /* retrieve any finished pages */
- {
- ogg_page og;
-
- while(ogg_stream_pageout(&os_en,&og)){
- /* We have a page. Check it carefully */
-
- fprintf(stderr,"%ld, ",pageno);
-
- if(headers[pageno]==NULL){
- fprintf(stderr,"coded too many pages!\n");
- exit(1);
- }
-
- check_page(data+outptr,headers[pageno],&og);
-
- outptr+=og.body_len;
- pageno++;
- if(pageskip){
- bosflag=1;
- pageskip--;
- deptr+=og.body_len;
- }
-
- /* have a complete page; submit it to sync/decode */
-
- {
- ogg_page og_de;
- ogg_packet op_de,op_de2;
- char *buf=ogg_sync_buffer(&oy,og.header_len+og.body_len);
- char *next=buf;
- byteskipcount+=og.header_len;
- if(byteskipcount>byteskip){
- memcpy(next,og.header,byteskipcount-byteskip);
- next+=byteskipcount-byteskip;
- byteskipcount=byteskip;
- }
-
- byteskipcount+=og.body_len;
- if(byteskipcount>byteskip){
- memcpy(next,og.body,byteskipcount-byteskip);
- next+=byteskipcount-byteskip;
- byteskipcount=byteskip;
- }
-
- ogg_sync_wrote(&oy,next-buf);
-
- while(1){
- int ret=ogg_sync_pageout(&oy,&og_de);
- if(ret==0)break;
- if(ret<0)continue;
- /* got a page. Happy happy. Verify that it's good. */
-
- fprintf(stderr,"(%ld), ",pageout);
-
- check_page(data+deptr,headers[pageout],&og_de);
- deptr+=og_de.body_len;
- pageout++;
-
- /* submit it to deconstitution */
- ogg_stream_pagein(&os_de,&og_de);
-
- /* packets out? */
- while(ogg_stream_packetpeek(&os_de,&op_de2)>0){
- ogg_stream_packetpeek(&os_de,NULL);
- ogg_stream_packetout(&os_de,&op_de); /* just catching them all */
-
- /* verify peek and out match */
- if(memcmp(&op_de,&op_de2,sizeof(op_de))){
- fprintf(stderr,"packetout != packetpeek! pos=%ld\n",
- depacket);
- exit(1);
- }
-
- /* verify the packet! */
- /* check data */
- if(memcmp(data+depacket,op_de.packet,op_de.bytes)){
- fprintf(stderr,"packet data mismatch in decode! pos=%ld\n",
- depacket);
- exit(1);
- }
- /* check bos flag */
- if(bosflag==0 && op_de.b_o_s==0){
- fprintf(stderr,"b_o_s flag not set on packet!\n");
- exit(1);
- }
- if(bosflag && op_de.b_o_s){
- fprintf(stderr,"b_o_s flag incorrectly set on packet!\n");
- exit(1);
- }
- bosflag=1;
- depacket+=op_de.bytes;
-
- /* check eos flag */
- if(eosflag){
- fprintf(stderr,"Multiple decoded packets with eos flag!\n");
- exit(1);
- }
-
- if(op_de.e_o_s)eosflag=1;
-
- /* check granulepos flag */
- if(op_de.granulepos!=-1){
- fprintf(stderr," granule:%ld ",(long)op_de.granulepos);
- }
- }
- }
- }
- }
- }
- }
- _ogg_free(data);
- if(headers[pageno]!=NULL){
- fprintf(stderr,"did not write last page!\n");
- exit(1);
- }
- if(headers[pageout]!=NULL){
- fprintf(stderr,"did not decode last page!\n");
- exit(1);
- }
- if(inptr!=outptr){
- fprintf(stderr,"encoded page data incomplete!\n");
- exit(1);
- }
- if(inptr!=deptr){
- fprintf(stderr,"decoded page data incomplete!\n");
- exit(1);
- }
- if(inptr!=depacket){
- fprintf(stderr,"decoded packet data incomplete!\n");
- exit(1);
- }
- if(!eosflag){
- fprintf(stderr,"Never got a packet with EOS set!\n");
- exit(1);
- }
- fprintf(stderr,"ok.\n");
- }
-
- int main(void){
-
- ogg_stream_init(&os_en,0x04030201);
- ogg_stream_init(&os_de,0x04030201);
- ogg_sync_init(&oy);
-
- /* Exercise each code path in the framing code. Also verify that
- the checksums are working. */
-
- {
- /* 17 only */
- const int packets[]={17, -1};
- const int *headret[]={head1_0,NULL};
-
- fprintf(stderr,"testing single page encoding... ");
- test_pack(packets,headret,0,0,0);
- }
-
- {
- /* 17, 254, 255, 256, 500, 510, 600 byte, pad */
- const int packets[]={17, 254, 255, 256, 500, 510, 600, -1};
- const int *headret[]={head1_1,head2_1,NULL};
-
- fprintf(stderr,"testing basic page encoding... ");
- test_pack(packets,headret,0,0,0);
- }
-
- {
- /* nil packets; beginning,middle,end */
- const int packets[]={0,17, 254, 255, 0, 256, 0, 500, 510, 600, 0, -1};
- const int *headret[]={head1_2,head2_2,NULL};
-
- fprintf(stderr,"testing basic nil packets... ");
- test_pack(packets,headret,0,0,0);
- }
-
- {
- /* large initial packet */
- const int packets[]={4345,259,255,-1};
- const int *headret[]={head1_3,head2_3,NULL};
-
- fprintf(stderr,"testing initial-packet lacing > 4k... ");
- test_pack(packets,headret,0,0,0);
- }
-
- {
- /* continuing packet test */
- const int packets[]={0,4345,259,255,-1};
- const int *headret[]={head1_4,head2_4,head3_4,NULL};
-
- fprintf(stderr,"testing single packet page span... ");
- test_pack(packets,headret,0,0,0);
- }
-
- /* page with the 255 segment limit */
- {
-
- const int packets[]={0,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,50,-1};
- const int *headret[]={head1_5,head2_5,head3_5,NULL};
-
- fprintf(stderr,"testing max packet segments... ");
- test_pack(packets,headret,0,0,0);
- }
-
- {
- /* packet that overspans over an entire page */
- const int packets[]={0,100,9000,259,255,-1};
- const int *headret[]={head1_6,head2_6,head3_6,head4_6,NULL};
-
- fprintf(stderr,"testing very large packets... ");
- test_pack(packets,headret,0,0,0);
- }
-
- {
- /* test for the libogg 1.1.1 resync in large continuation bug
- found by Josh Coalson) */
- const int packets[]={0,100,9000,259,255,-1};
- const int *headret[]={head1_6,head2_6,head3_6,head4_6,NULL};
-
- fprintf(stderr,"testing continuation resync in very large packets... ");
- test_pack(packets,headret,100,2,3);
- }
-
- {
- /* term only page. why not? */
- const int packets[]={0,100,4080,-1};
- const int *headret[]={head1_7,head2_7,head3_7,NULL};
-
- fprintf(stderr,"testing zero data page (1 nil packet)... ");
- test_pack(packets,headret,0,0,0);
- }
-
- {
- /* build a bunch of pages for testing */
- unsigned char *data=_ogg_malloc(1024*1024);
- int pl[]={0,100,4079,2956,2057,76,34,912,0,234,1000,1000,1000,300,-1};
- int inptr=0,i,j;
- ogg_page og[5];
-
- ogg_stream_reset(&os_en);
-
- for(i=0;pl[i]!=-1;i++){
- ogg_packet op;
- int len=pl[i];
-
- op.packet=data+inptr;
- op.bytes=len;
- op.e_o_s=(pl[i+1]<0?1:0);
- op.granulepos=(i+1)*1000;
-
- for(j=0;j<len;j++)data[inptr++]=i+j;
- ogg_stream_packetin(&os_en,&op);
- }
-
- _ogg_free(data);
-
- /* retrieve finished pages */
- for(i=0;i<5;i++){
- if(ogg_stream_pageout(&os_en,&og[i])==0){
- fprintf(stderr,"Too few pages output building sync tests!\n");
- exit(1);
- }
- copy_page(&og[i]);
- }
-
- /* Test lost pages on pagein/packetout: no rollback */
- {
- ogg_page temp;
- ogg_packet test;
-
- fprintf(stderr,"Testing loss of pages... ");
-
- ogg_sync_reset(&oy);
- ogg_stream_reset(&os_de);
- for(i=0;i<5;i++){
- memcpy(ogg_sync_buffer(&oy,og[i].header_len),og[i].header,
- og[i].header_len);
- ogg_sync_wrote(&oy,og[i].header_len);
- memcpy(ogg_sync_buffer(&oy,og[i].body_len),og[i].body,og[i].body_len);
- ogg_sync_wrote(&oy,og[i].body_len);
- }
-
- ogg_sync_pageout(&oy,&temp);
- ogg_stream_pagein(&os_de,&temp);
- ogg_sync_pageout(&oy,&temp);
- ogg_stream_pagein(&os_de,&temp);
- ogg_sync_pageout(&oy,&temp);
- /* skip */
- ogg_sync_pageout(&oy,&temp);
- ogg_stream_pagein(&os_de,&temp);
-
- /* do we get the expected results/packets? */
-
- if(ogg_stream_packetout(&os_de,&test)!=1)error();
- checkpacket(&test,0,0,0);
- if(ogg_stream_packetout(&os_de,&test)!=1)error();
- checkpacket(&test,100,1,-1);
- if(ogg_stream_packetout(&os_de,&test)!=1)error();
- checkpacket(&test,4079,2,3000);
- if(ogg_stream_packetout(&os_de,&test)!=-1){
- fprintf(stderr,"Error: loss of page did not return error\n");
- exit(1);
- }
- if(ogg_stream_packetout(&os_de,&test)!=1)error();
- checkpacket(&test,76,5,-1);
- if(ogg_stream_packetout(&os_de,&test)!=1)error();
- checkpacket(&test,34,6,-1);
- fprintf(stderr,"ok.\n");
- }
-
- /* Test lost pages on pagein/packetout: rollback with continuation */
- {
- ogg_page temp;
- ogg_packet test;
-
- fprintf(stderr,"Testing loss of pages (rollback required)... ");
-
- ogg_sync_reset(&oy);
- ogg_stream_reset(&os_de);
- for(i=0;i<5;i++){
- memcpy(ogg_sync_buffer(&oy,og[i].header_len),og[i].header,
- og[i].header_len);
- ogg_sync_wrote(&oy,og[i].header_len);
- memcpy(ogg_sync_buffer(&oy,og[i].body_len),og[i].body,og[i].body_len);
- ogg_sync_wrote(&oy,og[i].body_len);
- }
-
- ogg_sync_pageout(&oy,&temp);
- ogg_stream_pagein(&os_de,&temp);
- ogg_sync_pageout(&oy,&temp);
- ogg_stream_pagein(&os_de,&temp);
- ogg_sync_pageout(&oy,&temp);
- ogg_stream_pagein(&os_de,&temp);
- ogg_sync_pageout(&oy,&temp);
- /* skip */
- ogg_sync_pageout(&oy,&temp);
- ogg_stream_pagein(&os_de,&temp);
-
- /* do we get the expected results/packets? */
-
- if(ogg_stream_packetout(&os_de,&test)!=1)error();
- checkpacket(&test,0,0,0);
- if(ogg_stream_packetout(&os_de,&test)!=1)error();
- checkpacket(&test,100,1,-1);
- if(ogg_stream_packetout(&os_de,&test)!=1)error();
- checkpacket(&test,4079,2,3000);
- if(ogg_stream_packetout(&os_de,&test)!=1)error();
- checkpacket(&test,2956,3,4000);
- if(ogg_stream_packetout(&os_de,&test)!=-1){
- fprintf(stderr,"Error: loss of page did not return error\n");
- exit(1);
- }
- if(ogg_stream_packetout(&os_de,&test)!=1)error();
- checkpacket(&test,300,13,14000);
- fprintf(stderr,"ok.\n");
- }
-
- /* the rest only test sync */
- {
- ogg_page og_de;
- /* Test fractional page inputs: incomplete capture */
- fprintf(stderr,"Testing sync on partial inputs... ");
- ogg_sync_reset(&oy);
- memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header,
- 3);
- ogg_sync_wrote(&oy,3);
- if(ogg_sync_pageout(&oy,&og_de)>0)error();
-
- /* Test fractional page inputs: incomplete fixed header */
- memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header+3,
- 20);
- ogg_sync_wrote(&oy,20);
- if(ogg_sync_pageout(&oy,&og_de)>0)error();
-
- /* Test fractional page inputs: incomplete header */
- memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header+23,
- 5);
- ogg_sync_wrote(&oy,5);
- if(ogg_sync_pageout(&oy,&og_de)>0)error();
-
- /* Test fractional page inputs: incomplete body */
-
- memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header+28,
- og[1].header_len-28);
- ogg_sync_wrote(&oy,og[1].header_len-28);
- if(ogg_sync_pageout(&oy,&og_de)>0)error();
-
- memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body,1000);
- ogg_sync_wrote(&oy,1000);
- if(ogg_sync_pageout(&oy,&og_de)>0)error();
-
- memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body+1000,
- og[1].body_len-1000);
- ogg_sync_wrote(&oy,og[1].body_len-1000);
- if(ogg_sync_pageout(&oy,&og_de)<=0)error();
-
- fprintf(stderr,"ok.\n");
- }
-
- /* Test fractional page inputs: page + incomplete capture */
- {
- ogg_page og_de;
- fprintf(stderr,"Testing sync on 1+partial inputs... ");
- ogg_sync_reset(&oy);
-
- memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header,
- og[1].header_len);
- ogg_sync_wrote(&oy,og[1].header_len);
-
- memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body,
- og[1].body_len);
- ogg_sync_wrote(&oy,og[1].body_len);
-
- memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header,
- 20);
- ogg_sync_wrote(&oy,20);
- if(ogg_sync_pageout(&oy,&og_de)<=0)error();
- if(ogg_sync_pageout(&oy,&og_de)>0)error();
-
- memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header+20,
- og[1].header_len-20);
- ogg_sync_wrote(&oy,og[1].header_len-20);
- memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body,
- og[1].body_len);
- ogg_sync_wrote(&oy,og[1].body_len);
- if(ogg_sync_pageout(&oy,&og_de)<=0)error();
-
- fprintf(stderr,"ok.\n");
- }
-
- /* Test recapture: garbage + page */
- {
- ogg_page og_de;
- fprintf(stderr,"Testing search for capture... ");
- ogg_sync_reset(&oy);
-
- /* 'garbage' */
- memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body,
- og[1].body_len);
- ogg_sync_wrote(&oy,og[1].body_len);
-
- memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header,
- og[1].header_len);
- ogg_sync_wrote(&oy,og[1].header_len);
-
- memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body,
- og[1].body_len);
- ogg_sync_wrote(&oy,og[1].body_len);
-
- memcpy(ogg_sync_buffer(&oy,og[2].header_len),og[2].header,
- 20);
- ogg_sync_wrote(&oy,20);
- if(ogg_sync_pageout(&oy,&og_de)>0)error();
- if(ogg_sync_pageout(&oy,&og_de)<=0)error();
- if(ogg_sync_pageout(&oy,&og_de)>0)error();
-
- memcpy(ogg_sync_buffer(&oy,og[2].header_len),og[2].header+20,
- og[2].header_len-20);
- ogg_sync_wrote(&oy,og[2].header_len-20);
- memcpy(ogg_sync_buffer(&oy,og[2].body_len),og[2].body,
- og[2].body_len);
- ogg_sync_wrote(&oy,og[2].body_len);
- if(ogg_sync_pageout(&oy,&og_de)<=0)error();
-
- fprintf(stderr,"ok.\n");
- }
-
- /* Test recapture: page + garbage + page */
- {
- ogg_page og_de;
- fprintf(stderr,"Testing recapture... ");
- ogg_sync_reset(&oy);
-
- memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header,
- og[1].header_len);
- ogg_sync_wrote(&oy,og[1].header_len);
-
- memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body,
- og[1].body_len);
- ogg_sync_wrote(&oy,og[1].body_len);
-
- memcpy(ogg_sync_buffer(&oy,og[2].header_len),og[2].header,
- og[2].header_len);
- ogg_sync_wrote(&oy,og[2].header_len);
-
- memcpy(ogg_sync_buffer(&oy,og[2].header_len),og[2].header,
- og[2].header_len);
- ogg_sync_wrote(&oy,og[2].header_len);
-
- if(ogg_sync_pageout(&oy,&og_de)<=0)error();
-
- memcpy(ogg_sync_buffer(&oy,og[2].body_len),og[2].body,
- og[2].body_len-5);
- ogg_sync_wrote(&oy,og[2].body_len-5);
-
- memcpy(ogg_sync_buffer(&oy,og[3].header_len),og[3].header,
- og[3].header_len);
- ogg_sync_wrote(&oy,og[3].header_len);
-
- memcpy(ogg_sync_buffer(&oy,og[3].body_len),og[3].body,
- og[3].body_len);
- ogg_sync_wrote(&oy,og[3].body_len);
-
- if(ogg_sync_pageout(&oy,&og_de)>0)error();
- if(ogg_sync_pageout(&oy,&og_de)<=0)error();
-
- fprintf(stderr,"ok.\n");
- }
-
- /* Free page data that was previously copied */
- {
- for(i=0;i<5;i++){
- free_page(&og[i]);
- }
- }
- }
-
- return(0);
- }
-
- #endif
-
- #endif
- /********* End of inlined file: framing.c *********/
-
- /********* Start of inlined file: analysis.c *********/
-
- /********* Start of inlined file: juce_OggVorbisHeader.h *********/
- // This file is included at the start of each Ogg-Vorbis .c file, just to do a few housekeeping
- // tasks..
-
- #ifdef _MSC_VER
- #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4305 4189 4706)
- #endif
- /********* End of inlined file: juce_OggVorbisHeader.h *********/
-
- #if JUCE_USE_OGGVORBIS
-
- #include <stdio.h>
- #include <string.h>
- #include <math.h>
-
- /********* Start of inlined file: codec_internal.h *********/
- #ifndef _V_CODECI_H_
- #define _V_CODECI_H_
-
- /********* Start of inlined file: envelope.h *********/
- #ifndef _V_ENVELOPE_
- #define _V_ENVELOPE_
-
- /********* Start of inlined file: mdct.h *********/
- #ifndef _OGG_mdct_H_
- #define _OGG_mdct_H_
-
- /*#define MDCT_INTEGERIZED <- be warned there could be some hurt left here*/
- #ifdef MDCT_INTEGERIZED
-
- #define DATA_TYPE int
- #define REG_TYPE register int
- #define TRIGBITS 14
- #define cPI3_8 6270
- #define cPI2_8 11585
- #define cPI1_8 15137
-
- #define FLOAT_CONV(x) ((int)((x)*(1<<TRIGBITS)+.5))
- #define MULT_NORM(x) ((x)>>TRIGBITS)
- #define HALVE(x) ((x)>>1)
-
- #else
-
- #define DATA_TYPE float
- #define REG_TYPE float
- #define cPI3_8 .38268343236508977175F
- #define cPI2_8 .70710678118654752441F
- #define cPI1_8 .92387953251128675613F
-
- #define FLOAT_CONV(x) (x)
- #define MULT_NORM(x) (x)
- #define HALVE(x) ((x)*.5f)
-
- #endif
-
- typedef struct {
- int n;
- int log2n;
-
- DATA_TYPE *trig;
- int *bitrev;
-
- DATA_TYPE scale;
- } mdct_lookup;
-
- extern void mdct_init(mdct_lookup *lookup,int n);
- extern void mdct_clear(mdct_lookup *l);
- extern void mdct_forward(mdct_lookup *init, DATA_TYPE *in, DATA_TYPE *out);
- extern void mdct_backward(mdct_lookup *init, DATA_TYPE *in, DATA_TYPE *out);
-
- #endif
- /********* End of inlined file: mdct.h *********/
-
- #define VE_PRE 16
- #define VE_WIN 4
- #define VE_POST 2
- #define VE_AMP (VE_PRE+VE_POST-1)
-
- #define VE_BANDS 7
- #define VE_NEARDC 15
-
- #define VE_MINSTRETCH 2 /* a bit less than short block */
- #define VE_MAXSTRETCH 12 /* one-third full block */
-
- typedef struct {
- float ampbuf[VE_AMP];
- int ampptr;
-
- float nearDC[VE_NEARDC];
- float nearDC_acc;
- float nearDC_partialacc;
- int nearptr;
-
- } envelope_filter_state;
-
- typedef struct {
- int begin;
- int end;
- float *window;
- float total;
- } envelope_band;
-
- typedef struct {
- int ch;
- int winlength;
- int searchstep;
- float minenergy;
-
- mdct_lookup mdct;
- float *mdct_win;
-
- envelope_band band[VE_BANDS];
- envelope_filter_state *filter;
- int stretch;
-
- int *mark;
-
- long storage;
- long current;
- long curmark;
- long cursor;
- } envelope_lookup;
-
- extern void _ve_envelope_init(envelope_lookup *e,vorbis_info *vi);
- extern void _ve_envelope_clear(envelope_lookup *e);
- extern long _ve_envelope_search(vorbis_dsp_state *v);
- extern void _ve_envelope_shift(envelope_lookup *e,long shift);
- extern int _ve_envelope_mark(vorbis_dsp_state *v);
-
- #endif
- /********* End of inlined file: envelope.h *********/
-
- /********* Start of inlined file: codebook.h *********/
- #ifndef _V_CODEBOOK_H_
- #define _V_CODEBOOK_H_
-
- /* This structure encapsulates huffman and VQ style encoding books; it
- doesn't do anything specific to either.
-
- valuelist/quantlist are nonNULL (and q_* significant) only if
- there's entry->value mapping to be done.
-
- If encode-side mapping must be done (and thus the entry needs to be
- hunted), the auxiliary encode pointer will point to a decision
- tree. This is true of both VQ and huffman, but is mostly useful
- with VQ.
-
- */
-
- typedef struct static_codebook{
- long dim; /* codebook dimensions (elements per vector) */
- long entries; /* codebook entries */
- long *lengthlist; /* codeword lengths in bits */
-
- /* mapping ***************************************************************/
- int maptype; /* 0=none
- 1=implicitly populated values from map column
- 2=listed arbitrary values */
-
- /* The below does a linear, single monotonic sequence mapping. */
- long q_min; /* packed 32 bit float; quant value 0 maps to minval */
- long q_delta; /* packed 32 bit float; val 1 - val 0 == delta */
- int q_quant; /* bits: 0 < quant <= 16 */
- int q_sequencep; /* bitflag */
-
- long *quantlist; /* map == 1: (int)(entries^(1/dim)) element column map
- map == 2: list of dim*entries quantized entry vals
- */
-
- /* encode helpers ********************************************************/
- struct encode_aux_nearestmatch *nearest_tree;
- struct encode_aux_threshmatch *thresh_tree;
- struct encode_aux_pigeonhole *pigeon_tree;
-
- int allocedp;
- } static_codebook;
-
- /* this structures an arbitrary trained book to quickly find the
- nearest cell match */
- typedef struct encode_aux_nearestmatch{
- /* pre-calculated partitioning tree */
- long *ptr0;
- long *ptr1;
-
- long *p; /* decision points (each is an entry) */
- long *q; /* decision points (each is an entry) */
- long aux; /* number of tree entries */
- long alloc;
- } encode_aux_nearestmatch;
-
- /* assumes a maptype of 1; encode side only, so that's OK */
- typedef struct encode_aux_threshmatch{
- float *quantthresh;
- long *quantmap;
- int quantvals;
- int threshvals;
- } encode_aux_threshmatch;
-
- typedef struct encode_aux_pigeonhole{
- float min;
- float del;
-
- int mapentries;
- int quantvals;
- long *pigeonmap;
-
- long fittotal;
- long *fitlist;
- long *fitmap;
- long *fitlength;
- } encode_aux_pigeonhole;
-
- typedef struct codebook{
- long dim; /* codebook dimensions (elements per vector) */
- long entries; /* codebook entries */
- long used_entries; /* populated codebook entries */
- const static_codebook *c;
-
- /* for encode, the below are entry-ordered, fully populated */
- /* for decode, the below are ordered by bitreversed codeword and only
- used entries are populated */
- float *valuelist; /* list of dim*entries actual entry values */
- ogg_uint32_t *codelist; /* list of bitstream codewords for each entry */
-
- int *dec_index; /* only used if sparseness collapsed */
- char *dec_codelengths;
- ogg_uint32_t *dec_firsttable;
- int dec_firsttablen;
- int dec_maxlength;
-
- } codebook;
-
- extern void vorbis_staticbook_clear(static_codebook *b);
- extern void vorbis_staticbook_destroy(static_codebook *b);
- extern int vorbis_book_init_encode(codebook *dest,const static_codebook *source);
- extern int vorbis_book_init_decode(codebook *dest,const static_codebook *source);
- extern void vorbis_book_clear(codebook *b);
-
- extern float *_book_unquantize(const static_codebook *b,int n,int *map);
- extern float *_book_logdist(const static_codebook *b,float *vals);
- extern float _float32_unpack(long val);
- extern long _float32_pack(float val);
- extern int _best(codebook *book, float *a, int step);
- extern int _ilog(unsigned int v);
- extern long _book_maptype1_quantvals(const static_codebook *b);
-
- extern int vorbis_book_besterror(codebook *book,float *a,int step,int addmul);
- extern long vorbis_book_codeword(codebook *book,int entry);
- extern long vorbis_book_codelen(codebook *book,int entry);
-
- extern int vorbis_staticbook_pack(const static_codebook *c,oggpack_buffer *b);
- extern int vorbis_staticbook_unpack(oggpack_buffer *b,static_codebook *c);
-
- extern int vorbis_book_encode(codebook *book, int a, oggpack_buffer *b);
- extern int vorbis_book_errorv(codebook *book, float *a);
- extern int vorbis_book_encodev(codebook *book, int best,float *a,
- oggpack_buffer *b);
-
- extern long vorbis_book_decode(codebook *book, oggpack_buffer *b);
- extern long vorbis_book_decodevs_add(codebook *book, float *a,
- oggpack_buffer *b,int n);
- extern long vorbis_book_decodev_set(codebook *book, float *a,
- oggpack_buffer *b,int n);
- extern long vorbis_book_decodev_add(codebook *book, float *a,
- oggpack_buffer *b,int n);
- extern long vorbis_book_decodevv_add(codebook *book, float **a,
- long off,int ch,
- oggpack_buffer *b,int n);
-
- #endif
- /********* End of inlined file: codebook.h *********/
-
- #define BLOCKTYPE_IMPULSE 0
- #define BLOCKTYPE_PADDING 1
- #define BLOCKTYPE_TRANSITION 0
- #define BLOCKTYPE_LONG 1
-
- #define PACKETBLOBS 15
-
- typedef struct vorbis_block_internal{
- float **pcmdelay; /* this is a pointer into local storage */
- float ampmax;
- int blocktype;
-
- oggpack_buffer *packetblob[PACKETBLOBS]; /* initialized, must be freed;
- blob [PACKETBLOBS/2] points to
- the oggpack_buffer in the
- main vorbis_block */
- } vorbis_block_internal;
-
- typedef void vorbis_look_floor;
- typedef void vorbis_look_residue;
- typedef void vorbis_look_transform;
-
- /* mode ************************************************************/
- typedef struct {
- int blockflag;
- int windowtype;
- int transformtype;
- int mapping;
- } vorbis_info_mode;
-
- typedef void vorbis_info_floor;
- typedef void vorbis_info_residue;
- typedef void vorbis_info_mapping;
-
- /********* Start of inlined file: psy.h *********/
- #ifndef _V_PSY_H_
- #define _V_PSY_H_
-
- /********* Start of inlined file: smallft.h *********/
- #ifndef _V_SMFT_H_
- #define _V_SMFT_H_
-
- typedef struct {
- int n;
- float *trigcache;
- int *splitcache;
- } drft_lookup;
-
- extern void drft_forward(drft_lookup *l,float *data);
- extern void drft_backward(drft_lookup *l,float *data);
- extern void drft_init(drft_lookup *l,int n);
- extern void drft_clear(drft_lookup *l);
-
- #endif
- /********* End of inlined file: smallft.h *********/
-
- /********* Start of inlined file: backends.h *********/
- /* this is exposed up here because we need it for static modes.
- Lookups for each backend aren't exposed because there's no reason
- to do so */
-
- #ifndef _vorbis_backend_h_
- #define _vorbis_backend_h_
-
- /* this would all be simpler/shorter with templates, but.... */
- /* Floor backend generic *****************************************/
- typedef struct{
- void (*pack) (vorbis_info_floor *,oggpack_buffer *);
- vorbis_info_floor *(*unpack)(vorbis_info *,oggpack_buffer *);
- vorbis_look_floor *(*look) (vorbis_dsp_state *,vorbis_info_floor *);
- void (*free_info) (vorbis_info_floor *);
- void (*free_look) (vorbis_look_floor *);
- void *(*inverse1) (struct vorbis_block *,vorbis_look_floor *);
- int (*inverse2) (struct vorbis_block *,vorbis_look_floor *,
- void *buffer,float *);
- } vorbis_func_floor;
-
- typedef struct{
- int order;
- long rate;
- long barkmap;
-
- int ampbits;
- int ampdB;
-
- int numbooks; /* <= 16 */
- int books[16];
-
- float lessthan; /* encode-only config setting hacks for libvorbis */
- float greaterthan; /* encode-only config setting hacks for libvorbis */
-
- } vorbis_info_floor0;
-
- #define VIF_POSIT 63
- #define VIF_CLASS 16
- #define VIF_PARTS 31
- typedef struct{
- int partitions; /* 0 to 31 */
- int partitionclass[VIF_PARTS]; /* 0 to 15 */
-
- int class_dim[VIF_CLASS]; /* 1 to 8 */
- int class_subs[VIF_CLASS]; /* 0,1,2,3 (bits: 1<<n poss) */
- int class_book[VIF_CLASS]; /* subs ^ dim entries */
- int class_subbook[VIF_CLASS][8]; /* [VIF_CLASS][subs] */
-
- int mult; /* 1 2 3 or 4 */
- int postlist[VIF_POSIT+2]; /* first two implicit */
-
- /* encode side analysis parameters */
- float maxover;
- float maxunder;
- float maxerr;
-
- float twofitweight;
- float twofitatten;
-
- int n;
-
- } vorbis_info_floor1;
-
- /* Residue backend generic *****************************************/
- typedef struct{
- void (*pack) (vorbis_info_residue *,oggpack_buffer *);
- vorbis_info_residue *(*unpack)(vorbis_info *,oggpack_buffer *);
- vorbis_look_residue *(*look) (vorbis_dsp_state *,
- vorbis_info_residue *);
- void (*free_info) (vorbis_info_residue *);
- void (*free_look) (vorbis_look_residue *);
- long **(*classx) (struct vorbis_block *,vorbis_look_residue *,
- float **,int *,int);
- int (*forward) (oggpack_buffer *,struct vorbis_block *,
- vorbis_look_residue *,
- float **,float **,int *,int,long **);
- int (*inverse) (struct vorbis_block *,vorbis_look_residue *,
- float **,int *,int);
- } vorbis_func_residue;
-
- typedef struct vorbis_info_residue0{
- /* block-partitioned VQ coded straight residue */
- long begin;
- long end;
-
- /* first stage (lossless partitioning) */
- int grouping; /* group n vectors per partition */
- int partitions; /* possible codebooks for a partition */
- int groupbook; /* huffbook for partitioning */
- int secondstages[64]; /* expanded out to pointers in lookup */
- int booklist[256]; /* list of second stage books */
-
- float classmetric1[64];
- float classmetric2[64];
-
- } vorbis_info_residue0;
-
- /* Mapping backend generic *****************************************/
- typedef struct{
- void (*pack) (vorbis_info *,vorbis_info_mapping *,
- oggpack_buffer *);
- vorbis_info_mapping *(*unpack)(vorbis_info *,oggpack_buffer *);
- void (*free_info) (vorbis_info_mapping *);
- int (*forward) (struct vorbis_block *vb);
- int (*inverse) (struct vorbis_block *vb,vorbis_info_mapping *);
- } vorbis_func_mapping;
-
- typedef struct vorbis_info_mapping0{
- int submaps; /* <= 16 */
- int chmuxlist[256]; /* up to 256 channels in a Vorbis stream */
-
- int floorsubmap[16]; /* [mux] submap to floors */
- int residuesubmap[16]; /* [mux] submap to residue */
-
- int coupling_steps;
- int coupling_mag[256];
- int coupling_ang[256];
-
- } vorbis_info_mapping0;
-
- #endif
- /********* End of inlined file: backends.h *********/
-
- #ifndef EHMER_MAX
- #define EHMER_MAX 56
- #endif
-
- /* psychoacoustic setup ********************************************/
- #define P_BANDS 17 /* 62Hz to 16kHz */
- #define P_LEVELS 8 /* 30dB to 100dB */
- #define P_LEVEL_0 30. /* 30 dB */
- #define P_NOISECURVES 3
-
- #define NOISE_COMPAND_LEVELS 40
- typedef struct vorbis_info_psy{
- int blockflag;
-
- float ath_adjatt;
- float ath_maxatt;
-
- float tone_masteratt[P_NOISECURVES];
- float tone_centerboost;
- float tone_decay;
- float tone_abs_limit;
- float toneatt[P_BANDS];
-
- int noisemaskp;
- float noisemaxsupp;
- float noisewindowlo;
- float noisewindowhi;
- int noisewindowlomin;
- int noisewindowhimin;
- int noisewindowfixed;
- float noiseoff[P_NOISECURVES][P_BANDS];
- float noisecompand[NOISE_COMPAND_LEVELS];
-
- float max_curve_dB;
-
- int normal_channel_p;
- int normal_point_p;
- int normal_start;
- int normal_partition;
- double normal_thresh;
- } vorbis_info_psy;
-
- typedef struct{
- int eighth_octave_lines;
-
- /* for block long/short tuning; encode only */
- float preecho_thresh[VE_BANDS];
- float postecho_thresh[VE_BANDS];
- float stretch_penalty;
- float preecho_minenergy;
-
- float ampmax_att_per_sec;
-
- /* channel coupling config */
- int coupling_pkHz[PACKETBLOBS];
- int coupling_pointlimit[2][PACKETBLOBS];
- int coupling_prepointamp[PACKETBLOBS];
- int coupling_postpointamp[PACKETBLOBS];
- int sliding_lowpass[2][PACKETBLOBS];
-
- } vorbis_info_psy_global;
-
- typedef struct {
- float ampmax;
- int channels;
-
- vorbis_info_psy_global *gi;
- int coupling_pointlimit[2][P_NOISECURVES];
- } vorbis_look_psy_global;
-
- typedef struct {
- int n;
- struct vorbis_info_psy *vi;
-
- float ***tonecurves;
- float **noiseoffset;
-
- float *ath;
- long *octave; /* in n.ocshift format */
- long *bark;
-
- long firstoc;
- long shiftoc;
- int eighth_octave_lines; /* power of two, please */
- int total_octave_lines;
- long rate; /* cache it */
-
- float m_val; /* Masking compensation value */
-
- } vorbis_look_psy;
-
- extern void _vp_psy_init(vorbis_look_psy *p,vorbis_info_psy *vi,
- vorbis_info_psy_global *gi,int n,long rate);
- extern void _vp_psy_clear(vorbis_look_psy *p);
- extern void *_vi_psy_dup(void *source);
-
- extern void _vi_psy_free(vorbis_info_psy *i);
- extern vorbis_info_psy *_vi_psy_copy(vorbis_info_psy *i);
-
- extern void _vp_remove_floor(vorbis_look_psy *p,
- float *mdct,
- int *icodedflr,
- float *residue,
- int sliding_lowpass);
-
- extern void _vp_noisemask(vorbis_look_psy *p,
- float *logmdct,
- float *logmask);
-
- extern void _vp_tonemask(vorbis_look_psy *p,
- float *logfft,
- float *logmask,
- float global_specmax,
- float local_specmax);
-
- extern void _vp_offset_and_mix(vorbis_look_psy *p,
- float *noise,
- float *tone,
- int offset_select,
- float *logmask,
- float *mdct,
- float *logmdct);
-
- extern float _vp_ampmax_decay(float amp,vorbis_dsp_state *vd);
-
- extern float **_vp_quantize_couple_memo(vorbis_block *vb,
- vorbis_info_psy_global *g,
- vorbis_look_psy *p,
- vorbis_info_mapping0 *vi,
- float **mdct);
-
- extern void _vp_couple(int blobno,
- vorbis_info_psy_global *g,
- vorbis_look_psy *p,
- vorbis_info_mapping0 *vi,
- float **res,
- float **mag_memo,
- int **mag_sort,
- int **ifloor,
- int *nonzero,
- int sliding_lowpass);
-
- extern void _vp_noise_normalize(vorbis_look_psy *p,
- float *in,float *out,int *sortedindex);
-
- extern void _vp_noise_normalize_sort(vorbis_look_psy *p,
- float *magnitudes,int *sortedindex);
-
- extern int **_vp_quantize_couple_sort(vorbis_block *vb,
- vorbis_look_psy *p,
- vorbis_info_mapping0 *vi,
- float **mags);
-
- extern void hf_reduction(vorbis_info_psy_global *g,
- vorbis_look_psy *p,
- vorbis_info_mapping0 *vi,
- float **mdct);
-
- #endif
- /********* End of inlined file: psy.h *********/
-
- /********* Start of inlined file: bitrate.h *********/
- #ifndef _V_BITRATE_H_
- #define _V_BITRATE_H_
-
- /********* Start of inlined file: os.h *********/
- #ifndef _OS_H
- #define _OS_H
- /********************************************************************
- * *
- * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
- * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
- * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
- * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
- * *
- * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
- * by the XIPHOPHORUS Company http://www.xiph.org/ *
- * *
- ********************************************************************
-
- function: #ifdef jail to whip a few platforms into the UNIX ideal.
- last mod: $Id: os.h,v 1.1 2007/06/07 17:49:18 jules_rms Exp $
-
- ********************************************************************/
-
- #ifdef HAVE_CONFIG_H
- #include "config.h"
- #endif
-
- #include <math.h>
-
- /********* Start of inlined file: misc.h *********/
- #ifndef _V_RANDOM_H_
- #define _V_RANDOM_H_
-
- extern int analysis_noisy;
-
- extern void *_vorbis_block_alloc(vorbis_block *vb,long bytes);
- extern void _vorbis_block_ripcord(vorbis_block *vb);
- extern void _analysis_output(char *base,int i,float *v,int n,int bark,int dB,
- ogg_int64_t off);
-
- #ifdef DEBUG_MALLOC
-
- #define _VDBG_GRAPHFILE "malloc.m"
- extern void *_VDBG_malloc(void *ptr,long bytes,char *file,long line);
- extern void _VDBG_free(void *ptr,char *file,long line);
-
- #ifndef MISC_C
- #undef _ogg_malloc
- #undef _ogg_calloc
- #undef _ogg_realloc
- #undef _ogg_free
-
- #define _ogg_malloc(x) _VDBG_malloc(NULL,(x),__FILE__,__LINE__)
- #define _ogg_calloc(x,y) _VDBG_malloc(NULL,(x)*(y),__FILE__,__LINE__)
- #define _ogg_realloc(x,y) _VDBG_malloc((x),(y),__FILE__,__LINE__)
- #define _ogg_free(x) _VDBG_free((x),__FILE__,__LINE__)
- #endif
- #endif
-
- #endif
- /********* End of inlined file: misc.h *********/
-
- #ifndef _V_IFDEFJAIL_H_
- # define _V_IFDEFJAIL_H_
-
- # ifdef __GNUC__
- # define STIN static __inline__
- # elif _WIN32
- # define STIN static __inline
- # else
- # define STIN static
- # endif
-
- #ifdef DJGPP
- # define rint(x) (floor((x)+0.5f))
- #endif
-
- #ifndef M_PI
- # define M_PI (3.1415926536f)
- #endif
-
- #if defined(_WIN32) && !defined(__SYMBIAN32__)
- # include <malloc.h>
- # define rint(x) (floor((x)+0.5f))
- # define NO_FLOAT_MATH_LIB
- # define FAST_HYPOT(a, b) sqrt((a)*(a) + (b)*(b))
- #endif
-
- #if defined(__SYMBIAN32__) && defined(__WINS__)
- void *_alloca(size_t size);
- # define alloca _alloca
- #endif
-
- #ifndef FAST_HYPOT
- # define FAST_HYPOT hypot
- #endif
-
- #endif
-
- #ifdef HAVE_ALLOCA_H
- # include <alloca.h>
- #endif
-
- #ifdef USE_MEMORY_H
- # include <memory.h>
- #endif
-
- #ifndef min
- # define min(x,y) ((x)>(y)?(y):(x))
- #endif
-
- #ifndef max
- # define max(x,y) ((x)<(y)?(y):(x))
- #endif
-
- #if defined(__i386__) && defined(__GNUC__) && !defined(__BEOS__)
- # define VORBIS_FPU_CONTROL
- /* both GCC and MSVC are kinda stupid about rounding/casting to int.
- Because of encapsulation constraints (GCC can't see inside the asm
- block and so we end up doing stupid things like a store/load that
- is collectively a noop), we do it this way */
-
- /* we must set up the fpu before this works!! */
-
- typedef ogg_int16_t vorbis_fpu_control;
-
- static inline void vorbis_fpu_setround(vorbis_fpu_control *fpu){
- ogg_int16_t ret;
- ogg_int16_t temp;
- __asm__ __volatile__("fnstcw %0\n\t"
- "movw %0,%%dx\n\t"
- "orw $62463,%%dx\n\t"
- "movw %%dx,%1\n\t"
- "fldcw %1\n\t":"=m"(ret):"m"(temp): "dx");
- *fpu=ret;
- }
-
- static inline void vorbis_fpu_restore(vorbis_fpu_control fpu){
- __asm__ __volatile__("fldcw %0":: "m"(fpu));
- }
-
- /* assumes the FPU is in round mode! */
- static inline int vorbis_ftoi(double f){ /* yes, double! Otherwise,
- we get extra fst/fld to
- truncate precision */
- int i;
- __asm__("fistl %0": "=m"(i) : "t"(f));
- return(i);
- }
- #endif
-
- #if defined(_WIN32) && defined(_X86_) && !defined(__GNUC__) && !defined(__BORLANDC__)
- # define VORBIS_FPU_CONTROL
-
- typedef ogg_int16_t vorbis_fpu_control;
-
- static __inline int vorbis_ftoi(double f){
- int i;
- __asm{
- fld f
- fistp i
- }
- return i;
- }
-
- static __inline void vorbis_fpu_setround(vorbis_fpu_control *fpu){
- }
-
- static __inline void vorbis_fpu_restore(vorbis_fpu_control fpu){
- }
-
- #endif
-
- #ifndef VORBIS_FPU_CONTROL
-
- typedef int vorbis_fpu_control;
-
- static int vorbis_ftoi(double f){
- return (int)(f+.5);
- }
-
- /* We don't have special code for this compiler/arch, so do it the slow way */
- # define vorbis_fpu_setround(vorbis_fpu_control) {}
- # define vorbis_fpu_restore(vorbis_fpu_control) {}
-
- #endif
-
- #endif /* _OS_H */
- /********* End of inlined file: os.h *********/
-
- /* encode side bitrate tracking */
- typedef struct bitrate_manager_state {
- int managed;
-
- long avg_reservoir;
- long minmax_reservoir;
- long avg_bitsper;
- long min_bitsper;
- long max_bitsper;
-
- long short_per_long;
- double avgfloat;
-
- vorbis_block *vb;
- int choice;
- } bitrate_manager_state;
-
- typedef struct bitrate_manager_info{
- long avg_rate;
- long min_rate;
- long max_rate;
- long reservoir_bits;
- double reservoir_bias;
-
- double slew_damp;
-
- } bitrate_manager_info;
-
- extern void vorbis_bitrate_init(vorbis_info *vi,bitrate_manager_state *bs);
- extern void vorbis_bitrate_clear(bitrate_manager_state *bs);
- extern int vorbis_bitrate_managed(vorbis_block *vb);
- extern int vorbis_bitrate_addblock(vorbis_block *vb);
- extern int vorbis_bitrate_flushpacket(vorbis_dsp_state *vd, ogg_packet *op);
-
- #endif
- /********* End of inlined file: bitrate.h *********/
-
- static int ilog(unsigned int v){
- int ret=0;
- while(v){
- ret++;
- v>>=1;
- }
- return(ret);
- }
-
- static int ilog2(unsigned int v){
- int ret=0;
- if(v)--v;
- while(v){
- ret++;
- v>>=1;
- }
- return(ret);
- }
-
- typedef struct private_state {
- /* local lookup storage */
- envelope_lookup *ve; /* envelope lookup */
- int window[2];
- vorbis_look_transform **transform[2]; /* block, type */
- drft_lookup fft_look[2];
-
- int modebits;
- vorbis_look_floor **flr;
- vorbis_look_residue **residue;
- vorbis_look_psy *psy;
- vorbis_look_psy_global *psy_g_look;
-
- /* local storage, only used on the encoding side. This way the
- application does not need to worry about freeing some packets'
- memory and not others'; packet storage is always tracked.
- Cleared next call to a _dsp_ function */
- unsigned char *header;
- unsigned char *header1;
- unsigned char *header2;
-
- bitrate_manager_state bms;
-
- ogg_int64_t sample_count;
- } private_state;
-
- /* codec_setup_info contains all the setup information specific to the
- specific compression/decompression mode in progress (eg,
- psychoacoustic settings, channel setup, options, codebook
- etc).
- *********************************************************************/
-
- /********* Start of inlined file: highlevel.h *********/
- typedef struct highlevel_byblocktype {
- double tone_mask_setting;
- double tone_peaklimit_setting;
- double noise_bias_setting;
- double noise_compand_setting;
- } highlevel_byblocktype;
-
- typedef struct highlevel_encode_setup {
- void *setup;
- int set_in_stone;
-
- double base_setting;
- double long_setting;
- double short_setting;
- double impulse_noisetune;
-
- int managed;
- long bitrate_min;
- long bitrate_av;
- double bitrate_av_damp;
- long bitrate_max;
- long bitrate_reservoir;
- double bitrate_reservoir_bias;
-
- int impulse_block_p;
- int noise_normalize_p;
-
- double stereo_point_setting;
- double lowpass_kHz;
-
- double ath_floating_dB;
- double ath_absolute_dB;
-
- double amplitude_track_dBpersec;
- double trigger_setting;
-
- highlevel_byblocktype block[4]; /* padding, impulse, transition, long */
-
- } highlevel_encode_setup;
- /********* End of inlined file: highlevel.h *********/
-
- typedef struct codec_setup_info {
-
- /* Vorbis supports only short and long blocks, but allows the
- encoder to choose the sizes */
-
- long blocksizes[2];
-
- /* modes are the primary means of supporting on-the-fly different
- blocksizes, different channel mappings (LR or M/A),
- different residue backends, etc. Each mode consists of a
- blocksize flag and a mapping (along with the mapping setup */
-
- int modes;
- int maps;
- int floors;
- int residues;
- int books;
- int psys; /* encode only */
-
- vorbis_info_mode *mode_param[64];
- int map_type[64];
- vorbis_info_mapping *map_param[64];
- int floor_type[64];
- vorbis_info_floor *floor_param[64];
- int residue_type[64];
- vorbis_info_residue *residue_param[64];
- static_codebook *book_param[256];
- codebook *fullbooks;
-
- vorbis_info_psy *psy_param[4]; /* encode only */
- vorbis_info_psy_global psy_g_param;
-
- bitrate_manager_info bi;
- highlevel_encode_setup hi; /* used only by vorbisenc.c. It's a
- highly redundant structure, but
- improves clarity of program flow. */
- int halfrate_flag; /* painless downsample for decode */
- } codec_setup_info;
-
- extern vorbis_look_psy_global *_vp_global_look(vorbis_info *vi);
- extern void _vp_global_free(vorbis_look_psy_global *look);
-
- #endif
- /********* End of inlined file: codec_internal.h *********/
-
- /********* Start of inlined file: registry.h *********/
- #ifndef _V_REG_H_
- #define _V_REG_H_
-
- #define VI_TRANSFORMB 1
- #define VI_WINDOWB 1
- #define VI_TIMEB 1
- #define VI_FLOORB 2
- #define VI_RESB 3
- #define VI_MAPB 1
-
- extern vorbis_func_floor *_floor_P[];
- extern vorbis_func_residue *_residue_P[];
- extern vorbis_func_mapping *_mapping_P[];
-
- #endif
- /********* End of inlined file: registry.h *********/
-
- /********* Start of inlined file: scales.h *********/
- #ifndef _V_SCALES_H_
- #define _V_SCALES_H_
-
- #include <math.h>
-
- /* 20log10(x) */
- #define VORBIS_IEEE_FLOAT32 1
- #ifdef VORBIS_IEEE_FLOAT32
-
- static float unitnorm(float x){
- union {
- ogg_uint32_t i;
- float f;
- } ix;
- ix.f = x;
- ix.i = (ix.i & 0x80000000U) | (0x3f800000U);
- return ix.f;
- }
-
- /* Segher was off (too high) by ~ .3 decibel. Center the conversion correctly. */
- static float todB(const float *x){
- union {
- ogg_uint32_t i;
- float f;
- } ix;
- ix.f = *x;
- ix.i = ix.i&0x7fffffff;
- return (float)(ix.i * 7.17711438e-7f -764.6161886f);
- }
-
- #define todB_nn(x) todB(x)
-
- #else
-
- static float unitnorm(float x){
- if(x<0)return(-1.f);
- return(1.f);
- }
-
- #define todB(x) (*(x)==0?-400.f:log(*(x)**(x))*4.34294480f)
- #define todB_nn(x) (*(x)==0.f?-400.f:log(*(x))*8.6858896f)
-
- #endif
-
- #define fromdB(x) (exp((x)*.11512925f))
-
- /* The bark scale equations are approximations, since the original
- table was somewhat hand rolled. The below are chosen to have the
- best possible fit to the rolled tables, thus their somewhat odd
- appearance (these are more accurate and over a longer range than
- the oft-quoted bark equations found in the texts I have). The
- approximations are valid from 0 - 30kHz (nyquist) or so.
-
- all f in Hz, z in Bark */
-
- #define toBARK(n) (13.1f*atan(.00074f*(n))+2.24f*atan((n)*(n)*1.85e-8f)+1e-4f*(n))
- #define fromBARK(z) (102.f*(z)-2.f*pow(z,2.f)+.4f*pow(z,3.f)+pow(1.46f,z)-1.f)
- #define toMEL(n) (log(1.f+(n)*.001f)*1442.695f)
- #define fromMEL(m) (1000.f*exp((m)/1442.695f)-1000.f)
-
- /* Frequency to octave. We arbitrarily declare 63.5 Hz to be octave
- 0.0 */
-
- #define toOC(n) (log(n)*1.442695f-5.965784f)
- #define fromOC(o) (exp(((o)+5.965784f)*.693147f))
-
- #endif
- /********* End of inlined file: scales.h *********/
-
- int analysis_noisy=1;
-
- /* decides between modes, dispatches to the appropriate mapping. */
- int vorbis_analysis(vorbis_block *vb, ogg_packet *op){
- int ret,i;
- vorbis_block_internal *vbi=(vorbis_block_internal *)vb->internal;
-
- vb->glue_bits=0;
- vb->time_bits=0;
- vb->floor_bits=0;
- vb->res_bits=0;
-
- /* first things first. Make sure encode is ready */
- for(i=0;i<PACKETBLOBS;i++)
- oggpack_reset(vbi->packetblob[i]);
-
- /* we only have one mapping type (0), and we let the mapping code
- itself figure out what soft mode to use. This allows easier
- bitrate management */
-
- if((ret=_mapping_P[0]->forward(vb)))
- return(ret);
-
- if(op){
- if(vorbis_bitrate_managed(vb))
- /* The app is using a bitmanaged mode... but not using the
- bitrate management interface. */
- return(OV_EINVAL);
-
- op->packet=oggpack_get_buffer(&vb->opb);
- op->bytes=oggpack_bytes(&vb->opb);
- op->b_o_s=0;
- op->e_o_s=vb->eofflag;
- op->granulepos=vb->granulepos;
- op->packetno=vb->sequence; /* for sake of completeness */
- }
- return(0);
- }
-
- /* there was no great place to put this.... */
- void _analysis_output_always(char *base,int i,float *v,int n,int bark,int dB,ogg_int64_t off){
- int j;
- FILE *of;
- char buffer[80];
-
- /* if(i==5870){*/
- sprintf(buffer,"%s_%d.m",base,i);
- of=fopen(buffer,"w");
-
- if(!of)perror("failed to open data dump file");
-
- for(j=0;j<n;j++){
- if(bark){
- float b=toBARK((4000.f*j/n)+.25);
- fprintf(of,"%f ",b);
- }else
- if(off!=0)
- fprintf(of,"%f ",(double)(j+off)/8000.);
- else
- fprintf(of,"%f ",(double)j);
-
- if(dB){
- float val;
- if(v[j]==0.)
- val=-140.;
- else
- val=todB(v+j);
- fprintf(of,"%f\n",val);
- }else{
- fprintf(of,"%f\n",v[j]);
- }
- }
- fclose(of);
- /* } */
- }
-
- void _analysis_output(char *base,int i,float *v,int n,int bark,int dB,
- ogg_int64_t off){
- if(analysis_noisy)_analysis_output_always(base,i,v,n,bark,dB,off);
- }
-
- #endif
- /********* End of inlined file: analysis.c *********/
-
- /********* Start of inlined file: bitrate.c *********/
-
- /********* Start of inlined file: juce_OggVorbisHeader.h *********/
- // This file is included at the start of each Ogg-Vorbis .c file, just to do a few housekeeping
- // tasks..
-
- #ifdef _MSC_VER
- #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4305 4189 4706)
- #endif
- /********* End of inlined file: juce_OggVorbisHeader.h *********/
-
- #if JUCE_USE_OGGVORBIS
-
- #include <stdlib.h>
- #include <string.h>
- #include <math.h>
-
- /* compute bitrate tracking setup */
- void vorbis_bitrate_init(vorbis_info *vi,bitrate_manager_state *bm){
- codec_setup_info *ci=(codec_setup_info *)vi->codec_setup;
- bitrate_manager_info *bi=&ci->bi;
-
- memset(bm,0,sizeof(*bm));
-
- if(bi && (bi->reservoir_bits>0)){
- long ratesamples=vi->rate;
- int halfsamples=ci->blocksizes[0]>>1;
-
- bm->short_per_long=ci->blocksizes[1]/ci->blocksizes[0];
- bm->managed=1;
-
- bm->avg_bitsper= rint(1.*bi->avg_rate*halfsamples/ratesamples);
- bm->min_bitsper= rint(1.*bi->min_rate*halfsamples/ratesamples);
- bm->max_bitsper= rint(1.*bi->max_rate*halfsamples/ratesamples);
-
- bm->avgfloat=PACKETBLOBS/2;
-
- /* not a necessary fix, but one that leads to a more balanced
- typical initialization */
- {
- long desired_fill=bi->reservoir_bits*bi->reservoir_bias;
- bm->minmax_reservoir=desired_fill;
- bm->avg_reservoir=desired_fill;
- }
-
- }
- }
-
- void vorbis_bitrate_clear(bitrate_manager_state *bm){
- memset(bm,0,sizeof(*bm));
- return;
- }
-
- int vorbis_bitrate_managed(vorbis_block *vb){
- vorbis_dsp_state *vd=vb->vd;
- private_state *b=(private_state*)vd->backend_state;
- bitrate_manager_state *bm=&b->bms;
-
- if(bm && bm->managed)return(1);
- return(0);
- }
-
- /* finish taking in the block we just processed */
- int vorbis_bitrate_addblock(vorbis_block *vb){
- vorbis_block_internal *vbi=(vorbis_block_internal*)vb->internal;
- vorbis_dsp_state *vd=vb->vd;
- private_state *b=(private_state*)vd->backend_state;
- bitrate_manager_state *bm=&b->bms;
- vorbis_info *vi=vd->vi;
- codec_setup_info *ci=(codec_setup_info*)vi->codec_setup;
- bitrate_manager_info *bi=&ci->bi;
-
- int choice=rint(bm->avgfloat);
- long this_bits=oggpack_bytes(vbi->packetblob[choice])*8;
- long min_target_bits=(vb->W?bm->min_bitsper*bm->short_per_long:bm->min_bitsper);
- long max_target_bits=(vb->W?bm->max_bitsper*bm->short_per_long:bm->max_bitsper);
- int samples=ci->blocksizes[vb->W]>>1;
- long desired_fill=bi->reservoir_bits*bi->reservoir_bias;
- if(!bm->managed){
- /* not a bitrate managed stream, but for API simplicity, we'll
- buffer the packet to keep the code path clean */
-
- if(bm->vb)return(-1); /* one has been submitted without
- being claimed */
- bm->vb=vb;
- return(0);
- }
-
- bm->vb=vb;
-
- /* look ahead for avg floater */
- if(bm->avg_bitsper>0){
- double slew=0.;
- long avg_target_bits=(vb->W?bm->avg_bitsper*bm->short_per_long:bm->avg_bitsper);
- double slewlimit= 15./bi->slew_damp;
-
- /* choosing a new floater:
- if we're over target, we slew down
- if we're under target, we slew up
-
- choose slew as follows: look through packetblobs of this frame
- and set slew as the first in the appropriate direction that
- gives us the slew we want. This may mean no slew if delta is
- already favorable.
-
- Then limit slew to slew max */
-
- if(bm->avg_reservoir+(this_bits-avg_target_bits)>desired_fill){
- while(choice>0 && this_bits>avg_target_bits &&
- bm->avg_reservoir+(this_bits-avg_target_bits)>desired_fill){
- choice--;
- this_bits=oggpack_bytes(vbi->packetblob[choice])*8;
- }
- }else if(bm->avg_reservoir+(this_bits-avg_target_bits)<desired_fill){
- while(choice+1<PACKETBLOBS && this_bits<avg_target_bits &&
- bm->avg_reservoir+(this_bits-avg_target_bits)<desired_fill){
- choice++;
- this_bits=oggpack_bytes(vbi->packetblob[choice])*8;
- }
- }
-
- slew=rint(choice-bm->avgfloat)/samples*vi->rate;
- if(slew<-slewlimit)slew=-slewlimit;
- if(slew>slewlimit)slew=slewlimit;
- choice=rint(bm->avgfloat+= slew/vi->rate*samples);
- this_bits=oggpack_bytes(vbi->packetblob[choice])*8;
- }
-
- /* enforce min(if used) on the current floater (if used) */
- if(bm->min_bitsper>0){
- /* do we need to force the bitrate up? */
- if(this_bits<min_target_bits){
- while(bm->minmax_reservoir-(min_target_bits-this_bits)<0){
- choice++;
- if(choice>=PACKETBLOBS)break;
- this_bits=oggpack_bytes(vbi->packetblob[choice])*8;
- }
- }
- }
-
- /* enforce max (if used) on the current floater (if used) */
- if(bm->max_bitsper>0){
- /* do we need to force the bitrate down? */
- if(this_bits>max_target_bits){
- while(bm->minmax_reservoir+(this_bits-max_target_bits)>bi->reservoir_bits){
- choice--;
- if(choice<0)break;
- this_bits=oggpack_bytes(vbi->packetblob[choice])*8;
- }
- }
- }
-
- /* Choice of packetblobs now made based on floater, and min/max
- requirements. Now boundary check extreme choices */
-
- if(choice<0){
- /* choosing a smaller packetblob is insufficient to trim bitrate.
- frame will need to be truncated */
- long maxsize=(max_target_bits+(bi->reservoir_bits-bm->minmax_reservoir))/8;
- bm->choice=choice=0;
-
- if(oggpack_bytes(vbi->packetblob[choice])>maxsize){
-
- oggpack_writetrunc(vbi->packetblob[choice],maxsize*8);
- this_bits=oggpack_bytes(vbi->packetblob[choice])*8;
- }
- }else{
- long minsize=(min_target_bits-bm->minmax_reservoir+7)/8;
- if(choice>=PACKETBLOBS)
- choice=PACKETBLOBS-1;
-
- bm->choice=choice;
-
- /* prop up bitrate according to demand. pad this frame out with zeroes */
- minsize-=oggpack_bytes(vbi->packetblob[choice]);
- while(minsize-->0)oggpack_write(vbi->packetblob[choice],0,8);
- this_bits=oggpack_bytes(vbi->packetblob[choice])*8;
-
- }
-
- /* now we have the final packet and the final packet size. Update statistics */
- /* min and max reservoir */
- if(bm->min_bitsper>0 || bm->max_bitsper>0){
-
- if(max_target_bits>0 && this_bits>max_target_bits){
- bm->minmax_reservoir+=(this_bits-max_target_bits);
- }else if(min_target_bits>0 && this_bits<min_target_bits){
- bm->minmax_reservoir+=(this_bits-min_target_bits);
- }else{
- /* inbetween; we want to take reservoir toward but not past desired_fill */
- if(bm->minmax_reservoir>desired_fill){
- if(max_target_bits>0){ /* logical bulletproofing against initialization state */
- bm->minmax_reservoir+=(this_bits-max_target_bits);
- if(bm->minmax_reservoir<desired_fill)bm->minmax_reservoir=desired_fill;
- }else{
- bm->minmax_reservoir=desired_fill;
- }
- }else{
- if(min_target_bits>0){ /* logical bulletproofing against initialization state */
- bm->minmax_reservoir+=(this_bits-min_target_bits);
- if(bm->minmax_reservoir>desired_fill)bm->minmax_reservoir=desired_fill;
- }else{
- bm->minmax_reservoir=desired_fill;
- }
- }
- }
- }
-
- /* avg reservoir */
- if(bm->avg_bitsper>0){
- long avg_target_bits=(vb->W?bm->avg_bitsper*bm->short_per_long:bm->avg_bitsper);
- bm->avg_reservoir+=this_bits-avg_target_bits;
- }
-
- return(0);
- }
-
- int vorbis_bitrate_flushpacket(vorbis_dsp_state *vd,ogg_packet *op){
- private_state *b=(private_state*)vd->backend_state;
- bitrate_manager_state *bm=&b->bms;
- vorbis_block *vb=bm->vb;
- int choice=PACKETBLOBS/2;
- if(!vb)return 0;
-
- if(op){
- vorbis_block_internal *vbi=(vorbis_block_internal*)vb->internal;
-
- if(vorbis_bitrate_managed(vb))
- choice=bm->choice;
-
- op->packet=oggpack_get_buffer(vbi->packetblob[choice]);
- op->bytes=oggpack_bytes(vbi->packetblob[choice]);
- op->b_o_s=0;
- op->e_o_s=vb->eofflag;
- op->granulepos=vb->granulepos;
- op->packetno=vb->sequence; /* for sake of completeness */
- }
-
- bm->vb=0;
- return(1);
- }
-
- #endif
- /********* End of inlined file: bitrate.c *********/
-
- /********* Start of inlined file: block.c *********/
-
- /********* Start of inlined file: juce_OggVorbisHeader.h *********/
- // This file is included at the start of each Ogg-Vorbis .c file, just to do a few housekeeping
- // tasks..
-
- #ifdef _MSC_VER
- #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4305 4189 4706)
- #endif
- /********* End of inlined file: juce_OggVorbisHeader.h *********/
-
- #if JUCE_USE_OGGVORBIS
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
-
- /********* Start of inlined file: window.h *********/
- #ifndef _V_WINDOW_
- #define _V_WINDOW_
-
- extern float *_vorbis_window_get(int n);
- extern void _vorbis_apply_window(float *d,int *winno,long *blocksizes,
- int lW,int W,int nW);
-
- #endif
- /********* End of inlined file: window.h *********/
-
- /********* Start of inlined file: lpc.h *********/
- #ifndef _V_LPC_H_
- #define _V_LPC_H_
-
- /* simple linear scale LPC code */
- extern float vorbis_lpc_from_data(float *data,float *lpc,int n,int m);
-
- extern void vorbis_lpc_predict(float *coeff,float *prime,int m,
- float *data,long n);
-
- #endif
- /********* End of inlined file: lpc.h *********/
-
- /* pcm accumulator examples (not exhaustive):
-
- <-------------- lW ---------------->
- <--------------- W ---------------->
- : .....|..... _______________ |
- : .''' | '''_--- | |\ |
- :.....''' |_____--- '''......| | \_______|
- :.................|__________________|_______|__|______|
- |<------ Sl ------>| > Sr < |endW
- |beginSl |endSl | |endSr
- |beginW |endlW |beginSr
-
- |< lW >|
- <--------------- W ---------------->
- | | .. ______________ |
- | | ' `/ | ---_ |
- |___.'___/`. | ---_____|
- |_______|__|_______|_________________|
- | >|Sl|< |<------ Sr ----->|endW
- | | |endSl |beginSr |endSr
- |beginW | |endlW
- mult[0] |beginSl mult[n]
-
- <-------------- lW ----------------->
- |<--W-->|
- : .............. ___ | |
- : .''' |`/ \ | |
- :.....''' |/`....\|...|
- :.........................|___|___|___|
- |Sl |Sr |endW
- | | |endSr
- | |beginSr
- | |endSl
- |beginSl
- |beginW
- */
-
- /* block abstraction setup *********************************************/
-
- #ifndef WORD_ALIGN
- #define WORD_ALIGN 8
- #endif
-
- int vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb){
- int i;
- memset(vb,0,sizeof(*vb));
- vb->vd=v;
- vb->localalloc=0;
- vb->localstore=NULL;
- if(v->analysisp){
- vorbis_block_internal *vbi=(vorbis_block_internal*)
- (vb->internal=(vorbis_block_internal*)_ogg_calloc(1,sizeof(vorbis_block_internal)));
- vbi->ampmax=-9999;
-
- for(i=0;i<PACKETBLOBS;i++){
- if(i==PACKETBLOBS/2){
- vbi->packetblob[i]=&vb->opb;
- }else{
- vbi->packetblob[i]=
- (oggpack_buffer*) _ogg_calloc(1,sizeof(oggpack_buffer));
- }
- oggpack_writeinit(vbi->packetblob[i]);
- }
- }
-
- return(0);
- }
-
- void *_vorbis_block_alloc(vorbis_block *vb,long bytes){
- bytes=(bytes+(WORD_ALIGN-1)) & ~(WORD_ALIGN-1);
- if(bytes+vb->localtop>vb->localalloc){
- /* can't just _ogg_realloc... there are outstanding pointers */
- if(vb->localstore){
- struct alloc_chain *link=(struct alloc_chain*)_ogg_malloc(sizeof(*link));
- vb->totaluse+=vb->localtop;
- link->next=vb->reap;
- link->ptr=vb->localstore;
- vb->reap=link;
- }
- /* highly conservative */
- vb->localalloc=bytes;
- vb->localstore=_ogg_malloc(vb->localalloc);
- vb->localtop=0;
- }
- {
- void *ret=(void *)(((char *)vb->localstore)+vb->localtop);
- vb->localtop+=bytes;
- return ret;
- }
- }
-
- /* reap the chain, pull the ripcord */
- void _vorbis_block_ripcord(vorbis_block *vb){
- /* reap the chain */
- struct alloc_chain *reap=vb->reap;
- while(reap){
- struct alloc_chain *next=reap->next;
- _ogg_free(reap->ptr);
- memset(reap,0,sizeof(*reap));
- _ogg_free(reap);
- reap=next;
- }
- /* consolidate storage */
- if(vb->totaluse){
- vb->localstore=_ogg_realloc(vb->localstore,vb->totaluse+vb->localalloc);
- vb->localalloc+=vb->totaluse;
- vb->totaluse=0;
- }
-
- /* pull the ripcord */
- vb->localtop=0;
- vb->reap=NULL;
- }
-
- int vorbis_block_clear(vorbis_block *vb){
- int i;
- vorbis_block_internal *vbi=(vorbis_block_internal*)vb->internal;
-
- _vorbis_block_ripcord(vb);
- if(vb->localstore)_ogg_free(vb->localstore);
-
- if(vbi){
- for(i=0;i<PACKETBLOBS;i++){
- oggpack_writeclear(vbi->packetblob[i]);
- if(i!=PACKETBLOBS/2)_ogg_free(vbi->packetblob[i]);
- }
- _ogg_free(vbi);
- }
- memset(vb,0,sizeof(*vb));
- return(0);
- }
-
- /* Analysis side code, but directly related to blocking. Thus it's
- here and not in analysis.c (which is for analysis transforms only).
- The init is here because some of it is shared */
-
- static int _vds_shared_init(vorbis_dsp_state *v,vorbis_info *vi,int encp){
- int i;
- codec_setup_info *ci=(codec_setup_info*)vi->codec_setup;
- private_state *b=NULL;
- int hs;
-
- if(ci==NULL) return 1;
- hs=ci->halfrate_flag;
-
- memset(v,0,sizeof(*v));
- b=(private_state*) (v->backend_state=(private_state*)_ogg_calloc(1,sizeof(*b)));
-
- v->vi=vi;
- b->modebits=ilog2(ci->modes);
-
- b->transform[0]=(vorbis_look_transform**)_ogg_calloc(VI_TRANSFORMB,sizeof(*b->transform[0]));
- b->transform[1]=(vorbis_look_transform**)_ogg_calloc(VI_TRANSFORMB,sizeof(*b->transform[1]));
-
- /* MDCT is tranform 0 */
-
- b->transform[0][0]=_ogg_calloc(1,sizeof(mdct_lookup));
- b->transform[1][0]=_ogg_calloc(1,sizeof(mdct_lookup));
- mdct_init((mdct_lookup*)b->transform[0][0],ci->blocksizes[0]>>hs);
- mdct_init((mdct_lookup*)b->transform[1][0],ci->blocksizes[1]>>hs);
-
- /* Vorbis I uses only window type 0 */
- b->window[0]=ilog2(ci->blocksizes[0])-6;
- b->window[1]=ilog2(ci->blocksizes[1])-6;
-
- if(encp){ /* encode/decode differ here */
-
- /* analysis always needs an fft */
- drft_init(&b->fft_look[0],ci->blocksizes[0]);
- drft_init(&b->fft_look[1],ci->blocksizes[1]);
-
- /* finish the codebooks */
- if(!ci->fullbooks){
- ci->fullbooks=(codebook*) _ogg_calloc(ci->books,sizeof(*ci->fullbooks));
- for(i=0;i<ci->books;i++)
- vorbis_book_init_encode(ci->fullbooks+i,ci->book_param[i]);
- }
-
- b->psy=(vorbis_look_psy*)_ogg_calloc(ci->psys,sizeof(*b->psy));
- for(i=0;i<ci->psys;i++){
- _vp_psy_init(b->psy+i,
- ci->psy_param[i],
- &ci->psy_g_param,
- ci->blocksizes[ci->psy_param[i]->blockflag]/2,
- vi->rate);
- }
-
- v->analysisp=1;
- }else{
- /* finish the codebooks */
- if(!ci->fullbooks){
- ci->fullbooks=(codebook*) _ogg_calloc(ci->books,sizeof(*ci->fullbooks));
- for(i=0;i<ci->books;i++){
- vorbis_book_init_decode(ci->fullbooks+i,ci->book_param[i]);
- /* decode codebooks are now standalone after init */
- vorbis_staticbook_destroy(ci->book_param[i]);
- ci->book_param[i]=NULL;
- }
- }
- }
-
- /* initialize the storage vectors. blocksize[1] is small for encode,
- but the correct size for decode */
- v->pcm_storage=ci->blocksizes[1];
- v->pcm=(float**)_ogg_malloc(vi->channels*sizeof(*v->pcm));
- v->pcmret=(float**)_ogg_malloc(vi->channels*sizeof(*v->pcmret));
- {
- int i;
- for(i=0;i<vi->channels;i++)
- v->pcm[i]=(float*)_ogg_calloc(v->pcm_storage,sizeof(*v->pcm[i]));
- }
-
- /* all 1 (large block) or 0 (small block) */
- /* explicitly set for the sake of clarity */
- v->lW=0; /* previous window size */
- v->W=0; /* current window size */
-
- /* all vector indexes */
- v->centerW=ci->blocksizes[1]/2;
-
- v->pcm_current=v->centerW;
-
- /* initialize all the backend lookups */
- b->flr=(vorbis_look_floor**)_ogg_calloc(ci->floors,sizeof(*b->flr));
- b->residue=(vorbis_look_residue**)_ogg_calloc(ci->residues,sizeof(*b->residue));
-
- for(i=0;i<ci->floors;i++)
- b->flr[i]=_floor_P[ci->floor_type[i]]->
- look(v,ci->floor_param[i]);
-
- for(i=0;i<ci->residues;i++)
- b->residue[i]=_residue_P[ci->residue_type[i]]->
- look(v,ci->residue_param[i]);
-
- return 0;
- }
-
- /* arbitrary settings and spec-mandated numbers get filled in here */
- int vorbis_analysis_init(vorbis_dsp_state *v,vorbis_info *vi){
- private_state *b=NULL;
-
- if(_vds_shared_init(v,vi,1))return 1;
- b=(private_state*)v->backend_state;
- b->psy_g_look=_vp_global_look(vi);
-
- /* Initialize the envelope state storage */
- b->ve=(envelope_lookup*)_ogg_calloc(1,sizeof(*b->ve));
- _ve_envelope_init(b->ve,vi);
-
- vorbis_bitrate_init(vi,&b->bms);
-
- /* compressed audio packets start after the headers
- with sequence number 3 */
- v->sequence=3;
-
- return(0);
- }
-
- void vorbis_dsp_clear(vorbis_dsp_state *v){
- int i;
- if(v){
- vorbis_info *vi=v->vi;
- codec_setup_info *ci=(codec_setup_info*)(vi?vi->codec_setup:NULL);
- private_state *b=(private_state*)v->backend_state;
-
- if(b){
-
- if(b->ve){
- _ve_envelope_clear(b->ve);
- _ogg_free(b->ve);
- }
-
- if(b->transform[0]){
- mdct_clear((mdct_lookup*) b->transform[0][0]);
- _ogg_free(b->transform[0][0]);
- _ogg_free(b->transform[0]);
- }
- if(b->transform[1]){
- mdct_clear((mdct_lookup*) b->transform[1][0]);
- _ogg_free(b->transform[1][0]);
- _ogg_free(b->transform[1]);
- }
-
- if(b->flr){
- for(i=0;i<ci->floors;i++)
- _floor_P[ci->floor_type[i]]->
- free_look(b->flr[i]);
- _ogg_free(b->flr);
- }
- if(b->residue){
- for(i=0;i<ci->residues;i++)
- _residue_P[ci->residue_type[i]]->
- free_look(b->residue[i]);
- _ogg_free(b->residue);
- }
- if(b->psy){
- for(i=0;i<ci->psys;i++)
- _vp_psy_clear(b->psy+i);
- _ogg_free(b->psy);
- }
-
- if(b->psy_g_look)_vp_global_free(b->psy_g_look);
- vorbis_bitrate_clear(&b->bms);
-
- drft_clear(&b->fft_look[0]);
- drft_clear(&b->fft_look[1]);
-
- }
-
- if(v->pcm){
- for(i=0;i<vi->channels;i++)
- if(v->pcm[i])_ogg_free(v->pcm[i]);
- _ogg_free(v->pcm);
- if(v->pcmret)_ogg_free(v->pcmret);
- }
-
- if(b){
- /* free header, header1, header2 */
- if(b->header)_ogg_free(b->header);
- if(b->header1)_ogg_free(b->header1);
- if(b->header2)_ogg_free(b->header2);
- _ogg_free(b);
- }
-
- memset(v,0,sizeof(*v));
- }
- }
-
- float **vorbis_analysis_buffer(vorbis_dsp_state *v, int vals){
- int i;
- vorbis_info *vi=v->vi;
- private_state *b=(private_state*)v->backend_state;
-
- /* free header, header1, header2 */
- if(b->header)_ogg_free(b->header);b->header=NULL;
- if(b->header1)_ogg_free(b->header1);b->header1=NULL;
- if(b->header2)_ogg_free(b->header2);b->header2=NULL;
-
- /* Do we have enough storage space for the requested buffer? If not,
- expand the PCM (and envelope) storage */
-
- if(v->pcm_current+vals>=v->pcm_storage){
- v->pcm_storage=v->pcm_current+vals*2;
-
- for(i=0;i<vi->channels;i++){
- v->pcm[i]=(float*)_ogg_realloc(v->pcm[i],v->pcm_storage*sizeof(*v->pcm[i]));
- }
- }
-
- for(i=0;i<vi->channels;i++)
- v->pcmret[i]=v->pcm[i]+v->pcm_current;
-
- return(v->pcmret);
- }
-
- static void _preextrapolate_helper(vorbis_dsp_state *v){
- int i;
- int order=32;
- float *lpc=(float*)alloca(order*sizeof(*lpc));
- float *work=(float*)alloca(v->pcm_current*sizeof(*work));
- long j;
- v->preextrapolate=1;
-
- if(v->pcm_current-v->centerW>order*2){ /* safety */
- for(i=0;i<v->vi->channels;i++){
- /* need to run the extrapolation in reverse! */
- for(j=0;j<v->pcm_current;j++)
- work[j]=v->pcm[i][v->pcm_current-j-1];
-
- /* prime as above */
- vorbis_lpc_from_data(work,lpc,v->pcm_current-v->centerW,order);
-
- /* run the predictor filter */
- vorbis_lpc_predict(lpc,work+v->pcm_current-v->centerW-order,
- order,
- work+v->pcm_current-v->centerW,
- v->centerW);
-
- for(j=0;j<v->pcm_current;j++)
- v->pcm[i][v->pcm_current-j-1]=work[j];
-
- }
- }
- }
-
- /* call with val<=0 to set eof */
-
- int vorbis_analysis_wrote(vorbis_dsp_state *v, int vals){
- vorbis_info *vi=v->vi;
- codec_setup_info *ci=(codec_setup_info*)vi->codec_setup;
-
- if(vals<=0){
- int order=32;
- int i;
- float *lpc=(float*) alloca(order*sizeof(*lpc));
-
- /* if it wasn't done earlier (very short sample) */
- if(!v->preextrapolate)
- _preextrapolate_helper(v);
-
- /* We're encoding the end of the stream. Just make sure we have
- [at least] a few full blocks of zeroes at the end. */
- /* actually, we don't want zeroes; that could drop a large
- amplitude off a cliff, creating spread spectrum noise that will
- suck to encode. Extrapolate for the sake of cleanliness. */
-
- vorbis_analysis_buffer(v,ci->blocksizes[1]*3);
- v->eofflag=v->pcm_current;
- v->pcm_current+=ci->blocksizes[1]*3;
-
- for(i=0;i<vi->channels;i++){
- if(v->eofflag>order*2){
- /* extrapolate with LPC to fill in */
- long n;
-
- /* make a predictor filter */
- n=v->eofflag;
- if(n>ci->blocksizes[1])n=ci->blocksizes[1];
- vorbis_lpc_from_data(v->pcm[i]+v->eofflag-n,lpc,n,order);
-
- /* run the predictor filter */
- vorbis_lpc_predict(lpc,v->pcm[i]+v->eofflag-order,order,
- v->pcm[i]+v->eofflag,v->pcm_current-v->eofflag);
- }else{
- /* not enough data to extrapolate (unlikely to happen due to
- guarding the overlap, but bulletproof in case that
- assumtion goes away). zeroes will do. */
- memset(v->pcm[i]+v->eofflag,0,
- (v->pcm_current-v->eofflag)*sizeof(*v->pcm[i]));
-
- }
- }
- }else{
-
- if(v->pcm_current+vals>v->pcm_storage)
- return(OV_EINVAL);
-
- v->pcm_current+=vals;
-
- /* we may want to reverse extrapolate the beginning of a stream
- too... in case we're beginning on a cliff! */
- /* clumsy, but simple. It only runs once, so simple is good. */
- if(!v->preextrapolate && v->pcm_current-v->centerW>ci->blocksizes[1])
- _preextrapolate_helper(v);
-
- }
- return(0);
- }
-
- /* do the deltas, envelope shaping, pre-echo and determine the size of
- the next block on which to continue analysis */
- int vorbis_analysis_blockout(vorbis_dsp_state *v,vorbis_block *vb){
- int i;
- vorbis_info *vi=v->vi;
- codec_setup_info *ci=(codec_setup_info*)vi->codec_setup;
- private_state *b=(private_state*)v->backend_state;
- vorbis_look_psy_global *g=b->psy_g_look;
- long beginW=v->centerW-ci->blocksizes[v->W]/2,centerNext;
- vorbis_block_internal *vbi=(vorbis_block_internal *)vb->internal;
-
- /* check to see if we're started... */
- if(!v->preextrapolate)return(0);
-
- /* check to see if we're done... */
- if(v->eofflag==-1)return(0);
-
- /* By our invariant, we have lW, W and centerW set. Search for
- the next boundary so we can determine nW (the next window size)
- which lets us compute the shape of the current block's window */
-
- /* we do an envelope search even on a single blocksize; we may still
- be throwing more bits at impulses, and envelope search handles
- marking impulses too. */
- {
- long bp=_ve_envelope_search(v);
- if(bp==-1){
-
- if(v->eofflag==0)return(0); /* not enough data currently to search for a
- full long block */
- v->nW=0;
- }else{
-
- if(ci->blocksizes[0]==ci->blocksizes[1])
- v->nW=0;
- else
- v->nW=bp;
- }
- }
-
- centerNext=v->centerW+ci->blocksizes[v->W]/4+ci->blocksizes[v->nW]/4;
-
- {
- /* center of next block + next block maximum right side. */
-
- long blockbound=centerNext+ci->blocksizes[v->nW]/2;
- if(v->pcm_current<blockbound)return(0); /* not enough data yet;
- although this check is
- less strict that the
- _ve_envelope_search,
- the search is not run
- if we only use one
- block size */
-
- }
-
- /* fill in the block. Note that for a short window, lW and nW are *short*
- regardless of actual settings in the stream */
-
- _vorbis_block_ripcord(vb);
- vb->lW=v->lW;
- vb->W=v->W;
- vb->nW=v->nW;
-
- if(v->W){
- if(!v->lW || !v->nW){
- vbi->blocktype=BLOCKTYPE_TRANSITION;
- /*fprintf(stderr,"-");*/
- }else{
- vbi->blocktype=BLOCKTYPE_LONG;
- /*fprintf(stderr,"_");*/
- }
- }else{
- if(_ve_envelope_mark(v)){
- vbi->blocktype=BLOCKTYPE_IMPULSE;
- /*fprintf(stderr,"|");*/
-
- }else{
- vbi->blocktype=BLOCKTYPE_PADDING;
- /*fprintf(stderr,".");*/
-
- }
- }
-
- vb->vd=v;
- vb->sequence=v->sequence++;
- vb->granulepos=v->granulepos;
- vb->pcmend=ci->blocksizes[v->W];
-
- /* copy the vectors; this uses the local storage in vb */
-
- /* this tracks 'strongest peak' for later psychoacoustics */
- /* moved to the global psy state; clean this mess up */
- if(vbi->ampmax>g->ampmax)g->ampmax=vbi->ampmax;
- g->ampmax=_vp_ampmax_decay(g->ampmax,v);
- vbi->ampmax=g->ampmax;
-
- vb->pcm=(float**)_vorbis_block_alloc(vb,sizeof(*vb->pcm)*vi->channels);
- vbi->pcmdelay=(float**)_vorbis_block_alloc(vb,sizeof(*vbi->pcmdelay)*vi->channels);
- for(i=0;i<vi->channels;i++){
- vbi->pcmdelay[i]=
- (float*) _vorbis_block_alloc(vb,(vb->pcmend+beginW)*sizeof(*vbi->pcmdelay[i]));
- memcpy(vbi->pcmdelay[i],v->pcm[i],(vb->pcmend+beginW)*sizeof(*vbi->pcmdelay[i]));
- vb->pcm[i]=vbi->pcmdelay[i]+beginW;
-
- /* before we added the delay
- vb->pcm[i]=_vorbis_block_alloc(vb,vb->pcmend*sizeof(*vb->pcm[i]));
- memcpy(vb->pcm[i],v->pcm[i]+beginW,ci->blocksizes[v->W]*sizeof(*vb->pcm[i]));
- */
-
- }
-
- /* handle eof detection: eof==0 means that we've not yet received EOF
- eof>0 marks the last 'real' sample in pcm[]
- eof<0 'no more to do'; doesn't get here */
-
- if(v->eofflag){
- if(v->centerW>=v->eofflag){
- v->eofflag=-1;
- vb->eofflag=1;
- return(1);
- }
- }
-
- /* advance storage vectors and clean up */
- {
- int new_centerNext=ci->blocksizes[1]/2;
- int movementW=centerNext-new_centerNext;
-
- if(movementW>0){
-
- _ve_envelope_shift(b->ve,movementW);
- v->pcm_current-=movementW;
-
- for(i=0;i<vi->channels;i++)
- memmove(v->pcm[i],v->pcm[i]+movementW,
- v->pcm_current*sizeof(*v->pcm[i]));
-
- v->lW=v->W;
- v->W=v->nW;
- v->centerW=new_centerNext;
-
- if(v->eofflag){
- v->eofflag-=movementW;
- if(v->eofflag<=0)v->eofflag=-1;
- /* do not add padding to end of stream! */
- if(v->centerW>=v->eofflag){
- v->granulepos+=movementW-(v->centerW-v->eofflag);
- }else{
- v->granulepos+=movementW;
- }
- }else{
- v->granulepos+=movementW;
- }
- }
- }
-
- /* done */
- return(1);
- }
-
- int vorbis_synthesis_restart(vorbis_dsp_state *v){
- vorbis_info *vi=v->vi;
- codec_setup_info *ci;
- int hs;
-
- if(!v->backend_state)return -1;
- if(!vi)return -1;
- ci=(codec_setup_info*) vi->codec_setup;
- if(!ci)return -1;
- hs=ci->halfrate_flag;
-
- v->centerW=ci->blocksizes[1]>>(hs+1);
- v->pcm_current=v->centerW>>hs;
-
- v->pcm_returned=-1;
- v->granulepos=-1;
- v->sequence=-1;
- v->eofflag=0;
- ((private_state *)(v->backend_state))->sample_count=-1;
-
- return(0);
- }
-
- int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi){
- if(_vds_shared_init(v,vi,0)) return 1;
- vorbis_synthesis_restart(v);
-
- return 0;
- }
-
- /* Unlike in analysis, the window is only partially applied for each
- block. The time domain envelope is not yet handled at the point of
- calling (as it relies on the previous block). */
-
- int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){
- vorbis_info *vi=v->vi;
- codec_setup_info *ci=(codec_setup_info*)vi->codec_setup;
- private_state *b=(private_state*)v->backend_state;
- int hs=ci->halfrate_flag;
- int i,j;
-
- if(!vb)return(OV_EINVAL);
- if(v->pcm_current>v->pcm_returned && v->pcm_returned!=-1)return(OV_EINVAL);
-
- v->lW=v->W;
- v->W=vb->W;
- v->nW=-1;
-
- if((v->sequence==-1)||
- (v->sequence+1 != vb->sequence)){
- v->granulepos=-1; /* out of sequence; lose count */
- b->sample_count=-1;
- }
-
- v->sequence=vb->sequence;
-
- if(vb->pcm){ /* no pcm to process if vorbis_synthesis_trackonly
- was called on block */
- int n=ci->blocksizes[v->W]>>(hs+1);
- int n0=ci->blocksizes[0]>>(hs+1);
- int n1=ci->blocksizes[1]>>(hs+1);
-
- int thisCenter;
- int prevCenter;
-
- v->glue_bits+=vb->glue_bits;
- v->time_bits+=vb->time_bits;
- v->floor_bits+=vb->floor_bits;
- v->res_bits+=vb->res_bits;
-
- if(v->centerW){
- thisCenter=n1;
- prevCenter=0;
- }else{
- thisCenter=0;
- prevCenter=n1;
- }
-
- /* v->pcm is now used like a two-stage double buffer. We don't want
- to have to constantly shift *or* adjust memory usage. Don't
- accept a new block until the old is shifted out */
-
- for(j=0;j<vi->channels;j++){
- /* the overlap/add section */
- if(v->lW){
- if(v->W){
- /* large/large */
- float *w=_vorbis_window_get(b->window[1]-hs);
- float *pcm=v->pcm[j]+prevCenter;
- float *p=vb->pcm[j];
- for(i=0;i<n1;i++)
- pcm[i]=pcm[i]*w[n1-i-1] + p[i]*w[i];
- }else{
- /* large/small */
- float *w=_vorbis_window_get(b->window[0]-hs);
- float *pcm=v->pcm[j]+prevCenter+n1/2-n0/2;
- float *p=vb->pcm[j];
- for(i=0;i<n0;i++)
- pcm[i]=pcm[i]*w[n0-i-1] +p[i]*w[i];
- }
- }else{
- if(v->W){
- /* small/large */
- float *w=_vorbis_window_get(b->window[0]-hs);
- float *pcm=v->pcm[j]+prevCenter;
- float *p=vb->pcm[j]+n1/2-n0/2;
- for(i=0;i<n0;i++)
- pcm[i]=pcm[i]*w[n0-i-1] +p[i]*w[i];
- for(;i<n1/2+n0/2;i++)
- pcm[i]=p[i];
- }else{
- /* small/small */
- float *w=_vorbis_window_get(b->window[0]-hs);
- float *pcm=v->pcm[j]+prevCenter;
- float *p=vb->pcm[j];
- for(i=0;i<n0;i++)
- pcm[i]=pcm[i]*w[n0-i-1] +p[i]*w[i];
- }
- }
-
- /* the copy section */
- {
- float *pcm=v->pcm[j]+thisCenter;
- float *p=vb->pcm[j]+n;
- for(i=0;i<n;i++)
- pcm[i]=p[i];
- }
- }
-
- if(v->centerW)
- v->centerW=0;
- else
- v->centerW=n1;
-
- /* deal with initial packet state; we do this using the explicit
- pcm_returned==-1 flag otherwise we're sensitive to first block
- being short or long */
-
- if(v->pcm_returned==-1){
- v->pcm_returned=thisCenter;
- v->pcm_current=thisCenter;
- }else{
- v->pcm_returned=prevCenter;
- v->pcm_current=prevCenter+
- ((ci->blocksizes[v->lW]/4+
- ci->blocksizes[v->W]/4)>>hs);
- }
-
- }
-
- /* track the frame number... This is for convenience, but also
- making sure our last packet doesn't end with added padding. If
- the last packet is partial, the number of samples we'll have to
- return will be past the vb->granulepos.
-
- This is not foolproof! It will be confused if we begin
- decoding at the last page after a seek or hole. In that case,
- we don't have a starting point to judge where the last frame
- is. For this reason, vorbisfile will always try to make sure
- it reads the last two marked pages in proper sequence */
-
- if(b->sample_count==-1){
- b->sample_count=0;
- }else{
- b->sample_count+=ci->blocksizes[v->lW]/4+ci->blocksizes[v->W]/4;
- }
-
- if(v->granulepos==-1){
- if(vb->granulepos!=-1){ /* only set if we have a position to set to */
-
- v->granulepos=vb->granulepos;
-
- /* is this a short page? */
- if(b->sample_count>v->granulepos){
- /* corner case; if this is both the first and last audio page,
- then spec says the end is cut, not beginning */
- if(vb->eofflag){
- /* trim the end */
- /* no preceeding granulepos; assume we started at zero (we'd
- have to in a short single-page stream) */
- /* granulepos could be -1 due to a seek, but that would result
- in a long count, not short count */
-
- v->pcm_current-=(b->sample_count-v->granulepos)>>hs;
- }else{
- /* trim the beginning */
- v->pcm_returned+=(b->sample_count-v->granulepos)>>hs;
- if(v->pcm_returned>v->pcm_current)
- v->pcm_returned=v->pcm_current;
- }
-
- }
-
- }
- }else{
- v->granulepos+=ci->blocksizes[v->lW]/4+ci->blocksizes[v->W]/4;
- if(vb->granulepos!=-1 && v->granulepos!=vb->granulepos){
-
- if(v->granulepos>vb->granulepos){
- long extra=v->granulepos-vb->granulepos;
-
- if(extra)
- if(vb->eofflag){
- /* partial last frame. Strip the extra samples off */
- v->pcm_current-=extra>>hs;
- } /* else {Shouldn't happen *unless* the bitstream is out of
- spec. Either way, believe the bitstream } */
- } /* else {Shouldn't happen *unless* the bitstream is out of
- spec. Either way, believe the bitstream } */
- v->granulepos=vb->granulepos;
- }
- }
-
- /* Update, cleanup */
-
- if(vb->eofflag)v->eofflag=1;
- return(0);
-
- }
-
- /* pcm==NULL indicates we just want the pending samples, no more */
- int vorbis_synthesis_pcmout(vorbis_dsp_state *v,float ***pcm){
- vorbis_info *vi=v->vi;
-
- if(v->pcm_returned>-1 && v->pcm_returned<v->pcm_current){
- if(pcm){
- int i;
- for(i=0;i<vi->channels;i++)
- v->pcmret[i]=v->pcm[i]+v->pcm_returned;
- *pcm=v->pcmret;
- }
- return(v->pcm_current-v->pcm_returned);
- }
- return(0);
- }
-
- int vorbis_synthesis_read(vorbis_dsp_state *v,int n){
- if(n && v->pcm_returned+n>v->pcm_current)return(OV_EINVAL);
- v->pcm_returned+=n;
- return(0);
- }
-
- /* intended for use with a specific vorbisfile feature; we want access
- to the [usually synthetic/postextrapolated] buffer and lapping at
- the end of a decode cycle, specifically, a half-short-block worth.
- This funtion works like pcmout above, except it will also expose
- this implicit buffer data not normally decoded. */
- int vorbis_synthesis_lapout(vorbis_dsp_state *v,float ***pcm){
- vorbis_info *vi=v->vi;
- codec_setup_info *ci=(codec_setup_info *)vi->codec_setup;
- int hs=ci->halfrate_flag;
-
- int n=ci->blocksizes[v->W]>>(hs+1);
- int n0=ci->blocksizes[0]>>(hs+1);
- int n1=ci->blocksizes[1]>>(hs+1);
- int i,j;
-
- if(v->pcm_returned<0)return 0;
-
- /* our returned data ends at pcm_returned; because the synthesis pcm
- buffer is a two-fragment ring, that means our data block may be
- fragmented by buffering, wrapping or a short block not filling
- out a buffer. To simplify things, we unfragment if it's at all
- possibly needed. Otherwise, we'd need to call lapout more than
- once as well as hold additional dsp state. Opt for
- simplicity. */
-
- /* centerW was advanced by blockin; it would be the center of the
- *next* block */
- if(v->centerW==n1){
- /* the data buffer wraps; swap the halves */
- /* slow, sure, small */
- for(j=0;j<vi->channels;j++){
- float *p=v->pcm[j];
- for(i=0;i<n1;i++){
- float temp=p[i];
- p[i]=p[i+n1];
- p[i+n1]=temp;
- }
- }
-
- v->pcm_current-=n1;
- v->pcm_returned-=n1;
- v->centerW=0;
- }
-
- /* solidify buffer into contiguous space */
- if((v->lW^v->W)==1){
- /* long/short or short/long */
- for(j=0;j<vi->channels;j++){
- float *s=v->pcm[j];
- float *d=v->pcm[j]+(n1-n0)/2;
- for(i=(n1+n0)/2-1;i>=0;--i)
- d[i]=s[i];
- }
- v->pcm_returned+=(n1-n0)/2;
- v->pcm_current+=(n1-n0)/2;
- }else{
- if(v->lW==0){
- /* short/short */
- for(j=0;j<vi->channels;j++){
- float *s=v->pcm[j];
- float *d=v->pcm[j]+n1-n0;
- for(i=n0-1;i>=0;--i)
- d[i]=s[i];
- }
- v->pcm_returned+=n1-n0;
- v->pcm_current+=n1-n0;
- }
- }
-
- if(pcm){
- int i;
- for(i=0;i<vi->channels;i++)
- v->pcmret[i]=v->pcm[i]+v->pcm_returned;
- *pcm=v->pcmret;
- }
-
- return(n1+n-v->pcm_returned);
-
- }
-
- float *vorbis_window(vorbis_dsp_state *v,int W){
- vorbis_info *vi=v->vi;
- codec_setup_info *ci=(codec_setup_info*) vi->codec_setup;
- int hs=ci->halfrate_flag;
- private_state *b=(private_state*)v->backend_state;
-
- if(b->window[W]-1<0)return NULL;
- return _vorbis_window_get(b->window[W]-hs);
- }
-
- #endif
- /********* End of inlined file: block.c *********/
-
- /********* Start of inlined file: codebook.c *********/
-
- /********* Start of inlined file: juce_OggVorbisHeader.h *********/
- // This file is included at the start of each Ogg-Vorbis .c file, just to do a few housekeeping
- // tasks..
-
- #ifdef _MSC_VER
- #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4305 4189 4706)
- #endif
- /********* End of inlined file: juce_OggVorbisHeader.h *********/
-
- #if JUCE_USE_OGGVORBIS
-
- #include <stdlib.h>
- #include <string.h>
- #include <math.h>
-
- /* packs the given codebook into the bitstream **************************/
-
- int vorbis_staticbook_pack(const static_codebook *c,oggpack_buffer *opb){
- long i,j;
- int ordered=0;
-
- /* first the basic parameters */
- oggpack_write(opb,0x564342,24);
- oggpack_write(opb,c->dim,16);
- oggpack_write(opb,c->entries,24);
-
- /* pack the codewords. There are two packings; length ordered and
- length random. Decide between the two now. */
-
- for(i=1;i<c->entries;i++)
- if(c->lengthlist[i-1]==0 || c->lengthlist[i]<c->lengthlist[i-1])break;
- if(i==c->entries)ordered=1;
-
- if(ordered){
- /* length ordered. We only need to say how many codewords of
- each length. The actual codewords are generated
- deterministically */
-
- long count=0;
- oggpack_write(opb,1,1); /* ordered */
- oggpack_write(opb,c->lengthlist[0]-1,5); /* 1 to 32 */
-
- for(i=1;i<c->entries;i++){
- long thisx=c->lengthlist[i];
- long last=c->lengthlist[i-1];
- if(thisx>last){
- for(j=last;j<thisx;j++){
- oggpack_write(opb,i-count,_ilog(c->entries-count));
- count=i;
- }
- }
- }
- oggpack_write(opb,i-count,_ilog(c->entries-count));
-
- }else{
- /* length random. Again, we don't code the codeword itself, just
- the length. This time, though, we have to encode each length */
- oggpack_write(opb,0,1); /* unordered */
-
- /* algortihmic mapping has use for 'unused entries', which we tag
- here. The algorithmic mapping happens as usual, but the unused
- entry has no codeword. */
- for(i=0;i<c->entries;i++)
- if(c->lengthlist[i]==0)break;
-
- if(i==c->entries){
- oggpack_write(opb,0,1); /* no unused entries */
- for(i=0;i<c->entries;i++)
- oggpack_write(opb,c->lengthlist[i]-1,5);
- }else{
- oggpack_write(opb,1,1); /* we have unused entries; thus we tag */
- for(i=0;i<c->entries;i++){
- if(c->lengthlist[i]==0){
- oggpack_write(opb,0,1);
- }else{
- oggpack_write(opb,1,1);
- oggpack_write(opb,c->lengthlist[i]-1,5);
- }
- }
- }
- }
-
- /* is the entry number the desired return value, or do we have a
- mapping? If we have a mapping, what type? */
- oggpack_write(opb,c->maptype,4);
- switch(c->maptype){
- case 0:
- /* no mapping */
- break;
- case 1:case 2:
- /* implicitly populated value mapping */
- /* explicitly populated value mapping */
-
- if(!c->quantlist){
- /* no quantlist? error */
- return(-1);
- }
-
- /* values that define the dequantization */
- oggpack_write(opb,c->q_min,32);
- oggpack_write(opb,c->q_delta,32);
- oggpack_write(opb,c->q_quant-1,4);
- oggpack_write(opb,c->q_sequencep,1);
-
- {
- int quantvals;
- switch(c->maptype){
- case 1:
- /* a single column of (c->entries/c->dim) quantized values for
- building a full value list algorithmically (square lattice) */
- quantvals=_book_maptype1_quantvals(c);
- break;
- case 2:
- /* every value (c->entries*c->dim total) specified explicitly */
- quantvals=c->entries*c->dim;
- break;
- default: /* NOT_REACHABLE */
- quantvals=-1;
- }
-
- /* quantized values */
- for(i=0;i<quantvals;i++)
- oggpack_write(opb,labs(c->quantlist[i]),c->q_quant);
-
- }
- break;
- default:
- /* error case; we don't have any other map types now */
- return(-1);
- }
-
- return(0);
- }
-
- /* unpacks a codebook from the packet buffer into the codebook struct,
- readies the codebook auxiliary structures for decode *************/
- int vorbis_staticbook_unpack(oggpack_buffer *opb,static_codebook *s){
- long i,j;
- memset(s,0,sizeof(*s));
- s->allocedp=1;
-
- /* make sure alignment is correct */
- if(oggpack_read(opb,24)!=0x564342)goto _eofout;
-
- /* first the basic parameters */
- s->dim=oggpack_read(opb,16);
- s->entries=oggpack_read(opb,24);
- if(s->entries==-1)goto _eofout;
-
- /* codeword ordering.... length ordered or unordered? */
- switch((int)oggpack_read(opb,1)){
- case 0:
- /* unordered */
- s->lengthlist=(long*)_ogg_malloc(sizeof(*s->lengthlist)*s->entries);
-
- /* allocated but unused entries? */
- if(oggpack_read(opb,1)){
- /* yes, unused entries */
-
- for(i=0;i<s->entries;i++){
- if(oggpack_read(opb,1)){
- long num=oggpack_read(opb,5);
- if(num==-1)goto _eofout;
- s->lengthlist[i]=num+1;
- }else
- s->lengthlist[i]=0;
- }
- }else{
- /* all entries used; no tagging */
- for(i=0;i<s->entries;i++){
- long num=oggpack_read(opb,5);
- if(num==-1)goto _eofout;
- s->lengthlist[i]=num+1;
- }
- }
-
- break;
- case 1:
- /* ordered */
- {
- long length=oggpack_read(opb,5)+1;
- s->lengthlist=(long*)_ogg_malloc(sizeof(*s->lengthlist)*s->entries);
-
- for(i=0;i<s->entries;){
- long num=oggpack_read(opb,_ilog(s->entries-i));
- if(num==-1)goto _eofout;
- for(j=0;j<num && i<s->entries;j++,i++)
- s->lengthlist[i]=length;
- length++;
- }
- }
- break;
- default:
- /* EOF */
- return(-1);
- }
-
- /* Do we have a mapping to unpack? */
- switch((s->maptype=oggpack_read(opb,4))){
- case 0:
- /* no mapping */
- break;
- case 1: case 2:
- /* implicitly populated value mapping */
- /* explicitly populated value mapping */
-
- s->q_min=oggpack_read(opb,32);
- s->q_delta=oggpack_read(opb,32);
- s->q_quant=oggpack_read(opb,4)+1;
- s->q_sequencep=oggpack_read(opb,1);
-
- {
- int quantvals=0;
- switch(s->maptype){
- case 1:
- quantvals=_book_maptype1_quantvals(s);
- break;
- case 2:
- quantvals=s->entries*s->dim;
- break;
- }
-
- /* quantized values */
- s->quantlist=(long*)_ogg_malloc(sizeof(*s->quantlist)*quantvals);
- for(i=0;i<quantvals;i++)
- s->quantlist[i]=oggpack_read(opb,s->q_quant);
-
- if(quantvals&&s->quantlist[quantvals-1]==-1)goto _eofout;
- }
- break;
- default:
- goto _errout;
- }
-
- /* all set */
- return(0);
-
- _errout:
- _eofout:
- vorbis_staticbook_clear(s);
- return(-1);
- }
-
- /* returns the number of bits ************************************************/
- int vorbis_book_encode(codebook *book, int a, oggpack_buffer *b){
- oggpack_write(b,book->codelist[a],book->c->lengthlist[a]);
- return(book->c->lengthlist[a]);
- }
-
- /* One the encode side, our vector writers are each designed for a
- specific purpose, and the encoder is not flexible without modification:
-
- The LSP vector coder uses a single stage nearest-match with no
- interleave, so no step and no error return. This is specced by floor0
- and doesn't change.
-
- Residue0 encoding interleaves, uses multiple stages, and each stage
- peels of a specific amount of resolution from a lattice (thus we want
- to match by threshold, not nearest match). Residue doesn't *have* to
- be encoded that way, but to change it, one will need to add more
- infrastructure on the encode side (decode side is specced and simpler) */
-
- /* floor0 LSP (single stage, non interleaved, nearest match) */
- /* returns entry number and *modifies a* to the quantization value *****/
- int vorbis_book_errorv(codebook *book,float *a){
- int dim=book->dim,k;
- int best=_best(book,a,1);
- for(k=0;k<dim;k++)
- a[k]=(book->valuelist+best*dim)[k];
- return(best);
- }
-
- /* returns the number of bits and *modifies a* to the quantization value *****/
- int vorbis_book_encodev(codebook *book,int best,float *a,oggpack_buffer *b){
- int k,dim=book->dim;
- for(k=0;k<dim;k++)
- a[k]=(book->valuelist+best*dim)[k];
- return(vorbis_book_encode(book,best,b));
- }
-
- /* the 'eliminate the decode tree' optimization actually requires the
- codewords to be MSb first, not LSb. This is an annoying inelegancy
- (and one of the first places where carefully thought out design
- turned out to be wrong; Vorbis II and future Ogg codecs should go
- to an MSb bitpacker), but not actually the huge hit it appears to
- be. The first-stage decode table catches most words so that
- bitreverse is not in the main execution path. */
-
- STIN long decode_packed_entry_number(codebook *book, oggpack_buffer *b){
- int read=book->dec_maxlength;
- long lo,hi;
- long lok = oggpack_look(b,book->dec_firsttablen);
-
- if (lok >= 0) {
- long entry = book->dec_firsttable[lok];
- if(entry&0x80000000UL){
- lo=(entry>>15)&0x7fff;
- hi=book->used_entries-(entry&0x7fff);
- }else{
- oggpack_adv(b, book->dec_codelengths[entry-1]);
- return(entry-1);
- }
- }else{
- lo=0;
- hi=book->used_entries;
- }
-
- lok = oggpack_look(b, read);
-
- while(lok<0 && read>1)
- lok = oggpack_look(b, --read);
- if(lok<0)return -1;
-
- /* bisect search for the codeword in the ordered list */
- {
- ogg_uint32_t testword=bitreverse((ogg_uint32_t)lok);
-
- while(hi-lo>1){
- long p=(hi-lo)>>1;
- long test=book->codelist[lo+p]>testword;
- lo+=p&(test-1);
- hi-=p&(-test);
- }
-
- if(book->dec_codelengths[lo]<=read){
- oggpack_adv(b, book->dec_codelengths[lo]);
- return(lo);
- }
- }
-
- oggpack_adv(b, read);
- return(-1);
- }
-
- /* Decode side is specced and easier, because we don't need to find
- matches using different criteria; we simply read and map. There are
- two things we need to do 'depending':
-
- We may need to support interleave. We don't really, but it's
- convenient to do it here rather than rebuild the vector later.
-
- Cascades may be additive or multiplicitive; this is not inherent in
- the codebook, but set in the code using the codebook. Like
- interleaving, it's easiest to do it here.
- addmul==0 -> declarative (set the value)
- addmul==1 -> additive
- addmul==2 -> multiplicitive */
-
- /* returns the [original, not compacted] entry number or -1 on eof *********/
- long vorbis_book_decode(codebook *book, oggpack_buffer *b){
- long packed_entry=decode_packed_entry_number(book,b);
- if(packed_entry>=0)
- return(book->dec_index[packed_entry]);
-
- /* if there's no dec_index, the codebook unpacking isn't collapsed */
- return(packed_entry);
- }
-
- /* returns 0 on OK or -1 on eof *************************************/
- long vorbis_book_decodevs_add(codebook *book,float *a,oggpack_buffer *b,int n){
- int step=n/book->dim;
- long *entry = (long*)alloca(sizeof(*entry)*step);
- float **t = (float**)alloca(sizeof(*t)*step);
- int i,j,o;
-
- for (i = 0; i < step; i++) {
- entry[i]=decode_packed_entry_number(book,b);
- if(entry[i]==-1)return(-1);
- t[i] = book->valuelist+entry[i]*book->dim;
- }
- for(i=0,o=0;i<book->dim;i++,o+=step)
- for (j=0;j<step;j++)
- a[o+j]+=t[j][i];
- return(0);
- }
-
- long vorbis_book_decodev_add(codebook *book,float *a,oggpack_buffer *b,int n){
- int i,j,entry;
- float *t;
-
- if(book->dim>8){
- for(i=0;i<n;){
- entry = decode_packed_entry_number(book,b);
- if(entry==-1)return(-1);
- t = book->valuelist+entry*book->dim;
- for (j=0;j<book->dim;)
- a[i++]+=t[j++];
- }
- }else{
- for(i=0;i<n;){
- entry = decode_packed_entry_number(book,b);
- if(entry==-1)return(-1);
- t = book->valuelist+entry*book->dim;
- j=0;
- switch((int)book->dim){
- case 8:
- a[i++]+=t[j++];
- case 7:
- a[i++]+=t[j++];
- case 6:
- a[i++]+=t[j++];
- case 5:
- a[i++]+=t[j++];
- case 4:
- a[i++]+=t[j++];
- case 3:
- a[i++]+=t[j++];
- case 2:
- a[i++]+=t[j++];
- case 1:
- a[i++]+=t[j++];
- case 0:
- break;
- }
- }
- }
- return(0);
- }
-
- long vorbis_book_decodev_set(codebook *book,float *a,oggpack_buffer *b,int n){
- int i,j,entry;
- float *t;
-
- for(i=0;i<n;){
- entry = decode_packed_entry_number(book,b);
- if(entry==-1)return(-1);
- t = book->valuelist+entry*book->dim;
- for (j=0;j<book->dim;)
- a[i++]=t[j++];
- }
- return(0);
- }
-
- long vorbis_book_decodevv_add(codebook *book,float **a,long offset,int ch,
- oggpack_buffer *b,int n){
- long i,j,entry;
- int chptr=0;
-
- for(i=offset/ch;i<(offset+n)/ch;){
- entry = decode_packed_entry_number(book,b);
- if(entry==-1)return(-1);
- {
- const float *t = book->valuelist+entry*book->dim;
- for (j=0;j<book->dim;j++){
- a[chptr++][i]+=t[j];
- if(chptr==ch){
- chptr=0;
- i++;
- }
- }
- }
- }
- return(0);
- }
-
- #ifdef _V_SELFTEST
- /* Simple enough; pack a few candidate codebooks, unpack them. Code a
- number of vectors through (keeping track of the quantized values),
- and decode using the unpacked book. quantized version of in should
- exactly equal out */
-
- #include <stdio.h>
-
- #include "vorbis/book/lsp20_0.vqh"
- #include "vorbis/book/res0a_13.vqh"
- #define TESTSIZE 40
-
- float test1[TESTSIZE]={
- 0.105939f,
- 0.215373f,
- 0.429117f,
- 0.587974f,
-
- 0.181173f,
- 0.296583f,
- 0.515707f,
- 0.715261f,
-
- 0.162327f,
- 0.263834f,
- 0.342876f,
- 0.406025f,
-
- 0.103571f,
- 0.223561f,
- 0.368513f,
- 0.540313f,
-
- 0.136672f,
- 0.395882f,
- 0.587183f,
- 0.652476f,
-
- 0.114338f,
- 0.417300f,
- 0.525486f,
- 0.698679f,
-
- 0.147492f,
- 0.324481f,
- 0.643089f,
- 0.757582f,
-
- 0.139556f,
- 0.215795f,
- 0.324559f,
- 0.399387f,
-
- 0.120236f,
- 0.267420f,
- 0.446940f,
- 0.608760f,
-
- 0.115587f,
- 0.287234f,
- 0.571081f,
- 0.708603f,
- };
-
- float test3[TESTSIZE]={
- 0,1,-2,3,4,-5,6,7,8,9,
- 8,-2,7,-1,4,6,8,3,1,-9,
- 10,11,12,13,14,15,26,17,18,19,
- 30,-25,-30,-1,-5,-32,4,3,-2,0};
-
- static_codebook *testlist[]={&_vq_book_lsp20_0,
- &_vq_book_res0a_13,NULL};
- float *testvec[]={test1,test3};
-
- int main(){
- oggpack_buffer write;
- oggpack_buffer read;
- long ptr=0,i;
- oggpack_writeinit(&write);
-
- fprintf(stderr,"Testing codebook abstraction...:\n");
-
- while(testlist[ptr]){
- codebook c;
- static_codebook s;
- float *qv=alloca(sizeof(*qv)*TESTSIZE);
- float *iv=alloca(sizeof(*iv)*TESTSIZE);
- memcpy(qv,testvec[ptr],sizeof(*qv)*TESTSIZE);
- memset(iv,0,sizeof(*iv)*TESTSIZE);
-
- fprintf(stderr,"\tpacking/coding %ld... ",ptr);
-
- /* pack the codebook, write the testvector */
- oggpack_reset(&write);
- vorbis_book_init_encode(&c,testlist[ptr]); /* get it into memory
- we can write */
- vorbis_staticbook_pack(testlist[ptr],&write);
- fprintf(stderr,"Codebook size %ld bytes... ",oggpack_bytes(&write));
- for(i=0;i<TESTSIZE;i+=c.dim){
- int best=_best(&c,qv+i,1);
- vorbis_book_encodev(&c,best,qv+i,&write);
- }
- vorbis_book_clear(&c);
-
- fprintf(stderr,"OK.\n");
- fprintf(stderr,"\tunpacking/decoding %ld... ",ptr);
-
- /* transfer the write data to a read buffer and unpack/read */
- oggpack_readinit(&read,oggpack_get_buffer(&write),oggpack_bytes(&write));
- if(vorbis_staticbook_unpack(&read,&s)){
- fprintf(stderr,"Error unpacking codebook.\n");
- exit(1);
- }
- if(vorbis_book_init_decode(&c,&s)){
- fprintf(stderr,"Error initializing codebook.\n");
- exit(1);
- }
-
- for(i=0;i<TESTSIZE;i+=c.dim)
- if(vorbis_book_decodev_set(&c,iv+i,&read,c.dim)==-1){
- fprintf(stderr,"Error reading codebook test data (EOP).\n");
- exit(1);
- }
- for(i=0;i<TESTSIZE;i++)
- if(fabs(qv[i]-iv[i])>.000001){
- fprintf(stderr,"read (%g) != written (%g) at position (%ld)\n",
- iv[i],qv[i],i);
- exit(1);
- }
-
- fprintf(stderr,"OK\n");
- ptr++;
- }
-
- /* The above is the trivial stuff; now try unquantizing a log scale codebook */
-
- exit(0);
- }
-
- #endif
-
- #endif
- /********* End of inlined file: codebook.c *********/
-
- /********* Start of inlined file: envelope.c *********/
-
- /********* Start of inlined file: juce_OggVorbisHeader.h *********/
- // This file is included at the start of each Ogg-Vorbis .c file, just to do a few housekeeping
- // tasks..
-
- #ifdef _MSC_VER
- #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4305 4189 4706)
- #endif
- /********* End of inlined file: juce_OggVorbisHeader.h *********/
-
- #if JUCE_USE_OGGVORBIS
-
- #include <stdlib.h>
- #include <string.h>
- #include <stdio.h>
- #include <math.h>
-
- void _ve_envelope_init(envelope_lookup *e,vorbis_info *vi){
- codec_setup_info *ci=(codec_setup_info*)vi->codec_setup;
- vorbis_info_psy_global *gi=&ci->psy_g_param;
- int ch=vi->channels;
- int i,j;
- int n=e->winlength=128;
- e->searchstep=64; /* not random */
-
- e->minenergy=gi->preecho_minenergy;
- e->ch=ch;
- e->storage=128;
- e->cursor=ci->blocksizes[1]/2;
- e->mdct_win=(float*)_ogg_calloc(n,sizeof(*e->mdct_win));
- mdct_init(&e->mdct,n);
-
- for(i=0;i<n;i++){
- e->mdct_win[i]=sin(i/(n-1.)*M_PI);
- e->mdct_win[i]*=e->mdct_win[i];
- }
-
- /* magic follows */
- e->band[0].begin=2; e->band[0].end=4;
- e->band[1].begin=4; e->band[1].end=5;
- e->band[2].begin=6; e->band[2].end=6;
- e->band[3].begin=9; e->band[3].end=8;
- e->band[4].begin=13; e->band[4].end=8;
- e->band[5].begin=17; e->band[5].end=8;
- e->band[6].begin=22; e->band[6].end=8;
-
- for(j=0;j<VE_BANDS;j++){
- n=e->band[j].end;
- e->band[j].window=(float*)_ogg_malloc(n*sizeof(*e->band[0].window));
- for(i=0;i<n;i++){
- e->band[j].window[i]=sin((i+.5)/n*M_PI);
- e->band[j].total+=e->band[j].window[i];
- }
- e->band[j].total=1./e->band[j].total;
- }
-
- e->filter=(envelope_filter_state*)_ogg_calloc(VE_BANDS*ch,sizeof(*e->filter));
- e->mark=(int*)_ogg_calloc(e->storage,sizeof(*e->mark));
-
- }
-
- void _ve_envelope_clear(envelope_lookup *e){
- int i;
- mdct_clear(&e->mdct);
- for(i=0;i<VE_BANDS;i++)
- _ogg_free(e->band[i].window);
- _ogg_free(e->mdct_win);
- _ogg_free(e->filter);
- _ogg_free(e->mark);
- memset(e,0,sizeof(*e));
- }
-
- /* fairly straight threshhold-by-band based until we find something
- that works better and isn't patented. */
-
- static int _ve_amp(envelope_lookup *ve,
- vorbis_info_psy_global *gi,
- float *data,
- envelope_band *bands,
- envelope_filter_state *filters,
- long pos){
- long n=ve->winlength;
- int ret=0;
- long i,j;
- float decay;
-
- /* we want to have a 'minimum bar' for energy, else we're just
- basing blocks on quantization noise that outweighs the signal
- itself (for low power signals) */
-
- float minV=ve->minenergy;
- float *vec=(float*) alloca(n*sizeof(*vec));
-
- /* stretch is used to gradually lengthen the number of windows
- considered prevoius-to-potential-trigger */
- int stretch=max(VE_MINSTRETCH,ve->stretch/2);
- float penalty=gi->stretch_penalty-(ve->stretch/2-VE_MINSTRETCH);
- if(penalty<0.f)penalty=0.f;
- if(penalty>gi->stretch_penalty)penalty=gi->stretch_penalty;
-
- /*_analysis_output_always("lpcm",seq2,data,n,0,0,
- totalshift+pos*ve->searchstep);*/
-
- /* window and transform */
- for(i=0;i<n;i++)
- vec[i]=data[i]*ve->mdct_win[i];
- mdct_forward(&ve->mdct,vec,vec);
-
- /*_analysis_output_always("mdct",seq2,vec,n/2,0,1,0); */
-
- /* near-DC spreading function; this has nothing to do with
- psychoacoustics, just sidelobe leakage and window size */
- {
- float temp=vec[0]*vec[0]+.7*vec[1]*vec[1]+.2*vec[2]*vec[2];
- int ptr=filters->nearptr;
-
- /* the accumulation is regularly refreshed from scratch to avoid
- floating point creep */
- if(ptr==0){
- decay=filters->nearDC_acc=filters->nearDC_partialacc+temp;
- filters->nearDC_partialacc=temp;
- }else{
- decay=filters->nearDC_acc+=temp;
- filters->nearDC_partialacc+=temp;
- }
- filters->nearDC_acc-=filters->nearDC[ptr];
- filters->nearDC[ptr]=temp;
-
- decay*=(1./(VE_NEARDC+1));
- filters->nearptr++;
- if(filters->nearptr>=VE_NEARDC)filters->nearptr=0;
- decay=todB(&decay)*.5-15.f;
- }
-
- /* perform spreading and limiting, also smooth the spectrum. yes,
- the MDCT results in all real coefficients, but it still *behaves*
- like real/imaginary pairs */
- for(i=0;i<n/2;i+=2){
- float val=vec[i]*vec[i]+vec[i+1]*vec[i+1];
- val=todB(&val)*.5f;
- if(val<decay)val=decay;
- if(val<minV)val=minV;
- vec[i>>1]=val;
- decay-=8.;
- }
-
- /*_analysis_output_always("spread",seq2++,vec,n/4,0,0,0);*/
-
- /* perform preecho/postecho triggering by band */
- for(j=0;j<VE_BANDS;j++){
- float acc=0.;
- float valmax,valmin;
-
- /* accumulate amplitude */
- for(i=0;i<bands[j].end;i++)
- acc+=vec[i+bands[j].begin]*bands[j].window[i];
-
- acc*=bands[j].total;
-
- /* convert amplitude to delta */
- {
- int p,thisx=filters[j].ampptr;
- float postmax,postmin,premax=-99999.f,premin=99999.f;
-
- p=thisx;
- p--;
- if(p<0)p+=VE_AMP;
- postmax=max(acc,filters[j].ampbuf[p]);
- postmin=min(acc,filters[j].ampbuf[p]);
-
- for(i=0;i<stretch;i++){
- p--;
- if(p<0)p+=VE_AMP;
- premax=max(premax,filters[j].ampbuf[p]);
- premin=min(premin,filters[j].ampbuf[p]);
- }
-
- valmin=postmin-premin;
- valmax=postmax-premax;
-
- /*filters[j].markers[pos]=valmax;*/
- filters[j].ampbuf[thisx]=acc;
- filters[j].ampptr++;
- if(filters[j].ampptr>=VE_AMP)filters[j].ampptr=0;
- }
-
- /* look at min/max, decide trigger */
- if(valmax>gi->preecho_thresh[j]+penalty){
- ret|=1;
- ret|=4;
- }
- if(valmin<gi->postecho_thresh[j]-penalty)ret|=2;
- }
-
- return(ret);
- }
-
- #if 0
- static int seq=0;
- static ogg_int64_t totalshift=-1024;
- #endif
-
- long _ve_envelope_search(vorbis_dsp_state *v){
- vorbis_info *vi=v->vi;
- codec_setup_info *ci=(codec_setup_info *)vi->codec_setup;
- vorbis_info_psy_global *gi=&ci->psy_g_param;
- envelope_lookup *ve=((private_state *)(v->backend_state))->ve;
- long i,j;
-
- int first=ve->current/ve->searchstep;
- int last=v->pcm_current/ve->searchstep-VE_WIN;
- if(first<0)first=0;
-
- /* make sure we have enough storage to match the PCM */
- if(last+VE_WIN+VE_POST>ve->storage){
- ve->storage=last+VE_WIN+VE_POST; /* be sure */
- ve->mark=(int*)_ogg_realloc(ve->mark,ve->storage*sizeof(*ve->mark));
- }
-
- for(j=first;j<last;j++){
- int ret=0;
-
- ve->stretch++;
- if(ve->stretch>VE_MAXSTRETCH*2)
- ve->stretch=VE_MAXSTRETCH*2;
-
- for(i=0;i<ve->ch;i++){
- float *pcm=v->pcm[i]+ve->searchstep*(j);
- ret|=_ve_amp(ve,gi,pcm,ve->band,ve->filter+i*VE_BANDS,j);
- }
-
- ve->mark[j+VE_POST]=0;
- if(ret&1){
- ve->mark[j]=1;
- ve->mark[j+1]=1;
- }
-
- if(ret&2){
- ve->mark[j]=1;
- if(j>0)ve->mark[j-1]=1;
- }
-
- if(ret&4)ve->stretch=-1;
- }
-
- ve->current=last*ve->searchstep;
-
- {
- long centerW=v->centerW;
- long testW=
- centerW+
- ci->blocksizes[v->W]/4+
- ci->blocksizes[1]/2+
- ci->blocksizes[0]/4;
-
- j=ve->cursor;
-
- while(j<ve->current-(ve->searchstep)){/* account for postecho
- working back one window */
- if(j>=testW)return(1);
-
- ve->cursor=j;
-
- if(ve->mark[j/ve->searchstep]){
- if(j>centerW){
-
- #if 0
- if(j>ve->curmark){
- float *marker=alloca(v->pcm_current*sizeof(*marker));
- int l,m;
- memset(marker,0,sizeof(*marker)*v->pcm_current);
- fprintf(stderr,"mark! seq=%d, cursor:%fs time:%fs\n",
- seq,
- (totalshift+ve->cursor)/44100.,
- (totalshift+j)/44100.);
- _analysis_output_always("pcmL",seq,v->pcm[0],v->pcm_current,0,0,totalshift);
- _analysis_output_always("pcmR",seq,v->pcm[1],v->pcm_current,0,0,totalshift);
-
- _analysis_output_always("markL",seq,v->pcm[0],j,0,0,totalshift);
- _analysis_output_always("markR",seq,v->pcm[1],j,0,0,totalshift);
-
- for(m=0;m<VE_BANDS;m++){
- char buf[80];
- sprintf(buf,"delL%d",m);
- for(l=0;l<last;l++)marker[l*ve->searchstep]=ve->filter[m].markers[l]*.1;
- _analysis_output_always(buf,seq,marker,v->pcm_current,0,0,totalshift);
- }
-
- for(m=0;m<VE_BANDS;m++){
- char buf[80];
- sprintf(buf,"delR%d",m);
- for(l=0;l<last;l++)marker[l*ve->searchstep]=ve->filter[m+VE_BANDS].markers[l]*.1;
- _analysis_output_always(buf,seq,marker,v->pcm_current,0,0,totalshift);
- }
-
- for(l=0;l<last;l++)marker[l*ve->searchstep]=ve->mark[l]*.4;
- _analysis_output_always("mark",seq,marker,v->pcm_current,0,0,totalshift);
-
- seq++;
-
- }
- #endif
-
- ve->curmark=j;
- if(j>=testW)return(1);
- return(0);
- }
- }
- j+=ve->searchstep;
- }
- }
-
- return(-1);
- }
-
- int _ve_envelope_mark(vorbis_dsp_state *v){
- envelope_lookup *ve=((private_state *)(v->backend_state))->ve;
- vorbis_info *vi=v->vi;
- codec_setup_info *ci=(codec_setup_info*)vi->codec_setup;
- long centerW=v->centerW;
- long beginW=centerW-ci->blocksizes[v->W]/4;
- long endW=centerW+ci->blocksizes[v->W]/4;
- if(v->W){
- beginW-=ci->blocksizes[v->lW]/4;
- endW+=ci->blocksizes[v->nW]/4;
- }else{
- beginW-=ci->blocksizes[0]/4;
- endW+=ci->blocksizes[0]/4;
- }
-
- if(ve->curmark>=beginW && ve->curmark<endW)return(1);
- {
- long first=beginW/ve->searchstep;
- long last=endW/ve->searchstep;
- long i;
- for(i=first;i<last;i++)
- if(ve->mark[i])return(1);
- }
- return(0);
- }
-
- void _ve_envelope_shift(envelope_lookup *e,long shift){
- int smallsize=e->current/e->searchstep+VE_POST; /* adjust for placing marks
- ahead of ve->current */
- int smallshift=shift/e->searchstep;
-
- memmove(e->mark,e->mark+smallshift,(smallsize-smallshift)*sizeof(*e->mark));
-
- #if 0
- for(i=0;i<VE_BANDS*e->ch;i++)
- memmove(e->filter[i].markers,
- e->filter[i].markers+smallshift,
- (1024-smallshift)*sizeof(*(*e->filter).markers));
- totalshift+=shift;
- #endif
-
- e->current-=shift;
- if(e->curmark>=0)
- e->curmark-=shift;
- e->cursor-=shift;
- }
-
- #endif
- /********* End of inlined file: envelope.c *********/
-
- /********* Start of inlined file: floor0.c *********/
-
- /********* Start of inlined file: juce_OggVorbisHeader.h *********/
- // This file is included at the start of each Ogg-Vorbis .c file, just to do a few housekeeping
- // tasks..
-
- #ifdef _MSC_VER
- #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4305 4189 4706)
- #endif
- /********* End of inlined file: juce_OggVorbisHeader.h *********/
-
- #if JUCE_USE_OGGVORBIS
-
- #include <stdlib.h>
- #include <string.h>
- #include <math.h>
-
- /********* Start of inlined file: lsp.h *********/
- #ifndef _V_LSP_H_
- #define _V_LSP_H_
-
- extern int vorbis_lpc_to_lsp(float *lpc,float *lsp,int m);
-
- extern void vorbis_lsp_to_curve(float *curve,int *map,int n,int ln,
- float *lsp,int m,
- float amp,float ampoffset);
-
- #endif
- /********* End of inlined file: lsp.h *********/
-
- #include <stdio.h>
-
- typedef struct {
- int ln;
- int m;
- int **linearmap;
- int n[2];
-
- vorbis_info_floor0 *vi;
-
- long bits;
- long frames;
- } vorbis_look_floor0;
-
- /***********************************************/
-
- static void floor0_free_info(vorbis_info_floor *i){
- vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
- if(info){
- memset(info,0,sizeof(*info));
- _ogg_free(info);
- }
- }
-
- static void floor0_free_look(vorbis_look_floor *i){
- vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
- if(look){
-
- if(look->linearmap){
-
- if(look->linearmap[0])_ogg_free(look->linearmap[0]);
- if(look->linearmap[1])_ogg_free(look->linearmap[1]);
-
- _ogg_free(look->linearmap);
- }
- memset(look,0,sizeof(*look));
- _ogg_free(look);
- }
- }
-
- static vorbis_info_floor *floor0_unpack (vorbis_info *vi,oggpack_buffer *opb){
- codec_setup_info *ci=(codec_setup_info*)vi->codec_setup;
- int j;
-
- vorbis_info_floor0 *info=(vorbis_info_floor0*)_ogg_malloc(sizeof(*info));
- info->order=oggpack_read(opb,8);
- info->rate=oggpack_read(opb,16);
- info->barkmap=oggpack_read(opb,16);
- info->ampbits=oggpack_read(opb,6);
- info->ampdB=oggpack_read(opb,8);
- info->numbooks=oggpack_read(opb,4)+1;
-
- if(info->order<1)goto err_out;
- if(info->rate<1)goto err_out;
- if(info->barkmap<1)goto err_out;
- if(info->numbooks<1)goto err_out;
-
- for(j=0;j<info->numbooks;j++){
- info->books[j]=oggpack_read(opb,8);
- if(info->books[j]<0 || info->books[j]>=ci->books)goto err_out;
- }
- return(info);
-
- err_out:
- floor0_free_info(info);
- return(NULL);
- }
-
- /* initialize Bark scale and normalization lookups. We could do this
- with static tables, but Vorbis allows a number of possible
- combinations, so it's best to do it computationally.
-
- The below is authoritative in terms of defining scale mapping.
- Note that the scale depends on the sampling rate as well as the
- linear block and mapping sizes */
-
- static void floor0_map_lazy_init(vorbis_block *vb,
- vorbis_info_floor *infoX,
- vorbis_look_floor0 *look){
- if(!look->linearmap[vb->W]){
- vorbis_dsp_state *vd=vb->vd;
- vorbis_info *vi=vd->vi;
- codec_setup_info *ci=(codec_setup_info*)vi->codec_setup;
- vorbis_info_floor0 *info=(vorbis_info_floor0 *)infoX;
- int W=vb->W;
- int n=ci->blocksizes[W]/2,j;
-
- /* we choose a scaling constant so that:
- floor(bark(rate/2-1)*C)=mapped-1
- floor(bark(rate/2)*C)=mapped */
- float scale=look->ln/toBARK(info->rate/2.f);
-
- /* the mapping from a linear scale to a smaller bark scale is
- straightforward. We do *not* make sure that the linear mapping
- does not skip bark-scale bins; the decoder simply skips them and
- the encoder may do what it wishes in filling them. They're
- necessary in some mapping combinations to keep the scale spacing
- accurate */
- look->linearmap[W]=(int*)_ogg_malloc((n+1)*sizeof(**look->linearmap));
- for(j=0;j<n;j++){
- int val=floor( toBARK((info->rate/2.f)/n*j)
- *scale); /* bark numbers represent band edges */
- if(val>=look->ln)val=look->ln-1; /* guard against the approximation */
- look->linearmap[W][j]=val;
- }
- look->linearmap[W][j]=-1;
- look->n[W]=n;
- }
- }
-
- static vorbis_look_floor *floor0_look(vorbis_dsp_state *vd,
- vorbis_info_floor *i){
- vorbis_info_floor0 *info=(vorbis_info_floor0*)i;
- vorbis_look_floor0 *look=(vorbis_look_floor0*)_ogg_calloc(1,sizeof(*look));
- look->m=info->order;
- look->ln=info->barkmap;
- look->vi=info;
-
- look->linearmap=(int**)_ogg_calloc(2,sizeof(*look->linearmap));
-
- return look;
- }
-
- static void *floor0_inverse1(vorbis_block *vb,vorbis_look_floor *i){
- vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
- vorbis_info_floor0 *info=look->vi;
- int j,k;
-
- int ampraw=oggpack_read(&vb->opb,info->ampbits);
- if(ampraw>0){ /* also handles the -1 out of data case */
- long maxval=(1<<info->ampbits)-1;
- float amp=(float)ampraw/maxval*info->ampdB;
- int booknum=oggpack_read(&vb->opb,_ilog(info->numbooks));
-
- if(booknum!=-1 && booknum<info->numbooks){ /* be paranoid */
- codec_setup_info *ci=(codec_setup_info *)vb->vd->vi->codec_setup;
- codebook *b=ci->fullbooks+info->books[booknum];
- float last=0.f;
-
- /* the additional b->dim is a guard against any possible stack
- smash; b->dim is provably more than we can overflow the
- vector */
- float *lsp=(float*)_vorbis_block_alloc(vb,sizeof(*lsp)*(look->m+b->dim+1));
-
- for(j=0;j<look->m;j+=b->dim)
- if(vorbis_book_decodev_set(b,lsp+j,&vb->opb,b->dim)==-1)goto eop;
- for(j=0;j<look->m;){
- for(k=0;k<b->dim;k++,j++)lsp[j]+=last;
- last=lsp[j-1];
- }
-
- lsp[look->m]=amp;
- return(lsp);
- }
- }
- eop:
- return(NULL);
- }
-
- static int floor0_inverse2(vorbis_block *vb,vorbis_look_floor *i,
- void *memo,float *out){
- vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
- vorbis_info_floor0 *info=look->vi;
-
- floor0_map_lazy_init(vb,info,look);
-
- if(memo){
- float *lsp=(float *)memo;
- float amp=lsp[look->m];
-
- /* take the coefficients back to a spectral envelope curve */
- vorbis_lsp_to_curve(out,
- look->linearmap[vb->W],
- look->n[vb->W],
- look->ln,
- lsp,look->m,amp,(float)info->ampdB);
- return(1);
- }
- memset(out,0,sizeof(*out)*look->n[vb->W]);
- return(0);
- }
-
- /* export hooks */
- vorbis_func_floor floor0_exportbundle={
- NULL,&floor0_unpack,&floor0_look,&floor0_free_info,
- &floor0_free_look,&floor0_inverse1,&floor0_inverse2
- };
-
- #endif
- /********* End of inlined file: floor0.c *********/
-
- /********* Start of inlined file: floor1.c *********/
-
- /********* Start of inlined file: juce_OggVorbisHeader.h *********/
- // This file is included at the start of each Ogg-Vorbis .c file, just to do a few housekeeping
- // tasks..
-
- #ifdef _MSC_VER
- #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4305 4189 4706)
- #endif
- /********* End of inlined file: juce_OggVorbisHeader.h *********/
-
- #if JUCE_USE_OGGVORBIS
-
- #include <stdlib.h>
- #include <string.h>
- #include <math.h>
-
- #include <stdio.h>
-
- #define floor1_rangedB 140 /* floor 1 fixed at -140dB to 0dB range */
-
- typedef struct {
- int sorted_index[VIF_POSIT+2];
- int forward_index[VIF_POSIT+2];
- int reverse_index[VIF_POSIT+2];
-
- int hineighbor[VIF_POSIT];
- int loneighbor[VIF_POSIT];
- int posts;
-
- int n;
- int quant_q;
- vorbis_info_floor1 *vi;
-
- long phrasebits;
- long postbits;
- long frames;
- } vorbis_look_floor1;
-
- typedef struct lsfit_acc{
- long x0;
- long x1;
-
- long xa;
- long ya;
- long x2a;
- long y2a;
- long xya;
- long an;
- } lsfit_acc;
-
- /***********************************************/
-
- static void floor1_free_info(vorbis_info_floor *i){
- vorbis_info_floor1 *info=(vorbis_info_floor1 *)i;
- if(info){
- memset(info,0,sizeof(*info));
- _ogg_free(info);
- }
- }
-
- static void floor1_free_look(vorbis_look_floor *i){
- vorbis_look_floor1 *look=(vorbis_look_floor1 *)i;
- if(look){
- /*fprintf(stderr,"floor 1 bit usage %f:%f (%f total)\n",
- (float)look->phrasebits/look->frames,
- (float)look->postbits/look->frames,
- (float)(look->postbits+look->phrasebits)/look->frames);*/
-
- memset(look,0,sizeof(*look));
- _ogg_free(look);
- }
- }
-
- static void floor1_pack (vorbis_info_floor *i,oggpack_buffer *opb){
- vorbis_info_floor1 *info=(vorbis_info_floor1 *)i;
- int j,k;
- int count=0;
- int rangebits;
- int maxposit=info->postlist[1];
- int maxclass=-1;
-
- /* save out partitions */
- oggpack_write(opb,info->partitions,5); /* only 0 to 31 legal */
- for(j=0;j<info->partitions;j++){
- oggpack_write(opb,info->partitionclass[j],4); /* only 0 to 15 legal */
- if(maxclass<info->partitionclass[j])maxclass=info->partitionclass[j];
- }
-
- /* save out partition classes */
- for(j=0;j<maxclass+1;j++){
- oggpack_write(opb,info->class_dim[j]-1,3); /* 1 to 8 */
- oggpack_write(opb,info->class_subs[j],2); /* 0 to 3 */
- if(info->class_subs[j])oggpack_write(opb,info->class_book[j],8);
- for(k=0;k<(1<<info->class_subs[j]);k++)
- oggpack_write(opb,info->class_subbook[j][k]+1,8);
- }
-
- /* save out the post list */
- oggpack_write(opb,info->mult-1,2); /* only 1,2,3,4 legal now */
- oggpack_write(opb,ilog2(maxposit),4);
- rangebits=ilog2(maxposit);
-
- for(j=0,k=0;j<info->partitions;j++){
- count+=info->class_dim[info->partitionclass[j]];
- for(;k<count;k++)
- oggpack_write(opb,info->postlist[k+2],rangebits);
- }
- }
-
- static vorbis_info_floor *floor1_unpack (vorbis_info *vi,oggpack_buffer *opb){
- codec_setup_info *ci=(codec_setup_info*)vi->codec_setup;
- int j,k,count=0,maxclass=-1,rangebits;
-
- vorbis_info_floor1 *info=(vorbis_info_floor1*)_ogg_calloc(1,sizeof(*info));
- /* read partitions */
- info->partitions=oggpack_read(opb,5); /* only 0 to 31 legal */
- for(j=0;j<info->partitions;j++){
- info->partitionclass[j]=oggpack_read(opb,4); /* only 0 to 15 legal */
- if(maxclass<info->partitionclass[j])maxclass=info->partitionclass[j];
- }
-
- /* read partition classes */
- for(j=0;j<maxclass+1;j++){
- info->class_dim[j]=oggpack_read(opb,3)+1; /* 1 to 8 */
- info->class_subs[j]=oggpack_read(opb,2); /* 0,1,2,3 bits */
- if(info->class_subs[j]<0)
- goto err_out;
- if(info->class_subs[j])info->class_book[j]=oggpack_read(opb,8);
- if(info->class_book[j]<0 || info->class_book[j]>=ci->books)
- goto err_out;
- for(k=0;k<(1<<info->class_subs[j]);k++){
- info->class_subbook[j][k]=oggpack_read(opb,8)-1;
- if(info->class_subbook[j][k]<-1 || info->class_subbook[j][k]>=ci->books)
- goto err_out;
- }
- }
-
- /* read the post list */
- info->mult=oggpack_read(opb,2)+1; /* only 1,2,3,4 legal now */
- rangebits=oggpack_read(opb,4);
-
- for(j=0,k=0;j<info->partitions;j++){
- count+=info->class_dim[info->partitionclass[j]];
- for(;k<count;k++){
- int t=info->postlist[k+2]=oggpack_read(opb,rangebits);
- if(t<0 || t>=(1<<rangebits))
- goto err_out;
- }
- }
- info->postlist[0]=0;
- info->postlist[1]=1<<rangebits;
-
- return(info);
-
- err_out:
- floor1_free_info(info);
- return(NULL);
- }
-
- static int icomp(const void *a,const void *b){
- return(**(int **)a-**(int **)b);
- }
-
- static vorbis_look_floor *floor1_look(vorbis_dsp_state *vd,
- vorbis_info_floor *in){
-
- int *sortpointer[VIF_POSIT+2];
- vorbis_info_floor1 *info=(vorbis_info_floor1*)in;
- vorbis_look_floor1 *look=(vorbis_look_floor1*)_ogg_calloc(1,sizeof(*look));
- int i,j,n=0;
-
- look->vi=info;
- look->n=info->postlist[1];
-
- /* we drop each position value in-between already decoded values,
- and use linear interpolation to predict each new value past the
- edges. The positions are read in the order of the position
- list... we precompute the bounding positions in the lookup. Of
- course, the neighbors can change (if a position is declined), but
- this is an initial mapping */
-
- for(i=0;i<info->partitions;i++)n+=info->class_dim[info->partitionclass[i]];
- n+=2;
- look->posts=n;
-
- /* also store a sorted position index */
- for(i=0;i<n;i++)sortpointer[i]=info->postlist+i;
- qsort(sortpointer,n,sizeof(*sortpointer),icomp);
-
- /* points from sort order back to range number */
- for(i=0;i<n;i++)look->forward_index[i]=sortpointer[i]-info->postlist;
- /* points from range order to sorted position */
- for(i=0;i<n;i++)look->reverse_index[look->forward_index[i]]=i;
- /* we actually need the post values too */
- for(i=0;i<n;i++)look->sorted_index[i]=info->postlist[look->forward_index[i]];
-
- /* quantize values to multiplier spec */
- switch(info->mult){
- case 1: /* 1024 -> 256 */
- look->quant_q=256;
- break;
- case 2: /* 1024 -> 128 */
- look->quant_q=128;
- break;
- case 3: /* 1024 -> 86 */
- look->quant_q=86;
- break;
- case 4: /* 1024 -> 64 */
- look->quant_q=64;
- break;
- }
-
- /* discover our neighbors for decode where we don't use fit flags
- (that would push the neighbors outward) */
- for(i=0;i<n-2;i++){
- int lo=0;
- int hi=1;
- int lx=0;
- int hx=look->n;
- int currentx=info->postlist[i+2];
- for(j=0;j<i+2;j++){
- int x=info->postlist[j];
- if(x>lx && x<currentx){
- lo=j;
- lx=x;
- }
- if(x<hx && x>currentx){
- hi=j;
- hx=x;
- }
- }
- look->loneighbor[i]=lo;
- look->hineighbor[i]=hi;
- }
-
- return(look);
- }
-
- static int render_point(int x0,int x1,int y0,int y1,int x){
- y0&=0x7fff; /* mask off flag */
- y1&=0x7fff;
-
- {
- int dy=y1-y0;
- int adx=x1-x0;
- int ady=abs(dy);
- int err=ady*(x-x0);
-
- int off=err/adx;
- if(dy<0)return(y0-off);
- return(y0+off);
- }
- }
-
- static int vorbis_dBquant(const float *x){
- int i= *x*7.3142857f+1023.5f;
- if(i>1023)return(1023);
- if(i<0)return(0);
- return i;
- }
-
- static float FLOOR1_fromdB_LOOKUP[256]={
- 1.0649863e-07F, 1.1341951e-07F, 1.2079015e-07F, 1.2863978e-07F,
- 1.3699951e-07F, 1.4590251e-07F, 1.5538408e-07F, 1.6548181e-07F,
- 1.7623575e-07F, 1.8768855e-07F, 1.9988561e-07F, 2.128753e-07F,
- 2.2670913e-07F, 2.4144197e-07F, 2.5713223e-07F, 2.7384213e-07F,
- 2.9163793e-07F, 3.1059021e-07F, 3.3077411e-07F, 3.5226968e-07F,
- 3.7516214e-07F, 3.9954229e-07F, 4.2550680e-07F, 4.5315863e-07F,
- 4.8260743e-07F, 5.1396998e-07F, 5.4737065e-07F, 5.8294187e-07F,
- 6.2082472e-07F, 6.6116941e-07F, 7.0413592e-07F, 7.4989464e-07F,
- 7.9862701e-07F, 8.5052630e-07F, 9.0579828e-07F, 9.6466216e-07F,
- 1.0273513e-06F, 1.0941144e-06F, 1.1652161e-06F, 1.2409384e-06F,
- 1.3215816e-06F, 1.4074654e-06F, 1.4989305e-06F, 1.5963394e-06F,
- 1.7000785e-06F, 1.8105592e-06F, 1.9282195e-06F, 2.0535261e-06F,
- 2.1869758e-06F, 2.3290978e-06F, 2.4804557e-06F, 2.6416497e-06F,
- 2.8133190e-06F, 2.9961443e-06F, 3.1908506e-06F, 3.3982101e-06F,
- 3.6190449e-06F, 3.8542308e-06F, 4.1047004e-06F, 4.3714470e-06F,
- 4.6555282e-06F, 4.9580707e-06F, 5.2802740e-06F, 5.6234160e-06F,
- 5.9888572e-06F, 6.3780469e-06F, 6.7925283e-06F, 7.2339451e-06F,
- 7.7040476e-06F, 8.2047000e-06F, 8.7378876e-06F, 9.3057248e-06F,
- 9.9104632e-06F, 1.0554501e-05F, 1.1240392e-05F, 1.1970856e-05F,
- 1.2748789e-05F, 1.3577278e-05F, 1.4459606e-05F, 1.5399272e-05F,
- 1.6400004e-05F, 1.7465768e-05F, 1.8600792e-05F, 1.9809576e-05F,
- 2.1096914e-05F, 2.2467911e-05F, 2.3928002e-05F, 2.5482978e-05F,
- 2.7139006e-05F, 2.8902651e-05F, 3.0780908e-05F, 3.2781225e-05F,
- 3.4911534e-05F, 3.7180282e-05F, 3.9596466e-05F, 4.2169667e-05F,
- 4.4910090e-05F, 4.7828601e-05F, 5.0936773e-05F, 5.4246931e-05F,
- 5.7772202e-05F, 6.1526565e-05F, 6.5524908e-05F, 6.9783085e-05F,
- 7.4317983e-05F, 7.9147585e-05F, 8.4291040e-05F, 8.9768747e-05F,
- 9.5602426e-05F, 0.00010181521F, 0.00010843174F, 0.00011547824F,
- 0.00012298267F, 0.00013097477F, 0.00013948625F, 0.00014855085F,
- 0.00015820453F, 0.00016848555F, 0.00017943469F, 0.00019109536F,
- 0.00020351382F, 0.00021673929F, 0.00023082423F, 0.00024582449F,
- 0.00026179955F, 0.00027881276F, 0.00029693158F, 0.00031622787F,
- 0.00033677814F, 0.00035866388F, 0.00038197188F, 0.00040679456F,
- 0.00043323036F, 0.00046138411F, 0.00049136745F, 0.00052329927F,
- 0.00055730621F, 0.00059352311F, 0.00063209358F, 0.00067317058F,
- 0.00071691700F, 0.00076350630F, 0.00081312324F, 0.00086596457F,
- 0.00092223983F, 0.00098217216F, 0.0010459992F, 0.0011139742F,
- 0.0011863665F, 0.0012634633F, 0.0013455702F, 0.0014330129F,
- 0.0015261382F, 0.0016253153F, 0.0017309374F, 0.0018434235F,
- 0.0019632195F, 0.0020908006F, 0.0022266726F, 0.0023713743F,
- 0.0025254795F, 0.0026895994F, 0.0028643847F, 0.0030505286F,
- 0.0032487691F, 0.0034598925F, 0.0036847358F, 0.0039241906F,
- 0.0041792066F, 0.0044507950F, 0.0047400328F, 0.0050480668F,
- 0.0053761186F, 0.0057254891F, 0.0060975636F, 0.0064938176F,
- 0.0069158225F, 0.0073652516F, 0.0078438871F, 0.0083536271F,
- 0.0088964928F, 0.009474637F, 0.010090352F, 0.010746080F,
- 0.011444421F, 0.012188144F, 0.012980198F, 0.013823725F,
- 0.014722068F, 0.015678791F, 0.016697687F, 0.017782797F,
- 0.018938423F, 0.020169149F, 0.021479854F, 0.022875735F,
- 0.024362330F, 0.025945531F, 0.027631618F, 0.029427276F,
- 0.031339626F, 0.033376252F, 0.035545228F, 0.037855157F,
- 0.040315199F, 0.042935108F, 0.045725273F, 0.048696758F,
- 0.051861348F, 0.055231591F, 0.058820850F, 0.062643361F,
- 0.066714279F, 0.071049749F, 0.075666962F, 0.080584227F,
- 0.085821044F, 0.091398179F, 0.097337747F, 0.10366330F,
- 0.11039993F, 0.11757434F, 0.12521498F, 0.13335215F,
- 0.14201813F, 0.15124727F, 0.16107617F, 0.17154380F,
- 0.18269168F, 0.19456402F, 0.20720788F, 0.22067342F,
- 0.23501402F, 0.25028656F, 0.26655159F, 0.28387361F,
- 0.30232132F, 0.32196786F, 0.34289114F, 0.36517414F,
- 0.38890521F, 0.41417847F, 0.44109412F, 0.46975890F,
- 0.50028648F, 0.53279791F, 0.56742212F, 0.60429640F,
- 0.64356699F, 0.68538959F, 0.72993007F, 0.77736504F,
- 0.82788260F, 0.88168307F, 0.9389798F, 1.F,
- };
-
- static void render_line(int x0,int x1,int y0,int y1,float *d){
- int dy=y1-y0;
- int adx=x1-x0;
- int ady=abs(dy);
- int base=dy/adx;
- int sy=(dy<0?base-1:base+1);
- int x=x0;
- int y=y0;
- int err=0;
-
- ady-=abs(base*adx);
-
- d[x]*=FLOOR1_fromdB_LOOKUP[y];
- while(++x<x1){
- err=err+ady;
- if(err>=adx){
- err-=adx;
- y+=sy;
- }else{
- y+=base;
- }
- d[x]*=FLOOR1_fromdB_LOOKUP[y];
- }
- }
-
- static void render_line0(int x0,int x1,int y0,int y1,int *d){
- int dy=y1-y0;
- int adx=x1-x0;
- int ady=abs(dy);
- int base=dy/adx;
- int sy=(dy<0?base-1:base+1);
- int x=x0;
- int y=y0;
- int err=0;
-
- ady-=abs(base*adx);
-
- d[x]=y;
- while(++x<x1){
- err=err+ady;
- if(err>=adx){
- err-=adx;
- y+=sy;
- }else{
- y+=base;
- }
- d[x]=y;
- }
- }
-
- /* the floor has already been filtered to only include relevant sections */
- static int accumulate_fit(const float *flr,const float *mdct,
- int x0, int x1,lsfit_acc *a,
- int n,vorbis_info_floor1 *info){
- long i;
- long xa=0,ya=0,x2a=0,y2a=0,xya=0,na=0, xb=0,yb=0,x2b=0,y2b=0,xyb=0,nb=0;
-
- memset(a,0,sizeof(*a));
- a->x0=x0;
- a->x1=x1;
- if(x1>=n)x1=n-1;
-
- for(i=x0;i<=x1;i++){
- int quantized=vorbis_dBquant(flr+i);
- if(quantized){
- if(mdct[i]+info->twofitatten>=flr[i]){
- xa += i;
- ya += quantized;
- x2a += i*i;
- y2a += quantized*quantized;
- xya += i*quantized;
- na++;
- }else{
- xb += i;
- yb += quantized;
- x2b += i*i;
- y2b += quantized*quantized;
- xyb += i*quantized;
- nb++;
- }
- }
- }
-
- xb+=xa;
- yb+=ya;
- x2b+=x2a;
- y2b+=y2a;
- xyb+=xya;
- nb+=na;
-
- /* weight toward the actually used frequencies if we meet the threshhold */
- {
- int weight=nb*info->twofitweight/(na+1);
-
- a->xa=xa*weight+xb;
- a->ya=ya*weight+yb;
- a->x2a=x2a*weight+x2b;
- a->y2a=y2a*weight+y2b;
- a->xya=xya*weight+xyb;
- a->an=na*weight+nb;
- }
-
- return(na);
- }
-
- static void fit_line(lsfit_acc *a,int fits,int *y0,int *y1){
- long x=0,y=0,x2=0,y2=0,xy=0,an=0,i;
- long x0=a[0].x0;
- long x1=a[fits-1].x1;
-
- for(i=0;i<fits;i++){
- x+=a[i].xa;
- y+=a[i].ya;
- x2+=a[i].x2a;
- y2+=a[i].y2a;
- xy+=a[i].xya;
- an+=a[i].an;
- }
-
- if(*y0>=0){
- x+= x0;
- y+= *y0;
- x2+= x0 * x0;
- y2+= *y0 * *y0;
- xy+= *y0 * x0;
- an++;
- }
-
- if(*y1>=0){
- x+= x1;
- y+= *y1;
- x2+= x1 * x1;
- y2+= *y1 * *y1;
- xy+= *y1 * x1;
- an++;
- }
-
- if(an){
- /* need 64 bit multiplies, which C doesn't give portably as int */
- double fx=x;
- double fy=y;
- double fx2=x2;
- double fxy=xy;
- double denom=1./(an*fx2-fx*fx);
- double a=(fy*fx2-fxy*fx)*denom;
- double b=(an*fxy-fx*fy)*denom;
- *y0=rint(a+b*x0);
- *y1=rint(a+b*x1);
-
- /* limit to our range! */
- if(*y0>1023)*y0=1023;
- if(*y1>1023)*y1=1023;
- if(*y0<0)*y0=0;
- if(*y1<0)*y1=0;
-
- }else{
- *y0=0;
- *y1=0;
- }
- }
-
- /*static void fit_line_point(lsfit_acc *a,int fits,int *y0,int *y1){
- long y=0;
- int i;
-
- for(i=0;i<fits && y==0;i++)
- y+=a[i].ya;
-
- *y0=*y1=y;
- }*/
-
- static int inspect_error(int x0,int x1,int y0,int y1,const float *mask,
- const float *mdct,
- vorbis_info_floor1 *info){
- int dy=y1-y0;
- int adx=x1-x0;
- int ady=abs(dy);
- int base=dy/adx;
- int sy=(dy<0?base-1:base+1);
- int x=x0;
- int y=y0;
- int err=0;
- int val=vorbis_dBquant(mask+x);
- int mse=0;
- int n=0;
-
- ady-=abs(base*adx);
-
- mse=(y-val);
- mse*=mse;
- n++;
- if(mdct[x]+info->twofitatten>=mask[x]){
- if(y+info->maxover<val)return(1);
- if(y-info->maxunder>val)return(1);
- }
-
- while(++x<x1){
- err=err+ady;
- if(err>=adx){
- err-=adx;
- y+=sy;
- }else{
- y+=base;
- }
-
- val=vorbis_dBquant(mask+x);
- mse+=((y-val)*(y-val));
- n++;
- if(mdct[x]+info->twofitatten>=mask[x]){
- if(val){
- if(y+info->maxover<val)return(1);
- if(y-info->maxunder>val)return(1);
- }
- }
- }
-
- if(info->maxover*info->maxover/n>info->maxerr)return(0);
- if(info->maxunder*info->maxunder/n>info->maxerr)return(0);
- if(mse/n>info->maxerr)return(1);
- return(0);
- }
-
- static int post_Y(int *A,int *B,int pos){
- if(A[pos]<0)
- return B[pos];
- if(B[pos]<0)
- return A[pos];
-
- return (A[pos]+B[pos])>>1;
- }
-
- int *floor1_fit(vorbis_block *vb,void *look_,
- const float *logmdct, /* in */
- const float *logmask){
- long i,j;
- vorbis_look_floor1 *look = (vorbis_look_floor1*) look_;
- vorbis_info_floor1 *info=look->vi;
- long n=look->n;
- long posts=look->posts;
- long nonzero=0;
- lsfit_acc fits[VIF_POSIT+1];
- int fit_valueA[VIF_POSIT+2]; /* index by range list position */
- int fit_valueB[VIF_POSIT+2]; /* index by range list position */
-
- int loneighbor[VIF_POSIT+2]; /* sorted index of range list position (+2) */
- int hineighbor[VIF_POSIT+2];
- int *output=NULL;
- int memo[VIF_POSIT+2];
-
- for(i=0;i<posts;i++)fit_valueA[i]=-200; /* mark all unused */
- for(i=0;i<posts;i++)fit_valueB[i]=-200; /* mark all unused */
- for(i=0;i<posts;i++)loneighbor[i]=0; /* 0 for the implicit 0 post */
- for(i=0;i<posts;i++)hineighbor[i]=1; /* 1 for the implicit post at n */
- for(i=0;i<posts;i++)memo[i]=-1; /* no neighbor yet */
-
- /* quantize the relevant floor points and collect them into line fit
- structures (one per minimal division) at the same time */
- if(posts==0){
- nonzero+=accumulate_fit(logmask,logmdct,0,n,fits,n,info);
- }else{
- for(i=0;i<posts-1;i++)
- nonzero+=accumulate_fit(logmask,logmdct,look->sorted_index[i],
- look->sorted_index[i+1],fits+i,
- n,info);
- }
-
- if(nonzero){
- /* start by fitting the implicit base case.... */
- int y0=-200;
- int y1=-200;
- fit_line(fits,posts-1,&y0,&y1);
-
- fit_valueA[0]=y0;
- fit_valueB[0]=y0;
- fit_valueB[1]=y1;
- fit_valueA[1]=y1;
-
- /* Non degenerate case */
- /* start progressive splitting. This is a greedy, non-optimal
- algorithm, but simple and close enough to the best
- answer. */
- for(i=2;i<posts;i++){
- int sortpos=look->reverse_index[i];
- int ln=loneighbor[sortpos];
- int hn=hineighbor[sortpos];
-
- /* eliminate repeat searches of a particular range with a memo */
- if(memo[ln]!=hn){
- /* haven't performed this error search yet */
- int lsortpos=look->reverse_index[ln];
- int hsortpos=look->reverse_index[hn];
- memo[ln]=hn;
-
- {
- /* A note: we want to bound/minimize *local*, not global, error */
- int lx=info->postlist[ln];
- int hx=info->postlist[hn];
- int ly=post_Y(fit_valueA,fit_valueB,ln);
- int hy=post_Y(fit_valueA,fit_valueB,hn);
-
- if(ly==-1 || hy==-1){
- exit(1);
- }
-
- if(inspect_error(lx,hx,ly,hy,logmask,logmdct,info)){
- /* outside error bounds/begin search area. Split it. */
- int ly0=-200;
- int ly1=-200;
- int hy0=-200;
- int hy1=-200;
- fit_line(fits+lsortpos,sortpos-lsortpos,&ly0,&ly1);
- fit_line(fits+sortpos,hsortpos-sortpos,&hy0,&hy1);
-
- /* store new edge values */
- fit_valueB[ln]=ly0;
- if(ln==0)fit_valueA[ln]=ly0;
- fit_valueA[i]=ly1;
- fit_valueB[i]=hy0;
- fit_valueA[hn]=hy1;
- if(hn==1)fit_valueB[hn]=hy1;
-
- if(ly1>=0 || hy0>=0){
- /* store new neighbor values */
- for(j=sortpos-1;j>=0;j--)
- if(hineighbor[j]==hn)
- hineighbor[j]=i;
- else
- break;
- for(j=sortpos+1;j<posts;j++)
- if(loneighbor[j]==ln)
- loneighbor[j]=i;
- else
- break;
-
- }
- }else{
-
- fit_valueA[i]=-200;
- fit_valueB[i]=-200;
- }
- }
- }
- }
-
- output=(int*)_vorbis_block_alloc(vb,sizeof(*output)*posts);
-
- output[0]=post_Y(fit_valueA,fit_valueB,0);
- output[1]=post_Y(fit_valueA,fit_valueB,1);
-
- /* fill in posts marked as not using a fit; we will zero
- back out to 'unused' when encoding them so long as curve
- interpolation doesn't force them into use */
- for(i=2;i<posts;i++){
- int ln=look->loneighbor[i-2];
- int hn=look->hineighbor[i-2];
- int x0=info->postlist[ln];
- int x1=info->postlist[hn];
- int y0=output[ln];
- int y1=output[hn];
-
- int predicted=render_point(x0,x1,y0,y1,info->postlist[i]);
- int vx=post_Y(fit_valueA,fit_valueB,i);
-
- if(vx>=0 && predicted!=vx){
- output[i]=vx;
- }else{
- output[i]= predicted|0x8000;
- }
- }
- }
-
- return(output);
-
- }
-
- int *floor1_interpolate_fit(vorbis_block *vb,void *look_,
- int *A,int *B,
- int del){
-
- long i;
- vorbis_look_floor1* look = (vorbis_look_floor1*) look_;
- long posts=look->posts;
- int *output=NULL;
-
- if(A && B){
- output=(int*)_vorbis_block_alloc(vb,sizeof(*output)*posts);
-
- for(i=0;i<posts;i++){
- output[i]=((65536-del)*(A[i]&0x7fff)+del*(B[i]&0x7fff)+32768)>>16;
- if(A[i]&0x8000 && B[i]&0x8000)output[i]|=0x8000;
- }
- }
-
- return(output);
- }
-
- int floor1_encode(oggpack_buffer *opb,vorbis_block *vb,
- void*look_,
- int *post,int *ilogmask){
-
- long i,j;
- vorbis_look_floor1 *look = (vorbis_look_floor1 *) look_;
- vorbis_info_floor1 *info=look->vi;
- long posts=look->posts;
- codec_setup_info *ci=(codec_setup_info*)vb->vd->vi->codec_setup;
- int out[VIF_POSIT+2];
- static_codebook **sbooks=ci->book_param;
- codebook *books=ci->fullbooks;
- static long seq=0;
-
- /* quantize values to multiplier spec */
- if(post){
- for(i=0;i<posts;i++){
- int val=post[i]&0x7fff;
- switch(info->mult){
- case 1: /* 1024 -> 256 */
- val>>=2;
- break;
- case 2: /* 1024 -> 128 */
- val>>=3;
- break;
- case 3: /* 1024 -> 86 */
- val/=12;
- break;
- case 4: /* 1024 -> 64 */
- val>>=4;
- break;
- }
- post[i]=val | (post[i]&0x8000);
- }
-
- out[0]=post[0];
- out[1]=post[1];
-
- /* find prediction values for each post and subtract them */
- for(i=2;i<posts;i++){
- int ln=look->loneighbor[i-2];
- int hn=look->hineighbor[i-2];
- int x0=info->postlist[ln];
- int x1=info->postlist[hn];
- int y0=post[ln];
- int y1=post[hn];
-
- int predicted=render_point(x0,x1,y0,y1,info->postlist[i]);
-
- if((post[i]&0x8000) || (predicted==post[i])){
- post[i]=predicted|0x8000; /* in case there was roundoff jitter
- in interpolation */
- out[i]=0;
- }else{
- int headroom=(look->quant_q-predicted<predicted?
- look->quant_q-predicted:predicted);
-
- int val=post[i]-predicted;
-
- /* at this point the 'deviation' value is in the range +/- max
- range, but the real, unique range can always be mapped to
- only [0-maxrange). So we want to wrap the deviation into
- this limited range, but do it in the way that least screws
- an essentially gaussian probability distribution. */
-
- if(val<0)
- if(val<-headroom)
- val=headroom-val-1;
- else
- val=-1-(val<<1);
- else
- if(val>=headroom)
- val= val+headroom;
- else
- val<<=1;
-
- out[i]=val;
- post[ln]&=0x7fff;
- post[hn]&=0x7fff;
- }
- }
-
- /* we have everything we need. pack it out */
- /* mark nontrivial floor */
- oggpack_write(opb,1,1);
-
- /* beginning/end post */
- look->frames++;
- look->postbits+=ilog(look->quant_q-1)*2;
- oggpack_write(opb,out[0],ilog(look->quant_q-1));
- oggpack_write(opb,out[1],ilog(look->quant_q-1));
-
- /* partition by partition */
- for(i=0,j=2;i<info->partitions;i++){
- int classx=info->partitionclass[i];
- int cdim=info->class_dim[classx];
- int csubbits=info->class_subs[classx];
- int csub=1<<csubbits;
- int bookas[8]={0,0,0,0,0,0,0,0};
- int cval=0;
- int cshift=0;
- int k,l;
-
- /* generate the partition's first stage cascade value */
- if(csubbits){
- int maxval[8];
- for(k=0;k<csub;k++){
- int booknum=info->class_subbook[classx][k];
- if(booknum<0){
- maxval[k]=1;
- }else{
- maxval[k]=sbooks[info->class_subbook[classx][k]]->entries;
- }
- }
- for(k=0;k<cdim;k++){
- for(l=0;l<csub;l++){
- int val=out[j+k];
- if(val<maxval[l]){
- bookas[k]=l;
- break;
- }
- }
- cval|= bookas[k]<<cshift;
- cshift+=csubbits;
- }
- /* write it */
- look->phrasebits+=
- vorbis_book_encode(books+info->class_book[classx],cval,opb);
-
- #ifdef TRAIN_FLOOR1
- {
- FILE *of;
- char buffer[80];
- sprintf(buffer,"line_%dx%ld_class%d.vqd",
- vb->pcmend/2,posts-2,class);
- of=fopen(buffer,"a");
- fprintf(of,"%d\n",cval);
- fclose(of);
- }
- #endif
- }
-
- /* write post values */
- for(k=0;k<cdim;k++){
- int book=info->class_subbook[classx][bookas[k]];
- if(book>=0){
- /* hack to allow training with 'bad' books */
- if(out[j+k]<(books+book)->entries)
- look->postbits+=vorbis_book_encode(books+book,
- out[j+k],opb);
- /*else
- fprintf(stderr,"+!");*/
-
- #ifdef TRAIN_FLOOR1
- {
- FILE *of;
- char buffer[80];
- sprintf(buffer,"line_%dx%ld_%dsub%d.vqd",
- vb->pcmend/2,posts-2,class,bookas[k]);
- of=fopen(buffer,"a");
- fprintf(of,"%d\n",out[j+k]);
- fclose(of);
- }
- #endif
- }
- }
- j+=cdim;
- }
-
- {
- /* generate quantized floor equivalent to what we'd unpack in decode */
- /* render the lines */
- int hx=0;
- int lx=0;
- int ly=post[0]*info->mult;
- for(j=1;j<look->posts;j++){
- int current=look->forward_index[j];
- int hy=post[current]&0x7fff;
- if(hy==post[current]){
-
- hy*=info->mult;
- hx=info->postlist[current];
-
- render_line0(lx,hx,ly,hy,ilogmask);
-
- lx=hx;
- ly=hy;
- }
- }
- for(j=hx;j<vb->pcmend/2;j++)ilogmask[j]=ly; /* be certain */
- seq++;
- return(1);
- }
- }else{
- oggpack_write(opb,0,1);
- memset(ilogmask,0,vb->pcmend/2*sizeof(*ilogmask));
- seq++;
- return(0);
- }
- }
-
- static void *floor1_inverse1(vorbis_block *vb,vorbis_look_floor *in){
- vorbis_look_floor1 *look=(vorbis_look_floor1 *)in;
- vorbis_info_floor1 *info=look->vi;
- codec_setup_info *ci=(codec_setup_info*)vb->vd->vi->codec_setup;
-
- int i,j,k;
- codebook *books=ci->fullbooks;
-
- /* unpack wrapped/predicted values from stream */
- if(oggpack_read(&vb->opb,1)==1){
- int *fit_value=(int*)_vorbis_block_alloc(vb,(look->posts)*sizeof(*fit_value));
-
- fit_value[0]=oggpack_read(&vb->opb,ilog(look->quant_q-1));
- fit_value[1]=oggpack_read(&vb->opb,ilog(look->quant_q-1));
-
- /* partition by partition */
- for(i=0,j=2;i<info->partitions;i++){
- int classx=info->partitionclass[i];
- int cdim=info->class_dim[classx];
- int csubbits=info->class_subs[classx];
- int csub=1<<csubbits;
- int cval=0;
-
- /* decode the partition's first stage cascade value */
- if(csubbits){
- cval=vorbis_book_decode(books+info->class_book[classx],&vb->opb);
-
- if(cval==-1)goto eop;
- }
-
- for(k=0;k<cdim;k++){
- int book=info->class_subbook[classx][cval&(csub-1)];
- cval>>=csubbits;
- if(book>=0){
- if((fit_value[j+k]=vorbis_book_decode(books+book,&vb->opb))==-1)
- goto eop;
- }else{
- fit_value[j+k]=0;
- }
- }
- j+=cdim;
- }
-
- /* unwrap positive values and reconsitute via linear interpolation */
- for(i=2;i<look->posts;i++){
- int predicted=render_point(info->postlist[look->loneighbor[i-2]],
- info->postlist[look->hineighbor[i-2]],
- fit_value[look->loneighbor[i-2]],
- fit_value[look->hineighbor[i-2]],
- info->postlist[i]);
- int hiroom=look->quant_q-predicted;
- int loroom=predicted;
- int room=(hiroom<loroom?hiroom:loroom)<<1;
- int val=fit_value[i];
-
- if(val){
- if(val>=room){
- if(hiroom>loroom){
- val = val-loroom;
- }else{
- val = -1-(val-hiroom);
- }
- }else{
- if(val&1){
- val= -((val+1)>>1);
- }else{
- val>>=1;
- }
- }
-
- fit_value[i]=val+predicted;
- fit_value[look->loneighbor[i-2]]&=0x7fff;
- fit_value[look->hineighbor[i-2]]&=0x7fff;
-
- }else{
- fit_value[i]=predicted|0x8000;
- }
-
- }
-
- return(fit_value);
- }
- eop:
- return(NULL);
- }
-
- static int floor1_inverse2(vorbis_block *vb,vorbis_look_floor *in,void *memo,
- float *out){
- vorbis_look_floor1 *look=(vorbis_look_floor1 *)in;
- vorbis_info_floor1 *info=look->vi;
-
- codec_setup_info *ci=(codec_setup_info*)vb->vd->vi->codec_setup;
- int n=ci->blocksizes[vb->W]/2;
- int j;
-
- if(memo){
- /* render the lines */
- int *fit_value=(int *)memo;
- int hx=0;
- int lx=0;
- int ly=fit_value[0]*info->mult;
- for(j=1;j<look->posts;j++){
- int current=look->forward_index[j];
- int hy=fit_value[current]&0x7fff;
- if(hy==fit_value[current]){
-
- hy*=info->mult;
- hx=info->postlist[current];
-
- render_line(lx,hx,ly,hy,out);
-
- lx=hx;
- ly=hy;
- }
- }
- for(j=hx;j<n;j++)out[j]*=FLOOR1_fromdB_LOOKUP[ly]; /* be certain */
- return(1);
- }
- memset(out,0,sizeof(*out)*n);
- return(0);
- }
-
- /* export hooks */
- vorbis_func_floor floor1_exportbundle={
- &floor1_pack,&floor1_unpack,&floor1_look,&floor1_free_info,
- &floor1_free_look,&floor1_inverse1,&floor1_inverse2
- };
-
- #endif
- /********* End of inlined file: floor1.c *********/
-
- /********* Start of inlined file: info.c *********/
-
- /********* Start of inlined file: juce_OggVorbisHeader.h *********/
- // This file is included at the start of each Ogg-Vorbis .c file, just to do a few housekeeping
- // tasks..
-
- #ifdef _MSC_VER
- #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4305 4189 4706)
- #endif
- /********* End of inlined file: juce_OggVorbisHeader.h *********/
-
- #if JUCE_USE_OGGVORBIS
-
- /* general handling of the header and the vorbis_info structure (and
- substructures) */
-
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
-
- static void _v_writestring(oggpack_buffer *o,char *s, int bytes){
-
- while(bytes--){
- oggpack_write(o,*s++,8);
- }
- }
-
- static void _v_readstring(oggpack_buffer *o,char *buf,int bytes){
- while(bytes--){
- *buf++=oggpack_read(o,8);
- }
- }
-
- void vorbis_comment_init(vorbis_comment *vc){
- memset(vc,0,sizeof(*vc));
- }
-
- void vorbis_comment_add(vorbis_comment *vc,char *comment){
- vc->user_comments=(char**)_ogg_realloc(vc->user_comments,
- (vc->comments+2)*sizeof(*vc->user_comments));
- vc->comment_lengths=(int*)_ogg_realloc(vc->comment_lengths,
- (vc->comments+2)*sizeof(*vc->comment_lengths));
- vc->comment_lengths[vc->comments]=strlen(comment);
- vc->user_comments[vc->comments]=(char*)_ogg_malloc(vc->comment_lengths[vc->comments]+1);
- strcpy(vc->user_comments[vc->comments], comment);
- vc->comments++;
- vc->user_comments[vc->comments]=NULL;
- }
-
- void vorbis_comment_add_tag(vorbis_comment *vc, char *tag, char *contents){
- char *comment=(char*)alloca(strlen(tag)+strlen(contents)+2); /* +2 for = and \0 */
- strcpy(comment, tag);
- strcat(comment, "=");
- strcat(comment, contents);
- vorbis_comment_add(vc, comment);
- }
-
- /* This is more or less the same as strncasecmp - but that doesn't exist
- * everywhere, and this is a fairly trivial function, so we include it */
- static int tagcompare(const char *s1, const char *s2, int n){
- int c=0;
- while(c < n){
- if(toupper(s1[c]) != toupper(s2[c]))
- return !0;
- c++;
- }
- return 0;
- }
-
- char *vorbis_comment_query(vorbis_comment *vc, char *tag, int count){
- long i;
- int found = 0;
- int taglen = strlen(tag)+1; /* +1 for the = we append */
- char *fulltag = (char*)alloca(taglen+ 1);
-
- strcpy(fulltag, tag);
- strcat(fulltag, "=");
-
- for(i=0;i<vc->comments;i++){
- if(!tagcompare(vc->user_comments[i], fulltag, taglen)){
- if(count == found)
- /* We return a pointer to the data, not a copy */
- return vc->user_comments[i] + taglen;
- else
- found++;
- }
- }
- return NULL; /* didn't find anything */
- }
-
- int vorbis_comment_query_count(vorbis_comment *vc, char *tag){
- int i,count=0;
- int taglen = strlen(tag)+1; /* +1 for the = we append */
- char *fulltag = (char*)alloca(taglen+1);
- strcpy(fulltag,tag);
- strcat(fulltag, "=");
-
- for(i=0;i<vc->comments;i++){
- if(!tagcompare(vc->user_comments[i], fulltag, taglen))
- count++;
- }
-
- return count;
- }
-
- void vorbis_comment_clear(vorbis_comment *vc){
- if(vc){
- long i;
- for(i=0;i<vc->comments;i++)
- if(vc->user_comments[i])_ogg_free(vc->user_comments[i]);
- if(vc->user_comments)_ogg_free(vc->user_comments);
- if(vc->comment_lengths)_ogg_free(vc->comment_lengths);
- if(vc->vendor)_ogg_free(vc->vendor);
- }
- memset(vc,0,sizeof(*vc));
- }
-
- /* blocksize 0 is guaranteed to be short, 1 is guarantted to be long.
- They may be equal, but short will never ge greater than long */
- int vorbis_info_blocksize(vorbis_info *vi,int zo){
- codec_setup_info *ci = (codec_setup_info*)vi->codec_setup;
- return ci ? ci->blocksizes[zo] : -1;
- }
-
- /* used by synthesis, which has a full, alloced vi */
- void vorbis_info_init(vorbis_info *vi){
- memset(vi,0,sizeof(*vi));
- vi->codec_setup=_ogg_calloc(1,sizeof(codec_setup_info));
- }
-
- void vorbis_info_clear(vorbis_info *vi){
- codec_setup_info *ci=(codec_setup_info*)vi->codec_setup;
- int i;
-
- if(ci){
-
- for(i=0;i<ci->modes;i++)
- if(ci->mode_param[i])_ogg_free(ci->mode_param[i]);
-
- for(i=0;i<ci->maps;i++) /* unpack does the range checking */
- _mapping_P[ci->map_type[i]]->free_info(ci->map_param[i]);
-
- for(i=0;i<ci->floors;i++) /* unpack does the range checking */
- _floor_P[ci->floor_type[i]]->free_info(ci->floor_param[i]);
-
- for(i=0;i<ci->residues;i++) /* unpack does the range checking */
- _residue_P[ci->residue_type[i]]->free_info(ci->residue_param[i]);
-
- for(i=0;i<ci->books;i++){
- if(ci->book_param[i]){
- /* knows if the book was not alloced */
- vorbis_staticbook_destroy(ci->book_param[i]);
- }
- if(ci->fullbooks)
- vorbis_book_clear(ci->fullbooks+i);
- }
- if(ci->fullbooks)
- _ogg_free(ci->fullbooks);
-
- for(i=0;i<ci->psys;i++)
- _vi_psy_free(ci->psy_param[i]);
-
- _ogg_free(ci);
- }
-
- memset(vi,0,sizeof(*vi));
- }
-
- /* Header packing/unpacking ********************************************/
-
- static int _vorbis_unpack_info(vorbis_info *vi,oggpack_buffer *opb){
- codec_setup_info *ci=(codec_setup_info*)vi->codec_setup;
- if(!ci)return(OV_EFAULT);
-
- vi->version=oggpack_read(opb,32);
- if(vi->version!=0)return(OV_EVERSION);
-
- vi->channels=oggpack_read(opb,8);
- vi->rate=oggpack_read(opb,32);
-
- vi->bitrate_upper=oggpack_read(opb,32);
- vi->bitrate_nominal=oggpack_read(opb,32);
- vi->bitrate_lower=oggpack_read(opb,32);
-
- ci->blocksizes[0]=1<<oggpack_read(opb,4);
- ci->blocksizes[1]=1<<oggpack_read(opb,4);
-
- if(vi->rate<1)goto err_out;
- if(vi->channels<1)goto err_out;
- if(ci->blocksizes[0]<8)goto err_out;
- if(ci->blocksizes[1]<ci->blocksizes[0])goto err_out;
-
- if(oggpack_read(opb,1)!=1)goto err_out; /* EOP check */
-
- return(0);
- err_out:
- vorbis_info_clear(vi);
- return(OV_EBADHEADER);
- }
-
- static int _vorbis_unpack_comment(vorbis_comment *vc,oggpack_buffer *opb){
- int i;
- int vendorlen=oggpack_read(opb,32);
- if(vendorlen<0)goto err_out;
- vc->vendor=(char*)_ogg_calloc(vendorlen+1,1);
- _v_readstring(opb,vc->vendor,vendorlen);
- vc->comments=oggpack_read(opb,32);
- if(vc->comments<0)goto err_out;
- vc->user_comments=(char**)_ogg_calloc(vc->comments+1,sizeof(*vc->user_comments));
- vc->comment_lengths=(int*)_ogg_calloc(vc->comments+1, sizeof(*vc->comment_lengths));
-
- for(i=0;i<vc->comments;i++){
- int len=oggpack_read(opb,32);
- if(len<0)goto err_out;
- vc->comment_lengths[i]=len;
- vc->user_comments[i]=(char*)_ogg_calloc(len+1,1);
- _v_readstring(opb,vc->user_comments[i],len);
- }
- if(oggpack_read(opb,1)!=1)goto err_out; /* EOP check */
-
- return(0);
- err_out:
- vorbis_comment_clear(vc);
- return(OV_EBADHEADER);
- }
-
- /* all of the real encoding details are here. The modes, books,
- everything */
- static int _vorbis_unpack_books(vorbis_info *vi,oggpack_buffer *opb){
- codec_setup_info *ci=(codec_setup_info*)vi->codec_setup;
- int i;
- if(!ci)return(OV_EFAULT);
-
- /* codebooks */
- ci->books=oggpack_read(opb,8)+1;
- /*ci->book_param=_ogg_calloc(ci->books,sizeof(*ci->book_param));*/
- for(i=0;i<ci->books;i++){
- ci->book_param[i]=(static_codebook*)_ogg_calloc(1,sizeof(*ci->book_param[i]));
- if(vorbis_staticbook_unpack(opb,ci->book_param[i]))goto err_out;
- }
-
- /* time backend settings; hooks are unused */
- {
- int times=oggpack_read(opb,6)+1;
- for(i=0;i<times;i++){
- int test=oggpack_read(opb,16);
- if(test<0 || test>=VI_TIMEB)goto err_out;
- }
- }
-
- /* floor backend settings */
- ci->floors=oggpack_read(opb,6)+1;
- /*ci->floor_type=_ogg_malloc(ci->floors*sizeof(*ci->floor_type));*/
- /*ci->floor_param=_ogg_calloc(ci->floors,sizeof(void *));*/
- for(i=0;i<ci->floors;i++){
- ci->floor_type[i]=oggpack_read(opb,16);
- if(ci->floor_type[i]<0 || ci->floor_type[i]>=VI_FLOORB)goto err_out;
- ci->floor_param[i]=_floor_P[ci->floor_type[i]]->unpack(vi,opb);
- if(!ci->floor_param[i])goto err_out;
- }
-
- /* residue backend settings */
- ci->residues=oggpack_read(opb,6)+1;
- /*ci->residue_type=_ogg_malloc(ci->residues*sizeof(*ci->residue_type));*/
- /*ci->residue_param=_ogg_calloc(ci->residues,sizeof(void *));*/
- for(i=0;i<ci->residues;i++){
- ci->residue_type[i]=oggpack_read(opb,16);
- if(ci->residue_type[i]<0 || ci->residue_type[i]>=VI_RESB)goto err_out;
- ci->residue_param[i]=_residue_P[ci->residue_type[i]]->unpack(vi,opb);
- if(!ci->residue_param[i])goto err_out;
- }
-
- /* map backend settings */
- ci->maps=oggpack_read(opb,6)+1;
- /*ci->map_type=_ogg_malloc(ci->maps*sizeof(*ci->map_type));*/
- /*ci->map_param=_ogg_calloc(ci->maps,sizeof(void *));*/
- for(i=0;i<ci->maps;i++){
- ci->map_type[i]=oggpack_read(opb,16);
- if(ci->map_type[i]<0 || ci->map_type[i]>=VI_MAPB)goto err_out;
- ci->map_param[i]=_mapping_P[ci->map_type[i]]->unpack(vi,opb);
- if(!ci->map_param[i])goto err_out;
- }
-
- /* mode settings */
- ci->modes=oggpack_read(opb,6)+1;
- /*vi->mode_param=_ogg_calloc(vi->modes,sizeof(void *));*/
- for(i=0;i<ci->modes;i++){
- ci->mode_param[i]=(vorbis_info_mode*)_ogg_calloc(1,sizeof(*ci->mode_param[i]));
- ci->mode_param[i]->blockflag=oggpack_read(opb,1);
- ci->mode_param[i]->windowtype=oggpack_read(opb,16);
- ci->mode_param[i]->transformtype=oggpack_read(opb,16);
- ci->mode_param[i]->mapping=oggpack_read(opb,8);
-
- if(ci->mode_param[i]->windowtype>=VI_WINDOWB)goto err_out;
- if(ci->mode_param[i]->transformtype>=VI_WINDOWB)goto err_out;
- if(ci->mode_param[i]->mapping>=ci->maps)goto err_out;
- }
-
- if(oggpack_read(opb,1)!=1)goto err_out; /* top level EOP check */
-
- return(0);
- err_out:
- vorbis_info_clear(vi);
- return(OV_EBADHEADER);
- }
-
- /* The Vorbis header is in three packets; the initial small packet in
- the first page that identifies basic parameters, a second packet
- with bitstream comments and a third packet that holds the
- codebook. */
-
- int vorbis_synthesis_headerin(vorbis_info *vi,vorbis_comment *vc,ogg_packet *op){
- oggpack_buffer opb;
-
- if(op){
- oggpack_readinit(&opb,op->packet,op->bytes);
-
- /* Which of the three types of header is this? */
- /* Also verify header-ness, vorbis */
- {
- char buffer[6];
- int packtype=oggpack_read(&opb,8);
- memset(buffer,0,6);
- _v_readstring(&opb,buffer,6);
- if(memcmp(buffer,"vorbis",6)){
- /* not a vorbis header */
- return(OV_ENOTVORBIS);
- }
- switch(packtype){
- case 0x01: /* least significant *bit* is read first */
- if(!op->b_o_s){
- /* Not the initial packet */
- return(OV_EBADHEADER);
- }
- if(vi->rate!=0){
- /* previously initialized info header */
- return(OV_EBADHEADER);
- }
-
- return(_vorbis_unpack_info(vi,&opb));
-
- case 0x03: /* least significant *bit* is read first */
- if(vi->rate==0){
- /* um... we didn't get the initial header */
- return(OV_EBADHEADER);
- }
-
- return(_vorbis_unpack_comment(vc,&opb));
-
- case 0x05: /* least significant *bit* is read first */
- if(vi->rate==0 || vc->vendor==NULL){
- /* um... we didn;t get the initial header or comments yet */
- return(OV_EBADHEADER);
- }
-
- return(_vorbis_unpack_books(vi,&opb));
-
- default:
- /* Not a valid vorbis header type */
- return(OV_EBADHEADER);
- break;
- }
- }
- }
- return(OV_EBADHEADER);
- }
-
- /* pack side **********************************************************/
-
- static int _vorbis_pack_info(oggpack_buffer *opb,vorbis_info *vi){
- codec_setup_info *ci=(codec_setup_info*)vi->codec_setup;
- if(!ci)return(OV_EFAULT);
-
- /* preamble */
- oggpack_write(opb,0x01,8);
- _v_writestring(opb,"vorbis", 6);
-
- /* basic information about the stream */
- oggpack_write(opb,0x00,32);
- oggpack_write(opb,vi->channels,8);
- oggpack_write(opb,vi->rate,32);
-
- oggpack_write(opb,vi->bitrate_upper,32);
- oggpack_write(opb,vi->bitrate_nominal,32);
- oggpack_write(opb,vi->bitrate_lower,32);
-
- oggpack_write(opb,ilog2(ci->blocksizes[0]),4);
- oggpack_write(opb,ilog2(ci->blocksizes[1]),4);
- oggpack_write(opb,1,1);
-
- return(0);
- }
-
- static int _vorbis_pack_comment(oggpack_buffer *opb,vorbis_comment *vc){
- char temp[]="Xiph.Org libVorbis I 20050304";
- int bytes = strlen(temp);
-
- /* preamble */
- oggpack_write(opb,0x03,8);
- _v_writestring(opb,"vorbis", 6);
-
- /* vendor */
- oggpack_write(opb,bytes,32);
- _v_writestring(opb,temp, bytes);
-
- /* comments */
-
- oggpack_write(opb,vc->comments,32);
- if(vc->comments){
- int i;
- for(i=0;i<vc->comments;i++){
- if(vc->user_comments[i]){
- oggpack_write(opb,vc->comment_lengths[i],32);
- _v_writestring(opb,vc->user_comments[i], vc->comment_lengths[i]);
- }else{
- oggpack_write(opb,0,32);
- }
- }
- }
- oggpack_write(opb,1,1);
-
- return(0);
- }
-
- static int _vorbis_pack_books(oggpack_buffer *opb,vorbis_info *vi){
- codec_setup_info *ci=(codec_setup_info*)vi->codec_setup;
- int i;
- if(!ci)return(OV_EFAULT);
-
- oggpack_write(opb,0x05,8);
- _v_writestring(opb,"vorbis", 6);
-
- /* books */
- oggpack_write(opb,ci->books-1,8);
- for(i=0;i<ci->books;i++)
- if(vorbis_staticbook_pack(ci->book_param[i],opb))goto err_out;
-
- /* times; hook placeholders */
- oggpack_write(opb,0,6);
- oggpack_write(opb,0,16);
-
- /* floors */
- oggpack_write(opb,ci->floors-1,6);
- for(i=0;i<ci->floors;i++){
- oggpack_write(opb,ci->floor_type[i],16);
- if(_floor_P[ci->floor_type[i]]->pack)
- _floor_P[ci->floor_type[i]]->pack(ci->floor_param[i],opb);
- else
- goto err_out;
- }
-
- /* residues */
- oggpack_write(opb,ci->residues-1,6);
- for(i=0;i<ci->residues;i++){
- oggpack_write(opb,ci->residue_type[i],16);
- _residue_P[ci->residue_type[i]]->pack(ci->residue_param[i],opb);
- }
-
- /* maps */
- oggpack_write(opb,ci->maps-1,6);
- for(i=0;i<ci->maps;i++){
- oggpack_write(opb,ci->map_type[i],16);
- _mapping_P[ci->map_type[i]]->pack(vi,ci->map_param[i],opb);
- }
-
- /* modes */
- oggpack_write(opb,ci->modes-1,6);
- for(i=0;i<ci->modes;i++){
- oggpack_write(opb,ci->mode_param[i]->blockflag,1);
- oggpack_write(opb,ci->mode_param[i]->windowtype,16);
- oggpack_write(opb,ci->mode_param[i]->transformtype,16);
- oggpack_write(opb,ci->mode_param[i]->mapping,8);
- }
- oggpack_write(opb,1,1);
-
- return(0);
- err_out:
- return(-1);
- }
-
- int vorbis_commentheader_out(vorbis_comment *vc,
- ogg_packet *op){
-
- oggpack_buffer opb;
-
- oggpack_writeinit(&opb);
- if(_vorbis_pack_comment(&opb,vc)) return OV_EIMPL;
-
- op->packet = (unsigned char*) _ogg_malloc(oggpack_bytes(&opb));
- memcpy(op->packet, opb.buffer, oggpack_bytes(&opb));
-
- op->bytes=oggpack_bytes(&opb);
- op->b_o_s=0;
- op->e_o_s=0;
- op->granulepos=0;
- op->packetno=1;
-
- return 0;
- }
-
- int vorbis_analysis_headerout(vorbis_dsp_state *v,
- vorbis_comment *vc,
- ogg_packet *op,
- ogg_packet *op_comm,
- ogg_packet *op_code){
- int ret=OV_EIMPL;
- vorbis_info *vi=v->vi;
- oggpack_buffer opb;
- private_state *b=(private_state*)v->backend_state;
-
- if(!b){
- ret=OV_EFAULT;
- goto err_out;
- }
-
- /* first header packet **********************************************/
-
- oggpack_writeinit(&opb);
- if(_vorbis_pack_info(&opb,vi))goto err_out;
-
- /* build the packet */
- if(b->header)_ogg_free(b->header);
- b->header=(unsigned char*) _ogg_malloc(oggpack_bytes(&opb));
- memcpy(b->header,opb.buffer,oggpack_bytes(&opb));
- op->packet=b->header;
- op->bytes=oggpack_bytes(&opb);
- op->b_o_s=1;
- op->e_o_s=0;
- op->granulepos=0;
- op->packetno=0;
-
- /* second header packet (comments) **********************************/
-
- oggpack_reset(&opb);
- if(_vorbis_pack_comment(&opb,vc))goto err_out;
-
- if(b->header1)_ogg_free(b->header1);
- b->header1=(unsigned char*) _ogg_malloc(oggpack_bytes(&opb));
- memcpy(b->header1,opb.buffer,oggpack_bytes(&opb));
- op_comm->packet=b->header1;
- op_comm->bytes=oggpack_bytes(&opb);
- op_comm->b_o_s=0;
- op_comm->e_o_s=0;
- op_comm->granulepos=0;
- op_comm->packetno=1;
-
- /* third header packet (modes/codebooks) ****************************/
-
- oggpack_reset(&opb);
- if(_vorbis_pack_books(&opb,vi))goto err_out;
-
- if(b->header2)_ogg_free(b->header2);
- b->header2=(unsigned char*) _ogg_malloc(oggpack_bytes(&opb));
- memcpy(b->header2,opb.buffer,oggpack_bytes(&opb));
- op_code->packet=b->header2;
- op_code->bytes=oggpack_bytes(&opb);
- op_code->b_o_s=0;
- op_code->e_o_s=0;
- op_code->granulepos=0;
- op_code->packetno=2;
-
- oggpack_writeclear(&opb);
- return(0);
- err_out:
- oggpack_writeclear(&opb);
- memset(op,0,sizeof(*op));
- memset(op_comm,0,sizeof(*op_comm));
- memset(op_code,0,sizeof(*op_code));
-
- if(b->header)_ogg_free(b->header);
- if(b->header1)_ogg_free(b->header1);
- if(b->header2)_ogg_free(b->header2);
- b->header=NULL;
- b->header1=NULL;
- b->header2=NULL;
- return(ret);
- }
-
- double vorbis_granule_time(vorbis_dsp_state *v,ogg_int64_t granulepos){
- if(granulepos>=0)
- return((double)granulepos/v->vi->rate);
- return(-1);
- }
-
- #endif
- /********* End of inlined file: info.c *********/
-
- /********* Start of inlined file: lpc.c *********/
- /* Some of these routines (autocorrelator, LPC coefficient estimator)
- are derived from code written by Jutta Degener and Carsten Bormann;
- thus we include their copyright below. The entirety of this file
- is freely redistributable on the condition that both of these
- copyright notices are preserved without modification. */
-
- /* Preserved Copyright: *********************************************/
-
- /* Copyright 1992, 1993, 1994 by Jutta Degener and Carsten Bormann,
- Technische Universita"t Berlin
-
- Any use of this software is permitted provided that this notice is not
- removed and that neither the authors nor the Technische Universita"t
- Berlin are deemed to have made any representations as to the
- suitability of this software for any purpose nor are held responsible
- for any defects of this software. THERE IS ABSOLUTELY NO WARRANTY FOR
- THIS SOFTWARE.
-
- As a matter of courtesy, the authors request to be informed about uses
- this software has found, about bugs in this software, and about any
- improvements that may be of general interest.
-
- Berlin, 28.11.1994
- Jutta Degener
- Carsten Bormann
-
- *********************************************************************/
-
- /********* Start of inlined file: juce_OggVorbisHeader.h *********/
- // This file is included at the start of each Ogg-Vorbis .c file, just to do a few housekeeping
- // tasks..
-
- #ifdef _MSC_VER
- #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4305 4189 4706)
- #endif
- /********* End of inlined file: juce_OggVorbisHeader.h *********/
-
- #if JUCE_USE_OGGVORBIS
-
- #include <stdlib.h>
- #include <string.h>
- #include <math.h>
-
- /* Autocorrelation LPC coeff generation algorithm invented by
- N. Levinson in 1947, modified by J. Durbin in 1959. */
-
- /* Input : n elements of time doamin data
- Output: m lpc coefficients, excitation energy */
-
- float vorbis_lpc_from_data(float *data,float *lpci,int n,int m){
- double *aut=(double*)alloca(sizeof(*aut)*(m+1));
- double *lpc=(double*)alloca(sizeof(*lpc)*(m));
- double error;
- int i,j;
-
- /* autocorrelation, p+1 lag coefficients */
- j=m+1;
- while(j--){
- double d=0; /* double needed for accumulator depth */
- for(i=j;i<n;i++)d+=(double)data[i]*data[i-j];
- aut[j]=d;
- }
-
- /* Generate lpc coefficients from autocorr values */
-
- error=aut[0];
-
- for(i=0;i<m;i++){
- double r= -aut[i+1];
-
- if(error==0){
- memset(lpci,0,m*sizeof(*lpci));
- return 0;
- }
-
- /* Sum up this iteration's reflection coefficient; note that in
- Vorbis we don't save it. If anyone wants to recycle this code
- and needs reflection coefficients, save the results of 'r' from
- each iteration. */
-
- for(j=0;j<i;j++)r-=lpc[j]*aut[i-j];
- r/=error;
-
- /* Update LPC coefficients and total error */
-
- lpc[i]=r;
- for(j=0;j<i/2;j++){
- double tmp=lpc[j];
-
- lpc[j]+=r*lpc[i-1-j];
- lpc[i-1-j]+=r*tmp;
- }
- if(i%2)lpc[j]+=lpc[j]*r;
-
- error*=1.f-r*r;
- }
-
- for(j=0;j<m;j++)lpci[j]=(float)lpc[j];
-
- /* we need the error value to know how big an impulse to hit the
- filter with later */
-
- return error;
- }
-
- void vorbis_lpc_predict(float *coeff,float *prime,int m,
- float *data,long n){
-
- /* in: coeff[0...m-1] LPC coefficients
- prime[0...m-1] initial values (allocated size of n+m-1)
- out: data[0...n-1] data samples */
-
- long i,j,o,p;
- float y;
- float *work=(float*)alloca(sizeof(*work)*(m+n));
-
- if(!prime)
- for(i=0;i<m;i++)
- work[i]=0.f;
- else
- for(i=0;i<m;i++)
- work[i]=prime[i];
-
- for(i=0;i<n;i++){
- y=0;
- o=i;
- p=m;
- for(j=0;j<m;j++)
- y-=work[o++]*coeff[--p];
-
- data[i]=work[o]=y;
- }
- }
-
- #endif
- /********* End of inlined file: lpc.c *********/
-
- /********* Start of inlined file: lsp.c *********/
- /* Note that the lpc-lsp conversion finds the roots of polynomial with
- an iterative root polisher (CACM algorithm 283). It *is* possible
- to confuse this algorithm into not converging; that should only
- happen with absurdly closely spaced roots (very sharp peaks in the
- LPC f response) which in turn should be impossible in our use of
- the code. If this *does* happen anyway, it's a bug in the floor
- finder; find the cause of the confusion (probably a single bin
- spike or accidental near-float-limit resolution problems) and
- correct it. */
-
- /********* Start of inlined file: juce_OggVorbisHeader.h *********/
- // This file is included at the start of each Ogg-Vorbis .c file, just to do a few housekeeping
- // tasks..
-
- #ifdef _MSC_VER
- #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4305 4189 4706)
- #endif
- /********* End of inlined file: juce_OggVorbisHeader.h *********/
-
- #if JUCE_USE_OGGVORBIS
-
- #include <math.h>
- #include <string.h>
- #include <stdlib.h>
-
- /********* Start of inlined file: lookup.h *********/
- #ifndef _V_LOOKUP_H_
-
- #ifdef FLOAT_LOOKUP
- extern float vorbis_coslook(float a);
- extern float vorbis_invsqlook(float a);
- extern float vorbis_invsq2explook(int a);
- extern float vorbis_fromdBlook(float a);
- #endif
- #ifdef INT_LOOKUP
- extern long vorbis_invsqlook_i(long a,long e);
- extern long vorbis_coslook_i(long a);
- extern float vorbis_fromdBlook_i(long a);
- #endif
-
- #endif
- /********* End of inlined file: lookup.h *********/
-
- /* three possible LSP to f curve functions; the exact computation
- (float), a lookup based float implementation, and an integer
- implementation. The float lookup is likely the optimal choice on
- any machine with an FPU. The integer implementation is *not* fixed
- point (due to the need for a large dynamic range and thus a
- seperately tracked exponent) and thus much more complex than the
- relatively simple float implementations. It's mostly for future
- work on a fully fixed point implementation for processors like the
- ARM family. */
-
- /* undefine both for the 'old' but more precise implementation */
- #define FLOAT_LOOKUP
- #undef INT_LOOKUP
-
- #ifdef FLOAT_LOOKUP
-
- /********* Start of inlined file: lookup.c *********/
-
- /********* Start of inlined file: juce_OggVorbisHeader.h *********/
- // This file is included at the start of each Ogg-Vorbis .c file, just to do a few housekeeping
- // tasks..
-
- #ifdef _MSC_VER
- #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4305 4189 4706)
- #endif
- /********* End of inlined file: juce_OggVorbisHeader.h *********/
-
- #if JUCE_USE_OGGVORBIS
-
- #include <math.h>
-
- /********* Start of inlined file: lookup.h *********/
- #ifndef _V_LOOKUP_H_
-
- #ifdef FLOAT_LOOKUP
- extern float vorbis_coslook(float a);
- extern float vorbis_invsqlook(float a);
- extern float vorbis_invsq2explook(int a);
- extern float vorbis_fromdBlook(float a);
- #endif
- #ifdef INT_LOOKUP
- extern long vorbis_invsqlook_i(long a,long e);
- extern long vorbis_coslook_i(long a);
- extern float vorbis_fromdBlook_i(long a);
- #endif
-
- #endif
- /********* End of inlined file: lookup.h *********/
-
- /********* Start of inlined file: lookup_data.h *********/
- #ifndef _V_LOOKUP_DATA_H_
-
- #ifdef FLOAT_LOOKUP
- #define COS_LOOKUP_SZ 128
- static float COS_LOOKUP[COS_LOOKUP_SZ+1]={
- +1.0000000000000f,+0.9996988186962f,+0.9987954562052f,+0.9972904566787f,
- +0.9951847266722f,+0.9924795345987f,+0.9891765099648f,+0.9852776423889f,
- +0.9807852804032f,+0.9757021300385f,+0.9700312531945f,+0.9637760657954f,
- +0.9569403357322f,+0.9495281805930f,+0.9415440651830f,+0.9329927988347f,
- +0.9238795325113f,+0.9142097557035f,+0.9039892931234f,+0.8932243011955f,
- +0.8819212643484f,+0.8700869911087f,+0.8577286100003f,+0.8448535652497f,
- +0.8314696123025f,+0.8175848131516f,+0.8032075314806f,+0.7883464276266f,
- +0.7730104533627f,+0.7572088465065f,+0.7409511253550f,+0.7242470829515f,
- +0.7071067811865f,+0.6895405447371f,+0.6715589548470f,+0.6531728429538f,
- +0.6343932841636f,+0.6152315905806f,+0.5956993044924f,+0.5758081914178f,
- +0.5555702330196f,+0.5349976198871f,+0.5141027441932f,+0.4928981922298f,
- +0.4713967368260f,+0.4496113296546f,+0.4275550934303f,+0.4052413140050f,
- +0.3826834323651f,+0.3598950365350f,+0.3368898533922f,+0.3136817403989f,
- +0.2902846772545f,+0.2667127574749f,+0.2429801799033f,+0.2191012401569f,
- +0.1950903220161f,+0.1709618887603f,+0.1467304744554f,+0.1224106751992f,
- +0.0980171403296f,+0.0735645635997f,+0.0490676743274f,+0.0245412285229f,
- +0.0000000000000f,-0.0245412285229f,-0.0490676743274f,-0.0735645635997f,
- -0.0980171403296f,-0.1224106751992f,-0.1467304744554f,-0.1709618887603f,
- -0.1950903220161f,-0.2191012401569f,-0.2429801799033f,-0.2667127574749f,
- -0.2902846772545f,-0.3136817403989f,-0.3368898533922f,-0.3598950365350f,
- -0.3826834323651f,-0.4052413140050f,-0.4275550934303f,-0.4496113296546f,
- -0.4713967368260f,-0.4928981922298f,-0.5141027441932f,-0.5349976198871f,
- -0.5555702330196f,-0.5758081914178f,-0.5956993044924f,-0.6152315905806f,
- -0.6343932841636f,-0.6531728429538f,-0.6715589548470f,-0.6895405447371f,
- -0.7071067811865f,-0.7242470829515f,-0.7409511253550f,-0.7572088465065f,
- -0.7730104533627f,-0.7883464276266f,-0.8032075314806f,-0.8175848131516f,
- -0.8314696123025f,-0.8448535652497f,-0.8577286100003f,-0.8700869911087f,
- -0.8819212643484f,-0.8932243011955f,-0.9039892931234f,-0.9142097557035f,
- -0.9238795325113f,-0.9329927988347f,-0.9415440651830f,-0.9495281805930f,
- -0.9569403357322f,-0.9637760657954f,-0.9700312531945f,-0.9757021300385f,
- -0.9807852804032f,-0.9852776423889f,-0.9891765099648f,-0.9924795345987f,
- -0.9951847266722f,-0.9972904566787f,-0.9987954562052f,-0.9996988186962f,
- -1.0000000000000f,
- };
-
- #define INVSQ_LOOKUP_SZ 32
- static float INVSQ_LOOKUP[INVSQ_LOOKUP_SZ+1]={
- 1.414213562373f,1.392621247646f,1.371988681140f,1.352246807566f,
- 1.333333333333f,1.315191898443f,1.297771369046f,1.281025230441f,
- 1.264911064067f,1.249390095109f,1.234426799697f,1.219988562661f,
- 1.206045378311f,1.192569588000f,1.179535649239f,1.166919931983f,
- 1.154700538379f,1.142857142857f,1.131370849898f,1.120224067222f,
- 1.109400392450f,1.098884511590f,1.088662107904f,1.078719779941f,
- 1.069044967650f,1.059625885652f,1.050451462878f,1.041511287847f,
- 1.032795558989f,1.024295039463f,1.016001016002f,1.007905261358f,
- 1.000000000000f,
- };
-
- #define INVSQ2EXP_LOOKUP_MIN (-32)
- #define INVSQ2EXP_LOOKUP_MAX 32
- static float INVSQ2EXP_LOOKUP[INVSQ2EXP_LOOKUP_MAX-\
- INVSQ2EXP_LOOKUP_MIN+1]={
- 65536.f, 46340.95001f, 32768.f, 23170.47501f,
- 16384.f, 11585.2375f, 8192.f, 5792.618751f,
- 4096.f, 2896.309376f, 2048.f, 1448.154688f,
- 1024.f, 724.0773439f, 512.f, 362.038672f,
- 256.f, 181.019336f, 128.f, 90.50966799f,
- 64.f, 45.254834f, 32.f, 22.627417f,
- 16.f, 11.3137085f, 8.f, 5.656854249f,
- 4.f, 2.828427125f, 2.f, 1.414213562f,
- 1.f, 0.7071067812f, 0.5f, 0.3535533906f,
- 0.25f, 0.1767766953f, 0.125f, 0.08838834765f,
- 0.0625f, 0.04419417382f, 0.03125f, 0.02209708691f,
- 0.015625f, 0.01104854346f, 0.0078125f, 0.005524271728f,
- 0.00390625f, 0.002762135864f, 0.001953125f, 0.001381067932f,
- 0.0009765625f, 0.000690533966f, 0.00048828125f, 0.000345266983f,
- 0.000244140625f,0.0001726334915f,0.0001220703125f,8.631674575e-05f,
- 6.103515625e-05f,4.315837288e-05f,3.051757812e-05f,2.157918644e-05f,
- 1.525878906e-05f,
- };
-
- #endif
-
- #define FROMdB_LOOKUP_SZ 35
- #define FROMdB2_LOOKUP_SZ 32
- #define FROMdB_SHIFT 5
- #define FROMdB2_SHIFT 3
- #define FROMdB2_MASK 31
- static float FROMdB_LOOKUP[FROMdB_LOOKUP_SZ]={
- 1.f, 0.6309573445f, 0.3981071706f, 0.2511886432f,
- 0.1584893192f, 0.1f, 0.06309573445f, 0.03981071706f,
- 0.02511886432f, 0.01584893192f, 0.01f, 0.006309573445f,
- 0.003981071706f, 0.002511886432f, 0.001584893192f, 0.001f,
- 0.0006309573445f,0.0003981071706f,0.0002511886432f,0.0001584893192f,
- 0.0001f,6.309573445e-05f,3.981071706e-05f,2.511886432e-05f,
- 1.584893192e-05f, 1e-05f,6.309573445e-06f,3.981071706e-06f,
- 2.511886432e-06f,1.584893192e-06f, 1e-06f,6.309573445e-07f,
- 3.981071706e-07f,2.511886432e-07f,1.584893192e-07f,
- };
-
- static float FROMdB2_LOOKUP[FROMdB2_LOOKUP_SZ]={
- 0.9928302478f, 0.9786445908f, 0.9646616199f, 0.9508784391f,
- 0.9372921937f, 0.92390007f, 0.9106992942f, 0.8976871324f,
- 0.8848608897f, 0.8722179097f, 0.8597555737f, 0.8474713009f,
- 0.835362547f, 0.8234268041f, 0.8116616003f, 0.8000644989f,
- 0.7886330981f, 0.7773650302f, 0.7662579617f, 0.755309592f,
- 0.7445176537f, 0.7338799116f, 0.7233941627f, 0.7130582353f,
- 0.7028699885f, 0.6928273125f, 0.6829281272f, 0.6731703824f,
- 0.6635520573f, 0.6540711597f, 0.6447257262f, 0.6355138211f,
- };
-
- #ifdef INT_LOOKUP
-
- #define INVSQ_LOOKUP_I_SHIFT 10
- #define INVSQ_LOOKUP_I_MASK 1023
- static long INVSQ_LOOKUP_I[64+1]={
- 92682l, 91966l, 91267l, 90583l,
- 89915l, 89261l, 88621l, 87995l,
- 87381l, 86781l, 86192l, 85616l,
- 85051l, 84497l, 83953l, 83420l,
- 82897l, 82384l, 81880l, 81385l,
- 80899l, 80422l, 79953l, 79492l,
- 79039l, 78594l, 78156l, 77726l,
- 77302l, 76885l, 76475l, 76072l,
- 75674l, 75283l, 74898l, 74519l,
- 74146l, 73778l, 73415l, 73058l,
- 72706l, 72359l, 72016l, 71679l,
- 71347l, 71019l, 70695l, 70376l,
- 70061l, 69750l, 69444l, 69141l,
- 68842l, 68548l, 68256l, 67969l,
- 67685l, 67405l, 67128l, 66855l,
- 66585l, 66318l, 66054l, 65794l,
- 65536l,
- };
-
- #define COS_LOOKUP_I_SHIFT 9
- #define COS_LOOKUP_I_MASK 511
- #define COS_LOOKUP_I_SZ 128
- static long COS_LOOKUP_I[COS_LOOKUP_I_SZ+1]={
- 16384l, 16379l, 16364l, 16340l,
- 16305l, 16261l, 16207l, 16143l,
- 16069l, 15986l, 15893l, 15791l,
- 15679l, 15557l, 15426l, 15286l,
- 15137l, 14978l, 14811l, 14635l,
- 14449l, 14256l, 14053l, 13842l,
- 13623l, 13395l, 13160l, 12916l,
- 12665l, 12406l, 12140l, 11866l,
- 11585l, 11297l, 11003l, 10702l,
- 10394l, 10080l, 9760l, 9434l,
- 9102l, 8765l, 8423l, 8076l,
- 7723l, 7366l, 7005l, 6639l,
- 6270l, 5897l, 5520l, 5139l,
- 4756l, 4370l, 3981l, 3590l,
- 3196l, 2801l, 2404l, 2006l,
- 1606l, 1205l, 804l, 402l,
- 0l, -401l, -803l, -1204l,
- -1605l, -2005l, -2403l, -2800l,
- -3195l, -3589l, -3980l, -4369l,
- -4755l, -5138l, -5519l, -5896l,
- -6269l, -6638l, -7004l, -7365l,
- -7722l, -8075l, -8422l, -8764l,
- -9101l, -9433l, -9759l, -10079l,
- -10393l, -10701l, -11002l, -11296l,
- -11584l, -11865l, -12139l, -12405l,
- -12664l, -12915l, -13159l, -13394l,
- -13622l, -13841l, -14052l, -14255l,
- -14448l, -14634l, -14810l, -14977l,
- -15136l, -15285l, -15425l, -15556l,
- -15678l, -15790l, -15892l, -15985l,
- -16068l, -16142l, -16206l, -16260l,
- -16304l, -16339l, -16363l, -16378l,
- -16383l,
- };
-
- #endif
-
- #endif
- /********* End of inlined file: lookup_data.h *********/
-
- #ifdef FLOAT_LOOKUP
-
- /* interpolated lookup based cos function, domain 0 to PI only */
- float vorbis_coslook(float a){
- double d=a*(.31830989*(float)COS_LOOKUP_SZ);
- int i=vorbis_ftoi(d-.5);
-
- return COS_LOOKUP[i]+ (d-i)*(COS_LOOKUP[i+1]-COS_LOOKUP[i]);
- }
-
- /* interpolated 1./sqrt(p) where .5 <= p < 1. */
- float vorbis_invsqlook(float a){
- double d=a*(2.f*(float)INVSQ_LOOKUP_SZ)-(float)INVSQ_LOOKUP_SZ;
- int i=vorbis_ftoi(d-.5f);
- return INVSQ_LOOKUP[i]+ (d-i)*(INVSQ_LOOKUP[i+1]-INVSQ_LOOKUP[i]);
- }
-
- /* interpolated 1./sqrt(p) where .5 <= p < 1. */
- float vorbis_invsq2explook(int a){
- return INVSQ2EXP_LOOKUP[a-INVSQ2EXP_LOOKUP_MIN];
- }
-
- #include <stdio.h>
- /* interpolated lookup based fromdB function, domain -140dB to 0dB only */
- float vorbis_fromdBlook(float a){
- int i=vorbis_ftoi(a*((float)(-(1<<FROMdB2_SHIFT)))-.5f);
- return (i<0)?1.f:
- ((i>=(FROMdB_LOOKUP_SZ<<FROMdB_SHIFT))?0.f:
- FROMdB_LOOKUP[i>>FROMdB_SHIFT]*FROMdB2_LOOKUP[i&FROMdB2_MASK]);
- }
-
- #endif
-
- #ifdef INT_LOOKUP
- /* interpolated 1./sqrt(p) where .5 <= a < 1. (.100000... to .111111...) in
- 16.16 format
-
- returns in m.8 format */
- long vorbis_invsqlook_i(long a,long e){
- long i=(a&0x7fff)>>(INVSQ_LOOKUP_I_SHIFT-1);
- long d=(a&INVSQ_LOOKUP_I_MASK)<<(16-INVSQ_LOOKUP_I_SHIFT); /* 0.16 */
- long val=INVSQ_LOOKUP_I[i]- /* 1.16 */
- (((INVSQ_LOOKUP_I[i]-INVSQ_LOOKUP_I[i+1])* /* 0.16 */
- d)>>16); /* result 1.16 */
-
- e+=32;
- if(e&1)val=(val*5792)>>13; /* multiply val by 1/sqrt(2) */
- e=(e>>1)-8;
-
- return(val>>e);
- }
-
- /* interpolated lookup based fromdB function, domain -140dB to 0dB only */
- /* a is in n.12 format */
- float vorbis_fromdBlook_i(long a){
- int i=(-a)>>(12-FROMdB2_SHIFT);
- return (i<0)?1.f:
- ((i>=(FROMdB_LOOKUP_SZ<<FROMdB_SHIFT))?0.f:
- FROMdB_LOOKUP[i>>FROMdB_SHIFT]*FROMdB2_LOOKUP[i&FROMdB2_MASK]);
- }
-
- /* interpolated lookup based cos function, domain 0 to PI only */
- /* a is in 0.16 format, where 0==0, 2^^16-1==PI, return 0.14 */
- long vorbis_coslook_i(long a){
- int i=a>>COS_LOOKUP_I_SHIFT;
- int d=a&COS_LOOKUP_I_MASK;
- return COS_LOOKUP_I[i]- ((d*(COS_LOOKUP_I[i]-COS_LOOKUP_I[i+1]))>>
- COS_LOOKUP_I_SHIFT);
- }
-
- #endif
-
- #endif
- /********* End of inlined file: lookup.c *********/
-
- /* catch this in the build system; we #include for
- compilers (like gcc) that can't inline across
- modules */
-
- /* side effect: changes *lsp to cosines of lsp */
- void vorbis_lsp_to_curve(float *curve,int *map,int n,int ln,float *lsp,int m,
- float amp,float ampoffset){
- int i;
- float wdel=M_PI/ln;
- vorbis_fpu_control fpu;
- (void) fpu; // to avoid an unused variable warning
-
- vorbis_fpu_setround(&fpu);
- for(i=0;i<m;i++)lsp[i]=vorbis_coslook(lsp[i]);
-
- i=0;
- while(i<n){
- int k=map[i];
- int qexp;
- float p=.7071067812f;
- float q=.7071067812f;
- float w=vorbis_coslook(wdel*k);
- float *ftmp=lsp;
- int c=m>>1;
-
- do{
- q*=ftmp[0]-w;
- p*=ftmp[1]-w;
- ftmp+=2;
- }while(--c);
-
- if(m&1){
- /* odd order filter; slightly assymetric */
- /* the last coefficient */
- q*=ftmp[0]-w;
- q*=q;
- p*=p*(1.f-w*w);
- }else{
- /* even order filter; still symmetric */
- q*=q*(1.f+w);
- p*=p*(1.f-w);
- }
-
- q=frexp(p+q,&qexp);
- q=vorbis_fromdBlook(amp*
- vorbis_invsqlook(q)*
- vorbis_invsq2explook(qexp+m)-
- ampoffset);
-
- do{
- curve[i++]*=q;
- }while(map[i]==k);
- }
- vorbis_fpu_restore(fpu);
- }
-
- #else
-
- #ifdef INT_LOOKUP
-
- /********* Start of inlined file: lookup.c *********/
-
- /********* Start of inlined file: juce_OggVorbisHeader.h *********/
- // This file is included at the start of each Ogg-Vorbis .c file, just to do a few housekeeping
- // tasks..
-
- #ifdef _MSC_VER
- #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4305 4189 4706)
- #endif
- /********* End of inlined file: juce_OggVorbisHeader.h *********/
-
- #if JUCE_USE_OGGVORBIS
-
- #include <math.h>
-
- /********* Start of inlined file: lookup.h *********/
- #ifndef _V_LOOKUP_H_
-
- #ifdef FLOAT_LOOKUP
- extern float vorbis_coslook(float a);
- extern float vorbis_invsqlook(float a);
- extern float vorbis_invsq2explook(int a);
- extern float vorbis_fromdBlook(float a);
- #endif
- #ifdef INT_LOOKUP
- extern long vorbis_invsqlook_i(long a,long e);
- extern long vorbis_coslook_i(long a);
- extern float vorbis_fromdBlook_i(long a);
- #endif
-
- #endif
- /********* End of inlined file: lookup.h *********/
-
- /********* Start of inlined file: lookup_data.h *********/
- #ifndef _V_LOOKUP_DATA_H_
-
- #ifdef FLOAT_LOOKUP
- #define COS_LOOKUP_SZ 128
- static float COS_LOOKUP[COS_LOOKUP_SZ+1]={
- +1.0000000000000f,+0.9996988186962f,+0.9987954562052f,+0.9972904566787f,
- +0.9951847266722f,+0.9924795345987f,+0.9891765099648f,+0.9852776423889f,
- +0.9807852804032f,+0.9757021300385f,+0.9700312531945f,+0.9637760657954f,
- +0.9569403357322f,+0.9495281805930f,+0.9415440651830f,+0.9329927988347f,
- +0.9238795325113f,+0.9142097557035f,+0.9039892931234f,+0.8932243011955f,
- +0.8819212643484f,+0.8700869911087f,+0.8577286100003f,+0.8448535652497f,
- +0.8314696123025f,+0.8175848131516f,+0.8032075314806f,+0.7883464276266f,
- +0.7730104533627f,+0.7572088465065f,+0.7409511253550f,+0.7242470829515f,
- +0.7071067811865f,+0.6895405447371f,+0.6715589548470f,+0.6531728429538f,
- +0.6343932841636f,+0.6152315905806f,+0.5956993044924f,+0.5758081914178f,
- +0.5555702330196f,+0.5349976198871f,+0.5141027441932f,+0.4928981922298f,
- +0.4713967368260f,+0.4496113296546f,+0.4275550934303f,+0.4052413140050f,
- +0.3826834323651f,+0.3598950365350f,+0.3368898533922f,+0.3136817403989f,
- +0.2902846772545f,+0.2667127574749f,+0.2429801799033f,+0.2191012401569f,
- +0.1950903220161f,+0.1709618887603f,+0.1467304744554f,+0.1224106751992f,
- +0.0980171403296f,+0.0735645635997f,+0.0490676743274f,+0.0245412285229f,
- +0.0000000000000f,-0.0245412285229f,-0.0490676743274f,-0.0735645635997f,
- -0.0980171403296f,-0.1224106751992f,-0.1467304744554f,-0.1709618887603f,
- -0.1950903220161f,-0.2191012401569f,-0.2429801799033f,-0.2667127574749f,
- -0.2902846772545f,-0.3136817403989f,-0.3368898533922f,-0.3598950365350f,
- -0.3826834323651f,-0.4052413140050f,-0.4275550934303f,-0.4496113296546f,
- -0.4713967368260f,-0.4928981922298f,-0.5141027441932f,-0.5349976198871f,
- -0.5555702330196f,-0.5758081914178f,-0.5956993044924f,-0.6152315905806f,
- -0.6343932841636f,-0.6531728429538f,-0.6715589548470f,-0.6895405447371f,
- -0.7071067811865f,-0.7242470829515f,-0.7409511253550f,-0.7572088465065f,
- -0.7730104533627f,-0.7883464276266f,-0.8032075314806f,-0.8175848131516f,
- -0.8314696123025f,-0.8448535652497f,-0.8577286100003f,-0.8700869911087f,
- -0.8819212643484f,-0.8932243011955f,-0.9039892931234f,-0.9142097557035f,
- -0.9238795325113f,-0.9329927988347f,-0.9415440651830f,-0.9495281805930f,
- -0.9569403357322f,-0.9637760657954f,-0.9700312531945f,-0.9757021300385f,
- -0.9807852804032f,-0.9852776423889f,-0.9891765099648f,-0.9924795345987f,
- -0.9951847266722f,-0.9972904566787f,-0.9987954562052f,-0.9996988186962f,
- -1.0000000000000f,
- };
-
- #define INVSQ_LOOKUP_SZ 32
- static float INVSQ_LOOKUP[INVSQ_LOOKUP_SZ+1]={
- 1.414213562373f,1.392621247646f,1.371988681140f,1.352246807566f,
- 1.333333333333f,1.315191898443f,1.297771369046f,1.281025230441f,
- 1.264911064067f,1.249390095109f,1.234426799697f,1.219988562661f,
- 1.206045378311f,1.192569588000f,1.179535649239f,1.166919931983f,
- 1.154700538379f,1.142857142857f,1.131370849898f,1.120224067222f,
- 1.109400392450f,1.098884511590f,1.088662107904f,1.078719779941f,
- 1.069044967650f,1.059625885652f,1.050451462878f,1.041511287847f,
- 1.032795558989f,1.024295039463f,1.016001016002f,1.007905261358f,
- 1.000000000000f,
- };
-
- #define INVSQ2EXP_LOOKUP_MIN (-32)
- #define INVSQ2EXP_LOOKUP_MAX 32
- static float INVSQ2EXP_LOOKUP[INVSQ2EXP_LOOKUP_MAX-\
- INVSQ2EXP_LOOKUP_MIN+1]={
- 65536.f, 46340.95001f, 32768.f, 23170.47501f,
- 16384.f, 11585.2375f, 8192.f, 5792.618751f,
- 4096.f, 2896.309376f, 2048.f, 1448.154688f,
- 1024.f, 724.0773439f, 512.f, 362.038672f,
- 256.f, 181.019336f, 128.f, 90.50966799f,
- 64.f, 45.254834f, 32.f, 22.627417f,
- 16.f, 11.3137085f, 8.f, 5.656854249f,
- 4.f, 2.828427125f, 2.f, 1.414213562f,
- 1.f, 0.7071067812f, 0.5f, 0.3535533906f,
- 0.25f, 0.1767766953f, 0.125f, 0.08838834765f,
- 0.0625f, 0.04419417382f, 0.03125f, 0.02209708691f,
- 0.015625f, 0.01104854346f, 0.0078125f, 0.005524271728f,
- 0.00390625f, 0.002762135864f, 0.001953125f, 0.001381067932f,
- 0.0009765625f, 0.000690533966f, 0.00048828125f, 0.000345266983f,
- 0.000244140625f,0.0001726334915f,0.0001220703125f,8.631674575e-05f,
- 6.103515625e-05f,4.315837288e-05f,3.051757812e-05f,2.157918644e-05f,
- 1.525878906e-05f,
- };
-
- #endif
-
- #define FROMdB_LOOKUP_SZ 35
- #define FROMdB2_LOOKUP_SZ 32
- #define FROMdB_SHIFT 5
- #define FROMdB2_SHIFT 3
- #define FROMdB2_MASK 31
- static float FROMdB_LOOKUP[FROMdB_LOOKUP_SZ]={
- 1.f, 0.6309573445f, 0.3981071706f, 0.2511886432f,
- 0.1584893192f, 0.1f, 0.06309573445f, 0.03981071706f,
- 0.02511886432f, 0.01584893192f, 0.01f, 0.006309573445f,
- 0.003981071706f, 0.002511886432f, 0.001584893192f, 0.001f,
- 0.0006309573445f,0.0003981071706f,0.0002511886432f,0.0001584893192f,
- 0.0001f,6.309573445e-05f,3.981071706e-05f,2.511886432e-05f,
- 1.584893192e-05f, 1e-05f,6.309573445e-06f,3.981071706e-06f,
- 2.511886432e-06f,1.584893192e-06f, 1e-06f,6.309573445e-07f,
- 3.981071706e-07f,2.511886432e-07f,1.584893192e-07f,
- };
-
- static float FROMdB2_LOOKUP[FROMdB2_LOOKUP_SZ]={
- 0.9928302478f, 0.9786445908f, 0.9646616199f, 0.9508784391f,
- 0.9372921937f, 0.92390007f, 0.9106992942f, 0.8976871324f,
- 0.8848608897f, 0.8722179097f, 0.8597555737f, 0.8474713009f,
- 0.835362547f, 0.8234268041f, 0.8116616003f, 0.8000644989f,
- 0.7886330981f, 0.7773650302f, 0.7662579617f, 0.755309592f,
- 0.7445176537f, 0.7338799116f, 0.7233941627f, 0.7130582353f,
- 0.7028699885f, 0.6928273125f, 0.6829281272f, 0.6731703824f,
- 0.6635520573f, 0.6540711597f, 0.6447257262f, 0.6355138211f,
- };
-
- #ifdef INT_LOOKUP
-
- #define INVSQ_LOOKUP_I_SHIFT 10
- #define INVSQ_LOOKUP_I_MASK 1023
- static long INVSQ_LOOKUP_I[64+1]={
- 92682l, 91966l, 91267l, 90583l,
- 89915l, 89261l, 88621l, 87995l,
- 87381l, 86781l, 86192l, 85616l,
- 85051l, 84497l, 83953l, 83420l,
- 82897l, 82384l, 81880l, 81385l,
- 80899l, 80422l, 79953l, 79492l,
- 79039l, 78594l, 78156l, 77726l,
- 77302l, 76885l, 76475l, 76072l,
- 75674l, 75283l, 74898l, 74519l,
- 74146l, 73778l, 73415l, 73058l,
- 72706l, 72359l, 72016l, 71679l,
- 71347l, 71019l, 70695l, 70376l,
- 70061l, 69750l, 69444l, 69141l,
- 68842l, 68548l, 68256l, 67969l,
- 67685l, 67405l, 67128l, 66855l,
- 66585l, 66318l, 66054l, 65794l,
- 65536l,
- };
-
- #define COS_LOOKUP_I_SHIFT 9
- #define COS_LOOKUP_I_MASK 511
- #define COS_LOOKUP_I_SZ 128
- static long COS_LOOKUP_I[COS_LOOKUP_I_SZ+1]={
- 16384l, 16379l, 16364l, 16340l,
- 16305l, 16261l, 16207l, 16143l,
- 16069l, 15986l, 15893l, 15791l,
- 15679l, 15557l, 15426l, 15286l,
- 15137l, 14978l, 14811l, 14635l,
- 14449l, 14256l, 14053l, 13842l,
- 13623l, 13395l, 13160l, 12916l,
- 12665l, 12406l, 12140l, 11866l,
- 11585l, 11297l, 11003l, 10702l,
- 10394l, 10080l, 9760l, 9434l,
- 9102l, 8765l, 8423l, 8076l,
- 7723l, 7366l, 7005l, 6639l,
- 6270l, 5897l, 5520l, 5139l,
- 4756l, 4370l, 3981l, 3590l,
- 3196l, 2801l, 2404l, 2006l,
- 1606l, 1205l, 804l, 402l,
- 0l, -401l, -803l, -1204l,
- -1605l, -2005l, -2403l, -2800l,
- -3195l, -3589l, -3980l, -4369l,
- -4755l, -5138l, -5519l, -5896l,
- -6269l, -6638l, -7004l, -7365l,
- -7722l, -8075l, -8422l, -8764l,
- -9101l, -9433l, -9759l, -10079l,
- -10393l, -10701l, -11002l, -11296l,
- -11584l, -11865l, -12139l, -12405l,
- -12664l, -12915l, -13159l, -13394l,
- -13622l, -13841l, -14052l, -14255l,
- -14448l, -14634l, -14810l, -14977l,
- -15136l, -15285l, -15425l, -15556l,
- -15678l, -15790l, -15892l, -15985l,
- -16068l, -16142l, -16206l, -16260l,
- -16304l, -16339l, -16363l, -16378l,
- -16383l,
- };
-
- #endif
-
- #endif
- /********* End of inlined file: lookup_data.h *********/
-
- #ifdef FLOAT_LOOKUP
-
- /* interpolated lookup based cos function, domain 0 to PI only */
- float vorbis_coslook(float a){
- double d=a*(.31830989*(float)COS_LOOKUP_SZ);
- int i=vorbis_ftoi(d-.5);
-
- return COS_LOOKUP[i]+ (d-i)*(COS_LOOKUP[i+1]-COS_LOOKUP[i]);
- }
-
- /* interpolated 1./sqrt(p) where .5 <= p < 1. */
- float vorbis_invsqlook(float a){
- double d=a*(2.f*(float)INVSQ_LOOKUP_SZ)-(float)INVSQ_LOOKUP_SZ;
- int i=vorbis_ftoi(d-.5f);
- return INVSQ_LOOKUP[i]+ (d-i)*(INVSQ_LOOKUP[i+1]-INVSQ_LOOKUP[i]);
- }
-
- /* interpolated 1./sqrt(p) where .5 <= p < 1. */
- float vorbis_invsq2explook(int a){
- return INVSQ2EXP_LOOKUP[a-INVSQ2EXP_LOOKUP_MIN];
- }
-
- #include <stdio.h>
- /* interpolated lookup based fromdB function, domain -140dB to 0dB only */
- float vorbis_fromdBlook(float a){
- int i=vorbis_ftoi(a*((float)(-(1<<FROMdB2_SHIFT)))-.5f);
- return (i<0)?1.f:
- ((i>=(FROMdB_LOOKUP_SZ<<FROMdB_SHIFT))?0.f:
- FROMdB_LOOKUP[i>>FROMdB_SHIFT]*FROMdB2_LOOKUP[i&FROMdB2_MASK]);
- }
-
- #endif
-
- #ifdef INT_LOOKUP
- /* interpolated 1./sqrt(p) where .5 <= a < 1. (.100000... to .111111...) in
- 16.16 format
-
- returns in m.8 format */
- long vorbis_invsqlook_i(long a,long e){
- long i=(a&0x7fff)>>(INVSQ_LOOKUP_I_SHIFT-1);
- long d=(a&INVSQ_LOOKUP_I_MASK)<<(16-INVSQ_LOOKUP_I_SHIFT); /* 0.16 */
- long val=INVSQ_LOOKUP_I[i]- /* 1.16 */
- (((INVSQ_LOOKUP_I[i]-INVSQ_LOOKUP_I[i+1])* /* 0.16 */
- d)>>16); /* result 1.16 */
-
- e+=32;
- if(e&1)val=(val*5792)>>13; /* multiply val by 1/sqrt(2) */
- e=(e>>1)-8;
-
- return(val>>e);
- }
-
- /* interpolated lookup based fromdB function, domain -140dB to 0dB only */
- /* a is in n.12 format */
- float vorbis_fromdBlook_i(long a){
- int i=(-a)>>(12-FROMdB2_SHIFT);
- return (i<0)?1.f:
- ((i>=(FROMdB_LOOKUP_SZ<<FROMdB_SHIFT))?0.f:
- FROMdB_LOOKUP[i>>FROMdB_SHIFT]*FROMdB2_LOOKUP[i&FROMdB2_MASK]);
- }
-
- /* interpolated lookup based cos function, domain 0 to PI only */
- /* a is in 0.16 format, where 0==0, 2^^16-1==PI, return 0.14 */
- long vorbis_coslook_i(long a){
- int i=a>>COS_LOOKUP_I_SHIFT;
- int d=a&COS_LOOKUP_I_MASK;
- return COS_LOOKUP_I[i]- ((d*(COS_LOOKUP_I[i]-COS_LOOKUP_I[i+1]))>>
- COS_LOOKUP_I_SHIFT);
- }
-
- #endif
-
- #endif
- /********* End of inlined file: lookup.c *********/
-
- /* catch this in the build system; we #include for
- compilers (like gcc) that can't inline across
- modules */
-
- static int MLOOP_1[64]={
- 0,10,11,11, 12,12,12,12, 13,13,13,13, 13,13,13,13,
- 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,15,
- };
-
- static int MLOOP_2[64]={
- 0,4,5,5, 6,6,6,6, 7,7,7,7, 7,7,7,7,
- 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,9, 9,9,9,9, 9,9,9,9, 9,9,9,9,
- };
-
- static int MLOOP_3[8]={0,1,2,2,3,3,3,3};
-
- /* side effect: changes *lsp to cosines of lsp */
- void vorbis_lsp_to_curve(float *curve,int *map,int n,int ln,float *lsp,int m,
- float amp,float ampoffset){
-
- /* 0 <= m < 256 */
-
- /* set up for using all int later */
- int i;
- int ampoffseti=rint(ampoffset*4096.f);
- int ampi=rint(amp*16.f);
- long *ilsp=alloca(m*sizeof(*ilsp));
- for(i=0;i<m;i++)ilsp[i]=vorbis_coslook_i(lsp[i]/M_PI*65536.f+.5f);
-
- i=0;
- while(i<n){
- int j,k=map[i];
- unsigned long pi=46341; /* 2**-.5 in 0.16 */
- unsigned long qi=46341;
- int qexp=0,shift;
- long wi=vorbis_coslook_i(k*65536/ln);
-
- qi*=labs(ilsp[0]-wi);
- pi*=labs(ilsp[1]-wi);
-
- for(j=3;j<m;j+=2){
- if(!(shift=MLOOP_1[(pi|qi)>>25]))
- if(!(shift=MLOOP_2[(pi|qi)>>19]))
- shift=MLOOP_3[(pi|qi)>>16];
- qi=(qi>>shift)*labs(ilsp[j-1]-wi);
- pi=(pi>>shift)*labs(ilsp[j]-wi);
- qexp+=shift;
- }
- if(!(shift=MLOOP_1[(pi|qi)>>25]))
- if(!(shift=MLOOP_2[(pi|qi)>>19]))
- shift=MLOOP_3[(pi|qi)>>16];
-
- /* pi,qi normalized collectively, both tracked using qexp */
-
- if(m&1){
- /* odd order filter; slightly assymetric */
- /* the last coefficient */
- qi=(qi>>shift)*labs(ilsp[j-1]-wi);
- pi=(pi>>shift)<<14;
- qexp+=shift;
-
- if(!(shift=MLOOP_1[(pi|qi)>>25]))
- if(!(shift=MLOOP_2[(pi|qi)>>19]))
- shift=MLOOP_3[(pi|qi)>>16];
-
- pi>>=shift;
- qi>>=shift;
- qexp+=shift-14*((m+1)>>1);
-
- pi=((pi*pi)>>16);
- qi=((qi*qi)>>16);
- qexp=qexp*2+m;
-
- pi*=(1<<14)-((wi*wi)>>14);
- qi+=pi>>14;
-
- }else{
- /* even order filter; still symmetric */
-
- /* p*=p(1-w), q*=q(1+w), let normalization drift because it isn't
- worth tracking step by step */
-
- pi>>=shift;
- qi>>=shift;
- qexp+=shift-7*m;
-
- pi=((pi*pi)>>16);
- qi=((qi*qi)>>16);
- qexp=qexp*2+m;
-
- pi*=(1<<14)-wi;
- qi*=(1<<14)+wi;
- qi=(qi+pi)>>14;
-
- }
-
- /* we've let the normalization drift because it wasn't important;
- however, for the lookup, things must be normalized again. We
- need at most one right shift or a number of left shifts */
-
- if(qi&0xffff0000){ /* checks for 1.xxxxxxxxxxxxxxxx */
- qi>>=1; qexp++;
- }else
- while(qi && !(qi&0x8000)){ /* checks for 0.0xxxxxxxxxxxxxxx or less*/
- qi<<=1; qexp--;
- }
-
- amp=vorbis_fromdBlook_i(ampi* /* n.4 */
- vorbis_invsqlook_i(qi,qexp)-
- /* m.8, m+n<=8 */
- ampoffseti); /* 8.12[0] */
-
- curve[i]*=amp;
- while(map[++i]==k)curve[i]*=amp;
- }
- }
-
- #else
-
- /* old, nonoptimized but simple version for any poor sap who needs to
- figure out what the hell this code does, or wants the other
- fraction of a dB precision */
-
- /* side effect: changes *lsp to cosines of lsp */
- void vorbis_lsp_to_curve(float *curve,int *map,int n,int ln,float *lsp,int m,
- float amp,float ampoffset){
- int i;
- float wdel=M_PI/ln;
- for(i=0;i<m;i++)lsp[i]=2.f*cos(lsp[i]);
-
- i=0;
- while(i<n){
- int j,k=map[i];
- float p=.5f;
- float q=.5f;
- float w=2.f*cos(wdel*k);
- for(j=1;j<m;j+=2){
- q *= w-lsp[j-1];
- p *= w-lsp[j];
- }
- if(j==m){
- /* odd order filter; slightly assymetric */
- /* the last coefficient */
- q*=w-lsp[j-1];
- p*=p*(4.f-w*w);
- q*=q;
- }else{
- /* even order filter; still symmetric */
- p*=p*(2.f-w);
- q*=q*(2.f+w);
- }
-
- q=fromdB(amp/sqrt(p+q)-ampoffset);
-
- curve[i]*=q;
- while(map[++i]==k)curve[i]*=q;
- }
- }
-
- #endif
- #endif
-
- static void cheby(float *g, int ord) {
- int i, j;
-
- g[0] *= .5f;
- for(i=2; i<= ord; i++) {
- for(j=ord; j >= i; j--) {
- g[j-2] -= g[j];
- g[j] += g[j];
- }
- }
- }
-
- static int comp(const void *a,const void *b){
- return (*(float *)a<*(float *)b)-(*(float *)a>*(float *)b);
- }
-
- /* Newton-Raphson-Maehly actually functioned as a decent root finder,
- but there are root sets for which it gets into limit cycles
- (exacerbated by zero suppression) and fails. We can't afford to
- fail, even if the failure is 1 in 100,000,000, so we now use
- Laguerre and later polish with Newton-Raphson (which can then
- afford to fail) */
-
- #define EPSILON 10e-7
- static int Laguerre_With_Deflation(float *a,int ord,float *r){
- int i,m;
- double lastdelta=0.f;
- double *defl=(double*)alloca(sizeof(*defl)*(ord+1));
- for(i=0;i<=ord;i++)defl[i]=a[i];
-
- for(m=ord;m>0;m--){
- double newx=0.f,delta;
-
- /* iterate a root */
- while(1){
- double p=defl[m],pp=0.f,ppp=0.f,denom;
-
- /* eval the polynomial and its first two derivatives */
- for(i=m;i>0;i--){
- ppp = newx*ppp + pp;
- pp = newx*pp + p;
- p = newx*p + defl[i-1];
- }
-
- /* Laguerre's method */
- denom=(m-1) * ((m-1)*pp*pp - m*p*ppp);
- if(denom<0)
- return(-1); /* complex root! The LPC generator handed us a bad filter */
-
- if(pp>0){
- denom = pp + sqrt(denom);
- if(denom<EPSILON)denom=EPSILON;
- }else{
- denom = pp - sqrt(denom);
- if(denom>-(EPSILON))denom=-(EPSILON);
- }
-
- delta = m*p/denom;
- newx -= delta;
-
- if(delta<0.f)delta*=-1;
-
- if(fabs(delta/newx)<10e-12)break;
- lastdelta=delta;
- }
-
- r[m-1]=newx;
-
- /* forward deflation */
-
- for(i=m;i>0;i--)
- defl[i-1]+=newx*defl[i];
- defl++;
-
- }
- return(0);
- }
-
- /* for spit-and-polish only */
- static int Newton_Raphson(float *a,int ord,float *r){
- int i, k, count=0;
- double error=1.f;
- double *root=(double*)alloca(ord*sizeof(*root));
-
- for(i=0; i<ord;i++) root[i] = r[i];
-
- while(error>1e-20){
- error=0;
-
- for(i=0; i<ord; i++) { /* Update each point. */
- double pp=0.,delta;
- double rooti=root[i];
- double p=a[ord];
- for(k=ord-1; k>= 0; k--) {
-
- pp= pp* rooti + p;
- p = p * rooti + a[k];
- }
-
- delta = p/pp;
- root[i] -= delta;
- error+= delta*delta;
- }
-
- if(count>40)return(-1);
-
- count++;
- }
-
- /* Replaced the original bubble sort with a real sort. With your
- help, we can eliminate the bubble sort in our lifetime. --Monty */
-
- for(i=0; i<ord;i++) r[i] = root[i];
- return(0);
- }
-
- /* Convert lpc coefficients to lsp coefficients */
- int vorbis_lpc_to_lsp(float *lpc,float *lsp,int m){
- int order2=(m+1)>>1;
- int g1_order,g2_order;
- float *g1=(float*)alloca(sizeof(*g1)*(order2+1));
- float *g2=(float*)alloca(sizeof(*g2)*(order2+1));
- float *g1r=(float*)alloca(sizeof(*g1r)*(order2+1));
- float *g2r=(float*)alloca(sizeof(*g2r)*(order2+1));
- int i;
-
- /* even and odd are slightly different base cases */
- g1_order=(m+1)>>1;
- g2_order=(m) >>1;
-
- /* Compute the lengths of the x polynomials. */
- /* Compute the first half of K & R F1 & F2 polynomials. */
- /* Compute half of the symmetric and antisymmetric polynomials. */
- /* Remove the roots at +1 and -1. */
-
- g1[g1_order] = 1.f;
- for(i=1;i<=g1_order;i++) g1[g1_order-i] = lpc[i-1]+lpc[m-i];
- g2[g2_order] = 1.f;
- for(i=1;i<=g2_order;i++) g2[g2_order-i] = lpc[i-1]-lpc[m-i];
-
- if(g1_order>g2_order){
- for(i=2; i<=g2_order;i++) g2[g2_order-i] += g2[g2_order-i+2];
- }else{
- for(i=1; i<=g1_order;i++) g1[g1_order-i] -= g1[g1_order-i+1];
- for(i=1; i<=g2_order;i++) g2[g2_order-i] += g2[g2_order-i+1];
- }
-
- /* Convert into polynomials in cos(alpha) */
- cheby(g1,g1_order);
- cheby(g2,g2_order);
-
- /* Find the roots of the 2 even polynomials.*/
- if(Laguerre_With_Deflation(g1,g1_order,g1r) ||
- Laguerre_With_Deflation(g2,g2_order,g2r))
- return(-1);
-
- Newton_Raphson(g1,g1_order,g1r); /* if it fails, it leaves g1r alone */
- Newton_Raphson(g2,g2_order,g2r); /* if it fails, it leaves g2r alone */
-
- qsort(g1r,g1_order,sizeof(*g1r),comp);
- qsort(g2r,g2_order,sizeof(*g2r),comp);
-
- for(i=0;i<g1_order;i++)
- lsp[i*2] = acos(g1r[i]);
-
- for(i=0;i<g2_order;i++)
- lsp[i*2+1] = acos(g2r[i]);
- return(0);
- }
-
- #endif
- /********* End of inlined file: lsp.c *********/
-
- /********* Start of inlined file: mapping0.c *********/
-
- /********* Start of inlined file: juce_OggVorbisHeader.h *********/
- // This file is included at the start of each Ogg-Vorbis .c file, just to do a few housekeeping
- // tasks..
-
- #ifdef _MSC_VER
- #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4305 4189 4706)
- #endif
- /********* End of inlined file: juce_OggVorbisHeader.h *********/
-
- #if JUCE_USE_OGGVORBIS
-
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <math.h>
-
- /* simplistic, wasteful way of doing this (unique lookup for each
- mode/submapping); there should be a central repository for
- identical lookups. That will require minor work, so I'm putting it
- off as low priority.
-
- Why a lookup for each backend in a given mode? Because the
- blocksize is set by the mode, and low backend lookups may require
- parameters from other areas of the mode/mapping */
-
- static void mapping0_free_info(vorbis_info_mapping *i){
- vorbis_info_mapping0 *info=(vorbis_info_mapping0 *)i;
- if(info){
- memset(info,0,sizeof(*info));
- _ogg_free(info);
- }
- }
-
- static int ilog3(unsigned int v){
- int ret=0;
- if(v)--v;
- while(v){
- ret++;
- v>>=1;
- }
- return(ret);
- }
-
- static void mapping0_pack(vorbis_info *vi,vorbis_info_mapping *vm,
- oggpack_buffer *opb){
- int i;
- vorbis_info_mapping0 *info=(vorbis_info_mapping0 *)vm;
-
- /* another 'we meant to do it this way' hack... up to beta 4, we
- packed 4 binary zeros here to signify one submapping in use. We
- now redefine that to mean four bitflags that indicate use of
- deeper features; bit0:submappings, bit1:coupling,
- bit2,3:reserved. This is backward compatable with all actual uses
- of the beta code. */
-
- if(info->submaps>1){
- oggpack_write(opb,1,1);
- oggpack_write(opb,info->submaps-1,4);
- }else
- oggpack_write(opb,0,1);
-
- if(info->coupling_steps>0){
- oggpack_write(opb,1,1);
- oggpack_write(opb,info->coupling_steps-1,8);
-
- for(i=0;i<info->coupling_steps;i++){
- oggpack_write(opb,info->coupling_mag[i],ilog3(vi->channels));
- oggpack_write(opb,info->coupling_ang[i],ilog3(vi->channels));
- }
- }else
- oggpack_write(opb,0,1);
-
- oggpack_write(opb,0,2); /* 2,3:reserved */
-
- /* we don't write the channel submappings if we only have one... */
- if(info->submaps>1){
- for(i=0;i<vi->channels;i++)
- oggpack_write(opb,info->chmuxlist[i],4);
- }
- for(i=0;i<info->submaps;i++){
- oggpack_write(opb,0,8); /* time submap unused */
- oggpack_write(opb,info->floorsubmap[i],8);
- oggpack_write(opb,info->residuesubmap[i],8);
- }
- }
-
- /* also responsible for range checking */
- static vorbis_info_mapping *mapping0_unpack(vorbis_info *vi,oggpack_buffer *opb){
- int i;
- vorbis_info_mapping0 *info=(vorbis_info_mapping0*)_ogg_calloc(1,sizeof(*info));
- codec_setup_info *ci=(codec_setup_info*)vi->codec_setup;
- memset(info,0,sizeof(*info));
-
- if(oggpack_read(opb,1))
- info->submaps=oggpack_read(opb,4)+1;
- else
- info->submaps=1;
-
- if(oggpack_read(opb,1)){
- info->coupling_steps=oggpack_read(opb,8)+1;
-
- for(i=0;i<info->coupling_steps;i++){
- int testM=info->coupling_mag[i]=oggpack_read(opb,ilog3(vi->channels));
- int testA=info->coupling_ang[i]=oggpack_read(opb,ilog3(vi->channels));
-
- if(testM<0 ||
- testA<0 ||
- testM==testA ||
- testM>=vi->channels ||
- testA>=vi->channels) goto err_out;
- }
-
- }
-
- if(oggpack_read(opb,2)>0)goto err_out; /* 2,3:reserved */
-
- if(info->submaps>1){
- for(i=0;i<vi->channels;i++){
- info->chmuxlist[i]=oggpack_read(opb,4);
- if(info->chmuxlist[i]>=info->submaps)goto err_out;
- }
- }
- for(i=0;i<info->submaps;i++){
- oggpack_read(opb,8); /* time submap unused */
- info->floorsubmap[i]=oggpack_read(opb,8);
- if(info->floorsubmap[i]>=ci->floors)goto err_out;
- info->residuesubmap[i]=oggpack_read(opb,8);
- if(info->residuesubmap[i]>=ci->residues)goto err_out;
- }
-
- return info;
-
- err_out:
- mapping0_free_info(info);
- return(NULL);
- }
-
- #if 0
- static long seq=0;
- static ogg_int64_t total=0;
- static float FLOOR1_fromdB_LOOKUP[256]={
- 1.0649863e-07F, 1.1341951e-07F, 1.2079015e-07F, 1.2863978e-07F,
- 1.3699951e-07F, 1.4590251e-07F, 1.5538408e-07F, 1.6548181e-07F,
- 1.7623575e-07F, 1.8768855e-07F, 1.9988561e-07F, 2.128753e-07F,
- 2.2670913e-07F, 2.4144197e-07F, 2.5713223e-07F, 2.7384213e-07F,
- 2.9163793e-07F, 3.1059021e-07F, 3.3077411e-07F, 3.5226968e-07F,
- 3.7516214e-07F, 3.9954229e-07F, 4.2550680e-07F, 4.5315863e-07F,
- 4.8260743e-07F, 5.1396998e-07F, 5.4737065e-07F, 5.8294187e-07F,
- 6.2082472e-07F, 6.6116941e-07F, 7.0413592e-07F, 7.4989464e-07F,
- 7.9862701e-07F, 8.5052630e-07F, 9.0579828e-07F, 9.6466216e-07F,
- 1.0273513e-06F, 1.0941144e-06F, 1.1652161e-06F, 1.2409384e-06F,
- 1.3215816e-06F, 1.4074654e-06F, 1.4989305e-06F, 1.5963394e-06F,
- 1.7000785e-06F, 1.8105592e-06F, 1.9282195e-06F, 2.0535261e-06F,
- 2.1869758e-06F, 2.3290978e-06F, 2.4804557e-06F, 2.6416497e-06F,
- 2.8133190e-06F, 2.9961443e-06F, 3.1908506e-06F, 3.3982101e-06F,
- 3.6190449e-06F, 3.8542308e-06F, 4.1047004e-06F, 4.3714470e-06F,
- 4.6555282e-06F, 4.9580707e-06F, 5.2802740e-06F, 5.6234160e-06F,
- 5.9888572e-06F, 6.3780469e-06F, 6.7925283e-06F, 7.2339451e-06F,
- 7.7040476e-06F, 8.2047000e-06F, 8.7378876e-06F, 9.3057248e-06F,
- 9.9104632e-06F, 1.0554501e-05F, 1.1240392e-05F, 1.1970856e-05F,
- 1.2748789e-05F, 1.3577278e-05F, 1.4459606e-05F, 1.5399272e-05F,
- 1.6400004e-05F, 1.7465768e-05F, 1.8600792e-05F, 1.9809576e-05F,
- 2.1096914e-05F, 2.2467911e-05F, 2.3928002e-05F, 2.5482978e-05F,
- 2.7139006e-05F, 2.8902651e-05F, 3.0780908e-05F, 3.2781225e-05F,
- 3.4911534e-05F, 3.7180282e-05F, 3.9596466e-05F, 4.2169667e-05F,
- 4.4910090e-05F, 4.7828601e-05F, 5.0936773e-05F, 5.4246931e-05F,
- 5.7772202e-05F, 6.1526565e-05F, 6.5524908e-05F, 6.9783085e-05F,
- 7.4317983e-05F, 7.9147585e-05F, 8.4291040e-05F, 8.9768747e-05F,
- 9.5602426e-05F, 0.00010181521F, 0.00010843174F, 0.00011547824F,
- 0.00012298267F, 0.00013097477F, 0.00013948625F, 0.00014855085F,
- 0.00015820453F, 0.00016848555F, 0.00017943469F, 0.00019109536F,
- 0.00020351382F, 0.00021673929F, 0.00023082423F, 0.00024582449F,
- 0.00026179955F, 0.00027881276F, 0.00029693158F, 0.00031622787F,
- 0.00033677814F, 0.00035866388F, 0.00038197188F, 0.00040679456F,
- 0.00043323036F, 0.00046138411F, 0.00049136745F, 0.00052329927F,
- 0.00055730621F, 0.00059352311F, 0.00063209358F, 0.00067317058F,
- 0.00071691700F, 0.00076350630F, 0.00081312324F, 0.00086596457F,
- 0.00092223983F, 0.00098217216F, 0.0010459992F, 0.0011139742F,
- 0.0011863665F, 0.0012634633F, 0.0013455702F, 0.0014330129F,
- 0.0015261382F, 0.0016253153F, 0.0017309374F, 0.0018434235F,
- 0.0019632195F, 0.0020908006F, 0.0022266726F, 0.0023713743F,
- 0.0025254795F, 0.0026895994F, 0.0028643847F, 0.0030505286F,
- 0.0032487691F, 0.0034598925F, 0.0036847358F, 0.0039241906F,
- 0.0041792066F, 0.0044507950F, 0.0047400328F, 0.0050480668F,
- 0.0053761186F, 0.0057254891F, 0.0060975636F, 0.0064938176F,
- 0.0069158225F, 0.0073652516F, 0.0078438871F, 0.0083536271F,
- 0.0088964928F, 0.009474637F, 0.010090352F, 0.010746080F,
- 0.011444421F, 0.012188144F, 0.012980198F, 0.013823725F,
- 0.014722068F, 0.015678791F, 0.016697687F, 0.017782797F,
- 0.018938423F, 0.020169149F, 0.021479854F, 0.022875735F,
- 0.024362330F, 0.025945531F, 0.027631618F, 0.029427276F,
- 0.031339626F, 0.033376252F, 0.035545228F, 0.037855157F,
- 0.040315199F, 0.042935108F, 0.045725273F, 0.048696758F,
- 0.051861348F, 0.055231591F, 0.058820850F, 0.062643361F,
- 0.066714279F, 0.071049749F, 0.075666962F, 0.080584227F,
- 0.085821044F, 0.091398179F, 0.097337747F, 0.10366330F,
- 0.11039993F, 0.11757434F, 0.12521498F, 0.13335215F,
- 0.14201813F, 0.15124727F, 0.16107617F, 0.17154380F,
- 0.18269168F, 0.19456402F, 0.20720788F, 0.22067342F,
- 0.23501402F, 0.25028656F, 0.26655159F, 0.28387361F,
- 0.30232132F, 0.32196786F, 0.34289114F, 0.36517414F,
- 0.38890521F, 0.41417847F, 0.44109412F, 0.46975890F,
- 0.50028648F, 0.53279791F, 0.56742212F, 0.60429640F,
- 0.64356699F, 0.68538959F, 0.72993007F, 0.77736504F,
- 0.82788260F, 0.88168307F, 0.9389798F, 1.F,
- };
-
- #endif
-
- extern int *floor1_fit(vorbis_block *vb,void *look,
- const float *logmdct, /* in */
- const float *logmask);
- extern int *floor1_interpolate_fit(vorbis_block *vb,void *look,
- int *A,int *B,
- int del);
- extern int floor1_encode(oggpack_buffer *opb,vorbis_block *vb,
- void*look,
- int *post,int *ilogmask);
-
- static int mapping0_forward(vorbis_block *vb){
- vorbis_dsp_state *vd=vb->vd;
- vorbis_info *vi=vd->vi;
- codec_setup_info *ci=(codec_setup_info*)vi->codec_setup;
- private_state *b=(private_state*)vb->vd->backend_state;
- vorbis_block_internal *vbi=(vorbis_block_internal *)vb->internal;
- int n=vb->pcmend;
- int i,j,k;
-
- int *nonzero = (int*) alloca(sizeof(*nonzero)*vi->channels);
- float **gmdct = (float**) _vorbis_block_alloc(vb,vi->channels*sizeof(*gmdct));
- int **ilogmaskch= (int**) _vorbis_block_alloc(vb,vi->channels*sizeof(*ilogmaskch));
- int ***floor_posts = (int***) _vorbis_block_alloc(vb,vi->channels*sizeof(*floor_posts));
-
- float global_ampmax=vbi->ampmax;
- float *local_ampmax=(float*)alloca(sizeof(*local_ampmax)*vi->channels);
- int blocktype=vbi->blocktype;
-
- int modenumber=vb->W;
- vorbis_info_mapping0 *info=(vorbis_info_mapping0*)ci->map_param[modenumber];
- vorbis_look_psy *psy_look=
- b->psy+blocktype+(vb->W?2:0);
-
- vb->mode=modenumber;
-
- for(i=0;i<vi->channels;i++){
- float scale=4.f/n;
- float scale_dB;
-
- float *pcm =vb->pcm[i];
- float *logfft =pcm;
-
- gmdct[i]=(float*)_vorbis_block_alloc(vb,n/2*sizeof(**gmdct));
-
- scale_dB=todB(&scale) + .345; /* + .345 is a hack; the original
- todB estimation used on IEEE 754
- compliant machines had a bug that
- returned dB values about a third
- of a decibel too high. The bug
- was harmless because tunings
- implicitly took that into
- account. However, fixing the bug
- in the estimator requires
- changing all the tunings as well.
- For now, it's easier to sync
- things back up here, and
- recalibrate the tunings in the
- next major model upgrade. */
-
- #if 0
- if(vi->channels==2)
- if(i==0)
- _analysis_output("pcmL",seq,pcm,n,0,0,total-n/2);
- else
- _analysis_output("pcmR",seq,pcm,n,0,0,total-n/2);
- #endif
-
- /* window the PCM data */
- _vorbis_apply_window(pcm,b->window,ci->blocksizes,vb->lW,vb->W,vb->nW);
-
- #if 0
- if(vi->channels==2)
- if(i==0)
- _analysis_output("windowedL",seq,pcm,n,0,0,total-n/2);
- else
- _analysis_output("windowedR",seq,pcm,n,0,0,total-n/2);
- #endif
-
- /* transform the PCM data */
- /* only MDCT right now.... */
- mdct_forward((mdct_lookup*) b->transform[vb->W][0],pcm,gmdct[i]);
-
- /* FFT yields more accurate tonal estimation (not phase sensitive) */
- drft_forward(&b->fft_look[vb->W],pcm);
- logfft[0]=scale_dB+todB(pcm) + .345; /* + .345 is a hack; the
- original todB estimation used on
- IEEE 754 compliant machines had a
- bug that returned dB values about
- a third of a decibel too high.
- The bug was harmless because
- tunings implicitly took that into
- account. However, fixing the bug
- in the estimator requires
- changing all the tunings as well.
- For now, it's easier to sync
- things back up here, and
- recalibrate the tunings in the
- next major model upgrade. */
- local_ampmax[i]=logfft[0];
- for(j=1;j<n-1;j+=2){
- float temp=pcm[j]*pcm[j]+pcm[j+1]*pcm[j+1];
- temp=logfft[(j+1)>>1]=scale_dB+.5f*todB(&temp) + .345; /* +
- .345 is a hack; the original todB
- estimation used on IEEE 754
- compliant machines had a bug that
- returned dB values about a third
- of a decibel too high. The bug
- was harmless because tunings
- implicitly took that into
- account. However, fixing the bug
- in the estimator requires
- changing all the tunings as well.
- For now, it's easier to sync
- things back up here, and
- recalibrate the tunings in the
- next major model upgrade. */
- if(temp>local_ampmax[i])local_ampmax[i]=temp;
- }
-
- if(local_ampmax[i]>0.f)local_ampmax[i]=0.f;
- if(local_ampmax[i]>global_ampmax)global_ampmax=local_ampmax[i];
-
- #if 0
- if(vi->channels==2){
- if(i==0){
- _analysis_output("fftL",seq,logfft,n/2,1,0,0);
- }else{
- _analysis_output("fftR",seq,logfft,n/2,1,0,0);
- }
- }
- #endif
-
- }
-
- {
- float *noise = (float*) _vorbis_block_alloc(vb,n/2*sizeof(*noise));
- float *tone = (float*) _vorbis_block_alloc(vb,n/2*sizeof(*tone));
-
- for(i=0;i<vi->channels;i++){
- /* the encoder setup assumes that all the modes used by any
- specific bitrate tweaking use the same floor */
-
- int submap=info->chmuxlist[i];
-
- /* the following makes things clearer to *me* anyway */
- float *mdct =gmdct[i];
- float *logfft =vb->pcm[i];
-
- float *logmdct =logfft+n/2;
- float *logmask =logfft;
-
- vb->mode=modenumber;
-
- floor_posts[i]=(int**) _vorbis_block_alloc(vb,PACKETBLOBS*sizeof(**floor_posts));
- memset(floor_posts[i],0,sizeof(**floor_posts)*PACKETBLOBS);
-
- for(j=0;j<n/2;j++)
- logmdct[j]=todB(mdct+j) + .345; /* + .345 is a hack; the original
- todB estimation used on IEEE 754
- compliant machines had a bug that
- returned dB values about a third
- of a decibel too high. The bug
- was harmless because tunings
- implicitly took that into
- account. However, fixing the bug
- in the estimator requires
- changing all the tunings as well.
- For now, it's easier to sync
- things back up here, and
- recalibrate the tunings in the
- next major model upgrade. */
-
- #if 0
- if(vi->channels==2){
- if(i==0)
- _analysis_output("mdctL",seq,logmdct,n/2,1,0,0);
- else
- _analysis_output("mdctR",seq,logmdct,n/2,1,0,0);
- }else{
- _analysis_output("mdct",seq,logmdct,n/2,1,0,0);
- }
- #endif
-
- /* first step; noise masking. Not only does 'noise masking'
- give us curves from which we can decide how much resolution
- to give noise parts of the spectrum, it also implicitly hands
- us a tonality estimate (the larger the value in the
- 'noise_depth' vector, the more tonal that area is) */
-
- _vp_noisemask(psy_look,
- logmdct,
- noise); /* noise does not have by-frequency offset
- bias applied yet */
- #if 0
- if(vi->channels==2){
- if(i==0)
- _analysis_output("noiseL",seq,noise,n/2,1,0,0);
- else
- _analysis_output("noiseR",seq,noise,n/2,1,0,0);
- }
- #endif
-
- /* second step: 'all the other crap'; all the stuff that isn't
- computed/fit for bitrate management goes in the second psy
- vector. This includes tone masking, peak limiting and ATH */
-
- _vp_tonemask(psy_look,
- logfft,
- tone,
- global_ampmax,
- local_ampmax[i]);
-
- #if 0
- if(vi->channels==2){
- if(i==0)
- _analysis_output("toneL",seq,tone,n/2,1,0,0);
- else
- _analysis_output("toneR",seq,tone,n/2,1,0,0);
- }
- #endif
-
- /* third step; we offset the noise vectors, overlay tone
- masking. We then do a floor1-specific line fit. If we're
- performing bitrate management, the line fit is performed
- multiple times for up/down tweakage on demand. */
-
- #if 0
- {
- float aotuv[psy_look->n];
- #endif
-
- _vp_offset_and_mix(psy_look,
- noise,
- tone,
- 1,
- logmask,
- mdct,
- logmdct);
-
- #if 0
- if(vi->channels==2){
- if(i==0)
- _analysis_output("aotuvM1_L",seq,aotuv,psy_look->n,1,1,0);
- else
- _analysis_output("aotuvM1_R",seq,aotuv,psy_look->n,1,1,0);
- }
- }
- #endif
-
- #if 0
- if(vi->channels==2){
- if(i==0)
- _analysis_output("mask1L",seq,logmask,n/2,1,0,0);
- else
- _analysis_output("mask1R",seq,logmask,n/2,1,0,0);
- }
- #endif
-
- /* this algorithm is hardwired to floor 1 for now; abort out if
- we're *not* floor1. This won't happen unless someone has
- broken the encode setup lib. Guard it anyway. */
- if(ci->floor_type[info->floorsubmap[submap]]!=1)return(-1);
-
- floor_posts[i][PACKETBLOBS/2]=
- floor1_fit(vb,b->flr[info->floorsubmap[submap]],
- logmdct,
- logmask);
-
- /* are we managing bitrate? If so, perform two more fits for
- later rate tweaking (fits represent hi/lo) */
- if(vorbis_bitrate_managed(vb) && floor_posts[i][PACKETBLOBS/2]){
- /* higher rate by way of lower noise curve */
-
- _vp_offset_and_mix(psy_look,
- noise,
- tone,
- 2,
- logmask,
- mdct,
- logmdct);
-
- #if 0
- if(vi->channels==2){
- if(i==0)
- _analysis_output("mask2L",seq,logmask,n/2,1,0,0);
- else
- _analysis_output("mask2R",seq,logmask,n/2,1,0,0);
- }
- #endif
-
- floor_posts[i][PACKETBLOBS-1]=
- floor1_fit(vb,b->flr[info->floorsubmap[submap]],
- logmdct,
- logmask);
-
- /* lower rate by way of higher noise curve */
- _vp_offset_and_mix(psy_look,
- noise,
- tone,
- 0,
- logmask,
- mdct,
- logmdct);
-
- #if 0
- if(vi->channels==2)
- if(i==0)
- _analysis_output("mask0L",seq,logmask,n/2,1,0,0);
- else
- _analysis_output("mask0R",seq,logmask,n/2,1,0,0);
- #endif
-
- floor_posts[i][0]=
- floor1_fit(vb,b->flr[info->floorsubmap[submap]],
- logmdct,
- logmask);
-
- /* we also interpolate a range of intermediate curves for
- intermediate rates */
- for(k=1;k<PACKETBLOBS/2;k++)
- floor_posts[i][k]=
- floor1_interpolate_fit(vb,b->flr[info->floorsubmap[submap]],
- floor_posts[i][0],
- floor_posts[i][PACKETBLOBS/2],
- k*65536/(PACKETBLOBS/2));
- for(k=PACKETBLOBS/2+1;k<PACKETBLOBS-1;k++)
- floor_posts[i][k]=
- floor1_interpolate_fit(vb,b->flr[info->floorsubmap[submap]],
- floor_posts[i][PACKETBLOBS/2],
- floor_posts[i][PACKETBLOBS-1],
- (k-PACKETBLOBS/2)*65536/(PACKETBLOBS/2));
- }
- }
- }
- vbi->ampmax=global_ampmax;
-
- /*
- the next phases are performed once for vbr-only and PACKETBLOB
- times for bitrate managed modes.
-
- 1) encode actual mode being used
- 2) encode the floor for each channel, compute coded mask curve/res
- 3) normalize and couple.
- 4) encode residue
- 5) save packet bytes to the packetblob vector
-
- */
-
- /* iterate over the many masking curve fits we've created */
-
- {
- float **res_bundle=(float**) alloca(sizeof(*res_bundle)*vi->channels);
- float **couple_bundle=(float**) alloca(sizeof(*couple_bundle)*vi->channels);
- int *zerobundle=(int*) alloca(sizeof(*zerobundle)*vi->channels);
- int **sortindex=(int**) alloca(sizeof(*sortindex)*vi->channels);
- float **mag_memo;
- int **mag_sort;
-
- if(info->coupling_steps){
- mag_memo=_vp_quantize_couple_memo(vb,
- &ci->psy_g_param,
- psy_look,
- info,
- gmdct);
-
- mag_sort=_vp_quantize_couple_sort(vb,
- psy_look,
- info,
- mag_memo);
-
- hf_reduction(&ci->psy_g_param,
- psy_look,
- info,
- mag_memo);
- }
-
- memset(sortindex,0,sizeof(*sortindex)*vi->channels);
- if(psy_look->vi->normal_channel_p){
- for(i=0;i<vi->channels;i++){
- float *mdct =gmdct[i];
- sortindex[i]=(int*) alloca(sizeof(**sortindex)*n/2);
- _vp_noise_normalize_sort(psy_look,mdct,sortindex[i]);
- }
- }
-
- for(k=(vorbis_bitrate_managed(vb)?0:PACKETBLOBS/2);
- k<=(vorbis_bitrate_managed(vb)?PACKETBLOBS-1:PACKETBLOBS/2);
- k++){
- oggpack_buffer *opb=vbi->packetblob[k];
-
- /* start out our new packet blob with packet type and mode */
- /* Encode the packet type */
- oggpack_write(opb,0,1);
- /* Encode the modenumber */
- /* Encode frame mode, pre,post windowsize, then dispatch */
- oggpack_write(opb,modenumber,b->modebits);
- if(vb->W){
- oggpack_write(opb,vb->lW,1);
- oggpack_write(opb,vb->nW,1);
- }
-
- /* encode floor, compute masking curve, sep out residue */
- for(i=0;i<vi->channels;i++){
- int submap=info->chmuxlist[i];
- float *mdct =gmdct[i];
- float *res =vb->pcm[i];
- int *ilogmask=ilogmaskch[i]=
- (int*) _vorbis_block_alloc(vb,n/2*sizeof(**gmdct));
-
- nonzero[i]=floor1_encode(opb,vb,b->flr[info->floorsubmap[submap]],
- floor_posts[i][k],
- ilogmask);
- #if 0
- {
- char buf[80];
- sprintf(buf,"maskI%c%d",i?'R':'L',k);
- float work[n/2];
- for(j=0;j<n/2;j++)
- work[j]=FLOOR1_fromdB_LOOKUP[ilogmask[j]];
- _analysis_output(buf,seq,work,n/2,1,1,0);
- }
- #endif
- _vp_remove_floor(psy_look,
- mdct,
- ilogmask,
- res,
- ci->psy_g_param.sliding_lowpass[vb->W][k]);
-
- _vp_noise_normalize(psy_look,res,res+n/2,sortindex[i]);
-
- #if 0
- {
- char buf[80];
- float work[n/2];
- for(j=0;j<n/2;j++)
- work[j]=FLOOR1_fromdB_LOOKUP[ilogmask[j]]*(res+n/2)[j];
- sprintf(buf,"resI%c%d",i?'R':'L',k);
- _analysis_output(buf,seq,work,n/2,1,1,0);
-
- }
- #endif
- }
-
- /* our iteration is now based on masking curve, not prequant and
- coupling. Only one prequant/coupling step */
-
- /* quantize/couple */
- /* incomplete implementation that assumes the tree is all depth
- one, or no tree at all */
- if(info->coupling_steps){
- _vp_couple(k,
- &ci->psy_g_param,
- psy_look,
- info,
- vb->pcm,
- mag_memo,
- mag_sort,
- ilogmaskch,
- nonzero,
- ci->psy_g_param.sliding_lowpass[vb->W][k]);
- }
-
- /* classify and encode by submap */
- for(i=0;i<info->submaps;i++){
- int ch_in_bundle=0;
- long **classifications;
- int resnum=info->residuesubmap[i];
-
- for(j=0;j<vi->channels;j++){
- if(info->chmuxlist[j]==i){
- zerobundle[ch_in_bundle]=0;
- if(nonzero[j])zerobundle[ch_in_bundle]=1;
- res_bundle[ch_in_bundle]=vb->pcm[j];
- couple_bundle[ch_in_bundle++]=vb->pcm[j]+n/2;
- }
- }
-
- classifications=_residue_P[ci->residue_type[resnum]]->
- classx(vb,b->residue[resnum],couple_bundle,zerobundle,ch_in_bundle);
-
- _residue_P[ci->residue_type[resnum]]->
- forward(opb,vb,b->residue[resnum],
- couple_bundle,NULL,zerobundle,ch_in_bundle,classifications);
- }
-
- /* ok, done encoding. Next protopacket. */
- }
-
- }
-
- #if 0
- seq++;
- total+=ci->blocksizes[vb->W]/4+ci->blocksizes[vb->nW]/4;
- #endif
- return(0);
- }
-
- static int mapping0_inverse(vorbis_block *vb,vorbis_info_mapping *l){
- vorbis_dsp_state *vd=vb->vd;
- vorbis_info *vi=vd->vi;
- codec_setup_info *ci=(codec_setup_info*) vi->codec_setup;
- private_state *b=(private_state*)vd->backend_state;
- vorbis_info_mapping0 *info=(vorbis_info_mapping0 *)l;
-
- int i,j;
- long n=vb->pcmend=ci->blocksizes[vb->W];
-
- float **pcmbundle=(float**) alloca(sizeof(*pcmbundle)*vi->channels);
- int *zerobundle=(int*) alloca(sizeof(*zerobundle)*vi->channels);
-
- int *nonzero =(int*) alloca(sizeof(*nonzero)*vi->channels);
- void **floormemo=(void**) alloca(sizeof(*floormemo)*vi->channels);
-
- /* recover the spectral envelope; store it in the PCM vector for now */
- for(i=0;i<vi->channels;i++){
- int submap=info->chmuxlist[i];
- floormemo[i]=_floor_P[ci->floor_type[info->floorsubmap[submap]]]->
- inverse1(vb,b->flr[info->floorsubmap[submap]]);
- if(floormemo[i])
- nonzero[i]=1;
- else
- nonzero[i]=0;
- memset(vb->pcm[i],0,sizeof(*vb->pcm[i])*n/2);
- }
-
- /* channel coupling can 'dirty' the nonzero listing */
- for(i=0;i<info->coupling_steps;i++){
- if(nonzero[info->coupling_mag[i]] ||
- nonzero[info->coupling_ang[i]]){
- nonzero[info->coupling_mag[i]]=1;
- nonzero[info->coupling_ang[i]]=1;
- }
- }
-
- /* recover the residue into our working vectors */
- for(i=0;i<info->submaps;i++){
- int ch_in_bundle=0;
- for(j=0;j<vi->channels;j++){
- if(info->chmuxlist[j]==i){
- if(nonzero[j])
- zerobundle[ch_in_bundle]=1;
- else
- zerobundle[ch_in_bundle]=0;
- pcmbundle[ch_in_bundle++]=vb->pcm[j];
- }
- }
-
- _residue_P[ci->residue_type[info->residuesubmap[i]]]->
- inverse(vb,b->residue[info->residuesubmap[i]],
- pcmbundle,zerobundle,ch_in_bundle);
- }
-
- /* channel coupling */
- for(i=info->coupling_steps-1;i>=0;i--){
- float *pcmM=vb->pcm[info->coupling_mag[i]];
- float *pcmA=vb->pcm[info->coupling_ang[i]];
-
- for(j=0;j<n/2;j++){
- float mag=pcmM[j];
- float ang=pcmA[j];
-
- if(mag>0)
- if(ang>0){
- pcmM[j]=mag;
- pcmA[j]=mag-ang;
- }else{
- pcmA[j]=mag;
- pcmM[j]=mag+ang;
- }
- else
- if(ang>0){
- pcmM[j]=mag;
- pcmA[j]=mag+ang;
- }else{
- pcmA[j]=mag;
- pcmM[j]=mag-ang;
- }
- }
- }
-
- /* compute and apply spectral envelope */
- for(i=0;i<vi->channels;i++){
- float *pcm=vb->pcm[i];
- int submap=info->chmuxlist[i];
- _floor_P[ci->floor_type[info->floorsubmap[submap]]]->
- inverse2(vb,b->flr[info->floorsubmap[submap]],
- floormemo[i],pcm);
- }
-
- /* transform the PCM data; takes PCM vector, vb; modifies PCM vector */
- /* only MDCT right now.... */
- for(i=0;i<vi->channels;i++){
- float *pcm=vb->pcm[i];
- mdct_backward((mdct_lookup*) b->transform[vb->W][0],pcm,pcm);
- }
-
- /* all done! */
- return(0);
- }
-
- /* export hooks */
- vorbis_func_mapping mapping0_exportbundle={
- &mapping0_pack,
- &mapping0_unpack,
- &mapping0_free_info,
- &mapping0_forward,
- &mapping0_inverse
- };
-
- #endif
- /********* End of inlined file: mapping0.c *********/
-
- /********* Start of inlined file: mdct.c *********/
- /* this can also be run as an integer transform by uncommenting a
- define in mdct.h; the integerization is a first pass and although
- it's likely stable for Vorbis, the dynamic range is constrained and
- roundoff isn't done (so it's noisy). Consider it functional, but
- only a starting point. There's no point on a machine with an FPU */
-
- /********* Start of inlined file: juce_OggVorbisHeader.h *********/
- // This file is included at the start of each Ogg-Vorbis .c file, just to do a few housekeeping
- // tasks..
-
- #ifdef _MSC_VER
- #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4305 4189 4706)
- #endif
- /********* End of inlined file: juce_OggVorbisHeader.h *********/
-
- #if JUCE_USE_OGGVORBIS
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <math.h>
-
- /* build lookups for trig functions; also pre-figure scaling and
- some window function algebra. */
-
- void mdct_init(mdct_lookup *lookup,int n){
- int *bitrev=(int*) _ogg_malloc(sizeof(*bitrev)*(n/4));
- DATA_TYPE *T=(DATA_TYPE*) _ogg_malloc(sizeof(*T)*(n+n/4));
-
- int i;
- int n2=n>>1;
- int log2n=lookup->log2n=rint(log((float)n)/log(2.f));
- lookup->n=n;
- lookup->trig=T;
- lookup->bitrev=bitrev;
-
- /* trig lookups... */
-
- for(i=0;i<n/4;i++){
- T[i*2]=FLOAT_CONV(cos((M_PI/n)*(4*i)));
- T[i*2+1]=FLOAT_CONV(-sin((M_PI/n)*(4*i)));
- T[n2+i*2]=FLOAT_CONV(cos((M_PI/(2*n))*(2*i+1)));
- T[n2+i*2+1]=FLOAT_CONV(sin((M_PI/(2*n))*(2*i+1)));
- }
- for(i=0;i<n/8;i++){
- T[n+i*2]=FLOAT_CONV(cos((M_PI/n)*(4*i+2))*.5);
- T[n+i*2+1]=FLOAT_CONV(-sin((M_PI/n)*(4*i+2))*.5);
- }
-
- /* bitreverse lookup... */
-
- {
- int mask=(1<<(log2n-1))-1,i,j;
- int msb=1<<(log2n-2);
- for(i=0;i<n/8;i++){
- int acc=0;
- for(j=0;msb>>j;j++)
- if((msb>>j)&i)acc|=1<<j;
- bitrev[i*2]=((~acc)&mask)-1;
- bitrev[i*2+1]=acc;
-
- }
- }
- lookup->scale=FLOAT_CONV(4.f/n);
- }
-
- /* 8 point butterfly (in place, 4 register) */
- STIN void mdct_butterfly_8(DATA_TYPE *x){
- REG_TYPE r0 = x[6] + x[2];
- REG_TYPE r1 = x[6] - x[2];
- REG_TYPE r2 = x[4] + x[0];
- REG_TYPE r3 = x[4] - x[0];
-
- x[6] = r0 + r2;
- x[4] = r0 - r2;
-
- r0 = x[5] - x[1];
- r2 = x[7] - x[3];
- x[0] = r1 + r0;
- x[2] = r1 - r0;
-
- r0 = x[5] + x[1];
- r1 = x[7] + x[3];
- x[3] = r2 + r3;
- x[1] = r2 - r3;
- x[7] = r1 + r0;
- x[5] = r1 - r0;
-
- }
-
- /* 16 point butterfly (in place, 4 register) */
- STIN void mdct_butterfly_16(DATA_TYPE *x){
- REG_TYPE r0 = x[1] - x[9];
- REG_TYPE r1 = x[0] - x[8];
-
- x[8] += x[0];
- x[9] += x[1];
- x[0] = MULT_NORM((r0 + r1) * cPI2_8);
- x[1] = MULT_NORM((r0 - r1) * cPI2_8);
-
- r0 = x[3] - x[11];
- r1 = x[10] - x[2];
- x[10] += x[2];
- x[11] += x[3];
- x[2] = r0;
- x[3] = r1;
-
- r0 = x[12] - x[4];
- r1 = x[13] - x[5];
- x[12] += x[4];
- x[13] += x[5];
- x[4] = MULT_NORM((r0 - r1) * cPI2_8);
- x[5] = MULT_NORM((r0 + r1) * cPI2_8);
-
- r0 = x[14] - x[6];
- r1 = x[15] - x[7];
- x[14] += x[6];
- x[15] += x[7];
- x[6] = r0;
- x[7] = r1;
-
- mdct_butterfly_8(x);
- mdct_butterfly_8(x+8);
- }
-
- /* 32 point butterfly (in place, 4 register) */
- STIN void mdct_butterfly_32(DATA_TYPE *x){
- REG_TYPE r0 = x[30] - x[14];
- REG_TYPE r1 = x[31] - x[15];
-
- x[30] += x[14];
- x[31] += x[15];
- x[14] = r0;
- x[15] = r1;
-
- r0 = x[28] - x[12];
- r1 = x[29] - x[13];
- x[28] += x[12];
- x[29] += x[13];
- x[12] = MULT_NORM( r0 * cPI1_8 - r1 * cPI3_8 );
- x[13] = MULT_NORM( r0 * cPI3_8 + r1 * cPI1_8 );
-
- r0 = x[26] - x[10];
- r1 = x[27] - x[11];
- x[26] += x[10];
- x[27] += x[11];
- x[10] = MULT_NORM(( r0 - r1 ) * cPI2_8);
- x[11] = MULT_NORM(( r0 + r1 ) * cPI2_8);
-
- r0 = x[24] - x[8];
- r1 = x[25] - x[9];
- x[24] += x[8];
- x[25] += x[9];
- x[8] = MULT_NORM( r0 * cPI3_8 - r1 * cPI1_8 );
- x[9] = MULT_NORM( r1 * cPI3_8 + r0 * cPI1_8 );
-
- r0 = x[22] - x[6];
- r1 = x[7] - x[23];
- x[22] += x[6];
- x[23] += x[7];
- x[6] = r1;
- x[7] = r0;
-
- r0 = x[4] - x[20];
- r1 = x[5] - x[21];
- x[20] += x[4];
- x[21] += x[5];
- x[4] = MULT_NORM( r1 * cPI1_8 + r0 * cPI3_8 );
- x[5] = MULT_NORM( r1 * cPI3_8 - r0 * cPI1_8 );
-
- r0 = x[2] - x[18];
- r1 = x[3] - x[19];
- x[18] += x[2];
- x[19] += x[3];
- x[2] = MULT_NORM(( r1 + r0 ) * cPI2_8);
- x[3] = MULT_NORM(( r1 - r0 ) * cPI2_8);
-
- r0 = x[0] - x[16];
- r1 = x[1] - x[17];
- x[16] += x[0];
- x[17] += x[1];
- x[0] = MULT_NORM( r1 * cPI3_8 + r0 * cPI1_8 );
- x[1] = MULT_NORM( r1 * cPI1_8 - r0 * cPI3_8 );
-
- mdct_butterfly_16(x);
- mdct_butterfly_16(x+16);
-
- }
-
- /* N point first stage butterfly (in place, 2 register) */
- STIN void mdct_butterfly_first(DATA_TYPE *T,
- DATA_TYPE *x,
- int points){
-
- DATA_TYPE *x1 = x + points - 8;
- DATA_TYPE *x2 = x + (points>>1) - 8;
- REG_TYPE r0;
- REG_TYPE r1;
-
- do{
-
- r0 = x1[6] - x2[6];
- r1 = x1[7] - x2[7];
- x1[6] += x2[6];
- x1[7] += x2[7];
- x2[6] = MULT_NORM(r1 * T[1] + r0 * T[0]);
- x2[7] = MULT_NORM(r1 * T[0] - r0 * T[1]);
-
- r0 = x1[4] - x2[4];
- r1 = x1[5] - x2[5];
- x1[4] += x2[4];
- x1[5] += x2[5];
- x2[4] = MULT_NORM(r1 * T[5] + r0 * T[4]);
- x2[5] = MULT_NORM(r1 * T[4] - r0 * T[5]);
-
- r0 = x1[2] - x2[2];
- r1 = x1[3] - x2[3];
- x1[2] += x2[2];
- x1[3] += x2[3];
- x2[2] = MULT_NORM(r1 * T[9] + r0 * T[8]);
- x2[3] = MULT_NORM(r1 * T[8] - r0 * T[9]);
-
- r0 = x1[0] - x2[0];
- r1 = x1[1] - x2[1];
- x1[0] += x2[0];
- x1[1] += x2[1];
- x2[0] = MULT_NORM(r1 * T[13] + r0 * T[12]);
- x2[1] = MULT_NORM(r1 * T[12] - r0 * T[13]);
-
- x1-=8;
- x2-=8;
- T+=16;
-
- }while(x2>=x);
- }
-
- /* N/stage point generic N stage butterfly (in place, 2 register) */
- STIN void mdct_butterfly_generic(DATA_TYPE *T,
- DATA_TYPE *x,
- int points,
- int trigint){
-
- DATA_TYPE *x1 = x + points - 8;
- DATA_TYPE *x2 = x + (points>>1) - 8;
- REG_TYPE r0;
- REG_TYPE r1;
-
- do{
-
- r0 = x1[6] - x2[6];
- r1 = x1[7] - x2[7];
- x1[6] += x2[6];
- x1[7] += x2[7];
- x2[6] = MULT_NORM(r1 * T[1] + r0 * T[0]);
- x2[7] = MULT_NORM(r1 * T[0] - r0 * T[1]);
-
- T+=trigint;
-
- r0 = x1[4] - x2[4];
- r1 = x1[5] - x2[5];
- x1[4] += x2[4];
- x1[5] += x2[5];
- x2[4] = MULT_NORM(r1 * T[1] + r0 * T[0]);
- x2[5] = MULT_NORM(r1 * T[0] - r0 * T[1]);
-
- T+=trigint;
-
- r0 = x1[2] - x2[2];
- r1 = x1[3] - x2[3];
- x1[2] += x2[2];
- x1[3] += x2[3];
- x2[2] = MULT_NORM(r1 * T[1] + r0 * T[0]);
- x2[3] = MULT_NORM(r1 * T[0] - r0 * T[1]);
-
- T+=trigint;
-
- r0 = x1[0] - x2[0];
- r1 = x1[1] - x2[1];
- x1[0] += x2[0];
- x1[1] += x2[1];
- x2[0] = MULT_NORM(r1 * T[1] + r0 * T[0]);
- x2[1] = MULT_NORM(r1 * T[0] - r0 * T[1]);
-
- T+=trigint;
- x1-=8;
- x2-=8;
-
- }while(x2>=x);
- }
-
- STIN void mdct_butterflies(mdct_lookup *init,
- DATA_TYPE *x,
- int points){
-
- DATA_TYPE *T=init->trig;
- int stages=init->log2n-5;
- int i,j;
-
- if(--stages>0){
- mdct_butterfly_first(T,x,points);
- }
-
- for(i=1;--stages>0;i++){
- for(j=0;j<(1<<i);j++)
- mdct_butterfly_generic(T,x+(points>>i)*j,points>>i,4<<i);
- }
-
- for(j=0;j<points;j+=32)
- mdct_butterfly_32(x+j);
-
- }
-
- void mdct_clear(mdct_lookup *l){
- if(l){
- if(l->trig)_ogg_free(l->trig);
- if(l->bitrev)_ogg_free(l->bitrev);
- memset(l,0,sizeof(*l));
- }
- }
-
- STIN void mdct_bitreverse(mdct_lookup *init,
- DATA_TYPE *x){
- int n = init->n;
- int *bit = init->bitrev;
- DATA_TYPE *w0 = x;
- DATA_TYPE *w1 = x = w0+(n>>1);
- DATA_TYPE *T = init->trig+n;
-
- do{
- DATA_TYPE *x0 = x+bit[0];
- DATA_TYPE *x1 = x+bit[1];
-
- REG_TYPE r0 = x0[1] - x1[1];
- REG_TYPE r1 = x0[0] + x1[0];
- REG_TYPE r2 = MULT_NORM(r1 * T[0] + r0 * T[1]);
- REG_TYPE r3 = MULT_NORM(r1 * T[1] - r0 * T[0]);
-
- w1 -= 4;
-
- r0 = HALVE(x0[1] + x1[1]);
- r1 = HALVE(x0[0] - x1[0]);
-
- w0[0] = r0 + r2;
- w1[2] = r0 - r2;
- w0[1] = r1 + r3;
- w1[3] = r3 - r1;
-
- x0 = x+bit[2];
- x1 = x+bit[3];
-
- r0 = x0[1] - x1[1];
- r1 = x0[0] + x1[0];
- r2 = MULT_NORM(r1 * T[2] + r0 * T[3]);
- r3 = MULT_NORM(r1 * T[3] - r0 * T[2]);
-
- r0 = HALVE(x0[1] + x1[1]);
- r1 = HALVE(x0[0] - x1[0]);
-
- w0[2] = r0 + r2;
- w1[0] = r0 - r2;
- w0[3] = r1 + r3;
- w1[1] = r3 - r1;
-
- T += 4;
- bit += 4;
- w0 += 4;
-
- }while(w0<w1);
- }
-
- void mdct_backward(mdct_lookup *init, DATA_TYPE *in, DATA_TYPE *out){
- int n=init->n;
- int n2=n>>1;
- int n4=n>>2;
-
- /* rotate */
-
- DATA_TYPE *iX = in+n2-7;
- DATA_TYPE *oX = out+n2+n4;
- DATA_TYPE *T = init->trig+n4;
-
- do{
- oX -= 4;
- oX[0] = MULT_NORM(-iX[2] * T[3] - iX[0] * T[2]);
- oX[1] = MULT_NORM (iX[0] * T[3] - iX[2] * T[2]);
- oX[2] = MULT_NORM(-iX[6] * T[1] - iX[4] * T[0]);
- oX[3] = MULT_NORM (iX[4] * T[1] - iX[6] * T[0]);
- iX -= 8;
- T += 4;
- }while(iX>=in);
-
- iX = in+n2-8;
- oX = out+n2+n4;
- T = init->trig+n4;
-
- do{
- T -= 4;
- oX[0] = MULT_NORM (iX[4] * T[3] + iX[6] * T[2]);
- oX[1] = MULT_NORM (iX[4] * T[2] - iX[6] * T[3]);
- oX[2] = MULT_NORM (iX[0] * T[1] + iX[2] * T[0]);
- oX[3] = MULT_NORM (iX[0] * T[0] - iX[2] * T[1]);
- iX -= 8;
- oX += 4;
- }while(iX>=in);
-
- mdct_butterflies(init,out+n2,n2);
- mdct_bitreverse(init,out);
-
- /* roatate + window */
-
- {
- DATA_TYPE *oX1=out+n2+n4;
- DATA_TYPE *oX2=out+n2+n4;
- DATA_TYPE *iX =out;
- T =init->trig+n2;
-
- do{
- oX1-=4;
-
- oX1[3] = MULT_NORM (iX[0] * T[1] - iX[1] * T[0]);
- oX2[0] = -MULT_NORM (iX[0] * T[0] + iX[1] * T[1]);
-
- oX1[2] = MULT_NORM (iX[2] * T[3] - iX[3] * T[2]);
- oX2[1] = -MULT_NORM (iX[2] * T[2] + iX[3] * T[3]);
-
- oX1[1] = MULT_NORM (iX[4] * T[5] - iX[5] * T[4]);
- oX2[2] = -MULT_NORM (iX[4] * T[4] + iX[5] * T[5]);
-
- oX1[0] = MULT_NORM (iX[6] * T[7] - iX[7] * T[6]);
- oX2[3] = -MULT_NORM (iX[6] * T[6] + iX[7] * T[7]);
-
- oX2+=4;
- iX += 8;
- T += 8;
- }while(iX<oX1);
-
- iX=out+n2+n4;
- oX1=out+n4;
- oX2=oX1;
-
- do{
- oX1-=4;
- iX-=4;
-
- oX2[0] = -(oX1[3] = iX[3]);
- oX2[1] = -(oX1[2] = iX[2]);
- oX2[2] = -(oX1[1] = iX[1]);
- oX2[3] = -(oX1[0] = iX[0]);
-
- oX2+=4;
- }while(oX2<iX);
-
- iX=out+n2+n4;
- oX1=out+n2+n4;
- oX2=out+n2;
- do{
- oX1-=4;
- oX1[0]= iX[3];
- oX1[1]= iX[2];
- oX1[2]= iX[1];
- oX1[3]= iX[0];
- iX+=4;
- }while(oX1>oX2);
- }
- }
-
- void mdct_forward(mdct_lookup *init, DATA_TYPE *in, DATA_TYPE *out){
- int n=init->n;
- int n2=n>>1;
- int n4=n>>2;
- int n8=n>>3;
- DATA_TYPE *w=(DATA_TYPE*) alloca(n*sizeof(*w)); /* forward needs working space */
- DATA_TYPE *w2=w+n2;
-
- /* rotate */
-
- /* window + rotate + step 1 */
-
- REG_TYPE r0;
- REG_TYPE r1;
- DATA_TYPE *x0=in+n2+n4;
- DATA_TYPE *x1=x0+1;
- DATA_TYPE *T=init->trig+n2;
-
- int i=0;
-
- for(i=0;i<n8;i+=2){
- x0 -=4;
- T-=2;
- r0= x0[2] + x1[0];
- r1= x0[0] + x1[2];
- w2[i]= MULT_NORM(r1*T[1] + r0*T[0]);
- w2[i+1]= MULT_NORM(r1*T[0] - r0*T[1]);
- x1 +=4;
- }
-
- x1=in+1;
-
- for(;i<n2-n8;i+=2){
- T-=2;
- x0 -=4;
- r0= x0[2] - x1[0];
- r1= x0[0] - x1[2];
- w2[i]= MULT_NORM(r1*T[1] + r0*T[0]);
- w2[i+1]= MULT_NORM(r1*T[0] - r0*T[1]);
- x1 +=4;
- }
-
- x0=in+n;
-
- for(;i<n2;i+=2){
- T-=2;
- x0 -=4;
- r0= -x0[2] - x1[0];
- r1= -x0[0] - x1[2];
- w2[i]= MULT_NORM(r1*T[1] + r0*T[0]);
- w2[i+1]= MULT_NORM(r1*T[0] - r0*T[1]);
- x1 +=4;
- }
-
- mdct_butterflies(init,w+n2,n2);
- mdct_bitreverse(init,w);
-
- /* roatate + window */
-
- T=init->trig+n2;
- x0=out+n2;
-
- for(i=0;i<n4;i++){
- x0--;
- out[i] =MULT_NORM((w[0]*T[0]+w[1]*T[1])*init->scale);
- x0[0] =MULT_NORM((w[0]*T[1]-w[1]*T[0])*init->scale);
- w+=2;
- T+=2;
- }
- }
-
- #endif
- /********* End of inlined file: mdct.c *********/
-
- /********* Start of inlined file: psy.c *********/
-
- /********* Start of inlined file: juce_OggVorbisHeader.h *********/
- // This file is included at the start of each Ogg-Vorbis .c file, just to do a few housekeeping
- // tasks..
-
- #ifdef _MSC_VER
- #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4305 4189 4706)
- #endif
- /********* End of inlined file: juce_OggVorbisHeader.h *********/
-
- #if JUCE_USE_OGGVORBIS
-
- #include <stdlib.h>
- #include <math.h>
- #include <string.h>
-
- /********* Start of inlined file: masking.h *********/
- #ifndef _V_MASKING_H_
- #define _V_MASKING_H_
-
- /* more detailed ATH; the bass if flat to save stressing the floor
- overly for only a bin or two of savings. */
-
- #define MAX_ATH 88
- static float ATH[]={
- /*15*/ -51, -52, -53, -54, -55, -56, -57, -58,
- /*31*/ -59, -60, -61, -62, -63, -64, -65, -66,
- /*63*/ -67, -68, -69, -70, -71, -72, -73, -74,
- /*125*/ -75, -76, -77, -78, -80, -81, -82, -83,
- /*250*/ -84, -85, -86, -87, -88, -88, -89, -89,
- /*500*/ -90, -91, -91, -92, -93, -94, -95, -96,
- /*1k*/ -96, -97, -98, -98, -99, -99,-100,-100,
- /*2k*/ -101,-102,-103,-104,-106,-107,-107,-107,
- /*4k*/ -107,-105,-103,-102,-101, -99, -98, -96,
- /*8k*/ -95, -95, -96, -97, -96, -95, -93, -90,
- /*16k*/ -80, -70, -50, -40, -30, -30, -30, -30
- };
-
- /* The tone masking curves from Ehmer's and Fielder's papers have been
- replaced by an empirically collected data set. The previously
- published values were, far too often, simply on crack. */
-
- #define EHMER_OFFSET 16
- #define EHMER_MAX 56
-
- /* masking tones from -50 to 0dB, 62.5 through 16kHz at half octaves
- test tones from -2 octaves to +5 octaves sampled at eighth octaves */
- /* (Vorbis 0dB, the loudest possible tone, is assumed to be ~100dB SPL
- for collection of these curves) */
-
- static float tonemasks[P_BANDS][6][EHMER_MAX]={
- /* 62.5 Hz */
- {{ -60, -60, -60, -60, -60, -60, -60, -60,
- -60, -60, -60, -60, -62, -62, -65, -73,
- -69, -68, -68, -67, -70, -70, -72, -74,
- -75, -79, -79, -80, -83, -88, -93, -100,
- -110, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- { -48, -48, -48, -48, -48, -48, -48, -48,
- -48, -48, -48, -48, -48, -53, -61, -66,
- -66, -68, -67, -70, -76, -76, -72, -73,
- -75, -76, -78, -79, -83, -88, -93, -100,
- -110, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- { -37, -37, -37, -37, -37, -37, -37, -37,
- -38, -40, -42, -46, -48, -53, -55, -62,
- -65, -58, -56, -56, -61, -60, -65, -67,
- -69, -71, -77, -77, -78, -80, -82, -84,
- -88, -93, -98, -106, -112, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- { -25, -25, -25, -25, -25, -25, -25, -25,
- -25, -26, -27, -29, -32, -38, -48, -52,
- -52, -50, -48, -48, -51, -52, -54, -60,
- -67, -67, -66, -68, -69, -73, -73, -76,
- -80, -81, -81, -85, -85, -86, -88, -93,
- -100, -110, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- { -16, -16, -16, -16, -16, -16, -16, -16,
- -17, -19, -20, -22, -26, -28, -31, -40,
- -47, -39, -39, -40, -42, -43, -47, -51,
- -57, -52, -55, -55, -60, -58, -62, -63,
- -70, -67, -69, -72, -73, -77, -80, -82,
- -83, -87, -90, -94, -98, -104, -115, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- { -8, -8, -8, -8, -8, -8, -8, -8,
- -8, -8, -10, -11, -15, -19, -25, -30,
- -34, -31, -30, -31, -29, -32, -35, -42,
- -48, -42, -44, -46, -50, -50, -51, -52,
- -59, -54, -55, -55, -58, -62, -63, -66,
- -72, -73, -76, -75, -78, -80, -80, -81,
- -84, -88, -90, -94, -98, -101, -106, -110}},
- /* 88Hz */
- {{ -66, -66, -66, -66, -66, -66, -66, -66,
- -66, -66, -66, -66, -66, -67, -67, -67,
- -76, -72, -71, -74, -76, -76, -75, -78,
- -79, -79, -81, -83, -86, -89, -93, -97,
- -100, -105, -110, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- { -47, -47, -47, -47, -47, -47, -47, -47,
- -47, -47, -47, -48, -51, -55, -59, -66,
- -66, -66, -67, -66, -68, -69, -70, -74,
- -79, -77, -77, -78, -80, -81, -82, -84,
- -86, -88, -91, -95, -100, -108, -116, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- { -36, -36, -36, -36, -36, -36, -36, -36,
- -36, -37, -37, -41, -44, -48, -51, -58,
- -62, -60, -57, -59, -59, -60, -63, -65,
- -72, -71, -70, -72, -74, -77, -76, -78,
- -81, -81, -80, -83, -86, -91, -96, -100,
- -105, -110, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- { -28, -28, -28, -28, -28, -28, -28, -28,
- -28, -30, -32, -32, -33, -35, -41, -49,
- -50, -49, -47, -48, -48, -52, -51, -57,
- -65, -61, -59, -61, -64, -69, -70, -74,
- -77, -77, -78, -81, -84, -85, -87, -90,
- -92, -96, -100, -107, -112, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- { -19, -19, -19, -19, -19, -19, -19, -19,
- -20, -21, -23, -27, -30, -35, -36, -41,
- -46, -44, -42, -40, -41, -41, -43, -48,
- -55, -53, -52, -53, -56, -59, -58, -60,
- -67, -66, -69, -71, -72, -75, -79, -81,
- -84, -87, -90, -93, -97, -101, -107, -114,
- -999, -999, -999, -999, -999, -999, -999, -999},
- { -9, -9, -9, -9, -9, -9, -9, -9,
- -11, -12, -12, -15, -16, -20, -23, -30,
- -37, -34, -33, -34, -31, -32, -32, -38,
- -47, -44, -41, -40, -47, -49, -46, -46,
- -58, -50, -50, -54, -58, -62, -64, -67,
- -67, -70, -72, -76, -79, -83, -87, -91,
- -96, -100, -104, -110, -999, -999, -999, -999}},
- /* 125 Hz */
- {{ -62, -62, -62, -62, -62, -62, -62, -62,
- -62, -62, -63, -64, -66, -67, -66, -68,
- -75, -72, -76, -75, -76, -78, -79, -82,
- -84, -85, -90, -94, -101, -110, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- { -59, -59, -59, -59, -59, -59, -59, -59,
- -59, -59, -59, -60, -60, -61, -63, -66,
- -71, -68, -70, -70, -71, -72, -72, -75,
- -81, -78, -79, -82, -83, -86, -90, -97,
- -103, -113, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- { -53, -53, -53, -53, -53, -53, -53, -53,
- -53, -54, -55, -57, -56, -57, -55, -61,
- -65, -60, -60, -62, -63, -63, -66, -68,
- -74, -73, -75, -75, -78, -80, -80, -82,
- -85, -90, -96, -101, -108, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- { -46, -46, -46, -46, -46, -46, -46, -46,
- -46, -46, -47, -47, -47, -47, -48, -51,
- -57, -51, -49, -50, -51, -53, -54, -59,
- -66, -60, -62, -67, -67, -70, -72, -75,
- -76, -78, -81, -85, -88, -94, -97, -104,
- -112, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- { -36, -36, -36, -36, -36, -36, -36, -36,
- -39, -41, -42, -42, -39, -38, -41, -43,
- -52, -44, -40, -39, -37, -37, -40, -47,
- -54, -50, -48, -50, -55, -61, -59, -62,
- -66, -66, -66, -69, -69, -73, -74, -74,
- -75, -77, -79, -82, -87, -91, -95, -100,
- -108, -115, -999, -999, -999, -999, -999, -999},
- { -28, -26, -24, -22, -20, -20, -23, -29,
- -30, -31, -28, -27, -28, -28, -28, -35,
- -40, -33, -32, -29, -30, -30, -30, -37,
- -45, -41, -37, -38, -45, -47, -47, -48,
- -53, -49, -48, -50, -49, -49, -51, -52,
- -58, -56, -57, -56, -60, -61, -62, -70,
- -72, -74, -78, -83, -88, -93, -100, -106}},
- /* 177 Hz */
- {{-999, -999, -999, -999, -999, -999, -999, -999,
- -999, -110, -105, -100, -95, -91, -87, -83,
- -80, -78, -76, -78, -78, -81, -83, -85,
- -86, -85, -86, -87, -90, -97, -107, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- {-999, -999, -999, -110, -105, -100, -95, -90,
- -85, -81, -77, -73, -70, -67, -67, -68,
- -75, -73, -70, -69, -70, -72, -75, -79,
- -84, -83, -84, -86, -88, -89, -89, -93,
- -98, -105, -112, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- {-105, -100, -95, -90, -85, -80, -76, -71,
- -68, -68, -65, -63, -63, -62, -62, -64,
- -65, -64, -61, -62, -63, -64, -66, -68,
- -73, -73, -74, -75, -76, -81, -83, -85,
- -88, -89, -92, -95, -100, -108, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- { -80, -75, -71, -68, -65, -63, -62, -61,
- -61, -61, -61, -59, -56, -57, -53, -50,
- -58, -52, -50, -50, -52, -53, -54, -58,
- -67, -63, -67, -68, -72, -75, -78, -80,
- -81, -81, -82, -85, -89, -90, -93, -97,
- -101, -107, -114, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- { -65, -61, -59, -57, -56, -55, -55, -56,
- -56, -57, -55, -53, -52, -47, -44, -44,
- -50, -44, -41, -39, -39, -42, -40, -46,
- -51, -49, -50, -53, -54, -63, -60, -61,
- -62, -66, -66, -66, -70, -73, -74, -75,
- -76, -75, -79, -85, -89, -91, -96, -102,
- -110, -999, -999, -999, -999, -999, -999, -999},
- { -52, -50, -49, -49, -48, -48, -48, -49,
- -50, -50, -49, -46, -43, -39, -35, -33,
- -38, -36, -32, -29, -32, -32, -32, -35,
- -44, -39, -38, -38, -46, -50, -45, -46,
- -53, -50, -50, -50, -54, -54, -53, -53,
- -56, -57, -59, -66, -70, -72, -74, -79,
- -83, -85, -90, -97, -114, -999, -999, -999}},
- /* 250 Hz */
- {{-999, -999, -999, -999, -999, -999, -110, -105,
- -100, -95, -90, -86, -80, -75, -75, -79,
- -80, -79, -80, -81, -82, -88, -95, -103,
- -110, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- {-999, -999, -999, -999, -108, -103, -98, -93,
- -88, -83, -79, -78, -75, -71, -67, -68,
- -73, -73, -72, -73, -75, -77, -80, -82,
- -88, -93, -100, -107, -114, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- {-999, -999, -999, -110, -105, -101, -96, -90,
- -86, -81, -77, -73, -69, -66, -61, -62,
- -66, -64, -62, -65, -66, -70, -72, -76,
- -81, -80, -84, -90, -95, -102, -110, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- {-999, -999, -999, -107, -103, -97, -92, -88,
- -83, -79, -74, -70, -66, -59, -53, -58,
- -62, -55, -54, -54, -54, -58, -61, -62,
- -72, -70, -72, -75, -78, -80, -81, -80,
- -83, -83, -88, -93, -100, -107, -115, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- {-999, -999, -999, -105, -100, -95, -90, -85,
- -80, -75, -70, -66, -62, -56, -48, -44,
- -48, -46, -46, -43, -46, -48, -48, -51,
- -58, -58, -59, -60, -62, -62, -61, -61,
- -65, -64, -65, -68, -70, -74, -75, -78,
- -81, -86, -95, -110, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- {-999, -999, -105, -100, -95, -90, -85, -80,
- -75, -70, -65, -61, -55, -49, -39, -33,
- -40, -35, -32, -38, -40, -33, -35, -37,
- -46, -41, -45, -44, -46, -42, -45, -46,
- -52, -50, -50, -50, -54, -54, -55, -57,
- -62, -64, -66, -68, -70, -76, -81, -90,
- -100, -110, -999, -999, -999, -999, -999, -999}},
- /* 354 hz */
- {{-999, -999, -999, -999, -999, -999, -999, -999,
- -105, -98, -90, -85, -82, -83, -80, -78,
- -84, -79, -80, -83, -87, -89, -91, -93,
- -99, -106, -117, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- {-999, -999, -999, -999, -999, -999, -999, -999,
- -105, -98, -90, -85, -80, -75, -70, -68,
- -74, -72, -74, -77, -80, -82, -85, -87,
- -92, -89, -91, -95, -100, -106, -112, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- {-999, -999, -999, -999, -999, -999, -999, -999,
- -105, -98, -90, -83, -75, -71, -63, -64,
- -67, -62, -64, -67, -70, -73, -77, -81,
- -84, -83, -85, -89, -90, -93, -98, -104,
- -109, -114, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- {-999, -999, -999, -999, -999, -999, -999, -999,
- -103, -96, -88, -81, -75, -68, -58, -54,
- -56, -54, -56, -56, -58, -60, -63, -66,
- -74, -69, -72, -72, -75, -74, -77, -81,
- -81, -82, -84, -87, -93, -96, -99, -104,
- -110, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- {-999, -999, -999, -999, -999, -108, -102, -96,
- -91, -85, -80, -74, -68, -60, -51, -46,
- -48, -46, -43, -45, -47, -47, -49, -48,
- -56, -53, -55, -58, -57, -63, -58, -60,
- -66, -64, -67, -70, -70, -74, -77, -84,
- -86, -89, -91, -93, -94, -101, -109, -118,
- -999, -999, -999, -999, -999, -999, -999, -999},
- {-999, -999, -999, -108, -103, -98, -93, -88,
- -83, -78, -73, -68, -60, -53, -44, -35,
- -38, -38, -34, -34, -36, -40, -41, -44,
- -51, -45, -46, -47, -46, -54, -50, -49,
- -50, -50, -50, -51, -54, -57, -58, -60,
- -66, -66, -66, -64, -65, -68, -77, -82,
- -87, -95, -110, -999, -999, -999, -999, -999}},
- /* 500 Hz */
- {{-999, -999, -999, -999, -999, -999, -999, -999,
- -107, -102, -97, -92, -87, -83, -78, -75,
- -82, -79, -83, -85, -89, -92, -95, -98,
- -101, -105, -109, -113, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- {-999, -999, -999, -999, -999, -999, -999, -106,
- -100, -95, -90, -86, -81, -78, -74, -69,
- -74, -74, -76, -79, -83, -84, -86, -89,
- -92, -97, -93, -100, -103, -107, -110, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- {-999, -999, -999, -999, -999, -999, -106, -100,
- -95, -90, -87, -83, -80, -75, -69, -60,
- -66, -66, -68, -70, -74, -78, -79, -81,
- -81, -83, -84, -87, -93, -96, -99, -103,
- -107, -110, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- {-999, -999, -999, -999, -999, -108, -103, -98,
- -93, -89, -85, -82, -78, -71, -62, -55,
- -58, -58, -54, -54, -55, -59, -61, -62,
- -70, -66, -66, -67, -70, -72, -75, -78,
- -84, -84, -84, -88, -91, -90, -95, -98,
- -102, -103, -106, -110, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- {-999, -999, -999, -999, -108, -103, -98, -94,
- -90, -87, -82, -79, -73, -67, -58, -47,
- -50, -45, -41, -45, -48, -44, -44, -49,
- -54, -51, -48, -47, -49, -50, -51, -57,
- -58, -60, -63, -69, -70, -69, -71, -74,
- -78, -82, -90, -95, -101, -105, -110, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- {-999, -999, -999, -105, -101, -97, -93, -90,
- -85, -80, -77, -72, -65, -56, -48, -37,
- -40, -36, -34, -40, -50, -47, -38, -41,
- -47, -38, -35, -39, -38, -43, -40, -45,
- -50, -45, -44, -47, -50, -55, -48, -48,
- -52, -66, -70, -76, -82, -90, -97, -105,
- -110, -999, -999, -999, -999, -999, -999, -999}},
- /* 707 Hz */
- {{-999, -999, -999, -999, -999, -999, -999, -999,
- -999, -108, -103, -98, -93, -86, -79, -76,
- -83, -81, -85, -87, -89, -93, -98, -102,
- -107, -112, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- {-999, -999, -999, -999, -999, -999, -999, -999,
- -999, -108, -103, -98, -93, -86, -79, -71,
- -77, -74, -77, -79, -81, -84, -85, -90,
- -92, -93, -92, -98, -101, -108, -112, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- {-999, -999, -999, -999, -999, -999, -999, -999,
- -108, -103, -98, -93, -87, -78, -68, -65,
- -66, -62, -65, -67, -70, -73, -75, -78,
- -82, -82, -83, -84, -91, -93, -98, -102,
- -106, -110, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- {-999, -999, -999, -999, -999, -999, -999, -999,
- -105, -100, -95, -90, -82, -74, -62, -57,
- -58, -56, -51, -52, -52, -54, -54, -58,
- -66, -59, -60, -63, -66, -69, -73, -79,
- -83, -84, -80, -81, -81, -82, -88, -92,
- -98, -105, -113, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- {-999, -999, -999, -999, -999, -999, -999, -107,
- -102, -97, -92, -84, -79, -69, -57, -47,
- -52, -47, -44, -45, -50, -52, -42, -42,
- -53, -43, -43, -48, -51, -56, -55, -52,
- -57, -59, -61, -62, -67, -71, -78, -83,
- -86, -94, -98, -103, -110, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- {-999, -999, -999, -999, -999, -999, -105, -100,
- -95, -90, -84, -78, -70, -61, -51, -41,
- -40, -38, -40, -46, -52, -51, -41, -40,
- -46, -40, -38, -38, -41, -46, -41, -46,
- -47, -43, -43, -45, -41, -45, -56, -67,
- -68, -83, -87, -90, -95, -102, -107, -113,
- -999, -999, -999, -999, -999, -999, -999, -999}},
- /* 1000 Hz */
- {{-999, -999, -999, -999, -999, -999, -999, -999,
- -999, -109, -105, -101, -96, -91, -84, -77,
- -82, -82, -85, -89, -94, -100, -106, -110,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- {-999, -999, -999, -999, -999, -999, -999, -999,
- -999, -106, -103, -98, -92, -85, -80, -71,
- -75, -72, -76, -80, -84, -86, -89, -93,
- -100, -107, -113, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- {-999, -999, -999, -999, -999, -999, -999, -107,
- -104, -101, -97, -92, -88, -84, -80, -64,
- -66, -63, -64, -66, -69, -73, -77, -83,
- -83, -86, -91, -98, -104, -111, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- {-999, -999, -999, -999, -999, -999, -999, -107,
- -104, -101, -97, -92, -90, -84, -74, -57,
- -58, -52, -55, -54, -50, -52, -50, -52,
- -63, -62, -69, -76, -77, -78, -78, -79,
- -82, -88, -94, -100, -106, -111, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- {-999, -999, -999, -999, -999, -999, -106, -102,
- -98, -95, -90, -85, -83, -78, -70, -50,
- -50, -41, -44, -49, -47, -50, -50, -44,
- -55, -46, -47, -48, -48, -54, -49, -49,
- -58, -62, -71, -81, -87, -92, -97, -102,
- -108, -114, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- {-999, -999, -999, -999, -999, -999, -106, -102,
- -98, -95, -90, -85, -83, -78, -70, -45,
- -43, -41, -47, -50, -51, -50, -49, -45,
- -47, -41, -44, -41, -39, -43, -38, -37,
- -40, -41, -44, -50, -58, -65, -73, -79,
- -85, -92, -97, -101, -105, -109, -113, -999,
- -999, -999, -999, -999, -999, -999, -999, -999}},
- /* 1414 Hz */
- {{-999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -107, -100, -95, -87, -81,
- -85, -83, -88, -93, -100, -107, -114, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- {-999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -107, -101, -95, -88, -83, -76,
- -73, -72, -79, -84, -90, -95, -100, -105,
- -110, -115, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- {-999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -104, -98, -92, -87, -81, -70,
- -65, -62, -67, -71, -74, -80, -85, -91,
- -95, -99, -103, -108, -111, -114, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- {-999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -103, -97, -90, -85, -76, -60,
- -56, -54, -60, -62, -61, -56, -63, -65,
- -73, -74, -77, -75, -78, -81, -86, -87,
- -88, -91, -94, -98, -103, -110, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- {-999, -999, -999, -999, -999, -999, -999, -105,
- -100, -97, -92, -86, -81, -79, -70, -57,
- -51, -47, -51, -58, -60, -56, -53, -50,
- -58, -52, -50, -50, -53, -55, -64, -69,
- -71, -85, -82, -78, -81, -85, -95, -102,
- -112, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- {-999, -999, -999, -999, -999, -999, -999, -105,
- -100, -97, -92, -85, -83, -79, -72, -49,
- -40, -43, -43, -54, -56, -51, -50, -40,
- -43, -38, -36, -35, -37, -38, -37, -44,
- -54, -60, -57, -60, -70, -75, -84, -92,
- -103, -112, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999}},
- /* 2000 Hz */
- {{-999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -110, -102, -95, -89, -82,
- -83, -84, -90, -92, -99, -107, -113, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- {-999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -107, -101, -95, -89, -83, -72,
- -74, -78, -85, -88, -88, -90, -92, -98,
- -105, -111, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- {-999, -999, -999, -999, -999, -999, -999, -999,
- -999, -109, -103, -97, -93, -87, -81, -70,
- -70, -67, -75, -73, -76, -79, -81, -83,
- -88, -89, -97, -103, -110, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- {-999, -999, -999, -999, -999, -999, -999, -999,
- -999, -107, -100, -94, -88, -83, -75, -63,
- -59, -59, -63, -66, -60, -62, -67, -67,
- -77, -76, -81, -88, -86, -92, -96, -102,
- -109, -116, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- {-999, -999, -999, -999, -999, -999, -999, -999,
- -999, -105, -98, -92, -86, -81, -73, -56,
- -52, -47, -55, -60, -58, -52, -51, -45,
- -49, -50, -53, -54, -61, -71, -70, -69,
- -78, -79, -87, -90, -96, -104, -112, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- {-999, -999, -999, -999, -999, -999, -999, -999,
- -999, -103, -96, -90, -86, -78, -70, -51,
- -42, -47, -48, -55, -54, -54, -53, -42,
- -35, -28, -33, -38, -37, -44, -47, -49,
- -54, -63, -68, -78, -82, -89, -94, -99,
- -104, -109, -114, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999}},
- /* 2828 Hz */
- {{-999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -110, -100, -90, -79,
- -85, -81, -82, -82, -89, -94, -99, -103,
- -109, -115, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- {-999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -105, -97, -85, -72,
- -74, -70, -70, -70, -76, -85, -91, -93,
- -97, -103, -109, -115, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- {-999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -112, -93, -81, -68,
- -62, -60, -60, -57, -63, -70, -77, -82,
- -90, -93, -98, -104, -109, -113, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- {-999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -113, -100, -93, -84, -63,
- -58, -48, -53, -54, -52, -52, -57, -64,
- -66, -76, -83, -81, -85, -85, -90, -95,
- -98, -101, -103, -106, -108, -111, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- {-999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -105, -95, -86, -74, -53,
- -50, -38, -43, -49, -43, -42, -39, -39,
- -46, -52, -57, -56, -72, -69, -74, -81,
- -87, -92, -94, -97, -99, -102, -105, -108,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- {-999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -108, -99, -90, -76, -66, -45,
- -43, -41, -44, -47, -43, -47, -40, -30,
- -31, -31, -39, -33, -40, -41, -43, -53,
- -59, -70, -73, -77, -79, -82, -84, -87,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999}},
- /* 4000 Hz */
- {{-999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -110, -91, -76,
- -75, -85, -93, -98, -104, -110, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- {-999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -110, -91, -70,
- -70, -75, -86, -89, -94, -98, -101, -106,
- -110, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- {-999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -110, -95, -80, -60,
- -65, -64, -74, -83, -88, -91, -95, -99,
- -103, -107, -110, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- {-999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -110, -95, -80, -58,
- -55, -49, -66, -68, -71, -78, -78, -80,
- -88, -85, -89, -97, -100, -105, -110, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- {-999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -110, -95, -80, -53,
- -52, -41, -59, -59, -49, -58, -56, -63,
- -86, -79, -90, -93, -98, -103, -107, -112,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- {-999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -110, -97, -91, -73, -45,
- -40, -33, -53, -61, -49, -54, -50, -50,
- -60, -52, -67, -74, -81, -92, -96, -100,
- -105, -110, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999}},
- /* 5657 Hz */
- {{-999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -113, -106, -99, -92, -77,
- -80, -88, -97, -106, -115, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- {-999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -116, -109, -102, -95, -89, -74,
- -72, -88, -87, -95, -102, -109, -116, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- {-999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -116, -109, -102, -95, -89, -75,
- -66, -74, -77, -78, -86, -87, -90, -96,
- -105, -115, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- {-999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -115, -108, -101, -94, -88, -66,
- -56, -61, -70, -65, -78, -72, -83, -84,
- -93, -98, -105, -110, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- {-999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -110, -105, -95, -89, -82, -57,
- -52, -52, -59, -56, -59, -58, -69, -67,
- -88, -82, -82, -89, -94, -100, -108, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- {-999, -999, -999, -999, -999, -999, -999, -999,
- -999, -110, -101, -96, -90, -83, -77, -54,
- -43, -38, -50, -48, -52, -48, -42, -42,
- -51, -52, -53, -59, -65, -71, -78, -85,
- -95, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999}},
- /* 8000 Hz */
- {{-999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -120, -105, -86, -68,
- -78, -79, -90, -100, -110, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- {-999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -120, -105, -86, -66,
- -73, -77, -88, -96, -105, -115, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- {-999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -120, -105, -92, -80, -61,
- -64, -68, -80, -87, -92, -100, -110, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- {-999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -120, -104, -91, -79, -52,
- -60, -54, -64, -69, -77, -80, -82, -84,
- -85, -87, -88, -90, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- {-999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -118, -100, -87, -77, -49,
- -50, -44, -58, -61, -61, -67, -65, -62,
- -62, -62, -65, -68, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- {-999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -115, -98, -84, -62, -49,
- -44, -38, -46, -49, -49, -46, -39, -37,
- -39, -40, -42, -43, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999}},
- /* 11314 Hz */
- {{-999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -110, -88, -74,
- -77, -82, -82, -85, -90, -94, -99, -104,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- {-999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -110, -88, -66,
- -70, -81, -80, -81, -84, -88, -91, -93,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- {-999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -110, -88, -61,
- -63, -70, -71, -74, -77, -80, -83, -85,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- {-999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -110, -86, -62,
- -63, -62, -62, -58, -52, -50, -50, -52,
- -54, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- {-999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -118, -108, -84, -53,
- -50, -50, -50, -55, -47, -45, -40, -40,
- -40, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- {-999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -118, -100, -73, -43,
- -37, -42, -43, -53, -38, -37, -35, -35,
- -38, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999}},
- /* 16000 Hz */
- {{-999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -110, -100, -91, -84, -74,
- -80, -80, -80, -80, -80, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- {-999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -110, -100, -91, -84, -74,
- -68, -68, -68, -68, -68, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- {-999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -110, -100, -86, -78, -70,
- -60, -45, -30, -21, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- {-999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -110, -100, -87, -78, -67,
- -48, -38, -29, -21, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- {-999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -110, -100, -86, -69, -56,
- -45, -35, -33, -29, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999},
- {-999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -110, -100, -83, -71, -48,
- -27, -38, -37, -34, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999,
- -999, -999, -999, -999, -999, -999, -999, -999}}
- };
-
- #endif
- /********* End of inlined file: masking.h *********/
-
- #define NEGINF -9999.f
- static double stereo_threshholds[]={0.0, .5, 1.0, 1.5, 2.5, 4.5, 8.5, 16.5, 9e10};
- static double stereo_threshholds_limited[]={0.0, .5, 1.0, 1.5, 2.0, 2.5, 4.5, 8.5, 9e10};
-
- vorbis_look_psy_global *_vp_global_look(vorbis_info *vi){
- codec_setup_info *ci=(codec_setup_info*)vi->codec_setup;
- vorbis_info_psy_global *gi=&ci->psy_g_param;
- vorbis_look_psy_global *look=(vorbis_look_psy_global*)_ogg_calloc(1,sizeof(*look));
-
- look->channels=vi->channels;
-
- look->ampmax=-9999.;
- look->gi=gi;
- return(look);
- }
-
- void _vp_global_free(vorbis_look_psy_global *look){
- if(look){
- memset(look,0,sizeof(*look));
- _ogg_free(look);
- }
- }
-
- void _vi_gpsy_free(vorbis_info_psy_global *i){
- if(i){
- memset(i,0,sizeof(*i));
- _ogg_free(i);
- }
- }
-
- void _vi_psy_free(vorbis_info_psy *i){
- if(i){
- memset(i,0,sizeof(*i));
- _ogg_free(i);
- }
- }
-
- static void min_curve(float *c,
- float *c2){
- int i;
- for(i=0;i<EHMER_MAX;i++)if(c2[i]<c[i])c[i]=c2[i];
- }
- static void max_curve(float *c,
- float *c2){
- int i;
- for(i=0;i<EHMER_MAX;i++)if(c2[i]>c[i])c[i]=c2[i];
- }
-
- static void attenuate_curve(float *c,float att){
- int i;
- for(i=0;i<EHMER_MAX;i++)
- c[i]+=att;
- }
-
- static float ***setup_tone_curves(float curveatt_dB[P_BANDS],float binHz,int n,
- float center_boost, float center_decay_rate){
- int i,j,k,m;
- float ath[EHMER_MAX];
- float workc[P_BANDS][P_LEVELS][EHMER_MAX];
- float athc[P_LEVELS][EHMER_MAX];
- float *brute_buffer=(float*) alloca(n*sizeof(*brute_buffer));
-
- float ***ret=(float***) _ogg_malloc(sizeof(*ret)*P_BANDS);
-
- memset(workc,0,sizeof(workc));
-
- for(i=0;i<P_BANDS;i++){
- /* we add back in the ATH to avoid low level curves falling off to
- -infinity and unnecessarily cutting off high level curves in the
- curve limiting (last step). */
-
- /* A half-band's settings must be valid over the whole band, and
- it's better to mask too little than too much */
- int ath_offset=i*4;
- for(j=0;j<EHMER_MAX;j++){
- float min=999.;
- for(k=0;k<4;k++)
- if(j+k+ath_offset<MAX_ATH){
- if(min>ATH[j+k+ath_offset])min=ATH[j+k+ath_offset];
- }else{
- if(min>ATH[MAX_ATH-1])min=ATH[MAX_ATH-1];
- }
- ath[j]=min;
- }
-
- /* copy curves into working space, replicate the 50dB curve to 30
- and 40, replicate the 100dB curve to 110 */
- for(j=0;j<6;j++)
- memcpy(workc[i][j+2],tonemasks[i][j],EHMER_MAX*sizeof(*tonemasks[i][j]));
- memcpy(workc[i][0],tonemasks[i][0],EHMER_MAX*sizeof(*tonemasks[i][0]));
- memcpy(workc[i][1],tonemasks[i][0],EHMER_MAX*sizeof(*tonemasks[i][0]));
-
- /* apply centered curve boost/decay */
- for(j=0;j<P_LEVELS;j++){
- for(k=0;k<EHMER_MAX;k++){
- float adj=center_boost+abs(EHMER_OFFSET-k)*center_decay_rate;
- if(adj<0. && center_boost>0)adj=0.;
- if(adj>0. && center_boost<0)adj=0.;
- workc[i][j][k]+=adj;
- }
- }
-
- /* normalize curves so the driving amplitude is 0dB */
- /* make temp curves with the ATH overlayed */
- for(j=0;j<P_LEVELS;j++){
- attenuate_curve(workc[i][j],curveatt_dB[i]+100.-(j<2?2:j)*10.-P_LEVEL_0);
- memcpy(athc[j],ath,EHMER_MAX*sizeof(**athc));
- attenuate_curve(athc[j],+100.-j*10.f-P_LEVEL_0);
- max_curve(athc[j],workc[i][j]);
- }
-
- /* Now limit the louder curves.
-
- the idea is this: We don't know what the playback attenuation
- will be; 0dB SL moves every time the user twiddles the volume
- knob. So that means we have to use a single 'most pessimal' curve
- for all masking amplitudes, right? Wrong. The *loudest* sound
- can be in (we assume) a range of ...+100dB] SL. However, sounds
- 20dB down will be in a range ...+80], 40dB down is from ...+60],
- etc... */
-
- for(j=1;j<P_LEVELS;j++){
- min_curve(athc[j],athc[j-1]);
- min_curve(workc[i][j],athc[j]);
- }
- }
-
- for(i=0;i<P_BANDS;i++){
- int hi_curve,lo_curve,bin;
- ret[i]=(float**)_ogg_malloc(sizeof(**ret)*P_LEVELS);
-
- /* low frequency curves are measured with greater resolution than
- the MDCT/FFT will actually give us; we want the curve applied
- to the tone data to be pessimistic and thus apply the minimum
- masking possible for a given bin. That means that a single bin
- could span more than one octave and that the curve will be a
- composite of multiple octaves. It also may mean that a single
- bin may span > an eighth of an octave and that the eighth
- octave values may also be composited. */
-
- /* which octave curves will we be compositing? */
- bin=floor(fromOC(i*.5)/binHz);
- lo_curve= ceil(toOC(bin*binHz+1)*2);
- hi_curve= floor(toOC((bin+1)*binHz)*2);
- if(lo_curve>i)lo_curve=i;
- if(lo_curve<0)lo_curve=0;
- if(hi_curve>=P_BANDS)hi_curve=P_BANDS-1;
-
- for(m=0;m<P_LEVELS;m++){
- ret[i][m]=(float*)_ogg_malloc(sizeof(***ret)*(EHMER_MAX+2));
-
- for(j=0;j<n;j++)brute_buffer[j]=999.;
-
- /* render the curve into bins, then pull values back into curve.
- The point is that any inherent subsampling aliasing results in
- a safe minimum */
- for(k=lo_curve;k<=hi_curve;k++){
- int l=0;
-
- for(j=0;j<EHMER_MAX;j++){
- int lo_bin= fromOC(j*.125+k*.5-2.0625)/binHz;
- int hi_bin= fromOC(j*.125+k*.5-1.9375)/binHz+1;
-
- if(lo_bin<0)lo_bin=0;
- if(lo_bin>n)lo_bin=n;
- if(lo_bin<l)l=lo_bin;
- if(hi_bin<0)hi_bin=0;
- if(hi_bin>n)hi_bin=n;
-
- for(;l<hi_bin && l<n;l++)
- if(brute_buffer[l]>workc[k][m][j])
- brute_buffer[l]=workc[k][m][j];
- }
-
- for(;l<n;l++)
- if(brute_buffer[l]>workc[k][m][EHMER_MAX-1])
- brute_buffer[l]=workc[k][m][EHMER_MAX-1];
-
- }
-
- /* be equally paranoid about being valid up to next half ocatve */
- if(i+1<P_BANDS){
- int l=0;
- k=i+1;
- for(j=0;j<EHMER_MAX;j++){
- int lo_bin= fromOC(j*.125+i*.5-2.0625)/binHz;
- int hi_bin= fromOC(j*.125+i*.5-1.9375)/binHz+1;
-
- if(lo_bin<0)lo_bin=0;
- if(lo_bin>n)lo_bin=n;
- if(lo_bin<l)l=lo_bin;
- if(hi_bin<0)hi_bin=0;
- if(hi_bin>n)hi_bin=n;
-
- for(;l<hi_bin && l<n;l++)
- if(brute_buffer[l]>workc[k][m][j])
- brute_buffer[l]=workc[k][m][j];
- }
-
- for(;l<n;l++)
- if(brute_buffer[l]>workc[k][m][EHMER_MAX-1])
- brute_buffer[l]=workc[k][m][EHMER_MAX-1];
-
- }
-
- for(j=0;j<EHMER_MAX;j++){
- int bin=fromOC(j*.125+i*.5-2.)/binHz;
- if(bin<0){
- ret[i][m][j+2]=-999.;
- }else{
- if(bin>=n){
- ret[i][m][j+2]=-999.;
- }else{
- ret[i][m][j+2]=brute_buffer[bin];
- }
- }
- }
-
- /* add fenceposts */
- for(j=0;j<EHMER_OFFSET;j++)
- if(ret[i][m][j+2]>-200.f)break;
- ret[i][m][0]=j;
-
- for(j=EHMER_MAX-1;j>EHMER_OFFSET+1;j--)
- if(ret[i][m][j+2]>-200.f)
- break;
- ret[i][m][1]=j;
-
- }
- }
-
- return(ret);
- }
-
- void _vp_psy_init(vorbis_look_psy *p,vorbis_info_psy *vi,
- vorbis_info_psy_global *gi,int n,long rate){
- long i,j,lo=-99,hi=1;
- long maxoc;
- memset(p,0,sizeof(*p));
-
- p->eighth_octave_lines=gi->eighth_octave_lines;
- p->shiftoc=rint(log(gi->eighth_octave_lines*8.f)/log(2.f))-1;
-
- p->firstoc=toOC(.25f*rate*.5/n)*(1<<(p->shiftoc+1))-gi->eighth_octave_lines;
- maxoc=toOC((n+.25f)*rate*.5/n)*(1<<(p->shiftoc+1))+.5f;
- p->total_octave_lines=maxoc-p->firstoc+1;
- p->ath=(float*)_ogg_malloc(n*sizeof(*p->ath));
-
- p->octave=(long*)_ogg_malloc(n*sizeof(*p->octave));
- p->bark=(long*)_ogg_malloc(n*sizeof(*p->bark));
- p->vi=vi;
- p->n=n;
- p->rate=rate;
-
- /* AoTuV HF weighting */
- p->m_val = 1.;
- if(rate < 26000) p->m_val = 0;
- else if(rate < 38000) p->m_val = .94; /* 32kHz */
- else if(rate > 46000) p->m_val = 1.275; /* 48kHz */
-
- /* set up the lookups for a given blocksize and sample rate */
-
- for(i=0,j=0;i<MAX_ATH-1;i++){
- int endpos=rint(fromOC((i+1)*.125-2.)*2*n/rate);
- float base=ATH[i];
- if(j<endpos){
- float delta=(ATH[i+1]-base)/(endpos-j);
- for(;j<endpos && j<n;j++){
- p->ath[j]=base+100.;
- base+=delta;
- }
- }
- }
-
- for(i=0;i<n;i++){
- float bark=toBARK(rate/(2*n)*i);
-
- for(;lo+vi->noisewindowlomin<i &&
- toBARK(rate/(2*n)*lo)<(bark-vi->noisewindowlo);lo++);
-
- for(;hi<=n && (hi<i+vi->noisewindowhimin ||
- toBARK(rate/(2*n)*hi)<(bark+vi->noisewindowhi));hi++);
-
- p->bark[i]=((lo-1)<<16)+(hi-1);
-
- }
-
- for(i=0;i<n;i++)
- p->octave[i]=toOC((i+.25f)*.5*rate/n)*(1<<(p->shiftoc+1))+.5f;
-
- p->tonecurves=setup_tone_curves(vi->toneatt,rate*.5/n,n,
- vi->tone_centerboost,vi->tone_decay);
-
- /* set up rolling noise median */
- p->noiseoffset=(float**)_ogg_malloc(P_NOISECURVES*sizeof(*p->noiseoffset));
- for(i=0;i<P_NOISECURVES;i++)
- p->noiseoffset[i]=(float*)_ogg_malloc(n*sizeof(**p->noiseoffset));
-
- for(i=0;i<n;i++){
- float halfoc=toOC((i+.5)*rate/(2.*n))*2.;
- int inthalfoc;
- float del;
-
- if(halfoc<0)halfoc=0;
- if(halfoc>=P_BANDS-1)halfoc=P_BANDS-1;
- inthalfoc=(int)halfoc;
- del=halfoc-inthalfoc;
-
- for(j=0;j<P_NOISECURVES;j++)
- p->noiseoffset[j][i]=
- p->vi->noiseoff[j][inthalfoc]*(1.-del) +
- p->vi->noiseoff[j][inthalfoc+1]*del;
-
- }
- #if 0
- {
- static int ls=0;
- _analysis_output_always("noiseoff0",ls,p->noiseoffset[0],n,1,0,0);
- _analysis_output_always("noiseoff1",ls,p->noiseoffset[1],n,1,0,0);
- _analysis_output_always("noiseoff2",ls++,p->noiseoffset[2],n,1,0,0);
- }
- #endif
- }
-
- void _vp_psy_clear(vorbis_look_psy *p){
- int i,j;
- if(p){
- if(p->ath)_ogg_free(p->ath);
- if(p->octave)_ogg_free(p->octave);
- if(p->bark)_ogg_free(p->bark);
- if(p->tonecurves){
- for(i=0;i<P_BANDS;i++){
- for(j=0;j<P_LEVELS;j++){
- _ogg_free(p->tonecurves[i][j]);
- }
- _ogg_free(p->tonecurves[i]);
- }
- _ogg_free(p->tonecurves);
- }
- if(p->noiseoffset){
- for(i=0;i<P_NOISECURVES;i++){
- _ogg_free(p->noiseoffset[i]);
- }
- _ogg_free(p->noiseoffset);
- }
- memset(p,0,sizeof(*p));
- }
- }
-
- /* octave/(8*eighth_octave_lines) x scale and dB y scale */
- static void seed_curve(float *seed,
- const float **curves,
- float amp,
- int oc, int n,
- int linesper,float dBoffset){
- int i,post1;
- int seedptr;
- const float *posts,*curve;
-
- int choice=(int)((amp+dBoffset-P_LEVEL_0)*.1f);
- choice=max(choice,0);
- choice=min(choice,P_LEVELS-1);
- posts=curves[choice];
- curve=posts+2;
- post1=(int)posts[1];
- seedptr=oc+(posts[0]-EHMER_OFFSET)*linesper-(linesper>>1);
-
- for(i=posts[0];i<post1;i++){
- if(seedptr>0){
- float lin=amp+curve[i];
- if(seed[seedptr]<lin)seed[seedptr]=lin;
- }
- seedptr+=linesper;
- if(seedptr>=n)break;
- }
- }
-
- static void seed_loop(vorbis_look_psy *p,
- const float ***curves,
- const float *f,
- const float *flr,
- float *seed,
- float specmax){
- vorbis_info_psy *vi=p->vi;
- long n=p->n,i;
- float dBoffset=vi->max_curve_dB-specmax;
-
- /* prime the working vector with peak values */
-
- for(i=0;i<n;i++){
- float max=f[i];
- long oc=p->octave[i];
- while(i+1<n && p->octave[i+1]==oc){
- i++;
- if(f[i]>max)max=f[i];
- }
-
- if(max+6.f>flr[i]){
- oc=oc>>p->shiftoc;
-
- if(oc>=P_BANDS)oc=P_BANDS-1;
- if(oc<0)oc=0;
-
- seed_curve(seed,
- curves[oc],
- max,
- p->octave[i]-p->firstoc,
- p->total_octave_lines,
- p->eighth_octave_lines,
- dBoffset);
- }
- }
- }
-
- static void seed_chase(float *seeds, int linesper, long n){
- long *posstack=(long*)alloca(n*sizeof(*posstack));
- float *ampstack=(float*)alloca(n*sizeof(*ampstack));
- long stack=0;
- long pos=0;
- long i;
-
- for(i=0;i<n;i++){
- if(stack<2){
- posstack[stack]=i;
- ampstack[stack++]=seeds[i];
- }else{
- while(1){
- if(seeds[i]<ampstack[stack-1]){
- posstack[stack]=i;
- ampstack[stack++]=seeds[i];
- break;
- }else{
- if(i<posstack[stack-1]+linesper){
- if(stack>1 && ampstack[stack-1]<=ampstack[stack-2] &&
- i<posstack[stack-2]+linesper){
- /* we completely overlap, making stack-1 irrelevant. pop it */
- stack--;
- continue;
- }
- }
- posstack[stack]=i;
- ampstack[stack++]=seeds[i];
- break;
-
- }
- }
- }
- }
-
- /* the stack now contains only the positions that are relevant. Scan
- 'em straight through */
-
- for(i=0;i<stack;i++){
- long endpos;
- if(i<stack-1 && ampstack[i+1]>ampstack[i]){
- endpos=posstack[i+1];
- }else{
- endpos=posstack[i]+linesper+1; /* +1 is important, else bin 0 is
- discarded in short frames */
- }
- if(endpos>n)endpos=n;
- for(;pos<endpos;pos++)
- seeds[pos]=ampstack[i];
- }
-
- /* there. Linear time. I now remember this was on a problem set I
- had in Grad Skool... I didn't solve it at the time ;-) */
-
- }
-
- /* bleaugh, this is more complicated than it needs to be */
- #include<stdio.h>
- static void max_seeds(vorbis_look_psy *p,
- float *seed,
- float *flr){
- long n=p->total_octave_lines;
- int linesper=p->eighth_octave_lines;
- long linpos=0;
- long pos;
-
- seed_chase(seed,linesper,n); /* for masking */
-
- pos=p->octave[0]-p->firstoc-(linesper>>1);
-
- while(linpos+1<p->n){
- float minV=seed[pos];
- long end=((p->octave[linpos]+p->octave[linpos+1])>>1)-p->firstoc;
- if(minV>p->vi->tone_abs_limit)minV=p->vi->tone_abs_limit;
- while(pos+1<=end){
- pos++;
- if((seed[pos]>NEGINF && seed[pos]<minV) || minV==NEGINF)
- minV=seed[pos];
- }
-
- end=pos+p->firstoc;
- for(;linpos<p->n && p->octave[linpos]<=end;linpos++)
- if(flr[linpos]<minV)flr[linpos]=minV;
- }
-
- {
- float minV=seed[p->total_octave_lines-1];
- for(;linpos<p->n;linpos++)
- if(flr[linpos]<minV)flr[linpos]=minV;
- }
-
- }
-
- static void bark_noise_hybridmp(int n,const long *b,
- const float *f,
- float *noise,
- const float offset,
- const int fixed){
-
- float *N=(float*) alloca(n*sizeof(*N));
- float *X=(float*) alloca(n*sizeof(*N));
- float *XX=(float*) alloca(n*sizeof(*N));
- float *Y=(float*) alloca(n*sizeof(*N));
- float *XY=(float*) alloca(n*sizeof(*N));
-
- float tN, tX, tXX, tY, tXY;
- int i;
-
- int lo, hi;
- float R, A, B, D;
- float w, x, y;
-
- tN = tX = tXX = tY = tXY = 0.f;
-
- y = f[0] + offset;
- if (y < 1.f) y = 1.f;
-
- w = y * y * .5;
-
- tN += w;
- tX += w;
- tY += w * y;
-
- N[0] = tN;
- X[0] = tX;
- XX[0] = tXX;
- Y[0] = tY;
- XY[0] = tXY;
-
- for (i = 1, x = 1.f; i < n; i++, x += 1.f) {
-
- y = f[i] + offset;
- if (y < 1.f) y = 1.f;
-
- w = y * y;
-
- tN += w;
- tX += w * x;
- tXX += w * x * x;
- tY += w * y;
- tXY += w * x * y;
-
- N[i] = tN;
- X[i] = tX;
- XX[i] = tXX;
- Y[i] = tY;
- XY[i] = tXY;
- }
-
- for (i = 0, x = 0.f;; i++, x += 1.f) {
-
- lo = b[i] >> 16;
- if( lo>=0 ) break;
- hi = b[i] & 0xffff;
-
- tN = N[hi] + N[-lo];
- tX = X[hi] - X[-lo];
- tXX = XX[hi] + XX[-lo];
- tY = Y[hi] + Y[-lo];
- tXY = XY[hi] - XY[-lo];
-
- A = tY * tXX - tX * tXY;
- B = tN * tXY - tX * tY;
- D = tN * tXX - tX * tX;
- R = (A + x * B) / D;
- if (R < 0.f)
- R = 0.f;
-
- noise[i] = R - offset;
- }
-
- for ( ;; i++, x += 1.f) {
-
- lo = b[i] >> 16;
- hi = b[i] & 0xffff;
- if(hi>=n)break;
-
- tN = N[hi] - N[lo];
- tX = X[hi] - X[lo];
- tXX = XX[hi] - XX[lo];
- tY = Y[hi] - Y[lo];
- tXY = XY[hi] - XY[lo];
-
- A = tY * tXX - tX * tXY;
- B = tN * tXY - tX * tY;
- D = tN * tXX - tX * tX;
- R = (A + x * B) / D;
- if (R < 0.f) R = 0.f;
-
- noise[i] = R - offset;
- }
- for ( ; i < n; i++, x += 1.f) {
-
- R = (A + x * B) / D;
- if (R < 0.f) R = 0.f;
-
- noise[i] = R - offset;
- }
-
- if (fixed <= 0) return;
-
- for (i = 0, x = 0.f;; i++, x += 1.f) {
- hi = i + fixed / 2;
- lo = hi - fixed;
- if(lo>=0)break;
-
- tN = N[hi] + N[-lo];
- tX = X[hi] - X[-lo];
- tXX = XX[hi] + XX[-lo];
- tY = Y[hi] + Y[-lo];
- tXY = XY[hi] - XY[-lo];
-
- A = tY * tXX - tX * tXY;
- B = tN * tXY - tX * tY;
- D = tN * tXX - tX * tX;
- R = (A + x * B) / D;
-
- if (R - offset < noise[i]) noise[i] = R - offset;
- }
- for ( ;; i++, x += 1.f) {
-
- hi = i + fixed / 2;
- lo = hi - fixed;
- if(hi>=n)break;
-
- tN = N[hi] - N[lo];
- tX = X[hi] - X[lo];
- tXX = XX[hi] - XX[lo];
- tY = Y[hi] - Y[lo];
- tXY = XY[hi] - XY[lo];
-
- A = tY * tXX - tX * tXY;
- B = tN * tXY - tX * tY;
- D = tN * tXX - tX * tX;
- R = (A + x * B) / D;
-
- if (R - offset < noise[i]) noise[i] = R - offset;
- }
- for ( ; i < n; i++, x += 1.f) {
- R = (A + x * B) / D;
- if (R - offset < noise[i]) noise[i] = R - offset;
- }
- }
-
- static float FLOOR1_fromdB_INV_LOOKUP[256]={
- 0.F, 8.81683e+06F, 8.27882e+06F, 7.77365e+06F,
- 7.29930e+06F, 6.85389e+06F, 6.43567e+06F, 6.04296e+06F,
- 5.67422e+06F, 5.32798e+06F, 5.00286e+06F, 4.69759e+06F,
- 4.41094e+06F, 4.14178e+06F, 3.88905e+06F, 3.65174e+06F,
- 3.42891e+06F, 3.21968e+06F, 3.02321e+06F, 2.83873e+06F,
- 2.66551e+06F, 2.50286e+06F, 2.35014e+06F, 2.20673e+06F,
- 2.07208e+06F, 1.94564e+06F, 1.82692e+06F, 1.71544e+06F,
- 1.61076e+06F, 1.51247e+06F, 1.42018e+06F, 1.33352e+06F,
- 1.25215e+06F, 1.17574e+06F, 1.10400e+06F, 1.03663e+06F,
- 973377.F, 913981.F, 858210.F, 805842.F,
- 756669.F, 710497.F, 667142.F, 626433.F,
- 588208.F, 552316.F, 518613.F, 486967.F,
- 457252.F, 429351.F, 403152.F, 378551.F,
- 355452.F, 333762.F, 313396.F, 294273.F,
- 276316.F, 259455.F, 243623.F, 228757.F,
- 214798.F, 201691.F, 189384.F, 177828.F,
- 166977.F, 156788.F, 147221.F, 138237.F,
- 129802.F, 121881.F, 114444.F, 107461.F,
- 100903.F, 94746.3F, 88964.9F, 83536.2F,
- 78438.8F, 73652.5F, 69158.2F, 64938.1F,
- 60975.6F, 57254.9F, 53761.2F, 50480.6F,
- 47400.3F, 44507.9F, 41792.0F, 39241.9F,
- 36847.3F, 34598.9F, 32487.7F, 30505.3F,
- 28643.8F, 26896.0F, 25254.8F, 23713.7F,
- 22266.7F, 20908.0F, 19632.2F, 18434.2F,
- 17309.4F, 16253.1F, 15261.4F, 14330.1F,
- 13455.7F, 12634.6F, 11863.7F, 11139.7F,
- 10460.0F, 9821.72F, 9222.39F, 8659.64F,
- 8131.23F, 7635.06F, 7169.17F, 6731.70F,
- 6320.93F, 5935.23F, 5573.06F, 5232.99F,
- 4913.67F, 4613.84F, 4332.30F, 4067.94F,
- 3819.72F, 3586.64F, 3367.78F, 3162.28F,
- 2969.31F, 2788.13F, 2617.99F, 2458.24F,
- 2308.24F, 2167.39F, 2035.14F, 1910.95F,
- 1794.35F, 1684.85F, 1582.04F, 1485.51F,
- 1394.86F, 1309.75F, 1229.83F, 1154.78F,
- 1084.32F, 1018.15F, 956.024F, 897.687F,
- 842.910F, 791.475F, 743.179F, 697.830F,
- 655.249F, 615.265F, 577.722F, 542.469F,
- 509.367F, 478.286F, 449.101F, 421.696F,
- 395.964F, 371.803F, 349.115F, 327.812F,
- 307.809F, 289.026F, 271.390F, 254.830F,
- 239.280F, 224.679F, 210.969F, 198.096F,
- 186.008F, 174.658F, 164.000F, 153.993F,
- 144.596F, 135.773F, 127.488F, 119.708F,
- 112.404F, 105.545F, 99.1046F, 93.0572F,
- 87.3788F, 82.0469F, 77.0404F, 72.3394F,
- 67.9252F, 63.7804F, 59.8885F, 56.2341F,
- 52.8027F, 49.5807F, 46.5553F, 43.7144F,
- 41.0470F, 38.5423F, 36.1904F, 33.9821F,
- 31.9085F, 29.9614F, 28.1332F, 26.4165F,
- 24.8045F, 23.2910F, 21.8697F, 20.5352F,
- 19.2822F, 18.1056F, 17.0008F, 15.9634F,
- 14.9893F, 14.0746F, 13.2158F, 12.4094F,
- 11.6522F, 10.9411F, 10.2735F, 9.64662F,
- 9.05798F, 8.50526F, 7.98626F, 7.49894F,
- 7.04135F, 6.61169F, 6.20824F, 5.82941F,
- 5.47370F, 5.13970F, 4.82607F, 4.53158F,
- 4.25507F, 3.99542F, 3.75162F, 3.52269F,
- 3.30774F, 3.10590F, 2.91638F, 2.73842F,
- 2.57132F, 2.41442F, 2.26709F, 2.12875F,
- 1.99885F, 1.87688F, 1.76236F, 1.65482F,
- 1.55384F, 1.45902F, 1.36999F, 1.28640F,
- 1.20790F, 1.13419F, 1.06499F, 1.F
- };
-
- void _vp_remove_floor(vorbis_look_psy *p,
- float *mdct,
- int *codedflr,
- float *residue,
- int sliding_lowpass){
-
- int i,n=p->n;
-
- if(sliding_lowpass>n)sliding_lowpass=n;
-
- for(i=0;i<sliding_lowpass;i++){
- residue[i]=
- mdct[i]*FLOOR1_fromdB_INV_LOOKUP[codedflr[i]];
- }
-
- for(;i<n;i++)
- residue[i]=0.;
- }
-
- void _vp_noisemask(vorbis_look_psy *p,
- float *logmdct,
- float *logmask){
-
- int i,n=p->n;
- float *work=(float*) alloca(n*sizeof(*work));
-
- bark_noise_hybridmp(n,p->bark,logmdct,logmask,
- 140.,-1);
-
- for(i=0;i<n;i++)work[i]=logmdct[i]-logmask[i];
-
- bark_noise_hybridmp(n,p->bark,work,logmask,0.,
- p->vi->noisewindowfixed);
-
- for(i=0;i<n;i++)work[i]=logmdct[i]-work[i];
-
- #if 0
- {
- static int seq=0;
-
- float work2[n];
- for(i=0;i<n;i++){
- work2[i]=logmask[i]+work[i];
- }
-
- if(seq&1)
- _analysis_output("median2R",seq/2,work,n,1,0,0);
- else
- _analysis_output("median2L",seq/2,work,n,1,0,0);
-
- if(seq&1)
- _analysis_output("envelope2R",seq/2,work2,n,1,0,0);
- else
- _analysis_output("envelope2L",seq/2,work2,n,1,0,0);
- seq++;
- }
- #endif
-
- for(i=0;i<n;i++){
- int dB=logmask[i]+.5;
- if(dB>=NOISE_COMPAND_LEVELS)dB=NOISE_COMPAND_LEVELS-1;
- if(dB<0)dB=0;
- logmask[i]= work[i]+p->vi->noisecompand[dB];
- }
-
- }
-
- void _vp_tonemask(vorbis_look_psy *p,
- float *logfft,
- float *logmask,
- float global_specmax,
- float local_specmax){
-
- int i,n=p->n;
-
- float *seed=(float*) alloca(sizeof(*seed)*p->total_octave_lines);
- float att=local_specmax+p->vi->ath_adjatt;
- for(i=0;i<p->total_octave_lines;i++)seed[i]=NEGINF;
-
- /* set the ATH (floating below localmax, not global max by a
- specified att) */
- if(att<p->vi->ath_maxatt)att=p->vi->ath_maxatt;
-
- for(i=0;i<n;i++)
- logmask[i]=p->ath[i]+att;
-
- /* tone masking */
- seed_loop(p,(const float ***)p->tonecurves,logfft,logmask,seed,global_specmax);
- max_seeds(p,seed,logmask);
-
- }
-
- void _vp_offset_and_mix(vorbis_look_psy *p,
- float *noise,
- float *tone,
- int offset_select,
- float *logmask,
- float *mdct,
- float *logmdct){
- int i,n=p->n;
- float de, coeffi, cx;/* AoTuV */
- float toneatt=p->vi->tone_masteratt[offset_select];
-
- cx = p->m_val;
-
- for(i=0;i<n;i++){
- float val= noise[i]+p->noiseoffset[offset_select][i];
- if(val>p->vi->noisemaxsupp)val=p->vi->noisemaxsupp;
- logmask[i]=max(val,tone[i]+toneatt);
-
- /* AoTuV */
- /** @ M1 **
- The following codes improve a noise problem.
- A fundamental idea uses the value of masking and carries out
- the relative compensation of the MDCT.
- However, this code is not perfect and all noise problems cannot be solved.
- by Aoyumi @ 2004/04/18
- */
-
- if(offset_select == 1) {
- coeffi = -17.2; /* coeffi is a -17.2dB threshold */
- val = val - logmdct[i]; /* val == mdct line value relative to floor in dB */
-
- if(val > coeffi){
- /* mdct value is > -17.2 dB below floor */
-
- de = 1.0-((val-coeffi)*0.005*cx);
- /* pro-rated attenuation:
- -0.00 dB boost if mdct value is -17.2dB (relative to floor)
- -0.77 dB boost if mdct value is 0dB (relative to floor)
- -1.64 dB boost if mdct value is +17.2dB (relative to floor)
- etc... */
-
- if(de < 0) de = 0.0001;
- }else
- /* mdct value is <= -17.2 dB below floor */
-
- de = 1.0-((val-coeffi)*0.0003*cx);
- /* pro-rated attenuation:
- +0.00 dB atten if mdct value is -17.2dB (relative to floor)
- +0.45 dB atten if mdct value is -34.4dB (relative to floor)
- etc... */
-
- mdct[i] *= de;
-
- }
- }
- }
-
- float _vp_ampmax_decay(float amp,vorbis_dsp_state *vd){
- vorbis_info *vi=vd->vi;
- codec_setup_info *ci=(codec_setup_info*)vi->codec_setup;
- vorbis_info_psy_global *gi=&ci->psy_g_param;
-
- int n=ci->blocksizes[vd->W]/2;
- float secs=(float)n/vi->rate;
-
- amp+=secs*gi->ampmax_att_per_sec;
- if(amp<-9999)amp=-9999;
- return(amp);
- }
-
- static void couple_lossless(float A, float B,
- float *qA, float *qB){
- int test1=fabs(*qA)>fabs(*qB);
- test1-= fabs(*qA)<fabs(*qB);
-
- if(!test1)test1=((fabs(A)>fabs(B))<<1)-1;
- if(test1==1){
- *qB=(*qA>0.f?*qA-*qB:*qB-*qA);
- }else{
- float temp=*qB;
- *qB=(*qB>0.f?*qA-*qB:*qB-*qA);
- *qA=temp;
- }
-
- if(*qB>fabs(*qA)*1.9999f){
- *qB= -fabs(*qA)*2.f;
- *qA= -*qA;
- }
- }
-
- static float hypot_lookup[32]={
- -0.009935, -0.011245, -0.012726, -0.014397,
- -0.016282, -0.018407, -0.020800, -0.023494,
- -0.026522, -0.029923, -0.033737, -0.038010,
- -0.042787, -0.048121, -0.054064, -0.060671,
- -0.068000, -0.076109, -0.085054, -0.094892,
- -0.105675, -0.117451, -0.130260, -0.144134,
- -0.159093, -0.175146, -0.192286, -0.210490,
- -0.229718, -0.249913, -0.271001, -0.292893};
-
- static void precomputed_couple_point(float premag,
- int floorA,int floorB,
- float *mag, float *ang){
-
- int test=(floorA>floorB)-1;
- int offset=31-abs(floorA-floorB);
- float floormag=hypot_lookup[((offset<0)-1)&offset]+1.f;
-
- floormag*=FLOOR1_fromdB_INV_LOOKUP[(floorB&test)|(floorA&(~test))];
-
- *mag=premag*floormag;
- *ang=0.f;
- }
-
- /* just like below, this is currently set up to only do
- single-step-depth coupling. Otherwise, we'd have to do more
- copying (which will be inevitable later) */
-
- /* doing the real circular magnitude calculation is audibly superior
- to (A+B)/sqrt(2) */
- static float dipole_hypot(float a, float b){
- if(a>0.){
- if(b>0.)return sqrt(a*a+b*b);
- if(a>-b)return sqrt(a*a-b*b);
- return -sqrt(b*b-a*a);
- }
- if(b<0.)return -sqrt(a*a+b*b);
- if(-a>b)return -sqrt(a*a-b*b);
- return sqrt(b*b-a*a);
- }
- static float round_hypot(float a, float b){
- if(a>0.){
- if(b>0.)return sqrt(a*a+b*b);
- if(a>-b)return sqrt(a*a+b*b);
- return -sqrt(b*b+a*a);
- }
- if(b<0.)return -sqrt(a*a+b*b);
- if(-a>b)return -sqrt(a*a+b*b);
- return sqrt(b*b+a*a);
- }
-
- /* revert to round hypot for now */
- float **_vp_quantize_couple_memo(vorbis_block *vb,
- vorbis_info_psy_global *g,
- vorbis_look_psy *p,
- vorbis_info_mapping0 *vi,
- float **mdct){
-
- int i,j,n=p->n;
- float **ret=(float**) _vorbis_block_alloc(vb,vi->coupling_steps*sizeof(*ret));
- int limit=g->coupling_pointlimit[p->vi->blockflag][PACKETBLOBS/2];
-
- for(i=0;i<vi->coupling_steps;i++){
- float *mdctM=mdct[vi->coupling_mag[i]];
- float *mdctA=mdct[vi->coupling_ang[i]];
- ret[i]=(float*) _vorbis_block_alloc(vb,n*sizeof(**ret));
- for(j=0;j<limit;j++)
- ret[i][j]=dipole_hypot(mdctM[j],mdctA[j]);
- for(;j<n;j++)
- ret[i][j]=round_hypot(mdctM[j],mdctA[j]);
- }
-
- return(ret);
- }
-
- /* this is for per-channel noise normalization */
- static int apsort(const void *a, const void *b){
- float f1=fabs(**(float**)a);
- float f2=fabs(**(float**)b);
- return (f1<f2)-(f1>f2);
- }
-
- int **_vp_quantize_couple_sort(vorbis_block *vb,
- vorbis_look_psy *p,
- vorbis_info_mapping0 *vi,
- float **mags){
-
- if(p->vi->normal_point_p){
- int i,j,k,n=p->n;
- int **ret=(int**) _vorbis_block_alloc(vb,vi->coupling_steps*sizeof(*ret));
- int partition=p->vi->normal_partition;
- float **work=(float**) alloca(sizeof(*work)*partition);
-
- for(i=0;i<vi->coupling_steps;i++){
- ret[i]=(int*) _vorbis_block_alloc(vb,n*sizeof(**ret));
-
- for(j=0;j<n;j+=partition){
- for(k=0;k<partition;k++)work[k]=mags[i]+k+j;
- qsort(work,partition,sizeof(*work),apsort);
- for(k=0;k<partition;k++)ret[i][k+j]=work[k]-mags[i];
- }
- }
- return(ret);
- }
- return(NULL);
- }
-
- void _vp_noise_normalize_sort(vorbis_look_psy *p,
- float *magnitudes,int *sortedindex){
- int i,j,n=p->n;
- vorbis_info_psy *vi=p->vi;
- int partition=vi->normal_partition;
- float **work=(float**) alloca(sizeof(*work)*partition);
- int start=vi->normal_start;
-
- for(j=start;j<n;j+=partition){
- if(j+partition>n)partition=n-j;
- for(i=0;i<partition;i++)work[i]=magnitudes+i+j;
- qsort(work,partition,sizeof(*work),apsort);
- for(i=0;i<partition;i++){
- sortedindex[i+j-start]=work[i]-magnitudes;
- }
- }
- }
-
- void _vp_noise_normalize(vorbis_look_psy *p,
- float *in,float *out,int *sortedindex){
- int flag=0,i,j=0,n=p->n;
- vorbis_info_psy *vi=p->vi;
- int partition=vi->normal_partition;
- int start=vi->normal_start;
-
- if(start>n)start=n;
-
- if(vi->normal_channel_p){
- for(;j<start;j++)
- out[j]=rint(in[j]);
-
- for(;j+partition<=n;j+=partition){
- float acc=0.;
- int k;
-
- for(i=j;i<j+partition;i++)
- acc+=in[i]*in[i];
-
- for(i=0;i<partition;i++){
- k=sortedindex[i+j-start];
-
- if(in[k]*in[k]>=.25f){
- out[k]=rint(in[k]);
- acc-=in[k]*in[k];
- flag=1;
- }else{
- if(acc<vi->normal_thresh)break;
- out[k]=unitnorm(in[k]);
- acc-=1.;
- }
- }
-
- for(;i<partition;i++){
- k=sortedindex[i+j-start];
- out[k]=0.;
- }
- }
- }
-
- for(;j<n;j++)
- out[j]=rint(in[j]);
-
- }
-
- void _vp_couple(int blobno,
- vorbis_info_psy_global *g,
- vorbis_look_psy *p,
- vorbis_info_mapping0 *vi,
- float **res,
- float **mag_memo,
- int **mag_sort,
- int **ifloor,
- int *nonzero,
- int sliding_lowpass){
-
- int i,j,k,n=p->n;
-
- /* perform any requested channel coupling */
- /* point stereo can only be used in a first stage (in this encoder)
- because of the dependency on floor lookups */
- for(i=0;i<vi->coupling_steps;i++){
-
- /* once we're doing multistage coupling in which a channel goes
- through more than one coupling step, the floor vector
- magnitudes will also have to be recalculated an propogated
- along with PCM. Right now, we're not (that will wait until 5.1
- most likely), so the code isn't here yet. The memory management
- here is all assuming single depth couplings anyway. */
-
- /* make sure coupling a zero and a nonzero channel results in two
- nonzero channels. */
- if(nonzero[vi->coupling_mag[i]] ||
- nonzero[vi->coupling_ang[i]]){
-
- float *rM=res[vi->coupling_mag[i]];
- float *rA=res[vi->coupling_ang[i]];
- float *qM=rM+n;
- float *qA=rA+n;
- int *floorM=ifloor[vi->coupling_mag[i]];
- int *floorA=ifloor[vi->coupling_ang[i]];
- float prepoint=stereo_threshholds[g->coupling_prepointamp[blobno]];
- float postpoint=stereo_threshholds[g->coupling_postpointamp[blobno]];
- int partition=(p->vi->normal_point_p?p->vi->normal_partition:p->n);
- int limit=g->coupling_pointlimit[p->vi->blockflag][blobno];
- int pointlimit=limit;
-
- nonzero[vi->coupling_mag[i]]=1;
- nonzero[vi->coupling_ang[i]]=1;
-
- /* The threshold of a stereo is changed with the size of n */
- if(n > 1000)
- postpoint=stereo_threshholds_limited[g->coupling_postpointamp[blobno]];
-
- for(j=0;j<p->n;j+=partition){
- float acc=0.f;
-
- for(k=0;k<partition;k++){
- int l=k+j;
-
- if(l<sliding_lowpass){
- if((l>=limit && fabs(rM[l])<postpoint && fabs(rA[l])<postpoint) ||
- (fabs(rM[l])<prepoint && fabs(rA[l])<prepoint)){
-
- precomputed_couple_point(mag_memo[i][l],
- floorM[l],floorA[l],
- qM+l,qA+l);
-
- if(rint(qM[l])==0.f)acc+=qM[l]*qM[l];
- }else{
- couple_lossless(rM[l],rA[l],qM+l,qA+l);
- }
- }else{
- qM[l]=0.;
- qA[l]=0.;
- }
- }
-
- if(p->vi->normal_point_p){
- for(k=0;k<partition && acc>=p->vi->normal_thresh;k++){
- int l=mag_sort[i][j+k];
- if(l<sliding_lowpass && l>=pointlimit && rint(qM[l])==0.f){
- qM[l]=unitnorm(qM[l]);
- acc-=1.f;
- }
- }
- }
- }
- }
- }
- }
-
- /* AoTuV */
- /** @ M2 **
- The boost problem by the combination of noise normalization and point stereo is eased.
- However, this is a temporary patch.
- by Aoyumi @ 2004/04/18
- */
-
- void hf_reduction(vorbis_info_psy_global *g,
- vorbis_look_psy *p,
- vorbis_info_mapping0 *vi,
- float **mdct){
-
- int i,j,n=p->n, de=0.3*p->m_val;
- int limit=g->coupling_pointlimit[p->vi->blockflag][PACKETBLOBS/2];
-
- for(i=0; i<vi->coupling_steps; i++){
- /* for(j=start; j<limit; j++){} // ???*/
- for(j=limit; j<n; j++)
- mdct[i][j] *= (1.0 - de*((float)(j-limit) / (float)(n-limit)));
- }
- }
-
- #endif
- /********* End of inlined file: psy.c *********/
-
- /********* Start of inlined file: registry.c *********/
-
- /********* Start of inlined file: juce_OggVorbisHeader.h *********/
- // This file is included at the start of each Ogg-Vorbis .c file, just to do a few housekeeping
- // tasks..
-
- #ifdef _MSC_VER
- #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4305 4189 4706)
- #endif
- /********* End of inlined file: juce_OggVorbisHeader.h *********/
-
- #if JUCE_USE_OGGVORBIS
-
- /* seems like major overkill now; the backend numbers will grow into
- the infrastructure soon enough */
-
- extern vorbis_func_floor floor0_exportbundle;
- extern vorbis_func_floor floor1_exportbundle;
- extern vorbis_func_residue residue0_exportbundle;
- extern vorbis_func_residue residue1_exportbundle;
- extern vorbis_func_residue residue2_exportbundle;
- extern vorbis_func_mapping mapping0_exportbundle;
-
- vorbis_func_floor *_floor_P[]={
- &floor0_exportbundle,
- &floor1_exportbundle,
- };
-
- vorbis_func_residue *_residue_P[]={
- &residue0_exportbundle,
- &residue1_exportbundle,
- &residue2_exportbundle,
- };
-
- vorbis_func_mapping *_mapping_P[]={
- &mapping0_exportbundle,
- };
-
- #endif
- /********* End of inlined file: registry.c *********/
-
- /********* Start of inlined file: res0.c *********/
- /* Slow, slow, slow, simpleminded and did I mention it was slow? The
- encode/decode loops are coded for clarity and performance is not
- yet even a nagging little idea lurking in the shadows. Oh and BTW,
- it's slow. */
-
- /********* Start of inlined file: juce_OggVorbisHeader.h *********/
- // This file is included at the start of each Ogg-Vorbis .c file, just to do a few housekeeping
- // tasks..
-
- #ifdef _MSC_VER
- #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4305 4189 4706)
- #endif
- /********* End of inlined file: juce_OggVorbisHeader.h *********/
-
- #if JUCE_USE_OGGVORBIS
-
- #include <stdlib.h>
- #include <string.h>
- #include <math.h>
-
- #if defined(TRAIN_RES) || defined (TRAIN_RESAUX)
- #include <stdio.h>
- #endif
-
- typedef struct {
- vorbis_info_residue0 *info;
-
- int parts;
- int stages;
- codebook *fullbooks;
- codebook *phrasebook;
- codebook ***partbooks;
-
- int partvals;
- int **decodemap;
-
- long postbits;
- long phrasebits;
- long frames;
-
- #if defined(TRAIN_RES) || defined(TRAIN_RESAUX)
- int train_seq;
- long *training_data[8][64];
- float training_max[8][64];
- float training_min[8][64];
- float tmin;
- float tmax;
- #endif
-
- } vorbis_look_residue0;
-
- void res0_free_info(vorbis_info_residue *i){
- vorbis_info_residue0 *info=(vorbis_info_residue0 *)i;
- if(info){
- memset(info,0,sizeof(*info));
- _ogg_free(info);
- }
- }
-
- void res0_free_look(vorbis_look_residue *i){
- int j;
- if(i){
-
- vorbis_look_residue0 *look=(vorbis_look_residue0 *)i;
-
- #ifdef TRAIN_RES
- {
- int j,k,l;
- for(j=0;j<look->parts;j++){
- /*fprintf(stderr,"partition %d: ",j);*/
- for(k=0;k<8;k++)
- if(look->training_data[k][j]){
- char buffer[80];
- FILE *of;
- codebook *statebook=look->partbooks[j][k];
-
- /* long and short into the same bucket by current convention */
- sprintf(buffer,"res_part%d_pass%d.vqd",j,k);
- of=fopen(buffer,"a");
-
- for(l=0;l<statebook->entries;l++)
- fprintf(of,"%d:%ld\n",l,look->training_data[k][j][l]);
-
- fclose(of);
-
- /*fprintf(stderr,"%d(%.2f|%.2f) ",k,
- look->training_min[k][j],look->training_max[k][j]);*/
-
- _ogg_free(look->training_data[k][j]);
- look->training_data[k][j]=NULL;
- }
- /*fprintf(stderr,"\n");*/
- }
- }
- fprintf(stderr,"min/max residue: %g::%g\n",look->tmin,look->tmax);
-
- /*fprintf(stderr,"residue bit usage %f:%f (%f total)\n",
- (float)look->phrasebits/look->frames,
- (float)look->postbits/look->frames,
- (float)(look->postbits+look->phrasebits)/look->frames);*/
- #endif
-
- /*vorbis_info_residue0 *info=look->info;
-
- fprintf(stderr,
- "%ld frames encoded in %ld phrasebits and %ld residue bits "
- "(%g/frame) \n",look->frames,look->phrasebits,
- look->resbitsflat,
- (look->phrasebits+look->resbitsflat)/(float)look->frames);
-
- for(j=0;j<look->parts;j++){
- long acc=0;
- fprintf(stderr,"\t[%d] == ",j);
- for(k=0;k<look->stages;k++)
- if((info->secondstages[j]>>k)&1){
- fprintf(stderr,"%ld,",look->resbits[j][k]);
- acc+=look->resbits[j][k];
- }
-
- fprintf(stderr,":: (%ld vals) %1.2fbits/sample\n",look->resvals[j],
- acc?(float)acc/(look->resvals[j]*info->grouping):0);
- }
- fprintf(stderr,"\n");*/
-
- for(j=0;j<look->parts;j++)
- if(look->partbooks[j])_ogg_free(look->partbooks[j]);
- _ogg_free(look->partbooks);
- for(j=0;j<look->partvals;j++)
- _ogg_free(look->decodemap[j]);
- _ogg_free(look->decodemap);
-
- memset(look,0,sizeof(*look));
- _ogg_free(look);
- }
- }
-
- static int icount(unsigned int v){
- int ret=0;
- while(v){
- ret+=v&1;
- v>>=1;
- }
- return(ret);
- }
-
- void res0_pack(vorbis_info_residue *vr,oggpack_buffer *opb){
- vorbis_info_residue0 *info=(vorbis_info_residue0 *)vr;
- int j,acc=0;
- oggpack_write(opb,info->begin,24);
- oggpack_write(opb,info->end,24);
-
- oggpack_write(opb,info->grouping-1,24); /* residue vectors to group and
- code with a partitioned book */
- oggpack_write(opb,info->partitions-1,6); /* possible partition choices */
- oggpack_write(opb,info->groupbook,8); /* group huffman book */
-
- /* secondstages is a bitmask; as encoding progresses pass by pass, a
- bitmask of one indicates this partition class has bits to write
- this pass */
- for(j=0;j<info->partitions;j++){
- if(ilog(info->secondstages[j])>3){
- /* yes, this is a minor hack due to not thinking ahead */
- oggpack_write(opb,info->secondstages[j],3);
- oggpack_write(opb,1,1);
- oggpack_write(opb,info->secondstages[j]>>3,5);
- }else
- oggpack_write(opb,info->secondstages[j],4); /* trailing zero */
- acc+=icount(info->secondstages[j]);
- }
- for(j=0;j<acc;j++)
- oggpack_write(opb,info->booklist[j],8);
-
- }
-
- /* vorbis_info is for range checking */
- vorbis_info_residue *res0_unpack(vorbis_info *vi,oggpack_buffer *opb){
- int j,acc=0;
- vorbis_info_residue0 *info=(vorbis_info_residue0*) _ogg_calloc(1,sizeof(*info));
- codec_setup_info *ci=(codec_setup_info*) vi->codec_setup;
-
- info->begin=oggpack_read(opb,24);
- info->end=oggpack_read(opb,24);
- info->grouping=oggpack_read(opb,24)+1;
- info->partitions=oggpack_read(opb,6)+1;
- info->groupbook=oggpack_read(opb,8);
-
- for(j=0;j<info->partitions;j++){
- int cascade=oggpack_read(opb,3);
- if(oggpack_read(opb,1))
- cascade|=(oggpack_read(opb,5)<<3);
- info->secondstages[j]=cascade;
-
- acc+=icount(cascade);
- }
- for(j=0;j<acc;j++)
- info->booklist[j]=oggpack_read(opb,8);
-
- if(info->groupbook>=ci->books)goto errout;
- for(j=0;j<acc;j++)
- if(info->booklist[j]>=ci->books)goto errout;
-
- return(info);
- errout:
- res0_free_info(info);
- return(NULL);
- }
-
- vorbis_look_residue *res0_look(vorbis_dsp_state *vd,
- vorbis_info_residue *vr){
- vorbis_info_residue0 *info=(vorbis_info_residue0 *)vr;
- vorbis_look_residue0 *look=(vorbis_look_residue0 *)_ogg_calloc(1,sizeof(*look));
- codec_setup_info *ci=(codec_setup_info*)vd->vi->codec_setup;
-
- int j,k,acc=0;
- int dim;
- int maxstage=0;
- look->info=info;
-
- look->parts=info->partitions;
- look->fullbooks=ci->fullbooks;
- look->phrasebook=ci->fullbooks+info->groupbook;
- dim=look->phrasebook->dim;
-
- look->partbooks=(codebook***)_ogg_calloc(look->parts,sizeof(*look->partbooks));
-
- for(j=0;j<look->parts;j++){
- int stages=ilog(info->secondstages[j]);
- if(stages){
- if(stages>maxstage)maxstage=stages;
- look->partbooks[j]=(codebook**) _ogg_calloc(stages,sizeof(*look->partbooks[j]));
- for(k=0;k<stages;k++)
- if(info->secondstages[j]&(1<<k)){
- look->partbooks[j][k]=ci->fullbooks+info->booklist[acc++];
- #ifdef TRAIN_RES
- look->training_data[k][j]=_ogg_calloc(look->partbooks[j][k]->entries,
- sizeof(***look->training_data));
- #endif
- }
- }
- }
-
- look->partvals=rint(pow((float)look->parts,(float)dim));
- look->stages=maxstage;
- look->decodemap=(int**)_ogg_malloc(look->partvals*sizeof(*look->decodemap));
- for(j=0;j<look->partvals;j++){
- long val=j;
- long mult=look->partvals/look->parts;
- look->decodemap[j]=(int*)_ogg_malloc(dim*sizeof(*look->decodemap[j]));
- for(k=0;k<dim;k++){
- long deco=val/mult;
- val-=deco*mult;
- mult/=look->parts;
- look->decodemap[j][k]=deco;
- }
- }
- #if defined(TRAIN_RES) || defined (TRAIN_RESAUX)
- {
- static int train_seq=0;
- look->train_seq=train_seq++;
- }
- #endif
- return(look);
- }
-
- /* break an abstraction and copy some code for performance purposes */
- static int local_book_besterror(codebook *book,float *a){
- int dim=book->dim,i,k,o;
- int best=0;
- encode_aux_threshmatch *tt=book->c->thresh_tree;
-
- /* find the quant val of each scalar */
- for(k=0,o=dim;k<dim;++k){
- float val=a[--o];
- i=tt->threshvals>>1;
-
- if(val<tt->quantthresh[i]){
- if(val<tt->quantthresh[i-1]){
- for(--i;i>0;--i)
- if(val>=tt->quantthresh[i-1])
- break;
- }
- }else{
-
- for(++i;i<tt->threshvals-1;++i)
- if(val<tt->quantthresh[i])break;
-
- }
-
- best=(best*tt->quantvals)+tt->quantmap[i];
- }
- /* regular lattices are easy :-) */
-
- if(book->c->lengthlist[best]<=0){
- const static_codebook *c=book->c;
- int i,j;
- float bestf=0.f;
- float *e=book->valuelist;
- best=-1;
- for(i=0;i<book->entries;i++){
- if(c->lengthlist[i]>0){
- float thisx=0.f;
- for(j=0;j<dim;j++){
- float val=(e[j]-a[j]);
- thisx+=val*val;
- }
- if(best==-1 || thisx<bestf){
- bestf=thisx;
- best=i;
- }
- }
- e+=dim;
- }
- }
-
- {
- float *ptr=book->valuelist+best*dim;
- for(i=0;i<dim;i++)
- *a++ -= *ptr++;
- }
-
- return(best);
- }
-
- static int _encodepart(oggpack_buffer *opb,float *vec, int n,
- codebook *book,long *acc){
- int i,bits=0;
- int dim=book->dim;
- int step=n/dim;
-
- for(i=0;i<step;i++){
- int entry=local_book_besterror(book,vec+i*dim);
-
- #ifdef TRAIN_RES
- acc[entry]++;
- #endif
-
- bits+=vorbis_book_encode(book,entry,opb);
- }
-
- return(bits);
- }
-
- static long **_01class(vorbis_block *vb,vorbis_look_residue *vl,
- float **in,int ch){
- long i,j,k;
- vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl;
- vorbis_info_residue0 *info=look->info;
-
- /* move all this setup out later */
- int samples_per_partition=info->grouping;
- int possible_partitions=info->partitions;
- int n=info->end-info->begin;
-
- int partvals=n/samples_per_partition;
- long **partword=(long**)_vorbis_block_alloc(vb,ch*sizeof(*partword));
- float scale=100./samples_per_partition;
-
- /* we find the partition type for each partition of each
- channel. We'll go back and do the interleaved encoding in a
- bit. For now, clarity */
-
- for(i=0;i<ch;i++){
- partword[i]=(long*)_vorbis_block_alloc(vb,n/samples_per_partition*sizeof(*partword[i]));
- memset(partword[i],0,n/samples_per_partition*sizeof(*partword[i]));
- }
-
- for(i=0;i<partvals;i++){
- int offset=i*samples_per_partition+info->begin;
- for(j=0;j<ch;j++){
- float max=0.;
- float ent=0.;
- for(k=0;k<samples_per_partition;k++){
- if(fabs(in[j][offset+k])>max)max=fabs(in[j][offset+k]);
- ent+=fabs(rint(in[j][offset+k]));
- }
- ent*=scale;
-
- for(k=0;k<possible_partitions-1;k++)
- if(max<=info->classmetric1[k] &&
- (info->classmetric2[k]<0 || (int)ent<info->classmetric2[k]))
- break;
-
- partword[j][i]=k;
- }
- }
-
- #ifdef TRAIN_RESAUX
- {
- FILE *of;
- char buffer[80];
-
- for(i=0;i<ch;i++){
- sprintf(buffer,"resaux_%d.vqd",look->train_seq);
- of=fopen(buffer,"a");
- for(j=0;j<partvals;j++)
- fprintf(of,"%ld, ",partword[i][j]);
- fprintf(of,"\n");
- fclose(of);
- }
- }
- #endif
- look->frames++;
-
- return(partword);
- }
-
- /* designed for stereo or other modes where the partition size is an
- integer multiple of the number of channels encoded in the current
- submap */
- static long **_2class(vorbis_block *vb,vorbis_look_residue *vl,float **in,
- int ch){
- long i,j,k,l;
- vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl;
- vorbis_info_residue0 *info=look->info;
-
- /* move all this setup out later */
- int samples_per_partition=info->grouping;
- int possible_partitions=info->partitions;
- int n=info->end-info->begin;
-
- int partvals=n/samples_per_partition;
- long **partword=(long**)_vorbis_block_alloc(vb,sizeof(*partword));
-
- #if defined(TRAIN_RES) || defined (TRAIN_RESAUX)
- FILE *of;
- char buffer[80];
- #endif
-
- partword[0]=(long*)_vorbis_block_alloc(vb,n*ch/samples_per_partition*sizeof(*partword[0]));
- memset(partword[0],0,n*ch/samples_per_partition*sizeof(*partword[0]));
-
- for(i=0,l=info->begin/ch;i<partvals;i++){
- float magmax=0.f;
- float angmax=0.f;
- for(j=0;j<samples_per_partition;j+=ch){
- if(fabs(in[0][l])>magmax)magmax=fabs(in[0][l]);
- for(k=1;k<ch;k++)
- if(fabs(in[k][l])>angmax)angmax=fabs(in[k][l]);
- l++;
- }
-
- for(j=0;j<possible_partitions-1;j++)
- if(magmax<=info->classmetric1[j] &&
- angmax<=info->classmetric2[j])
- break;
-
- partword[0][i]=j;
-
- }
-
- #ifdef TRAIN_RESAUX
- sprintf(buffer,"resaux_%d.vqd",look->train_seq);
- of=fopen(buffer,"a");
- for(i=0;i<partvals;i++)
- fprintf(of,"%ld, ",partword[0][i]);
- fprintf(of,"\n");
- fclose(of);
- #endif
-
- look->frames++;
-
- return(partword);
- }
-
- static int _01forward(oggpack_buffer *opb,
- vorbis_block *vb,vorbis_look_residue *vl,
- float **in,int ch,
- long **partword,
- int (*encode)(oggpack_buffer *,float *,int,
- codebook *,long *)){
- long i,j,k,s;
- vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl;
- vorbis_info_residue0 *info=look->info;
-
- /* move all this setup out later */
- int samples_per_partition=info->grouping;
- int possible_partitions=info->partitions;
- int partitions_per_word=look->phrasebook->dim;
- int n=info->end-info->begin;
-
- int partvals=n/samples_per_partition;
- long resbits[128];
- long resvals[128];
-
- #ifdef TRAIN_RES
- for(i=0;i<ch;i++)
- for(j=info->begin;j<info->end;j++){
- if(in[i][j]>look->tmax)look->tmax=in[i][j];
- if(in[i][j]<look->tmin)look->tmin=in[i][j];
- }
- #endif
-
- memset(resbits,0,sizeof(resbits));
- memset(resvals,0,sizeof(resvals));
-
- /* we code the partition words for each channel, then the residual
- words for a partition per channel until we've written all the
- residual words for that partition word. Then write the next
- partition channel words... */
-
- for(s=0;s<look->stages;s++){
-
- for(i=0;i<partvals;){
-
- /* first we encode a partition codeword for each channel */
- if(s==0){
- for(j=0;j<ch;j++){
- long val=partword[j][i];
- for(k=1;k<partitions_per_word;k++){
- val*=possible_partitions;
- if(i+k<partvals)
- val+=partword[j][i+k];
- }
-
- /* training hack */
- if(val<look->phrasebook->entries)
- look->phrasebits+=vorbis_book_encode(look->phrasebook,val,opb);
- #if 0 /*def TRAIN_RES*/
- else
- fprintf(stderr,"!");
- #endif
-
- }
- }
-
- /* now we encode interleaved residual values for the partitions */
- for(k=0;k<partitions_per_word && i<partvals;k++,i++){
- long offset=i*samples_per_partition+info->begin;
-
- for(j=0;j<ch;j++){
- if(s==0)resvals[partword[j][i]]+=samples_per_partition;
- if(info->secondstages[partword[j][i]]&(1<<s)){
- codebook *statebook=look->partbooks[partword[j][i]][s];
- if(statebook){
- int ret;
- long *accumulator=NULL;
-
- #ifdef TRAIN_RES
- accumulator=look->training_data[s][partword[j][i]];
- {
- int l;
- float *samples=in[j]+offset;
- for(l=0;l<samples_per_partition;l++){
- if(samples[l]<look->training_min[s][partword[j][i]])
- look->training_min[s][partword[j][i]]=samples[l];
- if(samples[l]>look->training_max[s][partword[j][i]])
- look->training_max[s][partword[j][i]]=samples[l];
- }
- }
- #endif
-
- ret=encode(opb,in[j]+offset,samples_per_partition,
- statebook,accumulator);
-
- look->postbits+=ret;
- resbits[partword[j][i]]+=ret;
- }
- }
- }
- }
- }
- }
-
- /*{
- long total=0;
- long totalbits=0;
- fprintf(stderr,"%d :: ",vb->mode);
- for(k=0;k<possible_partitions;k++){
- fprintf(stderr,"%ld/%1.2g, ",resvals[k],(float)resbits[k]/resvals[k]);
- total+=resvals[k];
- totalbits+=resbits[k];
- }
-
- fprintf(stderr,":: %ld:%1.2g\n",total,(double)totalbits/total);
- }*/
- return(0);
- }
-
- /* a truncated packet here just means 'stop working'; it's not an error */
- static int _01inverse(vorbis_block *vb,vorbis_look_residue *vl,
- float **in,int ch,
- long (*decodepart)(codebook *, float *,
- oggpack_buffer *,int)){
-
- long i,j,k,l,s;
- vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl;
- vorbis_info_residue0 *info=look->info;
-
- /* move all this setup out later */
- int samples_per_partition=info->grouping;
- int partitions_per_word=look->phrasebook->dim;
- int n=info->end-info->begin;
-
- int partvals=n/samples_per_partition;
- int partwords=(partvals+partitions_per_word-1)/partitions_per_word;
- int ***partword=(int***)alloca(ch*sizeof(*partword));
-
- for(j=0;j<ch;j++)
- partword[j]=(int**)_vorbis_block_alloc(vb,partwords*sizeof(*partword[j]));
-
- for(s=0;s<look->stages;s++){
-
- /* each loop decodes on partition codeword containing
- partitions_pre_word partitions */
- for(i=0,l=0;i<partvals;l++){
- if(s==0){
- /* fetch the partition word for each channel */
- for(j=0;j<ch;j++){
- int temp=vorbis_book_decode(look->phrasebook,&vb->opb);
- if(temp==-1)goto eopbreak;
- partword[j][l]=look->decodemap[temp];
- if(partword[j][l]==NULL)goto errout;
- }
- }
-
- /* now we decode residual values for the partitions */
- for(k=0;k<partitions_per_word && i<partvals;k++,i++)
- for(j=0;j<ch;j++){
- long offset=info->begin+i*samples_per_partition;
- if(info->secondstages[partword[j][l][k]]&(1<<s)){
- codebook *stagebook=look->partbooks[partword[j][l][k]][s];
- if(stagebook){
- if(decodepart(stagebook,in[j]+offset,&vb->opb,
- samples_per_partition)==-1)goto eopbreak;
- }
- }
- }
- }
- }
-
- errout:
- eopbreak:
- return(0);
- }
-
- #if 0
- /* residue 0 and 1 are just slight variants of one another. 0 is
- interleaved, 1 is not */
- long **res0_class(vorbis_block *vb,vorbis_look_residue *vl,
- float **in,int *nonzero,int ch){
- /* we encode only the nonzero parts of a bundle */
- int i,used=0;
- for(i=0;i<ch;i++)
- if(nonzero[i])
- in[used++]=in[i];
- if(used)
- /*return(_01class(vb,vl,in,used,_interleaved_testhack));*/
- return(_01class(vb,vl,in,used));
- else
- return(0);
- }
-
- int res0_forward(vorbis_block *vb,vorbis_look_residue *vl,
- float **in,float **out,int *nonzero,int ch,
- long **partword){
- /* we encode only the nonzero parts of a bundle */
- int i,j,used=0,n=vb->pcmend/2;
- for(i=0;i<ch;i++)
- if(nonzero[i]){
- if(out)
- for(j=0;j<n;j++)
- out[i][j]+=in[i][j];
- in[used++]=in[i];
- }
- if(used){
- int ret=_01forward(vb,vl,in,used,partword,
- _interleaved_encodepart);
- if(out){
- used=0;
- for(i=0;i<ch;i++)
- if(nonzero[i]){
- for(j=0;j<n;j++)
- out[i][j]-=in[used][j];
- used++;
- }
- }
- return(ret);
- }else{
- return(0);
- }
- }
- #endif
-
- int res0_inverse(vorbis_block *vb,vorbis_look_residue *vl,
- float **in,int *nonzero,int ch){
- int i,used=0;
- for(i=0;i<ch;i++)
- if(nonzero[i])
- in[used++]=in[i];
- if(used)
- return(_01inverse(vb,vl,in,used,vorbis_book_decodevs_add));
- else
- return(0);
- }
-
- int res1_forward(oggpack_buffer *opb,vorbis_block *vb,vorbis_look_residue *vl,
- float **in,float **out,int *nonzero,int ch,
- long **partword){
- int i,j,used=0,n=vb->pcmend/2;
- for(i=0;i<ch;i++)
- if(nonzero[i]){
- if(out)
- for(j=0;j<n;j++)
- out[i][j]+=in[i][j];
- in[used++]=in[i];
- }
-
- if(used){
- int ret=_01forward(opb,vb,vl,in,used,partword,_encodepart);
- if(out){
- used=0;
- for(i=0;i<ch;i++)
- if(nonzero[i]){
- for(j=0;j<n;j++)
- out[i][j]-=in[used][j];
- used++;
- }
- }
- return(ret);
- }else{
- return(0);
- }
- }
-
- long **res1_class(vorbis_block *vb,vorbis_look_residue *vl,
- float **in,int *nonzero,int ch){
- int i,used=0;
- for(i=0;i<ch;i++)
- if(nonzero[i])
- in[used++]=in[i];
- if(used)
- return(_01class(vb,vl,in,used));
- else
- return(0);
- }
-
- int res1_inverse(vorbis_block *vb,vorbis_look_residue *vl,
- float **in,int *nonzero,int ch){
- int i,used=0;
- for(i=0;i<ch;i++)
- if(nonzero[i])
- in[used++]=in[i];
- if(used)
- return(_01inverse(vb,vl,in,used,vorbis_book_decodev_add));
- else
- return(0);
- }
-
- long **res2_class(vorbis_block *vb,vorbis_look_residue *vl,
- float **in,int *nonzero,int ch){
- int i,used=0;
- for(i=0;i<ch;i++)
- if(nonzero[i])used++;
- if(used)
- return(_2class(vb,vl,in,ch));
- else
- return(0);
- }
-
- /* res2 is slightly more different; all the channels are interleaved
- into a single vector and encoded. */
-
- int res2_forward(oggpack_buffer *opb,
- vorbis_block *vb,vorbis_look_residue *vl,
- float **in,float **out,int *nonzero,int ch,
- long **partword){
- long i,j,k,n=vb->pcmend/2,used=0;
-
- /* don't duplicate the code; use a working vector hack for now and
- reshape ourselves into a single channel res1 */
- /* ugly; reallocs for each coupling pass :-( */
- float *work=(float*)_vorbis_block_alloc(vb,ch*n*sizeof(*work));
- for(i=0;i<ch;i++){
- float *pcm=in[i];
- if(nonzero[i])used++;
- for(j=0,k=i;j<n;j++,k+=ch)
- work[k]=pcm[j];
- }
-
- if(used){
- int ret=_01forward(opb,vb,vl,&work,1,partword,_encodepart);
- /* update the sofar vector */
- if(out){
- for(i=0;i<ch;i++){
- float *pcm=in[i];
- float *sofar=out[i];
- for(j=0,k=i;j<n;j++,k+=ch)
- sofar[j]+=pcm[j]-work[k];
-
- }
- }
- return(ret);
- }else{
- return(0);
- }
- }
-
- /* duplicate code here as speed is somewhat more important */
- int res2_inverse(vorbis_block *vb,vorbis_look_residue *vl,
- float **in,int *nonzero,int ch){
- long i,k,l,s;
- vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl;
- vorbis_info_residue0 *info=look->info;
-
- /* move all this setup out later */
- int samples_per_partition=info->grouping;
- int partitions_per_word=look->phrasebook->dim;
- int n=info->end-info->begin;
-
- int partvals=n/samples_per_partition;
- int partwords=(partvals+partitions_per_word-1)/partitions_per_word;
- int **partword=(int**)_vorbis_block_alloc(vb,partwords*sizeof(*partword));
-
- for(i=0;i<ch;i++)if(nonzero[i])break;
- if(i==ch)return(0); /* no nonzero vectors */
-
- for(s=0;s<look->stages;s++){
- for(i=0,l=0;i<partvals;l++){
-
- if(s==0){
- /* fetch the partition word */
- int temp=vorbis_book_decode(look->phrasebook,&vb->opb);
- if(temp==-1)goto eopbreak;
- partword[l]=look->decodemap[temp];
- if(partword[l]==NULL)goto errout;
- }
-
- /* now we decode residual values for the partitions */
- for(k=0;k<partitions_per_word && i<partvals;k++,i++)
- if(info->secondstages[partword[l][k]]&(1<<s)){
- codebook *stagebook=look->partbooks[partword[l][k]][s];
-
- if(stagebook){
- if(vorbis_book_decodevv_add(stagebook,in,
- i*samples_per_partition+info->begin,ch,
- &vb->opb,samples_per_partition)==-1)
- goto eopbreak;
- }
- }
- }
- }
-
- errout:
- eopbreak:
- return(0);
- }
-
- vorbis_func_residue residue0_exportbundle={
- NULL,
- &res0_unpack,
- &res0_look,
- &res0_free_info,
- &res0_free_look,
- NULL,
- NULL,
- &res0_inverse
- };
-
- vorbis_func_residue residue1_exportbundle={
- &res0_pack,
- &res0_unpack,
- &res0_look,
- &res0_free_info,
- &res0_free_look,
- &res1_class,
- &res1_forward,
- &res1_inverse
- };
-
- vorbis_func_residue residue2_exportbundle={
- &res0_pack,
- &res0_unpack,
- &res0_look,
- &res0_free_info,
- &res0_free_look,
- &res2_class,
- &res2_forward,
- &res2_inverse
- };
-
- #endif
- /********* End of inlined file: res0.c *********/
-
- /********* Start of inlined file: sharedbook.c *********/
-
- /********* Start of inlined file: juce_OggVorbisHeader.h *********/
- // This file is included at the start of each Ogg-Vorbis .c file, just to do a few housekeeping
- // tasks..
-
- #ifdef _MSC_VER
- #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4305 4189 4706)
- #endif
- /********* End of inlined file: juce_OggVorbisHeader.h *********/
-
- #if JUCE_USE_OGGVORBIS
-
- #include <stdlib.h>
- #include <math.h>
- #include <string.h>
-
- /**** pack/unpack helpers ******************************************/
- int _ilog(unsigned int v){
- int ret=0;
- while(v){
- ret++;
- v>>=1;
- }
- return(ret);
- }
-
- /* 32 bit float (not IEEE; nonnormalized mantissa +
- biased exponent) : neeeeeee eeemmmmm mmmmmmmm mmmmmmmm
- Why not IEEE? It's just not that important here. */
-
- #define VQ_FEXP 10
- #define VQ_FMAN 21
- #define VQ_FEXP_BIAS 768 /* bias toward values smaller than 1. */
-
- /* doesn't currently guard under/overflow */
- long _float32_pack(float val){
- int sign=0;
- long exp;
- long mant;
- if(val<0){
- sign=0x80000000;
- val= -val;
- }
- exp= floor(log(val)/log(2.f));
- mant=rint(ldexp(val,(VQ_FMAN-1)-exp));
- exp=(exp+VQ_FEXP_BIAS)<<VQ_FMAN;
-
- return(sign|exp|mant);
- }
-
- float _float32_unpack(long val){
- double mant=val&0x1fffff;
- int sign=val&0x80000000;
- long exp =(val&0x7fe00000L)>>VQ_FMAN;
- if(sign)mant= -mant;
- return(ldexp(mant,exp-(VQ_FMAN-1)-VQ_FEXP_BIAS));
- }
-
- /* given a list of word lengths, generate a list of codewords. Works
- for length ordered or unordered, always assigns the lowest valued
- codewords first. Extended to handle unused entries (length 0) */
- ogg_uint32_t *_make_words(long *l,long n,long sparsecount){
- long i,j,count=0;
- ogg_uint32_t marker[33];
- ogg_uint32_t *r=(ogg_uint32_t*)_ogg_malloc((sparsecount?sparsecount:n)*sizeof(*r));
- memset(marker,0,sizeof(marker));
-
- for(i=0;i<n;i++){
- long length=l[i];
- if(length>0){
- ogg_uint32_t entry=marker[length];
-
- /* when we claim a node for an entry, we also claim the nodes
- below it (pruning off the imagined tree that may have dangled
- from it) as well as blocking the use of any nodes directly
- above for leaves */
-
- /* update ourself */
- if(length<32 && (entry>>length)){
- /* error condition; the lengths must specify an overpopulated tree */
- _ogg_free(r);
- return(NULL);
- }
- r[count++]=entry;
-
- /* Look to see if the next shorter marker points to the node
- above. if so, update it and repeat. */
- {
- for(j=length;j>0;j--){
-
- if(marker[j]&1){
- /* have to jump branches */
- if(j==1)
- marker[1]++;
- else
- marker[j]=marker[j-1]<<1;
- break; /* invariant says next upper marker would already
- have been moved if it was on the same path */
- }
- marker[j]++;
- }
- }
-
- /* prune the tree; the implicit invariant says all the longer
- markers were dangling from our just-taken node. Dangle them
- from our *new* node. */
- for(j=length+1;j<33;j++)
- if((marker[j]>>1) == entry){
- entry=marker[j];
- marker[j]=marker[j-1]<<1;
- }else
- break;
- }else
- if(sparsecount==0)count++;
- }
-
- /* bitreverse the words because our bitwise packer/unpacker is LSb
- endian */
- for(i=0,count=0;i<n;i++){
- ogg_uint32_t temp=0;
- for(j=0;j<l[i];j++){
- temp<<=1;
- temp|=(r[count]>>j)&1;
- }
-
- if(sparsecount){
- if(l[i])
- r[count++]=temp;
- }else
- r[count++]=temp;
- }
-
- return(r);
- }
-
- /* there might be a straightforward one-line way to do the below
- that's portable and totally safe against roundoff, but I haven't
- thought of it. Therefore, we opt on the side of caution */
- long _book_maptype1_quantvals(const static_codebook *b){
- long vals=floor(pow((float)b->entries,1.f/b->dim));
-
- /* the above *should* be reliable, but we'll not assume that FP is
- ever reliable when bitstream sync is at stake; verify via integer
- means that vals really is the greatest value of dim for which
- vals^b->bim <= b->entries */
- /* treat the above as an initial guess */
- while(1){
- long acc=1;
- long acc1=1;
- int i;
- for(i=0;i<b->dim;i++){
- acc*=vals;
- acc1*=vals+1;
- }
- if(acc<=b->entries && acc1>b->entries){
- return(vals);
- }else{
- if(acc>b->entries){
- vals--;
- }else{
- vals++;
- }
- }
- }
- }
-
- /* unpack the quantized list of values for encode/decode ***********/
- /* we need to deal with two map types: in map type 1, the values are
- generated algorithmically (each column of the vector counts through
- the values in the quant vector). in map type 2, all the values came
- in in an explicit list. Both value lists must be unpacked */
- float *_book_unquantize(const static_codebook *b,int n,int *sparsemap){
- long j,k,count=0;
- if(b->maptype==1 || b->maptype==2){
- int quantvals;
- float mindel=_float32_unpack(b->q_min);
- float delta=_float32_unpack(b->q_delta);
- float *r=(float*)_ogg_calloc(n*b->dim,sizeof(*r));
-
- /* maptype 1 and 2 both use a quantized value vector, but
- different sizes */
- switch(b->maptype){
- case 1:
- /* most of the time, entries%dimensions == 0, but we need to be
- well defined. We define that the possible vales at each
- scalar is values == entries/dim. If entries%dim != 0, we'll
- have 'too few' values (values*dim<entries), which means that
- we'll have 'left over' entries; left over entries use zeroed
- values (and are wasted). So don't generate codebooks like
- that */
- quantvals=_book_maptype1_quantvals(b);
- for(j=0;j<b->entries;j++){
- if((sparsemap && b->lengthlist[j]) || !sparsemap){
- float last=0.f;
- int indexdiv=1;
- for(k=0;k<b->dim;k++){
- int index= (j/indexdiv)%quantvals;
- float val=b->quantlist[index];
- val=fabs(val)*delta+mindel+last;
- if(b->q_sequencep)last=val;
- if(sparsemap)
- r[sparsemap[count]*b->dim+k]=val;
- else
- r[count*b->dim+k]=val;
- indexdiv*=quantvals;
- }
- count++;
- }
-
- }
- break;
- case 2:
- for(j=0;j<b->entries;j++){
- if((sparsemap && b->lengthlist[j]) || !sparsemap){
- float last=0.f;
-
- for(k=0;k<b->dim;k++){
- float val=b->quantlist[j*b->dim+k];
- val=fabs(val)*delta+mindel+last;
- if(b->q_sequencep)last=val;
- if(sparsemap)
- r[sparsemap[count]*b->dim+k]=val;
- else
- r[count*b->dim+k]=val;
- }
- count++;
- }
- }
- break;
- }
-
- return(r);
- }
- return(NULL);
- }
-
- void vorbis_staticbook_clear(static_codebook *b){
- if(b->allocedp){
- if(b->quantlist)_ogg_free(b->quantlist);
- if(b->lengthlist)_ogg_free(b->lengthlist);
- if(b->nearest_tree){
- _ogg_free(b->nearest_tree->ptr0);
- _ogg_free(b->nearest_tree->ptr1);
- _ogg_free(b->nearest_tree->p);
- _ogg_free(b->nearest_tree->q);
- memset(b->nearest_tree,0,sizeof(*b->nearest_tree));
- _ogg_free(b->nearest_tree);
- }
- if(b->thresh_tree){
- _ogg_free(b->thresh_tree->quantthresh);
- _ogg_free(b->thresh_tree->quantmap);
- memset(b->thresh_tree,0,sizeof(*b->thresh_tree));
- _ogg_free(b->thresh_tree);
- }
-
- memset(b,0,sizeof(*b));
- }
- }
-
- void vorbis_staticbook_destroy(static_codebook *b){
- if(b->allocedp){
- vorbis_staticbook_clear(b);
- _ogg_free(b);
- }
- }
-
- void vorbis_book_clear(codebook *b){
- /* static book is not cleared; we're likely called on the lookup and
- the static codebook belongs to the info struct */
- if(b->valuelist)_ogg_free(b->valuelist);
- if(b->codelist)_ogg_free(b->codelist);
-
- if(b->dec_index)_ogg_free(b->dec_index);
- if(b->dec_codelengths)_ogg_free(b->dec_codelengths);
- if(b->dec_firsttable)_ogg_free(b->dec_firsttable);
-
- memset(b,0,sizeof(*b));
- }
-
- int vorbis_book_init_encode(codebook *c,const static_codebook *s){
-
- memset(c,0,sizeof(*c));
- c->c=s;
- c->entries=s->entries;
- c->used_entries=s->entries;
- c->dim=s->dim;
- c->codelist=_make_words(s->lengthlist,s->entries,0);
- c->valuelist=_book_unquantize(s,s->entries,NULL);
-
- return(0);
- }
-
- static int sort32a(const void *a,const void *b){
- return ( **(ogg_uint32_t **)a>**(ogg_uint32_t **)b)-
- ( **(ogg_uint32_t **)a<**(ogg_uint32_t **)b);
- }
-
- /* decode codebook arrangement is more heavily optimized than encode */
- int vorbis_book_init_decode(codebook *c,const static_codebook *s){
- int i,j,n=0,tabn;
- int *sortindex;
- memset(c,0,sizeof(*c));
-
- /* count actually used entries */
- for(i=0;i<s->entries;i++)
- if(s->lengthlist[i]>0)
- n++;
-
- c->entries=s->entries;
- c->used_entries=n;
- c->dim=s->dim;
-
- /* two different remappings go on here.
-
- First, we collapse the likely sparse codebook down only to
- actually represented values/words. This collapsing needs to be
- indexed as map-valueless books are used to encode original entry
- positions as integers.
-
- Second, we reorder all vectors, including the entry index above,
- by sorted bitreversed codeword to allow treeless decode. */
-
- {
- /* perform sort */
- ogg_uint32_t *codes=_make_words(s->lengthlist,s->entries,c->used_entries);
- ogg_uint32_t **codep=(ogg_uint32_t**)alloca(sizeof(*codep)*n);
-
- if(codes==NULL)goto err_out;
-
- for(i=0;i<n;i++){
- codes[i]=bitreverse(codes[i]);
- codep[i]=codes+i;
- }
-
- qsort(codep,n,sizeof(*codep),sort32a);
-
- sortindex=(int*)alloca(n*sizeof(*sortindex));
- c->codelist=(ogg_uint32_t*)_ogg_malloc(n*sizeof(*c->codelist));
- /* the index is a reverse index */
- for(i=0;i<n;i++){
- int position=codep[i]-codes;
- sortindex[position]=i;
- }
-
- for(i=0;i<n;i++)
- c->codelist[sortindex[i]]=codes[i];
- _ogg_free(codes);
- }
-
- c->valuelist=_book_unquantize(s,n,sortindex);
- c->dec_index=(int*)_ogg_malloc(n*sizeof(*c->dec_index));
-
- for(n=0,i=0;i<s->entries;i++)
- if(s->lengthlist[i]>0)
- c->dec_index[sortindex[n++]]=i;
-
- c->dec_codelengths=(char*)_ogg_malloc(n*sizeof(*c->dec_codelengths));
- for(n=0,i=0;i<s->entries;i++)
- if(s->lengthlist[i]>0)
- c->dec_codelengths[sortindex[n++]]=s->lengthlist[i];
-
- c->dec_firsttablen=_ilog(c->used_entries)-4; /* this is magic */
- if(c->dec_firsttablen<5)c->dec_firsttablen=5;
- if(c->dec_firsttablen>8)c->dec_firsttablen=8;
-
- tabn=1<<c->dec_firsttablen;
- c->dec_firsttable=(ogg_uint32_t*)_ogg_calloc(tabn,sizeof(*c->dec_firsttable));
- c->dec_maxlength=0;
-
- for(i=0;i<n;i++){
- if(c->dec_maxlength<c->dec_codelengths[i])
- c->dec_maxlength=c->dec_codelengths[i];
- if(c->dec_codelengths[i]<=c->dec_firsttablen){
- ogg_uint32_t orig=bitreverse(c->codelist[i]);
- for(j=0;j<(1<<(c->dec_firsttablen-c->dec_codelengths[i]));j++)
- c->dec_firsttable[orig|(j<<c->dec_codelengths[i])]=i+1;
- }
- }
-
- /* now fill in 'unused' entries in the firsttable with hi/lo search
- hints for the non-direct-hits */
- {
- ogg_uint32_t mask=0xfffffffeUL<<(31-c->dec_firsttablen);
- long lo=0,hi=0;
-
- for(i=0;i<tabn;i++){
- ogg_uint32_t word=i<<(32-c->dec_firsttablen);
- if(c->dec_firsttable[bitreverse(word)]==0){
- while((lo+1)<n && c->codelist[lo+1]<=word)lo++;
- while( hi<n && word>=(c->codelist[hi]&mask))hi++;
-
- /* we only actually have 15 bits per hint to play with here.
- In order to overflow gracefully (nothing breaks, efficiency
- just drops), encode as the difference from the extremes. */
- {
- unsigned long loval=lo;
- unsigned long hival=n-hi;
-
- if(loval>0x7fff)loval=0x7fff;
- if(hival>0x7fff)hival=0x7fff;
- c->dec_firsttable[bitreverse(word)]=
- 0x80000000UL | (loval<<15) | hival;
- }
- }
- }
- }
-
- return(0);
- err_out:
- vorbis_book_clear(c);
- return(-1);
- }
-
- static float _dist(int el,float *ref, float *b,int step){
- int i;
- float acc=0.f;
- for(i=0;i<el;i++){
- float val=(ref[i]-b[i*step]);
- acc+=val*val;
- }
- return(acc);
- }
-
- int _best(codebook *book, float *a, int step){
- encode_aux_threshmatch *tt=book->c->thresh_tree;
-
- #if 0
- encode_aux_nearestmatch *nt=book->c->nearest_tree;
- encode_aux_pigeonhole *pt=book->c->pigeon_tree;
- #endif
- int dim=book->dim;
- int k,o;
- /*int savebest=-1;
- float saverr;*/
-
- /* do we have a threshhold encode hint? */
- if(tt){
- int index=0,i;
- /* find the quant val of each scalar */
- for(k=0,o=step*(dim-1);k<dim;k++,o-=step){
-
- i=tt->threshvals>>1;
- if(a[o]<tt->quantthresh[i]){
-
- for(;i>0;i--)
- if(a[o]>=tt->quantthresh[i-1])
- break;
-
- }else{
-
- for(i++;i<tt->threshvals-1;i++)
- if(a[o]<tt->quantthresh[i])break;
-
- }
-
- index=(index*tt->quantvals)+tt->quantmap[i];
- }
- /* regular lattices are easy :-) */
- if(book->c->lengthlist[index]>0) /* is this unused? If so, we'll
- use a decision tree after all
- and fall through*/
- return(index);
- }
-
- #if 0
- /* do we have a pigeonhole encode hint? */
- if(pt){
- const static_codebook *c=book->c;
- int i,besti=-1;
- float best=0.f;
- int entry=0;
-
- /* dealing with sequentialness is a pain in the ass */
- if(c->q_sequencep){
- int pv;
- long mul=1;
- float qlast=0;
- for(k=0,o=0;k<dim;k++,o+=step){
- pv=(int)((a[o]-qlast-pt->min)/pt->del);
- if(pv<0 || pv>=pt->mapentries)break;
- entry+=pt->pigeonmap[pv]*mul;
- mul*=pt->quantvals;
- qlast+=pv*pt->del+pt->min;
- }
- }else{
- for(k=0,o=step*(dim-1);k<dim;k++,o-=step){
- int pv=(int)((a[o]-pt->min)/pt->del);
- if(pv<0 || pv>=pt->mapentries)break;
- entry=entry*pt->quantvals+pt->pigeonmap[pv];
- }
- }
-
- /* must be within the pigeonholable range; if we quant outside (or
- in an entry that we define no list for), brute force it */
- if(k==dim && pt->fitlength[entry]){
- /* search the abbreviated list */
- long *list=pt->fitlist+pt->fitmap[entry];
- for(i=0;i<pt->fitlength[entry];i++){
- float this=_dist(dim,book->valuelist+list[i]*dim,a,step);
- if(besti==-1 || this<best){
- best=this;
- besti=list[i];
- }
- }
-
- return(besti);
- }
- }
-
- if(nt){
- /* optimized using the decision tree */
- while(1){
- float c=0.f;
- float *p=book->valuelist+nt->p[ptr];
- float *q=book->valuelist+nt->q[ptr];
-
- for(k=0,o=0;k<dim;k++,o+=step)
- c+=(p[k]-q[k])*(a[o]-(p[k]+q[k])*.5);
-
- if(c>0.f) /* in A */
- ptr= -nt->ptr0[ptr];
- else /* in B */
- ptr= -nt->ptr1[ptr];
- if(ptr<=0)break;
- }
- return(-ptr);
- }
- #endif
-
- /* brute force it! */
- {
- const static_codebook *c=book->c;
- int i,besti=-1;
- float best=0.f;
- float *e=book->valuelist;
- for(i=0;i<book->entries;i++){
- if(c->lengthlist[i]>0){
- float thisx=_dist(dim,e,a,step);
- if(besti==-1 || thisx<best){
- best=thisx;
- besti=i;
- }
- }
- e+=dim;
- }
-
- /*if(savebest!=-1 && savebest!=besti){
- fprintf(stderr,"brute force/pigeonhole disagreement:\n"
- "original:");
- for(i=0;i<dim*step;i+=step)fprintf(stderr,"%g,",a[i]);
- fprintf(stderr,"\n"
- "pigeonhole (entry %d, err %g):",savebest,saverr);
- for(i=0;i<dim;i++)fprintf(stderr,"%g,",
- (book->valuelist+savebest*dim)[i]);
- fprintf(stderr,"\n"
- "bruteforce (entry %d, err %g):",besti,best);
- for(i=0;i<dim;i++)fprintf(stderr,"%g,",
- (book->valuelist+besti*dim)[i]);
- fprintf(stderr,"\n");
- }*/
- return(besti);
- }
- }
-
- long vorbis_book_codeword(codebook *book,int entry){
- if(book->c) /* only use with encode; decode optimizations are
- allowed to break this */
- return book->codelist[entry];
- return -1;
- }
-
- long vorbis_book_codelen(codebook *book,int entry){
- if(book->c) /* only use with encode; decode optimizations are
- allowed to break this */
- return book->c->lengthlist[entry];
- return -1;
- }
-
- #ifdef _V_SELFTEST
-
- /* Unit tests of the dequantizer; this stuff will be OK
- cross-platform, I simply want to be sure that special mapping cases
- actually work properly; a bug could go unnoticed for a while */
-
- #include <stdio.h>
-
- /* cases:
-
- no mapping
- full, explicit mapping
- algorithmic mapping
-
- nonsequential
- sequential
- */
-
- static long full_quantlist1[]={0,1,2,3, 4,5,6,7, 8,3,6,1};
- static long partial_quantlist1[]={0,7,2};
-
- /* no mapping */
- static_codebook test1={
- 4,16,
- NULL,
- 0,
- 0,0,0,0,
- NULL,
- NULL,NULL
- };
- static float *test1_result=NULL;
-
- /* linear, full mapping, nonsequential */
- static_codebook test2={
- 4,3,
- NULL,
- 2,
- -533200896,1611661312,4,0,
- full_quantlist1,
- NULL,NULL
- };
- static float test2_result[]={-3,-2,-1,0, 1,2,3,4, 5,0,3,-2};
-
- /* linear, full mapping, sequential */
- static_codebook test3={
- 4,3,
- NULL,
- 2,
- -533200896,1611661312,4,1,
- full_quantlist1,
- NULL,NULL
- };
- static float test3_result[]={-3,-5,-6,-6, 1,3,6,10, 5,5,8,6};
-
- /* linear, algorithmic mapping, nonsequential */
- static_codebook test4={
- 3,27,
- NULL,
- 1,
- -533200896,1611661312,4,0,
- partial_quantlist1,
- NULL,NULL
- };
- static float test4_result[]={-3,-3,-3, 4,-3,-3, -1,-3,-3,
- -3, 4,-3, 4, 4,-3, -1, 4,-3,
- -3,-1,-3, 4,-1,-3, -1,-1,-3,
- -3,-3, 4, 4,-3, 4, -1,-3, 4,
- -3, 4, 4, 4, 4, 4, -1, 4, 4,
- -3,-1, 4, 4,-1, 4, -1,-1, 4,
- -3,-3,-1, 4,-3,-1, -1,-3,-1,
- -3, 4,-1, 4, 4,-1, -1, 4,-1,
- -3,-1,-1, 4,-1,-1, -1,-1,-1};
-
- /* linear, algorithmic mapping, sequential */
- static_codebook test5={
- 3,27,
- NULL,
- 1,
- -533200896,1611661312,4,1,
- partial_quantlist1,
- NULL,NULL
- };
- static float test5_result[]={-3,-6,-9, 4, 1,-2, -1,-4,-7,
- -3, 1,-2, 4, 8, 5, -1, 3, 0,
- -3,-4,-7, 4, 3, 0, -1,-2,-5,
- -3,-6,-2, 4, 1, 5, -1,-4, 0,
- -3, 1, 5, 4, 8,12, -1, 3, 7,
- -3,-4, 0, 4, 3, 7, -1,-2, 2,
- -3,-6,-7, 4, 1, 0, -1,-4,-5,
- -3, 1, 0, 4, 8, 7, -1, 3, 2,
- -3,-4,-5, 4, 3, 2, -1,-2,-3};
-
- void run_test(static_codebook *b,float *comp){
- float *out=_book_unquantize(b,b->entries,NULL);
- int i;
-
- if(comp){
- if(!out){
- fprintf(stderr,"_book_unquantize incorrectly returned NULL\n");
- exit(1);
- }
-
- for(i=0;i<b->entries*b->dim;i++)
- if(fabs(out[i]-comp[i])>.0001){
- fprintf(stderr,"disagreement in unquantized and reference data:\n"
- "position %d, %g != %g\n",i,out[i],comp[i]);
- exit(1);
- }
-
- }else{
- if(out){
- fprintf(stderr,"_book_unquantize returned a value array: \n"
- " correct result should have been NULL\n");
- exit(1);
- }
- }
- }
-
- int main(){
- /* run the nine dequant tests, and compare to the hand-rolled results */
- fprintf(stderr,"Dequant test 1... ");
- run_test(&test1,test1_result);
- fprintf(stderr,"OK\nDequant test 2... ");
- run_test(&test2,test2_result);
- fprintf(stderr,"OK\nDequant test 3... ");
- run_test(&test3,test3_result);
- fprintf(stderr,"OK\nDequant test 4... ");
- run_test(&test4,test4_result);
- fprintf(stderr,"OK\nDequant test 5... ");
- run_test(&test5,test5_result);
- fprintf(stderr,"OK\n\n");
-
- return(0);
- }
-
- #endif
-
- #endif
- /********* End of inlined file: sharedbook.c *********/
-
- /********* Start of inlined file: smallft.c *********/
- /* FFT implementation from OggSquish, minus cosine transforms,
- * minus all but radix 2/4 case. In Vorbis we only need this
- * cut-down version.
- *
- * To do more than just power-of-two sized vectors, see the full
- * version I wrote for NetLib.
- *
- * Note that the packing is a little strange; rather than the FFT r/i
- * packing following R_0, I_n, R_1, I_1, R_2, I_2 ... R_n-1, I_n-1,
- * it follows R_0, R_1, I_1, R_2, I_2 ... R_n-1, I_n-1, I_n like the
- * FORTRAN version
- */
-
- /********* Start of inlined file: juce_OggVorbisHeader.h *********/
- // This file is included at the start of each Ogg-Vorbis .c file, just to do a few housekeeping
- // tasks..
-
- #ifdef _MSC_VER
- #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4305 4189 4706)
- #endif
- /********* End of inlined file: juce_OggVorbisHeader.h *********/
-
- #if JUCE_USE_OGGVORBIS
-
- #include <stdlib.h>
- #include <string.h>
- #include <math.h>
-
- static void drfti1(int n, float *wa, int *ifac){
- static int ntryh[4] = { 4,2,3,5 };
- static float tpi = 6.28318530717958648f;
- float arg,argh,argld,fi;
- int ntry=0,i,j=-1;
- int k1, l1, l2, ib;
- int ld, ii, ip, is, nq, nr;
- int ido, ipm, nfm1;
- int nl=n;
- int nf=0;
-
- L101:
- j++;
- if (j < 4)
- ntry=ntryh[j];
- else
- ntry+=2;
-
- L104:
- nq=nl/ntry;
- nr=nl-ntry*nq;
- if (nr!=0) goto L101;
-
- nf++;
- ifac[nf+1]=ntry;
- nl=nq;
- if(ntry!=2)goto L107;
- if(nf==1)goto L107;
-
- for (i=1;i<nf;i++){
- ib=nf-i+1;
- ifac[ib+1]=ifac[ib];
- }
- ifac[2] = 2;
-
- L107:
- if(nl!=1)goto L104;
- ifac[0]=n;
- ifac[1]=nf;
- argh=tpi/n;
- is=0;
- nfm1=nf-1;
- l1=1;
-
- if(nfm1==0)return;
-
- for (k1=0;k1<nfm1;k1++){
- ip=ifac[k1+2];
- ld=0;
- l2=l1*ip;
- ido=n/l2;
- ipm=ip-1;
-
- for (j=0;j<ipm;j++){
- ld+=l1;
- i=is;
- argld=(float)ld*argh;
- fi=0.f;
- for (ii=2;ii<ido;ii+=2){
- fi+=1.f;
- arg=fi*argld;
- wa[i++]=cos(arg);
- wa[i++]=sin(arg);
- }
- is+=ido;
- }
- l1=l2;
- }
- }
-
- static void fdrffti(int n, float *wsave, int *ifac){
-
- if (n == 1) return;
- drfti1(n, wsave+n, ifac);
- }
-
- static void dradf2(int ido,int l1,float *cc,float *ch,float *wa1){
- int i,k;
- float ti2,tr2;
- int t0,t1,t2,t3,t4,t5,t6;
-
- t1=0;
- t0=(t2=l1*ido);
- t3=ido<<1;
- for(k=0;k<l1;k++){
- ch[t1<<1]=cc[t1]+cc[t2];
- ch[(t1<<1)+t3-1]=cc[t1]-cc[t2];
- t1+=ido;
- t2+=ido;
- }
-
- if(ido<2)return;
- if(ido==2)goto L105;
-
- t1=0;
- t2=t0;
- for(k=0;k<l1;k++){
- t3=t2;
- t4=(t1<<1)+(ido<<1);
- t5=t1;
- t6=t1+t1;
- for(i=2;i<ido;i+=2){
- t3+=2;
- t4-=2;
- t5+=2;
- t6+=2;
- tr2=wa1[i-2]*cc[t3-1]+wa1[i-1]*cc[t3];
- ti2=wa1[i-2]*cc[t3]-wa1[i-1]*cc[t3-1];
- ch[t6]=cc[t5]+ti2;
- ch[t4]=ti2-cc[t5];
- ch[t6-1]=cc[t5-1]+tr2;
- ch[t4-1]=cc[t5-1]-tr2;
- }
- t1+=ido;
- t2+=ido;
- }
-
- if(ido%2==1)return;
-
- L105:
- t3=(t2=(t1=ido)-1);
- t2+=t0;
- for(k=0;k<l1;k++){
- ch[t1]=-cc[t2];
- ch[t1-1]=cc[t3];
- t1+=ido<<1;
- t2+=ido;
- t3+=ido;
- }
- }
-
- static void dradf4(int ido,int l1,float *cc,float *ch,float *wa1,
- float *wa2,float *wa3){
- static float hsqt2 = .70710678118654752f;
- int i,k,t0,t1,t2,t3,t4,t5,t6;
- float ci2,ci3,ci4,cr2,cr3,cr4,ti1,ti2,ti3,ti4,tr1,tr2,tr3,tr4;
- t0=l1*ido;
-
- t1=t0;
- t4=t1<<1;
- t2=t1+(t1<<1);
- t3=0;
-
- for(k=0;k<l1;k++){
- tr1=cc[t1]+cc[t2];
- tr2=cc[t3]+cc[t4];
-
- ch[t5=t3<<2]=tr1+tr2;
- ch[(ido<<2)+t5-1]=tr2-tr1;
- ch[(t5+=(ido<<1))-1]=cc[t3]-cc[t4];
- ch[t5]=cc[t2]-cc[t1];
-
- t1+=ido;
- t2+=ido;
- t3+=ido;
- t4+=ido;
- }
-
- if(ido<2)return;
- if(ido==2)goto L105;
-
- t1=0;
- for(k=0;k<l1;k++){
- t2=t1;
- t4=t1<<2;
- t5=(t6=ido<<1)+t4;
- for(i=2;i<ido;i+=2){
- t3=(t2+=2);
- t4+=2;
- t5-=2;
-
- t3+=t0;
- cr2=wa1[i-2]*cc[t3-1]+wa1[i-1]*cc[t3];
- ci2=wa1[i-2]*cc[t3]-wa1[i-1]*cc[t3-1];
- t3+=t0;
- cr3=wa2[i-2]*cc[t3-1]+wa2[i-1]*cc[t3];
- ci3=wa2[i-2]*cc[t3]-wa2[i-1]*cc[t3-1];
- t3+=t0;
- cr4=wa3[i-2]*cc[t3-1]+wa3[i-1]*cc[t3];
- ci4=wa3[i-2]*cc[t3]-wa3[i-1]*cc[t3-1];
-
- tr1=cr2+cr4;
- tr4=cr4-cr2;
- ti1=ci2+ci4;
- ti4=ci2-ci4;
-
- ti2=cc[t2]+ci3;
- ti3=cc[t2]-ci3;
- tr2=cc[t2-1]+cr3;
- tr3=cc[t2-1]-cr3;
-
- ch[t4-1]=tr1+tr2;
- ch[t4]=ti1+ti2;
-
- ch[t5-1]=tr3-ti4;
- ch[t5]=tr4-ti3;
-
- ch[t4+t6-1]=ti4+tr3;
- ch[t4+t6]=tr4+ti3;
-
- ch[t5+t6-1]=tr2-tr1;
- ch[t5+t6]=ti1-ti2;
- }
- t1+=ido;
- }
- if(ido&1)return;
-
- L105:
-
- t2=(t1=t0+ido-1)+(t0<<1);
- t3=ido<<2;
- t4=ido;
- t5=ido<<1;
- t6=ido;
-
- for(k=0;k<l1;k++){
- ti1=-hsqt2*(cc[t1]+cc[t2]);
- tr1=hsqt2*(cc[t1]-cc[t2]);
-
- ch[t4-1]=tr1+cc[t6-1];
- ch[t4+t5-1]=cc[t6-1]-tr1;
-
- ch[t4]=ti1-cc[t1+t0];
- ch[t4+t5]=ti1+cc[t1+t0];
-
- t1+=ido;
- t2+=ido;
- t4+=t3;
- t6+=ido;
- }
- }
-
- static void dradfg(int ido,int ip,int l1,int idl1,float *cc,float *c1,
- float *c2,float *ch,float *ch2,float *wa){
-
- static float tpi=6.283185307179586f;
- int idij,ipph,i,j,k,l,ic,ik,is;
- int t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10;
- float dc2,ai1,ai2,ar1,ar2,ds2;
- int nbd;
- float dcp,arg,dsp,ar1h,ar2h;
- int idp2,ipp2;
-
- arg=tpi/(float)ip;
- dcp=cos(arg);
- dsp=sin(arg);
- ipph=(ip+1)>>1;
- ipp2=ip;
- idp2=ido;
- nbd=(ido-1)>>1;
- t0=l1*ido;
- t10=ip*ido;
-
- if(ido==1)goto L119;
- for(ik=0;ik<idl1;ik++)ch2[ik]=c2[ik];
-
- t1=0;
- for(j=1;j<ip;j++){
- t1+=t0;
- t2=t1;
- for(k=0;k<l1;k++){
- ch[t2]=c1[t2];
- t2+=ido;
- }
- }
-
- is=-ido;
- t1=0;
- if(nbd>l1){
- for(j=1;j<ip;j++){
- t1+=t0;
- is+=ido;
- t2= -ido+t1;
- for(k=0;k<l1;k++){
- idij=is-1;
- t2+=ido;
- t3=t2;
- for(i=2;i<ido;i+=2){
- idij+=2;
- t3+=2;
- ch[t3-1]=wa[idij-1]*c1[t3-1]+wa[idij]*c1[t3];
- ch[t3]=wa[idij-1]*c1[t3]-wa[idij]*c1[t3-1];
- }
- }
- }
- }else{
-
- for(j=1;j<ip;j++){
- is+=ido;
- idij=is-1;
- t1+=t0;
- t2=t1;
- for(i=2;i<ido;i+=2){
- idij+=2;
- t2+=2;
- t3=t2;
- for(k=0;k<l1;k++){
- ch[t3-1]=wa[idij-1]*c1[t3-1]+wa[idij]*c1[t3];
- ch[t3]=wa[idij-1]*c1[t3]-wa[idij]*c1[t3-1];
- t3+=ido;
- }
- }
- }
- }
-
- t1=0;
- t2=ipp2*t0;
- if(nbd<l1){
- for(j=1;j<ipph;j++){
- t1+=t0;
- t2-=t0;
- t3=t1;
- t4=t2;
- for(i=2;i<ido;i+=2){
- t3+=2;
- t4+=2;
- t5=t3-ido;
- t6=t4-ido;
- for(k=0;k<l1;k++){
- t5+=ido;
- t6+=ido;
- c1[t5-1]=ch[t5-1]+ch[t6-1];
- c1[t6-1]=ch[t5]-ch[t6];
- c1[t5]=ch[t5]+ch[t6];
- c1[t6]=ch[t6-1]-ch[t5-1];
- }
- }
- }
- }else{
- for(j=1;j<ipph;j++){
- t1+=t0;
- t2-=t0;
- t3=t1;
- t4=t2;
- for(k=0;k<l1;k++){
- t5=t3;
- t6=t4;
- for(i=2;i<ido;i+=2){
- t5+=2;
- t6+=2;
- c1[t5-1]=ch[t5-1]+ch[t6-1];
- c1[t6-1]=ch[t5]-ch[t6];
- c1[t5]=ch[t5]+ch[t6];
- c1[t6]=ch[t6-1]-ch[t5-1];
- }
- t3+=ido;
- t4+=ido;
- }
- }
- }
-
- L119:
- for(ik=0;ik<idl1;ik++)c2[ik]=ch2[ik];
-
- t1=0;
- t2=ipp2*idl1;
- for(j=1;j<ipph;j++){
- t1+=t0;
- t2-=t0;
- t3=t1-ido;
- t4=t2-ido;
- for(k=0;k<l1;k++){
- t3+=ido;
- t4+=ido;
- c1[t3]=ch[t3]+ch[t4];
- c1[t4]=ch[t4]-ch[t3];
- }
- }
-
- ar1=1.f;
- ai1=0.f;
- t1=0;
- t2=ipp2*idl1;
- t3=(ip-1)*idl1;
- for(l=1;l<ipph;l++){
- t1+=idl1;
- t2-=idl1;
- ar1h=dcp*ar1-dsp*ai1;
- ai1=dcp*ai1+dsp*ar1;
- ar1=ar1h;
- t4=t1;
- t5=t2;
- t6=t3;
- t7=idl1;
-
- for(ik=0;ik<idl1;ik++){
- ch2[t4++]=c2[ik]+ar1*c2[t7++];
- ch2[t5++]=ai1*c2[t6++];
- }
-
- dc2=ar1;
- ds2=ai1;
- ar2=ar1;
- ai2=ai1;
-
- t4=idl1;
- t5=(ipp2-1)*idl1;
- for(j=2;j<ipph;j++){
- t4+=idl1;
- t5-=idl1;
-
- ar2h=dc2*ar2-ds2*ai2;
- ai2=dc2*ai2+ds2*ar2;
- ar2=ar2h;
-
- t6=t1;
- t7=t2;
- t8=t4;
- t9=t5;
- for(ik=0;ik<idl1;ik++){
- ch2[t6++]+=ar2*c2[t8++];
- ch2[t7++]+=ai2*c2[t9++];
- }
- }
- }
-
- t1=0;
- for(j=1;j<ipph;j++){
- t1+=idl1;
- t2=t1;
- for(ik=0;ik<idl1;ik++)ch2[ik]+=c2[t2++];
- }
-
- if(ido<l1)goto L132;
-
- t1=0;
- t2=0;
- for(k=0;k<l1;k++){
- t3=t1;
- t4=t2;
- for(i=0;i<ido;i++)cc[t4++]=ch[t3++];
- t1+=ido;
- t2+=t10;
- }
-
- goto L135;
-
- L132:
- for(i=0;i<ido;i++){
- t1=i;
- t2=i;
- for(k=0;k<l1;k++){
- cc[t2]=ch[t1];
- t1+=ido;
- t2+=t10;
- }
- }
-
- L135:
- t1=0;
- t2=ido<<1;
- t3=0;
- t4=ipp2*t0;
- for(j=1;j<ipph;j++){
-
- t1+=t2;
- t3+=t0;
- t4-=t0;
-
- t5=t1;
- t6=t3;
- t7=t4;
-
- for(k=0;k<l1;k++){
- cc[t5-1]=ch[t6];
- cc[t5]=ch[t7];
- t5+=t10;
- t6+=ido;
- t7+=ido;
- }
- }
-
- if(ido==1)return;
- if(nbd<l1)goto L141;
-
- t1=-ido;
- t3=0;
- t4=0;
- t5=ipp2*t0;
- for(j=1;j<ipph;j++){
- t1+=t2;
- t3+=t2;
- t4+=t0;
- t5-=t0;
- t6=t1;
- t7=t3;
- t8=t4;
- t9=t5;
- for(k=0;k<l1;k++){
- for(i=2;i<ido;i+=2){
- ic=idp2-i;
- cc[i+t7-1]=ch[i+t8-1]+ch[i+t9-1];
- cc[ic+t6-1]=ch[i+t8-1]-ch[i+t9-1];
- cc[i+t7]=ch[i+t8]+ch[i+t9];
- cc[ic+t6]=ch[i+t9]-ch[i+t8];
- }
- t6+=t10;
- t7+=t10;
- t8+=ido;
- t9+=ido;
- }
- }
- return;
-
- L141:
-
- t1=-ido;
- t3=0;
- t4=0;
- t5=ipp2*t0;
- for(j=1;j<ipph;j++){
- t1+=t2;
- t3+=t2;
- t4+=t0;
- t5-=t0;
- for(i=2;i<ido;i+=2){
- t6=idp2+t1-i;
- t7=i+t3;
- t8=i+t4;
- t9=i+t5;
- for(k=0;k<l1;k++){
- cc[t7-1]=ch[t8-1]+ch[t9-1];
- cc[t6-1]=ch[t8-1]-ch[t9-1];
- cc[t7]=ch[t8]+ch[t9];
- cc[t6]=ch[t9]-ch[t8];
- t6+=t10;
- t7+=t10;
- t8+=ido;
- t9+=ido;
- }
- }
- }
- }
-
- static void drftf1(int n,float *c,float *ch,float *wa,int *ifac){
- int i,k1,l1,l2;
- int na,kh,nf;
- int ip,iw,ido,idl1,ix2,ix3;
-
- nf=ifac[1];
- na=1;
- l2=n;
- iw=n;
-
- for(k1=0;k1<nf;k1++){
- kh=nf-k1;
- ip=ifac[kh+1];
- l1=l2/ip;
- ido=n/l2;
- idl1=ido*l1;
- iw-=(ip-1)*ido;
- na=1-na;
-
- if(ip!=4)goto L102;
-
- ix2=iw+ido;
- ix3=ix2+ido;
- if(na!=0)
- dradf4(ido,l1,ch,c,wa+iw-1,wa+ix2-1,wa+ix3-1);
- else
- dradf4(ido,l1,c,ch,wa+iw-1,wa+ix2-1,wa+ix3-1);
- goto L110;
-
- L102:
- if(ip!=2)goto L104;
- if(na!=0)goto L103;
-
- dradf2(ido,l1,c,ch,wa+iw-1);
- goto L110;
-
- L103:
- dradf2(ido,l1,ch,c,wa+iw-1);
- goto L110;
-
- L104:
- if(ido==1)na=1-na;
- if(na!=0)goto L109;
-
- dradfg(ido,ip,l1,idl1,c,c,c,ch,ch,wa+iw-1);
- na=1;
- goto L110;
-
- L109:
- dradfg(ido,ip,l1,idl1,ch,ch,ch,c,c,wa+iw-1);
- na=0;
-
- L110:
- l2=l1;
- }
-
- if(na==1)return;
-
- for(i=0;i<n;i++)c[i]=ch[i];
- }
-
- static void dradb2(int ido,int l1,float *cc,float *ch,float *wa1){
- int i,k,t0,t1,t2,t3,t4,t5,t6;
- float ti2,tr2;
-
- t0=l1*ido;
-
- t1=0;
- t2=0;
- t3=(ido<<1)-1;
- for(k=0;k<l1;k++){
- ch[t1]=cc[t2]+cc[t3+t2];
- ch[t1+t0]=cc[t2]-cc[t3+t2];
- t2=(t1+=ido)<<1;
- }
-
- if(ido<2)return;
- if(ido==2)goto L105;
-
- t1=0;
- t2=0;
- for(k=0;k<l1;k++){
- t3=t1;
- t5=(t4=t2)+(ido<<1);
- t6=t0+t1;
- for(i=2;i<ido;i+=2){
- t3+=2;
- t4+=2;
- t5-=2;
- t6+=2;
- ch[t3-1]=cc[t4-1]+cc[t5-1];
- tr2=cc[t4-1]-cc[t5-1];
- ch[t3]=cc[t4]-cc[t5];
- ti2=cc[t4]+cc[t5];
- ch[t6-1]=wa1[i-2]*tr2-wa1[i-1]*ti2;
- ch[t6]=wa1[i-2]*ti2+wa1[i-1]*tr2;
- }
- t2=(t1+=ido)<<1;
- }
-
- if(ido%2==1)return;
-
- L105:
- t1=ido-1;
- t2=ido-1;
- for(k=0;k<l1;k++){
- ch[t1]=cc[t2]+cc[t2];
- ch[t1+t0]=-(cc[t2+1]+cc[t2+1]);
- t1+=ido;
- t2+=ido<<1;
- }
- }
-
- static void dradb3(int ido,int l1,float *cc,float *ch,float *wa1,
- float *wa2){
- static float taur = -.5f;
- static float taui = .8660254037844386f;
- int i,k,t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10;
- float ci2,ci3,di2,di3,cr2,cr3,dr2,dr3,ti2,tr2;
- t0=l1*ido;
-
- t1=0;
- t2=t0<<1;
- t3=ido<<1;
- t4=ido+(ido<<1);
- t5=0;
- for(k=0;k<l1;k++){
- tr2=cc[t3-1]+cc[t3-1];
- cr2=cc[t5]+(taur*tr2);
- ch[t1]=cc[t5]+tr2;
- ci3=taui*(cc[t3]+cc[t3]);
- ch[t1+t0]=cr2-ci3;
- ch[t1+t2]=cr2+ci3;
- t1+=ido;
- t3+=t4;
- t5+=t4;
- }
-
- if(ido==1)return;
-
- t1=0;
- t3=ido<<1;
- for(k=0;k<l1;k++){
- t7=t1+(t1<<1);
- t6=(t5=t7+t3);
- t8=t1;
- t10=(t9=t1+t0)+t0;
-
- for(i=2;i<ido;i+=2){
- t5+=2;
- t6-=2;
- t7+=2;
- t8+=2;
- t9+=2;
- t10+=2;
- tr2=cc[t5-1]+cc[t6-1];
- cr2=cc[t7-1]+(taur*tr2);
- ch[t8-1]=cc[t7-1]+tr2;
- ti2=cc[t5]-cc[t6];
- ci2=cc[t7]+(taur*ti2);
- ch[t8]=cc[t7]+ti2;
- cr3=taui*(cc[t5-1]-cc[t6-1]);
- ci3=taui*(cc[t5]+cc[t6]);
- dr2=cr2-ci3;
- dr3=cr2+ci3;
- di2=ci2+cr3;
- di3=ci2-cr3;
- ch[t9-1]=wa1[i-2]*dr2-wa1[i-1]*di2;
- ch[t9]=wa1[i-2]*di2+wa1[i-1]*dr2;
- ch[t10-1]=wa2[i-2]*dr3-wa2[i-1]*di3;
- ch[t10]=wa2[i-2]*di3+wa2[i-1]*dr3;
- }
- t1+=ido;
- }
- }
-
- static void dradb4(int ido,int l1,float *cc,float *ch,float *wa1,
- float *wa2,float *wa3){
- static float sqrt2=1.414213562373095f;
- int i,k,t0,t1,t2,t3,t4,t5,t6,t7,t8;
- float ci2,ci3,ci4,cr2,cr3,cr4,ti1,ti2,ti3,ti4,tr1,tr2,tr3,tr4;
- t0=l1*ido;
-
- t1=0;
- t2=ido<<2;
- t3=0;
- t6=ido<<1;
- for(k=0;k<l1;k++){
- t4=t3+t6;
- t5=t1;
- tr3=cc[t4-1]+cc[t4-1];
- tr4=cc[t4]+cc[t4];
- tr1=cc[t3]-cc[(t4+=t6)-1];
- tr2=cc[t3]+cc[t4-1];
- ch[t5]=tr2+tr3;
- ch[t5+=t0]=tr1-tr4;
- ch[t5+=t0]=tr2-tr3;
- ch[t5+=t0]=tr1+tr4;
- t1+=ido;
- t3+=t2;
- }
-
- if(ido<2)return;
- if(ido==2)goto L105;
-
- t1=0;
- for(k=0;k<l1;k++){
- t5=(t4=(t3=(t2=t1<<2)+t6))+t6;
- t7=t1;
- for(i=2;i<ido;i+=2){
- t2+=2;
- t3+=2;
- t4-=2;
- t5-=2;
- t7+=2;
- ti1=cc[t2]+cc[t5];
- ti2=cc[t2]-cc[t5];
- ti3=cc[t3]-cc[t4];
- tr4=cc[t3]+cc[t4];
- tr1=cc[t2-1]-cc[t5-1];
- tr2=cc[t2-1]+cc[t5-1];
- ti4=cc[t3-1]-cc[t4-1];
- tr3=cc[t3-1]+cc[t4-1];
- ch[t7-1]=tr2+tr3;
- cr3=tr2-tr3;
- ch[t7]=ti2+ti3;
- ci3=ti2-ti3;
- cr2=tr1-tr4;
- cr4=tr1+tr4;
- ci2=ti1+ti4;
- ci4=ti1-ti4;
-
- ch[(t8=t7+t0)-1]=wa1[i-2]*cr2-wa1[i-1]*ci2;
- ch[t8]=wa1[i-2]*ci2+wa1[i-1]*cr2;
- ch[(t8+=t0)-1]=wa2[i-2]*cr3-wa2[i-1]*ci3;
- ch[t8]=wa2[i-2]*ci3+wa2[i-1]*cr3;
- ch[(t8+=t0)-1]=wa3[i-2]*cr4-wa3[i-1]*ci4;
- ch[t8]=wa3[i-2]*ci4+wa3[i-1]*cr4;
- }
- t1+=ido;
- }
-
- if(ido%2 == 1)return;
-
- L105:
-
- t1=ido;
- t2=ido<<2;
- t3=ido-1;
- t4=ido+(ido<<1);
- for(k=0;k<l1;k++){
- t5=t3;
- ti1=cc[t1]+cc[t4];
- ti2=cc[t4]-cc[t1];
- tr1=cc[t1-1]-cc[t4-1];
- tr2=cc[t1-1]+cc[t4-1];
- ch[t5]=tr2+tr2;
- ch[t5+=t0]=sqrt2*(tr1-ti1);
- ch[t5+=t0]=ti2+ti2;
- ch[t5+=t0]=-sqrt2*(tr1+ti1);
-
- t3+=ido;
- t1+=t2;
- t4+=t2;
- }
- }
-
- static void dradbg(int ido,int ip,int l1,int idl1,float *cc,float *c1,
- float *c2,float *ch,float *ch2,float *wa){
- static float tpi=6.283185307179586f;
- int idij,ipph,i,j,k,l,ik,is,t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,
- t11,t12;
- float dc2,ai1,ai2,ar1,ar2,ds2;
- int nbd;
- float dcp,arg,dsp,ar1h,ar2h;
- int ipp2;
-
- t10=ip*ido;
- t0=l1*ido;
- arg=tpi/(float)ip;
- dcp=cos(arg);
- dsp=sin(arg);
- nbd=(ido-1)>>1;
- ipp2=ip;
- ipph=(ip+1)>>1;
- if(ido<l1)goto L103;
-
- t1=0;
- t2=0;
- for(k=0;k<l1;k++){
- t3=t1;
- t4=t2;
- for(i=0;i<ido;i++){
- ch[t3]=cc[t4];
- t3++;
- t4++;
- }
- t1+=ido;
- t2+=t10;
- }
- goto L106;
-
- L103:
- t1=0;
- for(i=0;i<ido;i++){
- t2=t1;
- t3=t1;
- for(k=0;k<l1;k++){
- ch[t2]=cc[t3];
- t2+=ido;
- t3+=t10;
- }
- t1++;
- }
-
- L106:
- t1=0;
- t2=ipp2*t0;
- t7=(t5=ido<<1);
- for(j=1;j<ipph;j++){
- t1+=t0;
- t2-=t0;
- t3=t1;
- t4=t2;
- t6=t5;
- for(k=0;k<l1;k++){
- ch[t3]=cc[t6-1]+cc[t6-1];
- ch[t4]=cc[t6]+cc[t6];
- t3+=ido;
- t4+=ido;
- t6+=t10;
- }
- t5+=t7;
- }
-
- if (ido == 1)goto L116;
- if(nbd<l1)goto L112;
-
- t1=0;
- t2=ipp2*t0;
- t7=0;
- for(j=1;j<ipph;j++){
- t1+=t0;
- t2-=t0;
- t3=t1;
- t4=t2;
-
- t7+=(ido<<1);
- t8=t7;
- for(k=0;k<l1;k++){
- t5=t3;
- t6=t4;
- t9=t8;
- t11=t8;
- for(i=2;i<ido;i+=2){
- t5+=2;
- t6+=2;
- t9+=2;
- t11-=2;
- ch[t5-1]=cc[t9-1]+cc[t11-1];
- ch[t6-1]=cc[t9-1]-cc[t11-1];
- ch[t5]=cc[t9]-cc[t11];
- ch[t6]=cc[t9]+cc[t11];
- }
- t3+=ido;
- t4+=ido;
- t8+=t10;
- }
- }
- goto L116;
-
- L112:
- t1=0;
- t2=ipp2*t0;
- t7=0;
- for(j=1;j<ipph;j++){
- t1+=t0;
- t2-=t0;
- t3=t1;
- t4=t2;
- t7+=(ido<<1);
- t8=t7;
- t9=t7;
- for(i=2;i<ido;i+=2){
- t3+=2;
- t4+=2;
- t8+=2;
- t9-=2;
- t5=t3;
- t6=t4;
- t11=t8;
- t12=t9;
- for(k=0;k<l1;k++){
- ch[t5-1]=cc[t11-1]+cc[t12-1];
- ch[t6-1]=cc[t11-1]-cc[t12-1];
- ch[t5]=cc[t11]-cc[t12];
- ch[t6]=cc[t11]+cc[t12];
- t5+=ido;
- t6+=ido;
- t11+=t10;
- t12+=t10;
- }
- }
- }
-
- L116:
- ar1=1.f;
- ai1=0.f;
- t1=0;
- t9=(t2=ipp2*idl1);
- t3=(ip-1)*idl1;
- for(l=1;l<ipph;l++){
- t1+=idl1;
- t2-=idl1;
-
- ar1h=dcp*ar1-dsp*ai1;
- ai1=dcp*ai1+dsp*ar1;
- ar1=ar1h;
- t4=t1;
- t5=t2;
- t6=0;
- t7=idl1;
- t8=t3;
- for(ik=0;ik<idl1;ik++){
- c2[t4++]=ch2[t6++]+ar1*ch2[t7++];
- c2[t5++]=ai1*ch2[t8++];
- }
- dc2=ar1;
- ds2=ai1;
- ar2=ar1;
- ai2=ai1;
-
- t6=idl1;
- t7=t9-idl1;
- for(j=2;j<ipph;j++){
- t6+=idl1;
- t7-=idl1;
- ar2h=dc2*ar2-ds2*ai2;
- ai2=dc2*ai2+ds2*ar2;
- ar2=ar2h;
- t4=t1;
- t5=t2;
- t11=t6;
- t12=t7;
- for(ik=0;ik<idl1;ik++){
- c2[t4++]+=ar2*ch2[t11++];
- c2[t5++]+=ai2*ch2[t12++];
- }
- }
- }
-
- t1=0;
- for(j=1;j<ipph;j++){
- t1+=idl1;
- t2=t1;
- for(ik=0;ik<idl1;ik++)ch2[ik]+=ch2[t2++];
- }
-
- t1=0;
- t2=ipp2*t0;
- for(j=1;j<ipph;j++){
- t1+=t0;
- t2-=t0;
- t3=t1;
- t4=t2;
- for(k=0;k<l1;k++){
- ch[t3]=c1[t3]-c1[t4];
- ch[t4]=c1[t3]+c1[t4];
- t3+=ido;
- t4+=ido;
- }
- }
-
- if(ido==1)goto L132;
- if(nbd<l1)goto L128;
-
- t1=0;
- t2=ipp2*t0;
- for(j=1;j<ipph;j++){
- t1+=t0;
- t2-=t0;
- t3=t1;
- t4=t2;
- for(k=0;k<l1;k++){
- t5=t3;
- t6=t4;
- for(i=2;i<ido;i+=2){
- t5+=2;
- t6+=2;
- ch[t5-1]=c1[t5-1]-c1[t6];
- ch[t6-1]=c1[t5-1]+c1[t6];
- ch[t5]=c1[t5]+c1[t6-1];
- ch[t6]=c1[t5]-c1[t6-1];
- }
- t3+=ido;
- t4+=ido;
- }
- }
- goto L132;
-
- L128:
- t1=0;
- t2=ipp2*t0;
- for(j=1;j<ipph;j++){
- t1+=t0;
- t2-=t0;
- t3=t1;
- t4=t2;
- for(i=2;i<ido;i+=2){
- t3+=2;
- t4+=2;
- t5=t3;
- t6=t4;
- for(k=0;k<l1;k++){
- ch[t5-1]=c1[t5-1]-c1[t6];
- ch[t6-1]=c1[t5-1]+c1[t6];
- ch[t5]=c1[t5]+c1[t6-1];
- ch[t6]=c1[t5]-c1[t6-1];
- t5+=ido;
- t6+=ido;
- }
- }
- }
-
- L132:
- if(ido==1)return;
-
- for(ik=0;ik<idl1;ik++)c2[ik]=ch2[ik];
-
- t1=0;
- for(j=1;j<ip;j++){
- t2=(t1+=t0);
- for(k=0;k<l1;k++){
- c1[t2]=ch[t2];
- t2+=ido;
- }
- }
-
- if(nbd>l1)goto L139;
-
- is= -ido-1;
- t1=0;
- for(j=1;j<ip;j++){
- is+=ido;
- t1+=t0;
- idij=is;
- t2=t1;
- for(i=2;i<ido;i+=2){
- t2+=2;
- idij+=2;
- t3=t2;
- for(k=0;k<l1;k++){
- c1[t3-1]=wa[idij-1]*ch[t3-1]-wa[idij]*ch[t3];
- c1[t3]=wa[idij-1]*ch[t3]+wa[idij]*ch[t3-1];
- t3+=ido;
- }
- }
- }
- return;
-
- L139:
- is= -ido-1;
- t1=0;
- for(j=1;j<ip;j++){
- is+=ido;
- t1+=t0;
- t2=t1;
- for(k=0;k<l1;k++){
- idij=is;
- t3=t2;
- for(i=2;i<ido;i+=2){
- idij+=2;
- t3+=2;
- c1[t3-1]=wa[idij-1]*ch[t3-1]-wa[idij]*ch[t3];
- c1[t3]=wa[idij-1]*ch[t3]+wa[idij]*ch[t3-1];
- }
- t2+=ido;
- }
- }
- }
-
- static void drftb1(int n, float *c, float *ch, float *wa, int *ifac){
- int i,k1,l1,l2;
- int na;
- int nf,ip,iw,ix2,ix3,ido,idl1;
-
- nf=ifac[1];
- na=0;
- l1=1;
- iw=1;
-
- for(k1=0;k1<nf;k1++){
- ip=ifac[k1 + 2];
- l2=ip*l1;
- ido=n/l2;
- idl1=ido*l1;
- if(ip!=4)goto L103;
- ix2=iw+ido;
- ix3=ix2+ido;
-
- if(na!=0)
- dradb4(ido,l1,ch,c,wa+iw-1,wa+ix2-1,wa+ix3-1);
- else
- dradb4(ido,l1,c,ch,wa+iw-1,wa+ix2-1,wa+ix3-1);
- na=1-na;
- goto L115;
-
- L103:
- if(ip!=2)goto L106;
-
- if(na!=0)
- dradb2(ido,l1,ch,c,wa+iw-1);
- else
- dradb2(ido,l1,c,ch,wa+iw-1);
- na=1-na;
- goto L115;
-
- L106:
- if(ip!=3)goto L109;
-
- ix2=iw+ido;
- if(na!=0)
- dradb3(ido,l1,ch,c,wa+iw-1,wa+ix2-1);
- else
- dradb3(ido,l1,c,ch,wa+iw-1,wa+ix2-1);
- na=1-na;
- goto L115;
-
- L109:
- /* The radix five case can be translated later..... */
- /* if(ip!=5)goto L112;
-
- ix2=iw+ido;
- ix3=ix2+ido;
- ix4=ix3+ido;
- if(na!=0)
- dradb5(ido,l1,ch,c,wa+iw-1,wa+ix2-1,wa+ix3-1,wa+ix4-1);
- else
- dradb5(ido,l1,c,ch,wa+iw-1,wa+ix2-1,wa+ix3-1,wa+ix4-1);
- na=1-na;
- goto L115;
-
- L112:*/
- if(na!=0)
- dradbg(ido,ip,l1,idl1,ch,ch,ch,c,c,wa+iw-1);
- else
- dradbg(ido,ip,l1,idl1,c,c,c,ch,ch,wa+iw-1);
- if(ido==1)na=1-na;
-
- L115:
- l1=l2;
- iw+=(ip-1)*ido;
- }
-
- if(na==0)return;
-
- for(i=0;i<n;i++)c[i]=ch[i];
- }
-
- void drft_forward(drft_lookup *l,float *data){
- if(l->n==1)return;
- drftf1(l->n,data,l->trigcache,l->trigcache+l->n,l->splitcache);
- }
-
- void drft_backward(drft_lookup *l,float *data){
- if (l->n==1)return;
- drftb1(l->n,data,l->trigcache,l->trigcache+l->n,l->splitcache);
- }
-
- void drft_init(drft_lookup *l,int n){
- l->n=n;
- l->trigcache=(float*)_ogg_calloc(3*n,sizeof(*l->trigcache));
- l->splitcache=(int*)_ogg_calloc(32,sizeof(*l->splitcache));
- fdrffti(n, l->trigcache, l->splitcache);
- }
-
- void drft_clear(drft_lookup *l){
- if(l){
- if(l->trigcache)_ogg_free(l->trigcache);
- if(l->splitcache)_ogg_free(l->splitcache);
- memset(l,0,sizeof(*l));
- }
- }
-
- #endif
- /********* End of inlined file: smallft.c *********/
-
- /********* Start of inlined file: synthesis.c *********/
-
- /********* Start of inlined file: juce_OggVorbisHeader.h *********/
- // This file is included at the start of each Ogg-Vorbis .c file, just to do a few housekeeping
- // tasks..
-
- #ifdef _MSC_VER
- #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4305 4189 4706)
- #endif
- /********* End of inlined file: juce_OggVorbisHeader.h *********/
-
- #if JUCE_USE_OGGVORBIS
-
- #include <stdio.h>
-
- int vorbis_synthesis(vorbis_block *vb,ogg_packet *op){
- vorbis_dsp_state *vd=vb->vd;
- private_state *b=(private_state*)vd->backend_state;
- vorbis_info *vi=vd->vi;
- codec_setup_info *ci=(codec_setup_info*) vi->codec_setup;
- oggpack_buffer *opb=&vb->opb;
- int type,mode,i;
-
- /* first things first. Make sure decode is ready */
- _vorbis_block_ripcord(vb);
- oggpack_readinit(opb,op->packet,op->bytes);
-
- /* Check the packet type */
- if(oggpack_read(opb,1)!=0){
- /* Oops. This is not an audio data packet */
- return(OV_ENOTAUDIO);
- }
-
- /* read our mode and pre/post windowsize */
- mode=oggpack_read(opb,b->modebits);
- if(mode==-1)return(OV_EBADPACKET);
-
- vb->mode=mode;
- vb->W=ci->mode_param[mode]->blockflag;
- if(vb->W){
-
- /* this doesn;t get mapped through mode selection as it's used
- only for window selection */
- vb->lW=oggpack_read(opb,1);
- vb->nW=oggpack_read(opb,1);
- if(vb->nW==-1) return(OV_EBADPACKET);
- }else{
- vb->lW=0;
- vb->nW=0;
- }
-
- /* more setup */
- vb->granulepos=op->granulepos;
- vb->sequence=op->packetno;
- vb->eofflag=op->e_o_s;
-
- /* alloc pcm passback storage */
- vb->pcmend=ci->blocksizes[vb->W];
- vb->pcm=(float**)_vorbis_block_alloc(vb,sizeof(*vb->pcm)*vi->channels);
- for(i=0;i<vi->channels;i++)
- vb->pcm[i]=(float*)_vorbis_block_alloc(vb,vb->pcmend*sizeof(*vb->pcm[i]));
-
- /* unpack_header enforces range checking */
- type=ci->map_type[ci->mode_param[mode]->mapping];
-
- return(_mapping_P[type]->inverse(vb,ci->map_param[ci->mode_param[mode]->
- mapping]));
- }
-
- /* used to track pcm position without actually performing decode.
- Useful for sequential 'fast forward' */
- int vorbis_synthesis_trackonly(vorbis_block *vb,ogg_packet *op){
- vorbis_dsp_state *vd=vb->vd;
- private_state *b=(private_state*)vd->backend_state;
- vorbis_info *vi=vd->vi;
- codec_setup_info *ci=(codec_setup_info*)vi->codec_setup;
- oggpack_buffer *opb=&vb->opb;
- int mode;
-
- /* first things first. Make sure decode is ready */
- _vorbis_block_ripcord(vb);
- oggpack_readinit(opb,op->packet,op->bytes);
-
- /* Check the packet type */
- if(oggpack_read(opb,1)!=0){
- /* Oops. This is not an audio data packet */
- return(OV_ENOTAUDIO);
- }
-
- /* read our mode and pre/post windowsize */
- mode=oggpack_read(opb,b->modebits);
- if(mode==-1)return(OV_EBADPACKET);
-
- vb->mode=mode;
- vb->W=ci->mode_param[mode]->blockflag;
- if(vb->W){
- vb->lW=oggpack_read(opb,1);
- vb->nW=oggpack_read(opb,1);
- if(vb->nW==-1) return(OV_EBADPACKET);
- }else{
- vb->lW=0;
- vb->nW=0;
- }
-
- /* more setup */
- vb->granulepos=op->granulepos;
- vb->sequence=op->packetno;
- vb->eofflag=op->e_o_s;
-
- /* no pcm */
- vb->pcmend=0;
- vb->pcm=NULL;
-
- return(0);
- }
-
- long vorbis_packet_blocksize(vorbis_info *vi,ogg_packet *op){
- codec_setup_info *ci=(codec_setup_info*)vi->codec_setup;
- oggpack_buffer opb;
- int mode;
-
- oggpack_readinit(&opb,op->packet,op->bytes);
-
- /* Check the packet type */
- if(oggpack_read(&opb,1)!=0){
- /* Oops. This is not an audio data packet */
- return(OV_ENOTAUDIO);
- }
-
- {
- int modebits=0;
- int v=ci->modes;
- while(v>1){
- modebits++;
- v>>=1;
- }
-
- /* read our mode and pre/post windowsize */
- mode=oggpack_read(&opb,modebits);
- }
- if(mode==-1)return(OV_EBADPACKET);
- return(ci->blocksizes[ci->mode_param[mode]->blockflag]);
- }
-
- int vorbis_synthesis_halfrate(vorbis_info *vi,int flag){
- /* set / clear half-sample-rate mode */
- codec_setup_info *ci=(codec_setup_info*)vi->codec_setup;
-
- /* right now, our MDCT can't handle < 64 sample windows. */
- if(ci->blocksizes[0]<=64 && flag)return -1;
- ci->halfrate_flag=(flag?1:0);
- return 0;
- }
-
- int vorbis_synthesis_halfrate_p(vorbis_info *vi){
- codec_setup_info *ci=(codec_setup_info*)vi->codec_setup;
- return ci->halfrate_flag;
- }
-
- #endif
- /********* End of inlined file: synthesis.c *********/
-
- /********* Start of inlined file: vorbisenc.c *********/
-
- /********* Start of inlined file: juce_OggVorbisHeader.h *********/
- // This file is included at the start of each Ogg-Vorbis .c file, just to do a few housekeeping
- // tasks..
-
- #ifdef _MSC_VER
- #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4305 4189 4706)
- #endif
- /********* End of inlined file: juce_OggVorbisHeader.h *********/
-
- #if JUCE_USE_OGGVORBIS
-
- #include <stdlib.h>
- #include <string.h>
- #include <math.h>
-
- /* careful with this; it's using static array sizing to make managing
- all the modes a little less annoying. If we use a residue backend
- with > 12 partition types, or a different division of iteration,
- this needs to be updated. */
- typedef struct {
- static_codebook *books[12][3];
- } static_bookblock;
-
- typedef struct {
- int res_type;
- int limit_type; /* 0 lowpass limited, 1 point stereo limited */
- vorbis_info_residue0 *res;
- static_codebook *book_aux;
- static_codebook *book_aux_managed;
- static_bookblock *books_base;
- static_bookblock *books_base_managed;
- } vorbis_residue_template;
-
- typedef struct {
- vorbis_info_mapping0 *map;
- vorbis_residue_template *res;
- } vorbis_mapping_template;
-
- typedef struct vp_adjblock{
- int block[P_BANDS];
- } vp_adjblock;
-
- typedef struct {
- int data[NOISE_COMPAND_LEVELS];
- } compandblock;
-
- /* high level configuration information for setting things up
- step-by-step with the detailed vorbis_encode_ctl interface.
- There's a fair amount of redundancy such that interactive setup
- does not directly deal with any vorbis_info or codec_setup_info
- initialization; it's all stored (until full init) in this highlevel
- setup, then flushed out to the real codec setup structs later. */
-
- typedef struct {
- int att[P_NOISECURVES];
- float boost;
- float decay;
- } att3;
- typedef struct { int data[P_NOISECURVES]; } adj3;
-
- typedef struct {
- int pre[PACKETBLOBS];
- int post[PACKETBLOBS];
- float kHz[PACKETBLOBS];
- float lowpasskHz[PACKETBLOBS];
- } adj_stereo;
-
- typedef struct {
- int lo;
- int hi;
- int fixed;
- } noiseguard;
- typedef struct {
- int data[P_NOISECURVES][17];
- } noise3;
-
- typedef struct {
- int mappings;
- double *rate_mapping;
- double *quality_mapping;
- int coupling_restriction;
- long samplerate_min_restriction;
- long samplerate_max_restriction;
-
- int *blocksize_short;
- int *blocksize_long;
-
- att3 *psy_tone_masteratt;
- int *psy_tone_0dB;
- int *psy_tone_dBsuppress;
-
- vp_adjblock *psy_tone_adj_impulse;
- vp_adjblock *psy_tone_adj_long;
- vp_adjblock *psy_tone_adj_other;
-
- noiseguard *psy_noiseguards;
- noise3 *psy_noise_bias_impulse;
- noise3 *psy_noise_bias_padding;
- noise3 *psy_noise_bias_trans;
- noise3 *psy_noise_bias_long;
- int *psy_noise_dBsuppress;
-
- compandblock *psy_noise_compand;
- double *psy_noise_compand_short_mapping;
- double *psy_noise_compand_long_mapping;
-
- int *psy_noise_normal_start[2];
- int *psy_noise_normal_partition[2];
- double *psy_noise_normal_thresh;
-
- int *psy_ath_float;
- int *psy_ath_abs;
-
- double *psy_lowpass;
-
- vorbis_info_psy_global *global_params;
- double *global_mapping;
- adj_stereo *stereo_modes;
-
- static_codebook ***floor_books;
- vorbis_info_floor1 *floor_params;
- int *floor_short_mapping;
- int *floor_long_mapping;
-
- vorbis_mapping_template *maps;
- } ve_setup_data_template;
-
- /* a few static coder conventions */
- static vorbis_info_mode _mode_template[2]={
- {0,0,0,0},
- {1,0,0,1}
- };
-
- static vorbis_info_mapping0 _map_nominal[2]={
- {1, {0,0}, {0}, {0}, 1,{0},{1}},
- {1, {0,0}, {1}, {1}, 1,{0},{1}}
- };
-
- /********* Start of inlined file: setup_44.h *********/
-
- /********* Start of inlined file: floor_all.h *********/
-
- /********* Start of inlined file: floor_books.h *********/
-
- static long _huff_lengthlist_line_256x7_0sub1[] = {
- 0, 2, 3, 3, 3, 3, 4, 3, 4,
- };
-
- static static_codebook _huff_book_line_256x7_0sub1 = {
- 1, 9,
- _huff_lengthlist_line_256x7_0sub1,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_256x7_0sub2[] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 3, 4, 3, 5, 3,
- 6, 3, 6, 4, 6, 4, 7, 5, 7,
- };
-
- static static_codebook _huff_book_line_256x7_0sub2 = {
- 1, 25,
- _huff_lengthlist_line_256x7_0sub2,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_256x7_0sub3[] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 5, 2, 5, 3, 5, 3,
- 6, 3, 6, 4, 7, 6, 7, 8, 7, 9, 8, 9, 9, 9,10, 9,
- 11,13,11,13,10,10,13,13,13,13,13,13,12,12,12,12,
- };
-
- static static_codebook _huff_book_line_256x7_0sub3 = {
- 1, 64,
- _huff_lengthlist_line_256x7_0sub3,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_256x7_1sub1[] = {
- 0, 3, 3, 3, 3, 2, 4, 3, 4,
- };
-
- static static_codebook _huff_book_line_256x7_1sub1 = {
- 1, 9,
- _huff_lengthlist_line_256x7_1sub1,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_256x7_1sub2[] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 3, 4, 3, 4, 4,
- 5, 4, 6, 5, 6, 7, 6, 8, 8,
- };
-
- static static_codebook _huff_book_line_256x7_1sub2 = {
- 1, 25,
- _huff_lengthlist_line_256x7_1sub2,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_256x7_1sub3[] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 4, 3, 6, 3, 7,
- 3, 8, 5, 8, 6, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7,
- };
-
- static static_codebook _huff_book_line_256x7_1sub3 = {
- 1, 64,
- _huff_lengthlist_line_256x7_1sub3,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_256x7_class0[] = {
- 7, 5, 5, 9, 9, 6, 6, 9,12, 8, 7, 8,11, 8, 9,15,
- 6, 3, 3, 7, 7, 4, 3, 6, 9, 6, 5, 6, 8, 6, 8,15,
- 8, 5, 5, 9, 8, 5, 4, 6,10, 7, 5, 5,11, 8, 7,15,
- 14,15,13,13,13,13, 8,11,15,10, 7, 6,11, 9,10,15,
- };
-
- static static_codebook _huff_book_line_256x7_class0 = {
- 1, 64,
- _huff_lengthlist_line_256x7_class0,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_256x7_class1[] = {
- 5, 6, 8,15, 6, 9,10,15,10,11,12,15,15,15,15,15,
- 4, 6, 7,15, 6, 7, 8,15, 9, 8, 9,15,15,15,15,15,
- 6, 8, 9,15, 7, 7, 8,15,10, 9,10,15,15,15,15,15,
- 15,13,15,15,15,10,11,15,15,13,13,15,15,15,15,15,
- 4, 6, 7,15, 6, 8, 9,15,10,10,12,15,15,15,15,15,
- 2, 5, 6,15, 5, 6, 7,15, 8, 6, 7,15,15,15,15,15,
- 5, 6, 8,15, 5, 6, 7,15, 9, 6, 7,15,15,15,15,15,
- 14,12,13,15,12,10,11,15,15,15,15,15,15,15,15,15,
- 7, 8, 9,15, 9,10,10,15,15,14,14,15,15,15,15,15,
- 5, 6, 7,15, 7, 8, 9,15,12, 9,10,15,15,15,15,15,
- 7, 7, 9,15, 7, 7, 8,15,12, 8, 9,15,15,15,15,15,
- 13,13,14,15,12,11,12,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,
- 13,13,13,15,15,15,15,15,15,15,15,15,15,15,15,15,
- 15,12,13,15,15,12,13,15,15,14,15,15,15,15,15,15,
- 15,15,15,15,15,15,13,15,15,15,15,15,15,15,15,15,
- };
-
- static static_codebook _huff_book_line_256x7_class1 = {
- 1, 256,
- _huff_lengthlist_line_256x7_class1,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_512x17_0sub0[] = {
- 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 6, 5, 6, 6, 6, 6, 5, 6, 6, 7, 6, 7, 6, 7, 6,
- 7, 6, 8, 7, 8, 7, 8, 7, 8, 7, 8, 7, 9, 7, 9, 7,
- 9, 7, 9, 8, 9, 8,10, 8,10, 8,10, 7,10, 6,10, 8,
- 10, 8,11, 7,10, 7,11, 8,11,11,12,12,11,11,12,11,
- 13,11,13,11,13,12,15,12,13,13,14,14,14,14,14,15,
- 15,15,16,14,17,19,19,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,
- };
-
- static static_codebook _huff_book_line_512x17_0sub0 = {
- 1, 128,
- _huff_lengthlist_line_512x17_0sub0,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_512x17_1sub0[] = {
- 2, 4, 5, 4, 5, 4, 5, 4, 5, 5, 5, 5, 5, 5, 6, 5,
- 6, 5, 6, 6, 7, 6, 7, 6, 8, 7, 8, 7, 8, 7, 8, 7,
- };
-
- static static_codebook _huff_book_line_512x17_1sub0 = {
- 1, 32,
- _huff_lengthlist_line_512x17_1sub0,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_512x17_1sub1[] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 4, 3, 5, 3, 5, 4, 5, 4, 5, 4, 5, 5, 5, 5, 6, 5,
- 6, 5, 7, 5, 8, 6, 8, 6, 8, 6, 8, 6, 8, 7, 9, 7,
- 9, 7,11, 9,11,11,12,11,14,12,14,16,14,16,13,16,
- 14,16,12,15,13,16,14,16,13,14,12,15,13,15,13,13,
- 13,15,12,14,14,15,13,15,12,15,15,15,15,15,15,15,
- 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
- };
-
- static static_codebook _huff_book_line_512x17_1sub1 = {
- 1, 128,
- _huff_lengthlist_line_512x17_1sub1,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_512x17_2sub1[] = {
- 0, 4, 5, 4, 4, 4, 5, 4, 4, 4, 5, 4, 5, 4, 5, 3,
- 5, 3,
- };
-
- static static_codebook _huff_book_line_512x17_2sub1 = {
- 1, 18,
- _huff_lengthlist_line_512x17_2sub1,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_512x17_2sub2[] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 4, 3, 4, 3, 4, 4, 5, 4, 5, 4, 6, 4, 6, 5,
- 6, 5, 7, 5, 7, 6, 8, 6, 8, 6, 8, 7, 8, 7, 9, 7,
- 9, 8,
- };
-
- static static_codebook _huff_book_line_512x17_2sub2 = {
- 1, 50,
- _huff_lengthlist_line_512x17_2sub2,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_512x17_2sub3[] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 3, 3, 3, 3, 4, 3, 4, 4, 5, 5, 6, 6, 7, 7,
- 7, 8, 8,11, 8, 9, 9, 9,10,11,11,11, 9,10,10,11,
- 11,11,11,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- };
-
- static static_codebook _huff_book_line_512x17_2sub3 = {
- 1, 128,
- _huff_lengthlist_line_512x17_2sub3,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_512x17_3sub1[] = {
- 0, 4, 4, 4, 4, 4, 4, 3, 4, 4, 4, 4, 4, 5, 4, 5,
- 5, 5,
- };
-
- static static_codebook _huff_book_line_512x17_3sub1 = {
- 1, 18,
- _huff_lengthlist_line_512x17_3sub1,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_512x17_3sub2[] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 2, 3, 3, 4, 3, 5, 4, 6, 4, 6, 5, 7, 6, 7,
- 6, 8, 6, 8, 7, 9, 8,10, 8,12, 9,13,10,15,10,15,
- 11,14,
- };
-
- static static_codebook _huff_book_line_512x17_3sub2 = {
- 1, 50,
- _huff_lengthlist_line_512x17_3sub2,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_512x17_3sub3[] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 4, 8, 4, 8, 4, 8, 4, 8, 5, 8, 5, 8, 6, 8,
- 4, 8, 4, 8, 5, 8, 5, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- };
-
- static static_codebook _huff_book_line_512x17_3sub3 = {
- 1, 128,
- _huff_lengthlist_line_512x17_3sub3,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_512x17_class1[] = {
- 1, 2, 3, 6, 5, 4, 7, 7,
- };
-
- static static_codebook _huff_book_line_512x17_class1 = {
- 1, 8,
- _huff_lengthlist_line_512x17_class1,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_512x17_class2[] = {
- 3, 3, 3,14, 5, 4, 4,11, 8, 6, 6,10,17,12,11,17,
- 6, 5, 5,15, 5, 3, 4,11, 8, 5, 5, 8,16, 9,10,14,
- 10, 8, 9,17, 8, 6, 6,13,10, 7, 7,10,16,11,13,14,
- 17,17,17,17,17,16,16,16,16,15,16,16,16,16,16,16,
- };
-
- static static_codebook _huff_book_line_512x17_class2 = {
- 1, 64,
- _huff_lengthlist_line_512x17_class2,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_512x17_class3[] = {
- 2, 4, 6,17, 4, 5, 7,17, 8, 7,10,17,17,17,17,17,
- 3, 4, 6,15, 3, 3, 6,15, 7, 6, 9,17,17,17,17,17,
- 6, 8,10,17, 6, 6, 8,16, 9, 8,10,17,17,15,16,17,
- 17,17,17,17,12,15,15,16,12,15,15,16,16,16,16,16,
- };
-
- static static_codebook _huff_book_line_512x17_class3 = {
- 1, 64,
- _huff_lengthlist_line_512x17_class3,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_128x4_class0[] = {
- 7, 7, 7,11, 6, 6, 7,11, 7, 6, 6,10,12,10,10,13,
- 7, 7, 8,11, 7, 7, 7,11, 7, 6, 7,10,11,10,10,13,
- 10,10, 9,12, 9, 9, 9,11, 8, 8, 8,11,13,11,10,14,
- 15,15,14,15,15,14,13,14,15,12,12,17,17,17,17,17,
- 7, 7, 6, 9, 6, 6, 6, 9, 7, 6, 6, 8,11,11,10,12,
- 7, 7, 7, 9, 7, 6, 6, 9, 7, 6, 6, 9,13,10,10,11,
- 10, 9, 8,10, 9, 8, 8,10, 8, 8, 7, 9,13,12,10,11,
- 17,14,14,13,15,14,12,13,17,13,12,15,17,17,14,17,
- 7, 6, 6, 7, 6, 6, 5, 7, 6, 6, 6, 6,11, 9, 9, 9,
- 7, 7, 6, 7, 7, 6, 6, 7, 6, 6, 6, 6,10, 9, 8, 9,
- 10, 9, 8, 8, 9, 8, 7, 8, 8, 7, 6, 8,11,10, 9,10,
- 17,17,12,15,15,15,12,14,14,14,10,12,15,13,12,13,
- 11,10, 8,10,11,10, 8, 8,10, 9, 7, 7,10, 9, 9,11,
- 11,11, 9,10,11,10, 8, 9,10, 8, 6, 8,10, 9, 9,11,
- 14,13,10,12,12,11,10,10, 8, 7, 8,10,10,11,11,12,
- 17,17,15,17,17,17,17,17,17,13,12,17,17,17,14,17,
- };
-
- static static_codebook _huff_book_line_128x4_class0 = {
- 1, 256,
- _huff_lengthlist_line_128x4_class0,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_128x4_0sub0[] = {
- 2, 2, 2, 2,
- };
-
- static static_codebook _huff_book_line_128x4_0sub0 = {
- 1, 4,
- _huff_lengthlist_line_128x4_0sub0,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_128x4_0sub1[] = {
- 0, 0, 0, 0, 3, 2, 3, 2, 3, 3,
- };
-
- static static_codebook _huff_book_line_128x4_0sub1 = {
- 1, 10,
- _huff_lengthlist_line_128x4_0sub1,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_128x4_0sub2[] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 4, 3, 4, 3,
- 4, 4, 5, 4, 5, 4, 6, 5, 6,
- };
-
- static static_codebook _huff_book_line_128x4_0sub2 = {
- 1, 25,
- _huff_lengthlist_line_128x4_0sub2,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_128x4_0sub3[] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 3, 5, 3, 5, 3,
- 5, 4, 6, 5, 6, 5, 7, 6, 6, 7, 7, 9, 9,11,11,16,
- 11,14,10,11,11,13,16,15,15,15,15,15,15,15,15,15,
- };
-
- static static_codebook _huff_book_line_128x4_0sub3 = {
- 1, 64,
- _huff_lengthlist_line_128x4_0sub3,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_256x4_class0[] = {
- 6, 7, 7,12, 6, 6, 7,12, 7, 6, 6,10,15,12,11,13,
- 7, 7, 8,13, 7, 7, 8,12, 7, 7, 7,11,12,12,11,13,
- 10, 9, 9,11, 9, 9, 9,10,10, 8, 8,12,14,12,12,14,
- 11,11,12,14,11,12,11,15,15,12,13,15,15,15,15,15,
- 6, 6, 7,10, 6, 6, 6,11, 7, 6, 6, 9,14,12,11,13,
- 7, 7, 7,10, 6, 6, 7, 9, 7, 7, 6,10,13,12,10,12,
- 9, 9, 9,11, 9, 9, 8, 9, 9, 8, 8,10,13,12,10,12,
- 12,12,11,13,12,12,11,12,15,13,12,15,15,15,14,14,
- 6, 6, 6, 8, 6, 6, 5, 6, 7, 7, 6, 5,11,10, 9, 8,
- 7, 6, 6, 7, 6, 6, 5, 6, 7, 7, 6, 6,11,10, 9, 8,
- 8, 8, 8, 9, 8, 8, 7, 8, 8, 8, 6, 7,11,10, 9, 9,
- 14,11,10,14,14,11,10,15,13,11, 9,11,15,12,12,11,
- 11, 9, 8, 8,10, 9, 8, 9,11,10, 9, 8,12,11,12,11,
- 13,10, 8, 9,11,10, 8, 9,10, 9, 8, 9,10, 8,12,12,
- 15,11,10,10,13,11,10,10, 8, 8, 7,12,10, 9,11,12,
- 15,12,11,15,13,11,11,15,12,14,11,13,15,15,13,13,
- };
-
- static static_codebook _huff_book_line_256x4_class0 = {
- 1, 256,
- _huff_lengthlist_line_256x4_class0,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_256x4_0sub0[] = {
- 2, 2, 2, 2,
- };
-
- static static_codebook _huff_book_line_256x4_0sub0 = {
- 1, 4,
- _huff_lengthlist_line_256x4_0sub0,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_256x4_0sub1[] = {
- 0, 0, 0, 0, 2, 2, 3, 3, 3, 3,
- };
-
- static static_codebook _huff_book_line_256x4_0sub1 = {
- 1, 10,
- _huff_lengthlist_line_256x4_0sub1,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_256x4_0sub2[] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 3, 4, 3, 4, 3,
- 5, 3, 5, 4, 5, 4, 6, 4, 6,
- };
-
- static static_codebook _huff_book_line_256x4_0sub2 = {
- 1, 25,
- _huff_lengthlist_line_256x4_0sub2,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_256x4_0sub3[] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 3, 5, 3, 5, 3,
- 6, 4, 7, 4, 7, 5, 7, 6, 7, 6, 7, 8,10,13,13,13,
- 13,13,13,13,13,13,13,13,13,13,13,12,12,12,12,12,
- };
-
- static static_codebook _huff_book_line_256x4_0sub3 = {
- 1, 64,
- _huff_lengthlist_line_256x4_0sub3,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_128x7_class0[] = {
- 10, 7, 8,13, 9, 6, 7,11,10, 8, 8,12,17,17,17,17,
- 7, 5, 5, 9, 6, 4, 4, 8, 8, 5, 5, 8,16,14,13,16,
- 7, 5, 5, 7, 6, 3, 3, 5, 8, 5, 4, 7,14,12,12,15,
- 10, 7, 8, 9, 7, 5, 5, 6, 9, 6, 5, 5,15,12, 9,10,
- };
-
- static static_codebook _huff_book_line_128x7_class0 = {
- 1, 64,
- _huff_lengthlist_line_128x7_class0,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_128x7_class1[] = {
- 8,13,17,17, 8,11,17,17,11,13,17,17,17,17,17,17,
- 6,10,16,17, 6,10,15,17, 8,10,16,17,17,17,17,17,
- 9,13,15,17, 8,11,17,17,10,12,17,17,17,17,17,17,
- 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
- 6,11,15,17, 7,10,15,17, 8,10,17,17,17,15,17,17,
- 4, 8,13,17, 4, 7,13,17, 6, 8,15,17,16,15,17,17,
- 6,11,15,17, 6, 9,13,17, 8,10,17,17,15,17,17,17,
- 16,17,17,17,12,14,15,17,13,14,15,17,17,17,17,17,
- 5,10,14,17, 5, 9,14,17, 7, 9,15,17,15,15,17,17,
- 3, 7,12,17, 3, 6,11,17, 5, 7,13,17,12,12,17,17,
- 5, 9,14,17, 3, 7,11,17, 5, 8,13,17,13,11,16,17,
- 12,17,17,17, 9,14,15,17,10,11,14,17,16,14,17,17,
- 8,12,17,17, 8,12,17,17,10,12,17,17,17,17,17,17,
- 5,10,17,17, 5, 9,15,17, 7, 9,17,17,13,13,17,17,
- 7,11,17,17, 6,10,15,17, 7, 9,15,17,12,11,17,17,
- 12,15,17,17,11,14,17,17,11,10,15,17,17,16,17,17,
- };
-
- static static_codebook _huff_book_line_128x7_class1 = {
- 1, 256,
- _huff_lengthlist_line_128x7_class1,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_128x7_0sub1[] = {
- 0, 3, 3, 3, 3, 3, 3, 3, 3,
- };
-
- static static_codebook _huff_book_line_128x7_0sub1 = {
- 1, 9,
- _huff_lengthlist_line_128x7_0sub1,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_128x7_0sub2[] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 4, 4, 4, 4,
- 5, 4, 5, 4, 5, 4, 6, 4, 6,
- };
-
- static static_codebook _huff_book_line_128x7_0sub2 = {
- 1, 25,
- _huff_lengthlist_line_128x7_0sub2,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_128x7_0sub3[] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 5, 3, 5, 3, 5, 4,
- 5, 4, 5, 5, 5, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5,
- 7, 8, 9,11,13,13,13,13,13,13,13,13,13,13,13,13,
- };
-
- static static_codebook _huff_book_line_128x7_0sub3 = {
- 1, 64,
- _huff_lengthlist_line_128x7_0sub3,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_128x7_1sub1[] = {
- 0, 3, 3, 2, 3, 3, 4, 3, 4,
- };
-
- static static_codebook _huff_book_line_128x7_1sub1 = {
- 1, 9,
- _huff_lengthlist_line_128x7_1sub1,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_128x7_1sub2[] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 3, 6, 3, 6, 3,
- 6, 3, 7, 3, 8, 4, 9, 4, 9,
- };
-
- static static_codebook _huff_book_line_128x7_1sub2 = {
- 1, 25,
- _huff_lengthlist_line_128x7_1sub2,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_128x7_1sub3[] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 7, 2, 7, 3, 8, 4,
- 9, 5, 9, 8,10,11,11,12,14,14,14,14,14,14,14,14,
- 14,14,14,14,14,14,14,14,14,14,14,14,13,13,13,13,
- };
-
- static static_codebook _huff_book_line_128x7_1sub3 = {
- 1, 64,
- _huff_lengthlist_line_128x7_1sub3,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_128x11_class1[] = {
- 1, 6, 3, 7, 2, 4, 5, 7,
- };
-
- static static_codebook _huff_book_line_128x11_class1 = {
- 1, 8,
- _huff_lengthlist_line_128x11_class1,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_128x11_class2[] = {
- 1, 6,12,16, 4,12,15,16, 9,15,16,16,16,16,16,16,
- 2, 5,11,16, 5,11,13,16, 9,13,16,16,16,16,16,16,
- 4, 8,12,16, 5, 9,12,16, 9,13,15,16,16,16,16,16,
- 15,16,16,16,11,14,13,16,12,15,16,16,16,16,16,15,
- };
-
- static static_codebook _huff_book_line_128x11_class2 = {
- 1, 64,
- _huff_lengthlist_line_128x11_class2,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_128x11_class3[] = {
- 7, 6, 9,17, 7, 6, 8,17,12, 9,11,16,16,16,16,16,
- 5, 4, 7,16, 5, 3, 6,14, 9, 6, 8,15,16,16,16,16,
- 5, 4, 6,13, 3, 2, 4,11, 7, 4, 6,13,16,11,10,14,
- 12,12,12,16, 9, 7,10,15,12, 9,11,16,16,15,15,16,
- };
-
- static static_codebook _huff_book_line_128x11_class3 = {
- 1, 64,
- _huff_lengthlist_line_128x11_class3,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_128x11_0sub0[] = {
- 5, 5, 5, 5, 5, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5,
- 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 6, 6, 6, 7, 6,
- 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 8, 6, 8, 6, 8, 7,
- 8, 7, 8, 7, 8, 7, 9, 7, 9, 8, 9, 8, 9, 8,10, 8,
- 10, 9,10, 9,10, 9,11, 9,11, 9,10,10,11,10,11,10,
- 11,11,11,11,11,11,12,13,14,14,14,15,15,16,16,16,
- 17,15,16,15,16,16,17,17,16,17,17,17,17,17,17,17,
- 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
- };
-
- static static_codebook _huff_book_line_128x11_0sub0 = {
- 1, 128,
- _huff_lengthlist_line_128x11_0sub0,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_128x11_1sub0[] = {
- 2, 5, 5, 5, 5, 5, 5, 4, 5, 5, 5, 5, 5, 5, 5, 5,
- 6, 5, 6, 5, 6, 5, 7, 6, 7, 6, 7, 6, 8, 6, 8, 6,
- };
-
- static static_codebook _huff_book_line_128x11_1sub0 = {
- 1, 32,
- _huff_lengthlist_line_128x11_1sub0,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_128x11_1sub1[] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 5, 3, 5, 3, 6, 4, 6, 4, 7, 4, 7, 4, 7, 4, 8, 4,
- 8, 4, 9, 5, 9, 5, 9, 5, 9, 6,10, 6,10, 6,11, 7,
- 10, 7,10, 8,11, 9,11, 9,11,10,11,11,12,11,11,12,
- 15,15,12,14,11,14,12,14,11,14,13,14,12,14,11,14,
- 11,14,12,14,11,14,11,14,13,13,14,14,14,14,14,14,
- 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,
- };
-
- static static_codebook _huff_book_line_128x11_1sub1 = {
- 1, 128,
- _huff_lengthlist_line_128x11_1sub1,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_128x11_2sub1[] = {
- 0, 4, 5, 4, 5, 4, 5, 3, 5, 3, 5, 3, 5, 4, 4, 4,
- 5, 5,
- };
-
- static static_codebook _huff_book_line_128x11_2sub1 = {
- 1, 18,
- _huff_lengthlist_line_128x11_2sub1,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_128x11_2sub2[] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 3, 3, 3, 4, 4, 4, 4, 5, 4, 5, 4, 6, 5, 7,
- 5, 7, 6, 8, 6, 8, 6, 9, 7, 9, 7,10, 7, 9, 8,11,
- 8,11,
- };
-
- static static_codebook _huff_book_line_128x11_2sub2 = {
- 1, 50,
- _huff_lengthlist_line_128x11_2sub2,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_128x11_2sub3[] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 4, 8, 3, 8, 4, 8, 4, 8, 6, 8, 5, 8, 4, 8,
- 4, 8, 6, 8, 7, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- };
-
- static static_codebook _huff_book_line_128x11_2sub3 = {
- 1, 128,
- _huff_lengthlist_line_128x11_2sub3,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_128x11_3sub1[] = {
- 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 4,
- 5, 4,
- };
-
- static static_codebook _huff_book_line_128x11_3sub1 = {
- 1, 18,
- _huff_lengthlist_line_128x11_3sub1,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_128x11_3sub2[] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 5, 3, 5, 4, 6, 4, 6, 4, 7, 4, 7, 4, 8, 4,
- 8, 4, 9, 4, 9, 4,10, 4,10, 5,10, 5,11, 5,12, 6,
- 12, 6,
- };
-
- static static_codebook _huff_book_line_128x11_3sub2 = {
- 1, 50,
- _huff_lengthlist_line_128x11_3sub2,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_128x11_3sub3[] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 7, 1, 6, 3, 7, 3, 8, 4, 8, 5, 8, 8, 8, 9,
- 7, 8, 8, 7, 7, 7, 8, 9,10, 9, 9,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10, 9, 9,
- };
-
- static static_codebook _huff_book_line_128x11_3sub3 = {
- 1, 128,
- _huff_lengthlist_line_128x11_3sub3,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_128x17_class1[] = {
- 1, 3, 4, 7, 2, 5, 6, 7,
- };
-
- static static_codebook _huff_book_line_128x17_class1 = {
- 1, 8,
- _huff_lengthlist_line_128x17_class1,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_128x17_class2[] = {
- 1, 4,10,19, 3, 8,13,19, 7,12,19,19,19,19,19,19,
- 2, 6,11,19, 8,13,19,19, 9,11,19,19,19,19,19,19,
- 6, 7,13,19, 9,13,19,19,10,13,18,18,18,18,18,18,
- 18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,
- };
-
- static static_codebook _huff_book_line_128x17_class2 = {
- 1, 64,
- _huff_lengthlist_line_128x17_class2,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_128x17_class3[] = {
- 3, 6,10,17, 4, 8,11,20, 8,10,11,20,20,20,20,20,
- 2, 4, 8,18, 4, 6, 8,17, 7, 8,10,20,20,17,20,20,
- 3, 5, 8,17, 3, 4, 6,17, 8, 8,10,17,17,12,16,20,
- 13,13,15,20,10,10,12,20,15,14,15,20,20,20,19,19,
- };
-
- static static_codebook _huff_book_line_128x17_class3 = {
- 1, 64,
- _huff_lengthlist_line_128x17_class3,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_128x17_0sub0[] = {
- 5, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5,
- 7, 5, 7, 5, 7, 5, 7, 5, 7, 5, 7, 5, 8, 5, 8, 5,
- 8, 5, 8, 5, 8, 6, 8, 6, 8, 6, 9, 6, 9, 6, 9, 6,
- 9, 6, 9, 7, 9, 7, 9, 7, 9, 7,10, 7,10, 8,10, 8,
- 10, 8,10, 8,10, 8,11, 8,11, 8,11, 8,11, 8,11, 9,
- 12, 9,12, 9,12, 9,12, 9,12,10,12,10,13,11,13,11,
- 14,12,14,13,15,14,16,14,17,15,18,16,20,20,20,20,
- 20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
- };
-
- static static_codebook _huff_book_line_128x17_0sub0 = {
- 1, 128,
- _huff_lengthlist_line_128x17_0sub0,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_128x17_1sub0[] = {
- 2, 5, 5, 4, 5, 4, 5, 4, 5, 5, 5, 5, 5, 5, 6, 5,
- 6, 5, 6, 5, 7, 6, 7, 6, 7, 6, 8, 6, 9, 7, 9, 7,
- };
-
- static static_codebook _huff_book_line_128x17_1sub0 = {
- 1, 32,
- _huff_lengthlist_line_128x17_1sub0,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_128x17_1sub1[] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 4, 3, 5, 3, 5, 3, 6, 3, 6, 4, 6, 4, 7, 4, 7, 5,
- 8, 5, 8, 6, 9, 7, 9, 7, 9, 8,10, 9,10, 9,11,10,
- 11,11,11,11,11,11,12,12,12,13,12,13,12,14,12,15,
- 12,14,12,16,13,17,13,17,14,17,14,16,13,17,14,17,
- 14,17,15,17,15,15,16,17,17,17,17,17,17,17,17,17,
- 17,17,17,17,17,17,16,16,16,16,16,16,16,16,16,16,
- };
-
- static static_codebook _huff_book_line_128x17_1sub1 = {
- 1, 128,
- _huff_lengthlist_line_128x17_1sub1,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_128x17_2sub1[] = {
- 0, 4, 5, 4, 6, 4, 8, 3, 9, 3, 9, 2, 9, 3, 8, 4,
- 9, 4,
- };
-
- static static_codebook _huff_book_line_128x17_2sub1 = {
- 1, 18,
- _huff_lengthlist_line_128x17_2sub1,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_128x17_2sub2[] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 5, 1, 5, 3, 5, 3, 5, 4, 7, 5,10, 7,10, 7,
- 12,10,14,10,14, 9,14,11,14,14,14,13,13,13,13,13,
- 13,13,
- };
-
- static static_codebook _huff_book_line_128x17_2sub2 = {
- 1, 50,
- _huff_lengthlist_line_128x17_2sub2,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_128x17_2sub3[] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 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, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- };
-
- static static_codebook _huff_book_line_128x17_2sub3 = {
- 1, 128,
- _huff_lengthlist_line_128x17_2sub3,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_128x17_3sub1[] = {
- 0, 4, 4, 4, 4, 4, 4, 4, 5, 3, 5, 3, 5, 4, 6, 4,
- 6, 4,
- };
-
- static static_codebook _huff_book_line_128x17_3sub1 = {
- 1, 18,
- _huff_lengthlist_line_128x17_3sub1,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_128x17_3sub2[] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 5, 3, 6, 3, 6, 4, 7, 4, 7, 4, 7, 4, 8, 4,
- 8, 4, 8, 4, 8, 4, 9, 4, 9, 5,10, 5,10, 7,10, 8,
- 10, 8,
- };
-
- static static_codebook _huff_book_line_128x17_3sub2 = {
- 1, 50,
- _huff_lengthlist_line_128x17_3sub2,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_128x17_3sub3[] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 3, 2, 4, 3, 4, 4, 4, 5, 4, 7, 5, 8, 5,11,
- 6,10, 6,12, 7,12, 7,12, 8,12, 8,12,10,12,12,12,
- 12,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- };
-
- static static_codebook _huff_book_line_128x17_3sub3 = {
- 1, 128,
- _huff_lengthlist_line_128x17_3sub3,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_1024x27_class1[] = {
- 2,10, 8,14, 7,12,11,14, 1, 5, 3, 7, 4, 9, 7,13,
- };
-
- static static_codebook _huff_book_line_1024x27_class1 = {
- 1, 16,
- _huff_lengthlist_line_1024x27_class1,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_1024x27_class2[] = {
- 1, 4, 2, 6, 3, 7, 5, 7,
- };
-
- static static_codebook _huff_book_line_1024x27_class2 = {
- 1, 8,
- _huff_lengthlist_line_1024x27_class2,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_1024x27_class3[] = {
- 1, 5, 7,21, 5, 8, 9,21,10, 9,12,20,20,16,20,20,
- 4, 8, 9,20, 6, 8, 9,20,11,11,13,20,20,15,17,20,
- 9,11,14,20, 8,10,15,20,11,13,15,20,20,20,20,20,
- 20,20,20,20,13,20,20,20,18,18,20,20,20,20,20,20,
- 3, 6, 8,20, 6, 7, 9,20,10, 9,12,20,20,20,20,20,
- 5, 7, 9,20, 6, 6, 9,20,10, 9,12,20,20,20,20,20,
- 8,10,13,20, 8, 9,12,20,11,10,12,20,20,20,20,20,
- 18,20,20,20,15,17,18,20,18,17,18,20,20,20,20,20,
- 7,10,12,20, 8, 9,11,20,14,13,14,20,20,20,20,20,
- 6, 9,12,20, 7, 8,11,20,12,11,13,20,20,20,20,20,
- 9,11,15,20, 8,10,14,20,12,11,14,20,20,20,20,20,
- 20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
- 11,16,18,20,15,15,17,20,20,17,20,20,20,20,20,20,
- 9,14,16,20,12,12,15,20,17,15,18,20,20,20,20,20,
- 16,19,18,20,15,16,20,20,17,17,20,20,20,20,20,20,
- 20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
- };
-
- static static_codebook _huff_book_line_1024x27_class3 = {
- 1, 256,
- _huff_lengthlist_line_1024x27_class3,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_1024x27_class4[] = {
- 2, 3, 7,13, 4, 4, 7,15, 8, 6, 9,17,21,16,15,21,
- 2, 5, 7,11, 5, 5, 7,14, 9, 7,10,16,17,15,16,21,
- 4, 7,10,17, 7, 7, 9,15,11, 9,11,16,21,18,15,21,
- 18,21,21,21,15,17,17,19,21,19,18,20,21,21,21,20,
- };
-
- static static_codebook _huff_book_line_1024x27_class4 = {
- 1, 64,
- _huff_lengthlist_line_1024x27_class4,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_1024x27_0sub0[] = {
- 5, 5, 5, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5,
- 6, 5, 6, 5, 6, 5, 6, 5, 7, 5, 7, 5, 7, 5, 7, 5,
- 8, 6, 8, 6, 8, 6, 9, 6, 9, 6,10, 6,10, 6,11, 6,
- 11, 7,11, 7,12, 7,12, 7,12, 7,12, 7,12, 7,12, 7,
- 12, 7,12, 8,13, 8,12, 8,12, 8,13, 8,13, 9,13, 9,
- 13, 9,13, 9,12,10,12,10,13,10,14,11,14,12,14,13,
- 14,13,14,14,15,16,15,15,15,14,15,17,21,22,22,21,
- 22,22,22,22,22,22,21,21,21,21,21,21,21,21,21,21,
- };
-
- static static_codebook _huff_book_line_1024x27_0sub0 = {
- 1, 128,
- _huff_lengthlist_line_1024x27_0sub0,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_1024x27_1sub0[] = {
- 2, 5, 5, 4, 5, 4, 5, 4, 5, 4, 6, 5, 6, 5, 6, 5,
- 6, 5, 7, 5, 7, 6, 8, 6, 8, 6, 8, 6, 9, 6, 9, 6,
- };
-
- static static_codebook _huff_book_line_1024x27_1sub0 = {
- 1, 32,
- _huff_lengthlist_line_1024x27_1sub0,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_1024x27_1sub1[] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 8, 5, 8, 4, 9, 4, 9, 4, 9, 4, 9, 4, 9, 4, 9, 4,
- 9, 4, 9, 4, 9, 4, 8, 4, 8, 4, 9, 5, 9, 5, 9, 5,
- 9, 5, 9, 6,10, 6,10, 7,10, 8,11, 9,11,11,12,13,
- 12,14,13,15,13,15,14,16,14,17,15,17,15,15,16,16,
- 15,16,16,16,15,18,16,15,17,17,19,19,19,19,19,19,
- 19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
- };
-
- static static_codebook _huff_book_line_1024x27_1sub1 = {
- 1, 128,
- _huff_lengthlist_line_1024x27_1sub1,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_1024x27_2sub0[] = {
- 1, 5, 5, 5, 5, 5, 5, 5, 6, 5, 6, 5, 6, 5, 6, 5,
- 6, 6, 7, 7, 7, 7, 8, 7, 8, 8, 9, 8,10, 9,10, 9,
- };
-
- static static_codebook _huff_book_line_1024x27_2sub0 = {
- 1, 32,
- _huff_lengthlist_line_1024x27_2sub0,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_1024x27_2sub1[] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 4, 3, 4, 3, 4, 4, 5, 4, 5, 4, 5, 5, 6, 5, 6, 5,
- 7, 5, 7, 6, 7, 6, 8, 7, 8, 7, 8, 7, 9, 8, 9, 9,
- 9, 9,10,10,10,11, 9,12, 9,12, 9,15,10,14, 9,13,
- 10,13,10,12,10,12,10,13,10,12,11,13,11,14,12,13,
- 13,14,14,13,14,15,14,16,13,13,14,16,16,16,16,16,
- 16,16,16,16,16,16,16,16,16,16,16,16,16,16,15,15,
- };
-
- static static_codebook _huff_book_line_1024x27_2sub1 = {
- 1, 128,
- _huff_lengthlist_line_1024x27_2sub1,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_1024x27_3sub1[] = {
- 0, 4, 5, 4, 5, 3, 5, 3, 5, 3, 5, 4, 4, 4, 4, 5,
- 5, 5,
- };
-
- static static_codebook _huff_book_line_1024x27_3sub1 = {
- 1, 18,
- _huff_lengthlist_line_1024x27_3sub1,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_1024x27_3sub2[] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 3, 3, 4, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6,
- 5, 7, 5, 8, 6, 8, 6, 9, 7,10, 7,10, 8,10, 8,11,
- 9,11,
- };
-
- static static_codebook _huff_book_line_1024x27_3sub2 = {
- 1, 50,
- _huff_lengthlist_line_1024x27_3sub2,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_1024x27_3sub3[] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 3, 7, 3, 8, 3,10, 3, 8, 3, 9, 3, 8, 4, 9,
- 4, 9, 5, 9, 6,10, 6, 9, 7,11, 7,12, 9,13,10,13,
- 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,12,12,12,12,12,12,12,
- 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
- };
-
- static static_codebook _huff_book_line_1024x27_3sub3 = {
- 1, 128,
- _huff_lengthlist_line_1024x27_3sub3,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_1024x27_4sub1[] = {
- 0, 4, 5, 4, 5, 4, 5, 4, 5, 3, 5, 3, 5, 3, 5, 4,
- 5, 4,
- };
-
- static static_codebook _huff_book_line_1024x27_4sub1 = {
- 1, 18,
- _huff_lengthlist_line_1024x27_4sub1,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_1024x27_4sub2[] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 4, 2, 4, 2, 5, 3, 5, 4, 6, 6, 6, 7, 7, 8,
- 7, 8, 7, 8, 7, 9, 8, 9, 8, 9, 8,10, 8,11, 9,12,
- 9,12,
- };
-
- static static_codebook _huff_book_line_1024x27_4sub2 = {
- 1, 50,
- _huff_lengthlist_line_1024x27_4sub2,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_1024x27_4sub3[] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 2, 5, 2, 6, 3, 6, 4, 7, 4, 7, 5, 9, 5,11,
- 6,11, 6,11, 7,11, 6,11, 6,11, 9,11, 8,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,10,10,10,10,10,10,
- };
-
- static static_codebook _huff_book_line_1024x27_4sub3 = {
- 1, 128,
- _huff_lengthlist_line_1024x27_4sub3,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_2048x27_class1[] = {
- 2, 6, 8, 9, 7,11,13,13, 1, 3, 5, 5, 6, 6,12,10,
- };
-
- static static_codebook _huff_book_line_2048x27_class1 = {
- 1, 16,
- _huff_lengthlist_line_2048x27_class1,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_2048x27_class2[] = {
- 1, 2, 3, 6, 4, 7, 5, 7,
- };
-
- static static_codebook _huff_book_line_2048x27_class2 = {
- 1, 8,
- _huff_lengthlist_line_2048x27_class2,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_2048x27_class3[] = {
- 3, 3, 6,16, 5, 5, 7,16, 9, 8,11,16,16,16,16,16,
- 5, 5, 8,16, 5, 5, 7,16, 8, 7, 9,16,16,16,16,16,
- 9, 9,12,16, 6, 8,11,16, 9,10,11,16,16,16,16,16,
- 16,16,16,16,13,16,16,16,15,16,16,16,16,16,16,16,
- 5, 4, 7,16, 6, 5, 8,16, 9, 8,10,16,16,16,16,16,
- 5, 5, 7,15, 5, 4, 6,15, 7, 6, 8,16,16,16,16,16,
- 9, 9,11,15, 7, 7, 9,16, 8, 8, 9,16,16,16,16,16,
- 16,16,16,16,15,15,15,16,15,15,14,16,16,16,16,16,
- 8, 8,11,16, 8, 9,10,16,11,10,14,16,16,16,16,16,
- 6, 8,10,16, 6, 7,10,16, 8, 8,11,16,14,16,16,16,
- 10,11,14,16, 9, 9,11,16,10,10,11,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,15,16,16,16,16,16,16,16,16,16,16,16,
- 12,16,15,16,12,14,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,16,16,16,16,16,16,16,16,16,
- };
-
- static static_codebook _huff_book_line_2048x27_class3 = {
- 1, 256,
- _huff_lengthlist_line_2048x27_class3,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_2048x27_class4[] = {
- 2, 4, 7,13, 4, 5, 7,15, 8, 7,10,16,16,14,16,16,
- 2, 4, 7,16, 3, 4, 7,14, 8, 8,10,16,16,16,15,16,
- 6, 8,11,16, 7, 7, 9,16,11, 9,13,16,16,16,15,16,
- 16,16,16,16,14,16,16,16,16,16,16,16,16,16,16,16,
- };
-
- static static_codebook _huff_book_line_2048x27_class4 = {
- 1, 64,
- _huff_lengthlist_line_2048x27_class4,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_2048x27_0sub0[] = {
- 5, 5, 5, 5, 5, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5,
- 6, 5, 7, 5, 7, 5, 7, 5, 8, 5, 8, 5, 8, 5, 9, 5,
- 9, 6,10, 6,10, 6,11, 6,11, 6,11, 6,11, 6,11, 6,
- 11, 6,11, 6,12, 7,11, 7,11, 7,11, 7,11, 7,10, 7,
- 11, 7,11, 7,12, 7,11, 8,11, 8,11, 8,11, 8,13, 8,
- 12, 9,11, 9,11, 9,11,10,12,10,12, 9,12,10,12,11,
- 14,12,16,12,12,11,14,16,17,17,17,17,17,17,17,17,
- 17,17,17,17,17,17,17,17,17,17,17,17,16,16,16,16,
- };
-
- static static_codebook _huff_book_line_2048x27_0sub0 = {
- 1, 128,
- _huff_lengthlist_line_2048x27_0sub0,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_2048x27_1sub0[] = {
- 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 6, 6, 6, 6, 6, 6, 7, 6, 7, 6, 7, 6, 7, 6,
- };
-
- static static_codebook _huff_book_line_2048x27_1sub0 = {
- 1, 32,
- _huff_lengthlist_line_2048x27_1sub0,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_2048x27_1sub1[] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 6, 5, 7, 5, 7, 4, 7, 4, 8, 4, 8, 4, 8, 4, 8, 3,
- 8, 4, 9, 4, 9, 4, 9, 4, 9, 4, 9, 5, 9, 5, 9, 6,
- 9, 7, 9, 8, 9, 9, 9,10, 9,11, 9,14, 9,15,10,15,
- 10,15,10,15,10,15,11,15,10,14,12,14,11,14,13,14,
- 13,15,15,15,12,15,15,15,13,15,13,15,13,15,15,15,
- 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,14,
- };
-
- static static_codebook _huff_book_line_2048x27_1sub1 = {
- 1, 128,
- _huff_lengthlist_line_2048x27_1sub1,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_2048x27_2sub0[] = {
- 2, 4, 5, 4, 5, 4, 5, 4, 5, 5, 5, 5, 5, 5, 6, 5,
- 6, 5, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8,
- };
-
- static static_codebook _huff_book_line_2048x27_2sub0 = {
- 1, 32,
- _huff_lengthlist_line_2048x27_2sub0,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_2048x27_2sub1[] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 3, 4, 3, 4, 3, 4, 4, 5, 4, 5, 5, 5, 6, 6, 6, 7,
- 6, 8, 6, 8, 6, 9, 7,10, 7,10, 7,10, 7,12, 7,12,
- 7,12, 9,12,11,12,10,12,10,12,11,12,12,12,10,12,
- 10,12,10,12, 9,12,11,12,12,12,12,12,11,12,11,12,
- 12,12,12,12,12,12,12,12,10,10,12,12,12,12,12,10,
- 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
- };
-
- static static_codebook _huff_book_line_2048x27_2sub1 = {
- 1, 128,
- _huff_lengthlist_line_2048x27_2sub1,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_2048x27_3sub1[] = {
- 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 5, 5,
- };
-
- static static_codebook _huff_book_line_2048x27_3sub1 = {
- 1, 18,
- _huff_lengthlist_line_2048x27_3sub1,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_2048x27_3sub2[] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 3, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6,
- 6, 7, 6, 7, 6, 8, 6, 9, 7, 9, 7, 9, 9,11, 9,12,
- 10,12,
- };
-
- static static_codebook _huff_book_line_2048x27_3sub2 = {
- 1, 50,
- _huff_lengthlist_line_2048x27_3sub2,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_2048x27_3sub3[] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 3, 6, 3, 7, 3, 7, 5, 7, 7, 7, 7, 7, 6, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- };
-
- static static_codebook _huff_book_line_2048x27_3sub3 = {
- 1, 128,
- _huff_lengthlist_line_2048x27_3sub3,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_2048x27_4sub1[] = {
- 0, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 4, 5, 4, 5, 4,
- 4, 5,
- };
-
- static static_codebook _huff_book_line_2048x27_4sub1 = {
- 1, 18,
- _huff_lengthlist_line_2048x27_4sub1,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_2048x27_4sub2[] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 3, 2, 4, 3, 4, 4, 4, 5, 5, 6, 5, 6, 5, 7,
- 6, 6, 6, 7, 7, 7, 8, 9, 9, 9,12,10,11,10,10,12,
- 10,10,
- };
-
- static static_codebook _huff_book_line_2048x27_4sub2 = {
- 1, 50,
- _huff_lengthlist_line_2048x27_4sub2,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_2048x27_4sub3[] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 3, 6, 5, 7, 5, 7, 7, 7, 7, 7, 5, 7, 5, 7,
- 5, 7, 5, 7, 7, 7, 7, 7, 4, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- };
-
- static static_codebook _huff_book_line_2048x27_4sub3 = {
- 1, 128,
- _huff_lengthlist_line_2048x27_4sub3,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_256x4low_class0[] = {
- 4, 5, 6,11, 5, 5, 6,10, 7, 7, 6, 6,14,13, 9, 9,
- 6, 6, 6,10, 6, 6, 6, 9, 8, 7, 7, 9,14,12, 8,11,
- 8, 7, 7,11, 8, 8, 7,11, 9, 9, 7, 9,13,11, 9,13,
- 19,19,18,19,15,16,16,19,11,11,10,13,10,10, 9,15,
- 5, 5, 6,13, 6, 6, 6,11, 8, 7, 6, 7,14,11,10,11,
- 6, 6, 6,12, 7, 6, 6,11, 8, 7, 7,11,13,11, 9,11,
- 9, 7, 6,12, 8, 7, 6,12, 9, 8, 8,11,13,10, 7,13,
- 19,19,17,19,17,14,14,19,12,10, 8,12,13,10, 9,16,
- 7, 8, 7,12, 7, 7, 7,11, 8, 7, 7, 8,12,12,11,11,
- 8, 8, 7,12, 8, 7, 6,11, 8, 7, 7,10,10,11,10,11,
- 9, 8, 8,13, 9, 8, 7,12,10, 9, 7,11, 9, 8, 7,11,
- 18,18,15,18,18,16,17,18,15,11,10,18,11, 9, 9,18,
- 16,16,13,16,12,11,10,16,12,11, 9, 6,15,12,11,13,
- 16,16,14,14,13,11,12,16,12, 9, 9,13,13,10,10,12,
- 17,18,17,17,14,15,14,16,14,12,14,15,12,10,11,12,
- 18,18,18,18,18,18,18,18,18,12,13,18,16,11, 9,18,
- };
-
- static static_codebook _huff_book_line_256x4low_class0 = {
- 1, 256,
- _huff_lengthlist_line_256x4low_class0,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_256x4low_0sub0[] = {
- 1, 3, 2, 3,
- };
-
- static static_codebook _huff_book_line_256x4low_0sub0 = {
- 1, 4,
- _huff_lengthlist_line_256x4low_0sub0,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_256x4low_0sub1[] = {
- 0, 0, 0, 0, 2, 3, 2, 3, 3, 3,
- };
-
- static static_codebook _huff_book_line_256x4low_0sub1 = {
- 1, 10,
- _huff_lengthlist_line_256x4low_0sub1,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_256x4low_0sub2[] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 4, 3, 4,
- 4, 4, 4, 4, 5, 5, 5, 6, 6,
- };
-
- static static_codebook _huff_book_line_256x4low_0sub2 = {
- 1, 25,
- _huff_lengthlist_line_256x4low_0sub2,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist_line_256x4low_0sub3[] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 2, 4, 3, 5, 4,
- 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 7, 7, 8, 6, 9,
- 7,12,11,16,13,16,12,15,13,15,12,14,12,15,15,15,
- };
-
- static static_codebook _huff_book_line_256x4low_0sub3 = {
- 1, 64,
- _huff_lengthlist_line_256x4low_0sub3,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
- /********* End of inlined file: floor_books.h *********/
-
- static static_codebook *_floor_128x4_books[]={
- &_huff_book_line_128x4_class0,
- &_huff_book_line_128x4_0sub0,
- &_huff_book_line_128x4_0sub1,
- &_huff_book_line_128x4_0sub2,
- &_huff_book_line_128x4_0sub3,
- };
- static static_codebook *_floor_256x4_books[]={
- &_huff_book_line_256x4_class0,
- &_huff_book_line_256x4_0sub0,
- &_huff_book_line_256x4_0sub1,
- &_huff_book_line_256x4_0sub2,
- &_huff_book_line_256x4_0sub3,
- };
- static static_codebook *_floor_128x7_books[]={
- &_huff_book_line_128x7_class0,
- &_huff_book_line_128x7_class1,
-
- &_huff_book_line_128x7_0sub1,
- &_huff_book_line_128x7_0sub2,
- &_huff_book_line_128x7_0sub3,
- &_huff_book_line_128x7_1sub1,
- &_huff_book_line_128x7_1sub2,
- &_huff_book_line_128x7_1sub3,
- };
- static static_codebook *_floor_256x7_books[]={
- &_huff_book_line_256x7_class0,
- &_huff_book_line_256x7_class1,
-
- &_huff_book_line_256x7_0sub1,
- &_huff_book_line_256x7_0sub2,
- &_huff_book_line_256x7_0sub3,
- &_huff_book_line_256x7_1sub1,
- &_huff_book_line_256x7_1sub2,
- &_huff_book_line_256x7_1sub3,
- };
- static static_codebook *_floor_128x11_books[]={
- &_huff_book_line_128x11_class1,
- &_huff_book_line_128x11_class2,
- &_huff_book_line_128x11_class3,
-
- &_huff_book_line_128x11_0sub0,
- &_huff_book_line_128x11_1sub0,
- &_huff_book_line_128x11_1sub1,
- &_huff_book_line_128x11_2sub1,
- &_huff_book_line_128x11_2sub2,
- &_huff_book_line_128x11_2sub3,
- &_huff_book_line_128x11_3sub1,
- &_huff_book_line_128x11_3sub2,
- &_huff_book_line_128x11_3sub3,
- };
- static static_codebook *_floor_128x17_books[]={
- &_huff_book_line_128x17_class1,
- &_huff_book_line_128x17_class2,
- &_huff_book_line_128x17_class3,
-
- &_huff_book_line_128x17_0sub0,
- &_huff_book_line_128x17_1sub0,
- &_huff_book_line_128x17_1sub1,
- &_huff_book_line_128x17_2sub1,
- &_huff_book_line_128x17_2sub2,
- &_huff_book_line_128x17_2sub3,
- &_huff_book_line_128x17_3sub1,
- &_huff_book_line_128x17_3sub2,
- &_huff_book_line_128x17_3sub3,
- };
- static static_codebook *_floor_256x4low_books[]={
- &_huff_book_line_256x4low_class0,
- &_huff_book_line_256x4low_0sub0,
- &_huff_book_line_256x4low_0sub1,
- &_huff_book_line_256x4low_0sub2,
- &_huff_book_line_256x4low_0sub3,
- };
- static static_codebook *_floor_1024x27_books[]={
- &_huff_book_line_1024x27_class1,
- &_huff_book_line_1024x27_class2,
- &_huff_book_line_1024x27_class3,
- &_huff_book_line_1024x27_class4,
-
- &_huff_book_line_1024x27_0sub0,
- &_huff_book_line_1024x27_1sub0,
- &_huff_book_line_1024x27_1sub1,
- &_huff_book_line_1024x27_2sub0,
- &_huff_book_line_1024x27_2sub1,
- &_huff_book_line_1024x27_3sub1,
- &_huff_book_line_1024x27_3sub2,
- &_huff_book_line_1024x27_3sub3,
- &_huff_book_line_1024x27_4sub1,
- &_huff_book_line_1024x27_4sub2,
- &_huff_book_line_1024x27_4sub3,
- };
- static static_codebook *_floor_2048x27_books[]={
- &_huff_book_line_2048x27_class1,
- &_huff_book_line_2048x27_class2,
- &_huff_book_line_2048x27_class3,
- &_huff_book_line_2048x27_class4,
-
- &_huff_book_line_2048x27_0sub0,
- &_huff_book_line_2048x27_1sub0,
- &_huff_book_line_2048x27_1sub1,
- &_huff_book_line_2048x27_2sub0,
- &_huff_book_line_2048x27_2sub1,
- &_huff_book_line_2048x27_3sub1,
- &_huff_book_line_2048x27_3sub2,
- &_huff_book_line_2048x27_3sub3,
- &_huff_book_line_2048x27_4sub1,
- &_huff_book_line_2048x27_4sub2,
- &_huff_book_line_2048x27_4sub3,
- };
-
- static static_codebook *_floor_512x17_books[]={
- &_huff_book_line_512x17_class1,
- &_huff_book_line_512x17_class2,
- &_huff_book_line_512x17_class3,
-
- &_huff_book_line_512x17_0sub0,
- &_huff_book_line_512x17_1sub0,
- &_huff_book_line_512x17_1sub1,
- &_huff_book_line_512x17_2sub1,
- &_huff_book_line_512x17_2sub2,
- &_huff_book_line_512x17_2sub3,
- &_huff_book_line_512x17_3sub1,
- &_huff_book_line_512x17_3sub2,
- &_huff_book_line_512x17_3sub3,
- };
-
- static static_codebook **_floor_books[10]={
- _floor_128x4_books,
- _floor_256x4_books,
- _floor_128x7_books,
- _floor_256x7_books,
- _floor_128x11_books,
- _floor_128x17_books,
- _floor_256x4low_books,
- _floor_1024x27_books,
- _floor_2048x27_books,
- _floor_512x17_books,
- };
-
- static vorbis_info_floor1 _floor[10]={
- /* 128 x 4 */
- {
- 1,{0},{4},{2},{0},
- {{1,2,3,4}},
- 4,{0,128, 33,8,16,70},
-
- 60,30,500, 1.,18., -1
- },
- /* 256 x 4 */
- {
- 1,{0},{4},{2},{0},
- {{1,2,3,4}},
- 4,{0,256, 66,16,32,140},
-
- 60,30,500, 1.,18., -1
- },
- /* 128 x 7 */
- {
- 2,{0,1},{3,4},{2,2},{0,1},
- {{-1,2,3,4},{-1,5,6,7}},
- 4,{0,128, 14,4,58, 2,8,28,90},
-
- 60,30,500, 1.,18., -1
- },
- /* 256 x 7 */
- {
- 2,{0,1},{3,4},{2,2},{0,1},
- {{-1,2,3,4},{-1,5,6,7}},
- 4,{0,256, 28,8,116, 4,16,56,180},
-
- 60,30,500, 1.,18., -1
- },
- /* 128 x 11 */
- {
- 4,{0,1,2,3},{2,3,3,3},{0,1,2,2},{-1,0,1,2},
- {{3},{4,5},{-1,6,7,8},{-1,9,10,11}},
-
- 2,{0,128, 8,33, 4,16,70, 2,6,12, 23,46,90},
-
- 60,30,500, 1,18., -1
- },
- /* 128 x 17 */
- {
- 6,{0,1,1,2,3,3},{2,3,3,3},{0,1,2,2},{-1,0,1,2},
- {{3},{4,5},{-1,6,7,8},{-1,9,10,11}},
- 2,{0,128, 12,46, 4,8,16, 23,33,70, 2,6,10, 14,19,28, 39,58,90},
-
- 60,30,500, 1,18., -1
- },
- /* 256 x 4 (low bitrate version) */
- {
- 1,{0},{4},{2},{0},
- {{1,2,3,4}},
- 4,{0,256, 66,16,32,140},
-
- 60,30,500, 1.,18., -1
- },
- /* 1024 x 27 */
- {
- 8,{0,1,2,2,3,3,4,4},{3,4,3,4,3},{0,1,1,2,2},{-1,0,1,2,3},
- {{4},{5,6},{7,8},{-1,9,10,11},{-1,12,13,14}},
- 2,{0,1024, 93,23,372, 6,46,186,750, 14,33,65, 130,260,556,
- 3,10,18,28, 39,55,79,111, 158,220,312, 464,650,850},
-
- 60,30,500, 3,18., -1 /* lowpass */
- },
- /* 2048 x 27 */
- {
- 8,{0,1,2,2,3,3,4,4},{3,4,3,4,3},{0,1,1,2,2},{-1,0,1,2,3},
- {{4},{5,6},{7,8},{-1,9,10,11},{-1,12,13,14}},
- 2,{0,2048, 186,46,744, 12,92,372,1500, 28,66,130, 260,520,1112,
- 6,20,36,56, 78,110,158,222, 316,440,624, 928,1300,1700},
-
- 60,30,500, 3,18., -1 /* lowpass */
- },
- /* 512 x 17 */
- {
- 6,{0,1,1,2,3,3},{2,3,3,3},{0,1,2,2},{-1,0,1,2},
- {{3},{4,5},{-1,6,7,8},{-1,9,10,11}},
- 2,{0,512, 46,186, 16,33,65, 93,130,278,
- 7,23,39, 55,79,110, 156,232,360},
-
- 60,30,500, 1,18., -1 /* lowpass! */
- },
-
- };
- /********* End of inlined file: floor_all.h *********/
-
- /********* Start of inlined file: residue_44.h *********/
-
- /********* Start of inlined file: res_books_stereo.h *********/
-
- static long _vq_quantlist__16c0_s_p1_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__16c0_s_p1_0[] = {
- 1, 4, 4, 0, 0, 0, 0, 0, 0, 5, 7, 7, 0, 0, 0, 0,
- 0, 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 5, 8, 8, 0, 0, 0, 0, 0, 0, 8, 9,10, 0, 0, 0,
- 0, 0, 0, 7, 9,10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 5, 8, 8, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0,
- 0, 0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 8, 8, 0, 0, 0, 0,
- 0, 0, 8,10,10, 0, 0, 0, 0, 0, 0, 8,10,10, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7,10,10, 0, 0, 0,
- 0, 0, 0, 9, 9,12, 0, 0, 0, 0, 0, 0,10,12,11, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7,10,10, 0, 0,
- 0, 0, 0, 0, 9,12,10, 0, 0, 0, 0, 0, 0,10,11,12,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 5, 8, 8, 0, 0, 0, 0, 0, 0, 8,10,10, 0, 0,
- 0, 0, 0, 0, 8,10,10, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 7,10,10, 0, 0, 0, 0, 0, 0,10,12,11, 0,
- 0, 0, 0, 0, 0, 9,10,12, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 7,10,10, 0, 0, 0, 0, 0, 0,10,11,12,
- 0, 0, 0, 0, 0, 0, 9,12, 9, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,
- };
-
- static float _vq_quantthresh__16c0_s_p1_0[] = {
- -0.5, 0.5,
- };
-
- static long _vq_quantmap__16c0_s_p1_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__16c0_s_p1_0 = {
- _vq_quantthresh__16c0_s_p1_0,
- _vq_quantmap__16c0_s_p1_0,
- 3,
- 3
- };
-
- static static_codebook _16c0_s_p1_0 = {
- 8, 6561,
- _vq_lengthlist__16c0_s_p1_0,
- 1, -535822336, 1611661312, 2, 0,
- _vq_quantlist__16c0_s_p1_0,
- NULL,
- &_vq_auxt__16c0_s_p1_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16c0_s_p2_0[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__16c0_s_p2_0[] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,
- };
-
- static float _vq_quantthresh__16c0_s_p2_0[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__16c0_s_p2_0[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__16c0_s_p2_0 = {
- _vq_quantthresh__16c0_s_p2_0,
- _vq_quantmap__16c0_s_p2_0,
- 5,
- 5
- };
-
- static static_codebook _16c0_s_p2_0 = {
- 4, 625,
- _vq_lengthlist__16c0_s_p2_0,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__16c0_s_p2_0,
- NULL,
- &_vq_auxt__16c0_s_p2_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16c0_s_p3_0[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__16c0_s_p3_0[] = {
- 1, 4, 4, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 6, 6, 7, 6, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 4, 6, 6, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 9, 9,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 6, 6, 6, 9, 9, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,
- };
-
- static float _vq_quantthresh__16c0_s_p3_0[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__16c0_s_p3_0[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__16c0_s_p3_0 = {
- _vq_quantthresh__16c0_s_p3_0,
- _vq_quantmap__16c0_s_p3_0,
- 5,
- 5
- };
-
- static static_codebook _16c0_s_p3_0 = {
- 4, 625,
- _vq_lengthlist__16c0_s_p3_0,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__16c0_s_p3_0,
- NULL,
- &_vq_auxt__16c0_s_p3_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16c0_s_p4_0[] = {
- 4,
- 3,
- 5,
- 2,
- 6,
- 1,
- 7,
- 0,
- 8,
- };
-
- static long _vq_lengthlist__16c0_s_p4_0[] = {
- 1, 3, 2, 7, 8, 0, 0, 0, 0, 0, 0, 0, 6, 6, 0, 0,
- 0, 0, 0, 0, 0, 6, 6, 0, 0, 0, 0, 0, 0, 0, 7, 7,
- 0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 0, 0, 0, 0, 0,
- 8, 8, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0,
- 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,
- };
-
- static float _vq_quantthresh__16c0_s_p4_0[] = {
- -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5,
- };
-
- static long _vq_quantmap__16c0_s_p4_0[] = {
- 7, 5, 3, 1, 0, 2, 4, 6,
- 8,
- };
-
- static encode_aux_threshmatch _vq_auxt__16c0_s_p4_0 = {
- _vq_quantthresh__16c0_s_p4_0,
- _vq_quantmap__16c0_s_p4_0,
- 9,
- 9
- };
-
- static static_codebook _16c0_s_p4_0 = {
- 2, 81,
- _vq_lengthlist__16c0_s_p4_0,
- 1, -531628032, 1611661312, 4, 0,
- _vq_quantlist__16c0_s_p4_0,
- NULL,
- &_vq_auxt__16c0_s_p4_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16c0_s_p5_0[] = {
- 4,
- 3,
- 5,
- 2,
- 6,
- 1,
- 7,
- 0,
- 8,
- };
-
- static long _vq_lengthlist__16c0_s_p5_0[] = {
- 1, 3, 3, 6, 6, 6, 6, 8, 8, 0, 0, 0, 7, 7, 7, 7,
- 8, 8, 0, 0, 0, 7, 7, 7, 7, 8, 8, 0, 0, 0, 7, 7,
- 8, 8, 9, 9, 0, 0, 0, 7, 7, 8, 8, 9, 9, 0, 0, 0,
- 8, 9, 8, 8,10,10, 0, 0, 0, 8, 8, 8, 8,10,10, 0,
- 0, 0,10,10, 9, 9,10,10, 0, 0, 0, 0, 0, 9, 9,10,
- 10,
- };
-
- static float _vq_quantthresh__16c0_s_p5_0[] = {
- -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5,
- };
-
- static long _vq_quantmap__16c0_s_p5_0[] = {
- 7, 5, 3, 1, 0, 2, 4, 6,
- 8,
- };
-
- static encode_aux_threshmatch _vq_auxt__16c0_s_p5_0 = {
- _vq_quantthresh__16c0_s_p5_0,
- _vq_quantmap__16c0_s_p5_0,
- 9,
- 9
- };
-
- static static_codebook _16c0_s_p5_0 = {
- 2, 81,
- _vq_lengthlist__16c0_s_p5_0,
- 1, -531628032, 1611661312, 4, 0,
- _vq_quantlist__16c0_s_p5_0,
- NULL,
- &_vq_auxt__16c0_s_p5_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16c0_s_p6_0[] = {
- 8,
- 7,
- 9,
- 6,
- 10,
- 5,
- 11,
- 4,
- 12,
- 3,
- 13,
- 2,
- 14,
- 1,
- 15,
- 0,
- 16,
- };
-
- static long _vq_lengthlist__16c0_s_p6_0[] = {
- 1, 3, 4, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9,10,10,11,
- 11, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10,10,10,11,
- 11,11, 0, 0, 0, 6, 6, 8, 8, 9, 9, 9, 9,10,10,11,
- 11,11,11, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10,10,
- 11,11,12,12, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10,
- 10,11,11,12,12, 0, 0, 0, 8, 8, 9, 9,10,10,10,10,
- 11,11,12,12,12,12, 0, 0, 0, 8, 8, 9, 9,10,10,10,
- 10,11,11,12,12,12,13, 0, 0, 0, 9, 9, 9, 9,10,10,
- 10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0,10,10,10,
- 10,10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, 9, 9,
- 10,10,11,11,12,12,13,13,13,13, 0, 0, 0, 0, 0, 9,
- 9,10,10,11,11,12,12,13,13,13,14, 0, 0, 0, 0, 0,
- 10,10,10,11,11,11,12,12,13,13,13,14, 0, 0, 0, 0,
- 0, 0, 0,10,10,11,11,12,12,13,13,14,14, 0, 0, 0,
- 0, 0, 0, 0,11,11,12,12,13,13,13,13,14,14, 0, 0,
- 0, 0, 0, 0, 0,11,11,12,12,12,13,13,14,15,14, 0,
- 0, 0, 0, 0, 0, 0,12,12,12,12,13,13,13,14,14,15,
- 0, 0, 0, 0, 0, 0, 0, 0, 0,12,12,13,13,14,13,14,
- 14,
- };
-
- static float _vq_quantthresh__16c0_s_p6_0[] = {
- -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5,
- 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5,
- };
-
- static long _vq_quantmap__16c0_s_p6_0[] = {
- 15, 13, 11, 9, 7, 5, 3, 1,
- 0, 2, 4, 6, 8, 10, 12, 14,
- 16,
- };
-
- static encode_aux_threshmatch _vq_auxt__16c0_s_p6_0 = {
- _vq_quantthresh__16c0_s_p6_0,
- _vq_quantmap__16c0_s_p6_0,
- 17,
- 17
- };
-
- static static_codebook _16c0_s_p6_0 = {
- 2, 289,
- _vq_lengthlist__16c0_s_p6_0,
- 1, -529530880, 1611661312, 5, 0,
- _vq_quantlist__16c0_s_p6_0,
- NULL,
- &_vq_auxt__16c0_s_p6_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16c0_s_p7_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__16c0_s_p7_0[] = {
- 1, 4, 4, 6, 6, 6, 7, 6, 6, 4, 7, 7,11,10,10,11,
- 11,10, 4, 7, 7,10,10,10,11,10,10, 6,10,10,11,11,
- 11,11,11,10, 6, 9, 9,11,12,12,11, 9, 9, 6, 9,10,
- 11,12,12,11, 9,10, 7,11,11,11,11,11,12,13,12, 6,
- 9,10,11,10,10,12,13,13, 6,10, 9,11,10,10,11,12,
- 13,
- };
-
- static float _vq_quantthresh__16c0_s_p7_0[] = {
- -5.5, 5.5,
- };
-
- static long _vq_quantmap__16c0_s_p7_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__16c0_s_p7_0 = {
- _vq_quantthresh__16c0_s_p7_0,
- _vq_quantmap__16c0_s_p7_0,
- 3,
- 3
- };
-
- static static_codebook _16c0_s_p7_0 = {
- 4, 81,
- _vq_lengthlist__16c0_s_p7_0,
- 1, -529137664, 1618345984, 2, 0,
- _vq_quantlist__16c0_s_p7_0,
- NULL,
- &_vq_auxt__16c0_s_p7_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16c0_s_p7_1[] = {
- 5,
- 4,
- 6,
- 3,
- 7,
- 2,
- 8,
- 1,
- 9,
- 0,
- 10,
- };
-
- static long _vq_lengthlist__16c0_s_p7_1[] = {
- 1, 3, 4, 6, 6, 7, 7, 8, 8, 8, 8,10,10,10, 7, 7,
- 8, 8, 8, 9, 9, 9,10,10,10, 6, 7, 8, 8, 8, 8, 9,
- 8,10,10,10, 7, 7, 8, 8, 9, 9, 9, 9,10,10,10, 7,
- 7, 8, 8, 9, 9, 8, 9,10,10,10, 8, 8, 9, 9, 9, 9,
- 9, 9,11,11,11, 8, 8, 9, 9, 9, 9, 9,10,10,11,11,
- 9, 9, 9, 9, 9, 9, 9,10,11,11,11,10,11, 9, 9, 9,
- 9,10, 9,11,11,11,10,11,10,10, 9, 9,10,10,11,11,
- 11,11,11, 9, 9, 9, 9,10,10,
- };
-
- static float _vq_quantthresh__16c0_s_p7_1[] = {
- -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5,
- 3.5, 4.5,
- };
-
- static long _vq_quantmap__16c0_s_p7_1[] = {
- 9, 7, 5, 3, 1, 0, 2, 4,
- 6, 8, 10,
- };
-
- static encode_aux_threshmatch _vq_auxt__16c0_s_p7_1 = {
- _vq_quantthresh__16c0_s_p7_1,
- _vq_quantmap__16c0_s_p7_1,
- 11,
- 11
- };
-
- static static_codebook _16c0_s_p7_1 = {
- 2, 121,
- _vq_lengthlist__16c0_s_p7_1,
- 1, -531365888, 1611661312, 4, 0,
- _vq_quantlist__16c0_s_p7_1,
- NULL,
- &_vq_auxt__16c0_s_p7_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16c0_s_p8_0[] = {
- 6,
- 5,
- 7,
- 4,
- 8,
- 3,
- 9,
- 2,
- 10,
- 1,
- 11,
- 0,
- 12,
- };
-
- static long _vq_lengthlist__16c0_s_p8_0[] = {
- 1, 4, 4, 7, 7, 7, 7, 7, 6, 8, 8,10,10, 6, 5, 6,
- 8, 8, 8, 8, 8, 8, 8, 9,10,10, 7, 6, 6, 8, 8, 8,
- 8, 8, 8, 8, 8,10,10, 0, 8, 8, 8, 8, 9, 8, 9, 9,
- 9,10,10,10, 0, 9, 8, 8, 8, 9, 9, 8, 8, 9, 9,10,
- 10, 0,12,11, 8, 8, 9, 9, 9, 9,10,10,11,10, 0,12,
- 13, 8, 8, 9,10, 9, 9,11,11,11,12, 0, 0, 0, 8, 8,
- 8, 8,10, 9,12,13,12,14, 0, 0, 0, 8, 8, 8, 9,10,
- 10,12,12,13,14, 0, 0, 0,13,13, 9, 9,11,11, 0, 0,
- 14, 0, 0, 0, 0,14,14,10,10,12,11,12,14,14,14, 0,
- 0, 0, 0, 0,11,11,13,13,14,13,14,14, 0, 0, 0, 0,
- 0,12,13,13,12,13,14,14,14,
- };
-
- static float _vq_quantthresh__16c0_s_p8_0[] = {
- -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5,
- 12.5, 17.5, 22.5, 27.5,
- };
-
- static long _vq_quantmap__16c0_s_p8_0[] = {
- 11, 9, 7, 5, 3, 1, 0, 2,
- 4, 6, 8, 10, 12,
- };
-
- static encode_aux_threshmatch _vq_auxt__16c0_s_p8_0 = {
- _vq_quantthresh__16c0_s_p8_0,
- _vq_quantmap__16c0_s_p8_0,
- 13,
- 13
- };
-
- static static_codebook _16c0_s_p8_0 = {
- 2, 169,
- _vq_lengthlist__16c0_s_p8_0,
- 1, -526516224, 1616117760, 4, 0,
- _vq_quantlist__16c0_s_p8_0,
- NULL,
- &_vq_auxt__16c0_s_p8_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16c0_s_p8_1[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__16c0_s_p8_1[] = {
- 1, 4, 3, 5, 5, 7, 7, 7, 6, 6, 7, 7, 7, 5, 5, 7,
- 7, 7, 6, 6, 7, 7, 7, 6, 6,
- };
-
- static float _vq_quantthresh__16c0_s_p8_1[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__16c0_s_p8_1[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__16c0_s_p8_1 = {
- _vq_quantthresh__16c0_s_p8_1,
- _vq_quantmap__16c0_s_p8_1,
- 5,
- 5
- };
-
- static static_codebook _16c0_s_p8_1 = {
- 2, 25,
- _vq_lengthlist__16c0_s_p8_1,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__16c0_s_p8_1,
- NULL,
- &_vq_auxt__16c0_s_p8_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16c0_s_p9_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__16c0_s_p9_0[] = {
- 1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7,
- };
-
- static float _vq_quantthresh__16c0_s_p9_0[] = {
- -157.5, 157.5,
- };
-
- static long _vq_quantmap__16c0_s_p9_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__16c0_s_p9_0 = {
- _vq_quantthresh__16c0_s_p9_0,
- _vq_quantmap__16c0_s_p9_0,
- 3,
- 3
- };
-
- static static_codebook _16c0_s_p9_0 = {
- 4, 81,
- _vq_lengthlist__16c0_s_p9_0,
- 1, -518803456, 1628680192, 2, 0,
- _vq_quantlist__16c0_s_p9_0,
- NULL,
- &_vq_auxt__16c0_s_p9_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16c0_s_p9_1[] = {
- 7,
- 6,
- 8,
- 5,
- 9,
- 4,
- 10,
- 3,
- 11,
- 2,
- 12,
- 1,
- 13,
- 0,
- 14,
- };
-
- static long _vq_lengthlist__16c0_s_p9_1[] = {
- 1, 5, 5, 5, 5, 9,11,11,10,10,10,10,10,10,10, 7,
- 6, 6, 6, 6,10,10,10,10,10,10,10,10,10,10, 7, 6,
- 6, 6, 6,10, 9,10,10,10,10,10,10,10,10,10, 7, 7,
- 8, 9,10,10,10,10,10,10,10,10,10,10,10, 8, 7,10,
- 10,10, 9,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,
- };
-
- static float _vq_quantthresh__16c0_s_p9_1[] = {
- -136.5, -115.5, -94.5, -73.5, -52.5, -31.5, -10.5, 10.5,
- 31.5, 52.5, 73.5, 94.5, 115.5, 136.5,
- };
-
- static long _vq_quantmap__16c0_s_p9_1[] = {
- 13, 11, 9, 7, 5, 3, 1, 0,
- 2, 4, 6, 8, 10, 12, 14,
- };
-
- static encode_aux_threshmatch _vq_auxt__16c0_s_p9_1 = {
- _vq_quantthresh__16c0_s_p9_1,
- _vq_quantmap__16c0_s_p9_1,
- 15,
- 15
- };
-
- static static_codebook _16c0_s_p9_1 = {
- 2, 225,
- _vq_lengthlist__16c0_s_p9_1,
- 1, -520986624, 1620377600, 4, 0,
- _vq_quantlist__16c0_s_p9_1,
- NULL,
- &_vq_auxt__16c0_s_p9_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16c0_s_p9_2[] = {
- 10,
- 9,
- 11,
- 8,
- 12,
- 7,
- 13,
- 6,
- 14,
- 5,
- 15,
- 4,
- 16,
- 3,
- 17,
- 2,
- 18,
- 1,
- 19,
- 0,
- 20,
- };
-
- static long _vq_lengthlist__16c0_s_p9_2[] = {
- 1, 5, 5, 7, 8, 8, 7, 9, 9, 9,12,12,11,12,12,10,
- 10,11,12,12,12,11,12,12, 8, 9, 8, 7, 9,10,10,11,
- 11,10,11,12,10,12,10,12,12,12,11,12,11, 9, 8, 8,
- 9,10, 9, 8, 9,10,12,12,11,11,12,11,10,11,12,11,
- 12,12, 8, 9, 9, 9,10,11,12,11,12,11,11,11,11,12,
- 12,11,11,12,12,11,11, 9, 9, 8, 9, 9,11, 9, 9,10,
- 9,11,11,11,11,12,11,11,10,12,12,12, 9,12,11,10,
- 11,11,11,11,12,12,12,11,11,11,12,10,12,12,12,10,
- 10, 9,10, 9,10,10, 9, 9, 9,10,10,12,10,11,11, 9,
- 11,11,10,11,11,11,10,10,10, 9, 9,10,10, 9, 9,10,
- 11,11,10,11,10,11,10,11,11,10,11,11,11,10, 9,10,
- 10, 9,10, 9, 9,11, 9, 9,11,10,10,11,11,10,10,11,
- 10,11, 8, 9,11,11,10, 9,10,11,11,10,11,11,10,10,
- 10,11,10, 9,10,10,11, 9,10,10, 9,11,10,10,10,10,
- 11,10,11,11, 9,11,10,11,10,10,11,11,10,10,10, 9,
- 10,10,11,11,11, 9,10,10,10,10,10,11,10,10,10, 9,
- 10,10,11,10,10,10,10,10, 9,10,11,10,10,10,10,11,
- 11,11,10,10,10,10,10,11,10,11,10,11,10,10,10, 9,
- 11,11,10,10,10,11,11,10,10,10,10,10,10,10,10,11,
- 11, 9,10,10,10,11,10,11,10,10,10,11, 9,10,11,10,
- 11,10,10, 9,10,10,10,11,10,11,10,10,10,10,10,11,
- 11,10,11,11,10,10,11,11,10, 9, 9,10,10,10,10,10,
- 9,11, 9,10,10,10,11,11,10,10,10,10,11,11,11,10,
- 9, 9,10,10,11,10,10,10,10,10,11,11,11,10,10,10,
- 11,11,11, 9,10,10,10,10, 9,10, 9,10,11,10,11,10,
- 10,11,11,10,11,11,11,11,11,10,11,10,10,10, 9,11,
- 11,10,11,11,11,11,11,11,11,11,11,10,11,10,10,10,
- 10,11,10,10,11, 9,10,10,10,
- };
-
- static float _vq_quantthresh__16c0_s_p9_2[] = {
- -9.5, -8.5, -7.5, -6.5, -5.5, -4.5, -3.5, -2.5,
- -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5.5,
- 6.5, 7.5, 8.5, 9.5,
- };
-
- static long _vq_quantmap__16c0_s_p9_2[] = {
- 19, 17, 15, 13, 11, 9, 7, 5,
- 3, 1, 0, 2, 4, 6, 8, 10,
- 12, 14, 16, 18, 20,
- };
-
- static encode_aux_threshmatch _vq_auxt__16c0_s_p9_2 = {
- _vq_quantthresh__16c0_s_p9_2,
- _vq_quantmap__16c0_s_p9_2,
- 21,
- 21
- };
-
- static static_codebook _16c0_s_p9_2 = {
- 2, 441,
- _vq_lengthlist__16c0_s_p9_2,
- 1, -529268736, 1611661312, 5, 0,
- _vq_quantlist__16c0_s_p9_2,
- NULL,
- &_vq_auxt__16c0_s_p9_2,
- NULL,
- 0
- };
-
- static long _huff_lengthlist__16c0_s_single[] = {
- 3, 4,19, 7, 9, 7, 8,11, 9,12, 4, 1,19, 6, 7, 7,
- 8,10,11,13,18,18,18,18,18,18,18,18,18,18, 8, 6,
- 18, 8, 9, 9,11,12,14,18, 9, 6,18, 9, 7, 8, 9,11,
- 12,18, 7, 6,18, 8, 7, 7, 7, 9,11,17, 8, 8,18, 9,
- 7, 6, 6, 8,11,17,10,10,18,12, 9, 8, 7, 9,12,18,
- 13,15,18,15,13,11,10,11,15,18,14,18,18,18,18,18,
- 16,16,18,18,
- };
-
- static static_codebook _huff_book__16c0_s_single = {
- 2, 100,
- _huff_lengthlist__16c0_s_single,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist__16c1_s_long[] = {
- 2, 5,20, 7,10, 7, 8,10,11,11, 4, 2,20, 5, 8, 6,
- 7, 9,10,10,20,20,20,20,19,19,19,19,19,19, 7, 5,
- 19, 6,10, 7, 9,11,13,17,11, 8,19,10, 7, 7, 8,10,
- 11,15, 7, 5,19, 7, 7, 5, 6, 9,11,16, 7, 6,19, 8,
- 7, 6, 6, 7, 9,13, 9, 9,19,11, 9, 8, 6, 7, 8,13,
- 12,14,19,16,13,10, 9, 8, 9,13,14,17,19,18,18,17,
- 12,11,11,13,
- };
-
- static static_codebook _huff_book__16c1_s_long = {
- 2, 100,
- _huff_lengthlist__16c1_s_long,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16c1_s_p1_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__16c1_s_p1_0[] = {
- 1, 5, 5, 0, 0, 0, 0, 0, 0, 5, 7, 7, 0, 0, 0, 0,
- 0, 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 5, 8, 7, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, 0,
- 0, 0, 0, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 5, 7, 8, 0, 0, 0, 0, 0, 0, 7, 9, 8, 0, 0,
- 0, 0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 8, 7, 0, 0, 0, 0,
- 0, 0, 8, 9, 9, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, 0,
- 0, 0, 0, 9, 9,11, 0, 0, 0, 0, 0, 0, 9,11,10, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0,
- 0, 0, 0, 0, 8,11, 9, 0, 0, 0, 0, 0, 0, 9,10,11,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 5, 7, 8, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0,
- 0, 0, 0, 0, 8, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 9,11,10, 0,
- 0, 0, 0, 0, 0, 8, 9,11, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 9,10,11,
- 0, 0, 0, 0, 0, 0, 9,11, 9, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,
- };
-
- static float _vq_quantthresh__16c1_s_p1_0[] = {
- -0.5, 0.5,
- };
-
- static long _vq_quantmap__16c1_s_p1_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__16c1_s_p1_0 = {
- _vq_quantthresh__16c1_s_p1_0,
- _vq_quantmap__16c1_s_p1_0,
- 3,
- 3
- };
-
- static static_codebook _16c1_s_p1_0 = {
- 8, 6561,
- _vq_lengthlist__16c1_s_p1_0,
- 1, -535822336, 1611661312, 2, 0,
- _vq_quantlist__16c1_s_p1_0,
- NULL,
- &_vq_auxt__16c1_s_p1_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16c1_s_p2_0[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__16c1_s_p2_0[] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,
- };
-
- static float _vq_quantthresh__16c1_s_p2_0[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__16c1_s_p2_0[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__16c1_s_p2_0 = {
- _vq_quantthresh__16c1_s_p2_0,
- _vq_quantmap__16c1_s_p2_0,
- 5,
- 5
- };
-
- static static_codebook _16c1_s_p2_0 = {
- 4, 625,
- _vq_lengthlist__16c1_s_p2_0,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__16c1_s_p2_0,
- NULL,
- &_vq_auxt__16c1_s_p2_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16c1_s_p3_0[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__16c1_s_p3_0[] = {
- 1, 4, 4, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 5, 5, 7, 7, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 4, 5, 5, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 9, 9,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 6, 7, 7, 9, 9, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,
- };
-
- static float _vq_quantthresh__16c1_s_p3_0[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__16c1_s_p3_0[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__16c1_s_p3_0 = {
- _vq_quantthresh__16c1_s_p3_0,
- _vq_quantmap__16c1_s_p3_0,
- 5,
- 5
- };
-
- static static_codebook _16c1_s_p3_0 = {
- 4, 625,
- _vq_lengthlist__16c1_s_p3_0,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__16c1_s_p3_0,
- NULL,
- &_vq_auxt__16c1_s_p3_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16c1_s_p4_0[] = {
- 4,
- 3,
- 5,
- 2,
- 6,
- 1,
- 7,
- 0,
- 8,
- };
-
- static long _vq_lengthlist__16c1_s_p4_0[] = {
- 1, 2, 3, 7, 7, 0, 0, 0, 0, 0, 0, 0, 6, 6, 0, 0,
- 0, 0, 0, 0, 0, 6, 6, 0, 0, 0, 0, 0, 0, 0, 7, 7,
- 0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 0, 0, 0, 0, 0,
- 8, 8, 0, 0, 0, 0, 0, 0, 0, 8, 9, 0, 0, 0, 0, 0,
- 0, 0,10,10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,
- };
-
- static float _vq_quantthresh__16c1_s_p4_0[] = {
- -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5,
- };
-
- static long _vq_quantmap__16c1_s_p4_0[] = {
- 7, 5, 3, 1, 0, 2, 4, 6,
- 8,
- };
-
- static encode_aux_threshmatch _vq_auxt__16c1_s_p4_0 = {
- _vq_quantthresh__16c1_s_p4_0,
- _vq_quantmap__16c1_s_p4_0,
- 9,
- 9
- };
-
- static static_codebook _16c1_s_p4_0 = {
- 2, 81,
- _vq_lengthlist__16c1_s_p4_0,
- 1, -531628032, 1611661312, 4, 0,
- _vq_quantlist__16c1_s_p4_0,
- NULL,
- &_vq_auxt__16c1_s_p4_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16c1_s_p5_0[] = {
- 4,
- 3,
- 5,
- 2,
- 6,
- 1,
- 7,
- 0,
- 8,
- };
-
- static long _vq_lengthlist__16c1_s_p5_0[] = {
- 1, 3, 3, 5, 5, 6, 6, 8, 8, 0, 0, 0, 7, 7, 7, 7,
- 9, 9, 0, 0, 0, 7, 7, 7, 7, 9, 9, 0, 0, 0, 8, 8,
- 8, 8, 9, 9, 0, 0, 0, 8, 8, 8, 8,10,10, 0, 0, 0,
- 9, 9, 8, 8,10,10, 0, 0, 0, 9, 9, 8, 8,10,10, 0,
- 0, 0,10,10, 9, 9,10,10, 0, 0, 0, 0, 0, 9, 9,10,
- 10,
- };
-
- static float _vq_quantthresh__16c1_s_p5_0[] = {
- -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5,
- };
-
- static long _vq_quantmap__16c1_s_p5_0[] = {
- 7, 5, 3, 1, 0, 2, 4, 6,
- 8,
- };
-
- static encode_aux_threshmatch _vq_auxt__16c1_s_p5_0 = {
- _vq_quantthresh__16c1_s_p5_0,
- _vq_quantmap__16c1_s_p5_0,
- 9,
- 9
- };
-
- static static_codebook _16c1_s_p5_0 = {
- 2, 81,
- _vq_lengthlist__16c1_s_p5_0,
- 1, -531628032, 1611661312, 4, 0,
- _vq_quantlist__16c1_s_p5_0,
- NULL,
- &_vq_auxt__16c1_s_p5_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16c1_s_p6_0[] = {
- 8,
- 7,
- 9,
- 6,
- 10,
- 5,
- 11,
- 4,
- 12,
- 3,
- 13,
- 2,
- 14,
- 1,
- 15,
- 0,
- 16,
- };
-
- static long _vq_lengthlist__16c1_s_p6_0[] = {
- 1, 3, 3, 6, 6, 8, 8, 9, 9, 9, 9,10,10,11,11,12,
- 12, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10,10,11,11,
- 12,12, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10,10,11,
- 11,12,12, 0, 0, 0, 8, 8, 8, 9,10, 9,10,10,10,10,
- 11,11,12,12, 0, 0, 0, 8, 8, 9, 9,10,10,10,10,11,
- 11,11,12,12,12, 0, 0, 0, 8, 8, 9, 9,10,10,10,10,
- 11,11,12,12,12,12, 0, 0, 0, 8, 8, 9, 9,10,10,10,
- 10,11,11,12,12,13,13, 0, 0, 0, 9, 9, 9, 9,10,10,
- 10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, 9, 9,10,
- 10,10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, 9, 9,
- 10,10,11,11,12,12,12,12,13,13, 0, 0, 0, 0, 0, 9,
- 9,10,10,11,11,12,12,12,12,13,13, 0, 0, 0, 0, 0,
- 10,10,11,10,11,11,12,12,13,13,13,13, 0, 0, 0, 0,
- 0, 0, 0,10,10,11,11,12,12,13,13,13,13, 0, 0, 0,
- 0, 0, 0, 0,11,11,12,12,12,12,13,13,14,14, 0, 0,
- 0, 0, 0, 0, 0,11,11,12,12,12,12,13,13,14,14, 0,
- 0, 0, 0, 0, 0, 0,12,12,12,12,13,13,13,13,14,14,
- 0, 0, 0, 0, 0, 0, 0, 0, 0,12,12,13,13,13,13,14,
- 14,
- };
-
- static float _vq_quantthresh__16c1_s_p6_0[] = {
- -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5,
- 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5,
- };
-
- static long _vq_quantmap__16c1_s_p6_0[] = {
- 15, 13, 11, 9, 7, 5, 3, 1,
- 0, 2, 4, 6, 8, 10, 12, 14,
- 16,
- };
-
- static encode_aux_threshmatch _vq_auxt__16c1_s_p6_0 = {
- _vq_quantthresh__16c1_s_p6_0,
- _vq_quantmap__16c1_s_p6_0,
- 17,
- 17
- };
-
- static static_codebook _16c1_s_p6_0 = {
- 2, 289,
- _vq_lengthlist__16c1_s_p6_0,
- 1, -529530880, 1611661312, 5, 0,
- _vq_quantlist__16c1_s_p6_0,
- NULL,
- &_vq_auxt__16c1_s_p6_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16c1_s_p7_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__16c1_s_p7_0[] = {
- 1, 4, 4, 6, 6, 6, 7, 6, 6, 4, 7, 7,10, 9,10,10,
- 10, 9, 4, 7, 7,10,10,10,11,10,10, 6,10,10,11,11,
- 11,11,10,10, 6,10, 9,11,11,11,11,10,10, 6,10,10,
- 11,11,11,11,10,10, 7,11,11,11,11,11,12,12,11, 6,
- 10,10,11,10,10,11,11,11, 6,10,10,10,11,10,11,11,
- 11,
- };
-
- static float _vq_quantthresh__16c1_s_p7_0[] = {
- -5.5, 5.5,
- };
-
- static long _vq_quantmap__16c1_s_p7_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__16c1_s_p7_0 = {
- _vq_quantthresh__16c1_s_p7_0,
- _vq_quantmap__16c1_s_p7_0,
- 3,
- 3
- };
-
- static static_codebook _16c1_s_p7_0 = {
- 4, 81,
- _vq_lengthlist__16c1_s_p7_0,
- 1, -529137664, 1618345984, 2, 0,
- _vq_quantlist__16c1_s_p7_0,
- NULL,
- &_vq_auxt__16c1_s_p7_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16c1_s_p7_1[] = {
- 5,
- 4,
- 6,
- 3,
- 7,
- 2,
- 8,
- 1,
- 9,
- 0,
- 10,
- };
-
- static long _vq_lengthlist__16c1_s_p7_1[] = {
- 2, 3, 3, 5, 6, 7, 7, 7, 7, 8, 8,10,10,10, 6, 6,
- 7, 7, 8, 8, 8, 8,10,10,10, 6, 6, 7, 7, 8, 8, 8,
- 8,10,10,10, 7, 7, 7, 7, 8, 8, 8, 8,10,10,10, 7,
- 7, 7, 7, 8, 8, 8, 8,10,10,10, 7, 7, 8, 8, 8, 8,
- 8, 8,10,10,10, 7, 7, 8, 8, 8, 8, 8, 8,10,10,10,
- 8, 8, 8, 8, 8, 8, 9, 9,10,10,10,10,10, 8, 8, 8,
- 8, 9, 9,10,10,10,10,10, 9, 9, 8, 8, 9, 9,10,10,
- 10,10,10, 8, 8, 8, 8, 9, 9,
- };
-
- static float _vq_quantthresh__16c1_s_p7_1[] = {
- -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5,
- 3.5, 4.5,
- };
-
- static long _vq_quantmap__16c1_s_p7_1[] = {
- 9, 7, 5, 3, 1, 0, 2, 4,
- 6, 8, 10,
- };
-
- static encode_aux_threshmatch _vq_auxt__16c1_s_p7_1 = {
- _vq_quantthresh__16c1_s_p7_1,
- _vq_quantmap__16c1_s_p7_1,
- 11,
- 11
- };
-
- static static_codebook _16c1_s_p7_1 = {
- 2, 121,
- _vq_lengthlist__16c1_s_p7_1,
- 1, -531365888, 1611661312, 4, 0,
- _vq_quantlist__16c1_s_p7_1,
- NULL,
- &_vq_auxt__16c1_s_p7_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16c1_s_p8_0[] = {
- 6,
- 5,
- 7,
- 4,
- 8,
- 3,
- 9,
- 2,
- 10,
- 1,
- 11,
- 0,
- 12,
- };
-
- static long _vq_lengthlist__16c1_s_p8_0[] = {
- 1, 4, 4, 6, 6, 7, 7, 7, 7, 8, 8, 9, 9, 6, 5, 5,
- 7, 8, 8, 9, 8, 8, 9, 9,10,11, 6, 5, 5, 8, 8, 9,
- 9, 8, 8, 9,10,10,11, 0, 8, 8, 8, 9, 9, 9, 9, 9,
- 10,10,11,11, 0, 9, 9, 9, 8, 9, 9, 9, 9,10,10,11,
- 11, 0,13,13, 9, 9,10,10,10,10,11,11,12,12, 0,14,
- 13, 9, 9,10,10,10,10,11,11,12,12, 0, 0, 0,10,10,
- 9, 9,11,11,12,12,13,12, 0, 0, 0,10,10, 9, 9,10,
- 10,12,12,13,13, 0, 0, 0,13,14,11,10,11,11,12,12,
- 13,14, 0, 0, 0,14,14,10,10,11,11,12,12,13,13, 0,
- 0, 0, 0, 0,12,12,12,12,13,13,14,15, 0, 0, 0, 0,
- 0,12,12,12,12,13,13,14,15,
- };
-
- static float _vq_quantthresh__16c1_s_p8_0[] = {
- -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5,
- 12.5, 17.5, 22.5, 27.5,
- };
-
- static long _vq_quantmap__16c1_s_p8_0[] = {
- 11, 9, 7, 5, 3, 1, 0, 2,
- 4, 6, 8, 10, 12,
- };
-
- static encode_aux_threshmatch _vq_auxt__16c1_s_p8_0 = {
- _vq_quantthresh__16c1_s_p8_0,
- _vq_quantmap__16c1_s_p8_0,
- 13,
- 13
- };
-
- static static_codebook _16c1_s_p8_0 = {
- 2, 169,
- _vq_lengthlist__16c1_s_p8_0,
- 1, -526516224, 1616117760, 4, 0,
- _vq_quantlist__16c1_s_p8_0,
- NULL,
- &_vq_auxt__16c1_s_p8_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16c1_s_p8_1[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__16c1_s_p8_1[] = {
- 2, 3, 3, 5, 5, 6, 6, 6, 5, 5, 6, 6, 6, 5, 5, 6,
- 6, 6, 5, 5, 6, 6, 6, 5, 5,
- };
-
- static float _vq_quantthresh__16c1_s_p8_1[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__16c1_s_p8_1[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__16c1_s_p8_1 = {
- _vq_quantthresh__16c1_s_p8_1,
- _vq_quantmap__16c1_s_p8_1,
- 5,
- 5
- };
-
- static static_codebook _16c1_s_p8_1 = {
- 2, 25,
- _vq_lengthlist__16c1_s_p8_1,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__16c1_s_p8_1,
- NULL,
- &_vq_auxt__16c1_s_p8_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16c1_s_p9_0[] = {
- 6,
- 5,
- 7,
- 4,
- 8,
- 3,
- 9,
- 2,
- 10,
- 1,
- 11,
- 0,
- 12,
- };
-
- static long _vq_lengthlist__16c1_s_p9_0[] = {
- 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8,
- };
-
- static float _vq_quantthresh__16c1_s_p9_0[] = {
- -1732.5, -1417.5, -1102.5, -787.5, -472.5, -157.5, 157.5, 472.5,
- 787.5, 1102.5, 1417.5, 1732.5,
- };
-
- static long _vq_quantmap__16c1_s_p9_0[] = {
- 11, 9, 7, 5, 3, 1, 0, 2,
- 4, 6, 8, 10, 12,
- };
-
- static encode_aux_threshmatch _vq_auxt__16c1_s_p9_0 = {
- _vq_quantthresh__16c1_s_p9_0,
- _vq_quantmap__16c1_s_p9_0,
- 13,
- 13
- };
-
- static static_codebook _16c1_s_p9_0 = {
- 2, 169,
- _vq_lengthlist__16c1_s_p9_0,
- 1, -513964032, 1628680192, 4, 0,
- _vq_quantlist__16c1_s_p9_0,
- NULL,
- &_vq_auxt__16c1_s_p9_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16c1_s_p9_1[] = {
- 7,
- 6,
- 8,
- 5,
- 9,
- 4,
- 10,
- 3,
- 11,
- 2,
- 12,
- 1,
- 13,
- 0,
- 14,
- };
-
- static long _vq_lengthlist__16c1_s_p9_1[] = {
- 1, 4, 4, 4, 4, 8, 8,12,13,14,14,14,14,14,14, 6,
- 6, 6, 6, 6,10, 9,14,14,14,14,14,14,14,14, 7, 6,
- 5, 6, 6,10, 9,12,13,13,13,13,13,13,13,13, 7, 7,
- 9, 9,11,11,12,13,13,13,13,13,13,13,13, 7, 7, 8,
- 8,11,12,13,13,13,13,13,13,13,13,13,12,12,10,10,
- 13,12,13,13,13,13,13,13,13,13,13,12,12,10,10,13,
- 13,13,13,13,13,13,13,13,13,13,13,13,13,12,13,12,
- 13,13,13,13,13,13,13,13,13,13,13,13,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,13,13,13,13,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,13,13,13,13,13,13,13,13,
- 13,13,13,13,13,13,13,13,13,12,13,13,13,13,13,13,
- 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
- 13,
- };
-
- static float _vq_quantthresh__16c1_s_p9_1[] = {
- -136.5, -115.5, -94.5, -73.5, -52.5, -31.5, -10.5, 10.5,
- 31.5, 52.5, 73.5, 94.5, 115.5, 136.5,
- };
-
- static long _vq_quantmap__16c1_s_p9_1[] = {
- 13, 11, 9, 7, 5, 3, 1, 0,
- 2, 4, 6, 8, 10, 12, 14,
- };
-
- static encode_aux_threshmatch _vq_auxt__16c1_s_p9_1 = {
- _vq_quantthresh__16c1_s_p9_1,
- _vq_quantmap__16c1_s_p9_1,
- 15,
- 15
- };
-
- static static_codebook _16c1_s_p9_1 = {
- 2, 225,
- _vq_lengthlist__16c1_s_p9_1,
- 1, -520986624, 1620377600, 4, 0,
- _vq_quantlist__16c1_s_p9_1,
- NULL,
- &_vq_auxt__16c1_s_p9_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16c1_s_p9_2[] = {
- 10,
- 9,
- 11,
- 8,
- 12,
- 7,
- 13,
- 6,
- 14,
- 5,
- 15,
- 4,
- 16,
- 3,
- 17,
- 2,
- 18,
- 1,
- 19,
- 0,
- 20,
- };
-
- static long _vq_lengthlist__16c1_s_p9_2[] = {
- 1, 4, 4, 6, 6, 7, 7, 8, 7, 8, 8, 9, 9, 9, 9,10,
- 10,10, 9,10,10,11,12,12, 8, 8, 8, 8, 9, 9, 9, 9,
- 10,10,10,10,10,11,11,10,12,11,11,13,11, 7, 7, 8,
- 8, 8, 8, 9, 9, 9,10,10,10,10, 9,10,10,11,11,12,
- 11,11, 8, 8, 8, 8, 9, 9,10,10,10,10,11,11,11,11,
- 11,11,11,12,11,12,12, 8, 8, 9, 9, 9, 9, 9,10,10,
- 10,10,10,10,11,11,11,11,11,11,12,11, 9, 9, 9, 9,
- 10,10,10,10,11,10,11,11,11,11,11,11,12,12,12,12,
- 11, 9, 9, 9, 9,10,10,10,10,11,11,11,11,11,11,11,
- 11,11,12,12,12,13, 9,10,10, 9,11,10,10,10,10,11,
- 11,11,11,11,10,11,12,11,12,12,11,12,11,10, 9,10,
- 10,11,10,11,11,11,11,11,11,11,11,11,12,12,11,12,
- 12,12,10,10,10,11,10,11,11,11,11,11,11,11,11,11,
- 11,11,12,13,12,12,11, 9,10,10,11,11,10,11,11,11,
- 12,11,11,11,11,11,12,12,13,13,12,13,10,10,12,10,
- 11,11,11,11,11,11,11,11,11,12,12,11,13,12,12,12,
- 12,13,12,11,11,11,11,11,11,12,11,12,11,11,11,11,
- 12,12,13,12,11,12,12,11,11,11,11,11,12,11,11,11,
- 11,12,11,11,12,11,12,13,13,12,12,12,12,11,11,11,
- 11,11,12,11,11,12,11,12,11,11,11,11,13,12,12,12,
- 12,13,11,11,11,12,12,11,11,11,12,11,12,12,12,11,
- 12,13,12,11,11,12,12,11,12,11,11,11,12,12,11,12,
- 11,11,11,12,12,12,12,13,12,13,12,12,12,12,11,11,
- 12,11,11,11,11,11,11,12,12,12,13,12,11,13,13,12,
- 12,11,12,10,11,11,11,11,12,11,12,12,11,12,12,13,
- 12,12,13,12,12,12,12,12,11,12,12,12,11,12,11,11,
- 11,12,13,12,13,13,13,13,13,12,13,13,12,12,13,11,
- 11,11,11,11,12,11,11,12,11,
- };
-
- static float _vq_quantthresh__16c1_s_p9_2[] = {
- -9.5, -8.5, -7.5, -6.5, -5.5, -4.5, -3.5, -2.5,
- -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5.5,
- 6.5, 7.5, 8.5, 9.5,
- };
-
- static long _vq_quantmap__16c1_s_p9_2[] = {
- 19, 17, 15, 13, 11, 9, 7, 5,
- 3, 1, 0, 2, 4, 6, 8, 10,
- 12, 14, 16, 18, 20,
- };
-
- static encode_aux_threshmatch _vq_auxt__16c1_s_p9_2 = {
- _vq_quantthresh__16c1_s_p9_2,
- _vq_quantmap__16c1_s_p9_2,
- 21,
- 21
- };
-
- static static_codebook _16c1_s_p9_2 = {
- 2, 441,
- _vq_lengthlist__16c1_s_p9_2,
- 1, -529268736, 1611661312, 5, 0,
- _vq_quantlist__16c1_s_p9_2,
- NULL,
- &_vq_auxt__16c1_s_p9_2,
- NULL,
- 0
- };
-
- static long _huff_lengthlist__16c1_s_short[] = {
- 5, 6,17, 8,12, 9,10,10,12,13, 5, 2,17, 4, 9, 5,
- 7, 8,11,13,16,16,16,16,16,16,16,16,16,16, 6, 4,
- 16, 5,10, 5, 7,10,14,16,13, 9,16,11, 8, 7, 8, 9,
- 13,16, 7, 4,16, 5, 7, 4, 6, 8,11,13, 8, 6,16, 7,
- 8, 5, 5, 7, 9,13, 9, 8,16, 9, 8, 6, 6, 7, 9,13,
- 11,11,16,10,10, 7, 7, 7, 9,13,13,13,16,13,13, 9,
- 9, 9,10,13,
- };
-
- static static_codebook _huff_book__16c1_s_short = {
- 2, 100,
- _huff_lengthlist__16c1_s_short,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist__16c2_s_long[] = {
- 4, 7, 9, 9, 9, 8, 9,10,15,19, 5, 4, 5, 6, 7, 7,
- 8, 9,14,16, 6, 5, 4, 5, 6, 7, 8,10,12,19, 7, 6,
- 5, 4, 5, 6, 7, 9,11,18, 8, 7, 6, 5, 5, 5, 7, 9,
- 10,17, 8, 7, 7, 5, 5, 5, 6, 7,12,18, 8, 8, 8, 7,
- 7, 5, 5, 7,12,18, 8, 9,10, 9, 9, 7, 6, 7,12,17,
- 14,18,16,16,15,12,11,10,12,18,15,17,18,18,18,15,
- 14,14,16,18,
- };
-
- static static_codebook _huff_book__16c2_s_long = {
- 2, 100,
- _huff_lengthlist__16c2_s_long,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16c2_s_p1_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__16c2_s_p1_0[] = {
- 1, 3, 3, 0, 0, 0, 0, 0, 0, 4, 5, 5, 0, 0, 0, 0,
- 0, 0, 4, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,
- };
-
- static float _vq_quantthresh__16c2_s_p1_0[] = {
- -0.5, 0.5,
- };
-
- static long _vq_quantmap__16c2_s_p1_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__16c2_s_p1_0 = {
- _vq_quantthresh__16c2_s_p1_0,
- _vq_quantmap__16c2_s_p1_0,
- 3,
- 3
- };
-
- static static_codebook _16c2_s_p1_0 = {
- 4, 81,
- _vq_lengthlist__16c2_s_p1_0,
- 1, -535822336, 1611661312, 2, 0,
- _vq_quantlist__16c2_s_p1_0,
- NULL,
- &_vq_auxt__16c2_s_p1_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16c2_s_p2_0[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__16c2_s_p2_0[] = {
- 2, 4, 3, 7, 7, 0, 0, 0, 7, 8, 0, 0, 0, 8, 8, 0,
- 0, 0, 8, 8, 0, 0, 0, 8, 8, 4, 5, 4, 8, 8, 0, 0,
- 0, 8, 8, 0, 0, 0, 8, 8, 0, 0, 0, 9, 9, 0, 0, 0,
- 9, 9, 4, 4, 5, 8, 8, 0, 0, 0, 8, 8, 0, 0, 0, 8,
- 8, 0, 0, 0, 9, 9, 0, 0, 0, 9, 9, 7, 8, 8,10,10,
- 0, 0, 0,12,11, 0, 0, 0,11,11, 0, 0, 0,14,13, 0,
- 0, 0,14,13, 7, 8, 8, 9,10, 0, 0, 0,11,12, 0, 0,
- 0,11,11, 0, 0, 0,14,14, 0, 0, 0,13,14, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8,11,11, 0, 0, 0,
- 11,11, 0, 0, 0,12,11, 0, 0, 0,12,12, 0, 0, 0,13,
- 13, 8, 8, 8,11,11, 0, 0, 0,11,11, 0, 0, 0,11,12,
- 0, 0, 0,12,13, 0, 0, 0,13,13, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 8, 8, 8,12,11, 0, 0, 0,12,11, 0,
- 0, 0,11,11, 0, 0, 0,13,13, 0, 0, 0,13,12, 8, 8,
- 8,11,12, 0, 0, 0,11,12, 0, 0, 0,11,11, 0, 0, 0,
- 13,13, 0, 0, 0,12,13, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 8, 9, 9,14,13, 0, 0, 0,13,12, 0, 0, 0,13,
- 13, 0, 0, 0,13,12, 0, 0, 0,13,13, 8, 9, 9,13,14,
- 0, 0, 0,12,13, 0, 0, 0,13,13, 0, 0, 0,12,13, 0,
- 0, 0,13,13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8,
- 9, 9,14,13, 0, 0, 0,13,13, 0, 0, 0,13,12, 0, 0,
- 0,13,13, 0, 0, 0,13,12, 8, 9, 9,14,14, 0, 0, 0,
- 13,13, 0, 0, 0,12,13, 0, 0, 0,13,13, 0, 0, 0,12,
- 13,
- };
-
- static float _vq_quantthresh__16c2_s_p2_0[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__16c2_s_p2_0[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__16c2_s_p2_0 = {
- _vq_quantthresh__16c2_s_p2_0,
- _vq_quantmap__16c2_s_p2_0,
- 5,
- 5
- };
-
- static static_codebook _16c2_s_p2_0 = {
- 4, 625,
- _vq_lengthlist__16c2_s_p2_0,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__16c2_s_p2_0,
- NULL,
- &_vq_auxt__16c2_s_p2_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16c2_s_p3_0[] = {
- 4,
- 3,
- 5,
- 2,
- 6,
- 1,
- 7,
- 0,
- 8,
- };
-
- static long _vq_lengthlist__16c2_s_p3_0[] = {
- 1, 3, 3, 6, 6, 7, 7, 8, 8, 0, 0, 0, 6, 6, 7, 7,
- 9, 9, 0, 0, 0, 6, 6, 7, 7, 9, 9, 0, 0, 0, 7, 7,
- 8, 8,10,10, 0, 0, 0, 7, 7, 8, 8,10,10, 0, 0, 0,
- 7, 7, 9, 9,10,10, 0, 0, 0, 7, 7, 9, 9,10,10, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,
- };
-
- static float _vq_quantthresh__16c2_s_p3_0[] = {
- -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5,
- };
-
- static long _vq_quantmap__16c2_s_p3_0[] = {
- 7, 5, 3, 1, 0, 2, 4, 6,
- 8,
- };
-
- static encode_aux_threshmatch _vq_auxt__16c2_s_p3_0 = {
- _vq_quantthresh__16c2_s_p3_0,
- _vq_quantmap__16c2_s_p3_0,
- 9,
- 9
- };
-
- static static_codebook _16c2_s_p3_0 = {
- 2, 81,
- _vq_lengthlist__16c2_s_p3_0,
- 1, -531628032, 1611661312, 4, 0,
- _vq_quantlist__16c2_s_p3_0,
- NULL,
- &_vq_auxt__16c2_s_p3_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16c2_s_p4_0[] = {
- 8,
- 7,
- 9,
- 6,
- 10,
- 5,
- 11,
- 4,
- 12,
- 3,
- 13,
- 2,
- 14,
- 1,
- 15,
- 0,
- 16,
- };
-
- static long _vq_lengthlist__16c2_s_p4_0[] = {
- 2, 3, 3, 5, 5, 6, 6, 7, 7, 7, 7, 8, 8, 9, 9,10,
- 10, 0, 0, 0, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9,10,10,
- 11,11, 0, 0, 0, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9,10,
- 10,10,11, 0, 0, 0, 6, 6, 8, 8, 8, 8, 9, 9,10,10,
- 10,11,11,11, 0, 0, 0, 6, 6, 8, 8, 9, 9, 9, 9,10,
- 10,11,11,11,11, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,
- 10,10,11,11,12,12, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9,
- 9,10,10,11,11,12,12, 0, 0, 0, 7, 7, 8, 8, 9, 9,
- 10,10,11,11,12,12,12,12, 0, 0, 0, 0, 0, 8, 8, 9,
- 9,10,10,11,11,12,12,12,12, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,
- };
-
- static float _vq_quantthresh__16c2_s_p4_0[] = {
- -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5,
- 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5,
- };
-
- static long _vq_quantmap__16c2_s_p4_0[] = {
- 15, 13, 11, 9, 7, 5, 3, 1,
- 0, 2, 4, 6, 8, 10, 12, 14,
- 16,
- };
-
- static encode_aux_threshmatch _vq_auxt__16c2_s_p4_0 = {
- _vq_quantthresh__16c2_s_p4_0,
- _vq_quantmap__16c2_s_p4_0,
- 17,
- 17
- };
-
- static static_codebook _16c2_s_p4_0 = {
- 2, 289,
- _vq_lengthlist__16c2_s_p4_0,
- 1, -529530880, 1611661312, 5, 0,
- _vq_quantlist__16c2_s_p4_0,
- NULL,
- &_vq_auxt__16c2_s_p4_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16c2_s_p5_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__16c2_s_p5_0[] = {
- 1, 4, 4, 5, 7, 7, 6, 7, 7, 4, 6, 6,10,10,10,10,
- 10,10, 4, 7, 6,10,10,10,10,10,10, 5, 9, 9, 9,12,
- 11,10,11,12, 7,10,10,12,12,12,12,12,12, 7,10,10,
- 11,12,12,12,12,13, 6,10,10,10,12,12,10,12,12, 7,
- 10,10,11,13,12,12,12,12, 7,10,10,11,12,12,12,12,
- 12,
- };
-
- static float _vq_quantthresh__16c2_s_p5_0[] = {
- -5.5, 5.5,
- };
-
- static long _vq_quantmap__16c2_s_p5_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__16c2_s_p5_0 = {
- _vq_quantthresh__16c2_s_p5_0,
- _vq_quantmap__16c2_s_p5_0,
- 3,
- 3
- };
-
- static static_codebook _16c2_s_p5_0 = {
- 4, 81,
- _vq_lengthlist__16c2_s_p5_0,
- 1, -529137664, 1618345984, 2, 0,
- _vq_quantlist__16c2_s_p5_0,
- NULL,
- &_vq_auxt__16c2_s_p5_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16c2_s_p5_1[] = {
- 5,
- 4,
- 6,
- 3,
- 7,
- 2,
- 8,
- 1,
- 9,
- 0,
- 10,
- };
-
- static long _vq_lengthlist__16c2_s_p5_1[] = {
- 2, 3, 3, 6, 6, 7, 7, 7, 7, 8, 8,11,11,11, 6, 6,
- 7, 7, 8, 8, 8, 8,11,11,11, 6, 6, 7, 7, 8, 8, 8,
- 8,11,11,11, 6, 6, 8, 8, 8, 8, 9, 9,11,11,11, 6,
- 6, 8, 8, 8, 8, 9, 9,11,11,11, 7, 7, 8, 8, 8, 8,
- 8, 8,11,11,11, 7, 7, 8, 8, 8, 8, 8, 9,11,11,11,
- 8, 8, 8, 8, 8, 8, 8, 8,11,11,11,11,11, 8, 8, 8,
- 8, 8, 8,11,11,11,11,11, 8, 8, 8, 8, 8, 8,11,11,
- 11,11,11, 7, 7, 8, 8, 8, 8,
- };
-
- static float _vq_quantthresh__16c2_s_p5_1[] = {
- -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5,
- 3.5, 4.5,
- };
-
- static long _vq_quantmap__16c2_s_p5_1[] = {
- 9, 7, 5, 3, 1, 0, 2, 4,
- 6, 8, 10,
- };
-
- static encode_aux_threshmatch _vq_auxt__16c2_s_p5_1 = {
- _vq_quantthresh__16c2_s_p5_1,
- _vq_quantmap__16c2_s_p5_1,
- 11,
- 11
- };
-
- static static_codebook _16c2_s_p5_1 = {
- 2, 121,
- _vq_lengthlist__16c2_s_p5_1,
- 1, -531365888, 1611661312, 4, 0,
- _vq_quantlist__16c2_s_p5_1,
- NULL,
- &_vq_auxt__16c2_s_p5_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16c2_s_p6_0[] = {
- 6,
- 5,
- 7,
- 4,
- 8,
- 3,
- 9,
- 2,
- 10,
- 1,
- 11,
- 0,
- 12,
- };
-
- static long _vq_lengthlist__16c2_s_p6_0[] = {
- 1, 4, 4, 7, 6, 8, 8, 9, 9,10,10,11,11, 5, 5, 5,
- 7, 7, 9, 9, 9, 9,11,11,12,12, 6, 5, 5, 7, 7, 9,
- 9,10,10,11,11,12,12, 0, 6, 6, 7, 7, 9, 9,10,10,
- 11,11,12,12, 0, 7, 7, 7, 7, 9, 9,10,10,11,12,12,
- 12, 0,11,11, 8, 8,10,10,11,11,12,12,13,13, 0,11,
- 12, 8, 8,10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0,
- };
-
- static float _vq_quantthresh__16c2_s_p6_0[] = {
- -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5,
- 12.5, 17.5, 22.5, 27.5,
- };
-
- static long _vq_quantmap__16c2_s_p6_0[] = {
- 11, 9, 7, 5, 3, 1, 0, 2,
- 4, 6, 8, 10, 12,
- };
-
- static encode_aux_threshmatch _vq_auxt__16c2_s_p6_0 = {
- _vq_quantthresh__16c2_s_p6_0,
- _vq_quantmap__16c2_s_p6_0,
- 13,
- 13
- };
-
- static static_codebook _16c2_s_p6_0 = {
- 2, 169,
- _vq_lengthlist__16c2_s_p6_0,
- 1, -526516224, 1616117760, 4, 0,
- _vq_quantlist__16c2_s_p6_0,
- NULL,
- &_vq_auxt__16c2_s_p6_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16c2_s_p6_1[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__16c2_s_p6_1[] = {
- 2, 3, 3, 5, 5, 6, 6, 6, 5, 5, 6, 6, 6, 5, 5, 6,
- 6, 6, 5, 5, 6, 6, 6, 5, 5,
- };
-
- static float _vq_quantthresh__16c2_s_p6_1[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__16c2_s_p6_1[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__16c2_s_p6_1 = {
- _vq_quantthresh__16c2_s_p6_1,
- _vq_quantmap__16c2_s_p6_1,
- 5,
- 5
- };
-
- static static_codebook _16c2_s_p6_1 = {
- 2, 25,
- _vq_lengthlist__16c2_s_p6_1,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__16c2_s_p6_1,
- NULL,
- &_vq_auxt__16c2_s_p6_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16c2_s_p7_0[] = {
- 6,
- 5,
- 7,
- 4,
- 8,
- 3,
- 9,
- 2,
- 10,
- 1,
- 11,
- 0,
- 12,
- };
-
- static long _vq_lengthlist__16c2_s_p7_0[] = {
- 1, 4, 4, 7, 7, 8, 8, 9, 9,10,10,11,11, 5, 5, 5,
- 8, 8, 9, 9,10,10,11,11,12,12, 6, 5, 5, 8, 8, 9,
- 9,10,10,11,11,12,13,18, 6, 6, 7, 7, 9, 9,10,10,
- 12,12,13,13,18, 6, 6, 7, 7, 9, 9,10,10,12,12,13,
- 13,18,11,10, 8, 8,10,10,11,11,12,12,13,13,18,11,
- 11, 8, 8,10,10,11,11,12,13,13,13,18,18,18,10,11,
- 11,11,12,12,13,13,14,14,18,18,18,11,11,11,11,12,
- 12,13,13,14,14,18,18,18,14,14,12,12,12,12,14,14,
- 15,14,18,18,18,15,15,11,12,12,12,13,13,15,15,18,
- 18,18,18,18,13,13,13,13,13,14,17,16,18,18,18,18,
- 18,13,14,13,13,14,13,15,14,
- };
-
- static float _vq_quantthresh__16c2_s_p7_0[] = {
- -60.5, -49.5, -38.5, -27.5, -16.5, -5.5, 5.5, 16.5,
- 27.5, 38.5, 49.5, 60.5,
- };
-
- static long _vq_quantmap__16c2_s_p7_0[] = {
- 11, 9, 7, 5, 3, 1, 0, 2,
- 4, 6, 8, 10, 12,
- };
-
- static encode_aux_threshmatch _vq_auxt__16c2_s_p7_0 = {
- _vq_quantthresh__16c2_s_p7_0,
- _vq_quantmap__16c2_s_p7_0,
- 13,
- 13
- };
-
- static static_codebook _16c2_s_p7_0 = {
- 2, 169,
- _vq_lengthlist__16c2_s_p7_0,
- 1, -523206656, 1618345984, 4, 0,
- _vq_quantlist__16c2_s_p7_0,
- NULL,
- &_vq_auxt__16c2_s_p7_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16c2_s_p7_1[] = {
- 5,
- 4,
- 6,
- 3,
- 7,
- 2,
- 8,
- 1,
- 9,
- 0,
- 10,
- };
-
- static long _vq_lengthlist__16c2_s_p7_1[] = {
- 2, 4, 4, 6, 6, 7, 7, 7, 7, 7, 7, 9, 9, 9, 6, 6,
- 7, 7, 8, 8, 8, 8, 9, 9, 9, 6, 6, 7, 7, 8, 8, 8,
- 8, 9, 9, 9, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 7,
- 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 7, 7, 7, 7, 8, 8,
- 8, 8, 9, 9, 9, 7, 7, 7, 7, 7, 7, 8, 8, 9, 9, 9,
- 7, 7, 8, 8, 7, 7, 8, 8, 9, 9, 9, 9, 9, 7, 7, 7,
- 7, 8, 8, 9, 9, 9, 9, 9, 8, 8, 7, 7, 8, 8, 9, 9,
- 9, 9, 9, 7, 7, 7, 7, 8, 8,
- };
-
- static float _vq_quantthresh__16c2_s_p7_1[] = {
- -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5,
- 3.5, 4.5,
- };
-
- static long _vq_quantmap__16c2_s_p7_1[] = {
- 9, 7, 5, 3, 1, 0, 2, 4,
- 6, 8, 10,
- };
-
- static encode_aux_threshmatch _vq_auxt__16c2_s_p7_1 = {
- _vq_quantthresh__16c2_s_p7_1,
- _vq_quantmap__16c2_s_p7_1,
- 11,
- 11
- };
-
- static static_codebook _16c2_s_p7_1 = {
- 2, 121,
- _vq_lengthlist__16c2_s_p7_1,
- 1, -531365888, 1611661312, 4, 0,
- _vq_quantlist__16c2_s_p7_1,
- NULL,
- &_vq_auxt__16c2_s_p7_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16c2_s_p8_0[] = {
- 7,
- 6,
- 8,
- 5,
- 9,
- 4,
- 10,
- 3,
- 11,
- 2,
- 12,
- 1,
- 13,
- 0,
- 14,
- };
-
- static long _vq_lengthlist__16c2_s_p8_0[] = {
- 1, 4, 4, 7, 6, 7, 7, 6, 6, 8, 8, 9, 9,10,10, 6,
- 6, 6, 8, 8, 9, 8, 8, 8, 9, 9,11,10,11,11, 7, 6,
- 6, 8, 8, 9, 8, 7, 7, 9, 9,10,10,12,11,14, 8, 8,
- 8, 9, 9, 9, 9, 9,10, 9,10,10,11,13,14, 8, 8, 8,
- 8, 9, 9, 8, 8, 9, 9,10,10,11,12,14,13,11, 9, 9,
- 9, 9, 9, 9, 9,10,11,10,13,12,14,11,13, 8, 9, 9,
- 9, 9, 9,10,10,11,10,13,12,14,14,14, 8, 9, 9, 9,
- 11,11,11,11,11,12,13,13,14,14,14, 9, 8, 9, 9,10,
- 10,12,10,11,12,12,14,14,14,14,11,12,10,10,12,12,
- 12,12,13,14,12,12,14,14,14,12,12, 9,10,11,11,12,
- 14,12,14,14,14,14,14,14,14,14,11,11,12,11,12,14,
- 14,14,14,14,14,14,14,14,14,12,11,11,11,11,14,14,
- 14,14,14,14,14,14,14,14,14,14,13,12,14,14,14,14,
- 14,14,14,14,14,14,14,14,14,12,12,12,13,14,14,13,
- 13,
- };
-
- static float _vq_quantthresh__16c2_s_p8_0[] = {
- -136.5, -115.5, -94.5, -73.5, -52.5, -31.5, -10.5, 10.5,
- 31.5, 52.5, 73.5, 94.5, 115.5, 136.5,
- };
-
- static long _vq_quantmap__16c2_s_p8_0[] = {
- 13, 11, 9, 7, 5, 3, 1, 0,
- 2, 4, 6, 8, 10, 12, 14,
- };
-
- static encode_aux_threshmatch _vq_auxt__16c2_s_p8_0 = {
- _vq_quantthresh__16c2_s_p8_0,
- _vq_quantmap__16c2_s_p8_0,
- 15,
- 15
- };
-
- static static_codebook _16c2_s_p8_0 = {
- 2, 225,
- _vq_lengthlist__16c2_s_p8_0,
- 1, -520986624, 1620377600, 4, 0,
- _vq_quantlist__16c2_s_p8_0,
- NULL,
- &_vq_auxt__16c2_s_p8_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16c2_s_p8_1[] = {
- 10,
- 9,
- 11,
- 8,
- 12,
- 7,
- 13,
- 6,
- 14,
- 5,
- 15,
- 4,
- 16,
- 3,
- 17,
- 2,
- 18,
- 1,
- 19,
- 0,
- 20,
- };
-
- static long _vq_lengthlist__16c2_s_p8_1[] = {
- 2, 4, 4, 6, 6, 7, 7, 7, 7, 8, 7, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8,11,12,11, 7, 7, 8, 8, 8, 8, 9, 9,
- 9, 9, 9, 9, 9, 9, 9,10, 9, 9,11,11,10, 7, 7, 8,
- 8, 8, 8, 9, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,11,
- 11,11, 8, 7, 8, 8, 9, 9, 9, 9, 9, 9,10,10, 9,10,
- 10, 9,10,10,11,11,12, 8, 8, 8, 8, 9, 9, 9, 9, 9,
- 9, 9, 9,10, 9,10,10,10,10,11,11,11, 8, 8, 9, 9,
- 9, 9, 9, 9, 9,10,10,10,10,10,10,10,10,10,11,11,
- 11, 8, 8, 9, 8, 9, 9, 9, 9,10, 9, 9, 9,10,10,10,
- 10, 9,10,11,11,11, 9, 9, 9, 9,10, 9, 9, 9,10,10,
- 9,10, 9,10,10,10,10,10,11,12,11,11,11, 9, 9, 9,
- 9, 9,10,10, 9,10,10,10,10,10,10,10,10,12,11,13,
- 13,11, 9, 9, 9, 9,10,10, 9,10,10,10,10,11,10,10,
- 10,10,11,12,11,12,11, 9, 9, 9,10,10, 9,10,10,10,
- 10,10,10,10,10,10,10,11,11,11,12,11, 9,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,11,12,12,12,
- 11,11,11,10, 9,10,10,10,10,10,10,10,10,11,10,10,
- 10,11,11,11,11,11,11,11,10,10,10,11,10,10,10,10,
- 10,10,10,10,10,10,11,11,11,11,12,12,11,10,10,10,
- 10,10,10,10,10,11,10,10,10,11,10,12,11,11,12,11,
- 11,11,10,10,10,10,10,11,10,10,10,10,10,11,10,10,
- 11,11,11,12,11,12,11,11,12,10,10,10,10,10,10,10,
- 11,10,10,11,10,12,11,11,11,12,11,11,11,11,10,10,
- 10,10,10,10,10,11,11,11,10,11,12,11,11,11,12,11,
- 12,11,12,10,11,10,10,10,10,11,10,10,10,10,10,10,
- 12,11,11,11,11,11,12,12,10,10,10,10,10,11,10,10,
- 11,10,11,11,11,11,11,11,11,11,11,11,11,11,12,11,
- 10,11,10,10,10,10,10,10,10,
- };
-
- static float _vq_quantthresh__16c2_s_p8_1[] = {
- -9.5, -8.5, -7.5, -6.5, -5.5, -4.5, -3.5, -2.5,
- -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5.5,
- 6.5, 7.5, 8.5, 9.5,
- };
-
- static long _vq_quantmap__16c2_s_p8_1[] = {
- 19, 17, 15, 13, 11, 9, 7, 5,
- 3, 1, 0, 2, 4, 6, 8, 10,
- 12, 14, 16, 18, 20,
- };
-
- static encode_aux_threshmatch _vq_auxt__16c2_s_p8_1 = {
- _vq_quantthresh__16c2_s_p8_1,
- _vq_quantmap__16c2_s_p8_1,
- 21,
- 21
- };
-
- static static_codebook _16c2_s_p8_1 = {
- 2, 441,
- _vq_lengthlist__16c2_s_p8_1,
- 1, -529268736, 1611661312, 5, 0,
- _vq_quantlist__16c2_s_p8_1,
- NULL,
- &_vq_auxt__16c2_s_p8_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16c2_s_p9_0[] = {
- 6,
- 5,
- 7,
- 4,
- 8,
- 3,
- 9,
- 2,
- 10,
- 1,
- 11,
- 0,
- 12,
- };
-
- static long _vq_lengthlist__16c2_s_p9_0[] = {
- 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8,
- };
-
- static float _vq_quantthresh__16c2_s_p9_0[] = {
- -5120.5, -4189.5, -3258.5, -2327.5, -1396.5, -465.5, 465.5, 1396.5,
- 2327.5, 3258.5, 4189.5, 5120.5,
- };
-
- static long _vq_quantmap__16c2_s_p9_0[] = {
- 11, 9, 7, 5, 3, 1, 0, 2,
- 4, 6, 8, 10, 12,
- };
-
- static encode_aux_threshmatch _vq_auxt__16c2_s_p9_0 = {
- _vq_quantthresh__16c2_s_p9_0,
- _vq_quantmap__16c2_s_p9_0,
- 13,
- 13
- };
-
- static static_codebook _16c2_s_p9_0 = {
- 2, 169,
- _vq_lengthlist__16c2_s_p9_0,
- 1, -510275072, 1631393792, 4, 0,
- _vq_quantlist__16c2_s_p9_0,
- NULL,
- &_vq_auxt__16c2_s_p9_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16c2_s_p9_1[] = {
- 8,
- 7,
- 9,
- 6,
- 10,
- 5,
- 11,
- 4,
- 12,
- 3,
- 13,
- 2,
- 14,
- 1,
- 15,
- 0,
- 16,
- };
-
- static long _vq_lengthlist__16c2_s_p9_1[] = {
- 1, 5, 5, 9, 8, 7, 7, 7, 6,10,11,11,11,11,11,11,
- 11, 8, 7, 6, 8, 8,10, 9,10,10,10, 9,11,10,10,10,
- 10,10, 8, 6, 6, 8, 8, 9, 8, 9, 8, 9,10,10,10,10,
- 10,10,10,10, 8,10, 9, 9, 9, 9,10,10,10,10,10,10,
- 10,10,10,10,10, 8, 9, 9, 9,10,10, 9,10,10,10,10,
- 10,10,10,10,10,10,10,10, 9, 8, 9, 9,10,10,10,10,
- 10,10,10,10,10,10,10,10, 9, 8, 8, 9, 9,10,10,10,
- 10,10,10,10,10,10,10,10,10,10, 9,10, 9, 9,10,10,
- 10,10,10,10,10,10,10,10,10,10,10, 9, 8, 9, 9,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, 9,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 8,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10, 9,10, 9,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10, 9,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,
- };
-
- static float _vq_quantthresh__16c2_s_p9_1[] = {
- -367.5, -318.5, -269.5, -220.5, -171.5, -122.5, -73.5, -24.5,
- 24.5, 73.5, 122.5, 171.5, 220.5, 269.5, 318.5, 367.5,
- };
-
- static long _vq_quantmap__16c2_s_p9_1[] = {
- 15, 13, 11, 9, 7, 5, 3, 1,
- 0, 2, 4, 6, 8, 10, 12, 14,
- 16,
- };
-
- static encode_aux_threshmatch _vq_auxt__16c2_s_p9_1 = {
- _vq_quantthresh__16c2_s_p9_1,
- _vq_quantmap__16c2_s_p9_1,
- 17,
- 17
- };
-
- static static_codebook _16c2_s_p9_1 = {
- 2, 289,
- _vq_lengthlist__16c2_s_p9_1,
- 1, -518488064, 1622704128, 5, 0,
- _vq_quantlist__16c2_s_p9_1,
- NULL,
- &_vq_auxt__16c2_s_p9_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16c2_s_p9_2[] = {
- 13,
- 12,
- 14,
- 11,
- 15,
- 10,
- 16,
- 9,
- 17,
- 8,
- 18,
- 7,
- 19,
- 6,
- 20,
- 5,
- 21,
- 4,
- 22,
- 3,
- 23,
- 2,
- 24,
- 1,
- 25,
- 0,
- 26,
- };
-
- static long _vq_lengthlist__16c2_s_p9_2[] = {
- 1, 4, 4, 5, 5, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 8, 7, 8, 7, 7, 4, 4,
- };
-
- static float _vq_quantthresh__16c2_s_p9_2[] = {
- -12.5, -11.5, -10.5, -9.5, -8.5, -7.5, -6.5, -5.5,
- -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5,
- 3.5, 4.5, 5.5, 6.5, 7.5, 8.5, 9.5, 10.5,
- 11.5, 12.5,
- };
-
- static long _vq_quantmap__16c2_s_p9_2[] = {
- 25, 23, 21, 19, 17, 15, 13, 11,
- 9, 7, 5, 3, 1, 0, 2, 4,
- 6, 8, 10, 12, 14, 16, 18, 20,
- 22, 24, 26,
- };
-
- static encode_aux_threshmatch _vq_auxt__16c2_s_p9_2 = {
- _vq_quantthresh__16c2_s_p9_2,
- _vq_quantmap__16c2_s_p9_2,
- 27,
- 27
- };
-
- static static_codebook _16c2_s_p9_2 = {
- 1, 27,
- _vq_lengthlist__16c2_s_p9_2,
- 1, -528875520, 1611661312, 5, 0,
- _vq_quantlist__16c2_s_p9_2,
- NULL,
- &_vq_auxt__16c2_s_p9_2,
- NULL,
- 0
- };
-
- static long _huff_lengthlist__16c2_s_short[] = {
- 7,10,11,11,11,14,15,15,17,14, 8, 6, 7, 7, 8, 9,
- 11,11,14,17, 9, 6, 6, 6, 7, 7,10,11,15,16, 9, 6,
- 6, 4, 4, 5, 8, 9,12,16,10, 6, 6, 4, 4, 4, 6, 9,
- 13,16,10, 7, 6, 5, 4, 3, 5, 7,13,16,11, 9, 8, 7,
- 6, 5, 5, 6,12,15,10,10,10, 9, 7, 6, 6, 7,11,15,
- 13,13,13,13,11,10,10, 9,12,16,16,16,16,14,16,15,
- 15,12,14,14,
- };
-
- static static_codebook _huff_book__16c2_s_short = {
- 2, 100,
- _huff_lengthlist__16c2_s_short,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _vq_quantlist__8c0_s_p1_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__8c0_s_p1_0[] = {
- 1, 5, 4, 0, 0, 0, 0, 0, 0, 5, 7, 7, 0, 0, 0, 0,
- 0, 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 5, 8, 8, 0, 0, 0, 0, 0, 0, 7, 8, 9, 0, 0, 0,
- 0, 0, 0, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 5, 8, 8, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0,
- 0, 0, 0, 0, 7, 9, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 8, 8, 0, 0, 0, 0,
- 0, 0, 8,10,10, 0, 0, 0, 0, 0, 0, 8, 9, 9, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7,10, 9, 0, 0, 0,
- 0, 0, 0, 8, 9,11, 0, 0, 0, 0, 0, 0, 9,11,11, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9,10, 0, 0,
- 0, 0, 0, 0, 9,11,10, 0, 0, 0, 0, 0, 0, 9,11,11,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 5, 8, 8, 0, 0, 0, 0, 0, 0, 8, 9, 9, 0, 0,
- 0, 0, 0, 0, 8, 9,10, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 9,11,11, 0,
- 0, 0, 0, 0, 0, 9,10,11, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 7, 9,10, 0, 0, 0, 0, 0, 0, 9,11,11,
- 0, 0, 0, 0, 0, 0, 8,11, 9, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,
- };
-
- static float _vq_quantthresh__8c0_s_p1_0[] = {
- -0.5, 0.5,
- };
-
- static long _vq_quantmap__8c0_s_p1_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__8c0_s_p1_0 = {
- _vq_quantthresh__8c0_s_p1_0,
- _vq_quantmap__8c0_s_p1_0,
- 3,
- 3
- };
-
- static static_codebook _8c0_s_p1_0 = {
- 8, 6561,
- _vq_lengthlist__8c0_s_p1_0,
- 1, -535822336, 1611661312, 2, 0,
- _vq_quantlist__8c0_s_p1_0,
- NULL,
- &_vq_auxt__8c0_s_p1_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__8c0_s_p2_0[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__8c0_s_p2_0[] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,
- };
-
- static float _vq_quantthresh__8c0_s_p2_0[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__8c0_s_p2_0[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__8c0_s_p2_0 = {
- _vq_quantthresh__8c0_s_p2_0,
- _vq_quantmap__8c0_s_p2_0,
- 5,
- 5
- };
-
- static static_codebook _8c0_s_p2_0 = {
- 4, 625,
- _vq_lengthlist__8c0_s_p2_0,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__8c0_s_p2_0,
- NULL,
- &_vq_auxt__8c0_s_p2_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__8c0_s_p3_0[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__8c0_s_p3_0[] = {
- 1, 4, 4, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 5, 6, 7, 7, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 4, 5, 5, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 7, 8, 8,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 6, 7, 7, 8, 8, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,
- };
-
- static float _vq_quantthresh__8c0_s_p3_0[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__8c0_s_p3_0[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__8c0_s_p3_0 = {
- _vq_quantthresh__8c0_s_p3_0,
- _vq_quantmap__8c0_s_p3_0,
- 5,
- 5
- };
-
- static static_codebook _8c0_s_p3_0 = {
- 4, 625,
- _vq_lengthlist__8c0_s_p3_0,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__8c0_s_p3_0,
- NULL,
- &_vq_auxt__8c0_s_p3_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__8c0_s_p4_0[] = {
- 4,
- 3,
- 5,
- 2,
- 6,
- 1,
- 7,
- 0,
- 8,
- };
-
- static long _vq_lengthlist__8c0_s_p4_0[] = {
- 1, 2, 3, 7, 7, 0, 0, 0, 0, 0, 0, 0, 6, 6, 0, 0,
- 0, 0, 0, 0, 0, 6, 6, 0, 0, 0, 0, 0, 0, 0, 7, 7,
- 0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 0, 0, 0, 0, 0,
- 8, 8, 0, 0, 0, 0, 0, 0, 0, 9, 8, 0, 0, 0, 0, 0,
- 0, 0,10,10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,
- };
-
- static float _vq_quantthresh__8c0_s_p4_0[] = {
- -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5,
- };
-
- static long _vq_quantmap__8c0_s_p4_0[] = {
- 7, 5, 3, 1, 0, 2, 4, 6,
- 8,
- };
-
- static encode_aux_threshmatch _vq_auxt__8c0_s_p4_0 = {
- _vq_quantthresh__8c0_s_p4_0,
- _vq_quantmap__8c0_s_p4_0,
- 9,
- 9
- };
-
- static static_codebook _8c0_s_p4_0 = {
- 2, 81,
- _vq_lengthlist__8c0_s_p4_0,
- 1, -531628032, 1611661312, 4, 0,
- _vq_quantlist__8c0_s_p4_0,
- NULL,
- &_vq_auxt__8c0_s_p4_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__8c0_s_p5_0[] = {
- 4,
- 3,
- 5,
- 2,
- 6,
- 1,
- 7,
- 0,
- 8,
- };
-
- static long _vq_lengthlist__8c0_s_p5_0[] = {
- 1, 3, 3, 5, 5, 7, 6, 8, 8, 0, 0, 0, 7, 7, 7, 7,
- 8, 8, 0, 0, 0, 7, 7, 7, 7, 8, 9, 0, 0, 0, 8, 8,
- 8, 8, 9, 9, 0, 0, 0, 8, 8, 8, 8, 9, 9, 0, 0, 0,
- 9, 9, 8, 8,10,10, 0, 0, 0, 9, 9, 8, 8,10,10, 0,
- 0, 0,10,10, 9, 9,10,10, 0, 0, 0, 0, 0, 9, 9,10,
- 10,
- };
-
- static float _vq_quantthresh__8c0_s_p5_0[] = {
- -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5,
- };
-
- static long _vq_quantmap__8c0_s_p5_0[] = {
- 7, 5, 3, 1, 0, 2, 4, 6,
- 8,
- };
-
- static encode_aux_threshmatch _vq_auxt__8c0_s_p5_0 = {
- _vq_quantthresh__8c0_s_p5_0,
- _vq_quantmap__8c0_s_p5_0,
- 9,
- 9
- };
-
- static static_codebook _8c0_s_p5_0 = {
- 2, 81,
- _vq_lengthlist__8c0_s_p5_0,
- 1, -531628032, 1611661312, 4, 0,
- _vq_quantlist__8c0_s_p5_0,
- NULL,
- &_vq_auxt__8c0_s_p5_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__8c0_s_p6_0[] = {
- 8,
- 7,
- 9,
- 6,
- 10,
- 5,
- 11,
- 4,
- 12,
- 3,
- 13,
- 2,
- 14,
- 1,
- 15,
- 0,
- 16,
- };
-
- static long _vq_lengthlist__8c0_s_p6_0[] = {
- 1, 3, 3, 6, 6, 8, 8, 9, 9, 8, 8,10, 9,10,10,11,
- 11, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10,10,11,11,
- 11,12, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10,10,11,
- 11,12,11, 0, 0, 0, 8, 8, 9, 9,10,10, 9, 9,10,10,
- 11,11,12,12, 0, 0, 0, 8, 8, 9, 9,10,10, 9, 9,11,
- 10,11,11,12,12, 0, 0, 0, 9, 9, 9, 9,10,10,10,10,
- 11,11,11,12,12,12, 0, 0, 0, 9, 9, 9, 9,10,10,10,
- 10,11,11,12,12,13,13, 0, 0, 0,10,10,10,10,11,11,
- 10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0,10, 9,10,
- 11,10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, 9, 9,
- 10, 9,10,11,12,12,13,13,14,13, 0, 0, 0, 0, 0, 9,
- 9, 9,10,10,10,11,11,13,12,13,13, 0, 0, 0, 0, 0,
- 10,10,10,10,11,11,12,12,13,13,14,14, 0, 0, 0, 0,
- 0, 0, 0,10,10,11,11,12,12,13,13,13,14, 0, 0, 0,
- 0, 0, 0, 0,11,11,11,11,12,12,13,14,14,14, 0, 0,
- 0, 0, 0, 0, 0,11,11,11,11,12,12,13,13,14,13, 0,
- 0, 0, 0, 0, 0, 0,11,11,12,12,13,13,14,14,14,14,
- 0, 0, 0, 0, 0, 0, 0, 0, 0,12,12,12,12,13,13,14,
- 14,
- };
-
- static float _vq_quantthresh__8c0_s_p6_0[] = {
- -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5,
- 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5,
- };
-
- static long _vq_quantmap__8c0_s_p6_0[] = {
- 15, 13, 11, 9, 7, 5, 3, 1,
- 0, 2, 4, 6, 8, 10, 12, 14,
- 16,
- };
-
- static encode_aux_threshmatch _vq_auxt__8c0_s_p6_0 = {
- _vq_quantthresh__8c0_s_p6_0,
- _vq_quantmap__8c0_s_p6_0,
- 17,
- 17
- };
-
- static static_codebook _8c0_s_p6_0 = {
- 2, 289,
- _vq_lengthlist__8c0_s_p6_0,
- 1, -529530880, 1611661312, 5, 0,
- _vq_quantlist__8c0_s_p6_0,
- NULL,
- &_vq_auxt__8c0_s_p6_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__8c0_s_p7_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__8c0_s_p7_0[] = {
- 1, 4, 4, 7, 6, 6, 7, 6, 6, 4, 7, 7,11, 9,10,12,
- 9,10, 4, 7, 7,10,10,10,11, 9, 9, 6,11,10,11,11,
- 12,11,11,11, 6,10,10,11,11,12,11,10,10, 6, 9,10,
- 11,11,11,11,10,10, 7,10,11,12,11,11,12,11,12, 6,
- 9, 9,10, 9, 9,11,10,10, 6, 9, 9,10,10,10,11,10,
- 10,
- };
-
- static float _vq_quantthresh__8c0_s_p7_0[] = {
- -5.5, 5.5,
- };
-
- static long _vq_quantmap__8c0_s_p7_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__8c0_s_p7_0 = {
- _vq_quantthresh__8c0_s_p7_0,
- _vq_quantmap__8c0_s_p7_0,
- 3,
- 3
- };
-
- static static_codebook _8c0_s_p7_0 = {
- 4, 81,
- _vq_lengthlist__8c0_s_p7_0,
- 1, -529137664, 1618345984, 2, 0,
- _vq_quantlist__8c0_s_p7_0,
- NULL,
- &_vq_auxt__8c0_s_p7_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__8c0_s_p7_1[] = {
- 5,
- 4,
- 6,
- 3,
- 7,
- 2,
- 8,
- 1,
- 9,
- 0,
- 10,
- };
-
- static long _vq_lengthlist__8c0_s_p7_1[] = {
- 1, 3, 3, 6, 6, 8, 8, 9, 9, 9, 9,10,10,10, 7, 7,
- 8, 8, 9, 9, 9, 9,10,10, 9, 7, 7, 8, 8, 9, 9, 9,
- 9,10,10,10, 8, 8, 9, 9, 9, 9, 9, 9,10,10,10, 8,
- 8, 9, 9, 9, 9, 8, 9,10,10,10, 8, 8, 9, 9, 9,10,
- 10,10,10,10,10, 9, 9, 9, 9, 9, 9,10,10,11,10,11,
- 9, 9, 9, 9,10,10,10,10,11,11,11,10,10, 9, 9,10,
- 10,10, 9,11,10,10,10,10,10,10, 9, 9,10,10,11,11,
- 10,10,10, 9, 9, 9,10,10,10,
- };
-
- static float _vq_quantthresh__8c0_s_p7_1[] = {
- -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5,
- 3.5, 4.5,
- };
-
- static long _vq_quantmap__8c0_s_p7_1[] = {
- 9, 7, 5, 3, 1, 0, 2, 4,
- 6, 8, 10,
- };
-
- static encode_aux_threshmatch _vq_auxt__8c0_s_p7_1 = {
- _vq_quantthresh__8c0_s_p7_1,
- _vq_quantmap__8c0_s_p7_1,
- 11,
- 11
- };
-
- static static_codebook _8c0_s_p7_1 = {
- 2, 121,
- _vq_lengthlist__8c0_s_p7_1,
- 1, -531365888, 1611661312, 4, 0,
- _vq_quantlist__8c0_s_p7_1,
- NULL,
- &_vq_auxt__8c0_s_p7_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__8c0_s_p8_0[] = {
- 6,
- 5,
- 7,
- 4,
- 8,
- 3,
- 9,
- 2,
- 10,
- 1,
- 11,
- 0,
- 12,
- };
-
- static long _vq_lengthlist__8c0_s_p8_0[] = {
- 1, 4, 4, 7, 6, 7, 7, 7, 7, 8, 8, 9, 9, 7, 6, 6,
- 7, 7, 8, 8, 7, 7, 8, 9,10,10, 7, 6, 6, 7, 7, 8,
- 7, 7, 7, 9, 9,10,12, 0, 8, 8, 8, 8, 8, 9, 8, 8,
- 9, 9,10,10, 0, 8, 8, 8, 8, 8, 9, 8, 9, 9, 9,11,
- 10, 0, 0,13, 9, 8, 9, 9, 9, 9,10,10,11,11, 0,13,
- 0, 9, 9, 9, 9, 9, 9,11,10,11,11, 0, 0, 0, 8, 9,
- 10, 9,10,10,13,11,12,12, 0, 0, 0, 8, 9, 9, 9,10,
- 10,13,12,12,13, 0, 0, 0,12, 0,10,10,12,11,10,11,
- 12,12, 0, 0, 0,13,13,10,10,10,11,12, 0,13, 0, 0,
- 0, 0, 0, 0,13,11, 0,12,12,12,13,12, 0, 0, 0, 0,
- 0, 0,13,13,11,13,13,11,12,
- };
-
- static float _vq_quantthresh__8c0_s_p8_0[] = {
- -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5,
- 12.5, 17.5, 22.5, 27.5,
- };
-
- static long _vq_quantmap__8c0_s_p8_0[] = {
- 11, 9, 7, 5, 3, 1, 0, 2,
- 4, 6, 8, 10, 12,
- };
-
- static encode_aux_threshmatch _vq_auxt__8c0_s_p8_0 = {
- _vq_quantthresh__8c0_s_p8_0,
- _vq_quantmap__8c0_s_p8_0,
- 13,
- 13
- };
-
- static static_codebook _8c0_s_p8_0 = {
- 2, 169,
- _vq_lengthlist__8c0_s_p8_0,
- 1, -526516224, 1616117760, 4, 0,
- _vq_quantlist__8c0_s_p8_0,
- NULL,
- &_vq_auxt__8c0_s_p8_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__8c0_s_p8_1[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__8c0_s_p8_1[] = {
- 1, 3, 4, 5, 5, 7, 6, 6, 6, 5, 7, 7, 7, 6, 6, 7,
- 7, 7, 6, 6, 7, 7, 7, 6, 6,
- };
-
- static float _vq_quantthresh__8c0_s_p8_1[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__8c0_s_p8_1[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__8c0_s_p8_1 = {
- _vq_quantthresh__8c0_s_p8_1,
- _vq_quantmap__8c0_s_p8_1,
- 5,
- 5
- };
-
- static static_codebook _8c0_s_p8_1 = {
- 2, 25,
- _vq_lengthlist__8c0_s_p8_1,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__8c0_s_p8_1,
- NULL,
- &_vq_auxt__8c0_s_p8_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__8c0_s_p9_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__8c0_s_p9_0[] = {
- 1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7,
- };
-
- static float _vq_quantthresh__8c0_s_p9_0[] = {
- -157.5, 157.5,
- };
-
- static long _vq_quantmap__8c0_s_p9_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__8c0_s_p9_0 = {
- _vq_quantthresh__8c0_s_p9_0,
- _vq_quantmap__8c0_s_p9_0,
- 3,
- 3
- };
-
- static static_codebook _8c0_s_p9_0 = {
- 4, 81,
- _vq_lengthlist__8c0_s_p9_0,
- 1, -518803456, 1628680192, 2, 0,
- _vq_quantlist__8c0_s_p9_0,
- NULL,
- &_vq_auxt__8c0_s_p9_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__8c0_s_p9_1[] = {
- 7,
- 6,
- 8,
- 5,
- 9,
- 4,
- 10,
- 3,
- 11,
- 2,
- 12,
- 1,
- 13,
- 0,
- 14,
- };
-
- static long _vq_lengthlist__8c0_s_p9_1[] = {
- 1, 4, 4, 5, 5,10, 8,11,11,11,11,11,11,11,11, 6,
- 6, 6, 7, 6,11,10,11,11,11,11,11,11,11,11, 7, 5,
- 6, 6, 6, 8, 7,11,11,11,11,11,11,11,11,11, 7, 8,
- 8, 8, 9, 9,11,11,11,11,11,11,11,11,11, 9, 8, 7,
- 8, 9,11,11,11,11,11,11,11,11,11,11,11,10,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,10,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,
- };
-
- static float _vq_quantthresh__8c0_s_p9_1[] = {
- -136.5, -115.5, -94.5, -73.5, -52.5, -31.5, -10.5, 10.5,
- 31.5, 52.5, 73.5, 94.5, 115.5, 136.5,
- };
-
- static long _vq_quantmap__8c0_s_p9_1[] = {
- 13, 11, 9, 7, 5, 3, 1, 0,
- 2, 4, 6, 8, 10, 12, 14,
- };
-
- static encode_aux_threshmatch _vq_auxt__8c0_s_p9_1 = {
- _vq_quantthresh__8c0_s_p9_1,
- _vq_quantmap__8c0_s_p9_1,
- 15,
- 15
- };
-
- static static_codebook _8c0_s_p9_1 = {
- 2, 225,
- _vq_lengthlist__8c0_s_p9_1,
- 1, -520986624, 1620377600, 4, 0,
- _vq_quantlist__8c0_s_p9_1,
- NULL,
- &_vq_auxt__8c0_s_p9_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__8c0_s_p9_2[] = {
- 10,
- 9,
- 11,
- 8,
- 12,
- 7,
- 13,
- 6,
- 14,
- 5,
- 15,
- 4,
- 16,
- 3,
- 17,
- 2,
- 18,
- 1,
- 19,
- 0,
- 20,
- };
-
- static long _vq_lengthlist__8c0_s_p9_2[] = {
- 1, 5, 5, 7, 7, 8, 7, 8, 8,10,10, 9, 9,10,10,10,
- 11,11,10,12,11,12,12,12, 9, 8, 8, 8, 8, 8, 9,10,
- 10,10,10,11,11,11,10,11,11,12,12,11,12, 8, 8, 7,
- 7, 8, 9,10,10,10, 9,10,10, 9,10,10,11,11,11,11,
- 11,11, 9, 9, 9, 9, 8, 9,10,10,11,10,10,11,11,12,
- 10,10,12,12,11,11,10, 9, 9,10, 8, 9,10,10,10, 9,
- 10,10,11,11,10,11,10,10,10,12,12,12, 9,10, 9,10,
- 9, 9,10,10,11,11,11,11,10,10,10,11,12,11,12,11,
- 12,10,11,10,11, 9,10, 9,10, 9,10,10, 9,10,10,11,
- 10,11,11,11,11,12,11, 9,10,10,10,10,11,11,11,11,
- 11,10,11,11,11,11,10,12,10,12,12,11,12,10,10,11,
- 10, 9,11,10,11, 9,10,11,10,10,10,11,11,11,11,12,
- 12,10, 9, 9,11,10, 9,12,11,10,12,12,11,11,11,11,
- 10,11,11,12,11,10,12, 9,11,10,11,10,10,11,10,11,
- 9,10,10,10,11,12,11,11,12,11,10,10,11,11, 9,10,
- 10,12,10,11,10,10,10, 9,10,10,10,10, 9,10,10,11,
- 11,11,11,12,11,10,10,10,10,11,11,10,11,11, 9,11,
- 10,12,10,12,11,10,11,10,10,10,11,10,10,11,11,10,
- 11,10,10,10,10,11,11,12,10,10,10,11,10,11,12,11,
- 10,11,10,10,11,11,10,12,10, 9,10,10,11,11,11,10,
- 12,10,10,11,11,11,10,10,11,10,10,10,11,10,11,10,
- 12,11,11,10,10,10,12,10,10,11, 9,10,11,11,11,10,
- 10,11,10,10, 9,11,11,12,12,11,12,11,11,11,11,11,
- 11, 9,10,11,10,12,10,10,10,10,11,10,10,11,10,10,
- 12,10,10,10,10,10, 9,12,10,10,10,10,12, 9,11,10,
- 10,11,10,12,12,10,12,12,12,10,10,10,10, 9,10,11,
- 10,10,12,10,10,12,11,10,11,10,10,12,11,10,12,10,
- 10,11, 9,11,10, 9,10, 9,10,
- };
-
- static float _vq_quantthresh__8c0_s_p9_2[] = {
- -9.5, -8.5, -7.5, -6.5, -5.5, -4.5, -3.5, -2.5,
- -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5.5,
- 6.5, 7.5, 8.5, 9.5,
- };
-
- static long _vq_quantmap__8c0_s_p9_2[] = {
- 19, 17, 15, 13, 11, 9, 7, 5,
- 3, 1, 0, 2, 4, 6, 8, 10,
- 12, 14, 16, 18, 20,
- };
-
- static encode_aux_threshmatch _vq_auxt__8c0_s_p9_2 = {
- _vq_quantthresh__8c0_s_p9_2,
- _vq_quantmap__8c0_s_p9_2,
- 21,
- 21
- };
-
- static static_codebook _8c0_s_p9_2 = {
- 2, 441,
- _vq_lengthlist__8c0_s_p9_2,
- 1, -529268736, 1611661312, 5, 0,
- _vq_quantlist__8c0_s_p9_2,
- NULL,
- &_vq_auxt__8c0_s_p9_2,
- NULL,
- 0
- };
-
- static long _huff_lengthlist__8c0_s_single[] = {
- 4, 5,18, 7,10, 6, 7, 8, 9,10, 5, 2,18, 5, 7, 5,
- 6, 7, 8,11,17,17,17,17,17,17,17,17,17,17, 7, 4,
- 17, 6, 9, 6, 8,10,12,15,11, 7,17, 9, 6, 6, 7, 9,
- 11,15, 6, 4,17, 6, 6, 4, 5, 8,11,16, 6, 6,17, 8,
- 6, 5, 6, 9,13,16, 8, 9,17,11, 9, 8, 8,11,13,17,
- 9,12,17,15,14,13,12,13,14,17,12,15,17,17,17,17,
- 17,16,17,17,
- };
-
- static static_codebook _huff_book__8c0_s_single = {
- 2, 100,
- _huff_lengthlist__8c0_s_single,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _vq_quantlist__8c1_s_p1_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__8c1_s_p1_0[] = {
- 1, 5, 5, 0, 0, 0, 0, 0, 0, 5, 7, 7, 0, 0, 0, 0,
- 0, 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 5, 8, 7, 0, 0, 0, 0, 0, 0, 7, 8, 9, 0, 0, 0,
- 0, 0, 0, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 5, 7, 8, 0, 0, 0, 0, 0, 0, 7, 9, 8, 0, 0,
- 0, 0, 0, 0, 7, 9, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 8, 8, 0, 0, 0, 0,
- 0, 0, 8, 9, 9, 0, 0, 0, 0, 0, 0, 8, 9, 9, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, 0,
- 0, 0, 0, 8, 8,10, 0, 0, 0, 0, 0, 0, 9,10,10, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0,
- 0, 0, 0, 0, 8,10, 9, 0, 0, 0, 0, 0, 0, 9,10,10,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 5, 8, 8, 0, 0, 0, 0, 0, 0, 8, 9, 9, 0, 0,
- 0, 0, 0, 0, 8, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 9,10,10, 0,
- 0, 0, 0, 0, 0, 8, 9,10, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 9,10,10,
- 0, 0, 0, 0, 0, 0, 8,10, 8, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,
- };
-
- static float _vq_quantthresh__8c1_s_p1_0[] = {
- -0.5, 0.5,
- };
-
- static long _vq_quantmap__8c1_s_p1_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__8c1_s_p1_0 = {
- _vq_quantthresh__8c1_s_p1_0,
- _vq_quantmap__8c1_s_p1_0,
- 3,
- 3
- };
-
- static static_codebook _8c1_s_p1_0 = {
- 8, 6561,
- _vq_lengthlist__8c1_s_p1_0,
- 1, -535822336, 1611661312, 2, 0,
- _vq_quantlist__8c1_s_p1_0,
- NULL,
- &_vq_auxt__8c1_s_p1_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__8c1_s_p2_0[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__8c1_s_p2_0[] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,
- };
-
- static float _vq_quantthresh__8c1_s_p2_0[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__8c1_s_p2_0[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__8c1_s_p2_0 = {
- _vq_quantthresh__8c1_s_p2_0,
- _vq_quantmap__8c1_s_p2_0,
- 5,
- 5
- };
-
- static static_codebook _8c1_s_p2_0 = {
- 4, 625,
- _vq_lengthlist__8c1_s_p2_0,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__8c1_s_p2_0,
- NULL,
- &_vq_auxt__8c1_s_p2_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__8c1_s_p3_0[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__8c1_s_p3_0[] = {
- 2, 4, 4, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 6, 6, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 4, 4, 4, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 7, 7,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 6, 6, 6, 7, 7, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,
- };
-
- static float _vq_quantthresh__8c1_s_p3_0[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__8c1_s_p3_0[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__8c1_s_p3_0 = {
- _vq_quantthresh__8c1_s_p3_0,
- _vq_quantmap__8c1_s_p3_0,
- 5,
- 5
- };
-
- static static_codebook _8c1_s_p3_0 = {
- 4, 625,
- _vq_lengthlist__8c1_s_p3_0,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__8c1_s_p3_0,
- NULL,
- &_vq_auxt__8c1_s_p3_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__8c1_s_p4_0[] = {
- 4,
- 3,
- 5,
- 2,
- 6,
- 1,
- 7,
- 0,
- 8,
- };
-
- static long _vq_lengthlist__8c1_s_p4_0[] = {
- 1, 2, 3, 7, 7, 0, 0, 0, 0, 0, 0, 0, 6, 6, 0, 0,
- 0, 0, 0, 0, 0, 6, 6, 0, 0, 0, 0, 0, 0, 0, 7, 7,
- 0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 0, 0, 0, 0, 0,
- 8, 8, 0, 0, 0, 0, 0, 0, 0, 9, 8, 0, 0, 0, 0, 0,
- 0, 0,10,10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,
- };
-
- static float _vq_quantthresh__8c1_s_p4_0[] = {
- -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5,
- };
-
- static long _vq_quantmap__8c1_s_p4_0[] = {
- 7, 5, 3, 1, 0, 2, 4, 6,
- 8,
- };
-
- static encode_aux_threshmatch _vq_auxt__8c1_s_p4_0 = {
- _vq_quantthresh__8c1_s_p4_0,
- _vq_quantmap__8c1_s_p4_0,
- 9,
- 9
- };
-
- static static_codebook _8c1_s_p4_0 = {
- 2, 81,
- _vq_lengthlist__8c1_s_p4_0,
- 1, -531628032, 1611661312, 4, 0,
- _vq_quantlist__8c1_s_p4_0,
- NULL,
- &_vq_auxt__8c1_s_p4_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__8c1_s_p5_0[] = {
- 4,
- 3,
- 5,
- 2,
- 6,
- 1,
- 7,
- 0,
- 8,
- };
-
- static long _vq_lengthlist__8c1_s_p5_0[] = {
- 1, 3, 3, 4, 5, 6, 6, 8, 8, 0, 0, 0, 8, 8, 7, 7,
- 9, 9, 0, 0, 0, 8, 8, 7, 7, 9, 9, 0, 0, 0, 9,10,
- 8, 8, 9, 9, 0, 0, 0,10,10, 8, 8, 9, 9, 0, 0, 0,
- 11,10, 8, 8,10,10, 0, 0, 0,11,11, 8, 8,10,10, 0,
- 0, 0,12,12, 9, 9,10,10, 0, 0, 0, 0, 0, 9, 9,10,
- 10,
- };
-
- static float _vq_quantthresh__8c1_s_p5_0[] = {
- -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5,
- };
-
- static long _vq_quantmap__8c1_s_p5_0[] = {
- 7, 5, 3, 1, 0, 2, 4, 6,
- 8,
- };
-
- static encode_aux_threshmatch _vq_auxt__8c1_s_p5_0 = {
- _vq_quantthresh__8c1_s_p5_0,
- _vq_quantmap__8c1_s_p5_0,
- 9,
- 9
- };
-
- static static_codebook _8c1_s_p5_0 = {
- 2, 81,
- _vq_lengthlist__8c1_s_p5_0,
- 1, -531628032, 1611661312, 4, 0,
- _vq_quantlist__8c1_s_p5_0,
- NULL,
- &_vq_auxt__8c1_s_p5_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__8c1_s_p6_0[] = {
- 8,
- 7,
- 9,
- 6,
- 10,
- 5,
- 11,
- 4,
- 12,
- 3,
- 13,
- 2,
- 14,
- 1,
- 15,
- 0,
- 16,
- };
-
- static long _vq_lengthlist__8c1_s_p6_0[] = {
- 1, 3, 3, 5, 5, 8, 8, 8, 8, 9, 9,10,10,11,11,11,
- 11, 0, 0, 0, 8, 8, 8, 8, 9, 9, 9, 9,10,10,11,11,
- 12,12, 0, 0, 0, 8, 8, 8, 8, 9, 9, 9, 9,10,10,11,
- 11,12,12, 0, 0, 0, 9, 9, 8, 8,10,10,10,10,11,11,
- 12,12,12,12, 0, 0, 0, 9, 9, 8, 8,10,10,10,10,11,
- 11,12,12,12,12, 0, 0, 0,10,10, 9, 9,10,10,10,10,
- 11,11,12,12,13,13, 0, 0, 0,10,10, 9, 9,10,10,10,
- 10,11,11,12,12,13,13, 0, 0, 0,11,11, 9, 9,10,10,
- 10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, 9, 9,10,
- 10,10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, 9, 9,
- 10,10,11,11,12,12,12,12,13,13, 0, 0, 0, 0, 0, 9,
- 9,10,10,11,11,12,11,12,12,13,13, 0, 0, 0, 0, 0,
- 10,10,11,11,11,11,12,12,13,12,13,13, 0, 0, 0, 0,
- 0, 0, 0,11,10,11,11,12,12,13,13,13,13, 0, 0, 0,
- 0, 0, 0, 0,11,11,12,12,12,12,13,13,13,14, 0, 0,
- 0, 0, 0, 0, 0,11,11,12,12,12,12,13,13,14,13, 0,
- 0, 0, 0, 0, 0, 0,12,12,12,12,13,13,13,13,14,14,
- 0, 0, 0, 0, 0, 0, 0, 0, 0,12,12,13,13,13,13,14,
- 14,
- };
-
- static float _vq_quantthresh__8c1_s_p6_0[] = {
- -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5,
- 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5,
- };
-
- static long _vq_quantmap__8c1_s_p6_0[] = {
- 15, 13, 11, 9, 7, 5, 3, 1,
- 0, 2, 4, 6, 8, 10, 12, 14,
- 16,
- };
-
- static encode_aux_threshmatch _vq_auxt__8c1_s_p6_0 = {
- _vq_quantthresh__8c1_s_p6_0,
- _vq_quantmap__8c1_s_p6_0,
- 17,
- 17
- };
-
- static static_codebook _8c1_s_p6_0 = {
- 2, 289,
- _vq_lengthlist__8c1_s_p6_0,
- 1, -529530880, 1611661312, 5, 0,
- _vq_quantlist__8c1_s_p6_0,
- NULL,
- &_vq_auxt__8c1_s_p6_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__8c1_s_p7_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__8c1_s_p7_0[] = {
- 1, 4, 4, 6, 6, 6, 7, 6, 6, 4, 7, 7,10, 9, 9,10,
- 9, 9, 5, 7, 7,10, 9, 9,10, 9, 9, 6,10,10,10,10,
- 10,11,10,10, 6, 9, 9,10, 9,10,11,10,10, 6, 9, 9,
- 10, 9, 9,11, 9,10, 7,10,10,11,11,11,11,10,10, 6,
- 9, 9,10,10,10,11, 9, 9, 6, 9, 9,10,10,10,10, 9,
- 9,
- };
-
- static float _vq_quantthresh__8c1_s_p7_0[] = {
- -5.5, 5.5,
- };
-
- static long _vq_quantmap__8c1_s_p7_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__8c1_s_p7_0 = {
- _vq_quantthresh__8c1_s_p7_0,
- _vq_quantmap__8c1_s_p7_0,
- 3,
- 3
- };
-
- static static_codebook _8c1_s_p7_0 = {
- 4, 81,
- _vq_lengthlist__8c1_s_p7_0,
- 1, -529137664, 1618345984, 2, 0,
- _vq_quantlist__8c1_s_p7_0,
- NULL,
- &_vq_auxt__8c1_s_p7_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__8c1_s_p7_1[] = {
- 5,
- 4,
- 6,
- 3,
- 7,
- 2,
- 8,
- 1,
- 9,
- 0,
- 10,
- };
-
- static long _vq_lengthlist__8c1_s_p7_1[] = {
- 2, 3, 3, 5, 5, 7, 7, 7, 7, 7, 7,10,10, 9, 7, 7,
- 7, 7, 8, 8, 8, 8, 9, 9, 9, 7, 7, 7, 7, 8, 8, 8,
- 8,10,10,10, 7, 7, 7, 7, 8, 8, 8, 8,10,10,10, 7,
- 7, 7, 7, 8, 8, 8, 8,10,10,10, 8, 8, 8, 8, 8, 8,
- 8, 8,10,10,10, 8, 8, 8, 8, 8, 8, 8, 8,10,10,10,
- 8, 8, 8, 8, 8, 8, 8, 8,10,10,10,10,10, 8, 8, 8,
- 8, 8, 8,10,10,10,10,10, 8, 8, 8, 8, 8, 8,10,10,
- 10,10,10, 8, 8, 8, 8, 8, 8,
- };
-
- static float _vq_quantthresh__8c1_s_p7_1[] = {
- -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5,
- 3.5, 4.5,
- };
-
- static long _vq_quantmap__8c1_s_p7_1[] = {
- 9, 7, 5, 3, 1, 0, 2, 4,
- 6, 8, 10,
- };
-
- static encode_aux_threshmatch _vq_auxt__8c1_s_p7_1 = {
- _vq_quantthresh__8c1_s_p7_1,
- _vq_quantmap__8c1_s_p7_1,
- 11,
- 11
- };
-
- static static_codebook _8c1_s_p7_1 = {
- 2, 121,
- _vq_lengthlist__8c1_s_p7_1,
- 1, -531365888, 1611661312, 4, 0,
- _vq_quantlist__8c1_s_p7_1,
- NULL,
- &_vq_auxt__8c1_s_p7_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__8c1_s_p8_0[] = {
- 6,
- 5,
- 7,
- 4,
- 8,
- 3,
- 9,
- 2,
- 10,
- 1,
- 11,
- 0,
- 12,
- };
-
- static long _vq_lengthlist__8c1_s_p8_0[] = {
- 1, 4, 4, 6, 6, 8, 8, 8, 8, 9, 9,10,10, 7, 5, 5,
- 7, 7, 8, 8, 8, 8, 9,10,11,11, 7, 5, 5, 7, 7, 8,
- 8, 9, 9,10,10,11,11, 0, 8, 8, 8, 8, 9, 9, 9, 9,
- 9,10,11,11, 0, 8, 8, 8, 8, 9, 9, 9, 9,10,10,11,
- 11, 0,12,12, 9, 9, 9, 9,10, 9,10,11,11,11, 0,13,
- 12, 9, 8, 9, 9,10,10,11,11,12,11, 0, 0, 0, 9, 9,
- 9, 9,10,10,11,11,12,12, 0, 0, 0,10,10, 9, 9,10,
- 10,11,11,12,12, 0, 0, 0,13,13,10,10,11,11,12,11,
- 13,12, 0, 0, 0,14,14,10,10,11,10,11,11,12,12, 0,
- 0, 0, 0, 0,12,12,11,11,12,12,13,13, 0, 0, 0, 0,
- 0,12,12,11,10,12,11,13,12,
- };
-
- static float _vq_quantthresh__8c1_s_p8_0[] = {
- -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5,
- 12.5, 17.5, 22.5, 27.5,
- };
-
- static long _vq_quantmap__8c1_s_p8_0[] = {
- 11, 9, 7, 5, 3, 1, 0, 2,
- 4, 6, 8, 10, 12,
- };
-
- static encode_aux_threshmatch _vq_auxt__8c1_s_p8_0 = {
- _vq_quantthresh__8c1_s_p8_0,
- _vq_quantmap__8c1_s_p8_0,
- 13,
- 13
- };
-
- static static_codebook _8c1_s_p8_0 = {
- 2, 169,
- _vq_lengthlist__8c1_s_p8_0,
- 1, -526516224, 1616117760, 4, 0,
- _vq_quantlist__8c1_s_p8_0,
- NULL,
- &_vq_auxt__8c1_s_p8_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__8c1_s_p8_1[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__8c1_s_p8_1[] = {
- 2, 3, 3, 5, 5, 6, 6, 6, 5, 5, 6, 6, 6, 5, 5, 6,
- 6, 6, 5, 5, 6, 6, 6, 5, 5,
- };
-
- static float _vq_quantthresh__8c1_s_p8_1[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__8c1_s_p8_1[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__8c1_s_p8_1 = {
- _vq_quantthresh__8c1_s_p8_1,
- _vq_quantmap__8c1_s_p8_1,
- 5,
- 5
- };
-
- static static_codebook _8c1_s_p8_1 = {
- 2, 25,
- _vq_lengthlist__8c1_s_p8_1,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__8c1_s_p8_1,
- NULL,
- &_vq_auxt__8c1_s_p8_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__8c1_s_p9_0[] = {
- 6,
- 5,
- 7,
- 4,
- 8,
- 3,
- 9,
- 2,
- 10,
- 1,
- 11,
- 0,
- 12,
- };
-
- static long _vq_lengthlist__8c1_s_p9_0[] = {
- 1, 3, 3,10,10,10,10,10,10,10,10,10,10, 5, 6, 6,
- 10,10,10,10,10,10,10,10,10,10, 6, 7, 8,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10, 9, 9, 9, 9,
- };
-
- static float _vq_quantthresh__8c1_s_p9_0[] = {
- -1732.5, -1417.5, -1102.5, -787.5, -472.5, -157.5, 157.5, 472.5,
- 787.5, 1102.5, 1417.5, 1732.5,
- };
-
- static long _vq_quantmap__8c1_s_p9_0[] = {
- 11, 9, 7, 5, 3, 1, 0, 2,
- 4, 6, 8, 10, 12,
- };
-
- static encode_aux_threshmatch _vq_auxt__8c1_s_p9_0 = {
- _vq_quantthresh__8c1_s_p9_0,
- _vq_quantmap__8c1_s_p9_0,
- 13,
- 13
- };
-
- static static_codebook _8c1_s_p9_0 = {
- 2, 169,
- _vq_lengthlist__8c1_s_p9_0,
- 1, -513964032, 1628680192, 4, 0,
- _vq_quantlist__8c1_s_p9_0,
- NULL,
- &_vq_auxt__8c1_s_p9_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__8c1_s_p9_1[] = {
- 7,
- 6,
- 8,
- 5,
- 9,
- 4,
- 10,
- 3,
- 11,
- 2,
- 12,
- 1,
- 13,
- 0,
- 14,
- };
-
- static long _vq_lengthlist__8c1_s_p9_1[] = {
- 1, 4, 4, 5, 5, 7, 7, 9, 9,11,11,12,12,13,13, 6,
- 5, 5, 6, 6, 9, 9,10,10,12,12,12,13,15,14, 6, 5,
- 5, 7, 7, 9, 9,10,10,12,12,12,13,14,13,17, 7, 7,
- 8, 8,10,10,11,11,12,13,13,13,13,13,17, 7, 7, 8,
- 8,10,10,11,11,13,13,13,13,14,14,17,11,11, 9, 9,
- 11,11,12,12,12,13,13,14,15,13,17,12,12, 9, 9,11,
- 11,12,12,13,13,13,13,14,16,17,17,17,11,12,12,12,
- 13,13,13,14,15,14,15,15,17,17,17,12,12,11,11,13,
- 13,14,14,15,14,15,15,17,17,17,15,15,13,13,14,14,
- 15,14,15,15,16,15,17,17,17,15,15,13,13,13,14,14,
- 15,15,15,15,16,17,17,17,17,16,14,15,14,14,15,14,
- 14,15,15,15,17,17,17,17,17,14,14,16,14,15,15,15,
- 15,15,15,17,17,17,17,17,17,16,16,15,17,15,15,14,
- 17,15,17,16,17,17,17,17,16,15,14,15,15,15,15,15,
- 15,
- };
-
- static float _vq_quantthresh__8c1_s_p9_1[] = {
- -136.5, -115.5, -94.5, -73.5, -52.5, -31.5, -10.5, 10.5,
- 31.5, 52.5, 73.5, 94.5, 115.5, 136.5,
- };
-
- static long _vq_quantmap__8c1_s_p9_1[] = {
- 13, 11, 9, 7, 5, 3, 1, 0,
- 2, 4, 6, 8, 10, 12, 14,
- };
-
- static encode_aux_threshmatch _vq_auxt__8c1_s_p9_1 = {
- _vq_quantthresh__8c1_s_p9_1,
- _vq_quantmap__8c1_s_p9_1,
- 15,
- 15
- };
-
- static static_codebook _8c1_s_p9_1 = {
- 2, 225,
- _vq_lengthlist__8c1_s_p9_1,
- 1, -520986624, 1620377600, 4, 0,
- _vq_quantlist__8c1_s_p9_1,
- NULL,
- &_vq_auxt__8c1_s_p9_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__8c1_s_p9_2[] = {
- 10,
- 9,
- 11,
- 8,
- 12,
- 7,
- 13,
- 6,
- 14,
- 5,
- 15,
- 4,
- 16,
- 3,
- 17,
- 2,
- 18,
- 1,
- 19,
- 0,
- 20,
- };
-
- static long _vq_lengthlist__8c1_s_p9_2[] = {
- 2, 4, 4, 6, 6, 7, 7, 8, 8, 8, 8, 9, 8, 9, 9, 9,
- 9, 9, 9, 9, 9,11,11,12, 7, 7, 7, 7, 8, 8, 9, 9,
- 9, 9,10,10,10,10,10,10,10,10,11,11,11, 7, 7, 7,
- 7, 8, 8, 9, 8, 9, 9, 9, 9, 9, 9,10,10,10,10,11,
- 11,12, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9,10,10,10,10,
- 10,10,10,10,11,11,11, 7, 7, 8, 8, 8, 8, 9, 9, 9,
- 9,10,10,10,10,10,10,10,10,11,11,11, 8, 8, 8, 8,
- 9, 9, 9, 9, 9, 9,10,10,10,10,10,10,10,10,11,11,
- 11, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9,10,10,10,10,10,
- 10,10,10,11,12,11, 9, 9, 8, 9, 9, 9, 9, 9,10,10,
- 10,10,10,10,10,10,10,10,11,11,11,11,11, 8, 8, 9,
- 9, 9, 9,10,10,10,10,10,10,10,10,10,10,11,12,11,
- 12,11, 9, 9, 9, 9, 9,10,10,10,10,10,10,10,10,10,
- 10,10,11,11,11,11,11, 9, 9, 9, 9,10,10,10,10,10,
- 10,10,10,10,10,10,10,12,11,12,11,11, 9, 9, 9,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,12,11,11,11,
- 11,11,11,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 11,11,11,12,11,11,12,11,10,10,10,10,10,10,10,10,
- 10,10,10,10,11,10,11,11,11,11,11,11,11,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,11,11,12,11,12,
- 11,11,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 11,11,12,11,12,11,11,11,11,10,10,10,10,10,10,10,
- 10,10,10,10,10,11,11,12,11,11,12,11,11,12,10,10,
- 11,10,10,10,10,10,10,10,10,10,11,11,11,11,11,11,
- 11,11,11,10,10,10,10,10,10,10,10,10,10,10,10,12,
- 12,11,12,11,11,12,12,12,11,11,10,10,10,10,10,10,
- 10,10,10,11,12,12,11,12,12,11,12,11,11,11,11,10,
- 10,10,10,10,10,10,10,10,10,
- };
-
- static float _vq_quantthresh__8c1_s_p9_2[] = {
- -9.5, -8.5, -7.5, -6.5, -5.5, -4.5, -3.5, -2.5,
- -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5.5,
- 6.5, 7.5, 8.5, 9.5,
- };
-
- static long _vq_quantmap__8c1_s_p9_2[] = {
- 19, 17, 15, 13, 11, 9, 7, 5,
- 3, 1, 0, 2, 4, 6, 8, 10,
- 12, 14, 16, 18, 20,
- };
-
- static encode_aux_threshmatch _vq_auxt__8c1_s_p9_2 = {
- _vq_quantthresh__8c1_s_p9_2,
- _vq_quantmap__8c1_s_p9_2,
- 21,
- 21
- };
-
- static static_codebook _8c1_s_p9_2 = {
- 2, 441,
- _vq_lengthlist__8c1_s_p9_2,
- 1, -529268736, 1611661312, 5, 0,
- _vq_quantlist__8c1_s_p9_2,
- NULL,
- &_vq_auxt__8c1_s_p9_2,
- NULL,
- 0
- };
-
- static long _huff_lengthlist__8c1_s_single[] = {
- 4, 6,18, 8,11, 8, 8, 9, 9,10, 4, 4,18, 5, 9, 5,
- 6, 7, 8,10,18,18,18,18,17,17,17,17,17,17, 7, 5,
- 17, 6,11, 6, 7, 8, 9,12,12, 9,17,12, 8, 8, 9,10,
- 10,13, 7, 5,17, 6, 8, 4, 5, 6, 8,10, 6, 5,17, 6,
- 8, 5, 4, 5, 7, 9, 7, 7,17, 8, 9, 6, 5, 5, 6, 8,
- 8, 8,17, 9,11, 8, 6, 6, 6, 7, 9,10,17,12,12,10,
- 9, 7, 7, 8,
- };
-
- static static_codebook _huff_book__8c1_s_single = {
- 2, 100,
- _huff_lengthlist__8c1_s_single,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist__44c2_s_long[] = {
- 6, 6,12,10,10,10, 9,10,12,12, 6, 1,10, 5, 6, 6,
- 7, 9,11,14,12, 9, 8,11, 7, 8, 9,11,13,15,10, 5,
- 12, 7, 8, 7, 9,12,14,15,10, 6, 7, 8, 5, 6, 7, 9,
- 12,14, 9, 6, 8, 7, 6, 6, 7, 9,12,12, 9, 7, 9, 9,
- 7, 6, 6, 7,10,10,10, 9,10,11, 8, 7, 6, 6, 8,10,
- 12,11,13,13,11,10, 8, 8, 8,10,11,13,15,15,14,13,
- 10, 8, 8, 9,
- };
-
- static static_codebook _huff_book__44c2_s_long = {
- 2, 100,
- _huff_lengthlist__44c2_s_long,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c2_s_p1_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__44c2_s_p1_0[] = {
- 2, 4, 4, 0, 0, 0, 0, 0, 0, 5, 6, 6, 0, 0, 0, 0,
- 0, 0, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 0, 0,
- 0, 0, 0, 6, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 6, 8, 7, 0, 0,
- 0, 0, 0, 0, 7, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 7, 7, 0, 0, 0, 0,
- 0, 0, 7, 8, 8, 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 0, 0,
- 0, 0, 0, 8, 9, 9, 0, 0, 0, 0, 0, 0, 8, 9, 9, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 8, 8, 0, 0,
- 0, 0, 0, 0, 8, 9, 8, 0, 0, 0, 0, 0, 0, 8, 9, 9,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 4, 7, 7, 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 0,
- 0, 0, 0, 0, 7, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 6, 8, 8, 0, 0, 0, 0, 0, 0, 8, 9, 9, 0,
- 0, 0, 0, 0, 0, 8, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 7, 8, 8, 0, 0, 0, 0, 0, 0, 8, 9, 9,
- 0, 0, 0, 0, 0, 0, 8, 9, 9, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,
- };
-
- static float _vq_quantthresh__44c2_s_p1_0[] = {
- -0.5, 0.5,
- };
-
- static long _vq_quantmap__44c2_s_p1_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c2_s_p1_0 = {
- _vq_quantthresh__44c2_s_p1_0,
- _vq_quantmap__44c2_s_p1_0,
- 3,
- 3
- };
-
- static static_codebook _44c2_s_p1_0 = {
- 8, 6561,
- _vq_lengthlist__44c2_s_p1_0,
- 1, -535822336, 1611661312, 2, 0,
- _vq_quantlist__44c2_s_p1_0,
- NULL,
- &_vq_auxt__44c2_s_p1_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c2_s_p2_0[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__44c2_s_p2_0[] = {
- 1, 4, 4, 0, 0, 0, 7, 7, 0, 0, 0, 7, 7, 0, 0, 0,
- 8, 8, 0, 0, 0, 0, 0, 0, 0, 4, 6, 6, 0, 0, 0, 8,
- 8, 0, 0, 0, 8, 8, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0,
- 0, 0, 4, 6, 6, 0, 0, 0, 8, 8, 0, 0, 0, 8, 8, 0,
- 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 0, 0,11,11, 0, 0,
- 0,11,11, 0, 0, 0,12,11, 0, 0, 0, 0, 0, 0, 0, 7,
- 8, 8, 0, 0, 0,10,11, 0, 0, 0,11,11, 0, 0, 0,11,
- 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 6, 8, 8, 0, 0, 0,11,11, 0, 0, 0,11,11,
- 0, 0, 0,12,12, 0, 0, 0, 0, 0, 0, 0, 6, 8, 8, 0,
- 0, 0,10,11, 0, 0, 0,10,11, 0, 0, 0,11,11, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 8, 9, 9, 0, 0, 0,11,12, 0, 0, 0,11,12, 0, 0, 0,
- 12,11, 0, 0, 0, 0, 0, 0, 0, 8,10, 9, 0, 0, 0,12,
- 11, 0, 0, 0,12,11, 0, 0, 0,11,12, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,
- };
-
- static float _vq_quantthresh__44c2_s_p2_0[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__44c2_s_p2_0[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c2_s_p2_0 = {
- _vq_quantthresh__44c2_s_p2_0,
- _vq_quantmap__44c2_s_p2_0,
- 5,
- 5
- };
-
- static static_codebook _44c2_s_p2_0 = {
- 4, 625,
- _vq_lengthlist__44c2_s_p2_0,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__44c2_s_p2_0,
- NULL,
- &_vq_auxt__44c2_s_p2_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c2_s_p3_0[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__44c2_s_p3_0[] = {
- 2, 4, 3, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 6, 6, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 4, 4, 4, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 9, 9,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 6, 6, 7, 9, 9, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,
- };
-
- static float _vq_quantthresh__44c2_s_p3_0[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__44c2_s_p3_0[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c2_s_p3_0 = {
- _vq_quantthresh__44c2_s_p3_0,
- _vq_quantmap__44c2_s_p3_0,
- 5,
- 5
- };
-
- static static_codebook _44c2_s_p3_0 = {
- 4, 625,
- _vq_lengthlist__44c2_s_p3_0,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__44c2_s_p3_0,
- NULL,
- &_vq_auxt__44c2_s_p3_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c2_s_p4_0[] = {
- 4,
- 3,
- 5,
- 2,
- 6,
- 1,
- 7,
- 0,
- 8,
- };
-
- static long _vq_lengthlist__44c2_s_p4_0[] = {
- 1, 3, 3, 6, 6, 0, 0, 0, 0, 0, 6, 6, 6, 6, 0, 0,
- 0, 0, 0, 6, 6, 6, 6, 0, 0, 0, 0, 0, 7, 7, 6, 6,
- 0, 0, 0, 0, 0, 0, 0, 6, 7, 0, 0, 0, 0, 0, 0, 0,
- 7, 8, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0,
- 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,
- };
-
- static float _vq_quantthresh__44c2_s_p4_0[] = {
- -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5,
- };
-
- static long _vq_quantmap__44c2_s_p4_0[] = {
- 7, 5, 3, 1, 0, 2, 4, 6,
- 8,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c2_s_p4_0 = {
- _vq_quantthresh__44c2_s_p4_0,
- _vq_quantmap__44c2_s_p4_0,
- 9,
- 9
- };
-
- static static_codebook _44c2_s_p4_0 = {
- 2, 81,
- _vq_lengthlist__44c2_s_p4_0,
- 1, -531628032, 1611661312, 4, 0,
- _vq_quantlist__44c2_s_p4_0,
- NULL,
- &_vq_auxt__44c2_s_p4_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c2_s_p5_0[] = {
- 4,
- 3,
- 5,
- 2,
- 6,
- 1,
- 7,
- 0,
- 8,
- };
-
- static long _vq_lengthlist__44c2_s_p5_0[] = {
- 1, 3, 3, 6, 6, 7, 7, 9, 9, 0, 7, 7, 7, 7, 7, 7,
- 9, 9, 0, 7, 7, 7, 7, 7, 7, 9, 9, 0, 8, 8, 7, 7,
- 8, 8,10,10, 0, 0, 0, 7, 7, 8, 8,10,10, 0, 0, 0,
- 9, 9, 8, 8,10,10, 0, 0, 0, 9, 9, 8, 8,10,10, 0,
- 0, 0,10,10, 9, 9,11,11, 0, 0, 0, 0, 0, 9, 9,11,
- 11,
- };
-
- static float _vq_quantthresh__44c2_s_p5_0[] = {
- -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5,
- };
-
- static long _vq_quantmap__44c2_s_p5_0[] = {
- 7, 5, 3, 1, 0, 2, 4, 6,
- 8,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c2_s_p5_0 = {
- _vq_quantthresh__44c2_s_p5_0,
- _vq_quantmap__44c2_s_p5_0,
- 9,
- 9
- };
-
- static static_codebook _44c2_s_p5_0 = {
- 2, 81,
- _vq_lengthlist__44c2_s_p5_0,
- 1, -531628032, 1611661312, 4, 0,
- _vq_quantlist__44c2_s_p5_0,
- NULL,
- &_vq_auxt__44c2_s_p5_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c2_s_p6_0[] = {
- 8,
- 7,
- 9,
- 6,
- 10,
- 5,
- 11,
- 4,
- 12,
- 3,
- 13,
- 2,
- 14,
- 1,
- 15,
- 0,
- 16,
- };
-
- static long _vq_lengthlist__44c2_s_p6_0[] = {
- 1, 4, 3, 6, 6, 8, 8, 9, 9, 9, 9, 9, 9,10,10,11,
- 11, 0, 7, 7, 7, 7, 8, 8, 9, 9, 9, 9,10,10,11,11,
- 12,11, 0, 7, 7, 7, 7, 8, 8, 9, 9, 9, 9,10,10,11,
- 11,11,12, 0, 8, 8, 7, 7, 9, 9,10,10, 9, 9,10,10,
- 11,11,12,12, 0, 0, 0, 7, 7, 9, 9,10,10,10, 9,10,
- 10,11,11,12,12, 0, 0, 0, 8, 8, 9, 9,10,10,10,10,
- 11,11,11,11,12,12, 0, 0, 0, 8, 8, 9, 9,10,10,10,
- 10,11,11,12,12,12,12, 0, 0, 0, 9, 9, 9, 9,10,10,
- 10,10,11,11,12,12,12,12, 0, 0, 0, 0, 0, 9, 9,10,
- 10,10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, 9, 9,
- 10,10,11,11,11,11,12,12,13,13, 0, 0, 0, 0, 0, 9,
- 9,10,10,11,11,11,11,12,12,13,13, 0, 0, 0, 0, 0,
- 10,10,10,10,11,11,12,12,13,12,13,13, 0, 0, 0, 0,
- 0, 0, 0,10,10,11,11,12,12,13,13,13,13, 0, 0, 0,
- 0, 0, 0, 0,11,11,12,12,12,12,13,13,13,14, 0, 0,
- 0, 0, 0, 0, 0,11,11,12,12,12,12,13,13,13,14, 0,
- 0, 0, 0, 0, 0, 0,12,12,12,12,13,13,13,13,14,14,
- 0, 0, 0, 0, 0, 0, 0, 0, 0,12,12,13,13,13,13,14,
- 14,
- };
-
- static float _vq_quantthresh__44c2_s_p6_0[] = {
- -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5,
- 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5,
- };
-
- static long _vq_quantmap__44c2_s_p6_0[] = {
- 15, 13, 11, 9, 7, 5, 3, 1,
- 0, 2, 4, 6, 8, 10, 12, 14,
- 16,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c2_s_p6_0 = {
- _vq_quantthresh__44c2_s_p6_0,
- _vq_quantmap__44c2_s_p6_0,
- 17,
- 17
- };
-
- static static_codebook _44c2_s_p6_0 = {
- 2, 289,
- _vq_lengthlist__44c2_s_p6_0,
- 1, -529530880, 1611661312, 5, 0,
- _vq_quantlist__44c2_s_p6_0,
- NULL,
- &_vq_auxt__44c2_s_p6_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c2_s_p7_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__44c2_s_p7_0[] = {
- 1, 4, 4, 7, 6, 6, 7, 6, 6, 4, 7, 7,10, 9, 9,11,
- 9, 9, 4, 7, 7,10, 9, 9,10, 9, 9, 7,10,10,11,10,
- 11,11,10,11, 6, 9, 9,11,10,10,11,10,10, 6, 9, 9,
- 11,10,11,11,10,10, 7,11,10,11,11,11,12,11,11, 6,
- 9, 9,11,10,10,11,11,10, 6, 9, 9,11,10,10,12,10,
- 11,
- };
-
- static float _vq_quantthresh__44c2_s_p7_0[] = {
- -5.5, 5.5,
- };
-
- static long _vq_quantmap__44c2_s_p7_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c2_s_p7_0 = {
- _vq_quantthresh__44c2_s_p7_0,
- _vq_quantmap__44c2_s_p7_0,
- 3,
- 3
- };
-
- static static_codebook _44c2_s_p7_0 = {
- 4, 81,
- _vq_lengthlist__44c2_s_p7_0,
- 1, -529137664, 1618345984, 2, 0,
- _vq_quantlist__44c2_s_p7_0,
- NULL,
- &_vq_auxt__44c2_s_p7_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c2_s_p7_1[] = {
- 5,
- 4,
- 6,
- 3,
- 7,
- 2,
- 8,
- 1,
- 9,
- 0,
- 10,
- };
-
- static long _vq_lengthlist__44c2_s_p7_1[] = {
- 2, 3, 4, 6, 6, 7, 7, 7, 7, 7, 7, 9, 7, 7, 6, 6,
- 7, 7, 8, 8, 8, 8, 9, 6, 6, 6, 6, 7, 7, 8, 8, 8,
- 8,10, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8,10,10,10, 7,
- 7, 7, 7, 8, 8, 8, 8,10,10,10, 7, 7, 8, 8, 8, 8,
- 8, 8,10,10,10, 7, 8, 8, 8, 8, 8, 8, 8,10,10,10,
- 8, 8, 8, 8, 8, 8, 8, 8,10,10,10,10,10, 8, 8, 8,
- 8, 8, 8,10,10,10,10,10, 9, 9, 8, 8, 8, 8,10,10,
- 10,10,10, 8, 8, 8, 8, 8, 8,
- };
-
- static float _vq_quantthresh__44c2_s_p7_1[] = {
- -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5,
- 3.5, 4.5,
- };
-
- static long _vq_quantmap__44c2_s_p7_1[] = {
- 9, 7, 5, 3, 1, 0, 2, 4,
- 6, 8, 10,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c2_s_p7_1 = {
- _vq_quantthresh__44c2_s_p7_1,
- _vq_quantmap__44c2_s_p7_1,
- 11,
- 11
- };
-
- static static_codebook _44c2_s_p7_1 = {
- 2, 121,
- _vq_lengthlist__44c2_s_p7_1,
- 1, -531365888, 1611661312, 4, 0,
- _vq_quantlist__44c2_s_p7_1,
- NULL,
- &_vq_auxt__44c2_s_p7_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c2_s_p8_0[] = {
- 6,
- 5,
- 7,
- 4,
- 8,
- 3,
- 9,
- 2,
- 10,
- 1,
- 11,
- 0,
- 12,
- };
-
- static long _vq_lengthlist__44c2_s_p8_0[] = {
- 1, 4, 4, 6, 6, 7, 7, 7, 7, 8, 8, 9, 9, 6, 5, 5,
- 7, 7, 8, 8, 8, 8, 9, 9,10,10, 7, 6, 5, 7, 7, 8,
- 8, 8, 8, 9, 9,10,10, 0, 8, 8, 8, 8, 9, 9, 9, 9,
- 10,10,11,11, 0, 8, 8, 8, 8, 9, 9, 9, 9,10,10,11,
- 11, 0,12,12, 9, 9,10,10,10,10,11,11,11,11, 0,13,
- 13, 9, 9,10,10,10,10,11,11,12,12, 0, 0, 0,10,10,
- 10,10,11,11,12,12,12,13, 0, 0, 0,10,10,10,10,11,
- 11,12,12,12,12, 0, 0, 0,14,14,10,11,11,11,12,12,
- 13,13, 0, 0, 0,14,14,11,10,11,11,13,12,13,13, 0,
- 0, 0, 0, 0,12,12,11,12,13,12,14,14, 0, 0, 0, 0,
- 0,12,12,12,12,13,12,14,14,
- };
-
- static float _vq_quantthresh__44c2_s_p8_0[] = {
- -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5,
- 12.5, 17.5, 22.5, 27.5,
- };
-
- static long _vq_quantmap__44c2_s_p8_0[] = {
- 11, 9, 7, 5, 3, 1, 0, 2,
- 4, 6, 8, 10, 12,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c2_s_p8_0 = {
- _vq_quantthresh__44c2_s_p8_0,
- _vq_quantmap__44c2_s_p8_0,
- 13,
- 13
- };
-
- static static_codebook _44c2_s_p8_0 = {
- 2, 169,
- _vq_lengthlist__44c2_s_p8_0,
- 1, -526516224, 1616117760, 4, 0,
- _vq_quantlist__44c2_s_p8_0,
- NULL,
- &_vq_auxt__44c2_s_p8_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c2_s_p8_1[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__44c2_s_p8_1[] = {
- 2, 4, 4, 5, 4, 6, 5, 5, 5, 5, 6, 5, 5, 5, 5, 6,
- 5, 5, 5, 5, 6, 6, 6, 5, 5,
- };
-
- static float _vq_quantthresh__44c2_s_p8_1[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__44c2_s_p8_1[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c2_s_p8_1 = {
- _vq_quantthresh__44c2_s_p8_1,
- _vq_quantmap__44c2_s_p8_1,
- 5,
- 5
- };
-
- static static_codebook _44c2_s_p8_1 = {
- 2, 25,
- _vq_lengthlist__44c2_s_p8_1,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__44c2_s_p8_1,
- NULL,
- &_vq_auxt__44c2_s_p8_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c2_s_p9_0[] = {
- 6,
- 5,
- 7,
- 4,
- 8,
- 3,
- 9,
- 2,
- 10,
- 1,
- 11,
- 0,
- 12,
- };
-
- static long _vq_lengthlist__44c2_s_p9_0[] = {
- 1, 5, 4,12,12,12,12,12,12,12,12,12,12, 4, 9, 8,
- 11,11,11,11,11,11,11,11,11,11, 2, 8, 7,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,10,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,
- };
-
- static float _vq_quantthresh__44c2_s_p9_0[] = {
- -1215.5, -994.5, -773.5, -552.5, -331.5, -110.5, 110.5, 331.5,
- 552.5, 773.5, 994.5, 1215.5,
- };
-
- static long _vq_quantmap__44c2_s_p9_0[] = {
- 11, 9, 7, 5, 3, 1, 0, 2,
- 4, 6, 8, 10, 12,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c2_s_p9_0 = {
- _vq_quantthresh__44c2_s_p9_0,
- _vq_quantmap__44c2_s_p9_0,
- 13,
- 13
- };
-
- static static_codebook _44c2_s_p9_0 = {
- 2, 169,
- _vq_lengthlist__44c2_s_p9_0,
- 1, -514541568, 1627103232, 4, 0,
- _vq_quantlist__44c2_s_p9_0,
- NULL,
- &_vq_auxt__44c2_s_p9_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c2_s_p9_1[] = {
- 6,
- 5,
- 7,
- 4,
- 8,
- 3,
- 9,
- 2,
- 10,
- 1,
- 11,
- 0,
- 12,
- };
-
- static long _vq_lengthlist__44c2_s_p9_1[] = {
- 1, 4, 4, 6, 6, 7, 6, 8, 8,10, 9,10,10, 6, 5, 5,
- 7, 7, 8, 7,10, 9,11,11,12,13, 6, 5, 5, 7, 7, 8,
- 8,10,10,11,11,13,13,18, 8, 8, 8, 8, 9, 9,10,10,
- 12,12,12,13,18, 8, 8, 8, 8, 9, 9,10,10,12,12,13,
- 13,18,11,11, 8, 8,10,10,11,11,12,11,13,12,18,11,
- 11, 9, 7,10,10,11,11,11,12,12,13,17,17,17,10,10,
- 11,11,12,12,12,10,12,12,17,17,17,11,10,11,10,13,
- 12,11,12,12,12,17,17,17,15,14,11,11,12,11,13,10,
- 13,12,17,17,17,14,14,12,10,11,11,13,13,13,13,17,
- 17,16,17,16,13,13,12,10,13,10,14,13,17,16,17,16,
- 17,13,12,12,10,13,11,14,14,
- };
-
- static float _vq_quantthresh__44c2_s_p9_1[] = {
- -93.5, -76.5, -59.5, -42.5, -25.5, -8.5, 8.5, 25.5,
- 42.5, 59.5, 76.5, 93.5,
- };
-
- static long _vq_quantmap__44c2_s_p9_1[] = {
- 11, 9, 7, 5, 3, 1, 0, 2,
- 4, 6, 8, 10, 12,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c2_s_p9_1 = {
- _vq_quantthresh__44c2_s_p9_1,
- _vq_quantmap__44c2_s_p9_1,
- 13,
- 13
- };
-
- static static_codebook _44c2_s_p9_1 = {
- 2, 169,
- _vq_lengthlist__44c2_s_p9_1,
- 1, -522616832, 1620115456, 4, 0,
- _vq_quantlist__44c2_s_p9_1,
- NULL,
- &_vq_auxt__44c2_s_p9_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c2_s_p9_2[] = {
- 8,
- 7,
- 9,
- 6,
- 10,
- 5,
- 11,
- 4,
- 12,
- 3,
- 13,
- 2,
- 14,
- 1,
- 15,
- 0,
- 16,
- };
-
- static long _vq_lengthlist__44c2_s_p9_2[] = {
- 2, 4, 4, 6, 6, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8,
- 8,10, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9,
- 9, 9,10, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9,
- 9, 9, 9,10, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9,
- 9, 9, 9, 9,10,10,10, 8, 7, 8, 8, 8, 8, 9, 9, 9,
- 9, 9, 9, 9, 9,10,11,11, 8, 8, 8, 8, 9, 9, 9, 9,
- 9, 9,10, 9, 9, 9,10,11,10, 8, 8, 8, 8, 9, 9, 9,
- 9, 9, 9, 9,10,10,10,10,11,10, 8, 8, 9, 9, 9, 9,
- 9, 9,10, 9, 9,10, 9,10,11,10,11,11,11, 8, 8, 9,
- 9, 9, 9, 9, 9, 9, 9,10,10,11,11,11,11,11, 9, 9,
- 9, 9, 9, 9,10, 9, 9, 9,10,10,11,11,11,11,11, 9,
- 9, 9, 9, 9, 9, 9, 9, 9,10, 9,10,11,11,11,11,11,
- 9, 9, 9, 9,10,10, 9, 9, 9,10,10,10,11,11,11,11,
- 11,11,11, 9, 9, 9,10, 9, 9,10,10,10,10,11,11,10,
- 11,11,11,11,10, 9,10,10, 9, 9, 9, 9,10,10,11,10,
- 11,11,11,11,11, 9, 9, 9, 9,10, 9,10,10,10,10,11,
- 10,11,11,11,11,11,10,10, 9, 9,10, 9,10,10,10,10,
- 10,10,10,11,11,11,11,11,11, 9, 9,10, 9,10, 9,10,
- 10,
- };
-
- static float _vq_quantthresh__44c2_s_p9_2[] = {
- -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5,
- 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5,
- };
-
- static long _vq_quantmap__44c2_s_p9_2[] = {
- 15, 13, 11, 9, 7, 5, 3, 1,
- 0, 2, 4, 6, 8, 10, 12, 14,
- 16,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c2_s_p9_2 = {
- _vq_quantthresh__44c2_s_p9_2,
- _vq_quantmap__44c2_s_p9_2,
- 17,
- 17
- };
-
- static static_codebook _44c2_s_p9_2 = {
- 2, 289,
- _vq_lengthlist__44c2_s_p9_2,
- 1, -529530880, 1611661312, 5, 0,
- _vq_quantlist__44c2_s_p9_2,
- NULL,
- &_vq_auxt__44c2_s_p9_2,
- NULL,
- 0
- };
-
- static long _huff_lengthlist__44c2_s_short[] = {
- 11, 9,13,12,12,11,12,12,13,15, 8, 2,11, 4, 8, 5,
- 7,10,12,15,13, 7,10, 9, 8, 8,10,13,17,17,11, 4,
- 12, 5, 9, 5, 8,11,14,16,12, 6, 8, 7, 6, 6, 8,11,
- 13,16,11, 4, 9, 5, 6, 4, 6,10,13,16,11, 6,11, 7,
- 7, 6, 7,10,13,15,13, 9,12, 9, 8, 6, 8,10,12,14,
- 14,10,10, 8, 6, 5, 6, 9,11,13,15,11,11, 9, 6, 5,
- 6, 8, 9,12,
- };
-
- static static_codebook _huff_book__44c2_s_short = {
- 2, 100,
- _huff_lengthlist__44c2_s_short,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist__44c3_s_long[] = {
- 5, 6,11,11,11,11,10,10,12,11, 5, 2,11, 5, 6, 6,
- 7, 9,11,13,13,10, 7,11, 6, 7, 8, 9,10,12,11, 5,
- 11, 6, 8, 7, 9,11,14,15,11, 6, 6, 8, 4, 5, 7, 8,
- 10,13,10, 5, 7, 7, 5, 5, 6, 8,10,11,10, 7, 7, 8,
- 6, 5, 5, 7, 9, 9,11, 8, 8,11, 8, 7, 6, 6, 7, 9,
- 12,11,10,13, 9, 9, 7, 7, 7, 9,11,13,12,15,12,11,
- 9, 8, 8, 8,
- };
-
- static static_codebook _huff_book__44c3_s_long = {
- 2, 100,
- _huff_lengthlist__44c3_s_long,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c3_s_p1_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__44c3_s_p1_0[] = {
- 2, 4, 4, 0, 0, 0, 0, 0, 0, 5, 6, 6, 0, 0, 0, 0,
- 0, 0, 5, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 0, 0,
- 0, 0, 0, 6, 7, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 6, 8, 7, 0, 0,
- 0, 0, 0, 0, 7, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 7, 7, 0, 0, 0, 0,
- 0, 0, 7, 8, 8, 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 0, 0,
- 0, 0, 0, 8, 8, 9, 0, 0, 0, 0, 0, 0, 8, 9, 9, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 8, 8, 0, 0,
- 0, 0, 0, 0, 7, 9, 8, 0, 0, 0, 0, 0, 0, 8, 9, 9,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 0,
- 0, 0, 0, 0, 7, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 6, 8, 8, 0, 0, 0, 0, 0, 0, 8, 9, 9, 0,
- 0, 0, 0, 0, 0, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 6, 8, 8, 0, 0, 0, 0, 0, 0, 8, 9, 9,
- 0, 0, 0, 0, 0, 0, 8, 9, 8, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,
- };
-
- static float _vq_quantthresh__44c3_s_p1_0[] = {
- -0.5, 0.5,
- };
-
- static long _vq_quantmap__44c3_s_p1_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c3_s_p1_0 = {
- _vq_quantthresh__44c3_s_p1_0,
- _vq_quantmap__44c3_s_p1_0,
- 3,
- 3
- };
-
- static static_codebook _44c3_s_p1_0 = {
- 8, 6561,
- _vq_lengthlist__44c3_s_p1_0,
- 1, -535822336, 1611661312, 2, 0,
- _vq_quantlist__44c3_s_p1_0,
- NULL,
- &_vq_auxt__44c3_s_p1_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c3_s_p2_0[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__44c3_s_p2_0[] = {
- 2, 5, 5, 0, 0, 0, 5, 5, 0, 0, 0, 5, 5, 0, 0, 0,
- 7, 8, 0, 0, 0, 0, 0, 0, 0, 5, 6, 6, 0, 0, 0, 7,
- 7, 0, 0, 0, 7, 7, 0, 0, 0,10,10, 0, 0, 0, 0, 0,
- 0, 0, 5, 6, 6, 0, 0, 0, 7, 7, 0, 0, 0, 7, 7, 0,
- 0, 0,10,10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 5, 7, 7, 0, 0, 0, 7, 7, 0, 0,
- 0, 7, 7, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 5,
- 7, 7, 0, 0, 0, 7, 7, 0, 0, 0, 7, 7, 0, 0, 0, 9,
- 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 5, 7, 7, 0, 0, 0, 7, 7, 0, 0, 0, 7, 7,
- 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 5, 7, 7, 0,
- 0, 0, 7, 7, 0, 0, 0, 7, 7, 0, 0, 0, 9, 9, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 8,10,10, 0, 0, 0, 9, 9, 0, 0, 0, 9, 9, 0, 0, 0,
- 10,10, 0, 0, 0, 0, 0, 0, 0, 8,10,10, 0, 0, 0, 9,
- 9, 0, 0, 0, 9, 9, 0, 0, 0,10,10, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,
- };
-
- static float _vq_quantthresh__44c3_s_p2_0[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__44c3_s_p2_0[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c3_s_p2_0 = {
- _vq_quantthresh__44c3_s_p2_0,
- _vq_quantmap__44c3_s_p2_0,
- 5,
- 5
- };
-
- static static_codebook _44c3_s_p2_0 = {
- 4, 625,
- _vq_lengthlist__44c3_s_p2_0,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__44c3_s_p2_0,
- NULL,
- &_vq_auxt__44c3_s_p2_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c3_s_p3_0[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__44c3_s_p3_0[] = {
- 2, 4, 3, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 6, 6, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 4, 4, 4, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 9, 9,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 6, 6, 7, 9, 9, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,
- };
-
- static float _vq_quantthresh__44c3_s_p3_0[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__44c3_s_p3_0[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c3_s_p3_0 = {
- _vq_quantthresh__44c3_s_p3_0,
- _vq_quantmap__44c3_s_p3_0,
- 5,
- 5
- };
-
- static static_codebook _44c3_s_p3_0 = {
- 4, 625,
- _vq_lengthlist__44c3_s_p3_0,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__44c3_s_p3_0,
- NULL,
- &_vq_auxt__44c3_s_p3_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c3_s_p4_0[] = {
- 4,
- 3,
- 5,
- 2,
- 6,
- 1,
- 7,
- 0,
- 8,
- };
-
- static long _vq_lengthlist__44c3_s_p4_0[] = {
- 2, 3, 3, 6, 6, 0, 0, 0, 0, 0, 4, 4, 6, 6, 0, 0,
- 0, 0, 0, 4, 4, 6, 6, 0, 0, 0, 0, 0, 5, 5, 6, 6,
- 0, 0, 0, 0, 0, 0, 0, 6, 6, 0, 0, 0, 0, 0, 0, 0,
- 7, 8, 0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 0, 0, 0,
- 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,
- };
-
- static float _vq_quantthresh__44c3_s_p4_0[] = {
- -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5,
- };
-
- static long _vq_quantmap__44c3_s_p4_0[] = {
- 7, 5, 3, 1, 0, 2, 4, 6,
- 8,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c3_s_p4_0 = {
- _vq_quantthresh__44c3_s_p4_0,
- _vq_quantmap__44c3_s_p4_0,
- 9,
- 9
- };
-
- static static_codebook _44c3_s_p4_0 = {
- 2, 81,
- _vq_lengthlist__44c3_s_p4_0,
- 1, -531628032, 1611661312, 4, 0,
- _vq_quantlist__44c3_s_p4_0,
- NULL,
- &_vq_auxt__44c3_s_p4_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c3_s_p5_0[] = {
- 4,
- 3,
- 5,
- 2,
- 6,
- 1,
- 7,
- 0,
- 8,
- };
-
- static long _vq_lengthlist__44c3_s_p5_0[] = {
- 1, 3, 4, 6, 6, 7, 7, 9, 9, 0, 5, 5, 7, 7, 7, 8,
- 9, 9, 0, 5, 5, 7, 7, 8, 8, 9, 9, 0, 7, 7, 8, 8,
- 8, 8,10,10, 0, 0, 0, 8, 8, 8, 8,10,10, 0, 0, 0,
- 9, 9, 9, 9,10,10, 0, 0, 0, 9, 9, 9, 9,10,10, 0,
- 0, 0,10,10,10,10,11,11, 0, 0, 0, 0, 0,10,10,11,
- 11,
- };
-
- static float _vq_quantthresh__44c3_s_p5_0[] = {
- -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5,
- };
-
- static long _vq_quantmap__44c3_s_p5_0[] = {
- 7, 5, 3, 1, 0, 2, 4, 6,
- 8,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c3_s_p5_0 = {
- _vq_quantthresh__44c3_s_p5_0,
- _vq_quantmap__44c3_s_p5_0,
- 9,
- 9
- };
-
- static static_codebook _44c3_s_p5_0 = {
- 2, 81,
- _vq_lengthlist__44c3_s_p5_0,
- 1, -531628032, 1611661312, 4, 0,
- _vq_quantlist__44c3_s_p5_0,
- NULL,
- &_vq_auxt__44c3_s_p5_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c3_s_p6_0[] = {
- 8,
- 7,
- 9,
- 6,
- 10,
- 5,
- 11,
- 4,
- 12,
- 3,
- 13,
- 2,
- 14,
- 1,
- 15,
- 0,
- 16,
- };
-
- static long _vq_lengthlist__44c3_s_p6_0[] = {
- 2, 3, 3, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9,10,10,11,
- 10, 0, 5, 5, 7, 7, 8, 8, 9, 9, 9, 9,10,10,10,10,
- 11,11, 0, 5, 5, 7, 7, 8, 8, 9, 9, 9, 9,10,10,10,
- 10,11,11, 0, 6, 6, 7, 7, 8, 8, 9, 9, 9, 9,10,10,
- 11,11,11,11, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10,
- 10,11,11,11,12, 0, 0, 0, 8, 8, 8, 8, 9, 9, 9, 9,
- 10,10,11,11,12,12, 0, 0, 0, 8, 8, 8, 8, 9, 9, 9,
- 9,10,10,11,11,12,12, 0, 0, 0, 9, 9, 9, 9,10,10,
- 10,10,11,10,11,11,12,12, 0, 0, 0, 0, 0, 9, 9,10,
- 10,10,10,11,11,11,11,12,12, 0, 0, 0, 0, 0, 9, 8,
- 9, 9,10,10,11,11,12,12,12,12, 0, 0, 0, 0, 0, 8,
- 8, 9, 9,10,10,11,11,12,11,12,12, 0, 0, 0, 0, 0,
- 9,10,10,10,11,11,11,11,12,12,13,13, 0, 0, 0, 0,
- 0, 0, 0,10,10,10,10,11,11,12,12,13,13, 0, 0, 0,
- 0, 0, 0, 0,11,11,11,11,12,12,12,12,13,13, 0, 0,
- 0, 0, 0, 0, 0,11,11,11,11,12,12,12,12,13,13, 0,
- 0, 0, 0, 0, 0, 0,11,11,12,12,12,12,13,13,13,13,
- 0, 0, 0, 0, 0, 0, 0, 0, 0,12,12,12,12,13,13,13,
- 13,
- };
-
- static float _vq_quantthresh__44c3_s_p6_0[] = {
- -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5,
- 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5,
- };
-
- static long _vq_quantmap__44c3_s_p6_0[] = {
- 15, 13, 11, 9, 7, 5, 3, 1,
- 0, 2, 4, 6, 8, 10, 12, 14,
- 16,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c3_s_p6_0 = {
- _vq_quantthresh__44c3_s_p6_0,
- _vq_quantmap__44c3_s_p6_0,
- 17,
- 17
- };
-
- static static_codebook _44c3_s_p6_0 = {
- 2, 289,
- _vq_lengthlist__44c3_s_p6_0,
- 1, -529530880, 1611661312, 5, 0,
- _vq_quantlist__44c3_s_p6_0,
- NULL,
- &_vq_auxt__44c3_s_p6_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c3_s_p7_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__44c3_s_p7_0[] = {
- 1, 4, 4, 7, 6, 6, 7, 6, 6, 4, 7, 7,10, 9, 9,11,
- 9, 9, 4, 7, 7,10, 9, 9,11, 9, 9, 7,10,10,11,11,
- 10,12,11,11, 6, 9, 9,11,10,10,11,10,10, 6, 9, 9,
- 11,10,10,11,10,10, 7,11,11,11,11,11,12,11,11, 6,
- 9, 9,11,10,10,11,10,10, 6, 9, 9,11,10,10,11,10,
- 10,
- };
-
- static float _vq_quantthresh__44c3_s_p7_0[] = {
- -5.5, 5.5,
- };
-
- static long _vq_quantmap__44c3_s_p7_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c3_s_p7_0 = {
- _vq_quantthresh__44c3_s_p7_0,
- _vq_quantmap__44c3_s_p7_0,
- 3,
- 3
- };
-
- static static_codebook _44c3_s_p7_0 = {
- 4, 81,
- _vq_lengthlist__44c3_s_p7_0,
- 1, -529137664, 1618345984, 2, 0,
- _vq_quantlist__44c3_s_p7_0,
- NULL,
- &_vq_auxt__44c3_s_p7_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c3_s_p7_1[] = {
- 5,
- 4,
- 6,
- 3,
- 7,
- 2,
- 8,
- 1,
- 9,
- 0,
- 10,
- };
-
- static long _vq_lengthlist__44c3_s_p7_1[] = {
- 2, 4, 4, 6, 6, 7, 7, 7, 7, 8, 8,10, 5, 5, 6, 6,
- 7, 7, 8, 8, 8, 8,10, 5, 5, 6, 6, 7, 7, 8, 8, 8,
- 8,10, 6, 6, 7, 7, 8, 8, 8, 8, 8, 8,10,10,10, 7,
- 7, 8, 7, 8, 8, 8, 8,10,10,10, 8, 8, 8, 8, 8, 8,
- 8, 8,10,10,10, 7, 8, 8, 8, 8, 8, 8, 8,10,10,10,
- 8, 8, 8, 8, 8, 8, 8, 8,10,10,10,10,10, 8, 8, 8,
- 8, 8, 8,10,10,10,10,10, 9, 9, 8, 8, 9, 8,10,10,
- 10,10,10, 8, 8, 8, 8, 8, 8,
- };
-
- static float _vq_quantthresh__44c3_s_p7_1[] = {
- -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5,
- 3.5, 4.5,
- };
-
- static long _vq_quantmap__44c3_s_p7_1[] = {
- 9, 7, 5, 3, 1, 0, 2, 4,
- 6, 8, 10,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c3_s_p7_1 = {
- _vq_quantthresh__44c3_s_p7_1,
- _vq_quantmap__44c3_s_p7_1,
- 11,
- 11
- };
-
- static static_codebook _44c3_s_p7_1 = {
- 2, 121,
- _vq_lengthlist__44c3_s_p7_1,
- 1, -531365888, 1611661312, 4, 0,
- _vq_quantlist__44c3_s_p7_1,
- NULL,
- &_vq_auxt__44c3_s_p7_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c3_s_p8_0[] = {
- 6,
- 5,
- 7,
- 4,
- 8,
- 3,
- 9,
- 2,
- 10,
- 1,
- 11,
- 0,
- 12,
- };
-
- static long _vq_lengthlist__44c3_s_p8_0[] = {
- 1, 4, 4, 6, 6, 7, 7, 8, 8, 9, 9,10,10, 6, 5, 5,
- 7, 7, 8, 8, 8, 8, 9, 9,10,10, 7, 5, 5, 7, 7, 8,
- 8, 8, 8, 9, 9,11,10, 0, 8, 8, 8, 8, 9, 9, 9, 9,
- 10,10,11,11, 0, 8, 8, 8, 8, 9, 9, 9, 9,10,10,11,
- 11, 0,12,12, 9, 9,10,10,10,10,11,11,11,12, 0,13,
- 13, 9, 9,10,10,10,10,11,11,12,12, 0, 0, 0,10,10,
- 10,10,11,11,12,12,12,12, 0, 0, 0,10,10,10,10,11,
- 11,12,12,12,12, 0, 0, 0,14,14,11,11,11,11,12,12,
- 13,13, 0, 0, 0,14,14,11,11,11,11,12,12,13,13, 0,
- 0, 0, 0, 0,12,12,12,12,13,13,14,13, 0, 0, 0, 0,
- 0,13,13,12,12,13,12,14,13,
- };
-
- static float _vq_quantthresh__44c3_s_p8_0[] = {
- -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5,
- 12.5, 17.5, 22.5, 27.5,
- };
-
- static long _vq_quantmap__44c3_s_p8_0[] = {
- 11, 9, 7, 5, 3, 1, 0, 2,
- 4, 6, 8, 10, 12,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c3_s_p8_0 = {
- _vq_quantthresh__44c3_s_p8_0,
- _vq_quantmap__44c3_s_p8_0,
- 13,
- 13
- };
-
- static static_codebook _44c3_s_p8_0 = {
- 2, 169,
- _vq_lengthlist__44c3_s_p8_0,
- 1, -526516224, 1616117760, 4, 0,
- _vq_quantlist__44c3_s_p8_0,
- NULL,
- &_vq_auxt__44c3_s_p8_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c3_s_p8_1[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__44c3_s_p8_1[] = {
- 2, 4, 4, 5, 5, 6, 5, 5, 5, 5, 6, 4, 5, 5, 5, 6,
- 5, 5, 5, 5, 6, 6, 6, 5, 5,
- };
-
- static float _vq_quantthresh__44c3_s_p8_1[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__44c3_s_p8_1[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c3_s_p8_1 = {
- _vq_quantthresh__44c3_s_p8_1,
- _vq_quantmap__44c3_s_p8_1,
- 5,
- 5
- };
-
- static static_codebook _44c3_s_p8_1 = {
- 2, 25,
- _vq_lengthlist__44c3_s_p8_1,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__44c3_s_p8_1,
- NULL,
- &_vq_auxt__44c3_s_p8_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c3_s_p9_0[] = {
- 6,
- 5,
- 7,
- 4,
- 8,
- 3,
- 9,
- 2,
- 10,
- 1,
- 11,
- 0,
- 12,
- };
-
- static long _vq_lengthlist__44c3_s_p9_0[] = {
- 1, 4, 4,12,12,12,12,12,12,12,12,12,12, 4, 9, 8,
- 12,12,12,12,12,12,12,12,12,12, 2, 9, 7,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,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,
- 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,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,12,12,12,12,12,12,12,12,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,
- };
-
- static float _vq_quantthresh__44c3_s_p9_0[] = {
- -1402.5, -1147.5, -892.5, -637.5, -382.5, -127.5, 127.5, 382.5,
- 637.5, 892.5, 1147.5, 1402.5,
- };
-
- static long _vq_quantmap__44c3_s_p9_0[] = {
- 11, 9, 7, 5, 3, 1, 0, 2,
- 4, 6, 8, 10, 12,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c3_s_p9_0 = {
- _vq_quantthresh__44c3_s_p9_0,
- _vq_quantmap__44c3_s_p9_0,
- 13,
- 13
- };
-
- static static_codebook _44c3_s_p9_0 = {
- 2, 169,
- _vq_lengthlist__44c3_s_p9_0,
- 1, -514332672, 1627381760, 4, 0,
- _vq_quantlist__44c3_s_p9_0,
- NULL,
- &_vq_auxt__44c3_s_p9_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c3_s_p9_1[] = {
- 7,
- 6,
- 8,
- 5,
- 9,
- 4,
- 10,
- 3,
- 11,
- 2,
- 12,
- 1,
- 13,
- 0,
- 14,
- };
-
- static long _vq_lengthlist__44c3_s_p9_1[] = {
- 1, 4, 4, 6, 6, 7, 7, 8, 7, 9, 9,10,10,10,10, 6,
- 5, 5, 7, 7, 8, 8,10, 8,11,10,12,12,13,13, 6, 5,
- 5, 7, 7, 8, 8,10, 9,11,11,12,12,13,12,18, 8, 8,
- 8, 8, 9, 9,10, 9,11,10,12,12,13,13,18, 8, 8, 8,
- 8, 9, 9,10,10,11,11,13,12,14,13,18,11,11, 9, 9,
- 10,10,11,11,11,12,13,12,13,14,18,11,11, 9, 8,11,
- 10,11,11,11,11,12,12,14,13,18,18,18,10,11,10,11,
- 12,12,12,12,13,12,14,13,18,18,18,10,11,11, 9,12,
- 11,12,12,12,13,13,13,18,18,17,14,14,11,11,12,12,
- 13,12,14,12,14,13,18,18,18,14,14,11,10,12, 9,12,
- 13,13,13,13,13,18,18,17,16,18,13,13,12,12,13,11,
- 14,12,14,14,17,18,18,17,18,13,12,13,10,12,11,14,
- 14,14,14,17,18,18,18,18,15,16,12,12,13,10,14,12,
- 14,15,18,18,18,16,17,16,14,12,11,13,10,13,13,14,
- 15,
- };
-
- static float _vq_quantthresh__44c3_s_p9_1[] = {
- -110.5, -93.5, -76.5, -59.5, -42.5, -25.5, -8.5, 8.5,
- 25.5, 42.5, 59.5, 76.5, 93.5, 110.5,
- };
-
- static long _vq_quantmap__44c3_s_p9_1[] = {
- 13, 11, 9, 7, 5, 3, 1, 0,
- 2, 4, 6, 8, 10, 12, 14,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c3_s_p9_1 = {
- _vq_quantthresh__44c3_s_p9_1,
- _vq_quantmap__44c3_s_p9_1,
- 15,
- 15
- };
-
- static static_codebook _44c3_s_p9_1 = {
- 2, 225,
- _vq_lengthlist__44c3_s_p9_1,
- 1, -522338304, 1620115456, 4, 0,
- _vq_quantlist__44c3_s_p9_1,
- NULL,
- &_vq_auxt__44c3_s_p9_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c3_s_p9_2[] = {
- 8,
- 7,
- 9,
- 6,
- 10,
- 5,
- 11,
- 4,
- 12,
- 3,
- 13,
- 2,
- 14,
- 1,
- 15,
- 0,
- 16,
- };
-
- static long _vq_lengthlist__44c3_s_p9_2[] = {
- 2, 5, 5, 6, 6, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8,
- 8,10, 6, 6, 7, 7, 8, 7, 8, 8, 8, 8, 8, 9, 9, 9,
- 9, 9,10, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9,
- 9, 9, 9,10, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9,
- 9, 9, 9, 9,10,10,10, 7, 7, 8, 8, 8, 9, 9, 9, 9,
- 9, 9, 9, 9, 9,11,11,11, 8, 8, 8, 8, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9,10,10,10, 8, 8, 8, 8, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9,10,10,10, 8, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9,10, 9,10,10,10,11,11, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9,11,10,11,11,11, 9, 9,
- 9, 9, 9, 9,10,10, 9, 9,10, 9,11,10,11,11,11, 9,
- 9, 9, 9, 9, 9, 9, 9,10,10,10, 9,11,11,11,11,11,
- 9, 9, 9, 9,10,10, 9, 9, 9, 9,10, 9,11,11,11,11,
- 11,11,11, 9, 9, 9, 9, 9, 9,10,10,10,10,11,11,11,
- 11,11,11,11,10, 9,10,10, 9,10, 9, 9,10, 9,11,10,
- 10,11,11,11,11, 9,10, 9, 9, 9, 9,10,10,10,10,11,
- 11,11,11,11,11,10,10,10, 9, 9,10, 9,10, 9,10,10,
- 10,10,11,11,11,11,11,11,11, 9, 9, 9, 9, 9,10,10,
- 10,
- };
-
- static float _vq_quantthresh__44c3_s_p9_2[] = {
- -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5,
- 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5,
- };
-
- static long _vq_quantmap__44c3_s_p9_2[] = {
- 15, 13, 11, 9, 7, 5, 3, 1,
- 0, 2, 4, 6, 8, 10, 12, 14,
- 16,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c3_s_p9_2 = {
- _vq_quantthresh__44c3_s_p9_2,
- _vq_quantmap__44c3_s_p9_2,
- 17,
- 17
- };
-
- static static_codebook _44c3_s_p9_2 = {
- 2, 289,
- _vq_lengthlist__44c3_s_p9_2,
- 1, -529530880, 1611661312, 5, 0,
- _vq_quantlist__44c3_s_p9_2,
- NULL,
- &_vq_auxt__44c3_s_p9_2,
- NULL,
- 0
- };
-
- static long _huff_lengthlist__44c3_s_short[] = {
- 10, 9,13,11,14,10,12,13,13,14, 7, 2,12, 5,10, 5,
- 7,10,12,14,12, 6, 9, 8, 7, 7, 9,11,13,16,10, 4,
- 12, 5,10, 6, 8,12,14,16,12, 6, 8, 7, 6, 5, 7,11,
- 12,16,10, 4, 8, 5, 6, 4, 6, 9,13,16,10, 6,10, 7,
- 7, 6, 7, 9,13,15,12, 9,11, 9, 8, 6, 7,10,12,14,
- 14,11,10, 9, 6, 5, 6, 9,11,13,15,13,11,10, 6, 5,
- 6, 8, 9,11,
- };
-
- static static_codebook _huff_book__44c3_s_short = {
- 2, 100,
- _huff_lengthlist__44c3_s_short,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist__44c4_s_long[] = {
- 4, 7,11,11,11,11,10,11,12,11, 5, 2,11, 5, 6, 6,
- 7, 9,11,12,11, 9, 6,10, 6, 7, 8, 9,10,11,11, 5,
- 11, 7, 8, 8, 9,11,13,14,11, 6, 5, 8, 4, 5, 7, 8,
- 10,11,10, 6, 7, 7, 5, 5, 6, 8, 9,11,10, 7, 8, 9,
- 6, 6, 6, 7, 8, 9,11, 9, 9,11, 7, 7, 6, 6, 7, 9,
- 12,12,10,13, 9, 8, 7, 7, 7, 8,11,13,11,14,11,10,
- 9, 8, 7, 7,
- };
-
- static static_codebook _huff_book__44c4_s_long = {
- 2, 100,
- _huff_lengthlist__44c4_s_long,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c4_s_p1_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__44c4_s_p1_0[] = {
- 2, 4, 4, 0, 0, 0, 0, 0, 0, 5, 6, 6, 0, 0, 0, 0,
- 0, 0, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 0, 0,
- 0, 0, 0, 6, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 6, 8, 7, 0, 0,
- 0, 0, 0, 0, 7, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 7, 7, 0, 0, 0, 0,
- 0, 0, 7, 8, 8, 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 0, 0,
- 0, 0, 0, 8, 9, 9, 0, 0, 0, 0, 0, 0, 8, 9, 9, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 8, 8, 0, 0,
- 0, 0, 0, 0, 8, 9, 8, 0, 0, 0, 0, 0, 0, 8, 9, 9,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 4, 7, 7, 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 0,
- 0, 0, 0, 0, 7, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 6, 8, 8, 0, 0, 0, 0, 0, 0, 8, 9, 9, 0,
- 0, 0, 0, 0, 0, 8, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 7, 8, 8, 0, 0, 0, 0, 0, 0, 8, 9, 9,
- 0, 0, 0, 0, 0, 0, 8, 9, 9, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,
- };
-
- static float _vq_quantthresh__44c4_s_p1_0[] = {
- -0.5, 0.5,
- };
-
- static long _vq_quantmap__44c4_s_p1_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c4_s_p1_0 = {
- _vq_quantthresh__44c4_s_p1_0,
- _vq_quantmap__44c4_s_p1_0,
- 3,
- 3
- };
-
- static static_codebook _44c4_s_p1_0 = {
- 8, 6561,
- _vq_lengthlist__44c4_s_p1_0,
- 1, -535822336, 1611661312, 2, 0,
- _vq_quantlist__44c4_s_p1_0,
- NULL,
- &_vq_auxt__44c4_s_p1_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c4_s_p2_0[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__44c4_s_p2_0[] = {
- 2, 5, 5, 0, 0, 0, 5, 5, 0, 0, 0, 5, 5, 0, 0, 0,
- 7, 7, 0, 0, 0, 0, 0, 0, 0, 5, 6, 6, 0, 0, 0, 7,
- 7, 0, 0, 0, 7, 7, 0, 0, 0,10,10, 0, 0, 0, 0, 0,
- 0, 0, 5, 6, 6, 0, 0, 0, 7, 7, 0, 0, 0, 7, 7, 0,
- 0, 0,10,10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 5, 8, 7, 0, 0, 0, 7, 7, 0, 0,
- 0, 7, 7, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 5,
- 7, 8, 0, 0, 0, 7, 7, 0, 0, 0, 7, 7, 0, 0, 0, 9,
- 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 5, 7, 7, 0, 0, 0, 7, 7, 0, 0, 0, 7, 7,
- 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 5, 7, 7, 0,
- 0, 0, 7, 7, 0, 0, 0, 7, 7, 0, 0, 0, 9, 9, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 7,10,10, 0, 0, 0, 9, 9, 0, 0, 0, 9, 9, 0, 0, 0,
- 10,10, 0, 0, 0, 0, 0, 0, 0, 8,10,10, 0, 0, 0, 9,
- 9, 0, 0, 0, 9, 9, 0, 0, 0,10,10, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,
- };
-
- static float _vq_quantthresh__44c4_s_p2_0[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__44c4_s_p2_0[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c4_s_p2_0 = {
- _vq_quantthresh__44c4_s_p2_0,
- _vq_quantmap__44c4_s_p2_0,
- 5,
- 5
- };
-
- static static_codebook _44c4_s_p2_0 = {
- 4, 625,
- _vq_lengthlist__44c4_s_p2_0,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__44c4_s_p2_0,
- NULL,
- &_vq_auxt__44c4_s_p2_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c4_s_p3_0[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__44c4_s_p3_0[] = {
- 2, 3, 3, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 5, 4, 6, 6, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 4, 4, 5, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 9, 9,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 6, 6, 7, 9, 9, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,
- };
-
- static float _vq_quantthresh__44c4_s_p3_0[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__44c4_s_p3_0[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c4_s_p3_0 = {
- _vq_quantthresh__44c4_s_p3_0,
- _vq_quantmap__44c4_s_p3_0,
- 5,
- 5
- };
-
- static static_codebook _44c4_s_p3_0 = {
- 4, 625,
- _vq_lengthlist__44c4_s_p3_0,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__44c4_s_p3_0,
- NULL,
- &_vq_auxt__44c4_s_p3_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c4_s_p4_0[] = {
- 4,
- 3,
- 5,
- 2,
- 6,
- 1,
- 7,
- 0,
- 8,
- };
-
- static long _vq_lengthlist__44c4_s_p4_0[] = {
- 2, 3, 3, 6, 6, 0, 0, 0, 0, 0, 4, 4, 6, 6, 0, 0,
- 0, 0, 0, 4, 4, 6, 6, 0, 0, 0, 0, 0, 5, 5, 6, 6,
- 0, 0, 0, 0, 0, 0, 0, 6, 6, 0, 0, 0, 0, 0, 0, 0,
- 7, 8, 0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 0, 0, 0,
- 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,
- };
-
- static float _vq_quantthresh__44c4_s_p4_0[] = {
- -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5,
- };
-
- static long _vq_quantmap__44c4_s_p4_0[] = {
- 7, 5, 3, 1, 0, 2, 4, 6,
- 8,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c4_s_p4_0 = {
- _vq_quantthresh__44c4_s_p4_0,
- _vq_quantmap__44c4_s_p4_0,
- 9,
- 9
- };
-
- static static_codebook _44c4_s_p4_0 = {
- 2, 81,
- _vq_lengthlist__44c4_s_p4_0,
- 1, -531628032, 1611661312, 4, 0,
- _vq_quantlist__44c4_s_p4_0,
- NULL,
- &_vq_auxt__44c4_s_p4_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c4_s_p5_0[] = {
- 4,
- 3,
- 5,
- 2,
- 6,
- 1,
- 7,
- 0,
- 8,
- };
-
- static long _vq_lengthlist__44c4_s_p5_0[] = {
- 2, 3, 3, 6, 6, 7, 7, 9, 9, 0, 4, 4, 6, 6, 7, 7,
- 9, 9, 0, 4, 5, 6, 6, 7, 7, 9, 9, 0, 6, 6, 7, 7,
- 8, 8,10,10, 0, 0, 0, 7, 7, 8, 8,10, 9, 0, 0, 0,
- 9, 8, 8, 8,10,10, 0, 0, 0, 8, 8, 8, 8,10,10, 0,
- 0, 0,10,10, 9, 9,11,11, 0, 0, 0, 0, 0, 9, 9,10,
- 10,
- };
-
- static float _vq_quantthresh__44c4_s_p5_0[] = {
- -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5,
- };
-
- static long _vq_quantmap__44c4_s_p5_0[] = {
- 7, 5, 3, 1, 0, 2, 4, 6,
- 8,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c4_s_p5_0 = {
- _vq_quantthresh__44c4_s_p5_0,
- _vq_quantmap__44c4_s_p5_0,
- 9,
- 9
- };
-
- static static_codebook _44c4_s_p5_0 = {
- 2, 81,
- _vq_lengthlist__44c4_s_p5_0,
- 1, -531628032, 1611661312, 4, 0,
- _vq_quantlist__44c4_s_p5_0,
- NULL,
- &_vq_auxt__44c4_s_p5_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c4_s_p6_0[] = {
- 8,
- 7,
- 9,
- 6,
- 10,
- 5,
- 11,
- 4,
- 12,
- 3,
- 13,
- 2,
- 14,
- 1,
- 15,
- 0,
- 16,
- };
-
- static long _vq_lengthlist__44c4_s_p6_0[] = {
- 2, 4, 4, 6, 6, 8, 8, 9, 9, 8, 8, 9, 9,10,10,11,
- 11, 0, 4, 4, 6, 6, 8, 8, 9, 9, 9, 9,10,10,11,11,
- 11,11, 0, 4, 4, 7, 6, 8, 8, 9, 9, 9, 9,10,10,11,
- 11,11,11, 0, 6, 6, 7, 7, 8, 8, 9, 9, 9, 9,10,10,
- 11,11,11,12, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10,
- 10,11,11,12,12, 0, 0, 0, 8, 8, 8, 8, 9, 9, 9, 9,
- 10,10,11,11,12,12, 0, 0, 0, 8, 8, 8, 8, 9, 9, 9,
- 9,10,10,11,11,12,12, 0, 0, 0, 9, 9, 9, 9,10,10,
- 10,10,11,11,11,11,12,12, 0, 0, 0, 0, 0, 9, 9,10,
- 10,10,10,11,11,11,11,12,12, 0, 0, 0, 0, 0, 9, 9,
- 9,10,10,10,11,11,11,11,12,12, 0, 0, 0, 0, 0, 9,
- 9, 9, 9,10,10,11,11,11,12,12,12, 0, 0, 0, 0, 0,
- 10,10,10,10,11,11,11,11,12,12,13,12, 0, 0, 0, 0,
- 0, 0, 0,10,10,11,11,11,11,12,12,12,12, 0, 0, 0,
- 0, 0, 0, 0,11,11,11,11,12,12,12,12,13,13, 0, 0,
- 0, 0, 0, 0, 0,11,11,11,11,12,12,12,12,13,13, 0,
- 0, 0, 0, 0, 0, 0,12,12,12,12,12,12,13,13,13,13,
- 0, 0, 0, 0, 0, 0, 0, 0, 0,12,12,12,12,12,13,13,
- 13,
- };
-
- static float _vq_quantthresh__44c4_s_p6_0[] = {
- -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5,
- 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5,
- };
-
- static long _vq_quantmap__44c4_s_p6_0[] = {
- 15, 13, 11, 9, 7, 5, 3, 1,
- 0, 2, 4, 6, 8, 10, 12, 14,
- 16,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c4_s_p6_0 = {
- _vq_quantthresh__44c4_s_p6_0,
- _vq_quantmap__44c4_s_p6_0,
- 17,
- 17
- };
-
- static static_codebook _44c4_s_p6_0 = {
- 2, 289,
- _vq_lengthlist__44c4_s_p6_0,
- 1, -529530880, 1611661312, 5, 0,
- _vq_quantlist__44c4_s_p6_0,
- NULL,
- &_vq_auxt__44c4_s_p6_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c4_s_p7_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__44c4_s_p7_0[] = {
- 1, 4, 4, 7, 6, 6, 7, 6, 6, 4, 7, 7,10, 9, 9,11,
- 9, 9, 4, 7, 7,10, 9, 9,11, 9, 9, 7,10,10,11,11,
- 10,11,11,11, 6, 9, 9,11,10,10,11,10,10, 6, 9, 9,
- 11,10,10,11,10,10, 7,11,11,12,11,11,12,11,11, 6,
- 9, 9,11,10,10,11,10,10, 6, 9, 9,11,10,10,11,10,
- 10,
- };
-
- static float _vq_quantthresh__44c4_s_p7_0[] = {
- -5.5, 5.5,
- };
-
- static long _vq_quantmap__44c4_s_p7_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c4_s_p7_0 = {
- _vq_quantthresh__44c4_s_p7_0,
- _vq_quantmap__44c4_s_p7_0,
- 3,
- 3
- };
-
- static static_codebook _44c4_s_p7_0 = {
- 4, 81,
- _vq_lengthlist__44c4_s_p7_0,
- 1, -529137664, 1618345984, 2, 0,
- _vq_quantlist__44c4_s_p7_0,
- NULL,
- &_vq_auxt__44c4_s_p7_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c4_s_p7_1[] = {
- 5,
- 4,
- 6,
- 3,
- 7,
- 2,
- 8,
- 1,
- 9,
- 0,
- 10,
- };
-
- static long _vq_lengthlist__44c4_s_p7_1[] = {
- 2, 4, 4, 6, 6, 7, 7, 7, 7, 8, 8,10, 5, 5, 6, 6,
- 7, 7, 8, 8, 8, 8,10, 5, 5, 6, 6, 7, 7, 8, 8, 8,
- 8,10, 6, 6, 7, 7, 8, 8, 8, 8, 8, 8,10,10,10, 7,
- 7, 8, 8, 8, 8, 8, 8,10,10,10, 8, 7, 8, 8, 8, 8,
- 8, 8,10,10,10, 7, 7, 8, 8, 8, 8, 8, 8,10,10,10,
- 8, 8, 8, 8, 8, 8, 8, 8,10,10,10,10,10, 8, 8, 8,
- 8, 8, 8,10,10,10,10,10, 9, 9, 8, 8, 9, 8,10,10,
- 10,10,10, 8, 8, 8, 8, 9, 9,
- };
-
- static float _vq_quantthresh__44c4_s_p7_1[] = {
- -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5,
- 3.5, 4.5,
- };
-
- static long _vq_quantmap__44c4_s_p7_1[] = {
- 9, 7, 5, 3, 1, 0, 2, 4,
- 6, 8, 10,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c4_s_p7_1 = {
- _vq_quantthresh__44c4_s_p7_1,
- _vq_quantmap__44c4_s_p7_1,
- 11,
- 11
- };
-
- static static_codebook _44c4_s_p7_1 = {
- 2, 121,
- _vq_lengthlist__44c4_s_p7_1,
- 1, -531365888, 1611661312, 4, 0,
- _vq_quantlist__44c4_s_p7_1,
- NULL,
- &_vq_auxt__44c4_s_p7_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c4_s_p8_0[] = {
- 6,
- 5,
- 7,
- 4,
- 8,
- 3,
- 9,
- 2,
- 10,
- 1,
- 11,
- 0,
- 12,
- };
-
- static long _vq_lengthlist__44c4_s_p8_0[] = {
- 1, 4, 4, 6, 6, 7, 7, 8, 8, 9, 9,10,10, 6, 5, 5,
- 7, 7, 8, 8, 8, 8, 9,10,11,11, 7, 5, 5, 7, 7, 8,
- 8, 9, 9,10,10,11,11, 0, 8, 8, 8, 8, 9, 9, 9, 9,
- 10,10,11,11, 0, 8, 8, 8, 8, 9, 9, 9, 9,10,10,11,
- 11, 0,12,12, 9, 9, 9, 9,10,10,10,10,11,11, 0,13,
- 13, 9, 9,10, 9,10,10,11,11,11,12, 0, 0, 0,10,10,
- 10,10,10,10,11,11,12,12, 0, 0, 0,10,10,10,10,10,
- 10,11,11,12,12, 0, 0, 0,14,14,11,11,11,11,12,12,
- 12,12, 0, 0, 0,14,14,11,11,11,11,12,12,12,13, 0,
- 0, 0, 0, 0,12,12,12,12,12,12,13,13, 0, 0, 0, 0,
- 0,13,12,12,12,12,12,13,13,
- };
-
- static float _vq_quantthresh__44c4_s_p8_0[] = {
- -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5,
- 12.5, 17.5, 22.5, 27.5,
- };
-
- static long _vq_quantmap__44c4_s_p8_0[] = {
- 11, 9, 7, 5, 3, 1, 0, 2,
- 4, 6, 8, 10, 12,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c4_s_p8_0 = {
- _vq_quantthresh__44c4_s_p8_0,
- _vq_quantmap__44c4_s_p8_0,
- 13,
- 13
- };
-
- static static_codebook _44c4_s_p8_0 = {
- 2, 169,
- _vq_lengthlist__44c4_s_p8_0,
- 1, -526516224, 1616117760, 4, 0,
- _vq_quantlist__44c4_s_p8_0,
- NULL,
- &_vq_auxt__44c4_s_p8_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c4_s_p8_1[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__44c4_s_p8_1[] = {
- 2, 4, 4, 5, 5, 6, 5, 5, 5, 5, 6, 5, 4, 5, 5, 6,
- 5, 5, 5, 5, 6, 6, 6, 5, 5,
- };
-
- static float _vq_quantthresh__44c4_s_p8_1[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__44c4_s_p8_1[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c4_s_p8_1 = {
- _vq_quantthresh__44c4_s_p8_1,
- _vq_quantmap__44c4_s_p8_1,
- 5,
- 5
- };
-
- static static_codebook _44c4_s_p8_1 = {
- 2, 25,
- _vq_lengthlist__44c4_s_p8_1,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__44c4_s_p8_1,
- NULL,
- &_vq_auxt__44c4_s_p8_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c4_s_p9_0[] = {
- 6,
- 5,
- 7,
- 4,
- 8,
- 3,
- 9,
- 2,
- 10,
- 1,
- 11,
- 0,
- 12,
- };
-
- static long _vq_lengthlist__44c4_s_p9_0[] = {
- 1, 3, 3,12,12,12,12,12,12,12,12,12,12, 4, 7, 7,
- 12,12,12,12,12,12,12,12,12,12, 3, 8, 8,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,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,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,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,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,12,12,12,12,12,12,
- 12,12,12,12,12,12,12,12,12,
- };
-
- static float _vq_quantthresh__44c4_s_p9_0[] = {
- -1732.5, -1417.5, -1102.5, -787.5, -472.5, -157.5, 157.5, 472.5,
- 787.5, 1102.5, 1417.5, 1732.5,
- };
-
- static long _vq_quantmap__44c4_s_p9_0[] = {
- 11, 9, 7, 5, 3, 1, 0, 2,
- 4, 6, 8, 10, 12,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c4_s_p9_0 = {
- _vq_quantthresh__44c4_s_p9_0,
- _vq_quantmap__44c4_s_p9_0,
- 13,
- 13
- };
-
- static static_codebook _44c4_s_p9_0 = {
- 2, 169,
- _vq_lengthlist__44c4_s_p9_0,
- 1, -513964032, 1628680192, 4, 0,
- _vq_quantlist__44c4_s_p9_0,
- NULL,
- &_vq_auxt__44c4_s_p9_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c4_s_p9_1[] = {
- 7,
- 6,
- 8,
- 5,
- 9,
- 4,
- 10,
- 3,
- 11,
- 2,
- 12,
- 1,
- 13,
- 0,
- 14,
- };
-
- static long _vq_lengthlist__44c4_s_p9_1[] = {
- 1, 4, 4, 5, 5, 7, 7, 9, 8,10, 9,10,10,10,10, 6,
- 5, 5, 7, 7, 9, 8,10, 9,11,10,12,12,13,13, 6, 5,
- 5, 7, 7, 9, 9,10,10,11,11,12,12,12,13,19, 8, 8,
- 8, 8, 9, 9,10,10,12,11,12,12,13,13,19, 8, 8, 8,
- 8, 9, 9,11,11,12,12,13,13,13,13,19,12,12, 9, 9,
- 11,11,11,11,12,11,13,12,13,13,18,12,12, 9, 9,11,
- 10,11,11,12,12,12,13,13,14,19,18,18,11,11,11,11,
- 12,12,13,12,13,13,14,14,16,18,18,11,11,11,10,12,
- 11,13,13,13,13,13,14,17,18,18,14,15,11,12,12,13,
- 13,13,13,14,14,14,18,18,18,15,15,12,10,13,10,13,
- 13,13,13,13,14,18,17,18,17,18,12,13,12,13,13,13,
- 14,14,16,14,18,17,18,18,17,13,12,13,10,12,12,14,
- 14,14,14,17,18,18,18,18,14,15,12,12,13,12,14,14,
- 15,15,18,18,18,17,18,15,14,12,11,12,12,14,14,14,
- 15,
- };
-
- static float _vq_quantthresh__44c4_s_p9_1[] = {
- -136.5, -115.5, -94.5, -73.5, -52.5, -31.5, -10.5, 10.5,
- 31.5, 52.5, 73.5, 94.5, 115.5, 136.5,
- };
-
- static long _vq_quantmap__44c4_s_p9_1[] = {
- 13, 11, 9, 7, 5, 3, 1, 0,
- 2, 4, 6, 8, 10, 12, 14,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c4_s_p9_1 = {
- _vq_quantthresh__44c4_s_p9_1,
- _vq_quantmap__44c4_s_p9_1,
- 15,
- 15
- };
-
- static static_codebook _44c4_s_p9_1 = {
- 2, 225,
- _vq_lengthlist__44c4_s_p9_1,
- 1, -520986624, 1620377600, 4, 0,
- _vq_quantlist__44c4_s_p9_1,
- NULL,
- &_vq_auxt__44c4_s_p9_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c4_s_p9_2[] = {
- 10,
- 9,
- 11,
- 8,
- 12,
- 7,
- 13,
- 6,
- 14,
- 5,
- 15,
- 4,
- 16,
- 3,
- 17,
- 2,
- 18,
- 1,
- 19,
- 0,
- 20,
- };
-
- static long _vq_lengthlist__44c4_s_p9_2[] = {
- 2, 5, 5, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8,
- 8, 9, 9, 9, 9,11, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9,
- 9, 9, 9, 9, 9, 9,10,10,10,10,11, 6, 6, 7, 7, 8,
- 8, 8, 8, 9, 9, 9, 9, 9, 9,10, 9,10,10,10,10,11,
- 7, 7, 7, 7, 8, 8, 9, 9, 9, 9, 9, 9, 9,10,10,10,
- 10,10,10,10,12,11,11, 7, 7, 8, 8, 9, 9, 9, 9, 9,
- 9,10,10,10,10,10,10,10,10,12,11,12, 8, 8, 8, 8,
- 9, 9, 9, 9, 9,10,10,10,10,10,10,10,10,10,11,11,
- 11, 8, 8, 8, 8, 9, 9, 9, 9,10,10,10,10,10,10,10,
- 10,10,10,11,11,12, 9, 9, 9, 9, 9, 9,10, 9,10,10,
- 10,10,10,10,10,10,10,10,11,11,11,11,11, 9, 9, 9,
- 9,10,10,10,10,10,10,10,10,10,10,10,10,11,12,11,
- 11,11, 9, 9, 9,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,11,11,11,11,11, 9, 9, 9, 9,10,10,10,10,10,
- 10,10,10,10,10,10,10,11,11,11,12,12,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,11,12,11,12,
- 11,11,11, 9,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,11,12,11,11,11,11,11,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,11,11,11,12,11,11,11,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,12,11,11,12,11,
- 11,11,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 11,11,11,11,11,11,11,11,11,10,10,10,10,10,10,10,
- 10,10,10,10,10,11,11,11,11,12,12,11,11,11,11,11,
- 11,11,10,10,10,10,10,10,10,10,12,12,12,11,11,11,
- 12,11,11,11,10,10,10,10,10,10,10,10,10,10,10,12,
- 11,12,12,12,12,12,11,12,11,11,10,10,10,10,10,10,
- 10,10,10,10,12,12,12,12,11,11,11,11,11,11,11,10,
- 10,10,10,10,10,10,10,10,10,
- };
-
- static float _vq_quantthresh__44c4_s_p9_2[] = {
- -9.5, -8.5, -7.5, -6.5, -5.5, -4.5, -3.5, -2.5,
- -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5.5,
- 6.5, 7.5, 8.5, 9.5,
- };
-
- static long _vq_quantmap__44c4_s_p9_2[] = {
- 19, 17, 15, 13, 11, 9, 7, 5,
- 3, 1, 0, 2, 4, 6, 8, 10,
- 12, 14, 16, 18, 20,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c4_s_p9_2 = {
- _vq_quantthresh__44c4_s_p9_2,
- _vq_quantmap__44c4_s_p9_2,
- 21,
- 21
- };
-
- static static_codebook _44c4_s_p9_2 = {
- 2, 441,
- _vq_lengthlist__44c4_s_p9_2,
- 1, -529268736, 1611661312, 5, 0,
- _vq_quantlist__44c4_s_p9_2,
- NULL,
- &_vq_auxt__44c4_s_p9_2,
- NULL,
- 0
- };
-
- static long _huff_lengthlist__44c4_s_short[] = {
- 4, 7,14,10,15,10,12,15,16,15, 4, 2,11, 5,10, 6,
- 8,11,14,14,14,10, 7,11, 6, 8,10,11,13,15, 9, 4,
- 11, 5, 9, 6, 9,12,14,15,14, 9, 6, 9, 4, 5, 7,10,
- 12,13, 9, 5, 7, 6, 5, 5, 7,10,13,13,10, 8, 9, 8,
- 7, 6, 8,10,14,14,13,11,10,10, 7, 7, 8,11,14,15,
- 13,12, 9, 9, 6, 5, 7,10,14,17,15,13,11,10, 6, 6,
- 7, 9,12,17,
- };
-
- static static_codebook _huff_book__44c4_s_short = {
- 2, 100,
- _huff_lengthlist__44c4_s_short,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist__44c5_s_long[] = {
- 3, 8, 9,13,10,12,12,12,12,12, 6, 4, 6, 8, 6, 8,
- 10,10,11,12, 8, 5, 4,10, 4, 7, 8, 9,10,11,13, 8,
- 10, 8, 9, 9,11,12,13,14,10, 6, 4, 9, 3, 5, 6, 8,
- 10,11,11, 8, 6, 9, 5, 5, 6, 7, 9,11,12, 9, 7,11,
- 6, 6, 6, 7, 8,10,12,11, 9,12, 7, 7, 6, 6, 7, 9,
- 13,12,10,13, 9, 8, 7, 7, 7, 8,11,15,11,15,11,10,
- 9, 8, 7, 7,
- };
-
- static static_codebook _huff_book__44c5_s_long = {
- 2, 100,
- _huff_lengthlist__44c5_s_long,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c5_s_p1_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__44c5_s_p1_0[] = {
- 2, 4, 4, 0, 0, 0, 0, 0, 0, 4, 7, 7, 0, 0, 0, 0,
- 0, 0, 4, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, 0,
- 0, 0, 0, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 4, 7, 7, 0, 0, 0, 0, 0, 0, 7, 9, 8, 0, 0,
- 0, 0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 7, 7, 0, 0, 0, 0,
- 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, 0,
- 0, 0, 0, 9,10,11, 0, 0, 0, 0, 0, 0, 9,10,10, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0,
- 0, 0, 0, 0, 8,10, 9, 0, 0, 0, 0, 0, 0, 9,10,11,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 4, 7, 7, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0,
- 0, 0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 9,11,10, 0,
- 0, 0, 0, 0, 0, 8, 9,10, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 9,10,10,
- 0, 0, 0, 0, 0, 0, 9,11,10, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,
- };
-
- static float _vq_quantthresh__44c5_s_p1_0[] = {
- -0.5, 0.5,
- };
-
- static long _vq_quantmap__44c5_s_p1_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c5_s_p1_0 = {
- _vq_quantthresh__44c5_s_p1_0,
- _vq_quantmap__44c5_s_p1_0,
- 3,
- 3
- };
-
- static static_codebook _44c5_s_p1_0 = {
- 8, 6561,
- _vq_lengthlist__44c5_s_p1_0,
- 1, -535822336, 1611661312, 2, 0,
- _vq_quantlist__44c5_s_p1_0,
- NULL,
- &_vq_auxt__44c5_s_p1_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c5_s_p2_0[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__44c5_s_p2_0[] = {
- 2, 4, 4, 0, 0, 0, 5, 5, 0, 0, 0, 5, 5, 0, 0, 0,
- 8, 7, 0, 0, 0, 0, 0, 0, 0, 4, 6, 6, 0, 0, 0, 8,
- 8, 0, 0, 0, 8, 7, 0, 0, 0,10,10, 0, 0, 0, 0, 0,
- 0, 0, 4, 6, 6, 0, 0, 0, 8, 8, 0, 0, 0, 7, 8, 0,
- 0, 0,10,10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 5, 8, 7, 0, 0, 0, 8, 8, 0, 0,
- 0, 8, 8, 0, 0, 0,10,10, 0, 0, 0, 0, 0, 0, 0, 5,
- 7, 8, 0, 0, 0, 8, 8, 0, 0, 0, 8, 8, 0, 0, 0,10,
- 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 5, 8, 8, 0, 0, 0, 8, 8, 0, 0, 0, 8, 8,
- 0, 0, 0,10,10, 0, 0, 0, 0, 0, 0, 0, 5, 8, 8, 0,
- 0, 0, 8, 8, 0, 0, 0, 8, 8, 0, 0, 0,10,10, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 8,10,10, 0, 0, 0,10,10, 0, 0, 0, 9,10, 0, 0, 0,
- 11,10, 0, 0, 0, 0, 0, 0, 0, 8,10,10, 0, 0, 0,10,
- 10, 0, 0, 0,10,10, 0, 0, 0,10,11, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,
- };
-
- static float _vq_quantthresh__44c5_s_p2_0[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__44c5_s_p2_0[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c5_s_p2_0 = {
- _vq_quantthresh__44c5_s_p2_0,
- _vq_quantmap__44c5_s_p2_0,
- 5,
- 5
- };
-
- static static_codebook _44c5_s_p2_0 = {
- 4, 625,
- _vq_lengthlist__44c5_s_p2_0,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__44c5_s_p2_0,
- NULL,
- &_vq_auxt__44c5_s_p2_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c5_s_p3_0[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__44c5_s_p3_0[] = {
- 2, 4, 3, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 5, 5, 6, 6, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 3, 5, 5, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 8, 8,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 5, 6, 6, 8, 8, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,
- };
-
- static float _vq_quantthresh__44c5_s_p3_0[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__44c5_s_p3_0[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c5_s_p3_0 = {
- _vq_quantthresh__44c5_s_p3_0,
- _vq_quantmap__44c5_s_p3_0,
- 5,
- 5
- };
-
- static static_codebook _44c5_s_p3_0 = {
- 4, 625,
- _vq_lengthlist__44c5_s_p3_0,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__44c5_s_p3_0,
- NULL,
- &_vq_auxt__44c5_s_p3_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c5_s_p4_0[] = {
- 4,
- 3,
- 5,
- 2,
- 6,
- 1,
- 7,
- 0,
- 8,
- };
-
- static long _vq_lengthlist__44c5_s_p4_0[] = {
- 2, 3, 3, 6, 6, 0, 0, 0, 0, 0, 4, 4, 6, 6, 0, 0,
- 0, 0, 0, 4, 4, 6, 6, 0, 0, 0, 0, 0, 5, 5, 6, 6,
- 0, 0, 0, 0, 0, 0, 0, 6, 6, 0, 0, 0, 0, 0, 0, 0,
- 7, 7, 0, 0, 0, 0, 0, 0, 0, 8, 7, 0, 0, 0, 0, 0,
- 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,
- };
-
- static float _vq_quantthresh__44c5_s_p4_0[] = {
- -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5,
- };
-
- static long _vq_quantmap__44c5_s_p4_0[] = {
- 7, 5, 3, 1, 0, 2, 4, 6,
- 8,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c5_s_p4_0 = {
- _vq_quantthresh__44c5_s_p4_0,
- _vq_quantmap__44c5_s_p4_0,
- 9,
- 9
- };
-
- static static_codebook _44c5_s_p4_0 = {
- 2, 81,
- _vq_lengthlist__44c5_s_p4_0,
- 1, -531628032, 1611661312, 4, 0,
- _vq_quantlist__44c5_s_p4_0,
- NULL,
- &_vq_auxt__44c5_s_p4_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c5_s_p5_0[] = {
- 4,
- 3,
- 5,
- 2,
- 6,
- 1,
- 7,
- 0,
- 8,
- };
-
- static long _vq_lengthlist__44c5_s_p5_0[] = {
- 2, 4, 3, 6, 6, 7, 7, 9, 9, 0, 4, 4, 6, 6, 7, 7,
- 9, 9, 0, 4, 4, 6, 6, 7, 7, 9, 9, 0, 6, 6, 7, 7,
- 7, 7, 9, 9, 0, 0, 0, 7, 6, 7, 7, 9, 9, 0, 0, 0,
- 8, 8, 8, 8,10,10, 0, 0, 0, 8, 8, 8, 8,10,10, 0,
- 0, 0, 9, 9, 9, 9,10,10, 0, 0, 0, 0, 0, 9, 9,10,
- 10,
- };
-
- static float _vq_quantthresh__44c5_s_p5_0[] = {
- -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5,
- };
-
- static long _vq_quantmap__44c5_s_p5_0[] = {
- 7, 5, 3, 1, 0, 2, 4, 6,
- 8,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c5_s_p5_0 = {
- _vq_quantthresh__44c5_s_p5_0,
- _vq_quantmap__44c5_s_p5_0,
- 9,
- 9
- };
-
- static static_codebook _44c5_s_p5_0 = {
- 2, 81,
- _vq_lengthlist__44c5_s_p5_0,
- 1, -531628032, 1611661312, 4, 0,
- _vq_quantlist__44c5_s_p5_0,
- NULL,
- &_vq_auxt__44c5_s_p5_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c5_s_p6_0[] = {
- 8,
- 7,
- 9,
- 6,
- 10,
- 5,
- 11,
- 4,
- 12,
- 3,
- 13,
- 2,
- 14,
- 1,
- 15,
- 0,
- 16,
- };
-
- static long _vq_lengthlist__44c5_s_p6_0[] = {
- 2, 4, 4, 6, 6, 8, 8, 9, 9, 9, 9,10,10,10,10,11,
- 11, 0, 4, 4, 6, 6, 8, 8, 9, 9, 9, 9,10,10,11,11,
- 12,12, 0, 4, 4, 6, 6, 8, 8, 9, 9, 9, 9,10,10,11,
- 11,12,12, 0, 6, 6, 7, 7, 8, 8, 9, 9, 9, 9,10,10,
- 11,11,12,12, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10,
- 10,11,11,12,12, 0, 0, 0, 7, 7, 9, 9,10,10,10,10,
- 11,11,11,11,12,12, 0, 0, 0, 7, 7, 8, 9,10,10,10,
- 10,11,11,11,11,12,12, 0, 0, 0, 8, 8, 9, 9,10,10,
- 10,10,11,11,12,12,12,12, 0, 0, 0, 0, 0, 9, 9,10,
- 10,10,10,11,11,12,12,12,12, 0, 0, 0, 0, 0, 9, 9,
- 10,10,10,10,11,11,12,12,12,12, 0, 0, 0, 0, 0, 9,
- 9, 9,10,10,10,11,11,12,12,12,12, 0, 0, 0, 0, 0,
- 10,10,10,10,11,11,11,12,12,12,13,13, 0, 0, 0, 0,
- 0, 0, 0,10,10,11,11,11,11,12,12,13,13, 0, 0, 0,
- 0, 0, 0, 0,11,11,11,11,12,12,12,13,13,13, 0, 0,
- 0, 0, 0, 0, 0,11,11,11,11,12,12,12,12,13,13, 0,
- 0, 0, 0, 0, 0, 0,12,12,12,12,13,12,13,13,13,13,
- 0, 0, 0, 0, 0, 0, 0, 0, 0,12,12,12,12,13,13,13,
- 13,
- };
-
- static float _vq_quantthresh__44c5_s_p6_0[] = {
- -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5,
- 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5,
- };
-
- static long _vq_quantmap__44c5_s_p6_0[] = {
- 15, 13, 11, 9, 7, 5, 3, 1,
- 0, 2, 4, 6, 8, 10, 12, 14,
- 16,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c5_s_p6_0 = {
- _vq_quantthresh__44c5_s_p6_0,
- _vq_quantmap__44c5_s_p6_0,
- 17,
- 17
- };
-
- static static_codebook _44c5_s_p6_0 = {
- 2, 289,
- _vq_lengthlist__44c5_s_p6_0,
- 1, -529530880, 1611661312, 5, 0,
- _vq_quantlist__44c5_s_p6_0,
- NULL,
- &_vq_auxt__44c5_s_p6_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c5_s_p7_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__44c5_s_p7_0[] = {
- 1, 4, 4, 7, 6, 6, 7, 6, 6, 4, 7, 7,10, 9, 9,11,
- 9, 9, 4, 7, 7,10, 9, 9,11, 9, 9, 7,10,10,11,11,
- 10,11,11,11, 6, 9, 9,11,10,10,11,10,10, 6, 9, 9,
- 11,10,10,11,10,10, 7,11,11,12,11,11,12,11,11, 6,
- 9, 9,11,10,10,11,10,10, 6, 9, 9,11,10,10,11,10,
- 10,
- };
-
- static float _vq_quantthresh__44c5_s_p7_0[] = {
- -5.5, 5.5,
- };
-
- static long _vq_quantmap__44c5_s_p7_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c5_s_p7_0 = {
- _vq_quantthresh__44c5_s_p7_0,
- _vq_quantmap__44c5_s_p7_0,
- 3,
- 3
- };
-
- static static_codebook _44c5_s_p7_0 = {
- 4, 81,
- _vq_lengthlist__44c5_s_p7_0,
- 1, -529137664, 1618345984, 2, 0,
- _vq_quantlist__44c5_s_p7_0,
- NULL,
- &_vq_auxt__44c5_s_p7_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c5_s_p7_1[] = {
- 5,
- 4,
- 6,
- 3,
- 7,
- 2,
- 8,
- 1,
- 9,
- 0,
- 10,
- };
-
- static long _vq_lengthlist__44c5_s_p7_1[] = {
- 2, 4, 4, 6, 6, 7, 7, 8, 8, 8, 8,10, 5, 5, 6, 6,
- 7, 7, 8, 8, 8, 8,10, 5, 5, 6, 6, 7, 7, 8, 8, 8,
- 8,10, 6, 6, 7, 7, 8, 8, 8, 8, 8, 8,10,10,10, 7,
- 7, 8, 8, 8, 8, 8, 8,10,10,10, 7, 7, 8, 8, 8, 8,
- 8, 8,10,10,10, 7, 7, 8, 8, 8, 8, 8, 8,10,10,10,
- 8, 8, 8, 8, 8, 8, 8, 9,10,10,10,10,10, 8, 8, 8,
- 8, 8, 8,10,10,10,10,10, 9, 9, 8, 8, 8, 8,10,10,
- 10,10,10, 8, 8, 8, 8, 8, 8,
- };
-
- static float _vq_quantthresh__44c5_s_p7_1[] = {
- -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5,
- 3.5, 4.5,
- };
-
- static long _vq_quantmap__44c5_s_p7_1[] = {
- 9, 7, 5, 3, 1, 0, 2, 4,
- 6, 8, 10,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c5_s_p7_1 = {
- _vq_quantthresh__44c5_s_p7_1,
- _vq_quantmap__44c5_s_p7_1,
- 11,
- 11
- };
-
- static static_codebook _44c5_s_p7_1 = {
- 2, 121,
- _vq_lengthlist__44c5_s_p7_1,
- 1, -531365888, 1611661312, 4, 0,
- _vq_quantlist__44c5_s_p7_1,
- NULL,
- &_vq_auxt__44c5_s_p7_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c5_s_p8_0[] = {
- 6,
- 5,
- 7,
- 4,
- 8,
- 3,
- 9,
- 2,
- 10,
- 1,
- 11,
- 0,
- 12,
- };
-
- static long _vq_lengthlist__44c5_s_p8_0[] = {
- 1, 4, 4, 6, 6, 7, 7, 8, 8, 9, 9,10,10, 6, 5, 5,
- 7, 7, 8, 8, 8, 9,10,10,10,10, 7, 5, 5, 7, 7, 8,
- 8, 9, 9,10,10,10,10, 0, 8, 8, 8, 8, 9, 9, 9, 9,
- 10,10,11,11, 0, 8, 8, 8, 8, 9, 9, 9, 9,10,10,11,
- 11, 0,12,12, 9, 9, 9,10,10,10,10,10,11,11, 0,13,
- 13, 9, 9, 9, 9,10,10,11,11,11,11, 0, 0, 0,10,10,
- 10,10,10,10,11,11,11,11, 0, 0, 0,10,10,10,10,10,
- 10,11,11,12,12, 0, 0, 0,14,14,11,11,11,11,12,12,
- 12,12, 0, 0, 0,14,14,11,11,11,11,12,12,12,12, 0,
- 0, 0, 0, 0,12,12,12,12,12,12,13,13, 0, 0, 0, 0,
- 0,12,12,12,12,12,12,13,13,
- };
-
- static float _vq_quantthresh__44c5_s_p8_0[] = {
- -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5,
- 12.5, 17.5, 22.5, 27.5,
- };
-
- static long _vq_quantmap__44c5_s_p8_0[] = {
- 11, 9, 7, 5, 3, 1, 0, 2,
- 4, 6, 8, 10, 12,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c5_s_p8_0 = {
- _vq_quantthresh__44c5_s_p8_0,
- _vq_quantmap__44c5_s_p8_0,
- 13,
- 13
- };
-
- static static_codebook _44c5_s_p8_0 = {
- 2, 169,
- _vq_lengthlist__44c5_s_p8_0,
- 1, -526516224, 1616117760, 4, 0,
- _vq_quantlist__44c5_s_p8_0,
- NULL,
- &_vq_auxt__44c5_s_p8_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c5_s_p8_1[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__44c5_s_p8_1[] = {
- 2, 4, 4, 5, 5, 6, 5, 5, 5, 5, 6, 4, 5, 5, 5, 6,
- 5, 5, 5, 5, 6, 6, 6, 5, 5,
- };
-
- static float _vq_quantthresh__44c5_s_p8_1[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__44c5_s_p8_1[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c5_s_p8_1 = {
- _vq_quantthresh__44c5_s_p8_1,
- _vq_quantmap__44c5_s_p8_1,
- 5,
- 5
- };
-
- static static_codebook _44c5_s_p8_1 = {
- 2, 25,
- _vq_lengthlist__44c5_s_p8_1,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__44c5_s_p8_1,
- NULL,
- &_vq_auxt__44c5_s_p8_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c5_s_p9_0[] = {
- 7,
- 6,
- 8,
- 5,
- 9,
- 4,
- 10,
- 3,
- 11,
- 2,
- 12,
- 1,
- 13,
- 0,
- 14,
- };
-
- static long _vq_lengthlist__44c5_s_p9_0[] = {
- 1, 3, 3,13,13,13,13,13,13,13,13,13,13,13,13, 4,
- 7, 7,13,13,13,13,13,13,13,13,13,13,13,13, 3, 8,
- 6,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,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,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,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,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,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,13,13,13,13,13,13,13,13,13,13,13,13,13,
- 13,13,13,13,13,13,13,13,13,12,12,12,12,12,12,12,
- 12,
- };
-
- static float _vq_quantthresh__44c5_s_p9_0[] = {
- -2320.5, -1963.5, -1606.5, -1249.5, -892.5, -535.5, -178.5, 178.5,
- 535.5, 892.5, 1249.5, 1606.5, 1963.5, 2320.5,
- };
-
- static long _vq_quantmap__44c5_s_p9_0[] = {
- 13, 11, 9, 7, 5, 3, 1, 0,
- 2, 4, 6, 8, 10, 12, 14,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c5_s_p9_0 = {
- _vq_quantthresh__44c5_s_p9_0,
- _vq_quantmap__44c5_s_p9_0,
- 15,
- 15
- };
-
- static static_codebook _44c5_s_p9_0 = {
- 2, 225,
- _vq_lengthlist__44c5_s_p9_0,
- 1, -512522752, 1628852224, 4, 0,
- _vq_quantlist__44c5_s_p9_0,
- NULL,
- &_vq_auxt__44c5_s_p9_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c5_s_p9_1[] = {
- 8,
- 7,
- 9,
- 6,
- 10,
- 5,
- 11,
- 4,
- 12,
- 3,
- 13,
- 2,
- 14,
- 1,
- 15,
- 0,
- 16,
- };
-
- static long _vq_lengthlist__44c5_s_p9_1[] = {
- 1, 4, 4, 5, 5, 7, 7, 9, 8,10, 9,10,10,11,10,11,
- 11, 6, 5, 5, 7, 7, 8, 9,10,10,11,10,12,11,12,11,
- 13,12, 6, 5, 5, 7, 7, 9, 9,10,10,11,11,12,12,13,
- 12,13,13,18, 8, 8, 8, 8, 9, 9,10,11,11,11,12,11,
- 13,11,13,12,18, 8, 8, 8, 8,10,10,11,11,12,12,13,
- 13,13,13,13,14,18,12,12, 9, 9,11,11,11,11,12,12,
- 13,12,13,12,13,13,20,13,12, 9, 9,11,11,11,11,12,
- 12,13,13,13,14,14,13,20,18,19,11,12,11,11,12,12,
- 13,13,13,13,13,13,14,13,18,19,19,12,11,11,11,12,
- 12,13,12,13,13,13,14,14,13,18,17,19,14,15,12,12,
- 12,13,13,13,14,14,14,14,14,14,19,19,19,16,15,12,
- 11,13,12,14,14,14,13,13,14,14,14,19,18,19,18,19,
- 13,13,13,13,14,14,14,13,14,14,14,14,18,17,19,19,
- 19,13,13,13,11,13,11,13,14,14,14,14,14,19,17,17,
- 18,18,16,16,13,13,13,13,14,13,15,15,14,14,19,19,
- 17,17,18,16,16,13,11,14,10,13,12,14,14,14,14,19,
- 19,19,19,19,18,17,13,14,13,11,14,13,14,14,15,15,
- 19,19,19,17,19,18,18,14,13,12,11,14,11,15,15,15,
- 15,
- };
-
- static float _vq_quantthresh__44c5_s_p9_1[] = {
- -157.5, -136.5, -115.5, -94.5, -73.5, -52.5, -31.5, -10.5,
- 10.5, 31.5, 52.5, 73.5, 94.5, 115.5, 136.5, 157.5,
- };
-
- static long _vq_quantmap__44c5_s_p9_1[] = {
- 15, 13, 11, 9, 7, 5, 3, 1,
- 0, 2, 4, 6, 8, 10, 12, 14,
- 16,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c5_s_p9_1 = {
- _vq_quantthresh__44c5_s_p9_1,
- _vq_quantmap__44c5_s_p9_1,
- 17,
- 17
- };
-
- static static_codebook _44c5_s_p9_1 = {
- 2, 289,
- _vq_lengthlist__44c5_s_p9_1,
- 1, -520814592, 1620377600, 5, 0,
- _vq_quantlist__44c5_s_p9_1,
- NULL,
- &_vq_auxt__44c5_s_p9_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c5_s_p9_2[] = {
- 10,
- 9,
- 11,
- 8,
- 12,
- 7,
- 13,
- 6,
- 14,
- 5,
- 15,
- 4,
- 16,
- 3,
- 17,
- 2,
- 18,
- 1,
- 19,
- 0,
- 20,
- };
-
- static long _vq_lengthlist__44c5_s_p9_2[] = {
- 3, 5, 5, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 9,11, 5, 6, 7, 7, 8, 7, 8, 8, 8, 8,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,11, 5, 5, 7, 7, 7,
- 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,11,
- 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9,
- 9,10, 9,10,11,11,11, 7, 7, 8, 8, 8, 8, 9, 9, 9,
- 9, 9, 9,10,10,10,10,10,10,11,11,11, 8, 8, 8, 8,
- 9, 9, 9, 9, 9, 9, 9,10,10,10,10,10,10,10,11,11,
- 11, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9,10,10,10,10,10,
- 10,10,10,11,11,11, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 10,10,10,10,10,10,10,10,11,11,11,11,11, 9, 9, 9,
- 9, 9, 9,10, 9,10,10,10,10,10,10,10,10,11,11,11,
- 11,11, 9, 9, 9, 9, 9, 9,10,10,10,10,10,10,10,10,
- 10,10,11,11,11,11,11, 9, 9, 9, 9, 9, 9,10,10,10,
- 10,10,10,10,10,10,10,11,11,11,11,11, 9, 9,10, 9,
- 10,10,10,10,10,10,10,10,10,10,10,10,11,11,11,11,
- 11,11,11, 9, 9,10,10,10,10,10,10,10,10,10,10,10,
- 10,11,11,11,11,11,11,11,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,11,11,11,11,11,11,11,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,11,11,11,11,11,
- 11,11,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 11,11,11,11,11,11,11,11,11,10,10,10,10,10,10,10,
- 10,10,10,10,10,11,11,11,11,11,11,11,11,11,10,10,
- 10,10,10,10,10,10,10,10,10,10,11,11,11,11,11,11,
- 11,11,11,10,10,10,10,10,10,10,10,10,10,10,10,11,
- 11,11,11,11,11,11,11,11,10,10,10,10,10,10,10,10,
- 10,10,10,10,11,11,11,11,11,11,11,11,11,11,11,10,
- 10,10,10,10,10,10,10,10,10,
- };
-
- static float _vq_quantthresh__44c5_s_p9_2[] = {
- -9.5, -8.5, -7.5, -6.5, -5.5, -4.5, -3.5, -2.5,
- -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5.5,
- 6.5, 7.5, 8.5, 9.5,
- };
-
- static long _vq_quantmap__44c5_s_p9_2[] = {
- 19, 17, 15, 13, 11, 9, 7, 5,
- 3, 1, 0, 2, 4, 6, 8, 10,
- 12, 14, 16, 18, 20,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c5_s_p9_2 = {
- _vq_quantthresh__44c5_s_p9_2,
- _vq_quantmap__44c5_s_p9_2,
- 21,
- 21
- };
-
- static static_codebook _44c5_s_p9_2 = {
- 2, 441,
- _vq_lengthlist__44c5_s_p9_2,
- 1, -529268736, 1611661312, 5, 0,
- _vq_quantlist__44c5_s_p9_2,
- NULL,
- &_vq_auxt__44c5_s_p9_2,
- NULL,
- 0
- };
-
- static long _huff_lengthlist__44c5_s_short[] = {
- 5, 8,10,14,11,11,12,16,15,17, 5, 5, 7, 9, 7, 8,
- 10,13,17,17, 7, 5, 5,10, 5, 7, 8,11,13,15,10, 8,
- 10, 8, 8, 8,11,15,18,18, 8, 5, 5, 8, 3, 4, 6,10,
- 14,16, 9, 7, 6, 7, 4, 3, 5, 9,14,18,10, 9, 8,10,
- 6, 5, 6, 9,14,18,12,12,11,12, 8, 7, 8,11,14,18,
- 14,13,12,10, 7, 5, 6, 9,14,18,14,14,13,10, 6, 5,
- 6, 8,11,16,
- };
-
- static static_codebook _huff_book__44c5_s_short = {
- 2, 100,
- _huff_lengthlist__44c5_s_short,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist__44c6_s_long[] = {
- 3, 8,11,13,14,14,13,13,16,14, 6, 3, 4, 7, 9, 9,
- 10,11,14,13,10, 4, 3, 5, 7, 7, 9,10,13,15,12, 7,
- 4, 4, 6, 6, 8,10,13,15,12, 8, 6, 6, 6, 6, 8,10,
- 13,14,11, 9, 7, 6, 6, 6, 7, 8,12,11,13,10, 9, 8,
- 7, 6, 6, 7,11,11,13,11,10, 9, 9, 7, 7, 6,10,11,
- 13,13,13,13,13,11, 9, 8,10,12,12,15,15,16,15,12,
- 11,10,10,12,
- };
-
- static static_codebook _huff_book__44c6_s_long = {
- 2, 100,
- _huff_lengthlist__44c6_s_long,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c6_s_p1_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__44c6_s_p1_0[] = {
- 1, 5, 5, 0, 5, 5, 0, 5, 5, 5, 8, 7, 0, 9, 9, 0,
- 9, 8, 5, 7, 8, 0, 9, 9, 0, 8, 9, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 5, 9, 8, 0, 8, 8, 0, 8, 8, 5, 8, 9,
- 0, 8, 8, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5,
- 9, 9, 0, 8, 8, 0, 8, 8, 5, 9, 9, 0, 8, 8, 0, 8,
- 8,
- };
-
- static float _vq_quantthresh__44c6_s_p1_0[] = {
- -0.5, 0.5,
- };
-
- static long _vq_quantmap__44c6_s_p1_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c6_s_p1_0 = {
- _vq_quantthresh__44c6_s_p1_0,
- _vq_quantmap__44c6_s_p1_0,
- 3,
- 3
- };
-
- static static_codebook _44c6_s_p1_0 = {
- 4, 81,
- _vq_lengthlist__44c6_s_p1_0,
- 1, -535822336, 1611661312, 2, 0,
- _vq_quantlist__44c6_s_p1_0,
- NULL,
- &_vq_auxt__44c6_s_p1_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c6_s_p2_0[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__44c6_s_p2_0[] = {
- 3, 5, 5, 8, 8, 0, 5, 5, 8, 8, 0, 5, 5, 8, 8, 0,
- 7, 7, 9, 9, 0, 0, 0, 9, 9, 5, 7, 7, 9, 9, 0, 8,
- 8,10,10, 0, 8, 7,10, 9, 0,10,10,11,11, 0, 0, 0,
- 11,11, 5, 7, 7, 9, 9, 0, 8, 8,10,10, 0, 7, 8, 9,
- 10, 0,10,10,11,11, 0, 0, 0,11,11, 8, 9, 9,11,11,
- 0,11,11,12,12, 0,11,10,12,12, 0,13,14,14,14, 0,
- 0, 0,14,13, 8, 9, 9,11,11, 0,11,11,12,12, 0,10,
- 11,12,12, 0,14,13,14,14, 0, 0, 0,13,14, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 5, 8, 7,11,10, 0, 7, 7,10,10,
- 0, 7, 7,10,10, 0, 9, 9,11,10, 0, 0, 0,11,11, 5,
- 7, 8,10,11, 0, 7, 7,10,10, 0, 7, 7,10,10, 0, 9,
- 9,10,11, 0, 0, 0,11,11, 8,10, 9,12,12, 0,10,10,
- 12,12, 0,10,10,12,12, 0,12,12,13,13, 0, 0, 0,13,
- 13, 8, 9,10,12,12, 0,10,10,11,12, 0,10,10,12,12,
- 0,12,12,13,13, 0, 0, 0,13,13, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 5, 8, 8,11,11, 0, 7, 7,10,10, 0, 7, 7,
- 10,10, 0, 9, 9,10,11, 0, 0, 0,11,10, 5, 8, 8,11,
- 11, 0, 7, 7,10,10, 0, 7, 7,10,10, 0, 9, 9,11,11,
- 0, 0, 0,10,11, 8,10,10,12,12, 0,10,10,12,12, 0,
- 10,10,12,12, 0,12,13,13,13, 0, 0, 0,14,13, 8,10,
- 10,12,12, 0,10,10,12,12, 0,10,10,12,12, 0,13,12,
- 13,13, 0, 0, 0,13,13, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 7,10,10,14,13, 0, 9, 9,13,12, 0, 9, 9,12,12, 0,
- 10,10,12,12, 0, 0, 0,12,12, 7,10,10,13,14, 0, 9,
- 9,12,13, 0, 9, 9,12,12, 0,10,10,12,12, 0, 0, 0,
- 12,12, 9,11,11,14,13, 0,11,10,14,13, 0,11,11,13,
- 13, 0,12,12,13,13, 0, 0, 0,13,13, 9,11,11,13,14,
- 0,10,11,13,14, 0,11,11,13,13, 0,12,12,13,13, 0,
- 0, 0,13,13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9,
- 11,11,14,14, 0,11,11,13,13, 0,11,10,13,13, 0,12,
- 12,13,13, 0, 0, 0,13,13, 9,11,11,14,14, 0,11,11,
- 13,13, 0,10,11,13,13, 0,12,12,14,13, 0, 0, 0,13,
- 13,
- };
-
- static float _vq_quantthresh__44c6_s_p2_0[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__44c6_s_p2_0[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c6_s_p2_0 = {
- _vq_quantthresh__44c6_s_p2_0,
- _vq_quantmap__44c6_s_p2_0,
- 5,
- 5
- };
-
- static static_codebook _44c6_s_p2_0 = {
- 4, 625,
- _vq_lengthlist__44c6_s_p2_0,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__44c6_s_p2_0,
- NULL,
- &_vq_auxt__44c6_s_p2_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c6_s_p3_0[] = {
- 4,
- 3,
- 5,
- 2,
- 6,
- 1,
- 7,
- 0,
- 8,
- };
-
- static long _vq_lengthlist__44c6_s_p3_0[] = {
- 2, 3, 4, 6, 6, 7, 7, 9, 9, 0, 4, 4, 6, 6, 7, 7,
- 9,10, 0, 4, 4, 6, 6, 7, 7,10, 9, 0, 5, 5, 7, 7,
- 8, 8,10,10, 0, 0, 0, 7, 6, 8, 8,10,10, 0, 0, 0,
- 7, 7, 9, 9,11,11, 0, 0, 0, 7, 7, 9, 9,11,11, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,
- };
-
- static float _vq_quantthresh__44c6_s_p3_0[] = {
- -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5,
- };
-
- static long _vq_quantmap__44c6_s_p3_0[] = {
- 7, 5, 3, 1, 0, 2, 4, 6,
- 8,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c6_s_p3_0 = {
- _vq_quantthresh__44c6_s_p3_0,
- _vq_quantmap__44c6_s_p3_0,
- 9,
- 9
- };
-
- static static_codebook _44c6_s_p3_0 = {
- 2, 81,
- _vq_lengthlist__44c6_s_p3_0,
- 1, -531628032, 1611661312, 4, 0,
- _vq_quantlist__44c6_s_p3_0,
- NULL,
- &_vq_auxt__44c6_s_p3_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c6_s_p4_0[] = {
- 8,
- 7,
- 9,
- 6,
- 10,
- 5,
- 11,
- 4,
- 12,
- 3,
- 13,
- 2,
- 14,
- 1,
- 15,
- 0,
- 16,
- };
-
- static long _vq_lengthlist__44c6_s_p4_0[] = {
- 2, 4, 4, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9, 9,10,10,
- 10, 0, 4, 4, 6, 6, 8, 8, 9, 9, 9, 9,10,10,10,10,
- 11,11, 0, 4, 4, 6, 6, 8, 8, 9, 9, 9, 9,10,10,10,
- 10,11,11, 0, 6, 6, 7, 7, 8, 8, 9, 9, 9, 9,10,10,
- 11,11,11,11, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10,
- 10,11,11,11,11, 0, 0, 0, 7, 7, 9, 9,10,10,10,10,
- 11,11,11,11,12,12, 0, 0, 0, 7, 7, 9, 9,10,10,10,
- 10,11,11,11,11,12,12, 0, 0, 0, 7, 7, 8, 8, 9, 9,
- 10,10,11,11,12,12,12,12, 0, 0, 0, 0, 0, 8, 8, 9,
- 9,10,10,11,11,12,12,12,12, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,
- };
-
- static float _vq_quantthresh__44c6_s_p4_0[] = {
- -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5,
- 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5,
- };
-
- static long _vq_quantmap__44c6_s_p4_0[] = {
- 15, 13, 11, 9, 7, 5, 3, 1,
- 0, 2, 4, 6, 8, 10, 12, 14,
- 16,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c6_s_p4_0 = {
- _vq_quantthresh__44c6_s_p4_0,
- _vq_quantmap__44c6_s_p4_0,
- 17,
- 17
- };
-
- static static_codebook _44c6_s_p4_0 = {
- 2, 289,
- _vq_lengthlist__44c6_s_p4_0,
- 1, -529530880, 1611661312, 5, 0,
- _vq_quantlist__44c6_s_p4_0,
- NULL,
- &_vq_auxt__44c6_s_p4_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c6_s_p5_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__44c6_s_p5_0[] = {
- 1, 4, 4, 5, 7, 7, 6, 7, 7, 4, 6, 6, 9, 9,10,10,
- 10, 9, 4, 6, 6, 9,10, 9,10, 9,10, 6, 9, 9,10,12,
- 11,10,11,11, 7,10, 9,11,12,12,12,12,12, 7,10,10,
- 11,12,12,12,12,12, 6,10,10,10,12,12,11,12,12, 7,
- 9,10,11,12,12,12,12,12, 7,10, 9,12,12,12,12,12,
- 12,
- };
-
- static float _vq_quantthresh__44c6_s_p5_0[] = {
- -5.5, 5.5,
- };
-
- static long _vq_quantmap__44c6_s_p5_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c6_s_p5_0 = {
- _vq_quantthresh__44c6_s_p5_0,
- _vq_quantmap__44c6_s_p5_0,
- 3,
- 3
- };
-
- static static_codebook _44c6_s_p5_0 = {
- 4, 81,
- _vq_lengthlist__44c6_s_p5_0,
- 1, -529137664, 1618345984, 2, 0,
- _vq_quantlist__44c6_s_p5_0,
- NULL,
- &_vq_auxt__44c6_s_p5_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c6_s_p5_1[] = {
- 5,
- 4,
- 6,
- 3,
- 7,
- 2,
- 8,
- 1,
- 9,
- 0,
- 10,
- };
-
- static long _vq_lengthlist__44c6_s_p5_1[] = {
- 3, 5, 4, 6, 6, 7, 7, 8, 8, 8, 8,11, 4, 4, 6, 6,
- 7, 7, 8, 8, 8, 8,11, 4, 4, 6, 6, 7, 7, 8, 8, 8,
- 8,11, 6, 6, 6, 6, 8, 8, 8, 8, 9, 9,11,11,11, 6,
- 6, 7, 8, 8, 8, 8, 9,11,11,11, 7, 7, 8, 8, 8, 8,
- 8, 8,11,11,11, 7, 7, 8, 8, 8, 8, 8, 8,11,11,11,
- 8, 8, 8, 8, 8, 8, 8, 8,11,11,11,10,10, 8, 8, 8,
- 8, 8, 8,11,11,11,10,10, 8, 8, 8, 8, 8, 8,11,11,
- 11,10,10, 7, 7, 8, 8, 8, 8,
- };
-
- static float _vq_quantthresh__44c6_s_p5_1[] = {
- -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5,
- 3.5, 4.5,
- };
-
- static long _vq_quantmap__44c6_s_p5_1[] = {
- 9, 7, 5, 3, 1, 0, 2, 4,
- 6, 8, 10,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c6_s_p5_1 = {
- _vq_quantthresh__44c6_s_p5_1,
- _vq_quantmap__44c6_s_p5_1,
- 11,
- 11
- };
-
- static static_codebook _44c6_s_p5_1 = {
- 2, 121,
- _vq_lengthlist__44c6_s_p5_1,
- 1, -531365888, 1611661312, 4, 0,
- _vq_quantlist__44c6_s_p5_1,
- NULL,
- &_vq_auxt__44c6_s_p5_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c6_s_p6_0[] = {
- 6,
- 5,
- 7,
- 4,
- 8,
- 3,
- 9,
- 2,
- 10,
- 1,
- 11,
- 0,
- 12,
- };
-
- static long _vq_lengthlist__44c6_s_p6_0[] = {
- 1, 4, 4, 6, 6, 8, 8, 8, 8,10, 9,10,10, 6, 5, 5,
- 7, 7, 9, 9, 9, 9,10,10,11,11, 6, 5, 5, 7, 7, 9,
- 9,10, 9,11,10,11,11, 0, 6, 6, 7, 7, 9, 9,10,10,
- 11,11,12,12, 0, 7, 7, 7, 7, 9, 9,10,10,11,11,12,
- 12, 0,11,11, 8, 8,10,10,11,11,12,12,12,12, 0,11,
- 12, 9, 8,10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0,
- };
-
- static float _vq_quantthresh__44c6_s_p6_0[] = {
- -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5,
- 12.5, 17.5, 22.5, 27.5,
- };
-
- static long _vq_quantmap__44c6_s_p6_0[] = {
- 11, 9, 7, 5, 3, 1, 0, 2,
- 4, 6, 8, 10, 12,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c6_s_p6_0 = {
- _vq_quantthresh__44c6_s_p6_0,
- _vq_quantmap__44c6_s_p6_0,
- 13,
- 13
- };
-
- static static_codebook _44c6_s_p6_0 = {
- 2, 169,
- _vq_lengthlist__44c6_s_p6_0,
- 1, -526516224, 1616117760, 4, 0,
- _vq_quantlist__44c6_s_p6_0,
- NULL,
- &_vq_auxt__44c6_s_p6_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c6_s_p6_1[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__44c6_s_p6_1[] = {
- 3, 4, 4, 5, 5, 5, 4, 4, 5, 5, 5, 4, 4, 5, 5, 6,
- 5, 5, 5, 5, 6, 6, 6, 5, 5,
- };
-
- static float _vq_quantthresh__44c6_s_p6_1[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__44c6_s_p6_1[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c6_s_p6_1 = {
- _vq_quantthresh__44c6_s_p6_1,
- _vq_quantmap__44c6_s_p6_1,
- 5,
- 5
- };
-
- static static_codebook _44c6_s_p6_1 = {
- 2, 25,
- _vq_lengthlist__44c6_s_p6_1,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__44c6_s_p6_1,
- NULL,
- &_vq_auxt__44c6_s_p6_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c6_s_p7_0[] = {
- 6,
- 5,
- 7,
- 4,
- 8,
- 3,
- 9,
- 2,
- 10,
- 1,
- 11,
- 0,
- 12,
- };
-
- static long _vq_lengthlist__44c6_s_p7_0[] = {
- 1, 4, 4, 6, 6, 8, 8, 8, 8,10,10,11,10, 6, 5, 5,
- 7, 7, 8, 8, 9, 9,10,10,12,11, 6, 5, 5, 7, 7, 8,
- 8, 9, 9,10,10,12,11,21, 7, 7, 7, 7, 9, 9,10,10,
- 11,11,12,12,21, 7, 7, 7, 7, 9, 9,10,10,11,11,12,
- 12,21,12,12, 9, 9,10,10,11,11,11,11,12,12,21,12,
- 12, 9, 9,10,10,11,11,12,12,12,12,21,21,21,11,11,
- 10,10,11,12,12,12,13,13,21,21,21,11,11,10,10,12,
- 12,12,12,13,13,21,21,21,15,15,11,11,12,12,13,13,
- 13,13,21,21,21,15,16,11,11,12,12,13,13,14,14,21,
- 21,21,21,20,13,13,13,13,13,13,14,14,20,20,20,20,
- 20,13,13,13,13,13,13,14,14,
- };
-
- static float _vq_quantthresh__44c6_s_p7_0[] = {
- -60.5, -49.5, -38.5, -27.5, -16.5, -5.5, 5.5, 16.5,
- 27.5, 38.5, 49.5, 60.5,
- };
-
- static long _vq_quantmap__44c6_s_p7_0[] = {
- 11, 9, 7, 5, 3, 1, 0, 2,
- 4, 6, 8, 10, 12,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c6_s_p7_0 = {
- _vq_quantthresh__44c6_s_p7_0,
- _vq_quantmap__44c6_s_p7_0,
- 13,
- 13
- };
-
- static static_codebook _44c6_s_p7_0 = {
- 2, 169,
- _vq_lengthlist__44c6_s_p7_0,
- 1, -523206656, 1618345984, 4, 0,
- _vq_quantlist__44c6_s_p7_0,
- NULL,
- &_vq_auxt__44c6_s_p7_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c6_s_p7_1[] = {
- 5,
- 4,
- 6,
- 3,
- 7,
- 2,
- 8,
- 1,
- 9,
- 0,
- 10,
- };
-
- static long _vq_lengthlist__44c6_s_p7_1[] = {
- 3, 5, 5, 6, 6, 7, 7, 7, 7, 7, 7, 9, 5, 5, 6, 6,
- 7, 7, 7, 7, 8, 7, 8, 5, 5, 6, 6, 7, 7, 7, 7, 7,
- 7, 9, 6, 6, 7, 7, 7, 7, 8, 7, 7, 8, 9, 9, 9, 7,
- 7, 7, 7, 7, 7, 7, 8, 9, 9, 9, 7, 7, 7, 7, 8, 8,
- 8, 8, 9, 9, 9, 7, 7, 7, 7, 7, 7, 8, 8, 9, 9, 9,
- 8, 8, 8, 8, 7, 7, 8, 8, 9, 9, 9, 9, 8, 8, 8, 7,
- 7, 8, 8, 9, 9, 9, 8, 8, 8, 8, 7, 7, 8, 8, 9, 9,
- 9, 8, 8, 7, 7, 7, 7, 8, 8,
- };
-
- static float _vq_quantthresh__44c6_s_p7_1[] = {
- -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5,
- 3.5, 4.5,
- };
-
- static long _vq_quantmap__44c6_s_p7_1[] = {
- 9, 7, 5, 3, 1, 0, 2, 4,
- 6, 8, 10,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c6_s_p7_1 = {
- _vq_quantthresh__44c6_s_p7_1,
- _vq_quantmap__44c6_s_p7_1,
- 11,
- 11
- };
-
- static static_codebook _44c6_s_p7_1 = {
- 2, 121,
- _vq_lengthlist__44c6_s_p7_1,
- 1, -531365888, 1611661312, 4, 0,
- _vq_quantlist__44c6_s_p7_1,
- NULL,
- &_vq_auxt__44c6_s_p7_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c6_s_p8_0[] = {
- 7,
- 6,
- 8,
- 5,
- 9,
- 4,
- 10,
- 3,
- 11,
- 2,
- 12,
- 1,
- 13,
- 0,
- 14,
- };
-
- static long _vq_lengthlist__44c6_s_p8_0[] = {
- 1, 4, 4, 7, 7, 8, 8, 7, 7, 8, 7, 9, 8,10, 9, 6,
- 5, 5, 8, 8, 9, 9, 8, 8, 9, 9,11,10,11,10, 6, 5,
- 5, 8, 8, 9, 9, 8, 8, 9, 9,10,10,11,11,18, 8, 8,
- 9, 8,10,10, 9, 9,10,10,10,10,11,10,18, 8, 8, 9,
- 9,10,10, 9, 9,10,10,11,11,12,12,18,12,13, 9,10,
- 10,10, 9,10,10,10,11,11,12,11,18,13,13, 9, 9,10,
- 10,10,10,10,10,11,11,12,12,18,18,18,10,10, 9, 9,
- 11,11,11,11,11,12,12,12,18,18,18,10, 9,10, 9,11,
- 10,11,11,11,11,13,12,18,18,18,14,13,10,10,11,11,
- 12,12,12,12,12,12,18,18,18,14,13,10,10,11,10,12,
- 12,12,12,12,12,18,18,18,18,18,12,12,11,11,12,12,
- 13,13,13,14,18,18,18,18,18,12,12,11,11,12,11,13,
- 13,14,13,18,18,18,18,18,16,16,11,12,12,13,13,13,
- 14,13,18,18,18,18,18,16,15,12,11,12,11,13,11,15,
- 14,
- };
-
- static float _vq_quantthresh__44c6_s_p8_0[] = {
- -136.5, -115.5, -94.5, -73.5, -52.5, -31.5, -10.5, 10.5,
- 31.5, 52.5, 73.5, 94.5, 115.5, 136.5,
- };
-
- static long _vq_quantmap__44c6_s_p8_0[] = {
- 13, 11, 9, 7, 5, 3, 1, 0,
- 2, 4, 6, 8, 10, 12, 14,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c6_s_p8_0 = {
- _vq_quantthresh__44c6_s_p8_0,
- _vq_quantmap__44c6_s_p8_0,
- 15,
- 15
- };
-
- static static_codebook _44c6_s_p8_0 = {
- 2, 225,
- _vq_lengthlist__44c6_s_p8_0,
- 1, -520986624, 1620377600, 4, 0,
- _vq_quantlist__44c6_s_p8_0,
- NULL,
- &_vq_auxt__44c6_s_p8_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c6_s_p8_1[] = {
- 10,
- 9,
- 11,
- 8,
- 12,
- 7,
- 13,
- 6,
- 14,
- 5,
- 15,
- 4,
- 16,
- 3,
- 17,
- 2,
- 18,
- 1,
- 19,
- 0,
- 20,
- };
-
- static long _vq_lengthlist__44c6_s_p8_1[] = {
- 3, 5, 5, 6, 6, 7, 7, 7, 7, 8, 7, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8,10, 6, 6, 7, 7, 8, 8, 8, 8, 8, 8,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10, 6, 6, 7, 7, 8,
- 8, 8, 8, 8, 8, 9, 8, 9, 9, 9, 9, 9, 9, 9, 9,10,
- 7, 7, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9,10,11,11, 8, 7, 8, 8, 8, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9,11,11,11, 8, 8, 8, 8,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,11,11,
- 11, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9,11,11,11, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9,11,11,11,11,11, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10,10, 9,11,11,11,
- 11,11, 9, 9, 9, 9, 9, 9,10, 9, 9,10, 9,10, 9, 9,
- 10, 9,11,11,11,11,11, 9, 9, 9, 9, 9, 9, 9,10,10,
- 10,10, 9,10,10, 9,10,11,11,11,11,11, 9, 9, 9, 9,
- 10,10,10, 9,10,10,10,10, 9,10,10, 9,11,11,11,11,
- 11,11,11, 9, 9, 9, 9,10,10,10,10, 9,10,10,10,10,
- 10,11,11,11,11,11,11,11,10, 9,10,10,10,10,10,10,
- 10, 9,10, 9,10,10,11,11,11,11,11,11,11,10, 9,10,
- 9,10,10, 9,10,10,10,10,10,10,10,11,11,11,11,11,
- 11,11,10,10,10,10,10,10,10, 9,10,10,10,10,10, 9,
- 11,11,11,11,11,11,11,11,11,10,10,10,10,10,10,10,
- 10,10,10,10,10,11,11,11,11,11,11,11,11,11,10,10,
- 10,10,10,10,10,10,10,10,10,10,11,11,11,11,11,11,
- 11,11,11,10,10,10,10,10,10,10,10,10, 9,10,10,11,
- 11,11,11,11,11,11,11,11,10,10,10, 9,10,10,10,10,
- 10,10,10,10,10,11,11,11,11,11,11,11,11,10,11, 9,
- 10,10,10,10,10,10,10,10,10,
- };
-
- static float _vq_quantthresh__44c6_s_p8_1[] = {
- -9.5, -8.5, -7.5, -6.5, -5.5, -4.5, -3.5, -2.5,
- -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5.5,
- 6.5, 7.5, 8.5, 9.5,
- };
-
- static long _vq_quantmap__44c6_s_p8_1[] = {
- 19, 17, 15, 13, 11, 9, 7, 5,
- 3, 1, 0, 2, 4, 6, 8, 10,
- 12, 14, 16, 18, 20,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c6_s_p8_1 = {
- _vq_quantthresh__44c6_s_p8_1,
- _vq_quantmap__44c6_s_p8_1,
- 21,
- 21
- };
-
- static static_codebook _44c6_s_p8_1 = {
- 2, 441,
- _vq_lengthlist__44c6_s_p8_1,
- 1, -529268736, 1611661312, 5, 0,
- _vq_quantlist__44c6_s_p8_1,
- NULL,
- &_vq_auxt__44c6_s_p8_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c6_s_p9_0[] = {
- 6,
- 5,
- 7,
- 4,
- 8,
- 3,
- 9,
- 2,
- 10,
- 1,
- 11,
- 0,
- 12,
- };
-
- static long _vq_lengthlist__44c6_s_p9_0[] = {
- 1, 3, 3,11,11,11,11,11,11,11,11,11,11, 4, 7, 7,
- 11,11,11,11,11,11,11,11,11,11, 5, 8, 9,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,
- };
-
- static float _vq_quantthresh__44c6_s_p9_0[] = {
- -3503.5, -2866.5, -2229.5, -1592.5, -955.5, -318.5, 318.5, 955.5,
- 1592.5, 2229.5, 2866.5, 3503.5,
- };
-
- static long _vq_quantmap__44c6_s_p9_0[] = {
- 11, 9, 7, 5, 3, 1, 0, 2,
- 4, 6, 8, 10, 12,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c6_s_p9_0 = {
- _vq_quantthresh__44c6_s_p9_0,
- _vq_quantmap__44c6_s_p9_0,
- 13,
- 13
- };
-
- static static_codebook _44c6_s_p9_0 = {
- 2, 169,
- _vq_lengthlist__44c6_s_p9_0,
- 1, -511845376, 1630791680, 4, 0,
- _vq_quantlist__44c6_s_p9_0,
- NULL,
- &_vq_auxt__44c6_s_p9_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c6_s_p9_1[] = {
- 6,
- 5,
- 7,
- 4,
- 8,
- 3,
- 9,
- 2,
- 10,
- 1,
- 11,
- 0,
- 12,
- };
-
- static long _vq_lengthlist__44c6_s_p9_1[] = {
- 1, 4, 4, 7, 7, 7, 7, 7, 6, 8, 8, 8, 8, 6, 6, 6,
- 8, 8, 8, 8, 8, 7, 9, 8,10,10, 5, 6, 6, 8, 8, 9,
- 9, 8, 8,10,10,10,10,16, 9, 9, 9, 9, 9, 9, 9, 8,
- 10, 9,11,11,16, 8, 9, 9, 9, 9, 9, 9, 9,10,10,11,
- 11,16,13,13, 9, 9,10, 9, 9,10,11,11,11,12,16,13,
- 14, 9, 8,10, 8, 9, 9,10,10,12,11,16,14,16, 9, 9,
- 9, 9,11,11,12,11,12,11,16,16,16, 9, 7, 9, 6,11,
- 11,11,10,11,11,16,16,16,11,12, 9,10,11,11,12,11,
- 13,13,16,16,16,12,11,10, 7,12,10,12,12,12,12,16,
- 16,15,16,16,10,11,10,11,13,13,14,12,16,16,16,15,
- 15,12,10,11,11,13,11,12,13,
- };
-
- static float _vq_quantthresh__44c6_s_p9_1[] = {
- -269.5, -220.5, -171.5, -122.5, -73.5, -24.5, 24.5, 73.5,
- 122.5, 171.5, 220.5, 269.5,
- };
-
- static long _vq_quantmap__44c6_s_p9_1[] = {
- 11, 9, 7, 5, 3, 1, 0, 2,
- 4, 6, 8, 10, 12,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c6_s_p9_1 = {
- _vq_quantthresh__44c6_s_p9_1,
- _vq_quantmap__44c6_s_p9_1,
- 13,
- 13
- };
-
- static static_codebook _44c6_s_p9_1 = {
- 2, 169,
- _vq_lengthlist__44c6_s_p9_1,
- 1, -518889472, 1622704128, 4, 0,
- _vq_quantlist__44c6_s_p9_1,
- NULL,
- &_vq_auxt__44c6_s_p9_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c6_s_p9_2[] = {
- 24,
- 23,
- 25,
- 22,
- 26,
- 21,
- 27,
- 20,
- 28,
- 19,
- 29,
- 18,
- 30,
- 17,
- 31,
- 16,
- 32,
- 15,
- 33,
- 14,
- 34,
- 13,
- 35,
- 12,
- 36,
- 11,
- 37,
- 10,
- 38,
- 9,
- 39,
- 8,
- 40,
- 7,
- 41,
- 6,
- 42,
- 5,
- 43,
- 4,
- 44,
- 3,
- 45,
- 2,
- 46,
- 1,
- 47,
- 0,
- 48,
- };
-
- static long _vq_lengthlist__44c6_s_p9_2[] = {
- 2, 4, 3, 4, 5, 5, 5, 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, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7,
- };
-
- static float _vq_quantthresh__44c6_s_p9_2[] = {
- -23.5, -22.5, -21.5, -20.5, -19.5, -18.5, -17.5, -16.5,
- -15.5, -14.5, -13.5, -12.5, -11.5, -10.5, -9.5, -8.5,
- -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5,
- 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5,
- 8.5, 9.5, 10.5, 11.5, 12.5, 13.5, 14.5, 15.5,
- 16.5, 17.5, 18.5, 19.5, 20.5, 21.5, 22.5, 23.5,
- };
-
- static long _vq_quantmap__44c6_s_p9_2[] = {
- 47, 45, 43, 41, 39, 37, 35, 33,
- 31, 29, 27, 25, 23, 21, 19, 17,
- 15, 13, 11, 9, 7, 5, 3, 1,
- 0, 2, 4, 6, 8, 10, 12, 14,
- 16, 18, 20, 22, 24, 26, 28, 30,
- 32, 34, 36, 38, 40, 42, 44, 46,
- 48,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c6_s_p9_2 = {
- _vq_quantthresh__44c6_s_p9_2,
- _vq_quantmap__44c6_s_p9_2,
- 49,
- 49
- };
-
- static static_codebook _44c6_s_p9_2 = {
- 1, 49,
- _vq_lengthlist__44c6_s_p9_2,
- 1, -526909440, 1611661312, 6, 0,
- _vq_quantlist__44c6_s_p9_2,
- NULL,
- &_vq_auxt__44c6_s_p9_2,
- NULL,
- 0
- };
-
- static long _huff_lengthlist__44c6_s_short[] = {
- 3, 9,11,11,13,14,19,17,17,19, 5, 4, 5, 8,10,10,
- 13,16,18,19, 7, 4, 4, 5, 8, 9,12,14,17,19, 8, 6,
- 5, 5, 7, 7,10,13,16,18,10, 8, 7, 6, 5, 5, 8,11,
- 17,19,11, 9, 7, 7, 5, 4, 5, 8,17,19,13,11, 8, 7,
- 7, 5, 5, 7,16,18,14,13, 8, 6, 6, 5, 5, 7,16,18,
- 18,16,10, 8, 8, 7, 7, 9,16,18,18,18,12,10,10, 9,
- 9,10,17,18,
- };
-
- static static_codebook _huff_book__44c6_s_short = {
- 2, 100,
- _huff_lengthlist__44c6_s_short,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist__44c7_s_long[] = {
- 3, 8,11,13,15,14,14,13,15,14, 6, 4, 5, 7, 9,10,
- 11,11,14,13,10, 4, 3, 5, 7, 8, 9,10,13,13,12, 7,
- 4, 4, 5, 6, 8, 9,12,14,13, 9, 6, 5, 5, 6, 8, 9,
- 12,14,12, 9, 7, 6, 5, 5, 6, 8,11,11,12,11, 9, 8,
- 7, 6, 6, 7,10,11,13,11,10, 9, 8, 7, 6, 6, 9,11,
- 13,13,12,12,12,10, 9, 8, 9,11,12,14,15,15,14,12,
- 11,10,10,12,
- };
-
- static static_codebook _huff_book__44c7_s_long = {
- 2, 100,
- _huff_lengthlist__44c7_s_long,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c7_s_p1_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__44c7_s_p1_0[] = {
- 1, 5, 5, 0, 5, 5, 0, 5, 5, 5, 8, 7, 0, 9, 9, 0,
- 9, 8, 5, 7, 8, 0, 9, 9, 0, 8, 9, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 5, 9, 9, 0, 8, 8, 0, 8, 8, 5, 8, 9,
- 0, 8, 8, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5,
- 9, 9, 0, 8, 8, 0, 8, 8, 5, 8, 9, 0, 8, 8, 0, 8,
- 8,
- };
-
- static float _vq_quantthresh__44c7_s_p1_0[] = {
- -0.5, 0.5,
- };
-
- static long _vq_quantmap__44c7_s_p1_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c7_s_p1_0 = {
- _vq_quantthresh__44c7_s_p1_0,
- _vq_quantmap__44c7_s_p1_0,
- 3,
- 3
- };
-
- static static_codebook _44c7_s_p1_0 = {
- 4, 81,
- _vq_lengthlist__44c7_s_p1_0,
- 1, -535822336, 1611661312, 2, 0,
- _vq_quantlist__44c7_s_p1_0,
- NULL,
- &_vq_auxt__44c7_s_p1_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c7_s_p2_0[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__44c7_s_p2_0[] = {
- 3, 5, 5, 8, 8, 0, 5, 5, 8, 8, 0, 5, 5, 8, 8, 0,
- 7, 7, 9, 9, 0, 0, 0, 9, 9, 5, 7, 7, 9, 9, 0, 8,
- 8,10,10, 0, 8, 7,10, 9, 0,10,10,11,11, 0, 0, 0,
- 11,11, 5, 7, 7, 9, 9, 0, 8, 8,10,10, 0, 7, 8, 9,
- 10, 0,10,10,11,11, 0, 0, 0,11,11, 8, 9, 9,11,10,
- 0,11,11,12,12, 0,11,10,12,12, 0,13,14,14,14, 0,
- 0, 0,14,13, 8, 9, 9,10,11, 0,11,11,12,12, 0,10,
- 11,12,12, 0,13,13,14,14, 0, 0, 0,13,14, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 5, 8, 7,11,10, 0, 7, 7,10,10,
- 0, 7, 7,10,10, 0, 9, 9,11,10, 0, 0, 0,11,11, 5,
- 7, 8,10,11, 0, 7, 7,10,10, 0, 7, 7,10,10, 0, 9,
- 9,10,11, 0, 0, 0,11,11, 8,10, 9,12,12, 0,10,10,
- 12,12, 0,10,10,12,12, 0,12,12,13,13, 0, 0, 0,13,
- 13, 8, 9,10,12,12, 0,10,10,12,12, 0,10,10,11,12,
- 0,12,12,13,13, 0, 0, 0,13,13, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 5, 8, 8,11,11, 0, 7, 7,10,10, 0, 7, 7,
- 10,10, 0, 9, 9,10,11, 0, 0, 0,11,10, 5, 8, 8,10,
- 11, 0, 7, 7,10,10, 0, 7, 7,10,10, 0, 9, 9,11,10,
- 0, 0, 0,10,11, 9,10,10,12,12, 0,10,10,12,12, 0,
- 10,10,12,12, 0,12,13,13,13, 0, 0, 0,13,12, 9,10,
- 10,12,12, 0,10,10,12,12, 0,10,10,12,12, 0,13,12,
- 13,13, 0, 0, 0,12,13, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 7,10,10,14,13, 0, 9, 9,12,12, 0, 9, 9,12,12, 0,
- 10,10,12,12, 0, 0, 0,12,12, 7,10,10,13,14, 0, 9,
- 9,12,13, 0, 9, 9,12,12, 0,10,10,12,12, 0, 0, 0,
- 12,12, 9,11,11,14,13, 0,11,10,13,12, 0,11,11,13,
- 13, 0,12,12,13,13, 0, 0, 0,13,13, 9,11,11,13,14,
- 0,10,11,12,13, 0,11,11,13,13, 0,12,12,13,13, 0,
- 0, 0,13,13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9,
- 11,11,14,14, 0,10,11,13,13, 0,11,10,13,13, 0,12,
- 12,13,13, 0, 0, 0,13,12, 9,11,11,14,14, 0,11,10,
- 13,13, 0,10,11,13,13, 0,12,12,14,13, 0, 0, 0,13,
- 13,
- };
-
- static float _vq_quantthresh__44c7_s_p2_0[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__44c7_s_p2_0[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c7_s_p2_0 = {
- _vq_quantthresh__44c7_s_p2_0,
- _vq_quantmap__44c7_s_p2_0,
- 5,
- 5
- };
-
- static static_codebook _44c7_s_p2_0 = {
- 4, 625,
- _vq_lengthlist__44c7_s_p2_0,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__44c7_s_p2_0,
- NULL,
- &_vq_auxt__44c7_s_p2_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c7_s_p3_0[] = {
- 4,
- 3,
- 5,
- 2,
- 6,
- 1,
- 7,
- 0,
- 8,
- };
-
- static long _vq_lengthlist__44c7_s_p3_0[] = {
- 2, 4, 4, 5, 5, 7, 7, 9, 9, 0, 4, 4, 6, 6, 7, 7,
- 9, 9, 0, 4, 4, 6, 6, 7, 7, 9, 9, 0, 5, 5, 6, 6,
- 8, 8,10,10, 0, 0, 0, 6, 6, 8, 8,10,10, 0, 0, 0,
- 7, 7, 9, 9,10,10, 0, 0, 0, 7, 7, 8, 8,10,10, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,
- };
-
- static float _vq_quantthresh__44c7_s_p3_0[] = {
- -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5,
- };
-
- static long _vq_quantmap__44c7_s_p3_0[] = {
- 7, 5, 3, 1, 0, 2, 4, 6,
- 8,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c7_s_p3_0 = {
- _vq_quantthresh__44c7_s_p3_0,
- _vq_quantmap__44c7_s_p3_0,
- 9,
- 9
- };
-
- static static_codebook _44c7_s_p3_0 = {
- 2, 81,
- _vq_lengthlist__44c7_s_p3_0,
- 1, -531628032, 1611661312, 4, 0,
- _vq_quantlist__44c7_s_p3_0,
- NULL,
- &_vq_auxt__44c7_s_p3_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c7_s_p4_0[] = {
- 8,
- 7,
- 9,
- 6,
- 10,
- 5,
- 11,
- 4,
- 12,
- 3,
- 13,
- 2,
- 14,
- 1,
- 15,
- 0,
- 16,
- };
-
- static long _vq_lengthlist__44c7_s_p4_0[] = {
- 3, 4, 4, 5, 5, 7, 7, 8, 8, 8, 8, 9, 9,10,10,11,
- 11, 0, 4, 4, 6, 6, 7, 7, 8, 8, 9, 9,10,10,11,11,
- 12,12, 0, 4, 4, 6, 6, 7, 7, 8, 8, 9, 9,10,10,11,
- 11,12,12, 0, 5, 5, 6, 6, 8, 8, 9, 9, 9, 9,10,10,
- 11,12,12,12, 0, 0, 0, 6, 6, 8, 7, 9, 9, 9, 9,10,
- 10,11,11,12,12, 0, 0, 0, 7, 7, 8, 8, 9, 9,10,10,
- 11,11,12,12,13,12, 0, 0, 0, 7, 7, 8, 8, 9, 9,10,
- 10,11,11,12,12,12,13, 0, 0, 0, 7, 7, 8, 8, 9, 9,
- 10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, 8, 8, 9,
- 9,10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,
- };
-
- static float _vq_quantthresh__44c7_s_p4_0[] = {
- -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5,
- 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5,
- };
-
- static long _vq_quantmap__44c7_s_p4_0[] = {
- 15, 13, 11, 9, 7, 5, 3, 1,
- 0, 2, 4, 6, 8, 10, 12, 14,
- 16,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c7_s_p4_0 = {
- _vq_quantthresh__44c7_s_p4_0,
- _vq_quantmap__44c7_s_p4_0,
- 17,
- 17
- };
-
- static static_codebook _44c7_s_p4_0 = {
- 2, 289,
- _vq_lengthlist__44c7_s_p4_0,
- 1, -529530880, 1611661312, 5, 0,
- _vq_quantlist__44c7_s_p4_0,
- NULL,
- &_vq_auxt__44c7_s_p4_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c7_s_p5_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__44c7_s_p5_0[] = {
- 1, 4, 4, 5, 7, 7, 6, 7, 7, 4, 6, 7,10,10,10,10,
- 10, 9, 4, 6, 6,10,10,10,10, 9,10, 5,10,10, 9,11,
- 12,10,11,12, 7,10,10,11,12,12,12,12,12, 7,10,10,
- 11,12,12,12,12,12, 6,10,10,10,12,12,11,12,12, 7,
- 10,10,12,12,12,12,11,12, 7,10,10,11,12,12,12,12,
- 12,
- };
-
- static float _vq_quantthresh__44c7_s_p5_0[] = {
- -5.5, 5.5,
- };
-
- static long _vq_quantmap__44c7_s_p5_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c7_s_p5_0 = {
- _vq_quantthresh__44c7_s_p5_0,
- _vq_quantmap__44c7_s_p5_0,
- 3,
- 3
- };
-
- static static_codebook _44c7_s_p5_0 = {
- 4, 81,
- _vq_lengthlist__44c7_s_p5_0,
- 1, -529137664, 1618345984, 2, 0,
- _vq_quantlist__44c7_s_p5_0,
- NULL,
- &_vq_auxt__44c7_s_p5_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c7_s_p5_1[] = {
- 5,
- 4,
- 6,
- 3,
- 7,
- 2,
- 8,
- 1,
- 9,
- 0,
- 10,
- };
-
- static long _vq_lengthlist__44c7_s_p5_1[] = {
- 3, 5, 5, 6, 6, 7, 7, 8, 8, 8, 8,11, 4, 4, 6, 6,
- 7, 7, 8, 8, 9, 9,11, 4, 4, 6, 6, 7, 7, 8, 8, 9,
- 9,12, 5, 5, 6, 6, 7, 7, 9, 9, 9, 9,12,12,12, 6,
- 6, 7, 7, 9, 9, 9, 9,11,11,11, 7, 7, 7, 7, 8, 8,
- 9, 9,11,11,11, 7, 7, 7, 7, 8, 8, 9, 9,11,11,11,
- 7, 7, 8, 8, 8, 8, 9, 9,11,11,11,11,11, 8, 8, 8,
- 8, 8, 9,11,11,11,11,11, 8, 8, 8, 8, 8, 8,11,11,
- 11,11,11, 7, 7, 8, 8, 8, 8,
- };
-
- static float _vq_quantthresh__44c7_s_p5_1[] = {
- -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5,
- 3.5, 4.5,
- };
-
- static long _vq_quantmap__44c7_s_p5_1[] = {
- 9, 7, 5, 3, 1, 0, 2, 4,
- 6, 8, 10,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c7_s_p5_1 = {
- _vq_quantthresh__44c7_s_p5_1,
- _vq_quantmap__44c7_s_p5_1,
- 11,
- 11
- };
-
- static static_codebook _44c7_s_p5_1 = {
- 2, 121,
- _vq_lengthlist__44c7_s_p5_1,
- 1, -531365888, 1611661312, 4, 0,
- _vq_quantlist__44c7_s_p5_1,
- NULL,
- &_vq_auxt__44c7_s_p5_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c7_s_p6_0[] = {
- 6,
- 5,
- 7,
- 4,
- 8,
- 3,
- 9,
- 2,
- 10,
- 1,
- 11,
- 0,
- 12,
- };
-
- static long _vq_lengthlist__44c7_s_p6_0[] = {
- 1, 4, 4, 6, 6, 7, 7, 8, 7, 9, 8,10,10, 6, 5, 5,
- 7, 7, 8, 8, 9, 9, 9,10,11,11, 7, 5, 5, 7, 7, 8,
- 8, 9, 9,10,10,11,11, 0, 7, 7, 7, 7, 9, 8, 9, 9,
- 10,10,11,11, 0, 8, 8, 7, 7, 8, 9, 9, 9,10,10,11,
- 11, 0,11,11, 9, 9,10,10,11,10,11,11,12,12, 0,12,
- 12, 9, 9,10,10,11,11,11,11,12,12, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0,
- };
-
- static float _vq_quantthresh__44c7_s_p6_0[] = {
- -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5,
- 12.5, 17.5, 22.5, 27.5,
- };
-
- static long _vq_quantmap__44c7_s_p6_0[] = {
- 11, 9, 7, 5, 3, 1, 0, 2,
- 4, 6, 8, 10, 12,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c7_s_p6_0 = {
- _vq_quantthresh__44c7_s_p6_0,
- _vq_quantmap__44c7_s_p6_0,
- 13,
- 13
- };
-
- static static_codebook _44c7_s_p6_0 = {
- 2, 169,
- _vq_lengthlist__44c7_s_p6_0,
- 1, -526516224, 1616117760, 4, 0,
- _vq_quantlist__44c7_s_p6_0,
- NULL,
- &_vq_auxt__44c7_s_p6_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c7_s_p6_1[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__44c7_s_p6_1[] = {
- 3, 4, 4, 5, 5, 5, 4, 4, 5, 5, 5, 4, 4, 5, 5, 6,
- 5, 5, 5, 5, 6, 6, 6, 5, 5,
- };
-
- static float _vq_quantthresh__44c7_s_p6_1[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__44c7_s_p6_1[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c7_s_p6_1 = {
- _vq_quantthresh__44c7_s_p6_1,
- _vq_quantmap__44c7_s_p6_1,
- 5,
- 5
- };
-
- static static_codebook _44c7_s_p6_1 = {
- 2, 25,
- _vq_lengthlist__44c7_s_p6_1,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__44c7_s_p6_1,
- NULL,
- &_vq_auxt__44c7_s_p6_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c7_s_p7_0[] = {
- 6,
- 5,
- 7,
- 4,
- 8,
- 3,
- 9,
- 2,
- 10,
- 1,
- 11,
- 0,
- 12,
- };
-
- static long _vq_lengthlist__44c7_s_p7_0[] = {
- 1, 4, 4, 6, 6, 7, 8, 9, 9,10,10,12,11, 6, 5, 5,
- 7, 7, 8, 8, 9,10,11,11,12,12, 7, 5, 5, 7, 7, 8,
- 8,10,10,11,11,12,12,20, 7, 7, 7, 7, 8, 9,10,10,
- 11,11,12,13,20, 7, 7, 7, 7, 9, 9,10,10,11,12,13,
- 13,20,11,11, 8, 8, 9, 9,11,11,12,12,13,13,20,11,
- 11, 8, 8, 9, 9,11,11,12,12,13,13,20,20,20,10,10,
- 10,10,12,12,13,13,13,13,20,20,20,10,10,10,10,12,
- 12,13,13,13,14,20,20,20,14,14,11,11,12,12,13,13,
- 14,14,20,20,20,14,14,11,11,12,12,13,13,14,14,20,
- 20,20,20,19,13,13,13,13,14,14,15,14,19,19,19,19,
- 19,13,13,13,13,14,14,15,15,
- };
-
- static float _vq_quantthresh__44c7_s_p7_0[] = {
- -60.5, -49.5, -38.5, -27.5, -16.5, -5.5, 5.5, 16.5,
- 27.5, 38.5, 49.5, 60.5,
- };
-
- static long _vq_quantmap__44c7_s_p7_0[] = {
- 11, 9, 7, 5, 3, 1, 0, 2,
- 4, 6, 8, 10, 12,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c7_s_p7_0 = {
- _vq_quantthresh__44c7_s_p7_0,
- _vq_quantmap__44c7_s_p7_0,
- 13,
- 13
- };
-
- static static_codebook _44c7_s_p7_0 = {
- 2, 169,
- _vq_lengthlist__44c7_s_p7_0,
- 1, -523206656, 1618345984, 4, 0,
- _vq_quantlist__44c7_s_p7_0,
- NULL,
- &_vq_auxt__44c7_s_p7_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c7_s_p7_1[] = {
- 5,
- 4,
- 6,
- 3,
- 7,
- 2,
- 8,
- 1,
- 9,
- 0,
- 10,
- };
-
- static long _vq_lengthlist__44c7_s_p7_1[] = {
- 4, 5, 5, 6, 6, 7, 7, 7, 7, 7, 7, 8, 6, 6, 7, 7,
- 7, 7, 7, 7, 7, 7, 8, 6, 6, 6, 7, 7, 7, 7, 7, 7,
- 7, 8, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 7,
- 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 7, 7, 7, 7, 7, 7,
- 7, 7, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8,
- 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 7, 7, 7,
- 7, 7, 7, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 8, 8,
- 8, 8, 8, 7, 7, 7, 7, 7, 7,
- };
-
- static float _vq_quantthresh__44c7_s_p7_1[] = {
- -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5,
- 3.5, 4.5,
- };
-
- static long _vq_quantmap__44c7_s_p7_1[] = {
- 9, 7, 5, 3, 1, 0, 2, 4,
- 6, 8, 10,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c7_s_p7_1 = {
- _vq_quantthresh__44c7_s_p7_1,
- _vq_quantmap__44c7_s_p7_1,
- 11,
- 11
- };
-
- static static_codebook _44c7_s_p7_1 = {
- 2, 121,
- _vq_lengthlist__44c7_s_p7_1,
- 1, -531365888, 1611661312, 4, 0,
- _vq_quantlist__44c7_s_p7_1,
- NULL,
- &_vq_auxt__44c7_s_p7_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c7_s_p8_0[] = {
- 7,
- 6,
- 8,
- 5,
- 9,
- 4,
- 10,
- 3,
- 11,
- 2,
- 12,
- 1,
- 13,
- 0,
- 14,
- };
-
- static long _vq_lengthlist__44c7_s_p8_0[] = {
- 1, 4, 4, 7, 7, 8, 8, 8, 7, 9, 8, 9, 9,10,10, 6,
- 5, 5, 7, 7, 9, 9, 8, 8,10, 9,11,10,12,11, 6, 5,
- 5, 8, 7, 9, 9, 8, 8,10,10,11,11,12,11,19, 8, 8,
- 8, 8,10,10, 9, 9,10,10,11,11,12,11,19, 8, 8, 8,
- 8,10,10, 9, 9,10,10,11,11,12,12,19,12,12, 9, 9,
- 10,10, 9,10,10,10,11,11,12,12,19,12,12, 9, 9,10,
- 10,10,10,10,10,12,12,12,12,19,19,19, 9, 9, 9, 9,
- 11,10,11,11,12,11,13,13,19,19,19, 9, 9, 9, 9,11,
- 10,11,11,11,12,13,13,19,19,19,13,13,10,10,11,11,
- 12,12,12,12,13,12,19,19,19,14,13,10,10,11,11,12,
- 12,12,13,13,13,19,19,19,19,19,12,12,12,11,12,13,
- 14,13,13,13,19,19,19,19,19,12,12,12,11,12,12,13,
- 14,13,14,19,19,19,19,19,16,16,12,13,12,13,13,14,
- 15,14,19,18,18,18,18,16,15,12,11,12,11,14,12,14,
- 14,
- };
-
- static float _vq_quantthresh__44c7_s_p8_0[] = {
- -136.5, -115.5, -94.5, -73.5, -52.5, -31.5, -10.5, 10.5,
- 31.5, 52.5, 73.5, 94.5, 115.5, 136.5,
- };
-
- static long _vq_quantmap__44c7_s_p8_0[] = {
- 13, 11, 9, 7, 5, 3, 1, 0,
- 2, 4, 6, 8, 10, 12, 14,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c7_s_p8_0 = {
- _vq_quantthresh__44c7_s_p8_0,
- _vq_quantmap__44c7_s_p8_0,
- 15,
- 15
- };
-
- static static_codebook _44c7_s_p8_0 = {
- 2, 225,
- _vq_lengthlist__44c7_s_p8_0,
- 1, -520986624, 1620377600, 4, 0,
- _vq_quantlist__44c7_s_p8_0,
- NULL,
- &_vq_auxt__44c7_s_p8_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c7_s_p8_1[] = {
- 10,
- 9,
- 11,
- 8,
- 12,
- 7,
- 13,
- 6,
- 14,
- 5,
- 15,
- 4,
- 16,
- 3,
- 17,
- 2,
- 18,
- 1,
- 19,
- 0,
- 20,
- };
-
- static long _vq_lengthlist__44c7_s_p8_1[] = {
- 3, 5, 5, 7, 6, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8,10, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10, 6, 6, 7, 7, 8,
- 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10,
- 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9,10,10,10, 8, 8, 8, 8, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9,10,10,10, 8, 8, 8, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10,10,
- 10, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9,10,10,10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9,10,11,10,10,10, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9,10, 9, 9,10, 9, 9,10,11,10,
- 11,10, 9, 9, 9, 9, 9, 9, 9,10,10,10, 9,10, 9, 9,
- 9, 9,11,10,11,10,10, 9, 9, 9, 9, 9, 9,10, 9, 9,
- 10, 9, 9,10, 9, 9,10,11,10,10,11,10, 9, 9, 9, 9,
- 9,10,10, 9,10,10,10,10, 9,10,10,10,10,10,10,11,
- 11,11,10, 9, 9, 9,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,11,11,10,10,10,10,10,10,10,10,10,10,10,
- 10, 9,10,10, 9,10,11,11,10,11,10,11,10, 9,10,10,
- 9,10,10,10,10,10,10,10,10,10,10,11,11,11,11,10,
- 11,11,10,10,10,10,10,10, 9,10, 9,10,10, 9,10, 9,
- 10,10,10,11,10,11,10,11,11,10,10,10,10,10,10, 9,
- 10,10,10,10,10,10,10,11,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,11,10,11,
- 11,10,10,10,10, 9, 9,10,10, 9, 9,10, 9,10,10,10,
- 10,11,11,10,10,10,10,10,10,10, 9, 9,10,10,10, 9,
- 9,10,10,10,10,10,11,10,11,10,10,10,10,10,10, 9,
- 10,10,10,10,10,10,10,10,10,
- };
-
- static float _vq_quantthresh__44c7_s_p8_1[] = {
- -9.5, -8.5, -7.5, -6.5, -5.5, -4.5, -3.5, -2.5,
- -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5.5,
- 6.5, 7.5, 8.5, 9.5,
- };
-
- static long _vq_quantmap__44c7_s_p8_1[] = {
- 19, 17, 15, 13, 11, 9, 7, 5,
- 3, 1, 0, 2, 4, 6, 8, 10,
- 12, 14, 16, 18, 20,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c7_s_p8_1 = {
- _vq_quantthresh__44c7_s_p8_1,
- _vq_quantmap__44c7_s_p8_1,
- 21,
- 21
- };
-
- static static_codebook _44c7_s_p8_1 = {
- 2, 441,
- _vq_lengthlist__44c7_s_p8_1,
- 1, -529268736, 1611661312, 5, 0,
- _vq_quantlist__44c7_s_p8_1,
- NULL,
- &_vq_auxt__44c7_s_p8_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c7_s_p9_0[] = {
- 6,
- 5,
- 7,
- 4,
- 8,
- 3,
- 9,
- 2,
- 10,
- 1,
- 11,
- 0,
- 12,
- };
-
- static long _vq_lengthlist__44c7_s_p9_0[] = {
- 1, 3, 3,11,11,11,11,11,11,11,11,11,11, 4, 6, 6,
- 11,11,11,11,11,11,11,11,11,11, 4, 7, 7,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,
- };
-
- static float _vq_quantthresh__44c7_s_p9_0[] = {
- -3503.5, -2866.5, -2229.5, -1592.5, -955.5, -318.5, 318.5, 955.5,
- 1592.5, 2229.5, 2866.5, 3503.5,
- };
-
- static long _vq_quantmap__44c7_s_p9_0[] = {
- 11, 9, 7, 5, 3, 1, 0, 2,
- 4, 6, 8, 10, 12,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c7_s_p9_0 = {
- _vq_quantthresh__44c7_s_p9_0,
- _vq_quantmap__44c7_s_p9_0,
- 13,
- 13
- };
-
- static static_codebook _44c7_s_p9_0 = {
- 2, 169,
- _vq_lengthlist__44c7_s_p9_0,
- 1, -511845376, 1630791680, 4, 0,
- _vq_quantlist__44c7_s_p9_0,
- NULL,
- &_vq_auxt__44c7_s_p9_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c7_s_p9_1[] = {
- 6,
- 5,
- 7,
- 4,
- 8,
- 3,
- 9,
- 2,
- 10,
- 1,
- 11,
- 0,
- 12,
- };
-
- static long _vq_lengthlist__44c7_s_p9_1[] = {
- 1, 4, 4, 7, 7, 7, 7, 7, 6, 8, 8, 8, 8, 6, 6, 6,
- 8, 8, 9, 8, 8, 7, 9, 8,11,10, 5, 6, 6, 8, 8, 9,
- 8, 8, 8,10, 9,11,11,16, 8, 8, 9, 8, 9, 9, 9, 8,
- 10, 9,11,10,16, 8, 8, 9, 9,10,10, 9, 9,10,10,11,
- 11,16,13,13, 9, 9,10,10, 9,10,11,11,12,11,16,13,
- 13, 9, 8,10, 9,10,10,10,10,11,11,16,14,16, 8, 9,
- 9, 9,11,10,11,11,12,11,16,16,16, 9, 7,10, 7,11,
- 10,11,11,12,11,16,16,16,12,12, 9,10,11,11,12,11,
- 12,12,16,16,16,12,10,10, 7,11, 8,12,11,12,12,16,
- 16,15,16,16,11,12,10,10,12,11,12,12,16,16,16,15,
- 15,11,11,10,10,12,12,12,12,
- };
-
- static float _vq_quantthresh__44c7_s_p9_1[] = {
- -269.5, -220.5, -171.5, -122.5, -73.5, -24.5, 24.5, 73.5,
- 122.5, 171.5, 220.5, 269.5,
- };
-
- static long _vq_quantmap__44c7_s_p9_1[] = {
- 11, 9, 7, 5, 3, 1, 0, 2,
- 4, 6, 8, 10, 12,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c7_s_p9_1 = {
- _vq_quantthresh__44c7_s_p9_1,
- _vq_quantmap__44c7_s_p9_1,
- 13,
- 13
- };
-
- static static_codebook _44c7_s_p9_1 = {
- 2, 169,
- _vq_lengthlist__44c7_s_p9_1,
- 1, -518889472, 1622704128, 4, 0,
- _vq_quantlist__44c7_s_p9_1,
- NULL,
- &_vq_auxt__44c7_s_p9_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c7_s_p9_2[] = {
- 24,
- 23,
- 25,
- 22,
- 26,
- 21,
- 27,
- 20,
- 28,
- 19,
- 29,
- 18,
- 30,
- 17,
- 31,
- 16,
- 32,
- 15,
- 33,
- 14,
- 34,
- 13,
- 35,
- 12,
- 36,
- 11,
- 37,
- 10,
- 38,
- 9,
- 39,
- 8,
- 40,
- 7,
- 41,
- 6,
- 42,
- 5,
- 43,
- 4,
- 44,
- 3,
- 45,
- 2,
- 46,
- 1,
- 47,
- 0,
- 48,
- };
-
- static long _vq_lengthlist__44c7_s_p9_2[] = {
- 2, 4, 3, 4, 5, 5, 5, 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, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7,
- };
-
- static float _vq_quantthresh__44c7_s_p9_2[] = {
- -23.5, -22.5, -21.5, -20.5, -19.5, -18.5, -17.5, -16.5,
- -15.5, -14.5, -13.5, -12.5, -11.5, -10.5, -9.5, -8.5,
- -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5,
- 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5,
- 8.5, 9.5, 10.5, 11.5, 12.5, 13.5, 14.5, 15.5,
- 16.5, 17.5, 18.5, 19.5, 20.5, 21.5, 22.5, 23.5,
- };
-
- static long _vq_quantmap__44c7_s_p9_2[] = {
- 47, 45, 43, 41, 39, 37, 35, 33,
- 31, 29, 27, 25, 23, 21, 19, 17,
- 15, 13, 11, 9, 7, 5, 3, 1,
- 0, 2, 4, 6, 8, 10, 12, 14,
- 16, 18, 20, 22, 24, 26, 28, 30,
- 32, 34, 36, 38, 40, 42, 44, 46,
- 48,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c7_s_p9_2 = {
- _vq_quantthresh__44c7_s_p9_2,
- _vq_quantmap__44c7_s_p9_2,
- 49,
- 49
- };
-
- static static_codebook _44c7_s_p9_2 = {
- 1, 49,
- _vq_lengthlist__44c7_s_p9_2,
- 1, -526909440, 1611661312, 6, 0,
- _vq_quantlist__44c7_s_p9_2,
- NULL,
- &_vq_auxt__44c7_s_p9_2,
- NULL,
- 0
- };
-
- static long _huff_lengthlist__44c7_s_short[] = {
- 4,11,12,14,15,15,17,17,18,18, 5, 6, 6, 8, 9,10,
- 13,17,18,19, 7, 5, 4, 6, 8, 9,11,15,19,19, 8, 6,
- 5, 5, 6, 7,11,14,16,17, 9, 7, 7, 6, 7, 7,10,13,
- 15,19,10, 8, 7, 6, 7, 6, 7, 9,14,16,12,10, 9, 7,
- 7, 6, 4, 5,10,15,14,13,11, 7, 6, 6, 4, 2, 7,13,
- 16,16,15, 9, 8, 8, 8, 6, 9,13,19,19,17,12,11,10,
- 10, 9,11,14,
- };
-
- static static_codebook _huff_book__44c7_s_short = {
- 2, 100,
- _huff_lengthlist__44c7_s_short,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist__44c8_s_long[] = {
- 3, 8,12,13,14,14,14,13,14,14, 6, 4, 5, 8,10,10,
- 11,11,14,13, 9, 5, 4, 5, 7, 8, 9,10,13,13,12, 7,
- 5, 4, 5, 6, 8, 9,12,13,13, 9, 6, 5, 5, 5, 7, 9,
- 11,14,12,10, 7, 6, 5, 4, 6, 7,10,11,12,11, 9, 8,
- 7, 5, 5, 6,10,10,13,12,10, 9, 8, 6, 6, 5, 8,10,
- 14,13,12,12,11,10, 9, 7, 8,10,12,13,14,14,13,12,
- 11, 9, 9,10,
- };
-
- static static_codebook _huff_book__44c8_s_long = {
- 2, 100,
- _huff_lengthlist__44c8_s_long,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c8_s_p1_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__44c8_s_p1_0[] = {
- 1, 5, 5, 0, 5, 5, 0, 5, 5, 5, 7, 7, 0, 9, 8, 0,
- 9, 8, 6, 7, 7, 0, 8, 9, 0, 8, 9, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 5, 9, 8, 0, 8, 8, 0, 8, 8, 5, 8, 9,
- 0, 8, 8, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5,
- 9, 8, 0, 8, 8, 0, 8, 8, 5, 8, 9, 0, 8, 8, 0, 8,
- 8,
- };
-
- static float _vq_quantthresh__44c8_s_p1_0[] = {
- -0.5, 0.5,
- };
-
- static long _vq_quantmap__44c8_s_p1_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c8_s_p1_0 = {
- _vq_quantthresh__44c8_s_p1_0,
- _vq_quantmap__44c8_s_p1_0,
- 3,
- 3
- };
-
- static static_codebook _44c8_s_p1_0 = {
- 4, 81,
- _vq_lengthlist__44c8_s_p1_0,
- 1, -535822336, 1611661312, 2, 0,
- _vq_quantlist__44c8_s_p1_0,
- NULL,
- &_vq_auxt__44c8_s_p1_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c8_s_p2_0[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__44c8_s_p2_0[] = {
- 3, 5, 5, 8, 8, 0, 5, 5, 8, 8, 0, 5, 5, 8, 8, 0,
- 7, 7, 9, 9, 0, 0, 0, 9, 9, 5, 7, 7, 9, 9, 0, 8,
- 7,10, 9, 0, 8, 7,10, 9, 0,10,10,11,11, 0, 0, 0,
- 11,11, 5, 7, 7, 9, 9, 0, 7, 8, 9,10, 0, 7, 8, 9,
- 10, 0,10,10,11,11, 0, 0, 0,11,11, 8, 9, 9,11,10,
- 0,11,10,12,11, 0,11,10,12,12, 0,13,13,14,14, 0,
- 0, 0,14,13, 8, 9, 9,10,11, 0,10,11,12,12, 0,10,
- 11,12,12, 0,13,13,14,14, 0, 0, 0,13,14, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 5, 8, 7,11,10, 0, 7, 7,10,10,
- 0, 7, 7,10,10, 0, 9, 9,10,10, 0, 0, 0,11,10, 5,
- 7, 8,10,11, 0, 7, 7,10,10, 0, 7, 7,10,10, 0, 9,
- 9,10,10, 0, 0, 0,10,10, 8,10, 9,12,12, 0,10,10,
- 12,11, 0,10,10,12,12, 0,12,12,13,12, 0, 0, 0,13,
- 12, 8, 9,10,12,12, 0,10,10,11,12, 0,10,10,11,12,
- 0,12,12,13,13, 0, 0, 0,12,13, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 6, 8, 7,11,10, 0, 7, 7,10,10, 0, 7, 7,
- 10,10, 0, 9, 9,10,11, 0, 0, 0,10,10, 6, 7, 8,10,
- 11, 0, 7, 7,10,10, 0, 7, 7,10,10, 0, 9, 9,10,10,
- 0, 0, 0,10,10, 9,10, 9,12,12, 0,10,10,12,12, 0,
- 10,10,12,11, 0,12,12,13,13, 0, 0, 0,13,12, 8, 9,
- 10,12,12, 0,10,10,12,12, 0,10,10,11,12, 0,12,12,
- 13,13, 0, 0, 0,12,13, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 7,10,10,13,13, 0, 9, 9,12,12, 0, 9, 9,12,12, 0,
- 10,10,12,12, 0, 0, 0,12,12, 7,10,10,13,13, 0, 9,
- 9,12,12, 0, 9, 9,12,12, 0,10,10,12,12, 0, 0, 0,
- 12,12, 9,11,11,14,13, 0,10,10,13,12, 0,11,10,13,
- 12, 0,12,12,13,12, 0, 0, 0,13,13, 9,11,11,13,14,
- 0,10,11,12,13, 0,10,11,13,13, 0,12,12,12,13, 0,
- 0, 0,13,13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9,
- 11,11,14,14, 0,10,11,13,13, 0,11,10,13,13, 0,11,
- 12,13,13, 0, 0, 0,13,12, 9,11,11,14,14, 0,11,10,
- 13,13, 0,10,11,13,13, 0,12,12,13,13, 0, 0, 0,12,
- 13,
- };
-
- static float _vq_quantthresh__44c8_s_p2_0[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__44c8_s_p2_0[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c8_s_p2_0 = {
- _vq_quantthresh__44c8_s_p2_0,
- _vq_quantmap__44c8_s_p2_0,
- 5,
- 5
- };
-
- static static_codebook _44c8_s_p2_0 = {
- 4, 625,
- _vq_lengthlist__44c8_s_p2_0,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__44c8_s_p2_0,
- NULL,
- &_vq_auxt__44c8_s_p2_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c8_s_p3_0[] = {
- 4,
- 3,
- 5,
- 2,
- 6,
- 1,
- 7,
- 0,
- 8,
- };
-
- static long _vq_lengthlist__44c8_s_p3_0[] = {
- 2, 4, 4, 5, 5, 7, 7, 9, 9, 0, 4, 4, 6, 6, 7, 7,
- 9, 9, 0, 4, 4, 6, 6, 7, 7, 9, 9, 0, 5, 5, 6, 6,
- 8, 8,10,10, 0, 0, 0, 6, 6, 8, 8,10,10, 0, 0, 0,
- 7, 7, 9, 9,10,10, 0, 0, 0, 7, 7, 8, 8,10,10, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,
- };
-
- static float _vq_quantthresh__44c8_s_p3_0[] = {
- -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5,
- };
-
- static long _vq_quantmap__44c8_s_p3_0[] = {
- 7, 5, 3, 1, 0, 2, 4, 6,
- 8,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c8_s_p3_0 = {
- _vq_quantthresh__44c8_s_p3_0,
- _vq_quantmap__44c8_s_p3_0,
- 9,
- 9
- };
-
- static static_codebook _44c8_s_p3_0 = {
- 2, 81,
- _vq_lengthlist__44c8_s_p3_0,
- 1, -531628032, 1611661312, 4, 0,
- _vq_quantlist__44c8_s_p3_0,
- NULL,
- &_vq_auxt__44c8_s_p3_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c8_s_p4_0[] = {
- 8,
- 7,
- 9,
- 6,
- 10,
- 5,
- 11,
- 4,
- 12,
- 3,
- 13,
- 2,
- 14,
- 1,
- 15,
- 0,
- 16,
- };
-
- static long _vq_lengthlist__44c8_s_p4_0[] = {
- 3, 4, 4, 5, 5, 7, 7, 8, 8, 8, 8, 9, 9,10,10,11,
- 11, 0, 4, 4, 6, 6, 7, 7, 8, 8, 9, 8,10,10,11,11,
- 11,11, 0, 4, 4, 6, 6, 7, 7, 8, 8, 9, 9,10,10,11,
- 11,11,11, 0, 6, 5, 6, 6, 7, 7, 9, 9, 9, 9,10,10,
- 11,11,12,12, 0, 0, 0, 6, 6, 7, 7, 9, 9, 9, 9,10,
- 10,11,11,12,12, 0, 0, 0, 7, 7, 8, 8, 9, 9,10,10,
- 11,11,11,12,12,12, 0, 0, 0, 7, 7, 8, 8, 9, 9,10,
- 10,11,11,11,12,12,12, 0, 0, 0, 7, 7, 8, 8, 9, 9,
- 10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, 8, 8, 9,
- 9,10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,
- };
-
- static float _vq_quantthresh__44c8_s_p4_0[] = {
- -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5,
- 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5,
- };
-
- static long _vq_quantmap__44c8_s_p4_0[] = {
- 15, 13, 11, 9, 7, 5, 3, 1,
- 0, 2, 4, 6, 8, 10, 12, 14,
- 16,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c8_s_p4_0 = {
- _vq_quantthresh__44c8_s_p4_0,
- _vq_quantmap__44c8_s_p4_0,
- 17,
- 17
- };
-
- static static_codebook _44c8_s_p4_0 = {
- 2, 289,
- _vq_lengthlist__44c8_s_p4_0,
- 1, -529530880, 1611661312, 5, 0,
- _vq_quantlist__44c8_s_p4_0,
- NULL,
- &_vq_auxt__44c8_s_p4_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c8_s_p5_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__44c8_s_p5_0[] = {
- 1, 4, 4, 5, 7, 7, 6, 7, 7, 4, 7, 6,10,10,10,10,
- 10,10, 4, 6, 6,10,10,10,10, 9,10, 5,10,10, 9,11,
- 11,10,11,11, 7,10,10,11,12,12,12,12,12, 7,10,10,
- 11,12,12,12,12,12, 6,10,10,10,12,12,10,12,12, 7,
- 10,10,11,12,12,12,12,12, 7,10,10,11,12,12,12,12,
- 12,
- };
-
- static float _vq_quantthresh__44c8_s_p5_0[] = {
- -5.5, 5.5,
- };
-
- static long _vq_quantmap__44c8_s_p5_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c8_s_p5_0 = {
- _vq_quantthresh__44c8_s_p5_0,
- _vq_quantmap__44c8_s_p5_0,
- 3,
- 3
- };
-
- static static_codebook _44c8_s_p5_0 = {
- 4, 81,
- _vq_lengthlist__44c8_s_p5_0,
- 1, -529137664, 1618345984, 2, 0,
- _vq_quantlist__44c8_s_p5_0,
- NULL,
- &_vq_auxt__44c8_s_p5_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c8_s_p5_1[] = {
- 5,
- 4,
- 6,
- 3,
- 7,
- 2,
- 8,
- 1,
- 9,
- 0,
- 10,
- };
-
- static long _vq_lengthlist__44c8_s_p5_1[] = {
- 3, 5, 5, 6, 6, 7, 7, 8, 8, 8, 8,11, 4, 5, 6, 6,
- 7, 7, 8, 8, 8, 8,11, 5, 5, 6, 6, 7, 7, 8, 8, 8,
- 9,12, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9,12,12,12, 6,
- 6, 7, 7, 8, 8, 9, 9,11,11,11, 6, 6, 7, 7, 8, 8,
- 8, 8,11,11,11, 6, 6, 7, 7, 8, 8, 8, 8,11,11,11,
- 7, 7, 7, 8, 8, 8, 8, 8,11,11,11,11,11, 7, 7, 8,
- 8, 8, 8,11,11,11,11,11, 7, 7, 7, 7, 8, 8,11,11,
- 11,11,11, 7, 7, 7, 7, 8, 8,
- };
-
- static float _vq_quantthresh__44c8_s_p5_1[] = {
- -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5,
- 3.5, 4.5,
- };
-
- static long _vq_quantmap__44c8_s_p5_1[] = {
- 9, 7, 5, 3, 1, 0, 2, 4,
- 6, 8, 10,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c8_s_p5_1 = {
- _vq_quantthresh__44c8_s_p5_1,
- _vq_quantmap__44c8_s_p5_1,
- 11,
- 11
- };
-
- static static_codebook _44c8_s_p5_1 = {
- 2, 121,
- _vq_lengthlist__44c8_s_p5_1,
- 1, -531365888, 1611661312, 4, 0,
- _vq_quantlist__44c8_s_p5_1,
- NULL,
- &_vq_auxt__44c8_s_p5_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c8_s_p6_0[] = {
- 6,
- 5,
- 7,
- 4,
- 8,
- 3,
- 9,
- 2,
- 10,
- 1,
- 11,
- 0,
- 12,
- };
-
- static long _vq_lengthlist__44c8_s_p6_0[] = {
- 1, 4, 4, 6, 6, 7, 7, 8, 8, 9, 9,10,10, 6, 5, 5,
- 7, 7, 8, 8, 9, 9,10,10,11,11, 6, 5, 5, 7, 7, 8,
- 8, 9, 9,10,10,11,11, 0, 7, 7, 7, 7, 9, 9,10,10,
- 10,10,11,11, 0, 7, 7, 7, 7, 9, 9,10,10,10,10,11,
- 11, 0,11,11, 9, 9,10,10,11,11,11,11,12,12, 0,12,
- 12, 9, 9,10,10,11,11,12,12,12,12, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0,
- };
-
- static float _vq_quantthresh__44c8_s_p6_0[] = {
- -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5,
- 12.5, 17.5, 22.5, 27.5,
- };
-
- static long _vq_quantmap__44c8_s_p6_0[] = {
- 11, 9, 7, 5, 3, 1, 0, 2,
- 4, 6, 8, 10, 12,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c8_s_p6_0 = {
- _vq_quantthresh__44c8_s_p6_0,
- _vq_quantmap__44c8_s_p6_0,
- 13,
- 13
- };
-
- static static_codebook _44c8_s_p6_0 = {
- 2, 169,
- _vq_lengthlist__44c8_s_p6_0,
- 1, -526516224, 1616117760, 4, 0,
- _vq_quantlist__44c8_s_p6_0,
- NULL,
- &_vq_auxt__44c8_s_p6_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c8_s_p6_1[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__44c8_s_p6_1[] = {
- 3, 4, 4, 5, 5, 5, 4, 4, 5, 5, 5, 4, 4, 5, 5, 6,
- 5, 5, 5, 5, 6, 6, 6, 5, 5,
- };
-
- static float _vq_quantthresh__44c8_s_p6_1[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__44c8_s_p6_1[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c8_s_p6_1 = {
- _vq_quantthresh__44c8_s_p6_1,
- _vq_quantmap__44c8_s_p6_1,
- 5,
- 5
- };
-
- static static_codebook _44c8_s_p6_1 = {
- 2, 25,
- _vq_lengthlist__44c8_s_p6_1,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__44c8_s_p6_1,
- NULL,
- &_vq_auxt__44c8_s_p6_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c8_s_p7_0[] = {
- 6,
- 5,
- 7,
- 4,
- 8,
- 3,
- 9,
- 2,
- 10,
- 1,
- 11,
- 0,
- 12,
- };
-
- static long _vq_lengthlist__44c8_s_p7_0[] = {
- 1, 4, 4, 6, 6, 8, 7, 9, 9,10,10,12,12, 6, 5, 5,
- 7, 7, 8, 8,10,10,11,11,12,12, 7, 5, 5, 7, 7, 8,
- 8,10,10,11,11,12,12,21, 7, 7, 7, 7, 8, 9,10,10,
- 11,11,12,12,21, 7, 7, 7, 7, 9, 9,10,10,12,12,13,
- 13,21,11,11, 8, 8, 9, 9,11,11,12,12,13,13,21,11,
- 11, 8, 8, 9, 9,11,11,12,12,13,13,21,21,21,10,10,
- 10,10,11,11,12,13,13,13,21,21,21,10,10,10,10,11,
- 11,13,13,14,13,21,21,21,13,13,11,11,12,12,13,13,
- 14,14,21,21,21,14,14,11,11,12,12,13,13,14,14,21,
- 21,21,21,20,13,13,13,12,14,14,16,15,20,20,20,20,
- 20,13,13,13,13,14,13,15,15,
- };
-
- static float _vq_quantthresh__44c8_s_p7_0[] = {
- -60.5, -49.5, -38.5, -27.5, -16.5, -5.5, 5.5, 16.5,
- 27.5, 38.5, 49.5, 60.5,
- };
-
- static long _vq_quantmap__44c8_s_p7_0[] = {
- 11, 9, 7, 5, 3, 1, 0, 2,
- 4, 6, 8, 10, 12,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c8_s_p7_0 = {
- _vq_quantthresh__44c8_s_p7_0,
- _vq_quantmap__44c8_s_p7_0,
- 13,
- 13
- };
-
- static static_codebook _44c8_s_p7_0 = {
- 2, 169,
- _vq_lengthlist__44c8_s_p7_0,
- 1, -523206656, 1618345984, 4, 0,
- _vq_quantlist__44c8_s_p7_0,
- NULL,
- &_vq_auxt__44c8_s_p7_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c8_s_p7_1[] = {
- 5,
- 4,
- 6,
- 3,
- 7,
- 2,
- 8,
- 1,
- 9,
- 0,
- 10,
- };
-
- static long _vq_lengthlist__44c8_s_p7_1[] = {
- 4, 5, 6, 6, 6, 7, 7, 7, 7, 7, 7, 8, 6, 6, 6, 7,
- 7, 7, 7, 7, 7, 7, 8, 6, 6, 6, 6, 7, 7, 7, 7, 7,
- 7, 8, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 7,
- 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 7, 7, 7, 7, 7, 7,
- 7, 7, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8,
- 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 7, 7, 7,
- 7, 7, 7, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 8, 8,
- 8, 8, 8, 7, 7, 7, 7, 7, 7,
- };
-
- static float _vq_quantthresh__44c8_s_p7_1[] = {
- -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5,
- 3.5, 4.5,
- };
-
- static long _vq_quantmap__44c8_s_p7_1[] = {
- 9, 7, 5, 3, 1, 0, 2, 4,
- 6, 8, 10,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c8_s_p7_1 = {
- _vq_quantthresh__44c8_s_p7_1,
- _vq_quantmap__44c8_s_p7_1,
- 11,
- 11
- };
-
- static static_codebook _44c8_s_p7_1 = {
- 2, 121,
- _vq_lengthlist__44c8_s_p7_1,
- 1, -531365888, 1611661312, 4, 0,
- _vq_quantlist__44c8_s_p7_1,
- NULL,
- &_vq_auxt__44c8_s_p7_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c8_s_p8_0[] = {
- 7,
- 6,
- 8,
- 5,
- 9,
- 4,
- 10,
- 3,
- 11,
- 2,
- 12,
- 1,
- 13,
- 0,
- 14,
- };
-
- static long _vq_lengthlist__44c8_s_p8_0[] = {
- 1, 4, 4, 7, 6, 8, 8, 8, 7, 9, 8,10,10,11,10, 6,
- 5, 5, 7, 7, 9, 9, 8, 8,10,10,11,11,12,11, 6, 5,
- 5, 7, 7, 9, 9, 9, 9,10,10,11,11,12,12,20, 8, 8,
- 8, 8, 9, 9, 9, 9,10,10,11,11,12,12,20, 8, 8, 8,
- 8,10, 9, 9, 9,10,10,11,11,12,12,20,12,12, 9, 9,
- 10,10,10,10,10,11,12,12,12,12,20,12,12, 9, 9,10,
- 10,10,10,11,11,12,12,13,13,20,20,20, 9, 9, 9, 9,
- 11,10,11,11,12,12,12,13,20,19,19, 9, 9, 9, 9,11,
- 11,11,12,12,12,13,13,19,19,19,13,13,10,10,11,11,
- 12,12,13,13,13,13,19,19,19,14,13,11,10,11,11,12,
- 12,12,13,13,13,19,19,19,19,19,12,12,12,12,13,13,
- 13,13,14,13,19,19,19,19,19,12,12,12,11,12,12,13,
- 14,14,14,19,19,19,19,19,16,15,13,12,13,13,13,14,
- 14,14,19,19,19,19,19,17,17,13,12,13,11,14,13,15,
- 15,
- };
-
- static float _vq_quantthresh__44c8_s_p8_0[] = {
- -136.5, -115.5, -94.5, -73.5, -52.5, -31.5, -10.5, 10.5,
- 31.5, 52.5, 73.5, 94.5, 115.5, 136.5,
- };
-
- static long _vq_quantmap__44c8_s_p8_0[] = {
- 13, 11, 9, 7, 5, 3, 1, 0,
- 2, 4, 6, 8, 10, 12, 14,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c8_s_p8_0 = {
- _vq_quantthresh__44c8_s_p8_0,
- _vq_quantmap__44c8_s_p8_0,
- 15,
- 15
- };
-
- static static_codebook _44c8_s_p8_0 = {
- 2, 225,
- _vq_lengthlist__44c8_s_p8_0,
- 1, -520986624, 1620377600, 4, 0,
- _vq_quantlist__44c8_s_p8_0,
- NULL,
- &_vq_auxt__44c8_s_p8_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c8_s_p8_1[] = {
- 10,
- 9,
- 11,
- 8,
- 12,
- 7,
- 13,
- 6,
- 14,
- 5,
- 15,
- 4,
- 16,
- 3,
- 17,
- 2,
- 18,
- 1,
- 19,
- 0,
- 20,
- };
-
- static long _vq_lengthlist__44c8_s_p8_1[] = {
- 4, 5, 5, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8,10, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10, 6, 6, 7, 7, 8,
- 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10,
- 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9,10,10,10, 8, 8, 8, 8, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9,10,10,10, 8, 8, 8, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10,10,
- 10, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9,10,10,10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9,10,10,10,10,10, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10,10,10,
- 10,10, 9, 9, 9, 9, 9, 9, 9, 9,10, 9, 9, 9, 9, 9,
- 9, 9,10,10,10,10,10, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9,10,10,10,10,10, 9, 9, 9, 9,
- 9, 9, 9, 9,10,10,10, 9, 9, 9, 9, 9,10,10,10,10,
- 10,10,10, 9, 9, 9, 9, 9,10,10,10, 9, 9, 9, 9, 9,
- 9,10,10,10,10,10,10,10, 9,10,10, 9,10,10,10,10,
- 9,10, 9,10,10, 9,10,10,10,10,10,10,10, 9,10,10,
- 10,10,10,10, 9, 9,10,10, 9,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10, 9, 9, 9,10, 9, 9, 9, 9,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10, 9, 9,
- 10, 9,10, 9,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10, 9, 9,10, 9, 9, 9,10,10,10,10,10,10,
- 10,10,10,10,10, 9, 9, 9, 9, 9, 9,10, 9, 9,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10, 9,10, 9,
- 9,10, 9, 9,10,10,10,10,10,10,10,10,10,10,10,10,
- 10, 9, 9,10,10, 9,10, 9, 9,
- };
-
- static float _vq_quantthresh__44c8_s_p8_1[] = {
- -9.5, -8.5, -7.5, -6.5, -5.5, -4.5, -3.5, -2.5,
- -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5.5,
- 6.5, 7.5, 8.5, 9.5,
- };
-
- static long _vq_quantmap__44c8_s_p8_1[] = {
- 19, 17, 15, 13, 11, 9, 7, 5,
- 3, 1, 0, 2, 4, 6, 8, 10,
- 12, 14, 16, 18, 20,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c8_s_p8_1 = {
- _vq_quantthresh__44c8_s_p8_1,
- _vq_quantmap__44c8_s_p8_1,
- 21,
- 21
- };
-
- static static_codebook _44c8_s_p8_1 = {
- 2, 441,
- _vq_lengthlist__44c8_s_p8_1,
- 1, -529268736, 1611661312, 5, 0,
- _vq_quantlist__44c8_s_p8_1,
- NULL,
- &_vq_auxt__44c8_s_p8_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c8_s_p9_0[] = {
- 8,
- 7,
- 9,
- 6,
- 10,
- 5,
- 11,
- 4,
- 12,
- 3,
- 13,
- 2,
- 14,
- 1,
- 15,
- 0,
- 16,
- };
-
- static long _vq_lengthlist__44c8_s_p9_0[] = {
- 1, 4, 3,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11, 4, 7, 7,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11, 4, 8,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,
- };
-
- static float _vq_quantthresh__44c8_s_p9_0[] = {
- -6982.5, -6051.5, -5120.5, -4189.5, -3258.5, -2327.5, -1396.5, -465.5,
- 465.5, 1396.5, 2327.5, 3258.5, 4189.5, 5120.5, 6051.5, 6982.5,
- };
-
- static long _vq_quantmap__44c8_s_p9_0[] = {
- 15, 13, 11, 9, 7, 5, 3, 1,
- 0, 2, 4, 6, 8, 10, 12, 14,
- 16,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c8_s_p9_0 = {
- _vq_quantthresh__44c8_s_p9_0,
- _vq_quantmap__44c8_s_p9_0,
- 17,
- 17
- };
-
- static static_codebook _44c8_s_p9_0 = {
- 2, 289,
- _vq_lengthlist__44c8_s_p9_0,
- 1, -509798400, 1631393792, 5, 0,
- _vq_quantlist__44c8_s_p9_0,
- NULL,
- &_vq_auxt__44c8_s_p9_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c8_s_p9_1[] = {
- 9,
- 8,
- 10,
- 7,
- 11,
- 6,
- 12,
- 5,
- 13,
- 4,
- 14,
- 3,
- 15,
- 2,
- 16,
- 1,
- 17,
- 0,
- 18,
- };
-
- static long _vq_lengthlist__44c8_s_p9_1[] = {
- 1, 4, 4, 7, 6, 7, 7, 7, 7, 8, 8, 9, 9,10,10,10,
- 10,11,11, 6, 6, 6, 8, 8, 9, 8, 8, 7,10, 8,11,10,
- 12,11,12,12,13,13, 5, 5, 6, 8, 8, 9, 9, 8, 8,10,
- 9,11,11,12,12,13,13,13,13,17, 8, 8, 9, 9, 9, 9,
- 9, 9,10, 9,12,10,12,12,13,12,13,13,17, 9, 8, 9,
- 9, 9, 9, 9, 9,10,10,12,12,12,12,13,13,13,13,17,
- 13,13, 9, 9,10,10,10,10,11,11,12,11,13,12,13,13,
- 14,15,17,13,13, 9, 8,10, 9,10,10,11,11,12,12,14,
- 13,15,13,14,15,17,17,17, 9,10, 9,10,11,11,12,12,
- 12,12,13,13,14,14,15,15,17,17,17, 9, 8, 9, 8,11,
- 11,12,12,12,12,14,13,14,14,14,15,17,17,17,12,14,
- 9,10,11,11,12,12,14,13,13,14,15,13,15,15,17,17,
- 17,13,11,10, 8,11, 9,13,12,13,13,13,13,13,14,14,
- 14,17,17,17,17,17,11,12,11,11,13,13,14,13,15,14,
- 13,15,16,15,17,17,17,17,17,11,11,12, 8,13,12,14,
- 13,17,14,15,14,15,14,17,17,17,17,17,15,15,12,12,
- 12,12,13,14,14,14,15,14,17,14,17,17,17,17,17,16,
- 17,12,12,13,12,13,13,14,14,14,14,14,14,17,17,17,
- 17,17,17,17,14,14,13,12,13,13,15,15,14,13,15,17,
- 17,17,17,17,17,17,17,13,14,13,13,13,13,14,15,15,
- 15,14,15,17,17,17,17,17,17,17,16,15,13,14,13,13,
- 14,14,15,14,14,16,17,17,17,17,17,17,17,16,16,13,
- 14,13,13,14,14,15,14,15,14,
- };
-
- static float _vq_quantthresh__44c8_s_p9_1[] = {
- -416.5, -367.5, -318.5, -269.5, -220.5, -171.5, -122.5, -73.5,
- -24.5, 24.5, 73.5, 122.5, 171.5, 220.5, 269.5, 318.5,
- 367.5, 416.5,
- };
-
- static long _vq_quantmap__44c8_s_p9_1[] = {
- 17, 15, 13, 11, 9, 7, 5, 3,
- 1, 0, 2, 4, 6, 8, 10, 12,
- 14, 16, 18,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c8_s_p9_1 = {
- _vq_quantthresh__44c8_s_p9_1,
- _vq_quantmap__44c8_s_p9_1,
- 19,
- 19
- };
-
- static static_codebook _44c8_s_p9_1 = {
- 2, 361,
- _vq_lengthlist__44c8_s_p9_1,
- 1, -518287360, 1622704128, 5, 0,
- _vq_quantlist__44c8_s_p9_1,
- NULL,
- &_vq_auxt__44c8_s_p9_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c8_s_p9_2[] = {
- 24,
- 23,
- 25,
- 22,
- 26,
- 21,
- 27,
- 20,
- 28,
- 19,
- 29,
- 18,
- 30,
- 17,
- 31,
- 16,
- 32,
- 15,
- 33,
- 14,
- 34,
- 13,
- 35,
- 12,
- 36,
- 11,
- 37,
- 10,
- 38,
- 9,
- 39,
- 8,
- 40,
- 7,
- 41,
- 6,
- 42,
- 5,
- 43,
- 4,
- 44,
- 3,
- 45,
- 2,
- 46,
- 1,
- 47,
- 0,
- 48,
- };
-
- static long _vq_lengthlist__44c8_s_p9_2[] = {
- 2, 4, 4, 4, 5, 5, 5, 5, 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, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7,
- };
-
- static float _vq_quantthresh__44c8_s_p9_2[] = {
- -23.5, -22.5, -21.5, -20.5, -19.5, -18.5, -17.5, -16.5,
- -15.5, -14.5, -13.5, -12.5, -11.5, -10.5, -9.5, -8.5,
- -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5,
- 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5,
- 8.5, 9.5, 10.5, 11.5, 12.5, 13.5, 14.5, 15.5,
- 16.5, 17.5, 18.5, 19.5, 20.5, 21.5, 22.5, 23.5,
- };
-
- static long _vq_quantmap__44c8_s_p9_2[] = {
- 47, 45, 43, 41, 39, 37, 35, 33,
- 31, 29, 27, 25, 23, 21, 19, 17,
- 15, 13, 11, 9, 7, 5, 3, 1,
- 0, 2, 4, 6, 8, 10, 12, 14,
- 16, 18, 20, 22, 24, 26, 28, 30,
- 32, 34, 36, 38, 40, 42, 44, 46,
- 48,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c8_s_p9_2 = {
- _vq_quantthresh__44c8_s_p9_2,
- _vq_quantmap__44c8_s_p9_2,
- 49,
- 49
- };
-
- static static_codebook _44c8_s_p9_2 = {
- 1, 49,
- _vq_lengthlist__44c8_s_p9_2,
- 1, -526909440, 1611661312, 6, 0,
- _vq_quantlist__44c8_s_p9_2,
- NULL,
- &_vq_auxt__44c8_s_p9_2,
- NULL,
- 0
- };
-
- static long _huff_lengthlist__44c8_s_short[] = {
- 4,11,13,14,15,15,18,17,19,17, 5, 6, 8, 9,10,10,
- 12,15,19,19, 6, 6, 6, 6, 8, 8,11,14,18,19, 8, 6,
- 5, 4, 6, 7,10,13,16,17, 9, 7, 6, 5, 6, 7, 9,12,
- 15,19,10, 8, 7, 6, 6, 6, 7, 9,13,15,12,10, 9, 8,
- 7, 6, 4, 5,10,15,13,13,11, 8, 6, 6, 4, 2, 7,12,
- 17,15,16,10, 8, 8, 7, 6, 9,12,19,18,17,13,11,10,
- 10, 9,11,14,
- };
-
- static static_codebook _huff_book__44c8_s_short = {
- 2, 100,
- _huff_lengthlist__44c8_s_short,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist__44c9_s_long[] = {
- 3, 8,12,14,15,15,15,13,15,15, 6, 5, 8,10,12,12,
- 13,12,14,13,10, 6, 5, 6, 8, 9,11,11,13,13,13, 8,
- 5, 4, 5, 6, 8,10,11,13,14,10, 7, 5, 4, 5, 7, 9,
- 11,12,13,11, 8, 6, 5, 4, 5, 7, 9,11,12,11,10, 8,
- 7, 5, 4, 5, 9,10,13,13,11,10, 8, 6, 5, 4, 7, 9,
- 15,14,13,12,10, 9, 8, 7, 8, 9,12,12,14,13,12,11,
- 10, 9, 8, 9,
- };
-
- static static_codebook _huff_book__44c9_s_long = {
- 2, 100,
- _huff_lengthlist__44c9_s_long,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c9_s_p1_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__44c9_s_p1_0[] = {
- 1, 5, 5, 0, 5, 5, 0, 5, 5, 6, 8, 8, 0, 9, 8, 0,
- 9, 8, 6, 8, 8, 0, 8, 9, 0, 8, 9, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 5, 8, 8, 0, 7, 7, 0, 8, 8, 5, 8, 8,
- 0, 7, 8, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5,
- 9, 8, 0, 8, 8, 0, 7, 7, 5, 8, 9, 0, 8, 8, 0, 7,
- 7,
- };
-
- static float _vq_quantthresh__44c9_s_p1_0[] = {
- -0.5, 0.5,
- };
-
- static long _vq_quantmap__44c9_s_p1_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c9_s_p1_0 = {
- _vq_quantthresh__44c9_s_p1_0,
- _vq_quantmap__44c9_s_p1_0,
- 3,
- 3
- };
-
- static static_codebook _44c9_s_p1_0 = {
- 4, 81,
- _vq_lengthlist__44c9_s_p1_0,
- 1, -535822336, 1611661312, 2, 0,
- _vq_quantlist__44c9_s_p1_0,
- NULL,
- &_vq_auxt__44c9_s_p1_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c9_s_p2_0[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__44c9_s_p2_0[] = {
- 3, 5, 5, 8, 8, 0, 5, 5, 8, 8, 0, 5, 5, 8, 8, 0,
- 7, 7, 9, 9, 0, 0, 0, 9, 9, 6, 7, 7, 9, 8, 0, 8,
- 8, 9, 9, 0, 8, 7, 9, 9, 0, 9,10,10,10, 0, 0, 0,
- 11,10, 6, 7, 7, 8, 9, 0, 8, 8, 9, 9, 0, 7, 8, 9,
- 9, 0,10, 9,11,10, 0, 0, 0,10,10, 8, 9, 8,10,10,
- 0,10,10,12,11, 0,10,10,11,11, 0,12,13,13,13, 0,
- 0, 0,13,12, 8, 8, 9,10,10, 0,10,10,11,12, 0,10,
- 10,11,11, 0,13,12,13,13, 0, 0, 0,13,13, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 6, 8, 7,10,10, 0, 7, 7,10, 9,
- 0, 7, 7,10,10, 0, 9, 9,10,10, 0, 0, 0,10,10, 6,
- 7, 8,10,10, 0, 7, 7, 9,10, 0, 7, 7,10,10, 0, 9,
- 9,10,10, 0, 0, 0,10,10, 8, 9, 9,11,11, 0,10,10,
- 11,11, 0,10,10,11,11, 0,12,12,12,12, 0, 0, 0,12,
- 12, 8, 9,10,11,11, 0, 9,10,11,11, 0,10,10,11,11,
- 0,12,12,12,12, 0, 0, 0,12,12, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 5, 8, 7,10,10, 0, 7, 7,10,10, 0, 7, 7,
- 10, 9, 0, 9, 9,10,10, 0, 0, 0,10,10, 6, 7, 8,10,
- 10, 0, 7, 7,10,10, 0, 7, 7, 9,10, 0, 9, 9,10,10,
- 0, 0, 0,10,10, 8,10, 9,12,11, 0,10,10,12,11, 0,
- 10, 9,11,11, 0,11,12,12,12, 0, 0, 0,12,12, 8, 9,
- 10,11,12, 0,10,10,11,11, 0, 9,10,11,11, 0,12,11,
- 12,12, 0, 0, 0,12,12, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 7,10, 9,12,12, 0, 9, 9,12,11, 0, 9, 9,11,11, 0,
- 10,10,12,11, 0, 0, 0,11,12, 7, 9,10,12,12, 0, 9,
- 9,11,12, 0, 9, 9,11,11, 0,10,10,11,12, 0, 0, 0,
- 11,11, 9,11,10,13,12, 0,10,10,12,12, 0,10,10,12,
- 12, 0,11,11,12,12, 0, 0, 0,13,12, 9,10,11,12,13,
- 0,10,10,12,12, 0,10,10,12,12, 0,11,12,12,12, 0,
- 0, 0,12,13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9,
- 11,10,13,13, 0,10,10,12,12, 0,10,10,12,12, 0,11,
- 12,12,12, 0, 0, 0,12,12, 9,10,11,13,13, 0,10,10,
- 12,12, 0,10,10,12,12, 0,12,11,13,12, 0, 0, 0,12,
- 12,
- };
-
- static float _vq_quantthresh__44c9_s_p2_0[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__44c9_s_p2_0[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c9_s_p2_0 = {
- _vq_quantthresh__44c9_s_p2_0,
- _vq_quantmap__44c9_s_p2_0,
- 5,
- 5
- };
-
- static static_codebook _44c9_s_p2_0 = {
- 4, 625,
- _vq_lengthlist__44c9_s_p2_0,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__44c9_s_p2_0,
- NULL,
- &_vq_auxt__44c9_s_p2_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c9_s_p3_0[] = {
- 4,
- 3,
- 5,
- 2,
- 6,
- 1,
- 7,
- 0,
- 8,
- };
-
- static long _vq_lengthlist__44c9_s_p3_0[] = {
- 3, 4, 4, 5, 5, 6, 6, 8, 8, 0, 4, 4, 5, 5, 6, 7,
- 8, 8, 0, 4, 4, 5, 5, 7, 7, 8, 8, 0, 5, 5, 6, 6,
- 7, 7, 9, 9, 0, 0, 0, 6, 6, 7, 7, 9, 9, 0, 0, 0,
- 7, 7, 8, 8, 9, 9, 0, 0, 0, 7, 7, 8, 8, 9, 9, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,
- };
-
- static float _vq_quantthresh__44c9_s_p3_0[] = {
- -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5,
- };
-
- static long _vq_quantmap__44c9_s_p3_0[] = {
- 7, 5, 3, 1, 0, 2, 4, 6,
- 8,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c9_s_p3_0 = {
- _vq_quantthresh__44c9_s_p3_0,
- _vq_quantmap__44c9_s_p3_0,
- 9,
- 9
- };
-
- static static_codebook _44c9_s_p3_0 = {
- 2, 81,
- _vq_lengthlist__44c9_s_p3_0,
- 1, -531628032, 1611661312, 4, 0,
- _vq_quantlist__44c9_s_p3_0,
- NULL,
- &_vq_auxt__44c9_s_p3_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c9_s_p4_0[] = {
- 8,
- 7,
- 9,
- 6,
- 10,
- 5,
- 11,
- 4,
- 12,
- 3,
- 13,
- 2,
- 14,
- 1,
- 15,
- 0,
- 16,
- };
-
- static long _vq_lengthlist__44c9_s_p4_0[] = {
- 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9,10,10,10,
- 10, 0, 5, 4, 5, 5, 7, 7, 8, 8, 8, 8, 9, 9,10,10,
- 11,11, 0, 5, 5, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9,10,
- 10,11,11, 0, 6, 5, 6, 6, 7, 7, 8, 8, 9, 9,10,10,
- 11,11,11,12, 0, 0, 0, 6, 6, 7, 7, 8, 8, 9, 9,10,
- 10,11,11,12,12, 0, 0, 0, 7, 7, 7, 7, 9, 9, 9, 9,
- 10,10,11,11,12,12, 0, 0, 0, 7, 7, 7, 8, 9, 9, 9,
- 9,10,10,11,11,12,12, 0, 0, 0, 7, 7, 8, 8, 9, 9,
- 10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, 8, 8, 9,
- 9,10,10,11,11,12,12,12,12, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,
- };
-
- static float _vq_quantthresh__44c9_s_p4_0[] = {
- -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5,
- 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5,
- };
-
- static long _vq_quantmap__44c9_s_p4_0[] = {
- 15, 13, 11, 9, 7, 5, 3, 1,
- 0, 2, 4, 6, 8, 10, 12, 14,
- 16,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c9_s_p4_0 = {
- _vq_quantthresh__44c9_s_p4_0,
- _vq_quantmap__44c9_s_p4_0,
- 17,
- 17
- };
-
- static static_codebook _44c9_s_p4_0 = {
- 2, 289,
- _vq_lengthlist__44c9_s_p4_0,
- 1, -529530880, 1611661312, 5, 0,
- _vq_quantlist__44c9_s_p4_0,
- NULL,
- &_vq_auxt__44c9_s_p4_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c9_s_p5_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__44c9_s_p5_0[] = {
- 1, 4, 4, 5, 7, 7, 6, 7, 7, 4, 7, 6, 9,10,10,10,
- 10, 9, 4, 6, 7, 9,10,10,10, 9,10, 5, 9, 9, 9,11,
- 11,10,11,11, 7,10, 9,11,12,11,12,12,12, 7, 9,10,
- 11,11,12,12,12,12, 6,10,10,10,12,12,10,12,11, 7,
- 10,10,11,12,12,11,12,12, 7,10,10,11,12,12,12,12,
- 12,
- };
-
- static float _vq_quantthresh__44c9_s_p5_0[] = {
- -5.5, 5.5,
- };
-
- static long _vq_quantmap__44c9_s_p5_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c9_s_p5_0 = {
- _vq_quantthresh__44c9_s_p5_0,
- _vq_quantmap__44c9_s_p5_0,
- 3,
- 3
- };
-
- static static_codebook _44c9_s_p5_0 = {
- 4, 81,
- _vq_lengthlist__44c9_s_p5_0,
- 1, -529137664, 1618345984, 2, 0,
- _vq_quantlist__44c9_s_p5_0,
- NULL,
- &_vq_auxt__44c9_s_p5_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c9_s_p5_1[] = {
- 5,
- 4,
- 6,
- 3,
- 7,
- 2,
- 8,
- 1,
- 9,
- 0,
- 10,
- };
-
- static long _vq_lengthlist__44c9_s_p5_1[] = {
- 4, 5, 5, 6, 6, 7, 7, 7, 7, 7, 7,11, 5, 5, 6, 6,
- 7, 7, 7, 7, 8, 8,11, 5, 5, 6, 6, 7, 7, 7, 7, 8,
- 8,11, 5, 5, 6, 6, 7, 7, 8, 8, 8, 8,11,11,11, 6,
- 6, 7, 7, 7, 8, 8, 8,11,11,11, 6, 6, 7, 7, 7, 8,
- 8, 8,11,11,11, 6, 6, 7, 7, 7, 7, 8, 8,11,11,11,
- 7, 7, 7, 7, 7, 7, 8, 8,11,11,11,10,10, 7, 7, 7,
- 7, 8, 8,11,11,11,11,11, 7, 7, 7, 7, 7, 7,11,11,
- 11,11,11, 7, 7, 7, 7, 7, 7,
- };
-
- static float _vq_quantthresh__44c9_s_p5_1[] = {
- -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5,
- 3.5, 4.5,
- };
-
- static long _vq_quantmap__44c9_s_p5_1[] = {
- 9, 7, 5, 3, 1, 0, 2, 4,
- 6, 8, 10,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c9_s_p5_1 = {
- _vq_quantthresh__44c9_s_p5_1,
- _vq_quantmap__44c9_s_p5_1,
- 11,
- 11
- };
-
- static static_codebook _44c9_s_p5_1 = {
- 2, 121,
- _vq_lengthlist__44c9_s_p5_1,
- 1, -531365888, 1611661312, 4, 0,
- _vq_quantlist__44c9_s_p5_1,
- NULL,
- &_vq_auxt__44c9_s_p5_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c9_s_p6_0[] = {
- 6,
- 5,
- 7,
- 4,
- 8,
- 3,
- 9,
- 2,
- 10,
- 1,
- 11,
- 0,
- 12,
- };
-
- static long _vq_lengthlist__44c9_s_p6_0[] = {
- 2, 4, 4, 6, 6, 7, 7, 7, 7, 8, 8, 9, 9, 5, 4, 4,
- 6, 6, 8, 8, 9, 9, 9, 9,10,10, 6, 4, 4, 6, 6, 8,
- 8, 9, 9, 9, 9,10,10, 0, 6, 6, 7, 7, 8, 8, 9, 9,
- 10,10,11,11, 0, 6, 6, 7, 7, 8, 8, 9, 9,10,10,11,
- 11, 0,10,10, 8, 8, 9, 9,10,10,11,11,12,12, 0,11,
- 11, 8, 8, 9, 9,10,10,11,11,12,12, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0,
- };
-
- static float _vq_quantthresh__44c9_s_p6_0[] = {
- -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5,
- 12.5, 17.5, 22.5, 27.5,
- };
-
- static long _vq_quantmap__44c9_s_p6_0[] = {
- 11, 9, 7, 5, 3, 1, 0, 2,
- 4, 6, 8, 10, 12,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c9_s_p6_0 = {
- _vq_quantthresh__44c9_s_p6_0,
- _vq_quantmap__44c9_s_p6_0,
- 13,
- 13
- };
-
- static static_codebook _44c9_s_p6_0 = {
- 2, 169,
- _vq_lengthlist__44c9_s_p6_0,
- 1, -526516224, 1616117760, 4, 0,
- _vq_quantlist__44c9_s_p6_0,
- NULL,
- &_vq_auxt__44c9_s_p6_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c9_s_p6_1[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__44c9_s_p6_1[] = {
- 4, 4, 4, 5, 5, 5, 4, 4, 5, 5, 5, 4, 4, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5,
- };
-
- static float _vq_quantthresh__44c9_s_p6_1[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__44c9_s_p6_1[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c9_s_p6_1 = {
- _vq_quantthresh__44c9_s_p6_1,
- _vq_quantmap__44c9_s_p6_1,
- 5,
- 5
- };
-
- static static_codebook _44c9_s_p6_1 = {
- 2, 25,
- _vq_lengthlist__44c9_s_p6_1,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__44c9_s_p6_1,
- NULL,
- &_vq_auxt__44c9_s_p6_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c9_s_p7_0[] = {
- 6,
- 5,
- 7,
- 4,
- 8,
- 3,
- 9,
- 2,
- 10,
- 1,
- 11,
- 0,
- 12,
- };
-
- static long _vq_lengthlist__44c9_s_p7_0[] = {
- 2, 4, 4, 6, 6, 7, 7, 8, 8,10,10,11,11, 6, 4, 4,
- 6, 6, 8, 8, 9, 9,10,10,12,12, 6, 4, 5, 6, 6, 8,
- 8, 9, 9,10,10,12,12,20, 6, 6, 6, 6, 8, 8, 9,10,
- 11,11,12,12,20, 6, 6, 6, 6, 8, 8,10,10,11,11,12,
- 12,20,10,10, 7, 7, 9, 9,10,10,11,11,12,12,20,11,
- 11, 7, 7, 9, 9,10,10,11,11,12,12,20,20,20, 9, 9,
- 9, 9,11,11,12,12,13,13,20,20,20, 9, 9, 9, 9,11,
- 11,12,12,13,13,20,20,20,13,13,10,10,11,11,12,13,
- 13,13,20,20,20,13,13,10,10,11,11,12,13,13,13,20,
- 20,20,20,19,12,12,12,12,13,13,14,15,19,19,19,19,
- 19,12,12,12,12,13,13,14,14,
- };
-
- static float _vq_quantthresh__44c9_s_p7_0[] = {
- -60.5, -49.5, -38.5, -27.5, -16.5, -5.5, 5.5, 16.5,
- 27.5, 38.5, 49.5, 60.5,
- };
-
- static long _vq_quantmap__44c9_s_p7_0[] = {
- 11, 9, 7, 5, 3, 1, 0, 2,
- 4, 6, 8, 10, 12,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c9_s_p7_0 = {
- _vq_quantthresh__44c9_s_p7_0,
- _vq_quantmap__44c9_s_p7_0,
- 13,
- 13
- };
-
- static static_codebook _44c9_s_p7_0 = {
- 2, 169,
- _vq_lengthlist__44c9_s_p7_0,
- 1, -523206656, 1618345984, 4, 0,
- _vq_quantlist__44c9_s_p7_0,
- NULL,
- &_vq_auxt__44c9_s_p7_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c9_s_p7_1[] = {
- 5,
- 4,
- 6,
- 3,
- 7,
- 2,
- 8,
- 1,
- 9,
- 0,
- 10,
- };
-
- static long _vq_lengthlist__44c9_s_p7_1[] = {
- 5, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6,
- 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 7, 7, 7, 7, 7,
- 7, 8, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 8, 8, 8, 6,
- 6, 7, 7, 7, 7, 7, 7, 8, 8, 8, 7, 7, 7, 7, 7, 7,
- 7, 7, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8,
- 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 7, 7, 7,
- 7, 7, 7, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 8, 8,
- 8, 8, 8, 7, 7, 7, 7, 7, 7,
- };
-
- static float _vq_quantthresh__44c9_s_p7_1[] = {
- -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5,
- 3.5, 4.5,
- };
-
- static long _vq_quantmap__44c9_s_p7_1[] = {
- 9, 7, 5, 3, 1, 0, 2, 4,
- 6, 8, 10,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c9_s_p7_1 = {
- _vq_quantthresh__44c9_s_p7_1,
- _vq_quantmap__44c9_s_p7_1,
- 11,
- 11
- };
-
- static static_codebook _44c9_s_p7_1 = {
- 2, 121,
- _vq_lengthlist__44c9_s_p7_1,
- 1, -531365888, 1611661312, 4, 0,
- _vq_quantlist__44c9_s_p7_1,
- NULL,
- &_vq_auxt__44c9_s_p7_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c9_s_p8_0[] = {
- 7,
- 6,
- 8,
- 5,
- 9,
- 4,
- 10,
- 3,
- 11,
- 2,
- 12,
- 1,
- 13,
- 0,
- 14,
- };
-
- static long _vq_lengthlist__44c9_s_p8_0[] = {
- 1, 4, 4, 7, 6, 8, 8, 8, 8, 9, 9,10,10,11,10, 6,
- 5, 5, 7, 7, 9, 9, 8, 9,10,10,11,11,12,12, 6, 5,
- 5, 7, 7, 9, 9, 9, 9,10,10,11,11,12,12,21, 7, 8,
- 8, 8, 9, 9, 9, 9,10,10,11,11,12,12,21, 8, 8, 8,
- 8, 9, 9, 9, 9,10,10,11,11,12,12,21,11,12, 9, 9,
- 10,10,10,10,10,11,11,12,12,12,21,12,12, 9, 8,10,
- 10,10,10,11,11,12,12,13,13,21,21,21, 9, 9, 9, 9,
- 11,11,11,11,12,12,12,13,21,20,20, 9, 9, 9, 9,10,
- 11,11,11,12,12,13,13,20,20,20,13,13,10,10,11,11,
- 12,12,13,13,13,13,20,20,20,13,13,10,10,11,11,12,
- 12,13,13,13,13,20,20,20,20,20,12,12,12,12,12,12,
- 13,13,14,14,20,20,20,20,20,12,12,12,11,13,12,13,
- 13,14,14,20,20,20,20,20,15,16,13,12,13,13,14,13,
- 14,14,20,20,20,20,20,16,15,12,12,13,12,14,13,14,
- 14,
- };
-
- static float _vq_quantthresh__44c9_s_p8_0[] = {
- -136.5, -115.5, -94.5, -73.5, -52.5, -31.5, -10.5, 10.5,
- 31.5, 52.5, 73.5, 94.5, 115.5, 136.5,
- };
-
- static long _vq_quantmap__44c9_s_p8_0[] = {
- 13, 11, 9, 7, 5, 3, 1, 0,
- 2, 4, 6, 8, 10, 12, 14,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c9_s_p8_0 = {
- _vq_quantthresh__44c9_s_p8_0,
- _vq_quantmap__44c9_s_p8_0,
- 15,
- 15
- };
-
- static static_codebook _44c9_s_p8_0 = {
- 2, 225,
- _vq_lengthlist__44c9_s_p8_0,
- 1, -520986624, 1620377600, 4, 0,
- _vq_quantlist__44c9_s_p8_0,
- NULL,
- &_vq_auxt__44c9_s_p8_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c9_s_p8_1[] = {
- 10,
- 9,
- 11,
- 8,
- 12,
- 7,
- 13,
- 6,
- 14,
- 5,
- 15,
- 4,
- 16,
- 3,
- 17,
- 2,
- 18,
- 1,
- 19,
- 0,
- 20,
- };
-
- static long _vq_lengthlist__44c9_s_p8_1[] = {
- 4, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8,10, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10, 6, 6, 7, 7, 8,
- 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10,
- 7, 7, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9,10,10,10, 8, 8, 8, 8, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9,10,10,10, 8, 8, 8, 8,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10,10,
- 10, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9,10,10,10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9,10,10,10,10,10, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10,10,10,
- 10,10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9,10,10,10,10,10, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9,10,10,10,10,10, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9,10, 9, 9, 9,10,10,10,10,
- 10,10,10, 9, 9, 9, 9, 9, 9,10, 9, 9, 9, 9, 9, 9,
- 9,10,10,10,10,10,10,10, 9, 9, 9,10,10,10,10,10,
- 9, 9, 9, 9, 9, 9,10,10,10,10,10,10,10, 9, 9,10,
- 9,10, 9, 9, 9, 9, 9, 9, 9, 9,10,10,10,10,10,10,
- 10,10,10,10, 9, 9,10,10, 9, 9, 9, 9, 9, 9, 9, 9,
- 10,10,10,10,10,10,10,10,10,10,10,10,10, 9, 9, 9,
- 9, 9, 9, 9, 9,10,10,10,10,10,10,10,10,10,10,10,
- 10,10, 9, 9,10, 9, 9, 9, 9, 9,10,10,10,10,10,10,
- 10,10,10,10,10, 9, 9,10,10, 9, 9,10, 9, 9, 9,10,
- 10,10,10,10,10,10,10,10,10,10, 9, 9,10, 9, 9, 9,
- 9, 9, 9, 9,10,10,10,10,10,10,10,10,10,10,10, 9,
- 9, 9, 9,10, 9, 9, 9, 9, 9,
- };
-
- static float _vq_quantthresh__44c9_s_p8_1[] = {
- -9.5, -8.5, -7.5, -6.5, -5.5, -4.5, -3.5, -2.5,
- -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5.5,
- 6.5, 7.5, 8.5, 9.5,
- };
-
- static long _vq_quantmap__44c9_s_p8_1[] = {
- 19, 17, 15, 13, 11, 9, 7, 5,
- 3, 1, 0, 2, 4, 6, 8, 10,
- 12, 14, 16, 18, 20,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c9_s_p8_1 = {
- _vq_quantthresh__44c9_s_p8_1,
- _vq_quantmap__44c9_s_p8_1,
- 21,
- 21
- };
-
- static static_codebook _44c9_s_p8_1 = {
- 2, 441,
- _vq_lengthlist__44c9_s_p8_1,
- 1, -529268736, 1611661312, 5, 0,
- _vq_quantlist__44c9_s_p8_1,
- NULL,
- &_vq_auxt__44c9_s_p8_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c9_s_p9_0[] = {
- 9,
- 8,
- 10,
- 7,
- 11,
- 6,
- 12,
- 5,
- 13,
- 4,
- 14,
- 3,
- 15,
- 2,
- 16,
- 1,
- 17,
- 0,
- 18,
- };
-
- static long _vq_lengthlist__44c9_s_p9_0[] = {
- 1, 4, 3,12,12,12,12,12,12,12,12,12,12,12,12,12,
- 12,12,12, 4, 5, 6,12,12,12,12,12,12,12,12,12,12,
- 12,12,12,12,12,12, 4, 6, 6,12,12,12,12,12,12,12,
- 12,12,12,12,12,12,12,12,12,12,12,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,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,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,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,
- 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,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,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,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,12,12,12,12,12,12,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,
- };
-
- static float _vq_quantthresh__44c9_s_p9_0[] = {
- -7913.5, -6982.5, -6051.5, -5120.5, -4189.5, -3258.5, -2327.5, -1396.5,
- -465.5, 465.5, 1396.5, 2327.5, 3258.5, 4189.5, 5120.5, 6051.5,
- 6982.5, 7913.5,
- };
-
- static long _vq_quantmap__44c9_s_p9_0[] = {
- 17, 15, 13, 11, 9, 7, 5, 3,
- 1, 0, 2, 4, 6, 8, 10, 12,
- 14, 16, 18,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c9_s_p9_0 = {
- _vq_quantthresh__44c9_s_p9_0,
- _vq_quantmap__44c9_s_p9_0,
- 19,
- 19
- };
-
- static static_codebook _44c9_s_p9_0 = {
- 2, 361,
- _vq_lengthlist__44c9_s_p9_0,
- 1, -508535424, 1631393792, 5, 0,
- _vq_quantlist__44c9_s_p9_0,
- NULL,
- &_vq_auxt__44c9_s_p9_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c9_s_p9_1[] = {
- 9,
- 8,
- 10,
- 7,
- 11,
- 6,
- 12,
- 5,
- 13,
- 4,
- 14,
- 3,
- 15,
- 2,
- 16,
- 1,
- 17,
- 0,
- 18,
- };
-
- static long _vq_lengthlist__44c9_s_p9_1[] = {
- 1, 4, 4, 7, 7, 7, 7, 8, 7, 9, 8, 9, 9,10,10,11,
- 11,11,11, 6, 5, 5, 8, 8, 9, 9, 9, 8,10, 9,11,10,
- 12,12,13,12,13,13, 5, 5, 5, 8, 8, 9, 9, 9, 9,10,
- 10,11,11,12,12,13,12,13,13,17, 8, 8, 9, 9, 9, 9,
- 9, 9,10,10,12,11,13,12,13,13,13,13,18, 8, 8, 9,
- 9, 9, 9, 9, 9,11,11,12,12,13,13,13,13,13,13,17,
- 13,12, 9, 9,10,10,10,10,11,11,12,12,12,13,13,13,
- 14,14,18,13,12, 9, 9,10,10,10,10,11,11,12,12,13,
- 13,13,14,14,14,17,18,18,10,10,10,10,11,11,11,12,
- 12,12,14,13,14,13,13,14,18,18,18,10, 9,10, 9,11,
- 11,12,12,12,12,13,13,15,14,14,14,18,18,16,13,14,
- 10,11,11,11,12,13,13,13,13,14,13,13,14,14,18,18,
- 18,14,12,11, 9,11,10,13,12,13,13,13,14,14,14,13,
- 14,18,18,17,18,18,11,12,12,12,13,13,14,13,14,14,
- 13,14,14,14,18,18,18,18,17,12,10,12, 9,13,11,13,
- 14,14,14,14,14,15,14,18,18,17,17,18,14,15,12,13,
- 13,13,14,13,14,14,15,14,15,14,18,17,18,18,18,15,
- 15,12,10,14,10,14,14,13,13,14,14,14,14,18,16,18,
- 18,18,18,17,14,14,13,14,14,13,13,14,14,14,15,15,
- 18,18,18,18,17,17,17,14,14,14,12,14,13,14,14,15,
- 14,15,14,18,18,18,18,18,18,18,17,16,13,13,13,14,
- 14,14,14,15,16,15,18,18,18,18,18,18,18,17,17,13,
- 13,13,13,14,13,14,15,15,15,
- };
-
- static float _vq_quantthresh__44c9_s_p9_1[] = {
- -416.5, -367.5, -318.5, -269.5, -220.5, -171.5, -122.5, -73.5,
- -24.5, 24.5, 73.5, 122.5, 171.5, 220.5, 269.5, 318.5,
- 367.5, 416.5,
- };
-
- static long _vq_quantmap__44c9_s_p9_1[] = {
- 17, 15, 13, 11, 9, 7, 5, 3,
- 1, 0, 2, 4, 6, 8, 10, 12,
- 14, 16, 18,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c9_s_p9_1 = {
- _vq_quantthresh__44c9_s_p9_1,
- _vq_quantmap__44c9_s_p9_1,
- 19,
- 19
- };
-
- static static_codebook _44c9_s_p9_1 = {
- 2, 361,
- _vq_lengthlist__44c9_s_p9_1,
- 1, -518287360, 1622704128, 5, 0,
- _vq_quantlist__44c9_s_p9_1,
- NULL,
- &_vq_auxt__44c9_s_p9_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c9_s_p9_2[] = {
- 24,
- 23,
- 25,
- 22,
- 26,
- 21,
- 27,
- 20,
- 28,
- 19,
- 29,
- 18,
- 30,
- 17,
- 31,
- 16,
- 32,
- 15,
- 33,
- 14,
- 34,
- 13,
- 35,
- 12,
- 36,
- 11,
- 37,
- 10,
- 38,
- 9,
- 39,
- 8,
- 40,
- 7,
- 41,
- 6,
- 42,
- 5,
- 43,
- 4,
- 44,
- 3,
- 45,
- 2,
- 46,
- 1,
- 47,
- 0,
- 48,
- };
-
- static long _vq_lengthlist__44c9_s_p9_2[] = {
- 2, 4, 4, 5, 5, 5, 5, 5, 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, 7, 7, 7, 7, 7,
- 7,
- };
-
- static float _vq_quantthresh__44c9_s_p9_2[] = {
- -23.5, -22.5, -21.5, -20.5, -19.5, -18.5, -17.5, -16.5,
- -15.5, -14.5, -13.5, -12.5, -11.5, -10.5, -9.5, -8.5,
- -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5,
- 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5,
- 8.5, 9.5, 10.5, 11.5, 12.5, 13.5, 14.5, 15.5,
- 16.5, 17.5, 18.5, 19.5, 20.5, 21.5, 22.5, 23.5,
- };
-
- static long _vq_quantmap__44c9_s_p9_2[] = {
- 47, 45, 43, 41, 39, 37, 35, 33,
- 31, 29, 27, 25, 23, 21, 19, 17,
- 15, 13, 11, 9, 7, 5, 3, 1,
- 0, 2, 4, 6, 8, 10, 12, 14,
- 16, 18, 20, 22, 24, 26, 28, 30,
- 32, 34, 36, 38, 40, 42, 44, 46,
- 48,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c9_s_p9_2 = {
- _vq_quantthresh__44c9_s_p9_2,
- _vq_quantmap__44c9_s_p9_2,
- 49,
- 49
- };
-
- static static_codebook _44c9_s_p9_2 = {
- 1, 49,
- _vq_lengthlist__44c9_s_p9_2,
- 1, -526909440, 1611661312, 6, 0,
- _vq_quantlist__44c9_s_p9_2,
- NULL,
- &_vq_auxt__44c9_s_p9_2,
- NULL,
- 0
- };
-
- static long _huff_lengthlist__44c9_s_short[] = {
- 5,13,18,16,17,17,19,18,19,19, 5, 7,10,11,12,12,
- 13,16,17,18, 6, 6, 7, 7, 9, 9,10,14,17,19, 8, 7,
- 6, 5, 6, 7, 9,12,19,17, 8, 7, 7, 6, 5, 6, 8,11,
- 15,19, 9, 8, 7, 6, 5, 5, 6, 8,13,15,11,10, 8, 8,
- 7, 5, 4, 4,10,14,12,13,11, 9, 7, 6, 4, 2, 6,12,
- 18,16,16,13, 8, 7, 7, 5, 8,13,16,17,18,15,11, 9,
- 9, 8,10,13,
- };
-
- static static_codebook _huff_book__44c9_s_short = {
- 2, 100,
- _huff_lengthlist__44c9_s_short,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist__44c0_s_long[] = {
- 5, 4, 8, 9, 8, 9,10,12,15, 4, 1, 5, 5, 6, 8,11,
- 12,12, 8, 5, 8, 9, 9,11,13,12,12, 9, 5, 8, 5, 7,
- 9,12,13,13, 8, 6, 8, 7, 7, 9,11,11,11, 9, 7, 9,
- 7, 7, 7, 7,10,12,10,10,11, 9, 8, 7, 7, 9,11,11,
- 12,13,12,11, 9, 8, 9,11,13,16,16,15,15,12,10,11,
- 12,
- };
-
- static static_codebook _huff_book__44c0_s_long = {
- 2, 81,
- _huff_lengthlist__44c0_s_long,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c0_s_p1_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__44c0_s_p1_0[] = {
- 1, 5, 5, 0, 0, 0, 0, 0, 0, 5, 7, 7, 0, 0, 0, 0,
- 0, 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 5, 8, 7, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, 0,
- 0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0,
- 0, 0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 7, 7, 0, 0, 0, 0,
- 0, 0, 8,10, 9, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, 0,
- 0, 0, 0, 9,10,11, 0, 0, 0, 0, 0, 0, 9,11,10, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0,
- 0, 0, 0, 0, 9,11, 9, 0, 0, 0, 0, 0, 0, 9,10,11,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0,
- 0, 0, 0, 0, 8, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 9,11,10, 0,
- 0, 0, 0, 0, 0, 9, 9,11, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 7, 9,10, 0, 0, 0, 0, 0, 0, 9,10,11,
- 0, 0, 0, 0, 0, 0, 9,11,10, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,
- };
-
- static float _vq_quantthresh__44c0_s_p1_0[] = {
- -0.5, 0.5,
- };
-
- static long _vq_quantmap__44c0_s_p1_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c0_s_p1_0 = {
- _vq_quantthresh__44c0_s_p1_0,
- _vq_quantmap__44c0_s_p1_0,
- 3,
- 3
- };
-
- static static_codebook _44c0_s_p1_0 = {
- 8, 6561,
- _vq_lengthlist__44c0_s_p1_0,
- 1, -535822336, 1611661312, 2, 0,
- _vq_quantlist__44c0_s_p1_0,
- NULL,
- &_vq_auxt__44c0_s_p1_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c0_s_p2_0[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__44c0_s_p2_0[] = {
- 1, 4, 4, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 5, 5, 7, 6, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 4, 5, 6, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 7, 9, 9,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 6, 7, 7, 9, 9, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,
- };
-
- static float _vq_quantthresh__44c0_s_p2_0[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__44c0_s_p2_0[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c0_s_p2_0 = {
- _vq_quantthresh__44c0_s_p2_0,
- _vq_quantmap__44c0_s_p2_0,
- 5,
- 5
- };
-
- static static_codebook _44c0_s_p2_0 = {
- 4, 625,
- _vq_lengthlist__44c0_s_p2_0,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__44c0_s_p2_0,
- NULL,
- &_vq_auxt__44c0_s_p2_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c0_s_p3_0[] = {
- 4,
- 3,
- 5,
- 2,
- 6,
- 1,
- 7,
- 0,
- 8,
- };
-
- static long _vq_lengthlist__44c0_s_p3_0[] = {
- 1, 3, 2, 8, 7, 0, 0, 0, 0, 0, 0, 0, 6, 6, 0, 0,
- 0, 0, 0, 0, 0, 6, 6, 0, 0, 0, 0, 0, 0, 0, 7, 7,
- 0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 0, 0, 0, 0, 0,
- 8, 8, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0,
- 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,
- };
-
- static float _vq_quantthresh__44c0_s_p3_0[] = {
- -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5,
- };
-
- static long _vq_quantmap__44c0_s_p3_0[] = {
- 7, 5, 3, 1, 0, 2, 4, 6,
- 8,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c0_s_p3_0 = {
- _vq_quantthresh__44c0_s_p3_0,
- _vq_quantmap__44c0_s_p3_0,
- 9,
- 9
- };
-
- static static_codebook _44c0_s_p3_0 = {
- 2, 81,
- _vq_lengthlist__44c0_s_p3_0,
- 1, -531628032, 1611661312, 4, 0,
- _vq_quantlist__44c0_s_p3_0,
- NULL,
- &_vq_auxt__44c0_s_p3_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c0_s_p4_0[] = {
- 4,
- 3,
- 5,
- 2,
- 6,
- 1,
- 7,
- 0,
- 8,
- };
-
- static long _vq_lengthlist__44c0_s_p4_0[] = {
- 1, 3, 3, 6, 6, 6, 6, 8, 8, 0, 0, 0, 7, 7, 7, 7,
- 9, 9, 0, 0, 0, 7, 7, 7, 7, 9, 9, 0, 0, 0, 7, 7,
- 7, 8, 9, 9, 0, 0, 0, 7, 7, 7, 7, 9, 9, 0, 0, 0,
- 9, 9, 8, 8,10,10, 0, 0, 0, 8, 9, 8, 8,10,10, 0,
- 0, 0,10,10, 9, 9,10,10, 0, 0, 0, 0, 0, 9, 9,10,
- 10,
- };
-
- static float _vq_quantthresh__44c0_s_p4_0[] = {
- -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5,
- };
-
- static long _vq_quantmap__44c0_s_p4_0[] = {
- 7, 5, 3, 1, 0, 2, 4, 6,
- 8,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c0_s_p4_0 = {
- _vq_quantthresh__44c0_s_p4_0,
- _vq_quantmap__44c0_s_p4_0,
- 9,
- 9
- };
-
- static static_codebook _44c0_s_p4_0 = {
- 2, 81,
- _vq_lengthlist__44c0_s_p4_0,
- 1, -531628032, 1611661312, 4, 0,
- _vq_quantlist__44c0_s_p4_0,
- NULL,
- &_vq_auxt__44c0_s_p4_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c0_s_p5_0[] = {
- 8,
- 7,
- 9,
- 6,
- 10,
- 5,
- 11,
- 4,
- 12,
- 3,
- 13,
- 2,
- 14,
- 1,
- 15,
- 0,
- 16,
- };
-
- static long _vq_lengthlist__44c0_s_p5_0[] = {
- 1, 4, 3, 6, 6, 8, 7, 8, 8, 8, 8, 9, 9,10,10,11,
- 11, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9, 9,10,10,10,
- 11,11, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10,10,10,
- 10,11,11, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10,10,
- 11,11,11,11, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10,
- 10,11,11,11,11, 0, 0, 0, 8, 8, 9, 9, 9, 9,10,10,
- 10,10,11,11,12,12, 0, 0, 0, 8, 8, 9, 9, 9, 9,10,
- 10,10,10,11,11,12,12, 0, 0, 0, 9, 9, 9, 9,10,10,
- 10,10,11,11,11,12,12,12, 0, 0, 0, 0, 0, 9, 9,10,
- 10,10,10,11,11,11,11,12,12, 0, 0, 0, 0, 0, 9, 9,
- 10,10,10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, 9,
- 9,10,10,10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0,
- 10,10,11,11,11,11,11,12,12,12,13,13, 0, 0, 0, 0,
- 0, 0, 0,11,10,11,11,11,11,12,12,13,13, 0, 0, 0,
- 0, 0, 0, 0,11,11,12,11,12,12,12,12,13,13, 0, 0,
- 0, 0, 0, 0, 0,11,11,11,12,12,12,12,13,13,13, 0,
- 0, 0, 0, 0, 0, 0,12,12,12,12,12,13,13,13,14,14,
- 0, 0, 0, 0, 0, 0, 0, 0, 0,12,12,12,12,13,13,14,
- 14,
- };
-
- static float _vq_quantthresh__44c0_s_p5_0[] = {
- -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5,
- 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5,
- };
-
- static long _vq_quantmap__44c0_s_p5_0[] = {
- 15, 13, 11, 9, 7, 5, 3, 1,
- 0, 2, 4, 6, 8, 10, 12, 14,
- 16,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c0_s_p5_0 = {
- _vq_quantthresh__44c0_s_p5_0,
- _vq_quantmap__44c0_s_p5_0,
- 17,
- 17
- };
-
- static static_codebook _44c0_s_p5_0 = {
- 2, 289,
- _vq_lengthlist__44c0_s_p5_0,
- 1, -529530880, 1611661312, 5, 0,
- _vq_quantlist__44c0_s_p5_0,
- NULL,
- &_vq_auxt__44c0_s_p5_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c0_s_p6_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__44c0_s_p6_0[] = {
- 1, 4, 4, 7, 6, 6, 7, 6, 6, 4, 7, 7,10, 9, 9,10,
- 9, 9, 4, 6, 7,10, 9, 9,11, 9, 9, 7,10,10,11,11,
- 11,12,10,11, 6, 9, 9,11,10,11,11,10,10, 6, 9, 9,
- 11,10,11,11,10,10, 7,11,10,12,11,11,11,11,11, 7,
- 9, 9,10,10,10,11,11,10, 6, 9, 9,11,10,10,11,10,
- 10,
- };
-
- static float _vq_quantthresh__44c0_s_p6_0[] = {
- -5.5, 5.5,
- };
-
- static long _vq_quantmap__44c0_s_p6_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c0_s_p6_0 = {
- _vq_quantthresh__44c0_s_p6_0,
- _vq_quantmap__44c0_s_p6_0,
- 3,
- 3
- };
-
- static static_codebook _44c0_s_p6_0 = {
- 4, 81,
- _vq_lengthlist__44c0_s_p6_0,
- 1, -529137664, 1618345984, 2, 0,
- _vq_quantlist__44c0_s_p6_0,
- NULL,
- &_vq_auxt__44c0_s_p6_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c0_s_p6_1[] = {
- 5,
- 4,
- 6,
- 3,
- 7,
- 2,
- 8,
- 1,
- 9,
- 0,
- 10,
- };
-
- static long _vq_lengthlist__44c0_s_p6_1[] = {
- 2, 3, 3, 6, 6, 7, 7, 7, 7, 7, 8,10,10,10, 6, 6,
- 7, 7, 8, 8, 8, 8,10,10,10, 6, 6, 7, 7, 8, 8, 8,
- 8,10,10,10, 7, 7, 7, 7, 8, 8, 8, 8,10,10,10, 7,
- 7, 7, 7, 8, 8, 8, 8,10,10,10, 8, 7, 8, 8, 8, 8,
- 8, 8,10,10,10, 7, 7, 8, 8, 8, 8, 8, 8,10,10,10,
- 8, 8, 8, 8, 8, 8, 8, 8,10,10,10,10,10, 8, 8, 8,
- 8, 8, 8,10,10,10,10,10, 9, 9, 8, 8, 8, 8,10,10,
- 10,10,10, 8, 8, 8, 8, 8, 8,
- };
-
- static float _vq_quantthresh__44c0_s_p6_1[] = {
- -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5,
- 3.5, 4.5,
- };
-
- static long _vq_quantmap__44c0_s_p6_1[] = {
- 9, 7, 5, 3, 1, 0, 2, 4,
- 6, 8, 10,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c0_s_p6_1 = {
- _vq_quantthresh__44c0_s_p6_1,
- _vq_quantmap__44c0_s_p6_1,
- 11,
- 11
- };
-
- static static_codebook _44c0_s_p6_1 = {
- 2, 121,
- _vq_lengthlist__44c0_s_p6_1,
- 1, -531365888, 1611661312, 4, 0,
- _vq_quantlist__44c0_s_p6_1,
- NULL,
- &_vq_auxt__44c0_s_p6_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c0_s_p7_0[] = {
- 6,
- 5,
- 7,
- 4,
- 8,
- 3,
- 9,
- 2,
- 10,
- 1,
- 11,
- 0,
- 12,
- };
-
- static long _vq_lengthlist__44c0_s_p7_0[] = {
- 1, 4, 4, 6, 6, 7, 7, 7, 7, 8, 8, 9, 9, 7, 5, 5,
- 7, 7, 8, 8, 8, 8, 9, 9,10,10, 7, 5, 6, 7, 7, 8,
- 8, 8, 8, 9, 9,10,10, 0, 8, 8, 8, 8, 9, 9, 9, 9,
- 10,10,11,11, 0, 8, 8, 8, 8, 9, 9, 9, 9,10,10,11,
- 11, 0,12,12, 9, 9,10,10,10,10,11,11,11,11, 0,13,
- 13, 9, 9, 9, 9,10,10,11,11,11,12, 0, 0, 0,10,10,
- 10,10,11,11,11,11,12,12, 0, 0, 0,10,10, 9, 9,11,
- 11,11,12,12,12, 0, 0, 0,13,13,10,10,11,11,12,12,
- 13,13, 0, 0, 0,14,14,10,10,11,11,12,12,13,13, 0,
- 0, 0, 0, 0,11,11,11,11,13,12,13,13, 0, 0, 0, 0,
- 0,12,12,11,11,12,12,13,13,
- };
-
- static float _vq_quantthresh__44c0_s_p7_0[] = {
- -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5,
- 12.5, 17.5, 22.5, 27.5,
- };
-
- static long _vq_quantmap__44c0_s_p7_0[] = {
- 11, 9, 7, 5, 3, 1, 0, 2,
- 4, 6, 8, 10, 12,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c0_s_p7_0 = {
- _vq_quantthresh__44c0_s_p7_0,
- _vq_quantmap__44c0_s_p7_0,
- 13,
- 13
- };
-
- static static_codebook _44c0_s_p7_0 = {
- 2, 169,
- _vq_lengthlist__44c0_s_p7_0,
- 1, -526516224, 1616117760, 4, 0,
- _vq_quantlist__44c0_s_p7_0,
- NULL,
- &_vq_auxt__44c0_s_p7_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c0_s_p7_1[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__44c0_s_p7_1[] = {
- 2, 3, 3, 5, 5, 6, 6, 6, 5, 5, 6, 6, 6, 5, 5, 6,
- 6, 6, 5, 5, 6, 6, 6, 5, 5,
- };
-
- static float _vq_quantthresh__44c0_s_p7_1[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__44c0_s_p7_1[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c0_s_p7_1 = {
- _vq_quantthresh__44c0_s_p7_1,
- _vq_quantmap__44c0_s_p7_1,
- 5,
- 5
- };
-
- static static_codebook _44c0_s_p7_1 = {
- 2, 25,
- _vq_lengthlist__44c0_s_p7_1,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__44c0_s_p7_1,
- NULL,
- &_vq_auxt__44c0_s_p7_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c0_s_p8_0[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__44c0_s_p8_0[] = {
- 1, 5, 5,10,10, 6, 9, 8,10,10, 6,10, 9,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10, 8,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,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,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,10,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,
- };
-
- static float _vq_quantthresh__44c0_s_p8_0[] = {
- -331.5, -110.5, 110.5, 331.5,
- };
-
- static long _vq_quantmap__44c0_s_p8_0[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c0_s_p8_0 = {
- _vq_quantthresh__44c0_s_p8_0,
- _vq_quantmap__44c0_s_p8_0,
- 5,
- 5
- };
-
- static static_codebook _44c0_s_p8_0 = {
- 4, 625,
- _vq_lengthlist__44c0_s_p8_0,
- 1, -518283264, 1627103232, 3, 0,
- _vq_quantlist__44c0_s_p8_0,
- NULL,
- &_vq_auxt__44c0_s_p8_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c0_s_p8_1[] = {
- 6,
- 5,
- 7,
- 4,
- 8,
- 3,
- 9,
- 2,
- 10,
- 1,
- 11,
- 0,
- 12,
- };
-
- static long _vq_lengthlist__44c0_s_p8_1[] = {
- 1, 4, 4, 6, 6, 7, 7, 9, 9,11,12,13,12, 6, 5, 5,
- 7, 7, 8, 8,10, 9,12,12,12,12, 6, 5, 5, 7, 7, 8,
- 8,10, 9,12,11,11,13,16, 7, 7, 8, 8, 9, 9,10,10,
- 12,12,13,12,16, 7, 7, 8, 7, 9, 9,10,10,11,12,12,
- 13,16,10,10, 8, 8,10,10,11,12,12,12,13,13,16,11,
- 10, 8, 7,11,10,11,11,12,11,13,13,16,16,16,10,10,
- 10,10,11,11,13,12,13,13,16,16,16,11, 9,11, 9,15,
- 13,12,13,13,13,16,16,16,15,13,11,11,12,13,12,12,
- 14,13,16,16,16,14,13,11,11,13,12,14,13,13,13,16,
- 16,16,16,16,13,13,13,12,14,13,14,14,16,16,16,16,
- 16,13,13,12,12,14,14,15,13,
- };
-
- static float _vq_quantthresh__44c0_s_p8_1[] = {
- -93.5, -76.5, -59.5, -42.5, -25.5, -8.5, 8.5, 25.5,
- 42.5, 59.5, 76.5, 93.5,
- };
-
- static long _vq_quantmap__44c0_s_p8_1[] = {
- 11, 9, 7, 5, 3, 1, 0, 2,
- 4, 6, 8, 10, 12,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c0_s_p8_1 = {
- _vq_quantthresh__44c0_s_p8_1,
- _vq_quantmap__44c0_s_p8_1,
- 13,
- 13
- };
-
- static static_codebook _44c0_s_p8_1 = {
- 2, 169,
- _vq_lengthlist__44c0_s_p8_1,
- 1, -522616832, 1620115456, 4, 0,
- _vq_quantlist__44c0_s_p8_1,
- NULL,
- &_vq_auxt__44c0_s_p8_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c0_s_p8_2[] = {
- 8,
- 7,
- 9,
- 6,
- 10,
- 5,
- 11,
- 4,
- 12,
- 3,
- 13,
- 2,
- 14,
- 1,
- 15,
- 0,
- 16,
- };
-
- static long _vq_lengthlist__44c0_s_p8_2[] = {
- 2, 4, 4, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8,
- 8,10,10,10, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9, 9,
- 9, 9,10,10,10, 7, 7, 7, 7, 8, 8, 9, 9, 9, 9, 9,
- 9, 9, 9,10,10,10, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9,
- 9,10, 9, 9,10,10,10, 7, 7, 8, 8, 9, 8, 9, 9, 9,
- 9,10, 9, 9,10,10,10,10, 8, 8, 8, 8, 9, 8, 9, 9,
- 9, 9, 9,10, 9,10,10,10,10, 7, 7, 8, 8, 9, 9, 9,
- 9, 9, 9,10, 9,10,10,10,10,10, 8, 8, 8, 9, 9, 9,
- 9, 9, 9, 9,10,10,10, 9,11,10,10,10,10, 8, 8, 9,
- 9, 9, 9, 9,10, 9, 9, 9,10,10,10,10,11,11, 9, 9,
- 9, 9, 9, 9, 9, 9,10, 9, 9,10,11,10,10,11,11, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9,10, 9,11,11,10,11,11,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10, 9,11,10,10,11,
- 11,11,11, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10,10,10,
- 11,11,11,11, 9,10, 9,10, 9, 9, 9, 9,10, 9,10,11,
- 10,11,10,10,10,10,10, 9, 9, 9,10, 9, 9, 9,10,11,
- 11,10,11,11,10,11,10,10,10, 9, 9, 9, 9,10, 9, 9,
- 10,11,10,11,11,11,11,10,11,10,10, 9,10, 9, 9, 9,
- 10,
- };
-
- static float _vq_quantthresh__44c0_s_p8_2[] = {
- -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5,
- 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5,
- };
-
- static long _vq_quantmap__44c0_s_p8_2[] = {
- 15, 13, 11, 9, 7, 5, 3, 1,
- 0, 2, 4, 6, 8, 10, 12, 14,
- 16,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c0_s_p8_2 = {
- _vq_quantthresh__44c0_s_p8_2,
- _vq_quantmap__44c0_s_p8_2,
- 17,
- 17
- };
-
- static static_codebook _44c0_s_p8_2 = {
- 2, 289,
- _vq_lengthlist__44c0_s_p8_2,
- 1, -529530880, 1611661312, 5, 0,
- _vq_quantlist__44c0_s_p8_2,
- NULL,
- &_vq_auxt__44c0_s_p8_2,
- NULL,
- 0
- };
-
- static long _huff_lengthlist__44c0_s_short[] = {
- 9, 8,12,11,12,13,14,14,16, 6, 1, 5, 6, 6, 9,12,
- 14,17, 9, 4, 5, 9, 7, 9,13,15,16, 8, 5, 8, 6, 8,
- 10,13,17,17, 9, 6, 7, 7, 8, 9,13,15,17,11, 8, 9,
- 9, 9,10,12,16,16,13, 7, 8, 7, 7, 9,12,14,15,13,
- 6, 7, 5, 5, 7,10,13,13,14, 7, 8, 5, 6, 7, 9,10,
- 12,
- };
-
- static static_codebook _huff_book__44c0_s_short = {
- 2, 81,
- _huff_lengthlist__44c0_s_short,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist__44c0_sm_long[] = {
- 5, 4, 9,10, 9,10,11,12,13, 4, 1, 5, 7, 7, 9,11,
- 12,14, 8, 5, 7, 9, 8,10,13,13,13,10, 7, 9, 4, 6,
- 7,10,12,14, 9, 6, 7, 6, 6, 7,10,12,12, 9, 8, 9,
- 7, 6, 7, 8,11,12,11,11,11, 9, 8, 7, 8,10,12,12,
- 13,14,12,11, 9, 9, 9,12,12,17,17,15,16,12,10,11,
- 13,
- };
-
- static static_codebook _huff_book__44c0_sm_long = {
- 2, 81,
- _huff_lengthlist__44c0_sm_long,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c0_sm_p1_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__44c0_sm_p1_0[] = {
- 1, 5, 5, 0, 0, 0, 0, 0, 0, 5, 7, 7, 0, 0, 0, 0,
- 0, 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 5, 8, 7, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, 0,
- 0, 0, 0, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 7, 9, 8, 0, 0,
- 0, 0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 8, 7, 0, 0, 0, 0,
- 0, 0, 8, 9, 9, 0, 0, 0, 0, 0, 0, 8, 9, 9, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, 0,
- 0, 0, 0, 9,10,10, 0, 0, 0, 0, 0, 0, 9,10,10, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0,
- 0, 0, 0, 0, 8,10, 9, 0, 0, 0, 0, 0, 0, 9,10,10,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 5, 7, 8, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0,
- 0, 0, 0, 0, 8, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 9,10,10, 0,
- 0, 0, 0, 0, 0, 9, 9,10, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 9,10,10,
- 0, 0, 0, 0, 0, 0, 9,10,10, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,
- };
-
- static float _vq_quantthresh__44c0_sm_p1_0[] = {
- -0.5, 0.5,
- };
-
- static long _vq_quantmap__44c0_sm_p1_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c0_sm_p1_0 = {
- _vq_quantthresh__44c0_sm_p1_0,
- _vq_quantmap__44c0_sm_p1_0,
- 3,
- 3
- };
-
- static static_codebook _44c0_sm_p1_0 = {
- 8, 6561,
- _vq_lengthlist__44c0_sm_p1_0,
- 1, -535822336, 1611661312, 2, 0,
- _vq_quantlist__44c0_sm_p1_0,
- NULL,
- &_vq_auxt__44c0_sm_p1_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c0_sm_p2_0[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__44c0_sm_p2_0[] = {
- 1, 4, 4, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 5, 5, 7, 7, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 4, 5, 5, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 7, 9, 9,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 7, 7, 7, 9, 9, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,
- };
-
- static float _vq_quantthresh__44c0_sm_p2_0[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__44c0_sm_p2_0[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c0_sm_p2_0 = {
- _vq_quantthresh__44c0_sm_p2_0,
- _vq_quantmap__44c0_sm_p2_0,
- 5,
- 5
- };
-
- static static_codebook _44c0_sm_p2_0 = {
- 4, 625,
- _vq_lengthlist__44c0_sm_p2_0,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__44c0_sm_p2_0,
- NULL,
- &_vq_auxt__44c0_sm_p2_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c0_sm_p3_0[] = {
- 4,
- 3,
- 5,
- 2,
- 6,
- 1,
- 7,
- 0,
- 8,
- };
-
- static long _vq_lengthlist__44c0_sm_p3_0[] = {
- 1, 3, 3, 7, 7, 0, 0, 0, 0, 0, 5, 4, 7, 7, 0, 0,
- 0, 0, 0, 5, 5, 7, 7, 0, 0, 0, 0, 0, 6, 7, 8, 8,
- 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0,
- 9,10, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0,
- 0, 0,11,11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,
- };
-
- static float _vq_quantthresh__44c0_sm_p3_0[] = {
- -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5,
- };
-
- static long _vq_quantmap__44c0_sm_p3_0[] = {
- 7, 5, 3, 1, 0, 2, 4, 6,
- 8,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c0_sm_p3_0 = {
- _vq_quantthresh__44c0_sm_p3_0,
- _vq_quantmap__44c0_sm_p3_0,
- 9,
- 9
- };
-
- static static_codebook _44c0_sm_p3_0 = {
- 2, 81,
- _vq_lengthlist__44c0_sm_p3_0,
- 1, -531628032, 1611661312, 4, 0,
- _vq_quantlist__44c0_sm_p3_0,
- NULL,
- &_vq_auxt__44c0_sm_p3_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c0_sm_p4_0[] = {
- 4,
- 3,
- 5,
- 2,
- 6,
- 1,
- 7,
- 0,
- 8,
- };
-
- static long _vq_lengthlist__44c0_sm_p4_0[] = {
- 1, 4, 3, 6, 6, 7, 7, 9, 9, 0, 5, 5, 7, 7, 8, 7,
- 9, 9, 0, 5, 5, 7, 7, 8, 8, 9, 9, 0, 7, 7, 8, 8,
- 8, 8,10,10, 0, 0, 0, 8, 8, 8, 8,10,10, 0, 0, 0,
- 9, 9, 9, 9,11,11, 0, 0, 0, 9, 9, 9, 9,11,11, 0,
- 0, 0,10,10,10,10,11,11, 0, 0, 0, 0, 0, 9, 9,11,
- 11,
- };
-
- static float _vq_quantthresh__44c0_sm_p4_0[] = {
- -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5,
- };
-
- static long _vq_quantmap__44c0_sm_p4_0[] = {
- 7, 5, 3, 1, 0, 2, 4, 6,
- 8,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c0_sm_p4_0 = {
- _vq_quantthresh__44c0_sm_p4_0,
- _vq_quantmap__44c0_sm_p4_0,
- 9,
- 9
- };
-
- static static_codebook _44c0_sm_p4_0 = {
- 2, 81,
- _vq_lengthlist__44c0_sm_p4_0,
- 1, -531628032, 1611661312, 4, 0,
- _vq_quantlist__44c0_sm_p4_0,
- NULL,
- &_vq_auxt__44c0_sm_p4_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c0_sm_p5_0[] = {
- 8,
- 7,
- 9,
- 6,
- 10,
- 5,
- 11,
- 4,
- 12,
- 3,
- 13,
- 2,
- 14,
- 1,
- 15,
- 0,
- 16,
- };
-
- static long _vq_lengthlist__44c0_sm_p5_0[] = {
- 1, 4, 4, 6, 6, 8, 8, 8, 8, 8, 8, 9, 9,10,10,11,
- 11, 0, 6, 6, 7, 7, 8, 8, 9, 9, 9, 9,10,10,10,11,
- 11,11, 0, 5, 6, 7, 7, 8, 8, 9, 9, 9, 9,10,10,10,
- 11,11,11, 0, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9,10,10,
- 11,11,12,12, 0, 0, 0, 8, 8, 8, 8, 9, 9, 9, 9,10,
- 10,11,11,12,12, 0, 0, 0, 8, 8, 9, 9,10,10,10,10,
- 11,11,11,11,12,12, 0, 0, 0, 8, 8, 9, 9,10,10,10,
- 10,11,11,11,11,12,12, 0, 0, 0, 9, 9, 9, 9,10,10,
- 10,10,11,11,12,12,12,13, 0, 0, 0, 0, 0, 9, 9,10,
- 10,10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, 9, 9,
- 10,10,11,11,11,11,12,12,13,13, 0, 0, 0, 0, 0, 9,
- 9,10,10,11,10,11,11,12,12,13,13, 0, 0, 0, 0, 0,
- 10,10,10,10,11,11,12,12,12,13,13,13, 0, 0, 0, 0,
- 0, 0, 0,10,10,11,11,12,12,12,13,13,13, 0, 0, 0,
- 0, 0, 0, 0,11,11,12,12,12,12,13,13,14,14, 0, 0,
- 0, 0, 0, 0, 0,11,11,12,11,12,12,13,13,13,13, 0,
- 0, 0, 0, 0, 0, 0,12,12,12,12,13,13,13,13,14,14,
- 0, 0, 0, 0, 0, 0, 0, 0, 0,12,12,12,12,13,13,14,
- 14,
- };
-
- static float _vq_quantthresh__44c0_sm_p5_0[] = {
- -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5,
- 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5,
- };
-
- static long _vq_quantmap__44c0_sm_p5_0[] = {
- 15, 13, 11, 9, 7, 5, 3, 1,
- 0, 2, 4, 6, 8, 10, 12, 14,
- 16,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c0_sm_p5_0 = {
- _vq_quantthresh__44c0_sm_p5_0,
- _vq_quantmap__44c0_sm_p5_0,
- 17,
- 17
- };
-
- static static_codebook _44c0_sm_p5_0 = {
- 2, 289,
- _vq_lengthlist__44c0_sm_p5_0,
- 1, -529530880, 1611661312, 5, 0,
- _vq_quantlist__44c0_sm_p5_0,
- NULL,
- &_vq_auxt__44c0_sm_p5_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c0_sm_p6_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__44c0_sm_p6_0[] = {
- 1, 4, 4, 7, 6, 6, 7, 6, 6, 4, 7, 7,10, 9, 9,11,
- 9, 9, 4, 7, 7,10, 9, 9,11, 9, 9, 7,10,10,10,11,
- 11,11,10,10, 6, 9, 9,11,11,10,11,10,10, 6, 9, 9,
- 11,10,11,11,10,10, 7,11,10,11,11,11,11,11,11, 6,
- 9, 9,11,10,10,11,11,10, 6, 9, 9,11,10,10,11,10,
- 11,
- };
-
- static float _vq_quantthresh__44c0_sm_p6_0[] = {
- -5.5, 5.5,
- };
-
- static long _vq_quantmap__44c0_sm_p6_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c0_sm_p6_0 = {
- _vq_quantthresh__44c0_sm_p6_0,
- _vq_quantmap__44c0_sm_p6_0,
- 3,
- 3
- };
-
- static static_codebook _44c0_sm_p6_0 = {
- 4, 81,
- _vq_lengthlist__44c0_sm_p6_0,
- 1, -529137664, 1618345984, 2, 0,
- _vq_quantlist__44c0_sm_p6_0,
- NULL,
- &_vq_auxt__44c0_sm_p6_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c0_sm_p6_1[] = {
- 5,
- 4,
- 6,
- 3,
- 7,
- 2,
- 8,
- 1,
- 9,
- 0,
- 10,
- };
-
- static long _vq_lengthlist__44c0_sm_p6_1[] = {
- 2, 4, 4, 6, 6, 7, 7, 7, 7, 7, 8, 9, 5, 5, 6, 6,
- 7, 7, 8, 8, 8, 8, 9, 5, 5, 6, 6, 7, 7, 8, 8, 8,
- 8,10, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8,10,10,10, 7,
- 7, 7, 7, 8, 8, 8, 8,10,10,10, 8, 8, 8, 8, 8, 8,
- 8, 8,10,10,10, 8, 8, 8, 8, 8, 8, 8, 8,10,10,10,
- 8, 8, 8, 8, 8, 8, 8, 8,10,10,10,10,10, 8, 8, 8,
- 8, 8, 8,10,10,10,10,10, 9, 9, 8, 8, 8, 8,10,10,
- 10,10,10, 8, 8, 8, 8, 8, 8,
- };
-
- static float _vq_quantthresh__44c0_sm_p6_1[] = {
- -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5,
- 3.5, 4.5,
- };
-
- static long _vq_quantmap__44c0_sm_p6_1[] = {
- 9, 7, 5, 3, 1, 0, 2, 4,
- 6, 8, 10,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c0_sm_p6_1 = {
- _vq_quantthresh__44c0_sm_p6_1,
- _vq_quantmap__44c0_sm_p6_1,
- 11,
- 11
- };
-
- static static_codebook _44c0_sm_p6_1 = {
- 2, 121,
- _vq_lengthlist__44c0_sm_p6_1,
- 1, -531365888, 1611661312, 4, 0,
- _vq_quantlist__44c0_sm_p6_1,
- NULL,
- &_vq_auxt__44c0_sm_p6_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c0_sm_p7_0[] = {
- 6,
- 5,
- 7,
- 4,
- 8,
- 3,
- 9,
- 2,
- 10,
- 1,
- 11,
- 0,
- 12,
- };
-
- static long _vq_lengthlist__44c0_sm_p7_0[] = {
- 1, 4, 4, 6, 6, 7, 7, 7, 7, 8, 8, 9, 9, 7, 5, 5,
- 7, 7, 8, 8, 8, 8, 9, 9,10,10, 7, 6, 5, 7, 7, 8,
- 8, 8, 8, 9, 9,10,10, 0, 8, 8, 8, 8, 9, 9, 9, 9,
- 10,10,11,11, 0, 8, 8, 8, 8, 9, 9, 9, 9,10,10,11,
- 11, 0,12,12, 9, 9,10,10,10,10,11,11,11,11, 0,13,
- 13, 9, 9, 9, 9,10,10,11,11,11,12, 0, 0, 0, 9,10,
- 10,10,11,11,12,11,12,12, 0, 0, 0,10,10, 9, 9,11,
- 11,12,12,12,12, 0, 0, 0,13,13,10,10,11,11,12,12,
- 13,13, 0, 0, 0,14,14,10,10,11,11,12,12,13,13, 0,
- 0, 0, 0, 0,11,12,11,11,13,12,13,13, 0, 0, 0, 0,
- 0,12,12,11,11,13,12,14,14,
- };
-
- static float _vq_quantthresh__44c0_sm_p7_0[] = {
- -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5,
- 12.5, 17.5, 22.5, 27.5,
- };
-
- static long _vq_quantmap__44c0_sm_p7_0[] = {
- 11, 9, 7, 5, 3, 1, 0, 2,
- 4, 6, 8, 10, 12,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c0_sm_p7_0 = {
- _vq_quantthresh__44c0_sm_p7_0,
- _vq_quantmap__44c0_sm_p7_0,
- 13,
- 13
- };
-
- static static_codebook _44c0_sm_p7_0 = {
- 2, 169,
- _vq_lengthlist__44c0_sm_p7_0,
- 1, -526516224, 1616117760, 4, 0,
- _vq_quantlist__44c0_sm_p7_0,
- NULL,
- &_vq_auxt__44c0_sm_p7_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c0_sm_p7_1[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__44c0_sm_p7_1[] = {
- 2, 4, 4, 4, 4, 6, 5, 5, 5, 5, 6, 5, 5, 5, 5, 6,
- 6, 6, 5, 5, 6, 6, 6, 5, 5,
- };
-
- static float _vq_quantthresh__44c0_sm_p7_1[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__44c0_sm_p7_1[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c0_sm_p7_1 = {
- _vq_quantthresh__44c0_sm_p7_1,
- _vq_quantmap__44c0_sm_p7_1,
- 5,
- 5
- };
-
- static static_codebook _44c0_sm_p7_1 = {
- 2, 25,
- _vq_lengthlist__44c0_sm_p7_1,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__44c0_sm_p7_1,
- NULL,
- &_vq_auxt__44c0_sm_p7_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c0_sm_p8_0[] = {
- 4,
- 3,
- 5,
- 2,
- 6,
- 1,
- 7,
- 0,
- 8,
- };
-
- static long _vq_lengthlist__44c0_sm_p8_0[] = {
- 1, 3, 3,11,11,11,11,11,11, 3, 7, 6,11,11,11,11,
- 11,11, 4, 8, 7,11,11,11,11,11,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,12,12,12,12,12,12,
- 12,
- };
-
- static float _vq_quantthresh__44c0_sm_p8_0[] = {
- -773.5, -552.5, -331.5, -110.5, 110.5, 331.5, 552.5, 773.5,
- };
-
- static long _vq_quantmap__44c0_sm_p8_0[] = {
- 7, 5, 3, 1, 0, 2, 4, 6,
- 8,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c0_sm_p8_0 = {
- _vq_quantthresh__44c0_sm_p8_0,
- _vq_quantmap__44c0_sm_p8_0,
- 9,
- 9
- };
-
- static static_codebook _44c0_sm_p8_0 = {
- 2, 81,
- _vq_lengthlist__44c0_sm_p8_0,
- 1, -516186112, 1627103232, 4, 0,
- _vq_quantlist__44c0_sm_p8_0,
- NULL,
- &_vq_auxt__44c0_sm_p8_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c0_sm_p8_1[] = {
- 6,
- 5,
- 7,
- 4,
- 8,
- 3,
- 9,
- 2,
- 10,
- 1,
- 11,
- 0,
- 12,
- };
-
- static long _vq_lengthlist__44c0_sm_p8_1[] = {
- 1, 4, 4, 6, 6, 7, 7, 9, 9,10,11,12,12, 6, 5, 5,
- 7, 7, 8, 8,10,10,12,11,12,12, 6, 5, 5, 7, 7, 8,
- 8,10,10,12,11,12,12,17, 7, 7, 8, 8, 9, 9,10,10,
- 12,12,13,13,18, 7, 7, 8, 7, 9, 9,10,10,12,12,12,
- 13,19,10,10, 8, 8,10,10,11,11,12,12,13,14,19,11,
- 10, 8, 7,10,10,11,11,12,12,13,12,19,19,19,10,10,
- 10,10,11,11,12,12,13,13,19,19,19,11, 9,11, 9,14,
- 12,13,12,13,13,19,20,18,13,14,11,11,12,12,13,13,
- 14,13,20,20,20,15,13,11,10,13,11,13,13,14,13,20,
- 20,20,20,20,13,14,12,12,13,13,13,13,20,20,20,20,
- 20,13,13,12,12,16,13,15,13,
- };
-
- static float _vq_quantthresh__44c0_sm_p8_1[] = {
- -93.5, -76.5, -59.5, -42.5, -25.5, -8.5, 8.5, 25.5,
- 42.5, 59.5, 76.5, 93.5,
- };
-
- static long _vq_quantmap__44c0_sm_p8_1[] = {
- 11, 9, 7, 5, 3, 1, 0, 2,
- 4, 6, 8, 10, 12,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c0_sm_p8_1 = {
- _vq_quantthresh__44c0_sm_p8_1,
- _vq_quantmap__44c0_sm_p8_1,
- 13,
- 13
- };
-
- static static_codebook _44c0_sm_p8_1 = {
- 2, 169,
- _vq_lengthlist__44c0_sm_p8_1,
- 1, -522616832, 1620115456, 4, 0,
- _vq_quantlist__44c0_sm_p8_1,
- NULL,
- &_vq_auxt__44c0_sm_p8_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c0_sm_p8_2[] = {
- 8,
- 7,
- 9,
- 6,
- 10,
- 5,
- 11,
- 4,
- 12,
- 3,
- 13,
- 2,
- 14,
- 1,
- 15,
- 0,
- 16,
- };
-
- static long _vq_lengthlist__44c0_sm_p8_2[] = {
- 2, 5, 5, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8,
- 8,10, 6, 6, 7, 7, 7, 7, 8, 8, 9, 9, 9, 9, 9, 9,
- 9, 9,10, 6, 6, 7, 7, 8, 7, 8, 8, 9, 9, 9, 9, 9,
- 9, 9, 9,10, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9,
- 9, 9, 9, 9,10,10,10, 7, 7, 8, 8, 9, 8, 9, 9, 9,
- 9,10, 9, 9,10,10,10,11, 8, 8, 8, 8, 9, 9, 9, 9,
- 9, 9, 9,10, 9,10,10,10,10, 8, 8, 8, 8, 9, 9, 9,
- 9, 9, 9, 9, 9,10,10,11,10,10, 8, 8, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9,10,10,10,10,10,11,11, 8, 8, 9,
- 9, 9, 9, 9, 9, 9, 9, 9,10,11,11,11,11,11, 9, 9,
- 9, 9, 9, 9, 9, 9,10, 9,10, 9,11,11,10,11,11, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9,10, 9,11,11,10,11,11,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10, 9,11,10,11,11,
- 11,11,11, 9, 9,10, 9, 9, 9, 9, 9, 9, 9,10,11,10,
- 11,11,11,11,10,10,10,10, 9, 9, 9, 9, 9, 9,10,11,
- 11,11,11,11,11, 9,10, 9, 9, 9, 9, 9, 9, 9, 9,11,
- 11,10,11,11,11,10,10,10, 9, 9, 9, 9, 9, 9, 9, 9,
- 10,11,10,11,11,11,11,11,11, 9, 9, 9, 9, 9, 9, 9,
- 9,
- };
-
- static float _vq_quantthresh__44c0_sm_p8_2[] = {
- -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5,
- 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5,
- };
-
- static long _vq_quantmap__44c0_sm_p8_2[] = {
- 15, 13, 11, 9, 7, 5, 3, 1,
- 0, 2, 4, 6, 8, 10, 12, 14,
- 16,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c0_sm_p8_2 = {
- _vq_quantthresh__44c0_sm_p8_2,
- _vq_quantmap__44c0_sm_p8_2,
- 17,
- 17
- };
-
- static static_codebook _44c0_sm_p8_2 = {
- 2, 289,
- _vq_lengthlist__44c0_sm_p8_2,
- 1, -529530880, 1611661312, 5, 0,
- _vq_quantlist__44c0_sm_p8_2,
- NULL,
- &_vq_auxt__44c0_sm_p8_2,
- NULL,
- 0
- };
-
- static long _huff_lengthlist__44c0_sm_short[] = {
- 6, 6,12,13,13,14,16,17,17, 4, 2, 5, 8, 7, 9,12,
- 15,15, 9, 4, 5, 9, 7, 9,12,16,18,11, 6, 7, 4, 6,
- 8,11,14,18,10, 5, 6, 5, 5, 7,10,14,17,10, 5, 7,
- 7, 6, 7,10,13,16,11, 5, 7, 7, 7, 8,10,12,15,13,
- 6, 7, 5, 5, 7, 9,12,13,16, 8, 9, 6, 6, 7, 9,10,
- 12,
- };
-
- static static_codebook _huff_book__44c0_sm_short = {
- 2, 81,
- _huff_lengthlist__44c0_sm_short,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist__44c1_s_long[] = {
- 5, 5, 9,10, 9, 9,10,11,12, 5, 1, 5, 6, 6, 7,10,
- 12,14, 9, 5, 6, 8, 8,10,12,14,14,10, 5, 8, 5, 6,
- 8,11,13,14, 9, 5, 7, 6, 6, 8,10,12,11, 9, 7, 9,
- 7, 6, 6, 7,10,10,10, 9,12, 9, 8, 7, 7,10,12,11,
- 11,13,12,10, 9, 8, 9,11,11,14,15,15,13,11, 9, 9,
- 11,
- };
-
- static static_codebook _huff_book__44c1_s_long = {
- 2, 81,
- _huff_lengthlist__44c1_s_long,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c1_s_p1_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__44c1_s_p1_0[] = {
- 2, 4, 4, 0, 0, 0, 0, 0, 0, 5, 7, 6, 0, 0, 0, 0,
- 0, 0, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 0, 0,
- 0, 0, 0, 7, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 0,
- 0, 0, 0, 0, 7, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 7, 7, 0, 0, 0, 0,
- 0, 0, 7, 8, 8, 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 0, 0,
- 0, 0, 0, 8, 9,10, 0, 0, 0, 0, 0, 0, 8, 9, 9, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 8, 8, 0, 0,
- 0, 0, 0, 0, 8, 9, 8, 0, 0, 0, 0, 0, 0, 8, 9, 9,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 4, 7, 7, 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 0,
- 0, 0, 0, 0, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 6, 8, 8, 0, 0, 0, 0, 0, 0, 8,10, 9, 0,
- 0, 0, 0, 0, 0, 8, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 7, 8, 8, 0, 0, 0, 0, 0, 0, 8, 9, 9,
- 0, 0, 0, 0, 0, 0, 8, 9, 9, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,
- };
-
- static float _vq_quantthresh__44c1_s_p1_0[] = {
- -0.5, 0.5,
- };
-
- static long _vq_quantmap__44c1_s_p1_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c1_s_p1_0 = {
- _vq_quantthresh__44c1_s_p1_0,
- _vq_quantmap__44c1_s_p1_0,
- 3,
- 3
- };
-
- static static_codebook _44c1_s_p1_0 = {
- 8, 6561,
- _vq_lengthlist__44c1_s_p1_0,
- 1, -535822336, 1611661312, 2, 0,
- _vq_quantlist__44c1_s_p1_0,
- NULL,
- &_vq_auxt__44c1_s_p1_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c1_s_p2_0[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__44c1_s_p2_0[] = {
- 2, 3, 4, 6, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 6, 6, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 4, 4, 5, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 8, 8,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 6, 6, 6, 8, 8, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,
- };
-
- static float _vq_quantthresh__44c1_s_p2_0[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__44c1_s_p2_0[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c1_s_p2_0 = {
- _vq_quantthresh__44c1_s_p2_0,
- _vq_quantmap__44c1_s_p2_0,
- 5,
- 5
- };
-
- static static_codebook _44c1_s_p2_0 = {
- 4, 625,
- _vq_lengthlist__44c1_s_p2_0,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__44c1_s_p2_0,
- NULL,
- &_vq_auxt__44c1_s_p2_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c1_s_p3_0[] = {
- 4,
- 3,
- 5,
- 2,
- 6,
- 1,
- 7,
- 0,
- 8,
- };
-
- static long _vq_lengthlist__44c1_s_p3_0[] = {
- 1, 3, 2, 7, 7, 0, 0, 0, 0, 0,13,13, 6, 6, 0, 0,
- 0, 0, 0,12, 0, 6, 6, 0, 0, 0, 0, 0, 0, 0, 7, 7,
- 0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 0, 0, 0, 0, 0,
- 8, 9, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0,
- 0, 0,11,10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,
- };
-
- static float _vq_quantthresh__44c1_s_p3_0[] = {
- -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5,
- };
-
- static long _vq_quantmap__44c1_s_p3_0[] = {
- 7, 5, 3, 1, 0, 2, 4, 6,
- 8,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c1_s_p3_0 = {
- _vq_quantthresh__44c1_s_p3_0,
- _vq_quantmap__44c1_s_p3_0,
- 9,
- 9
- };
-
- static static_codebook _44c1_s_p3_0 = {
- 2, 81,
- _vq_lengthlist__44c1_s_p3_0,
- 1, -531628032, 1611661312, 4, 0,
- _vq_quantlist__44c1_s_p3_0,
- NULL,
- &_vq_auxt__44c1_s_p3_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c1_s_p4_0[] = {
- 4,
- 3,
- 5,
- 2,
- 6,
- 1,
- 7,
- 0,
- 8,
- };
-
- static long _vq_lengthlist__44c1_s_p4_0[] = {
- 1, 3, 3, 6, 5, 6, 6, 8, 8, 0, 0, 0, 7, 7, 7, 7,
- 9, 9, 0, 0, 0, 7, 7, 7, 7, 9, 9, 0, 0, 0, 7, 7,
- 8, 8,10,10, 0, 0, 0, 7, 7, 8, 8,10,10, 0, 0, 0,
- 9, 9, 8, 8,10,10, 0, 0, 0, 8, 8, 8, 8,10,10, 0,
- 0, 0,10,10, 9, 9,11,11, 0, 0, 0, 0, 0, 9, 9,11,
- 11,
- };
-
- static float _vq_quantthresh__44c1_s_p4_0[] = {
- -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5,
- };
-
- static long _vq_quantmap__44c1_s_p4_0[] = {
- 7, 5, 3, 1, 0, 2, 4, 6,
- 8,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c1_s_p4_0 = {
- _vq_quantthresh__44c1_s_p4_0,
- _vq_quantmap__44c1_s_p4_0,
- 9,
- 9
- };
-
- static static_codebook _44c1_s_p4_0 = {
- 2, 81,
- _vq_lengthlist__44c1_s_p4_0,
- 1, -531628032, 1611661312, 4, 0,
- _vq_quantlist__44c1_s_p4_0,
- NULL,
- &_vq_auxt__44c1_s_p4_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c1_s_p5_0[] = {
- 8,
- 7,
- 9,
- 6,
- 10,
- 5,
- 11,
- 4,
- 12,
- 3,
- 13,
- 2,
- 14,
- 1,
- 15,
- 0,
- 16,
- };
-
- static long _vq_lengthlist__44c1_s_p5_0[] = {
- 1, 4, 3, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9,10,10,11,
- 11, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10,10,10,10,
- 11,11, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10,10,10,
- 10,11,11, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10,10,
- 11,11,11,11, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10,
- 10,11,11,12,11, 0, 0, 0, 8, 8, 9, 9, 9,10,10,10,
- 10,10,11,11,12,12, 0, 0, 0, 8, 8, 9, 9,10, 9,10,
- 10,10,10,11,11,12,12, 0, 0, 0, 9, 9, 9, 9,10,10,
- 10,10,11,11,12,12,12,12, 0, 0, 0, 0, 0, 9, 9,10,
- 10,10,10,11,11,12,12,12,12, 0, 0, 0, 0, 0, 9, 9,
- 10,10,10,11,11,11,12,12,13,13, 0, 0, 0, 0, 0, 9,
- 9,10,10,10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0,
- 10,10,10,10,11,11,12,12,12,12,13,13, 0, 0, 0, 0,
- 0, 0, 0,10,10,11,11,12,12,12,12,13,13, 0, 0, 0,
- 0, 0, 0, 0,11,11,12,12,12,12,13,13,13,13, 0, 0,
- 0, 0, 0, 0, 0,11,11,11,11,12,12,13,13,13,13, 0,
- 0, 0, 0, 0, 0, 0,12,12,12,12,12,12,13,13,14,14,
- 0, 0, 0, 0, 0, 0, 0, 0, 0,12,12,12,12,13,13,14,
- 14,
- };
-
- static float _vq_quantthresh__44c1_s_p5_0[] = {
- -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5,
- 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5,
- };
-
- static long _vq_quantmap__44c1_s_p5_0[] = {
- 15, 13, 11, 9, 7, 5, 3, 1,
- 0, 2, 4, 6, 8, 10, 12, 14,
- 16,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c1_s_p5_0 = {
- _vq_quantthresh__44c1_s_p5_0,
- _vq_quantmap__44c1_s_p5_0,
- 17,
- 17
- };
-
- static static_codebook _44c1_s_p5_0 = {
- 2, 289,
- _vq_lengthlist__44c1_s_p5_0,
- 1, -529530880, 1611661312, 5, 0,
- _vq_quantlist__44c1_s_p5_0,
- NULL,
- &_vq_auxt__44c1_s_p5_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c1_s_p6_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__44c1_s_p6_0[] = {
- 1, 4, 4, 7, 6, 6, 7, 6, 6, 4, 7, 7,10, 9, 9,11,
- 9, 9, 4, 7, 7,10, 9, 9,11, 9, 9, 6,10,10,11,11,
- 11,11,10,10, 6, 9, 9,11,10,10,11,10,10, 6, 9, 9,
- 11,10,11,11,10,10, 7,11,10,11,11,11,12,11,11, 7,
- 9, 9,11,10,10,11,11,10, 6, 9, 9,10,10,10,12,10,
- 11,
- };
-
- static float _vq_quantthresh__44c1_s_p6_0[] = {
- -5.5, 5.5,
- };
-
- static long _vq_quantmap__44c1_s_p6_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c1_s_p6_0 = {
- _vq_quantthresh__44c1_s_p6_0,
- _vq_quantmap__44c1_s_p6_0,
- 3,
- 3
- };
-
- static static_codebook _44c1_s_p6_0 = {
- 4, 81,
- _vq_lengthlist__44c1_s_p6_0,
- 1, -529137664, 1618345984, 2, 0,
- _vq_quantlist__44c1_s_p6_0,
- NULL,
- &_vq_auxt__44c1_s_p6_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c1_s_p6_1[] = {
- 5,
- 4,
- 6,
- 3,
- 7,
- 2,
- 8,
- 1,
- 9,
- 0,
- 10,
- };
-
- static long _vq_lengthlist__44c1_s_p6_1[] = {
- 2, 3, 3, 6, 6, 7, 7, 7, 7, 8, 8,10,10,10, 6, 6,
- 7, 7, 8, 8, 8, 8,10,10,10, 6, 6, 7, 7, 8, 8, 8,
- 8,10,10,10, 7, 7, 7, 7, 8, 8, 8, 8,10,10,10, 7,
- 7, 7, 7, 8, 8, 8, 8,10,10,10, 7, 7, 8, 8, 8, 8,
- 8, 8,10,10,10, 7, 7, 8, 8, 8, 8, 8, 8,10,10,10,
- 8, 8, 8, 8, 8, 8, 8, 8,10,10,10,10,10, 8, 8, 8,
- 8, 8, 8,10,10,10,10,10, 9, 9, 8, 8, 8, 8,10,10,
- 10,10,10, 8, 8, 8, 8, 8, 8,
- };
-
- static float _vq_quantthresh__44c1_s_p6_1[] = {
- -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5,
- 3.5, 4.5,
- };
-
- static long _vq_quantmap__44c1_s_p6_1[] = {
- 9, 7, 5, 3, 1, 0, 2, 4,
- 6, 8, 10,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c1_s_p6_1 = {
- _vq_quantthresh__44c1_s_p6_1,
- _vq_quantmap__44c1_s_p6_1,
- 11,
- 11
- };
-
- static static_codebook _44c1_s_p6_1 = {
- 2, 121,
- _vq_lengthlist__44c1_s_p6_1,
- 1, -531365888, 1611661312, 4, 0,
- _vq_quantlist__44c1_s_p6_1,
- NULL,
- &_vq_auxt__44c1_s_p6_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c1_s_p7_0[] = {
- 6,
- 5,
- 7,
- 4,
- 8,
- 3,
- 9,
- 2,
- 10,
- 1,
- 11,
- 0,
- 12,
- };
-
- static long _vq_lengthlist__44c1_s_p7_0[] = {
- 1, 4, 4, 6, 6, 7, 7, 7, 7, 8, 8,10, 9, 7, 5, 6,
- 7, 7, 8, 8, 8, 8, 9, 9,10,10, 7, 5, 5, 7, 7, 8,
- 8, 8, 8, 9, 9,10,10, 0, 8, 8, 8, 8, 9, 9, 9, 9,
- 10,10,11,10, 0, 8, 8, 8, 8, 9, 9, 9, 9,10,10,11,
- 11, 0,12,12, 9, 9, 9,10,10,10,11,11,11,11, 0,13,
- 13, 9, 9, 9, 9,10,10,11,11,11,11, 0, 0, 0,10,10,
- 10,10,11,11,12,11,12,12, 0, 0, 0,10,10,10, 9,11,
- 11,12,11,13,12, 0, 0, 0,13,13,10,10,11,11,12,12,
- 13,13, 0, 0, 0,14,14,10,10,11,11,12,12,13,13, 0,
- 0, 0, 0, 0,11,12,11,11,12,12,14,13, 0, 0, 0, 0,
- 0,12,11,11,11,13,10,14,13,
- };
-
- static float _vq_quantthresh__44c1_s_p7_0[] = {
- -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5,
- 12.5, 17.5, 22.5, 27.5,
- };
-
- static long _vq_quantmap__44c1_s_p7_0[] = {
- 11, 9, 7, 5, 3, 1, 0, 2,
- 4, 6, 8, 10, 12,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c1_s_p7_0 = {
- _vq_quantthresh__44c1_s_p7_0,
- _vq_quantmap__44c1_s_p7_0,
- 13,
- 13
- };
-
- static static_codebook _44c1_s_p7_0 = {
- 2, 169,
- _vq_lengthlist__44c1_s_p7_0,
- 1, -526516224, 1616117760, 4, 0,
- _vq_quantlist__44c1_s_p7_0,
- NULL,
- &_vq_auxt__44c1_s_p7_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c1_s_p7_1[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__44c1_s_p7_1[] = {
- 2, 3, 3, 5, 5, 6, 6, 6, 5, 5, 6, 6, 6, 5, 5, 6,
- 6, 6, 5, 5, 6, 6, 6, 5, 5,
- };
-
- static float _vq_quantthresh__44c1_s_p7_1[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__44c1_s_p7_1[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c1_s_p7_1 = {
- _vq_quantthresh__44c1_s_p7_1,
- _vq_quantmap__44c1_s_p7_1,
- 5,
- 5
- };
-
- static static_codebook _44c1_s_p7_1 = {
- 2, 25,
- _vq_lengthlist__44c1_s_p7_1,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__44c1_s_p7_1,
- NULL,
- &_vq_auxt__44c1_s_p7_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c1_s_p8_0[] = {
- 6,
- 5,
- 7,
- 4,
- 8,
- 3,
- 9,
- 2,
- 10,
- 1,
- 11,
- 0,
- 12,
- };
-
- static long _vq_lengthlist__44c1_s_p8_0[] = {
- 1, 4, 3,10,10,10,10,10,10,10,10,10,10, 4, 8, 6,
- 10,10,10,10,10,10,10,10,10,10, 4, 8, 7,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,
- };
-
- static float _vq_quantthresh__44c1_s_p8_0[] = {
- -1215.5, -994.5, -773.5, -552.5, -331.5, -110.5, 110.5, 331.5,
- 552.5, 773.5, 994.5, 1215.5,
- };
-
- static long _vq_quantmap__44c1_s_p8_0[] = {
- 11, 9, 7, 5, 3, 1, 0, 2,
- 4, 6, 8, 10, 12,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c1_s_p8_0 = {
- _vq_quantthresh__44c1_s_p8_0,
- _vq_quantmap__44c1_s_p8_0,
- 13,
- 13
- };
-
- static static_codebook _44c1_s_p8_0 = {
- 2, 169,
- _vq_lengthlist__44c1_s_p8_0,
- 1, -514541568, 1627103232, 4, 0,
- _vq_quantlist__44c1_s_p8_0,
- NULL,
- &_vq_auxt__44c1_s_p8_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c1_s_p8_1[] = {
- 6,
- 5,
- 7,
- 4,
- 8,
- 3,
- 9,
- 2,
- 10,
- 1,
- 11,
- 0,
- 12,
- };
-
- static long _vq_lengthlist__44c1_s_p8_1[] = {
- 1, 4, 4, 6, 5, 7, 7, 9, 9,10,10,12,12, 6, 5, 5,
- 7, 7, 8, 8,10,10,12,11,12,12, 6, 5, 5, 7, 7, 8,
- 8,10,10,11,11,12,12,15, 7, 7, 8, 8, 9, 9,11,11,
- 12,12,13,12,15, 8, 8, 8, 7, 9, 9,10,10,12,12,13,
- 13,16,11,10, 8, 8,10,10,11,11,12,12,13,13,16,11,
- 11, 9, 8,11,10,11,11,12,12,13,12,16,16,16,10,11,
- 10,11,12,12,12,12,13,13,16,16,16,11, 9,11, 9,14,
- 12,12,12,13,13,16,16,16,12,14,11,12,12,12,13,13,
- 14,13,16,16,16,15,13,12,10,13,10,13,14,13,13,16,
- 16,16,16,16,13,14,12,13,13,12,13,13,16,16,16,16,
- 16,13,12,12,11,14,12,15,13,
- };
-
- static float _vq_quantthresh__44c1_s_p8_1[] = {
- -93.5, -76.5, -59.5, -42.5, -25.5, -8.5, 8.5, 25.5,
- 42.5, 59.5, 76.5, 93.5,
- };
-
- static long _vq_quantmap__44c1_s_p8_1[] = {
- 11, 9, 7, 5, 3, 1, 0, 2,
- 4, 6, 8, 10, 12,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c1_s_p8_1 = {
- _vq_quantthresh__44c1_s_p8_1,
- _vq_quantmap__44c1_s_p8_1,
- 13,
- 13
- };
-
- static static_codebook _44c1_s_p8_1 = {
- 2, 169,
- _vq_lengthlist__44c1_s_p8_1,
- 1, -522616832, 1620115456, 4, 0,
- _vq_quantlist__44c1_s_p8_1,
- NULL,
- &_vq_auxt__44c1_s_p8_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c1_s_p8_2[] = {
- 8,
- 7,
- 9,
- 6,
- 10,
- 5,
- 11,
- 4,
- 12,
- 3,
- 13,
- 2,
- 14,
- 1,
- 15,
- 0,
- 16,
- };
-
- static long _vq_lengthlist__44c1_s_p8_2[] = {
- 2, 4, 4, 6, 6, 6, 6, 7, 7, 8, 8, 8, 8, 8, 8, 8,
- 8,10,10,10, 7, 7, 7, 7, 8, 8, 9, 9, 9, 9, 9, 9,
- 9, 9,10,10,10, 7, 7, 8, 7, 8, 8, 9, 9, 9, 9, 9,
- 9, 9, 9,10,10,10, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9,
- 9,10, 9, 9,10,10,10, 7, 7, 8, 8, 9, 8, 9, 9, 9,
- 9,10, 9, 9,10,10,11,11, 8, 8, 8, 8, 9, 9, 9, 9,
- 9, 9,10, 9, 9,10,10,10,10, 8, 8, 8, 8, 9, 9, 9,
- 9, 9, 9, 9, 9,10,10,11,11,11, 8, 8, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9,10,10,10,10,11,11,11, 8, 8, 9,
- 9, 9, 9,10, 9, 9, 9, 9, 9,11,11,11,11,11, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,11,10,10,11,11, 9,
- 9, 9, 9, 9, 9, 9, 9, 9,10,10,10,10,11,10,11,11,
- 9, 9, 9, 9, 9, 9, 9, 9, 9,10,10, 9,10,10,11,11,
- 11,11,11, 9, 9, 9,10, 9, 9, 9, 9, 9, 9,10,11,11,
- 11,11,11,11,10,10,10,10, 9, 9, 9, 9, 9, 9,10,11,
- 11,11,11,11,11, 9,10, 9, 9, 9, 9,10, 9, 9, 9,11,
- 11,11,11,11,11,11,10,10, 9, 9, 9, 9, 9, 9,10, 9,
- 11,11,10,11,11,11,11,10,11, 9, 9, 9, 9, 9, 9, 9,
- 9,
- };
-
- static float _vq_quantthresh__44c1_s_p8_2[] = {
- -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5,
- 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5,
- };
-
- static long _vq_quantmap__44c1_s_p8_2[] = {
- 15, 13, 11, 9, 7, 5, 3, 1,
- 0, 2, 4, 6, 8, 10, 12, 14,
- 16,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c1_s_p8_2 = {
- _vq_quantthresh__44c1_s_p8_2,
- _vq_quantmap__44c1_s_p8_2,
- 17,
- 17
- };
-
- static static_codebook _44c1_s_p8_2 = {
- 2, 289,
- _vq_lengthlist__44c1_s_p8_2,
- 1, -529530880, 1611661312, 5, 0,
- _vq_quantlist__44c1_s_p8_2,
- NULL,
- &_vq_auxt__44c1_s_p8_2,
- NULL,
- 0
- };
-
- static long _huff_lengthlist__44c1_s_short[] = {
- 6, 8,13,12,13,14,15,16,16, 4, 2, 4, 7, 6, 8,11,
- 13,15,10, 4, 4, 8, 6, 8,11,14,17,11, 5, 6, 5, 6,
- 8,12,14,17,11, 5, 5, 6, 5, 7,10,13,16,12, 6, 7,
- 8, 7, 8,10,13,15,13, 8, 8, 7, 7, 8,10,12,15,15,
- 7, 7, 5, 5, 7, 9,12,14,15, 8, 8, 6, 6, 7, 8,10,
- 11,
- };
-
- static static_codebook _huff_book__44c1_s_short = {
- 2, 81,
- _huff_lengthlist__44c1_s_short,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist__44c1_sm_long[] = {
- 5, 4, 8,10, 9, 9,10,11,12, 4, 2, 5, 6, 6, 8,10,
- 11,13, 8, 4, 6, 8, 7, 9,12,12,14,10, 6, 8, 4, 5,
- 6, 9,11,12, 9, 5, 6, 5, 5, 6, 9,11,11, 9, 7, 9,
- 6, 5, 5, 7,10,10,10, 9,11, 8, 7, 6, 7, 9,11,11,
- 12,13,10,10, 9, 8, 9,11,11,15,15,12,13,11, 9,10,
- 11,
- };
-
- static static_codebook _huff_book__44c1_sm_long = {
- 2, 81,
- _huff_lengthlist__44c1_sm_long,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c1_sm_p1_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__44c1_sm_p1_0[] = {
- 1, 5, 5, 0, 0, 0, 0, 0, 0, 5, 7, 7, 0, 0, 0, 0,
- 0, 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 5, 8, 7, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, 0,
- 0, 0, 0, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 7, 9, 8, 0, 0,
- 0, 0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 8, 7, 0, 0, 0, 0,
- 0, 0, 8, 9, 9, 0, 0, 0, 0, 0, 0, 8, 9, 9, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, 0,
- 0, 0, 0, 9, 9,10, 0, 0, 0, 0, 0, 0, 9,10,10, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0,
- 0, 0, 0, 0, 8,10, 9, 0, 0, 0, 0, 0, 0, 9,10,10,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 5, 7, 8, 0, 0, 0, 0, 0, 0, 8, 9, 9, 0, 0,
- 0, 0, 0, 0, 8, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 9,10,10, 0,
- 0, 0, 0, 0, 0, 8, 9,10, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 9,10,10,
- 0, 0, 0, 0, 0, 0, 9,10, 9, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,
- };
-
- static float _vq_quantthresh__44c1_sm_p1_0[] = {
- -0.5, 0.5,
- };
-
- static long _vq_quantmap__44c1_sm_p1_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c1_sm_p1_0 = {
- _vq_quantthresh__44c1_sm_p1_0,
- _vq_quantmap__44c1_sm_p1_0,
- 3,
- 3
- };
-
- static static_codebook _44c1_sm_p1_0 = {
- 8, 6561,
- _vq_lengthlist__44c1_sm_p1_0,
- 1, -535822336, 1611661312, 2, 0,
- _vq_quantlist__44c1_sm_p1_0,
- NULL,
- &_vq_auxt__44c1_sm_p1_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c1_sm_p2_0[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__44c1_sm_p2_0[] = {
- 2, 3, 4, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 6, 6, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 4, 4, 4, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 9, 9,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 6, 6, 7, 9, 9, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,
- };
-
- static float _vq_quantthresh__44c1_sm_p2_0[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__44c1_sm_p2_0[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c1_sm_p2_0 = {
- _vq_quantthresh__44c1_sm_p2_0,
- _vq_quantmap__44c1_sm_p2_0,
- 5,
- 5
- };
-
- static static_codebook _44c1_sm_p2_0 = {
- 4, 625,
- _vq_lengthlist__44c1_sm_p2_0,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__44c1_sm_p2_0,
- NULL,
- &_vq_auxt__44c1_sm_p2_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c1_sm_p3_0[] = {
- 4,
- 3,
- 5,
- 2,
- 6,
- 1,
- 7,
- 0,
- 8,
- };
-
- static long _vq_lengthlist__44c1_sm_p3_0[] = {
- 1, 3, 3, 7, 7, 0, 0, 0, 0, 0, 5, 5, 6, 6, 0, 0,
- 0, 0, 0, 5, 5, 7, 7, 0, 0, 0, 0, 0, 7, 7, 7, 7,
- 0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 0, 0, 0, 0, 0,
- 8, 9, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0,
- 0, 0,10,10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,
- };
-
- static float _vq_quantthresh__44c1_sm_p3_0[] = {
- -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5,
- };
-
- static long _vq_quantmap__44c1_sm_p3_0[] = {
- 7, 5, 3, 1, 0, 2, 4, 6,
- 8,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c1_sm_p3_0 = {
- _vq_quantthresh__44c1_sm_p3_0,
- _vq_quantmap__44c1_sm_p3_0,
- 9,
- 9
- };
-
- static static_codebook _44c1_sm_p3_0 = {
- 2, 81,
- _vq_lengthlist__44c1_sm_p3_0,
- 1, -531628032, 1611661312, 4, 0,
- _vq_quantlist__44c1_sm_p3_0,
- NULL,
- &_vq_auxt__44c1_sm_p3_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c1_sm_p4_0[] = {
- 4,
- 3,
- 5,
- 2,
- 6,
- 1,
- 7,
- 0,
- 8,
- };
-
- static long _vq_lengthlist__44c1_sm_p4_0[] = {
- 1, 3, 3, 6, 6, 7, 7, 9, 9, 0, 6, 6, 7, 7, 8, 8,
- 9, 9, 0, 6, 6, 7, 7, 8, 8, 9, 9, 0, 7, 7, 8, 8,
- 8, 8,10,10, 0, 0, 0, 8, 8, 8, 8,10,10, 0, 0, 0,
- 8, 8, 9, 9,11,11, 0, 0, 0, 9, 9, 9, 9,11,11, 0,
- 0, 0,10,10,10,10,11,11, 0, 0, 0, 0, 0, 9, 9,11,
- 11,
- };
-
- static float _vq_quantthresh__44c1_sm_p4_0[] = {
- -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5,
- };
-
- static long _vq_quantmap__44c1_sm_p4_0[] = {
- 7, 5, 3, 1, 0, 2, 4, 6,
- 8,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c1_sm_p4_0 = {
- _vq_quantthresh__44c1_sm_p4_0,
- _vq_quantmap__44c1_sm_p4_0,
- 9,
- 9
- };
-
- static static_codebook _44c1_sm_p4_0 = {
- 2, 81,
- _vq_lengthlist__44c1_sm_p4_0,
- 1, -531628032, 1611661312, 4, 0,
- _vq_quantlist__44c1_sm_p4_0,
- NULL,
- &_vq_auxt__44c1_sm_p4_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c1_sm_p5_0[] = {
- 8,
- 7,
- 9,
- 6,
- 10,
- 5,
- 11,
- 4,
- 12,
- 3,
- 13,
- 2,
- 14,
- 1,
- 15,
- 0,
- 16,
- };
-
- static long _vq_lengthlist__44c1_sm_p5_0[] = {
- 2, 3, 3, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9,10,10,11,
- 11, 0, 5, 5, 6, 6, 8, 8, 9, 9, 9, 9,10,10,10,10,
- 11,11, 0, 5, 5, 6, 6, 8, 8, 9, 9, 9, 9,10,10,10,
- 10,11,11, 0, 7, 7, 7, 7, 8, 8, 9, 9, 9, 9,10,10,
- 11,11,12,12, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10,
- 10,11,11,12,12, 0, 0, 0, 8, 8, 8, 8, 9, 9,10,10,
- 10,11,11,11,12,12, 0, 0, 0, 8, 8, 8, 8, 9, 9,10,
- 10,10,10,11,11,12,12, 0, 0, 0, 9, 9, 9, 9,10,10,
- 10,10,11,11,12,12,12,12, 0, 0, 0, 0, 0, 9, 9,10,
- 10,10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, 9, 9,
- 9, 9,10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, 9,
- 9, 9, 9,10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0,
- 9, 9,10,10,11,11,12,12,12,12,13,13, 0, 0, 0, 0,
- 0, 0, 0,10,10,11,11,12,12,12,12,13,13, 0, 0, 0,
- 0, 0, 0, 0,11,11,11,11,12,12,13,13,13,13, 0, 0,
- 0, 0, 0, 0, 0,11,11,11,11,12,12,13,13,13,13, 0,
- 0, 0, 0, 0, 0, 0,11,11,12,12,12,12,13,13,14,14,
- 0, 0, 0, 0, 0, 0, 0, 0, 0,12,12,12,12,13,13,14,
- 14,
- };
-
- static float _vq_quantthresh__44c1_sm_p5_0[] = {
- -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5,
- 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5,
- };
-
- static long _vq_quantmap__44c1_sm_p5_0[] = {
- 15, 13, 11, 9, 7, 5, 3, 1,
- 0, 2, 4, 6, 8, 10, 12, 14,
- 16,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c1_sm_p5_0 = {
- _vq_quantthresh__44c1_sm_p5_0,
- _vq_quantmap__44c1_sm_p5_0,
- 17,
- 17
- };
-
- static static_codebook _44c1_sm_p5_0 = {
- 2, 289,
- _vq_lengthlist__44c1_sm_p5_0,
- 1, -529530880, 1611661312, 5, 0,
- _vq_quantlist__44c1_sm_p5_0,
- NULL,
- &_vq_auxt__44c1_sm_p5_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c1_sm_p6_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__44c1_sm_p6_0[] = {
- 1, 4, 4, 7, 6, 6, 7, 6, 6, 4, 7, 7,10, 9, 9,11,
- 9, 9, 4, 7, 7,10, 9, 9,11, 9, 9, 7,10,10,10,11,
- 11,11,10,10, 6, 9, 9,11,11,10,11,10,10, 6, 9, 9,
- 11,10,11,11,10,10, 7,11,11,11,11,11,11,11,11, 6,
- 9, 9,11,10,10,11,11,10, 6, 9, 9,10,10,10,11,10,
- 11,
- };
-
- static float _vq_quantthresh__44c1_sm_p6_0[] = {
- -5.5, 5.5,
- };
-
- static long _vq_quantmap__44c1_sm_p6_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c1_sm_p6_0 = {
- _vq_quantthresh__44c1_sm_p6_0,
- _vq_quantmap__44c1_sm_p6_0,
- 3,
- 3
- };
-
- static static_codebook _44c1_sm_p6_0 = {
- 4, 81,
- _vq_lengthlist__44c1_sm_p6_0,
- 1, -529137664, 1618345984, 2, 0,
- _vq_quantlist__44c1_sm_p6_0,
- NULL,
- &_vq_auxt__44c1_sm_p6_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c1_sm_p6_1[] = {
- 5,
- 4,
- 6,
- 3,
- 7,
- 2,
- 8,
- 1,
- 9,
- 0,
- 10,
- };
-
- static long _vq_lengthlist__44c1_sm_p6_1[] = {
- 2, 4, 4, 6, 6, 7, 7, 7, 7, 8, 8,10, 5, 5, 6, 6,
- 7, 7, 8, 8, 8, 8,10, 5, 5, 6, 6, 7, 7, 8, 8, 8,
- 8,10, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8,10,10,10, 7,
- 7, 7, 7, 8, 8, 8, 8,10,10,10, 7, 7, 8, 8, 8, 8,
- 8, 8,10,10,10, 7, 7, 8, 8, 8, 8, 8, 8,10,10,10,
- 8, 8, 8, 8, 8, 8, 9, 8,10,10,10,10,10, 8, 8, 8,
- 8, 8, 8,10,10,10,10,10, 9, 9, 8, 8, 8, 8,10,10,
- 10,10,10, 8, 8, 8, 8, 8, 8,
- };
-
- static float _vq_quantthresh__44c1_sm_p6_1[] = {
- -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5,
- 3.5, 4.5,
- };
-
- static long _vq_quantmap__44c1_sm_p6_1[] = {
- 9, 7, 5, 3, 1, 0, 2, 4,
- 6, 8, 10,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c1_sm_p6_1 = {
- _vq_quantthresh__44c1_sm_p6_1,
- _vq_quantmap__44c1_sm_p6_1,
- 11,
- 11
- };
-
- static static_codebook _44c1_sm_p6_1 = {
- 2, 121,
- _vq_lengthlist__44c1_sm_p6_1,
- 1, -531365888, 1611661312, 4, 0,
- _vq_quantlist__44c1_sm_p6_1,
- NULL,
- &_vq_auxt__44c1_sm_p6_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c1_sm_p7_0[] = {
- 6,
- 5,
- 7,
- 4,
- 8,
- 3,
- 9,
- 2,
- 10,
- 1,
- 11,
- 0,
- 12,
- };
-
- static long _vq_lengthlist__44c1_sm_p7_0[] = {
- 1, 4, 4, 6, 6, 7, 7, 7, 7, 8, 8, 9, 9, 7, 5, 5,
- 7, 7, 8, 8, 8, 8, 9, 9,10,10, 7, 5, 6, 7, 7, 8,
- 8, 8, 8, 9, 9,11,10, 0, 8, 8, 8, 8, 9, 9, 9, 9,
- 10,10,11,11, 0, 8, 8, 8, 8, 9, 9, 9, 9,10,10,11,
- 11, 0,12,12, 9, 9,10,10,10,10,11,11,11,11, 0,13,
- 13, 9, 9, 9, 9,10,10,11,11,12,12, 0, 0, 0, 9,10,
- 9,10,11,11,12,11,13,12, 0, 0, 0,10,10, 9, 9,11,
- 11,12,12,13,12, 0, 0, 0,13,13,10,10,11,11,12,12,
- 13,13, 0, 0, 0,14,14,10,10,11,11,12,12,13,13, 0,
- 0, 0, 0, 0,11,12,11,11,12,13,14,13, 0, 0, 0, 0,
- 0,12,12,11,11,13,12,14,13,
- };
-
- static float _vq_quantthresh__44c1_sm_p7_0[] = {
- -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5,
- 12.5, 17.5, 22.5, 27.5,
- };
-
- static long _vq_quantmap__44c1_sm_p7_0[] = {
- 11, 9, 7, 5, 3, 1, 0, 2,
- 4, 6, 8, 10, 12,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c1_sm_p7_0 = {
- _vq_quantthresh__44c1_sm_p7_0,
- _vq_quantmap__44c1_sm_p7_0,
- 13,
- 13
- };
-
- static static_codebook _44c1_sm_p7_0 = {
- 2, 169,
- _vq_lengthlist__44c1_sm_p7_0,
- 1, -526516224, 1616117760, 4, 0,
- _vq_quantlist__44c1_sm_p7_0,
- NULL,
- &_vq_auxt__44c1_sm_p7_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c1_sm_p7_1[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__44c1_sm_p7_1[] = {
- 2, 4, 4, 4, 5, 6, 5, 5, 5, 5, 6, 5, 5, 5, 5, 6,
- 5, 5, 5, 5, 6, 6, 6, 5, 5,
- };
-
- static float _vq_quantthresh__44c1_sm_p7_1[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__44c1_sm_p7_1[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c1_sm_p7_1 = {
- _vq_quantthresh__44c1_sm_p7_1,
- _vq_quantmap__44c1_sm_p7_1,
- 5,
- 5
- };
-
- static static_codebook _44c1_sm_p7_1 = {
- 2, 25,
- _vq_lengthlist__44c1_sm_p7_1,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__44c1_sm_p7_1,
- NULL,
- &_vq_auxt__44c1_sm_p7_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c1_sm_p8_0[] = {
- 6,
- 5,
- 7,
- 4,
- 8,
- 3,
- 9,
- 2,
- 10,
- 1,
- 11,
- 0,
- 12,
- };
-
- static long _vq_lengthlist__44c1_sm_p8_0[] = {
- 1, 3, 3,13,13,13,13,13,13,13,13,13,13, 3, 6, 6,
- 13,13,13,13,13,13,13,13,13,13, 4, 8, 7,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,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,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,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,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,13,13,13,13,13,
- };
-
- static float _vq_quantthresh__44c1_sm_p8_0[] = {
- -1215.5, -994.5, -773.5, -552.5, -331.5, -110.5, 110.5, 331.5,
- 552.5, 773.5, 994.5, 1215.5,
- };
-
- static long _vq_quantmap__44c1_sm_p8_0[] = {
- 11, 9, 7, 5, 3, 1, 0, 2,
- 4, 6, 8, 10, 12,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c1_sm_p8_0 = {
- _vq_quantthresh__44c1_sm_p8_0,
- _vq_quantmap__44c1_sm_p8_0,
- 13,
- 13
- };
-
- static static_codebook _44c1_sm_p8_0 = {
- 2, 169,
- _vq_lengthlist__44c1_sm_p8_0,
- 1, -514541568, 1627103232, 4, 0,
- _vq_quantlist__44c1_sm_p8_0,
- NULL,
- &_vq_auxt__44c1_sm_p8_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c1_sm_p8_1[] = {
- 6,
- 5,
- 7,
- 4,
- 8,
- 3,
- 9,
- 2,
- 10,
- 1,
- 11,
- 0,
- 12,
- };
-
- static long _vq_lengthlist__44c1_sm_p8_1[] = {
- 1, 4, 4, 6, 6, 7, 7, 9, 9,10,11,12,12, 6, 5, 5,
- 7, 7, 8, 7,10,10,11,11,12,12, 6, 5, 5, 7, 7, 8,
- 8,10,10,11,11,12,12,16, 7, 7, 8, 8, 9, 9,11,11,
- 12,12,13,13,17, 7, 7, 8, 7, 9, 9,11,10,12,12,13,
- 13,19,11,10, 8, 8,10,10,11,11,12,12,13,13,19,11,
- 11, 9, 7,11,10,11,11,12,12,13,12,19,19,19,10,10,
- 10,10,11,12,12,12,13,14,18,19,19,11, 9,11, 9,13,
- 12,12,12,13,13,19,20,19,13,15,11,11,12,12,13,13,
- 14,13,18,19,20,15,13,12,10,13,10,13,13,13,14,20,
- 20,20,20,20,13,14,12,12,13,12,13,13,20,20,20,20,
- 20,13,12,12,12,14,12,14,13,
- };
-
- static float _vq_quantthresh__44c1_sm_p8_1[] = {
- -93.5, -76.5, -59.5, -42.5, -25.5, -8.5, 8.5, 25.5,
- 42.5, 59.5, 76.5, 93.5,
- };
-
- static long _vq_quantmap__44c1_sm_p8_1[] = {
- 11, 9, 7, 5, 3, 1, 0, 2,
- 4, 6, 8, 10, 12,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c1_sm_p8_1 = {
- _vq_quantthresh__44c1_sm_p8_1,
- _vq_quantmap__44c1_sm_p8_1,
- 13,
- 13
- };
-
- static static_codebook _44c1_sm_p8_1 = {
- 2, 169,
- _vq_lengthlist__44c1_sm_p8_1,
- 1, -522616832, 1620115456, 4, 0,
- _vq_quantlist__44c1_sm_p8_1,
- NULL,
- &_vq_auxt__44c1_sm_p8_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44c1_sm_p8_2[] = {
- 8,
- 7,
- 9,
- 6,
- 10,
- 5,
- 11,
- 4,
- 12,
- 3,
- 13,
- 2,
- 14,
- 1,
- 15,
- 0,
- 16,
- };
-
- static long _vq_lengthlist__44c1_sm_p8_2[] = {
- 2, 5, 5, 6, 6, 7, 6, 7, 7, 8, 8, 8, 8, 8, 8, 8,
- 8,10, 6, 6, 7, 7, 7, 7, 8, 8, 9, 9, 9, 9, 9, 9,
- 9, 9,10, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9,
- 9, 9, 9,10, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9,
- 9, 9, 9, 9,10,10,10, 7, 7, 8, 8, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9,10,11,11, 8, 8, 8, 8, 9, 9, 9, 9,
- 9, 9,10,10, 9,10,10,10,10, 8, 8, 8, 8, 9, 9, 9,
- 9, 9, 9, 9, 9,10,10,11,10,10, 8, 8, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9,10, 9,10,10,10,11,11, 8, 8, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9,11,11,11,11,11, 9, 9,
- 9, 9, 9, 9, 9, 9,10, 9,10, 9,11,11,11,11,11, 9,
- 8, 9, 9, 9, 9, 9, 9, 9,10,10, 9,11,11,10,11,11,
- 9, 9, 9, 9, 9, 9, 9, 9, 9,10,10, 9,11,11,11,11,
- 11,11,11, 9, 9,10, 9, 9, 9, 9,10, 9,10,10,11,10,
- 11,11,11,11, 9,10,10,10, 9, 9, 9, 9, 9, 9,10,11,
- 11,11,11,11,11, 9, 9, 9, 9, 9, 9, 9, 9,10, 9,11,
- 11,10,11,11,11,11,10,10, 9, 9, 9, 9, 9, 9,10, 9,
- 10,11,10,11,11,11,11,11,11, 9, 9,10, 9, 9, 9, 9,
- 9,
- };
-
- static float _vq_quantthresh__44c1_sm_p8_2[] = {
- -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5,
- 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5,
- };
-
- static long _vq_quantmap__44c1_sm_p8_2[] = {
- 15, 13, 11, 9, 7, 5, 3, 1,
- 0, 2, 4, 6, 8, 10, 12, 14,
- 16,
- };
-
- static encode_aux_threshmatch _vq_auxt__44c1_sm_p8_2 = {
- _vq_quantthresh__44c1_sm_p8_2,
- _vq_quantmap__44c1_sm_p8_2,
- 17,
- 17
- };
-
- static static_codebook _44c1_sm_p8_2 = {
- 2, 289,
- _vq_lengthlist__44c1_sm_p8_2,
- 1, -529530880, 1611661312, 5, 0,
- _vq_quantlist__44c1_sm_p8_2,
- NULL,
- &_vq_auxt__44c1_sm_p8_2,
- NULL,
- 0
- };
-
- static long _huff_lengthlist__44c1_sm_short[] = {
- 4, 7,13,14,14,15,16,18,18, 4, 2, 5, 8, 7, 9,12,
- 15,15,10, 4, 5,10, 6, 8,11,15,17,12, 5, 7, 5, 6,
- 8,11,14,17,11, 5, 6, 6, 5, 6, 9,13,17,12, 6, 7,
- 6, 5, 6, 8,12,14,14, 7, 8, 6, 6, 7, 9,11,14,14,
- 8, 9, 6, 5, 6, 9,11,13,16,10,10, 7, 6, 7, 8,10,
- 11,
- };
-
- static static_codebook _huff_book__44c1_sm_short = {
- 2, 81,
- _huff_lengthlist__44c1_sm_short,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist__44cn1_s_long[] = {
- 4, 4, 7, 8, 7, 8,10,12,17, 3, 1, 6, 6, 7, 8,10,
- 12,15, 7, 6, 9, 9, 9,11,12,14,17, 8, 6, 9, 6, 7,
- 9,11,13,17, 7, 6, 9, 7, 7, 8, 9,12,15, 8, 8,10,
- 8, 7, 7, 7,10,14, 9,10,12,10, 8, 8, 8,10,14,11,
- 13,15,13,12,11,11,12,16,17,18,18,19,20,18,16,16,
- 20,
- };
-
- static static_codebook _huff_book__44cn1_s_long = {
- 2, 81,
- _huff_lengthlist__44cn1_s_long,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44cn1_s_p1_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__44cn1_s_p1_0[] = {
- 1, 4, 4, 0, 0, 0, 0, 0, 0, 5, 7, 7, 0, 0, 0, 0,
- 0, 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 5, 8, 8, 0, 0, 0, 0, 0, 0, 8, 9, 9, 0, 0, 0,
- 0, 0, 0, 7, 9,10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 5, 8, 8, 0, 0, 0, 0, 0, 0, 7,10, 9, 0, 0,
- 0, 0, 0, 0, 8,10, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 8, 8, 0, 0, 0, 0,
- 0, 0, 8,10,10, 0, 0, 0, 0, 0, 0, 8, 9,10, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7,10,10, 0, 0, 0,
- 0, 0, 0, 9, 9,11, 0, 0, 0, 0, 0, 0,10,11,11, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7,10,10, 0, 0,
- 0, 0, 0, 0, 9,11, 9, 0, 0, 0, 0, 0, 0,10,11,11,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 5, 8, 8, 0, 0, 0, 0, 0, 0, 8,10,10, 0, 0,
- 0, 0, 0, 0, 8,10,10, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 7,10,10, 0, 0, 0, 0, 0, 0,10,11,11, 0,
- 0, 0, 0, 0, 0, 9, 9,11, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 7,10,10, 0, 0, 0, 0, 0, 0,10,11,11,
- 0, 0, 0, 0, 0, 0, 9,11, 9, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,
- };
-
- static float _vq_quantthresh__44cn1_s_p1_0[] = {
- -0.5, 0.5,
- };
-
- static long _vq_quantmap__44cn1_s_p1_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__44cn1_s_p1_0 = {
- _vq_quantthresh__44cn1_s_p1_0,
- _vq_quantmap__44cn1_s_p1_0,
- 3,
- 3
- };
-
- static static_codebook _44cn1_s_p1_0 = {
- 8, 6561,
- _vq_lengthlist__44cn1_s_p1_0,
- 1, -535822336, 1611661312, 2, 0,
- _vq_quantlist__44cn1_s_p1_0,
- NULL,
- &_vq_auxt__44cn1_s_p1_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44cn1_s_p2_0[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__44cn1_s_p2_0[] = {
- 1, 4, 4, 7, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 5, 5, 7, 7, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 4, 5, 5, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 7, 9, 9,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 6, 7, 7, 9, 9, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,
- };
-
- static float _vq_quantthresh__44cn1_s_p2_0[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__44cn1_s_p2_0[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__44cn1_s_p2_0 = {
- _vq_quantthresh__44cn1_s_p2_0,
- _vq_quantmap__44cn1_s_p2_0,
- 5,
- 5
- };
-
- static static_codebook _44cn1_s_p2_0 = {
- 4, 625,
- _vq_lengthlist__44cn1_s_p2_0,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__44cn1_s_p2_0,
- NULL,
- &_vq_auxt__44cn1_s_p2_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44cn1_s_p3_0[] = {
- 4,
- 3,
- 5,
- 2,
- 6,
- 1,
- 7,
- 0,
- 8,
- };
-
- static long _vq_lengthlist__44cn1_s_p3_0[] = {
- 1, 2, 3, 7, 7, 0, 0, 0, 0, 0, 0, 0, 6, 6, 0, 0,
- 0, 0, 0, 0, 0, 6, 6, 0, 0, 0, 0, 0, 0, 0, 7, 7,
- 0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 0, 0, 0, 0, 0,
- 9, 8, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0,
- 0, 0,10,10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,
- };
-
- static float _vq_quantthresh__44cn1_s_p3_0[] = {
- -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5,
- };
-
- static long _vq_quantmap__44cn1_s_p3_0[] = {
- 7, 5, 3, 1, 0, 2, 4, 6,
- 8,
- };
-
- static encode_aux_threshmatch _vq_auxt__44cn1_s_p3_0 = {
- _vq_quantthresh__44cn1_s_p3_0,
- _vq_quantmap__44cn1_s_p3_0,
- 9,
- 9
- };
-
- static static_codebook _44cn1_s_p3_0 = {
- 2, 81,
- _vq_lengthlist__44cn1_s_p3_0,
- 1, -531628032, 1611661312, 4, 0,
- _vq_quantlist__44cn1_s_p3_0,
- NULL,
- &_vq_auxt__44cn1_s_p3_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44cn1_s_p4_0[] = {
- 4,
- 3,
- 5,
- 2,
- 6,
- 1,
- 7,
- 0,
- 8,
- };
-
- static long _vq_lengthlist__44cn1_s_p4_0[] = {
- 1, 3, 3, 6, 6, 6, 6, 8, 8, 0, 0, 0, 6, 6, 7, 7,
- 9, 9, 0, 0, 0, 6, 6, 7, 7, 9, 9, 0, 0, 0, 7, 7,
- 8, 8,10,10, 0, 0, 0, 7, 7, 8, 8,10,10, 0, 0, 0,
- 9, 9, 9, 9,10,10, 0, 0, 0, 9, 9, 9, 9,10,10, 0,
- 0, 0,10,10,10,10,11,11, 0, 0, 0, 0, 0,10,10,11,
- 11,
- };
-
- static float _vq_quantthresh__44cn1_s_p4_0[] = {
- -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5,
- };
-
- static long _vq_quantmap__44cn1_s_p4_0[] = {
- 7, 5, 3, 1, 0, 2, 4, 6,
- 8,
- };
-
- static encode_aux_threshmatch _vq_auxt__44cn1_s_p4_0 = {
- _vq_quantthresh__44cn1_s_p4_0,
- _vq_quantmap__44cn1_s_p4_0,
- 9,
- 9
- };
-
- static static_codebook _44cn1_s_p4_0 = {
- 2, 81,
- _vq_lengthlist__44cn1_s_p4_0,
- 1, -531628032, 1611661312, 4, 0,
- _vq_quantlist__44cn1_s_p4_0,
- NULL,
- &_vq_auxt__44cn1_s_p4_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44cn1_s_p5_0[] = {
- 8,
- 7,
- 9,
- 6,
- 10,
- 5,
- 11,
- 4,
- 12,
- 3,
- 13,
- 2,
- 14,
- 1,
- 15,
- 0,
- 16,
- };
-
- static long _vq_lengthlist__44cn1_s_p5_0[] = {
- 1, 4, 3, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9,10,10,10,
- 10, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10,10,10,10,
- 11,11, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10,10,10,
- 10,11,11, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10,10,
- 11,11,11,12, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10,
- 10,11,11,11,11, 0, 0, 0, 8, 8, 9, 9, 9, 9,10,10,
- 10,10,11,11,12,12, 0, 0, 0, 8, 8, 9, 9, 9, 9,10,
- 10,10,11,11,11,12,12, 0, 0, 0, 9, 9,10, 9,10,10,
- 10,10,11,11,11,11,12,12, 0, 0, 0, 0, 0, 9, 9,10,
- 10,10,10,11,11,12,12,12,12, 0, 0, 0, 0, 0, 9, 9,
- 10,10,10,11,11,11,12,12,13,13, 0, 0, 0, 0, 0, 9,
- 9,10,10,10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0,
- 10,10,11,10,11,11,11,12,13,12,13,13, 0, 0, 0, 0,
- 0, 0, 0,11,10,11,11,12,12,12,12,13,13, 0, 0, 0,
- 0, 0, 0, 0,11,11,12,12,12,12,13,13,13,14, 0, 0,
- 0, 0, 0, 0, 0,11,11,12,12,12,12,13,13,13,14, 0,
- 0, 0, 0, 0, 0, 0,12,12,12,13,13,13,13,13,14,14,
- 0, 0, 0, 0, 0, 0, 0, 0, 0,12,12,13,12,13,13,14,
- 14,
- };
-
- static float _vq_quantthresh__44cn1_s_p5_0[] = {
- -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5,
- 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5,
- };
-
- static long _vq_quantmap__44cn1_s_p5_0[] = {
- 15, 13, 11, 9, 7, 5, 3, 1,
- 0, 2, 4, 6, 8, 10, 12, 14,
- 16,
- };
-
- static encode_aux_threshmatch _vq_auxt__44cn1_s_p5_0 = {
- _vq_quantthresh__44cn1_s_p5_0,
- _vq_quantmap__44cn1_s_p5_0,
- 17,
- 17
- };
-
- static static_codebook _44cn1_s_p5_0 = {
- 2, 289,
- _vq_lengthlist__44cn1_s_p5_0,
- 1, -529530880, 1611661312, 5, 0,
- _vq_quantlist__44cn1_s_p5_0,
- NULL,
- &_vq_auxt__44cn1_s_p5_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44cn1_s_p6_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__44cn1_s_p6_0[] = {
- 1, 4, 4, 7, 6, 6, 7, 6, 6, 4, 6, 6,10, 9, 9,11,
- 9, 9, 4, 6, 6,10, 9, 9,10, 9, 9, 7,10,10,11,11,
- 11,12,11,11, 7, 9, 9,11,11,10,11,10,10, 7, 9, 9,
- 11,10,11,11,10,10, 7,10,10,11,11,11,12,11,11, 7,
- 9, 9,11,10,10,11,10,10, 7, 9, 9,11,10,10,11,10,
- 10,
- };
-
- static float _vq_quantthresh__44cn1_s_p6_0[] = {
- -5.5, 5.5,
- };
-
- static long _vq_quantmap__44cn1_s_p6_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__44cn1_s_p6_0 = {
- _vq_quantthresh__44cn1_s_p6_0,
- _vq_quantmap__44cn1_s_p6_0,
- 3,
- 3
- };
-
- static static_codebook _44cn1_s_p6_0 = {
- 4, 81,
- _vq_lengthlist__44cn1_s_p6_0,
- 1, -529137664, 1618345984, 2, 0,
- _vq_quantlist__44cn1_s_p6_0,
- NULL,
- &_vq_auxt__44cn1_s_p6_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44cn1_s_p6_1[] = {
- 5,
- 4,
- 6,
- 3,
- 7,
- 2,
- 8,
- 1,
- 9,
- 0,
- 10,
- };
-
- static long _vq_lengthlist__44cn1_s_p6_1[] = {
- 1, 4, 4, 6, 6, 7, 7, 8, 8, 8, 8,10,10,10, 7, 6,
- 8, 8, 8, 8, 8, 8,10,10,10, 7, 6, 7, 7, 8, 8, 8,
- 8,10,10,10, 7, 7, 8, 8, 8, 8, 8, 8,10,10,10, 7,
- 7, 8, 8, 8, 8, 8, 8,10,10,10, 8, 8, 8, 8, 9, 9,
- 9, 9,10,10,10, 8, 8, 8, 8, 9, 9, 9, 9,10,10,10,
- 9, 9, 9, 9, 9, 9, 9, 9,10,10,10,10,10, 9, 9, 9,
- 9, 9, 9,10,10,10,10,10, 9, 9, 9, 9, 9, 9,10,10,
- 10,10,10, 9, 9, 9, 9, 9, 9,
- };
-
- static float _vq_quantthresh__44cn1_s_p6_1[] = {
- -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5,
- 3.5, 4.5,
- };
-
- static long _vq_quantmap__44cn1_s_p6_1[] = {
- 9, 7, 5, 3, 1, 0, 2, 4,
- 6, 8, 10,
- };
-
- static encode_aux_threshmatch _vq_auxt__44cn1_s_p6_1 = {
- _vq_quantthresh__44cn1_s_p6_1,
- _vq_quantmap__44cn1_s_p6_1,
- 11,
- 11
- };
-
- static static_codebook _44cn1_s_p6_1 = {
- 2, 121,
- _vq_lengthlist__44cn1_s_p6_1,
- 1, -531365888, 1611661312, 4, 0,
- _vq_quantlist__44cn1_s_p6_1,
- NULL,
- &_vq_auxt__44cn1_s_p6_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44cn1_s_p7_0[] = {
- 6,
- 5,
- 7,
- 4,
- 8,
- 3,
- 9,
- 2,
- 10,
- 1,
- 11,
- 0,
- 12,
- };
-
- static long _vq_lengthlist__44cn1_s_p7_0[] = {
- 1, 4, 4, 6, 6, 7, 7, 8, 8, 9, 9,10,10, 6, 5, 5,
- 7, 7, 8, 8, 8, 8, 9, 9,11,11, 7, 5, 5, 7, 7, 8,
- 8, 8, 8, 9,10,11,11, 0, 8, 8, 8, 8, 9, 9, 9, 9,
- 10,10,11,11, 0, 8, 8, 8, 8, 9, 9, 9, 9,10,10,11,
- 11, 0,12,12, 9, 9, 9,10,10,10,11,11,11,12, 0,13,
- 13, 9, 9, 9, 9,10,10,11,11,11,12, 0, 0, 0,10,10,
- 10,10,11,11,12,12,12,13, 0, 0, 0,10,10,10,10,11,
- 11,12,12,13,12, 0, 0, 0,14,14,11,10,11,12,12,13,
- 13,14, 0, 0, 0,15,15,11,11,12,11,12,12,14,13, 0,
- 0, 0, 0, 0,12,12,12,12,13,13,14,14, 0, 0, 0, 0,
- 0,13,13,12,12,13,13,13,14,
- };
-
- static float _vq_quantthresh__44cn1_s_p7_0[] = {
- -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5,
- 12.5, 17.5, 22.5, 27.5,
- };
-
- static long _vq_quantmap__44cn1_s_p7_0[] = {
- 11, 9, 7, 5, 3, 1, 0, 2,
- 4, 6, 8, 10, 12,
- };
-
- static encode_aux_threshmatch _vq_auxt__44cn1_s_p7_0 = {
- _vq_quantthresh__44cn1_s_p7_0,
- _vq_quantmap__44cn1_s_p7_0,
- 13,
- 13
- };
-
- static static_codebook _44cn1_s_p7_0 = {
- 2, 169,
- _vq_lengthlist__44cn1_s_p7_0,
- 1, -526516224, 1616117760, 4, 0,
- _vq_quantlist__44cn1_s_p7_0,
- NULL,
- &_vq_auxt__44cn1_s_p7_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44cn1_s_p7_1[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__44cn1_s_p7_1[] = {
- 2, 3, 3, 5, 5, 6, 6, 6, 5, 5, 6, 6, 6, 5, 5, 6,
- 6, 6, 5, 5, 6, 6, 6, 5, 5,
- };
-
- static float _vq_quantthresh__44cn1_s_p7_1[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__44cn1_s_p7_1[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__44cn1_s_p7_1 = {
- _vq_quantthresh__44cn1_s_p7_1,
- _vq_quantmap__44cn1_s_p7_1,
- 5,
- 5
- };
-
- static static_codebook _44cn1_s_p7_1 = {
- 2, 25,
- _vq_lengthlist__44cn1_s_p7_1,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__44cn1_s_p7_1,
- NULL,
- &_vq_auxt__44cn1_s_p7_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44cn1_s_p8_0[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__44cn1_s_p8_0[] = {
- 1, 7, 7,11,11, 8,11,11,11,11, 4,11, 3,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,10,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,10,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11, 7,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,10,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,10,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11, 8,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 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,
- 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,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,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
- 12,
- };
-
- static float _vq_quantthresh__44cn1_s_p8_0[] = {
- -331.5, -110.5, 110.5, 331.5,
- };
-
- static long _vq_quantmap__44cn1_s_p8_0[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__44cn1_s_p8_0 = {
- _vq_quantthresh__44cn1_s_p8_0,
- _vq_quantmap__44cn1_s_p8_0,
- 5,
- 5
- };
-
- static static_codebook _44cn1_s_p8_0 = {
- 4, 625,
- _vq_lengthlist__44cn1_s_p8_0,
- 1, -518283264, 1627103232, 3, 0,
- _vq_quantlist__44cn1_s_p8_0,
- NULL,
- &_vq_auxt__44cn1_s_p8_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44cn1_s_p8_1[] = {
- 6,
- 5,
- 7,
- 4,
- 8,
- 3,
- 9,
- 2,
- 10,
- 1,
- 11,
- 0,
- 12,
- };
-
- static long _vq_lengthlist__44cn1_s_p8_1[] = {
- 1, 4, 4, 6, 6, 8, 8, 9,10,10,11,11,11, 6, 5, 5,
- 7, 7, 8, 8, 9,10, 9,11,11,12, 5, 5, 5, 7, 7, 8,
- 9,10,10,12,12,14,13,15, 7, 7, 8, 8, 9,10,11,11,
- 10,12,10,11,15, 7, 8, 8, 8, 9, 9,11,11,13,12,12,
- 13,15,10,10, 8, 8,10,10,12,12,11,14,10,10,15,11,
- 11, 8, 8,10,10,12,13,13,14,15,13,15,15,15,10,10,
- 10,10,12,12,13,12,13,10,15,15,15,10,10,11,10,13,
- 11,13,13,15,13,15,15,15,13,13,10,11,11,11,12,10,
- 14,11,15,15,14,14,13,10,10,12,11,13,13,14,14,15,
- 15,15,15,15,11,11,11,11,12,11,15,12,15,15,15,15,
- 15,12,12,11,11,14,12,13,14,
- };
-
- static float _vq_quantthresh__44cn1_s_p8_1[] = {
- -93.5, -76.5, -59.5, -42.5, -25.5, -8.5, 8.5, 25.5,
- 42.5, 59.5, 76.5, 93.5,
- };
-
- static long _vq_quantmap__44cn1_s_p8_1[] = {
- 11, 9, 7, 5, 3, 1, 0, 2,
- 4, 6, 8, 10, 12,
- };
-
- static encode_aux_threshmatch _vq_auxt__44cn1_s_p8_1 = {
- _vq_quantthresh__44cn1_s_p8_1,
- _vq_quantmap__44cn1_s_p8_1,
- 13,
- 13
- };
-
- static static_codebook _44cn1_s_p8_1 = {
- 2, 169,
- _vq_lengthlist__44cn1_s_p8_1,
- 1, -522616832, 1620115456, 4, 0,
- _vq_quantlist__44cn1_s_p8_1,
- NULL,
- &_vq_auxt__44cn1_s_p8_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44cn1_s_p8_2[] = {
- 8,
- 7,
- 9,
- 6,
- 10,
- 5,
- 11,
- 4,
- 12,
- 3,
- 13,
- 2,
- 14,
- 1,
- 15,
- 0,
- 16,
- };
-
- static long _vq_lengthlist__44cn1_s_p8_2[] = {
- 3, 4, 3, 6, 6, 7, 7, 8, 8, 9, 9, 9, 9, 9, 9, 9,
- 9,10,11,11, 6, 6, 7, 7, 8, 8, 9, 9, 9, 9, 9, 9,
- 9, 9,10,10,10, 6, 6, 7, 7, 8, 8, 9, 9, 9, 9, 9,
- 9, 9, 9,10,10,10, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9,
- 9, 9,10, 9,10,11,10, 7, 6, 7, 7, 8, 8, 9, 9, 9,
- 9, 9, 9, 9,10,10,10,11, 7, 7, 8, 8, 8, 8, 9, 9,
- 9, 9, 9, 9, 9, 9,10,10,10, 7, 7, 8, 8, 8, 8, 9,
- 9, 9, 9, 9, 9, 9,10,11,11,11, 8, 8, 8, 8, 8, 8,
- 9, 9, 9, 9, 9, 9, 9, 9,11,10,10,11,11, 8, 8, 8,
- 9, 9, 9, 9, 9, 9,10, 9,10,10,10,10,11,11, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,11,11,10,11,11, 9,
- 9, 9, 9, 9, 9, 9, 9, 9,10,10,10,10,11,10,11,11,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,11,10,10,11,
- 11,11,11, 9, 9, 9, 9, 9, 9, 9, 9,10,10,10,11,11,
- 10,11,11,11, 9,10,10, 9, 9, 9, 9, 9, 9, 9,10,11,
- 11,11,11,11,11, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,11,
- 11,11,11,11,11,11,10,10, 9, 9, 9, 9, 9, 9, 9, 9,
- 11,11,11,10,11,11,11,11,11, 9, 9, 9,10, 9, 9, 9,
- 9,
- };
-
- static float _vq_quantthresh__44cn1_s_p8_2[] = {
- -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5,
- 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5,
- };
-
- static long _vq_quantmap__44cn1_s_p8_2[] = {
- 15, 13, 11, 9, 7, 5, 3, 1,
- 0, 2, 4, 6, 8, 10, 12, 14,
- 16,
- };
-
- static encode_aux_threshmatch _vq_auxt__44cn1_s_p8_2 = {
- _vq_quantthresh__44cn1_s_p8_2,
- _vq_quantmap__44cn1_s_p8_2,
- 17,
- 17
- };
-
- static static_codebook _44cn1_s_p8_2 = {
- 2, 289,
- _vq_lengthlist__44cn1_s_p8_2,
- 1, -529530880, 1611661312, 5, 0,
- _vq_quantlist__44cn1_s_p8_2,
- NULL,
- &_vq_auxt__44cn1_s_p8_2,
- NULL,
- 0
- };
-
- static long _huff_lengthlist__44cn1_s_short[] = {
- 10, 9,12,15,12,13,16,14,16, 7, 1, 5,14, 7,10,13,
- 16,16, 9, 4, 6,16, 8,11,16,16,16,14, 4, 7,16, 9,
- 12,14,16,16,10, 5, 7,14, 9,12,14,15,15,13, 8, 9,
- 14,10,12,13,14,15,13, 9, 9, 7, 6, 8,11,12,12,14,
- 8, 8, 5, 4, 5, 8,11,12,16,10,10, 6, 5, 6, 8, 9,
- 10,
- };
-
- static static_codebook _huff_book__44cn1_s_short = {
- 2, 81,
- _huff_lengthlist__44cn1_s_short,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist__44cn1_sm_long[] = {
- 3, 3, 8, 8, 8, 8,10,12,14, 3, 2, 6, 7, 7, 8,10,
- 12,16, 7, 6, 7, 9, 8,10,12,14,16, 8, 6, 8, 4, 5,
- 7, 9,11,13, 7, 6, 8, 5, 6, 7, 9,11,14, 8, 8,10,
- 7, 7, 6, 8,10,13, 9,11,12, 9, 9, 7, 8,10,12,10,
- 13,15,11,11,10, 9,10,13,13,16,17,14,15,14,13,14,
- 17,
- };
-
- static static_codebook _huff_book__44cn1_sm_long = {
- 2, 81,
- _huff_lengthlist__44cn1_sm_long,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44cn1_sm_p1_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__44cn1_sm_p1_0[] = {
- 1, 4, 5, 0, 0, 0, 0, 0, 0, 5, 7, 7, 0, 0, 0, 0,
- 0, 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 5, 8, 8, 0, 0, 0, 0, 0, 0, 8, 9, 9, 0, 0, 0,
- 0, 0, 0, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 5, 8, 8, 0, 0, 0, 0, 0, 0, 7, 9, 8, 0, 0,
- 0, 0, 0, 0, 8, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 8, 8, 0, 0, 0, 0,
- 0, 0, 8,10, 9, 0, 0, 0, 0, 0, 0, 8, 9, 9, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7,10, 9, 0, 0, 0,
- 0, 0, 0, 9, 9,10, 0, 0, 0, 0, 0, 0, 9,10,10, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0,
- 0, 0, 0, 0, 8,10, 9, 0, 0, 0, 0, 0, 0, 9,10,10,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 5, 8, 8, 0, 0, 0, 0, 0, 0, 8, 9, 9, 0, 0,
- 0, 0, 0, 0, 8, 9,10, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 9,10,10, 0,
- 0, 0, 0, 0, 0, 8, 9,10, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 7, 9,10, 0, 0, 0, 0, 0, 0, 9,10,10,
- 0, 0, 0, 0, 0, 0, 9,10, 9, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,
- };
-
- static float _vq_quantthresh__44cn1_sm_p1_0[] = {
- -0.5, 0.5,
- };
-
- static long _vq_quantmap__44cn1_sm_p1_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__44cn1_sm_p1_0 = {
- _vq_quantthresh__44cn1_sm_p1_0,
- _vq_quantmap__44cn1_sm_p1_0,
- 3,
- 3
- };
-
- static static_codebook _44cn1_sm_p1_0 = {
- 8, 6561,
- _vq_lengthlist__44cn1_sm_p1_0,
- 1, -535822336, 1611661312, 2, 0,
- _vq_quantlist__44cn1_sm_p1_0,
- NULL,
- &_vq_auxt__44cn1_sm_p1_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44cn1_sm_p2_0[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__44cn1_sm_p2_0[] = {
- 1, 4, 4, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 5, 5, 7, 7, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 4, 5, 5, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 7, 9, 9,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 7, 7, 7, 9, 9, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,
- };
-
- static float _vq_quantthresh__44cn1_sm_p2_0[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__44cn1_sm_p2_0[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__44cn1_sm_p2_0 = {
- _vq_quantthresh__44cn1_sm_p2_0,
- _vq_quantmap__44cn1_sm_p2_0,
- 5,
- 5
- };
-
- static static_codebook _44cn1_sm_p2_0 = {
- 4, 625,
- _vq_lengthlist__44cn1_sm_p2_0,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__44cn1_sm_p2_0,
- NULL,
- &_vq_auxt__44cn1_sm_p2_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44cn1_sm_p3_0[] = {
- 4,
- 3,
- 5,
- 2,
- 6,
- 1,
- 7,
- 0,
- 8,
- };
-
- static long _vq_lengthlist__44cn1_sm_p3_0[] = {
- 1, 3, 4, 7, 7, 0, 0, 0, 0, 0, 4, 4, 7, 7, 0, 0,
- 0, 0, 0, 4, 5, 7, 7, 0, 0, 0, 0, 0, 6, 7, 8, 8,
- 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0,
- 9, 9, 0, 0, 0, 0, 0, 0, 0,10, 9, 0, 0, 0, 0, 0,
- 0, 0,11,11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,
- };
-
- static float _vq_quantthresh__44cn1_sm_p3_0[] = {
- -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5,
- };
-
- static long _vq_quantmap__44cn1_sm_p3_0[] = {
- 7, 5, 3, 1, 0, 2, 4, 6,
- 8,
- };
-
- static encode_aux_threshmatch _vq_auxt__44cn1_sm_p3_0 = {
- _vq_quantthresh__44cn1_sm_p3_0,
- _vq_quantmap__44cn1_sm_p3_0,
- 9,
- 9
- };
-
- static static_codebook _44cn1_sm_p3_0 = {
- 2, 81,
- _vq_lengthlist__44cn1_sm_p3_0,
- 1, -531628032, 1611661312, 4, 0,
- _vq_quantlist__44cn1_sm_p3_0,
- NULL,
- &_vq_auxt__44cn1_sm_p3_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44cn1_sm_p4_0[] = {
- 4,
- 3,
- 5,
- 2,
- 6,
- 1,
- 7,
- 0,
- 8,
- };
-
- static long _vq_lengthlist__44cn1_sm_p4_0[] = {
- 1, 4, 3, 6, 6, 7, 7, 9, 9, 0, 5, 5, 7, 7, 8, 7,
- 9, 9, 0, 5, 5, 7, 7, 8, 8, 9, 9, 0, 7, 7, 8, 8,
- 8, 8,10,10, 0, 0, 0, 8, 8, 8, 8,10,10, 0, 0, 0,
- 9, 9, 9, 9,10,10, 0, 0, 0, 9, 9, 9, 9,10,10, 0,
- 0, 0,10,10,10,10,11,11, 0, 0, 0, 0, 0,10,10,11,
- 11,
- };
-
- static float _vq_quantthresh__44cn1_sm_p4_0[] = {
- -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5,
- };
-
- static long _vq_quantmap__44cn1_sm_p4_0[] = {
- 7, 5, 3, 1, 0, 2, 4, 6,
- 8,
- };
-
- static encode_aux_threshmatch _vq_auxt__44cn1_sm_p4_0 = {
- _vq_quantthresh__44cn1_sm_p4_0,
- _vq_quantmap__44cn1_sm_p4_0,
- 9,
- 9
- };
-
- static static_codebook _44cn1_sm_p4_0 = {
- 2, 81,
- _vq_lengthlist__44cn1_sm_p4_0,
- 1, -531628032, 1611661312, 4, 0,
- _vq_quantlist__44cn1_sm_p4_0,
- NULL,
- &_vq_auxt__44cn1_sm_p4_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44cn1_sm_p5_0[] = {
- 8,
- 7,
- 9,
- 6,
- 10,
- 5,
- 11,
- 4,
- 12,
- 3,
- 13,
- 2,
- 14,
- 1,
- 15,
- 0,
- 16,
- };
-
- static long _vq_lengthlist__44cn1_sm_p5_0[] = {
- 1, 4, 4, 6, 6, 8, 8, 9, 9, 8, 8, 9, 9,10,10,11,
- 11, 0, 6, 6, 7, 7, 8, 8, 9, 9, 9, 9,10,10,11,11,
- 12,12, 0, 6, 5, 7, 7, 8, 8, 9, 9, 9, 9,10,10,11,
- 11,12,12, 0, 7, 7, 7, 7, 8, 8, 9, 9, 9, 9,10,10,
- 11,11,12,12, 0, 0, 0, 7, 7, 8, 8, 9, 9,10,10,11,
- 11,11,11,12,12, 0, 0, 0, 8, 8, 9, 9,10,10,10,10,
- 11,11,12,12,12,12, 0, 0, 0, 8, 8, 9, 9,10,10,10,
- 10,11,11,12,12,12,12, 0, 0, 0, 9, 9, 9, 9,10,10,
- 10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, 9, 9,10,
- 10,10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, 9, 9,
- 10,10,11,11,12,12,13,13,13,13, 0, 0, 0, 0, 0, 9,
- 9,10,10,11,11,12,12,12,13,13,13, 0, 0, 0, 0, 0,
- 10,10,11,11,11,11,12,12,13,13,14,14, 0, 0, 0, 0,
- 0, 0, 0,11,11,11,11,12,12,13,13,14,14, 0, 0, 0,
- 0, 0, 0, 0,11,11,12,12,13,13,13,13,14,14, 0, 0,
- 0, 0, 0, 0, 0,11,11,12,12,13,13,13,13,14,14, 0,
- 0, 0, 0, 0, 0, 0,12,12,12,13,13,13,14,14,14,14,
- 0, 0, 0, 0, 0, 0, 0, 0, 0,12,12,13,13,14,14,14,
- 14,
- };
-
- static float _vq_quantthresh__44cn1_sm_p5_0[] = {
- -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5,
- 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5,
- };
-
- static long _vq_quantmap__44cn1_sm_p5_0[] = {
- 15, 13, 11, 9, 7, 5, 3, 1,
- 0, 2, 4, 6, 8, 10, 12, 14,
- 16,
- };
-
- static encode_aux_threshmatch _vq_auxt__44cn1_sm_p5_0 = {
- _vq_quantthresh__44cn1_sm_p5_0,
- _vq_quantmap__44cn1_sm_p5_0,
- 17,
- 17
- };
-
- static static_codebook _44cn1_sm_p5_0 = {
- 2, 289,
- _vq_lengthlist__44cn1_sm_p5_0,
- 1, -529530880, 1611661312, 5, 0,
- _vq_quantlist__44cn1_sm_p5_0,
- NULL,
- &_vq_auxt__44cn1_sm_p5_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44cn1_sm_p6_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__44cn1_sm_p6_0[] = {
- 1, 4, 4, 7, 6, 6, 7, 6, 6, 4, 7, 6,10, 9, 9,11,
- 9, 9, 4, 6, 7,10, 9, 9,11, 9, 9, 7,10,10,10,11,
- 11,11,11,10, 6, 9, 9,11,10,10,11,10,10, 6, 9, 9,
- 11,10,11,11,10,10, 7,11,11,11,11,11,12,11,11, 7,
- 9, 9,11,10,10,12,10,10, 7, 9, 9,11,10,10,11,10,
- 10,
- };
-
- static float _vq_quantthresh__44cn1_sm_p6_0[] = {
- -5.5, 5.5,
- };
-
- static long _vq_quantmap__44cn1_sm_p6_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__44cn1_sm_p6_0 = {
- _vq_quantthresh__44cn1_sm_p6_0,
- _vq_quantmap__44cn1_sm_p6_0,
- 3,
- 3
- };
-
- static static_codebook _44cn1_sm_p6_0 = {
- 4, 81,
- _vq_lengthlist__44cn1_sm_p6_0,
- 1, -529137664, 1618345984, 2, 0,
- _vq_quantlist__44cn1_sm_p6_0,
- NULL,
- &_vq_auxt__44cn1_sm_p6_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44cn1_sm_p6_1[] = {
- 5,
- 4,
- 6,
- 3,
- 7,
- 2,
- 8,
- 1,
- 9,
- 0,
- 10,
- };
-
- static long _vq_lengthlist__44cn1_sm_p6_1[] = {
- 2, 4, 4, 5, 5, 7, 7, 7, 7, 8, 8,10, 5, 5, 6, 6,
- 7, 7, 8, 8, 8, 8,10, 5, 5, 6, 6, 7, 7, 8, 8, 8,
- 8,10, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8,10,10,10, 7,
- 7, 7, 7, 8, 8, 8, 8,10,10,10, 8, 8, 8, 8, 8, 8,
- 8, 8,10,10,10, 8, 8, 8, 8, 8, 8, 8, 8,10,10,10,
- 8, 8, 8, 8, 8, 8, 9, 9,10,10,10,10,10, 8, 8, 8,
- 8, 9, 9,10,10,10,10,10, 9, 9, 9, 9, 8, 9,10,10,
- 10,10,10, 8, 9, 8, 8, 9, 8,
- };
-
- static float _vq_quantthresh__44cn1_sm_p6_1[] = {
- -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5,
- 3.5, 4.5,
- };
-
- static long _vq_quantmap__44cn1_sm_p6_1[] = {
- 9, 7, 5, 3, 1, 0, 2, 4,
- 6, 8, 10,
- };
-
- static encode_aux_threshmatch _vq_auxt__44cn1_sm_p6_1 = {
- _vq_quantthresh__44cn1_sm_p6_1,
- _vq_quantmap__44cn1_sm_p6_1,
- 11,
- 11
- };
-
- static static_codebook _44cn1_sm_p6_1 = {
- 2, 121,
- _vq_lengthlist__44cn1_sm_p6_1,
- 1, -531365888, 1611661312, 4, 0,
- _vq_quantlist__44cn1_sm_p6_1,
- NULL,
- &_vq_auxt__44cn1_sm_p6_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44cn1_sm_p7_0[] = {
- 6,
- 5,
- 7,
- 4,
- 8,
- 3,
- 9,
- 2,
- 10,
- 1,
- 11,
- 0,
- 12,
- };
-
- static long _vq_lengthlist__44cn1_sm_p7_0[] = {
- 1, 4, 4, 6, 6, 7, 7, 7, 7, 9, 9,10,10, 7, 5, 5,
- 7, 7, 8, 8, 8, 8,10, 9,11,10, 7, 5, 5, 7, 7, 8,
- 8, 8, 8, 9,10,11,11, 0, 8, 8, 8, 8, 9, 9, 9, 9,
- 10,10,11,11, 0, 8, 8, 8, 8, 9, 9, 9, 9,10,10,11,
- 11, 0,12,12, 9, 9, 9,10,10,10,11,11,12,12, 0,13,
- 13, 9, 9, 9, 9,10,10,11,11,12,12, 0, 0, 0,10,10,
- 10,10,11,11,12,12,12,13, 0, 0, 0,10,10,10,10,11,
- 11,12,12,12,12, 0, 0, 0,14,14,11,11,11,11,12,13,
- 13,13, 0, 0, 0,14,14,11,10,11,11,12,12,13,13, 0,
- 0, 0, 0, 0,12,12,12,12,13,13,13,14, 0, 0, 0, 0,
- 0,13,12,12,12,13,13,13,14,
- };
-
- static float _vq_quantthresh__44cn1_sm_p7_0[] = {
- -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5,
- 12.5, 17.5, 22.5, 27.5,
- };
-
- static long _vq_quantmap__44cn1_sm_p7_0[] = {
- 11, 9, 7, 5, 3, 1, 0, 2,
- 4, 6, 8, 10, 12,
- };
-
- static encode_aux_threshmatch _vq_auxt__44cn1_sm_p7_0 = {
- _vq_quantthresh__44cn1_sm_p7_0,
- _vq_quantmap__44cn1_sm_p7_0,
- 13,
- 13
- };
-
- static static_codebook _44cn1_sm_p7_0 = {
- 2, 169,
- _vq_lengthlist__44cn1_sm_p7_0,
- 1, -526516224, 1616117760, 4, 0,
- _vq_quantlist__44cn1_sm_p7_0,
- NULL,
- &_vq_auxt__44cn1_sm_p7_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44cn1_sm_p7_1[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__44cn1_sm_p7_1[] = {
- 2, 4, 4, 4, 5, 6, 5, 5, 5, 5, 6, 5, 5, 5, 5, 6,
- 5, 5, 5, 5, 6, 6, 6, 5, 5,
- };
-
- static float _vq_quantthresh__44cn1_sm_p7_1[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__44cn1_sm_p7_1[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__44cn1_sm_p7_1 = {
- _vq_quantthresh__44cn1_sm_p7_1,
- _vq_quantmap__44cn1_sm_p7_1,
- 5,
- 5
- };
-
- static static_codebook _44cn1_sm_p7_1 = {
- 2, 25,
- _vq_lengthlist__44cn1_sm_p7_1,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__44cn1_sm_p7_1,
- NULL,
- &_vq_auxt__44cn1_sm_p7_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44cn1_sm_p8_0[] = {
- 4,
- 3,
- 5,
- 2,
- 6,
- 1,
- 7,
- 0,
- 8,
- };
-
- static long _vq_lengthlist__44cn1_sm_p8_0[] = {
- 1, 4, 4,12,11,13,13,14,14, 4, 7, 7,11,13,14,14,
- 14,14, 3, 8, 3,14,14,14,14,14,14,14,10,12,14,14,
- 14,14,14,14,14,14, 5,14, 8,14,14,14,14,14,12,14,
- 13,14,14,14,14,14,14,14,13,14,10,14,14,14,14,14,
- 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,
- 14,
- };
-
- static float _vq_quantthresh__44cn1_sm_p8_0[] = {
- -773.5, -552.5, -331.5, -110.5, 110.5, 331.5, 552.5, 773.5,
- };
-
- static long _vq_quantmap__44cn1_sm_p8_0[] = {
- 7, 5, 3, 1, 0, 2, 4, 6,
- 8,
- };
-
- static encode_aux_threshmatch _vq_auxt__44cn1_sm_p8_0 = {
- _vq_quantthresh__44cn1_sm_p8_0,
- _vq_quantmap__44cn1_sm_p8_0,
- 9,
- 9
- };
-
- static static_codebook _44cn1_sm_p8_0 = {
- 2, 81,
- _vq_lengthlist__44cn1_sm_p8_0,
- 1, -516186112, 1627103232, 4, 0,
- _vq_quantlist__44cn1_sm_p8_0,
- NULL,
- &_vq_auxt__44cn1_sm_p8_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44cn1_sm_p8_1[] = {
- 6,
- 5,
- 7,
- 4,
- 8,
- 3,
- 9,
- 2,
- 10,
- 1,
- 11,
- 0,
- 12,
- };
-
- static long _vq_lengthlist__44cn1_sm_p8_1[] = {
- 1, 4, 4, 6, 6, 8, 8, 9, 9,10,11,11,11, 6, 5, 5,
- 7, 7, 8, 8,10,10,10,11,11,11, 6, 5, 5, 7, 7, 8,
- 8,10,10,11,12,12,12,14, 7, 7, 7, 8, 9, 9,11,11,
- 11,12,11,12,17, 7, 7, 8, 7, 9, 9,11,11,12,12,12,
- 12,14,11,11, 8, 8,10,10,11,12,12,13,11,12,14,11,
- 11, 8, 8,10,10,11,12,12,13,13,12,14,15,14,10,10,
- 10,10,11,12,12,12,12,11,14,13,16,10,10,10, 9,12,
- 11,12,12,13,14,14,15,14,14,13,10,10,11,11,12,11,
- 13,11,14,12,15,13,14,11,10,12,10,12,12,13,13,13,
- 13,14,15,15,12,12,11,11,12,11,13,12,14,14,14,14,
- 17,12,12,11,10,13,11,13,13,
- };
-
- static float _vq_quantthresh__44cn1_sm_p8_1[] = {
- -93.5, -76.5, -59.5, -42.5, -25.5, -8.5, 8.5, 25.5,
- 42.5, 59.5, 76.5, 93.5,
- };
-
- static long _vq_quantmap__44cn1_sm_p8_1[] = {
- 11, 9, 7, 5, 3, 1, 0, 2,
- 4, 6, 8, 10, 12,
- };
-
- static encode_aux_threshmatch _vq_auxt__44cn1_sm_p8_1 = {
- _vq_quantthresh__44cn1_sm_p8_1,
- _vq_quantmap__44cn1_sm_p8_1,
- 13,
- 13
- };
-
- static static_codebook _44cn1_sm_p8_1 = {
- 2, 169,
- _vq_lengthlist__44cn1_sm_p8_1,
- 1, -522616832, 1620115456, 4, 0,
- _vq_quantlist__44cn1_sm_p8_1,
- NULL,
- &_vq_auxt__44cn1_sm_p8_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44cn1_sm_p8_2[] = {
- 8,
- 7,
- 9,
- 6,
- 10,
- 5,
- 11,
- 4,
- 12,
- 3,
- 13,
- 2,
- 14,
- 1,
- 15,
- 0,
- 16,
- };
-
- static long _vq_lengthlist__44cn1_sm_p8_2[] = {
- 3, 4, 4, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9,
- 9,10, 6, 6, 6, 6, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9,
- 9, 9,10, 6, 6, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9, 9,
- 9, 9, 9,10, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9,
- 9, 9, 9, 9,10,10,10, 7, 7, 7, 8, 8, 8, 9, 9, 9,
- 9, 9, 9, 9, 9,10,10,10, 8, 8, 8, 8, 8, 8, 9, 9,
- 9, 9, 9, 9, 9, 9,10,10,10, 8, 8, 8, 8, 8, 8, 9,
- 9, 9, 9, 9, 9, 9, 9,11,10,11, 8, 8, 8, 8, 8, 8,
- 9, 9, 9, 9, 9, 9, 9, 9,10,10,10,11,11, 8, 8, 8,
- 8, 9, 9, 9, 9, 9, 9, 9, 9,11,10,11,11,11, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10,11,10,11,11, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10,11,11,10,11,11,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,11,10,11,11,
- 11,11,11, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10,11,11,
- 11,11,11,11, 9,10,10,10, 9, 9, 9, 9, 9, 9,11,10,
- 11,11,11,11,11, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,11,
- 11,11,11,11,11,11,10,10, 9, 9, 9, 9, 9, 9, 9, 9,
- 10,11,11,11,11,11,11,11,11, 9, 9, 9, 9, 9, 9, 9,
- 9,
- };
-
- static float _vq_quantthresh__44cn1_sm_p8_2[] = {
- -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5,
- 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5,
- };
-
- static long _vq_quantmap__44cn1_sm_p8_2[] = {
- 15, 13, 11, 9, 7, 5, 3, 1,
- 0, 2, 4, 6, 8, 10, 12, 14,
- 16,
- };
-
- static encode_aux_threshmatch _vq_auxt__44cn1_sm_p8_2 = {
- _vq_quantthresh__44cn1_sm_p8_2,
- _vq_quantmap__44cn1_sm_p8_2,
- 17,
- 17
- };
-
- static static_codebook _44cn1_sm_p8_2 = {
- 2, 289,
- _vq_lengthlist__44cn1_sm_p8_2,
- 1, -529530880, 1611661312, 5, 0,
- _vq_quantlist__44cn1_sm_p8_2,
- NULL,
- &_vq_auxt__44cn1_sm_p8_2,
- NULL,
- 0
- };
-
- static long _huff_lengthlist__44cn1_sm_short[] = {
- 5, 6,12,14,12,14,16,17,18, 4, 2, 5,11, 7,10,12,
- 14,15, 9, 4, 5,11, 7,10,13,15,18,15, 6, 7, 5, 6,
- 8,11,13,16,11, 5, 6, 5, 5, 6, 9,13,15,12, 5, 7,
- 6, 5, 6, 9,12,14,12, 6, 7, 8, 6, 7, 9,12,13,14,
- 8, 8, 7, 5, 5, 8,10,12,16, 9, 9, 8, 6, 6, 7, 9,
- 9,
- };
-
- static static_codebook _huff_book__44cn1_sm_short = {
- 2, 81,
- _huff_lengthlist__44cn1_sm_short,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
- /********* End of inlined file: res_books_stereo.h *********/
-
- /***** residue backends *********************************************/
-
- static vorbis_info_residue0 _residue_44_low={
- 0,-1, -1, 9,-1,
- /* 0 1 2 3 4 5 6 7 */
- {0},
- {-1},
- { .5, 1.5, 2.5, 2.5, 4.5, 8.5, 16.5, 32.5},
- { .5, .5, .5, 999., 4.5, 8.5, 16.5, 32.5},
- };
-
- static vorbis_info_residue0 _residue_44_mid={
- 0,-1, -1, 10,-1,
- /* 0 1 2 3 4 5 6 7 8 */
- {0},
- {-1},
- { .5, 1.5, 1.5, 2.5, 2.5, 4.5, 8.5, 16.5, 32.5},
- { .5, .5, 999., .5, 999., 4.5, 8.5, 16.5, 32.5},
- };
-
- static vorbis_info_residue0 _residue_44_high={
- 0,-1, -1, 10,-1,
- /* 0 1 2 3 4 5 6 7 8 */
- {0},
- {-1},
- { .5, 1.5, 2.5, 4.5, 8.5, 16.5, 32.5, 71.5,157.5},
- { .5, 1.5, 2.5, 3.5, 4.5, 8.5, 16.5, 71.5,157.5},
- };
-
- static static_bookblock _resbook_44s_n1={
- {
- {0},{0,0,&_44cn1_s_p1_0},{0,0,&_44cn1_s_p2_0},
- {0,0,&_44cn1_s_p3_0},{0,0,&_44cn1_s_p4_0},{0,0,&_44cn1_s_p5_0},
- {&_44cn1_s_p6_0,&_44cn1_s_p6_1},{&_44cn1_s_p7_0,&_44cn1_s_p7_1},
- {&_44cn1_s_p8_0,&_44cn1_s_p8_1,&_44cn1_s_p8_2}
- }
- };
- static static_bookblock _resbook_44sm_n1={
- {
- {0},{0,0,&_44cn1_sm_p1_0},{0,0,&_44cn1_sm_p2_0},
- {0,0,&_44cn1_sm_p3_0},{0,0,&_44cn1_sm_p4_0},{0,0,&_44cn1_sm_p5_0},
- {&_44cn1_sm_p6_0,&_44cn1_sm_p6_1},{&_44cn1_sm_p7_0,&_44cn1_sm_p7_1},
- {&_44cn1_sm_p8_0,&_44cn1_sm_p8_1,&_44cn1_sm_p8_2}
- }
- };
-
- static static_bookblock _resbook_44s_0={
- {
- {0},{0,0,&_44c0_s_p1_0},{0,0,&_44c0_s_p2_0},
- {0,0,&_44c0_s_p3_0},{0,0,&_44c0_s_p4_0},{0,0,&_44c0_s_p5_0},
- {&_44c0_s_p6_0,&_44c0_s_p6_1},{&_44c0_s_p7_0,&_44c0_s_p7_1},
- {&_44c0_s_p8_0,&_44c0_s_p8_1,&_44c0_s_p8_2}
- }
- };
- static static_bookblock _resbook_44sm_0={
- {
- {0},{0,0,&_44c0_sm_p1_0},{0,0,&_44c0_sm_p2_0},
- {0,0,&_44c0_sm_p3_0},{0,0,&_44c0_sm_p4_0},{0,0,&_44c0_sm_p5_0},
- {&_44c0_sm_p6_0,&_44c0_sm_p6_1},{&_44c0_sm_p7_0,&_44c0_sm_p7_1},
- {&_44c0_sm_p8_0,&_44c0_sm_p8_1,&_44c0_sm_p8_2}
- }
- };
-
- static static_bookblock _resbook_44s_1={
- {
- {0},{0,0,&_44c1_s_p1_0},{0,0,&_44c1_s_p2_0},
- {0,0,&_44c1_s_p3_0},{0,0,&_44c1_s_p4_0},{0,0,&_44c1_s_p5_0},
- {&_44c1_s_p6_0,&_44c1_s_p6_1},{&_44c1_s_p7_0,&_44c1_s_p7_1},
- {&_44c1_s_p8_0,&_44c1_s_p8_1,&_44c1_s_p8_2}
- }
- };
- static static_bookblock _resbook_44sm_1={
- {
- {0},{0,0,&_44c1_sm_p1_0},{0,0,&_44c1_sm_p2_0},
- {0,0,&_44c1_sm_p3_0},{0,0,&_44c1_sm_p4_0},{0,0,&_44c1_sm_p5_0},
- {&_44c1_sm_p6_0,&_44c1_sm_p6_1},{&_44c1_sm_p7_0,&_44c1_sm_p7_1},
- {&_44c1_sm_p8_0,&_44c1_sm_p8_1,&_44c1_sm_p8_2}
- }
- };
-
- static static_bookblock _resbook_44s_2={
- {
- {0},{0,0,&_44c2_s_p1_0},{0,0,&_44c2_s_p2_0},{0,0,&_44c2_s_p3_0},
- {0,0,&_44c2_s_p4_0},{0,0,&_44c2_s_p5_0},{0,0,&_44c2_s_p6_0},
- {&_44c2_s_p7_0,&_44c2_s_p7_1},{&_44c2_s_p8_0,&_44c2_s_p8_1},
- {&_44c2_s_p9_0,&_44c2_s_p9_1,&_44c2_s_p9_2}
- }
- };
- static static_bookblock _resbook_44s_3={
- {
- {0},{0,0,&_44c3_s_p1_0},{0,0,&_44c3_s_p2_0},{0,0,&_44c3_s_p3_0},
- {0,0,&_44c3_s_p4_0},{0,0,&_44c3_s_p5_0},{0,0,&_44c3_s_p6_0},
- {&_44c3_s_p7_0,&_44c3_s_p7_1},{&_44c3_s_p8_0,&_44c3_s_p8_1},
- {&_44c3_s_p9_0,&_44c3_s_p9_1,&_44c3_s_p9_2}
- }
- };
- static static_bookblock _resbook_44s_4={
- {
- {0},{0,0,&_44c4_s_p1_0},{0,0,&_44c4_s_p2_0},{0,0,&_44c4_s_p3_0},
- {0,0,&_44c4_s_p4_0},{0,0,&_44c4_s_p5_0},{0,0,&_44c4_s_p6_0},
- {&_44c4_s_p7_0,&_44c4_s_p7_1},{&_44c4_s_p8_0,&_44c4_s_p8_1},
- {&_44c4_s_p9_0,&_44c4_s_p9_1,&_44c4_s_p9_2}
- }
- };
- static static_bookblock _resbook_44s_5={
- {
- {0},{0,0,&_44c5_s_p1_0},{0,0,&_44c5_s_p2_0},{0,0,&_44c5_s_p3_0},
- {0,0,&_44c5_s_p4_0},{0,0,&_44c5_s_p5_0},{0,0,&_44c5_s_p6_0},
- {&_44c5_s_p7_0,&_44c5_s_p7_1},{&_44c5_s_p8_0,&_44c5_s_p8_1},
- {&_44c5_s_p9_0,&_44c5_s_p9_1,&_44c5_s_p9_2}
- }
- };
- static static_bookblock _resbook_44s_6={
- {
- {0},{0,0,&_44c6_s_p1_0},{0,0,&_44c6_s_p2_0},{0,0,&_44c6_s_p3_0},
- {0,0,&_44c6_s_p4_0},
- {&_44c6_s_p5_0,&_44c6_s_p5_1},
- {&_44c6_s_p6_0,&_44c6_s_p6_1},
- {&_44c6_s_p7_0,&_44c6_s_p7_1},
- {&_44c6_s_p8_0,&_44c6_s_p8_1},
- {&_44c6_s_p9_0,&_44c6_s_p9_1,&_44c6_s_p9_2}
- }
- };
- static static_bookblock _resbook_44s_7={
- {
- {0},{0,0,&_44c7_s_p1_0},{0,0,&_44c7_s_p2_0},{0,0,&_44c7_s_p3_0},
- {0,0,&_44c7_s_p4_0},
- {&_44c7_s_p5_0,&_44c7_s_p5_1},
- {&_44c7_s_p6_0,&_44c7_s_p6_1},
- {&_44c7_s_p7_0,&_44c7_s_p7_1},
- {&_44c7_s_p8_0,&_44c7_s_p8_1},
- {&_44c7_s_p9_0,&_44c7_s_p9_1,&_44c7_s_p9_2}
- }
- };
- static static_bookblock _resbook_44s_8={
- {
- {0},{0,0,&_44c8_s_p1_0},{0,0,&_44c8_s_p2_0},{0,0,&_44c8_s_p3_0},
- {0,0,&_44c8_s_p4_0},
- {&_44c8_s_p5_0,&_44c8_s_p5_1},
- {&_44c8_s_p6_0,&_44c8_s_p6_1},
- {&_44c8_s_p7_0,&_44c8_s_p7_1},
- {&_44c8_s_p8_0,&_44c8_s_p8_1},
- {&_44c8_s_p9_0,&_44c8_s_p9_1,&_44c8_s_p9_2}
- }
- };
- static static_bookblock _resbook_44s_9={
- {
- {0},{0,0,&_44c9_s_p1_0},{0,0,&_44c9_s_p2_0},{0,0,&_44c9_s_p3_0},
- {0,0,&_44c9_s_p4_0},
- {&_44c9_s_p5_0,&_44c9_s_p5_1},
- {&_44c9_s_p6_0,&_44c9_s_p6_1},
- {&_44c9_s_p7_0,&_44c9_s_p7_1},
- {&_44c9_s_p8_0,&_44c9_s_p8_1},
- {&_44c9_s_p9_0,&_44c9_s_p9_1,&_44c9_s_p9_2}
- }
- };
-
- static vorbis_residue_template _res_44s_n1[]={
- {2,0, &_residue_44_low,
- &_huff_book__44cn1_s_short,&_huff_book__44cn1_sm_short,
- &_resbook_44s_n1,&_resbook_44sm_n1},
-
- {2,0, &_residue_44_low,
- &_huff_book__44cn1_s_long,&_huff_book__44cn1_sm_long,
- &_resbook_44s_n1,&_resbook_44sm_n1}
- };
- static vorbis_residue_template _res_44s_0[]={
- {2,0, &_residue_44_low,
- &_huff_book__44c0_s_short,&_huff_book__44c0_sm_short,
- &_resbook_44s_0,&_resbook_44sm_0},
-
- {2,0, &_residue_44_low,
- &_huff_book__44c0_s_long,&_huff_book__44c0_sm_long,
- &_resbook_44s_0,&_resbook_44sm_0}
- };
- static vorbis_residue_template _res_44s_1[]={
- {2,0, &_residue_44_low,
- &_huff_book__44c1_s_short,&_huff_book__44c1_sm_short,
- &_resbook_44s_1,&_resbook_44sm_1},
-
- {2,0, &_residue_44_low,
- &_huff_book__44c1_s_long,&_huff_book__44c1_sm_long,
- &_resbook_44s_1,&_resbook_44sm_1}
- };
-
- static vorbis_residue_template _res_44s_2[]={
- {2,0, &_residue_44_mid,
- &_huff_book__44c2_s_short,&_huff_book__44c2_s_short,
- &_resbook_44s_2,&_resbook_44s_2},
-
- {2,0, &_residue_44_mid,
- &_huff_book__44c2_s_long,&_huff_book__44c2_s_long,
- &_resbook_44s_2,&_resbook_44s_2}
- };
- static vorbis_residue_template _res_44s_3[]={
- {2,0, &_residue_44_mid,
- &_huff_book__44c3_s_short,&_huff_book__44c3_s_short,
- &_resbook_44s_3,&_resbook_44s_3},
-
- {2,0, &_residue_44_mid,
- &_huff_book__44c3_s_long,&_huff_book__44c3_s_long,
- &_resbook_44s_3,&_resbook_44s_3}
- };
- static vorbis_residue_template _res_44s_4[]={
- {2,0, &_residue_44_mid,
- &_huff_book__44c4_s_short,&_huff_book__44c4_s_short,
- &_resbook_44s_4,&_resbook_44s_4},
-
- {2,0, &_residue_44_mid,
- &_huff_book__44c4_s_long,&_huff_book__44c4_s_long,
- &_resbook_44s_4,&_resbook_44s_4}
- };
- static vorbis_residue_template _res_44s_5[]={
- {2,0, &_residue_44_mid,
- &_huff_book__44c5_s_short,&_huff_book__44c5_s_short,
- &_resbook_44s_5,&_resbook_44s_5},
-
- {2,0, &_residue_44_mid,
- &_huff_book__44c5_s_long,&_huff_book__44c5_s_long,
- &_resbook_44s_5,&_resbook_44s_5}
- };
- static vorbis_residue_template _res_44s_6[]={
- {2,0, &_residue_44_high,
- &_huff_book__44c6_s_short,&_huff_book__44c6_s_short,
- &_resbook_44s_6,&_resbook_44s_6},
-
- {2,0, &_residue_44_high,
- &_huff_book__44c6_s_long,&_huff_book__44c6_s_long,
- &_resbook_44s_6,&_resbook_44s_6}
- };
- static vorbis_residue_template _res_44s_7[]={
- {2,0, &_residue_44_high,
- &_huff_book__44c7_s_short,&_huff_book__44c7_s_short,
- &_resbook_44s_7,&_resbook_44s_7},
-
- {2,0, &_residue_44_high,
- &_huff_book__44c7_s_long,&_huff_book__44c7_s_long,
- &_resbook_44s_7,&_resbook_44s_7}
- };
- static vorbis_residue_template _res_44s_8[]={
- {2,0, &_residue_44_high,
- &_huff_book__44c8_s_short,&_huff_book__44c8_s_short,
- &_resbook_44s_8,&_resbook_44s_8},
-
- {2,0, &_residue_44_high,
- &_huff_book__44c8_s_long,&_huff_book__44c8_s_long,
- &_resbook_44s_8,&_resbook_44s_8}
- };
- static vorbis_residue_template _res_44s_9[]={
- {2,0, &_residue_44_high,
- &_huff_book__44c9_s_short,&_huff_book__44c9_s_short,
- &_resbook_44s_9,&_resbook_44s_9},
-
- {2,0, &_residue_44_high,
- &_huff_book__44c9_s_long,&_huff_book__44c9_s_long,
- &_resbook_44s_9,&_resbook_44s_9}
- };
-
- static vorbis_mapping_template _mapres_template_44_stereo[]={
- { _map_nominal, _res_44s_n1 }, /* -1 */
- { _map_nominal, _res_44s_0 }, /* 0 */
- { _map_nominal, _res_44s_1 }, /* 1 */
- { _map_nominal, _res_44s_2 }, /* 2 */
- { _map_nominal, _res_44s_3 }, /* 3 */
- { _map_nominal, _res_44s_4 }, /* 4 */
- { _map_nominal, _res_44s_5 }, /* 5 */
- { _map_nominal, _res_44s_6 }, /* 6 */
- { _map_nominal, _res_44s_7 }, /* 7 */
- { _map_nominal, _res_44s_8 }, /* 8 */
- { _map_nominal, _res_44s_9 }, /* 9 */
- };
- /********* End of inlined file: residue_44.h *********/
-
- /********* Start of inlined file: psych_44.h *********/
- /* preecho trigger settings *****************************************/
-
- static vorbis_info_psy_global _psy_global_44[5]={
-
- {8, /* lines per eighth octave */
- {20.f,14.f,12.f,12.f,12.f,12.f,12.f},
- {-60.f,-30.f,-40.f,-40.f,-40.f,-40.f,-40.f}, 2,-75.f,
- -6.f,
- {99.},{{99.},{99.}},{0},{0},{{0.},{0.}}
- },
- {8, /* lines per eighth octave */
- {14.f,10.f,10.f,10.f,10.f,10.f,10.f},
- {-40.f,-30.f,-25.f,-25.f,-25.f,-25.f,-25.f}, 2,-80.f,
- -6.f,
- {99.},{{99.},{99.}},{0},{0},{{0.},{0.}}
- },
- {8, /* lines per eighth octave */
- {12.f,10.f,10.f,10.f,10.f,10.f,10.f},
- {-20.f,-20.f,-15.f,-15.f,-15.f,-15.f,-15.f}, 0,-80.f,
- -6.f,
- {99.},{{99.},{99.}},{0},{0},{{0.},{0.}}
- },
- {8, /* lines per eighth octave */
- {10.f,8.f,8.f,8.f,8.f,8.f,8.f},
- {-20.f,-15.f,-12.f,-12.f,-12.f,-12.f,-12.f}, 0,-80.f,
- -6.f,
- {99.},{{99.},{99.}},{0},{0},{{0.},{0.}}
- },
- {8, /* lines per eighth octave */
- {10.f,6.f,6.f,6.f,6.f,6.f,6.f},
- {-15.f,-15.f,-12.f,-12.f,-12.f,-12.f,-12.f}, 0,-85.f,
- -6.f,
- {99.},{{99.},{99.}},{0},{0},{{0.},{0.}}
- },
- };
-
- /* noise compander lookups * low, mid, high quality ****************/
- static compandblock _psy_compand_44[6]={
- /* sub-mode Z short */
- {{
- 0, 1, 2, 3, 4, 5, 6, 7, /* 7dB */
- 8, 9,10,11,12,13,14, 15, /* 15dB */
- 16,17,18,19,20,21,22, 23, /* 23dB */
- 24,25,26,27,28,29,30, 31, /* 31dB */
- 32,33,34,35,36,37,38, 39, /* 39dB */
- }},
- /* mode_Z nominal short */
- {{
- 0, 1, 2, 3, 4, 5, 6, 6, /* 7dB */
- 7, 7, 7, 7, 6, 6, 6, 7, /* 15dB */
- 7, 8, 9,10,11,12,13, 14, /* 23dB */
- 15,16,17,17,17,18,18, 19, /* 31dB */
- 19,19,20,21,22,23,24, 25, /* 39dB */
- }},
- /* mode A short */
- {{
- 0, 1, 2, 3, 4, 5, 5, 5, /* 7dB */
- 6, 6, 6, 5, 4, 4, 4, 4, /* 15dB */
- 4, 4, 5, 5, 5, 6, 6, 6, /* 23dB */
- 7, 7, 7, 8, 8, 8, 9, 10, /* 31dB */
- 11,12,13,14,15,16,17, 18, /* 39dB */
- }},
- /* sub-mode Z long */
- {{
- 0, 1, 2, 3, 4, 5, 6, 7, /* 7dB */
- 8, 9,10,11,12,13,14, 15, /* 15dB */
- 16,17,18,19,20,21,22, 23, /* 23dB */
- 24,25,26,27,28,29,30, 31, /* 31dB */
- 32,33,34,35,36,37,38, 39, /* 39dB */
- }},
- /* mode_Z nominal long */
- {{
- 0, 1, 2, 3, 4, 5, 6, 7, /* 7dB */
- 8, 9,10,11,12,12,13, 13, /* 15dB */
- 13,14,14,14,15,15,15, 15, /* 23dB */
- 16,16,17,17,17,18,18, 19, /* 31dB */
- 19,19,20,21,22,23,24, 25, /* 39dB */
- }},
- /* mode A long */
- {{
- 0, 1, 2, 3, 4, 5, 6, 7, /* 7dB */
- 8, 8, 7, 6, 5, 4, 4, 4, /* 15dB */
- 4, 4, 5, 5, 5, 6, 6, 6, /* 23dB */
- 7, 7, 7, 8, 8, 8, 9, 10, /* 31dB */
- 11,12,13,14,15,16,17, 18, /* 39dB */
- }}
- };
-
- /* tonal masking curve level adjustments *************************/
-
- static vp_adjblock _vp_tonemask_adj_longblock[12]={
-
- /* 63 125 250 500 1 2 4 8 16 */
-
- {{ -3, -8,-13,-15,-10,-10,-10,-10,-10,-10,-10, 0, 0, 0, 0, 0, 0}}, /* -1 */
-
- /* {{-15,-15,-15,-15,-10, -8, -4, -2, 0, 0, 0, 10, 0, 0, 0, 0, 0}}, 0 */
- {{ -4,-10,-14,-16,-15,-14,-13,-12,-12,-12,-11, -1, -1, -1, -1, -1, 0}}, /* 0 */
-
- /* {{-15,-15,-15,-15,-15,-12,-10, -8, 0, 0, 0, 5, 0, 0, 0, 0, 0}}, 1 */
- {{ -6,-12,-14,-16,-15,-15,-14,-13,-13,-12,-12, -2, -2, -1, -1, -1, 0}}, /* 1 */
-
- /* {{-15,-15,-15,-15,-15,-12,-10, -8, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, 2 */
- {{-12,-13,-14,-16,-16,-16,-15,-14,-13,-12,-12, -6, -3, -1, -1, -1, 0}}, /* 2 */
-
- /* {{-15,-15,-15,-15,-15,-12,-10, -8, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, 3 */
- {{-15,-15,-15,-16,-16,-16,-16,-14,-13,-13,-13,-10, -4, -2, -1, -1, 0}}, /* 3 */
-
- /* {{-15,-15,-15,-15,-15,-12,-10, -8, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, *//* 4 */
- {{-16,-16,-16,-16,-16,-16,-16,-15,-14,-14,-13,-11, -7 -3, -1, -1 , 0}}, /* 4 */
-
- /* {{-15,-15,-15,-15,-15,-12,-10, -8, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, 5 */
- {{-16,-16,-16,-16,-16,-16,-16,-15,-14,-14,-13,-11, -7 -3, -1, -1 , 0}}, /* 5 */
-
- /* {{-15,-15,-15,-15,-15,-12,-10, -8, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, 6 */
- {{-16,-16,-16,-16,-16,-16,-16,-15,-14,-14,-14,-12, -8, -4, -2, -2, 0}}, /* 6 */
-
- /* {{-15,-15,-15,-15,-15,-12,-10, -8, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, 7 */
- {{-16,-16,-16,-16,-16,-16,-16,-15,-14,-14,-14,-12, -9, -4, -2, -2, 0}}, /* 7 */
-
- /* {{-15,-15,-15,-15,-15,-12,-10, -8, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, 8 */
- {{-16,-16,-16,-16,-16,-16,-16,-15,-14,-14,-14,-12, -9, -4, -2, -2, 0}}, /* 8 */
-
- /* {{-15,-15,-15,-15,-15,-12,-10, -8, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, 9 */
- {{-16,-16,-16,-16,-16,-16,-16,-15,-14,-14,-14,-12, -9, -4, -2, -2, 0}}, /* 9 */
-
- /* {{-15,-15,-15,-15,-15,-12,-10, -8, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, 10 */
- {{-16,-16,-16,-16,-16,-16,-16,-15,-14,-14,-14,-12, -9, -4, -2, -2, 0}}, /* 10 */
- };
-
- static vp_adjblock _vp_tonemask_adj_otherblock[12]={
- /* 63 125 250 500 1 2 4 8 16 */
-
- {{ -3, -8,-13,-15,-10,-10, -9, -9, -9, -9, -9, 1, 1, 1, 1, 1, 1}}, /* -1 */
-
- /* {{-20,-20,-20,-20,-14,-12,-10, -8, -4, 0, 0, 10, 0, 0, 0, 0, 0}}, 0 */
- {{ -4,-10,-14,-16,-14,-13,-12,-12,-11,-11,-10, 0, 0, 0, 0, 0, 0}}, /* 0 */
-
- /* {{-20,-20,-20,-20,-20,-18,-16,-14,-10, 0, 0, 5, 0, 0, 0, 0, 0}}, 1 */
- {{ -6,-12,-14,-16,-15,-15,-14,-13,-13,-12,-12, -2, -2, -1, 0, 0, 0}}, /* 1 */
-
- /* {{-20,-20,-20,-20,-20,-18,-16,-14,-10, 0, 0, 0, 0, 0, 0, 0, 0}}, 2 */
- {{-12,-13,-14,-16,-16,-16,-15,-14,-13,-12,-12, -5, -2, -1, 0, 0, 0}}, /* 2 */
-
- /* {{-20,-20,-20,-20,-20,-18,-16,-14,-10, 0, 0, 0, 0, 0, 0, 0, 0}}, 3 */
- {{-15,-15,-15,-16,-16,-16,-16,-14,-13,-13,-13,-10, -4, -2, 0, 0, 0}}, /* 3 */
-
- /* {{-20,-20,-20,-20,-20,-18,-16,-14,-10, 0, 0, 0, 0, 0, 0, 0, 0}}, 4 */
- {{-16,-16,-16,-16,-16,-16,-16,-15,-14,-14,-13,-11, -7 -3, -1, -1 , 0}}, /* 4 */
-
- /* {{-20,-20,-20,-20,-20,-18,-16,-14,-10, 0, 0, 0, 0, 0, 0, 0, 0}}, 5 */
- {{-16,-16,-16,-16,-16,-16,-16,-15,-14,-14,-13,-11, -7 -3, -1, -1 , 0}}, /* 5 */
-
- /* {{-20,-20,-20,-20,-20,-18,-16,-14,-10, 0, 0, 0, 0, 0, 0, 0, 0}}, 6 */
- {{-16,-16,-16,-16,-16,-16,-16,-15,-14,-14,-14,-12, -8, -4, -2, -2, 0}}, /* 6 */
-
- /* {{-20,-20,-20,-20,-20,-18,-16,-14,-10, 0, 0, 0, 0, 0, 0, 0, 0}}, 7 */
- {{-16,-16,-16,-16,-16,-16,-16,-15,-14,-14,-14,-12, -9, -4, -2, -2, 0}}, /* 7 */
-
- /* {{-20,-20,-20,-20,-20,-18,-16,-14,-10, 0, 0, 0, 0, 0, 0, 0, 0}}, 8 */
- {{-16,-16,-16,-16,-16,-16,-16,-15,-14,-14,-14,-12, -9, -4, -2, -2, 0}}, /* 8 */
-
- /* {{-20,-20,-20,-20,-20,-18,-16,-14,-10, 0, 0, 0, 0, 0, 0, 0, 0}}, 9 */
- {{-16,-16,-16,-16,-16,-16,-16,-15,-14,-14,-14,-12, -9, -4, -2, -2, 0}}, /* 9 */
-
- /* {{-20,-20,-20,-20,-20,-18,-16,-14,-10, 0, 0, 0, 0, 0, 0, 0, 0}}, 10 */
- {{-16,-16,-16,-16,-16,-16,-16,-15,-14,-14,-14,-12, -9, -4, -2, -2, 0}}, /* 10 */
- };
-
- /* noise bias (transition block) */
- static noise3 _psy_noisebias_trans[12]={
- /* 63 125 250 500 1k 2k 4k 8k 16k*/
- /* -1 */
- {{{-10,-10,-10,-10,-10, -4, 0, 0, 4, 8, 8, 8, 8, 10, 12, 14, 20},
- {-30,-30,-30,-30,-26,-20,-16, -8, -6, -6, -2, 2, 2, 3, 6, 6, 15},
- {-30,-30,-30,-30,-30,-24,-20,-14,-10, -6, -8, -8, -6, -6, -6, -4, -2}}},
- /* 0
- {{{-15,-15,-15,-15,-15,-12,-10, -8, 0, 2, 4, 4, 5, 5, 5, 8, 10},
- {-30,-30,-30,-30,-26,-22,-20,-14, -8, -4, 0, 0, 0, 0, 2, 4, 10},
- {-30,-30,-30,-30,-26,-22,-20,-14,-10, -6, -6, -6, -6, -4, -4, -4, -2}}},*/
- {{{-15,-15,-15,-15,-15,-12, -6, -4, 0, 2, 4, 4, 5, 5, 5, 8, 10},
- {-30,-30,-30,-30,-26,-22,-20,-14, -8, -4, 0, 0, 0, 0, 2, 3, 6},
- {-30,-30,-30,-30,-26,-22,-20,-14,-10, -6, -6, -6, -6, -4, -4, -4, -2}}},
- /* 1
- {{{-15,-15,-15,-15,-15,-12,-10, -8, 0, 2, 4, 4, 5, 5, 5, 8, 10},
- {-30,-30,-30,-30,-26,-22,-20,-14,-10, -4, -2, -2, -2, -2, 0, 2, 8},
- {-30,-30,-30,-30,-26,-22,-20,-14,-10, -8, -8, -8, -8, -6, -6, -6, -4}}},*/
- {{{-15,-15,-15,-15,-15,-12,-10, -8, 0, 2, 4, 4, 5, 5, 5, 8, 10},
- {-30,-30,-30,-30,-26,-22,-20,-14,-10, -4, -2, -2, -2, -2, 0, 1, 4},
- {-30,-30,-30,-30,-26,-22,-20,-14,-10, -8, -8, -8, -8, -6, -6, -6, -4}}},
- /* 2
- {{{-15,-15,-15,-15,-15,-12,-10, -8, 0, 2, 2, 2, 4, 4, 5, 6, 10},
- {-30,-30,-30,-30,-26,-22,-20,-14,-10, -4, -2, -2, -2, -2, 0, 2, 6},
- {-30,-30,-30,-30,-26,-22,-20,-14,-10,-10,-10,-10,-10, -8, -8, -8, -4}}}, */
- {{{-15,-15,-15,-15,-15,-12,-10, -8, 0, 2, 2, 2, 4, 4, 5, 6, 10},
- {-30,-30,-30,-30,-26,-22,-20,-14,-10, -4, -3, -3, -3, -2, -1, 0, 3},
- {-30,-30,-30,-30,-26,-22,-20,-14,-10,-10,-10,-10,-10, -8, -8, -7, -4}}},
- /* 3
- {{{-15,-15,-15,-15,-15,-12,-10, -8, 0, 2, 2, 2, 4, 4, 4, 5, 8},
- {-30,-30,-30,-30,-26,-22,-20,-14,-10, -4, -3, -3, -3, -3, -1, 1, 6},
- {-30,-30,-30,-30,-26,-22,-20,-14,-10,-10,-10,-10,-10, -8, -8, -8, -4}}},*/
- {{{-15,-15,-15,-15,-15,-12,-10, -8, 0, 2, 2, 2, 4, 4, 4, 5, 8},
- {-30,-30,-30,-30,-26,-22,-20,-14,-10, -4, -3, -3, -3, -3, -2, 0, 2},
- {-30,-30,-30,-30,-26,-22,-20,-14,-10,-10,-10,-10,-10, -8, -8, -8, -4}}},
- /* 4
- {{{-20,-20,-20,-20,-20,-18,-14, -8, -1, 1, 1, 1, 2, 3, 3, 4, 7},
- {-30,-30,-30,-30,-26,-22,-20,-14,-10, -4, -3, -3, -3, -3, -1, 1, 5},
- {-30,-30,-30,-30,-26,-22,-20,-14,-10,-10,-10,-10,-10, -8, -8, -8, -4}}},*/
- {{{-20,-20,-20,-20,-20,-18,-14, -8, -1, 1, 1, 1, 2, 3, 3, 4, 7},
- {-30,-30,-30,-30,-26,-22,-20,-14,-10, -4, -3, -3, -3, -3, -2, -1, 1},
- {-30,-30,-30,-30,-26,-22,-20,-14,-10,-10,-10,-10,-10, -8, -8, -8, -4}}},
- /* 5
- {{{-24,-24,-24,-24,-20,-18,-14, -8, -1, 1, 1, 1, 2, 3, 3, 4, 7},
- {-32,-32,-32,-32,-28,-24,-22,-16,-12, -6, -4, -4, -4, -4, -2, -1, 2},
- {-34,-34,-34,-34,-30,-24,-24,-18,-14,-12,-12,-12,-12,-10,-10, -9, -5}}}, */
- {{{-24,-24,-24,-24,-20,-18,-14, -8, -1, 1, 1, 1, 2, 3, 3, 4, 7},
- {-32,-32,-32,-32,-28,-24,-22,-16,-12, -6, -4, -4, -4, -4, -3, -1, 0},
- {-34,-34,-34,-34,-30,-24,-24,-18,-14,-12,-12,-12,-12,-10,-10, -9, -5}}},
- /* 6
- {{{-24,-24,-24,-24,-20,-18,-14, -8, -1, 1, 1, 1, 2, 3, 3, 4, 7},
- {-32,-32,-32,-32,-28,-24,-24,-18,-14, -8, -6, -6, -6, -6, -4, -2, 1},
- {-34,-34,-34,-34,-30,-26,-24,-18,-17,-15,-15,-15,-15,-13,-13,-12, -8}}},*/
- {{{-24,-24,-24,-24,-20,-18,-14, -8, -1, 1, 1, 1, 2, 3, 3, 4, 7},
- {-32,-32,-32,-32,-28,-24,-24,-18,-14, -8, -6, -6, -6, -6, -5, -2, 0},
- {-34,-34,-34,-34,-30,-26,-26,-24,-22,-19,-19,-19,-19,-18,-17,-16,-12}}},
- /* 7
- {{{-24,-24,-24,-24,-20,-18,-14, -8, -1, 1, 1, 1, 2, 3, 3, 4, 7},
- {-32,-32,-32,-32,-28,-24,-24,-18,-14,-12,-10, -8, -8, -8, -6, -4, 0},
- {-34,-34,-34,-34,-30,-26,-26,-24,-22,-19,-19,-19,-19,-18,-17,-16,-12}}},*/
- {{{-24,-24,-24,-24,-20,-18,-14, -8, -1, 1, 1, 1, 2, 3, 3, 4, 7},
- {-32,-32,-32,-32,-28,-24,-24,-24,-18,-14,-12,-10,-10,-10, -8, -6, -2},
- {-34,-34,-34,-34,-30,-26,-26,-26,-24,-24,-24,-24,-24,-24,-24,-20,-16}}},
- /* 8
- {{{-24,-24,-24,-24,-22,-20,-15,-10, -8, -2, 0, 0, 0, 1, 2, 3, 7},
- {-36,-36,-36,-36,-30,-30,-30,-24,-18,-14,-12,-10,-10,-10, -8, -6, -2},
- {-36,-36,-36,-36,-34,-30,-28,-26,-24,-24,-24,-24,-24,-24,-24,-20,-16}}},*/
- {{{-24,-24,-24,-24,-22,-20,-15,-10, -8, -2, 0, 0, 0, 1, 2, 3, 7},
- {-36,-36,-36,-36,-30,-30,-30,-24,-20,-16,-16,-16,-16,-14,-12,-10, -7},
- {-36,-36,-36,-36,-34,-30,-28,-26,-24,-30,-30,-30,-30,-30,-30,-24,-20}}},
- /* 9
- {{{-28,-28,-28,-28,-28,-28,-28,-20,-14, -8, -4, -4, -4, -4, -4, -2, 2},
- {-36,-36,-36,-36,-34,-32,-32,-28,-20,-16,-16,-16,-16,-14,-12,-10, -7},
- {-40,-40,-40,-40,-40,-40,-40,-32,-30,-30,-30,-30,-30,-30,-30,-24,-20}}},*/
- {{{-28,-28,-28,-28,-28,-28,-28,-20,-14, -8, -4, -4, -4, -4, -4, -2, 2},
- {-38,-38,-38,-38,-36,-34,-34,-30,-24,-20,-20,-20,-20,-18,-16,-12,-10},
- {-40,-40,-40,-40,-40,-40,-40,-38,-35,-35,-35,-35,-35,-35,-35,-35,-30}}},
- /* 10 */
- {{{-30,-30,-30,-30,-30,-30,-30,-28,-20,-14,-14,-14,-14,-14,-14,-12,-10},
- {-40,-40,-40,-40,-40,-40,-40,-40,-35,-30,-30,-30,-30,-30,-30,-30,-20},
- {-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40}}},
- };
-
- /* noise bias (long block) */
- static noise3 _psy_noisebias_long[12]={
- /*63 125 250 500 1k 2k 4k 8k 16k*/
- /* -1 */
- {{{-10,-10,-10,-10,-10, -4, 0, 0, 0, 6, 6, 6, 6, 10, 10, 12, 20},
- {-20,-20,-20,-20,-20,-20,-10, -2, 0, 0, 0, 0, 0, 2, 4, 6, 15},
- {-20,-20,-20,-20,-20,-20,-20,-10, -6, -6, -6, -6, -6, -4, -4, -4, -2}}},
-
- /* 0 */
- /* {{{-10,-10,-10,-10,-10,-10, -8, 2, 2, 2, 4, 4, 5, 5, 5, 8, 10},
- {-20,-20,-20,-20,-20,-20,-20,-14, -6, 0, 0, 0, 0, 0, 2, 4, 10},
- {-20,-20,-20,-20,-20,-20,-20,-14, -8, -6, -6, -6, -6, -4, -4, -4, -2}}},*/
- {{{-10,-10,-10,-10,-10,-10, -8, 2, 2, 2, 4, 4, 5, 5, 5, 8, 10},
- {-20,-20,-20,-20,-20,-20,-20,-14, -6, 0, 0, 0, 0, 0, 2, 3, 6},
- {-20,-20,-20,-20,-20,-20,-20,-14, -8, -6, -6, -6, -6, -4, -4, -4, -2}}},
- /* 1 */
- /* {{{-10,-10,-10,-10,-10,-10, -8, -4, 0, 2, 4, 4, 5, 5, 5, 8, 10},
- {-20,-20,-20,-20,-20,-20,-20,-14,-10, -4, -2, -2, -2, -2, 0, 2, 8},
- {-20,-20,-20,-20,-20,-20,-20,-14,-10, -8, -8, -8, -8, -6, -6, -6, -4}}},*/
- {{{-10,-10,-10,-10,-10,-10, -8, -4, 0, 2, 4, 4, 5, 5, 5, 8, 10},
- {-20,-20,-20,-20,-20,-20,-20,-14,-10, -4, -2, -2, -2, -2, 0, 1, 4},
- {-20,-20,-20,-20,-20,-20,-20,-14,-10, -8, -8, -8, -8, -6, -6, -6, -4}}},
- /* 2 */
- /* {{{-10,-10,-10,-10,-10,-10,-10, -8, 0, 2, 2, 2, 4, 4, 5, 6, 10},
- {-20,-20,-20,-20,-20,-20,-20,-14,-10, -4, -2, -2, -2, -2, 0, 2, 6},
- {-20,-20,-20,-20,-20,-20,-20,-14,-10,-10,-10,-10,-10, -8, -8, -8, -4}}},*/
- {{{-10,-10,-10,-10,-10,-10,-10, -8, 0, 2, 2, 2, 4, 4, 5, 6, 10},
- {-20,-20,-20,-20,-20,-20,-20,-14,-10, -4, -3, -3, -3, -2, -1, 0, 3},
- {-20,-20,-20,-20,-20,-20,-20,-14,-10,-10,-10,-10,-10, -8, -8, -8, -4}}},
- /* 3 */
- /* {{{-10,-10,-10,-10,-10,-10,-10, -8, 0, 2, 2, 2, 4, 4, 4, 5, 8},
- {-20,-20,-20,-20,-20,-20,-20,-14,-10, -4, -3, -3, -3, -3, -1, 1, 6},
- {-20,-20,-20,-20,-20,-20,-20,-14,-10,-10,-10,-10,-10, -8, -8, -8, -4}}},*/
- {{{-10,-10,-10,-10,-10,-10,-10, -8, 0, 2, 2, 2, 4, 4, 4, 5, 8},
- {-20,-20,-20,-20,-20,-20,-20,-14,-10, -4, -3, -3, -3, -3, -2, 0, 2},
- {-20,-20,-20,-20,-20,-20,-20,-14,-10,-10,-10,-10,-10, -8, -8, -8, -5}}},
- /* 4 */
- /* {{{-15,-15,-15,-15,-15,-15,-15,-10, -4, 1, 1, 1, 2, 3, 3, 4, 7},
- {-20,-20,-20,-20,-20,-20,-20,-14,-10, -4, -3, -3, -3, -3, -1, 1, 5},
- {-20,-20,-20,-20,-20,-20,-20,-14,-10,-10,-10,-10,-10, -8, -8, -8, -4}}},*/
- {{{-15,-15,-15,-15,-15,-15,-15,-10, -4, 1, 1, 1, 2, 3, 3, 4, 7},
- {-20,-20,-20,-20,-20,-20,-20,-14,-10, -4, -3, -3, -3, -3, -2, -1, 1},
- {-20,-20,-20,-20,-20,-20,-20,-14,-10,-10,-10,-10,-10, -8, -8, -8, -7}}},
- /* 5 */
- /* {{{-15,-15,-15,-15,-15,-15,-15,-10, -4, 1, 1, 1, 2, 3, 3, 4, 7},
- {-22,-22,-22,-22,-22,-22,-22,-16,-12, -6, -4, -4, -4, -4, -2, -1, 2},
- {-24,-24,-24,-24,-24,-24,-24,-18,-14,-12,-12,-12,-12,-10,-10, -9, -5}}},*/
- {{{-15,-15,-15,-15,-15,-15,-15,-10, -4, 1, 1, 1, 2, 3, 3, 4, 7},
- {-22,-22,-22,-22,-22,-22,-22,-16,-12, -6, -4, -4, -4, -4, -3, -1, 0},
- {-24,-24,-24,-24,-24,-24,-24,-18,-14,-12,-12,-12,-12,-10,-10, -9, -8}}},
- /* 6 */
- /* {{{-15,-15,-15,-15,-15,-15,-15,-10, -4, 1, 1, 1, 2, 3, 3, 4, 7},
- {-24,-24,-24,-24,-24,-24,-24,-18,-14, -8, -6, -6, -6, -6, -4, -2, 1},
- {-26,-26,-26,-26,-26,-26,-26,-18,-16,-15,-15,-15,-15,-13,-13,-12, -8}}},*/
- {{{-15,-15,-15,-15,-15,-15,-15,-10, -4, 1, 1, 1, 2, 3, 3, 4, 7},
- {-24,-24,-24,-24,-24,-24,-24,-18,-14, -8, -6, -6, -6, -6, -5, -2, 0},
- {-26,-26,-26,-26,-26,-26,-26,-18,-16,-15,-15,-15,-15,-13,-13,-12,-10}}},
- /* 7 */
- {{{-15,-15,-15,-15,-15,-15,-15,-10, -4, 1, 1, 1, 2, 3, 3, 4, 7},
- {-24,-24,-24,-24,-24,-24,-24,-18,-14,-10, -8, -8, -8, -8, -6, -4, 0},
- {-26,-26,-26,-26,-26,-26,-26,-22,-20,-19,-19,-19,-19,-18,-17,-16,-12}}},
- /* 8 */
- {{{-15,-15,-15,-15,-15,-15,-15,-10, -4, 0, 0, 0, 0, 1, 2, 3, 7},
- {-26,-26,-26,-26,-26,-26,-26,-20,-16,-12,-10,-10,-10,-10, -8, -6, -2},
- {-28,-28,-28,-28,-28,-28,-28,-26,-24,-24,-24,-24,-24,-24,-24,-20,-16}}},
- /* 9 */
- {{{-22,-22,-22,-22,-22,-22,-22,-18,-14, -8, -4, -4, -4, -4, -4, -2, 2},
- {-26,-26,-26,-26,-26,-26,-26,-22,-18,-16,-16,-16,-16,-14,-12,-10, -7},
- {-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-24,-20}}},
- /* 10 */
- {{{-24,-24,-24,-24,-24,-24,-24,-24,-24,-18,-14,-14,-14,-14,-14,-12,-10},
- {-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-20},
- {-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40}}},
- };
-
- /* noise bias (impulse block) */
- static noise3 _psy_noisebias_impulse[12]={
- /* 63 125 250 500 1k 2k 4k 8k 16k*/
- /* -1 */
- {{{-10,-10,-10,-10,-10, -4, 0, 0, 4, 8, 8, 8, 8, 10, 12, 14, 20},
- {-30,-30,-30,-30,-26,-20,-16, -8, -6, -6, -2, 2, 2, 3, 6, 6, 15},
- {-30,-30,-30,-30,-30,-24,-20,-14,-10, -6, -8, -8, -6, -6, -6, -4, -2}}},
-
- /* 0 */
- /* {{{-10,-10,-10,-10,-10, -4, 0, 0, 4, 4, 8, 8, 8, 10, 12, 14, 20},
- {-30,-30,-30,-30,-26,-22,-20,-14, -6, -2, 0, 0, 0, 0, 2, 4, 10},
- {-30,-30,-30,-30,-30,-24,-20,-14,-10, -6, -8, -8, -6, -6, -6, -4, -2}}},*/
- {{{-10,-10,-10,-10,-10, -4, 0, 0, 4, 4, 8, 8, 8, 10, 12, 14, 20},
- {-30,-30,-30,-30,-26,-22,-20,-14, -6, -2, 0, 0, 0, 0, 2, 3, 6},
- {-30,-30,-30,-30,-30,-24,-20,-14,-10, -6, -8, -8, -6, -6, -6, -4, -2}}},
- /* 1 */
- {{{-12,-12,-12,-12,-12, -8, -6, -4, 0, 4, 4, 4, 4, 10, 12, 14, 20},
- {-30,-30,-30,-30,-26,-22,-20,-14,-10, -6, -4, -4, -2, -2, -2, -2, 2},
- {-30,-30,-30,-30,-26,-22,-20,-14,-10, -8,-10,-10, -8, -8, -8, -6, -4}}},
- /* 2 */
- {{{-14,-14,-14,-14,-14,-10, -8, -6, -2, 2, 2, 2, 2, 8, 10, 10, 16},
- {-30,-30,-30,-30,-26,-22,-20,-14,-10, -6, -6, -6, -4, -4, -4, -2, 0},
- {-30,-30,-30,-30,-26,-22,-20,-14,-10,-10,-10,-10,-10,-10,-10, -8, -4}}},
- /* 3 */
- {{{-14,-14,-14,-14,-14,-10, -8, -6, -2, 2, 2, 2, 2, 6, 8, 8, 14},
- {-30,-30,-30,-30,-26,-22,-20,-14,-10, -6, -6, -6, -4, -4, -4, -2, 0},
- {-30,-30,-30,-30,-26,-22,-20,-14,-10,-10,-10,-10,-10,-10,-10, -8, -4}}},
- /* 4 */
- {{{-16,-16,-16,-16,-16,-12,-10, -6, -2, 0, 0, 0, 0, 4, 6, 6, 12},
- {-30,-30,-30,-30,-26,-22,-20,-14,-10, -6, -6, -6, -4, -4, -4, -2, 0},
- {-30,-30,-30,-30,-26,-22,-20,-14,-10,-10,-10,-10,-10,-10,-10, -8, -4}}},
- /* 5 */
- {{{-20,-20,-20,-20,-20,-18,-14,-10, -4, 0, 0, 0, 0, 4, 4, 6, 11},
- {-32,-32,-32,-32,-28,-24,-22,-16,-10, -6, -8, -8, -6, -6, -6, -4, -2},
- {-34,-34,-34,-34,-30,-26,-24,-18,-14,-12,-12,-12,-12,-12,-10, -9, -5}}},
- /* 6
- {{{-20,-20,-20,-20,-20,-18,-14,-10, -4, 0, 0, 0, 0, 4, 4, 6, 11},
- {-34,-34,-34,-34,-30,-30,-24,-20,-12,-12,-14,-14,-10, -9, -8, -6, -4},
- {-34,-34,-34,-34,-34,-30,-26,-20,-16,-15,-15,-15,-15,-15,-13,-12, -8}}},*/
- {{{-20,-20,-20,-20,-20,-18,-14,-10, -4, 0, 0, 0, 0, 4, 4, 6, 11},
- {-34,-34,-34,-34,-30,-30,-30,-24,-16,-16,-16,-16,-16,-16,-14,-14,-12},
- {-36,-36,-36,-36,-36,-34,-28,-24,-20,-20,-20,-20,-20,-20,-20,-18,-16}}},
- /* 7 */
- /* {{{-22,-22,-22,-22,-22,-20,-14,-10, -6, 0, 0, 0, 0, 4, 4, 6, 11},
- {-34,-34,-34,-34,-30,-30,-24,-20,-14,-14,-16,-16,-14,-12,-10,-10,-10},
- {-34,-34,-34,-34,-32,-32,-30,-24,-20,-19,-19,-19,-19,-19,-17,-16,-12}}},*/
- {{{-22,-22,-22,-22,-22,-20,-14,-10, -6, 0, 0, 0, 0, 4, 4, 6, 11},
- {-34,-34,-34,-34,-30,-30,-30,-30,-26,-26,-26,-26,-26,-26,-26,-24,-22},
- {-40,-40,-40,-40,-40,-40,-40,-32,-30,-30,-30,-30,-30,-30,-30,-30,-24}}},
- /* 8 */
- /* {{{-24,-24,-24,-24,-24,-22,-14,-10, -6, -1, -1, -1, -1, 3, 3, 5, 10},
- {-34,-34,-34,-34,-30,-30,-30,-24,-20,-20,-20,-20,-20,-18,-16,-16,-14},
- {-36,-36,-36,-36,-36,-34,-28,-24,-24,-24,-24,-24,-24,-24,-24,-20,-16}}},*/
- {{{-24,-24,-24,-24,-24,-22,-14,-10, -6, -1, -1, -1, -1, 3, 3, 5, 10},
- {-34,-34,-34,-34,-34,-32,-32,-30,-26,-26,-26,-26,-26,-26,-26,-26,-24},
- {-40,-40,-40,-40,-40,-40,-40,-32,-30,-30,-30,-30,-30,-30,-30,-30,-24}}},
- /* 9 */
- /* {{{-28,-28,-28,-28,-28,-28,-28,-20,-14, -8, -4, -4, -4, -4, -4, -2, 2},
- {-36,-36,-36,-36,-34,-32,-32,-30,-26,-26,-26,-26,-26,-22,-20,-20,-18},
- {-40,-40,-40,-40,-40,-40,-40,-32,-30,-30,-30,-30,-30,-30,-30,-24,-20}}},*/
- {{{-28,-28,-28,-28,-28,-28,-28,-20,-14, -8, -4, -4, -4, -4, -4, -2, 2},
- {-36,-36,-36,-36,-34,-32,-32,-30,-26,-26,-26,-26,-26,-26,-26,-26,-26},
- {-40,-40,-40,-40,-40,-40,-40,-32,-30,-30,-30,-30,-30,-30,-30,-24,-20}}},
- /* 10 */
- {{{-30,-30,-30,-30,-30,-26,-24,-24,-24,-20,-16,-16,-16,-16,-16,-14,-12},
- {-40,-40,-40,-40,-40,-40,-40,-40,-35,-30,-30,-30,-30,-30,-30,-30,-26},
- {-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40}}},
- };
-
- /* noise bias (padding block) */
- static noise3 _psy_noisebias_padding[12]={
- /* 63 125 250 500 1k 2k 4k 8k 16k*/
-
- /* -1 */
- {{{-10,-10,-10,-10,-10, -4, 0, 0, 4, 8, 8, 8, 8, 10, 12, 14, 20},
- {-30,-30,-30,-30,-26,-20,-16, -8, -6, -6, -2, 2, 2, 3, 6, 6, 15},
- {-30,-30,-30,-30,-30,-24,-20,-14,-10, -6, -8, -8, -6, -6, -6, -4, -2}}},
-
- /* 0 */
- {{{-10,-10,-10,-10,-10, -4, 0, 0, 4, 8, 8, 8, 8, 10, 12, 14, 20},
- {-30,-30,-30,-30,-26,-22,-20,-14,-10, -4, -2, 2, 3, 6, 6, 8, 10},
- {-30,-30,-30,-30,-26,-22,-20,-14,-10, -4, -4, -4, -4, -4, -2, 0, 2}}},
- /* 1 */
- {{{-12,-12,-12,-12,-12, -8, -6, -4, 0, 4, 4, 4, 4, 10, 12, 14, 20},
- {-30,-30,-30,-30,-26,-22,-20,-14,-10, -4, 0, 0, 0, 2, 2, 4, 8},
- {-30,-30,-30,-30,-26,-22,-20,-14,-10, -6, -6, -6, -6, -6, -4, -2, 0}}},
- /* 2 */
- /* {{{-14,-14,-14,-14,-14,-10, -8, -6, -2, 2, 2, 2, 2, 8, 10, 10, 16},
- {-30,-30,-30,-30,-26,-22,-20,-14,-10, -4, 0, 0, 0, 2, 2, 4, 8},
- {-30,-30,-30,-30,-26,-22,-20,-14,-10, -8, -8, -8, -8, -8, -6, -4, -2}}},*/
- {{{-14,-14,-14,-14,-14,-10, -8, -6, -2, 2, 2, 2, 2, 8, 10, 10, 16},
- {-30,-30,-30,-30,-26,-22,-20,-14,-10, -6, -1, -1, -1, 0, 0, 2, 6},
- {-30,-30,-30,-30,-26,-22,-20,-14,-10, -8, -8, -8, -8, -8, -6, -4, -2}}},
- /* 3 */
- {{{-14,-14,-14,-14,-14,-10, -8, -6, -2, 2, 2, 2, 2, 6, 8, 8, 14},
- {-30,-30,-30,-30,-26,-22,-20,-14,-10, -6, -1, -1, -1, 0, 0, 2, 6},
- {-30,-30,-30,-30,-26,-22,-20,-14,-10, -8, -8, -8, -8, -8, -6, -4, -2}}},
- /* 4 */
- {{{-16,-16,-16,-16,-16,-12,-10, -6, -2, 0, 0, 0, 0, 4, 6, 6, 12},
- {-30,-30,-30,-30,-26,-22,-20,-14,-10, -6, -1, -1, -1, -1, 0, 2, 6},
- {-30,-30,-30,-30,-26,-22,-20,-14,-10, -8, -8, -8, -8, -8, -6, -4, -2}}},
- /* 5 */
- {{{-20,-20,-20,-20,-20,-18,-14,-10, -4, 0, 0, 0, 0, 4, 6, 6, 12},
- {-32,-32,-32,-32,-28,-24,-22,-16,-12, -6, -3, -3, -3, -3, -2, 0, 4},
- {-34,-34,-34,-34,-30,-26,-24,-18,-14,-10,-10,-10,-10,-10, -8, -5, -3}}},
- /* 6 */
- {{{-20,-20,-20,-20,-20,-18,-14,-10, -4, 0, 0, 0, 0, 4, 6, 6, 12},
- {-34,-34,-34,-34,-30,-30,-24,-20,-14, -8, -4, -4, -4, -4, -3, -1, 4},
- {-34,-34,-34,-34,-34,-30,-26,-20,-16,-13,-13,-13,-13,-13,-11, -8, -6}}},
- /* 7 */
- {{{-20,-20,-20,-20,-20,-18,-14,-10, -4, 0, 0, 0, 0, 4, 6, 6, 12},
- {-34,-34,-34,-34,-30,-30,-30,-24,-16,-10, -8, -6, -6, -6, -5, -3, 1},
- {-34,-34,-34,-34,-32,-32,-28,-22,-18,-16,-16,-16,-16,-16,-14,-12,-10}}},
- /* 8 */
- {{{-22,-22,-22,-22,-22,-20,-14,-10, -4, 0, 0, 0, 0, 3, 5, 5, 11},
- {-34,-34,-34,-34,-30,-30,-30,-24,-16,-12,-10, -8, -8, -8, -7, -5, -2},
- {-36,-36,-36,-36,-36,-34,-28,-22,-20,-20,-20,-20,-20,-20,-20,-16,-14}}},
- /* 9 */
- {{{-28,-28,-28,-28,-28,-28,-28,-20,-14, -8, -2, -2, -2, -2, 0, 2, 6},
- {-36,-36,-36,-36,-34,-32,-32,-24,-16,-12,-12,-12,-12,-12,-10, -8, -5},
- {-40,-40,-40,-40,-40,-40,-40,-32,-26,-24,-24,-24,-24,-24,-24,-20,-18}}},
- /* 10 */
- {{{-30,-30,-30,-30,-30,-26,-24,-24,-24,-20,-12,-12,-12,-12,-12,-10, -8},
- {-40,-40,-40,-40,-40,-40,-40,-40,-35,-30,-25,-25,-25,-25,-25,-25,-15},
- {-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40}}},
- };
-
- static noiseguard _psy_noiseguards_44[4]={
- {3,3,15},
- {3,3,15},
- {10,10,100},
- {10,10,100},
- };
-
- static int _psy_tone_suppress[12]={
- -20,-20,-20,-20,-20,-24,-30,-40,-40,-45,-45,-45,
- };
- static int _psy_tone_0dB[12]={
- 90,90,95,95,95,95,105,105,105,105,105,105,
- };
- static int _psy_noise_suppress[12]={
- -20,-20,-24,-24,-24,-24,-30,-40,-40,-45,-45,-45,
- };
-
- static vorbis_info_psy _psy_info_template={
- /* blockflag */
- -1,
- /* ath_adjatt, ath_maxatt */
- -140.,-140.,
- /* tonemask att boost/decay,suppr,curves */
- {0.f,0.f,0.f}, 0.,0., -40.f, {0.},
-
- /*noisemaskp,supp, low/high window, low/hi guard, minimum */
- 1, -0.f, .5f, .5f, 0,0,0,
- /* noiseoffset*3, noisecompand, max_curve_dB */
- {{-1},{-1},{-1}},{-1},105.f,
- /* noise normalization - channel_p, point_p, start, partition, thresh. */
- 0,0,-1,-1,0.,
- };
-
- /* ath ****************/
-
- static int _psy_ath_floater[12]={
- -100,-100,-100,-100,-100,-100,-105,-105,-105,-105,-110,-120,
- };
- static int _psy_ath_abs[12]={
- -130,-130,-130,-130,-140,-140,-140,-140,-140,-140,-140,-150,
- };
-
- /* stereo setup. These don't map directly to quality level, there's
- an additional indirection as several of the below may be used in a
- single bitmanaged stream
-
- ****************/
-
- /* various stereo possibilities */
-
- /* stereo mode by base quality level */
- static adj_stereo _psy_stereo_modes_44[12]={
- /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 -1 */
- {{ 4, 4, 4, 4, 4, 4, 4, 3, 2, 2, 1, 0, 0, 0, 0},
- { 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 5, 4, 3},
- { 1, 2, 3, 4, 4, 4, 4, 4, 4, 5, 6, 7, 8, 8, 8},
- { 12,12.5, 13,13.5, 14,14.5, 15, 99, 99, 99, 99, 99, 99, 99, 99}},
-
- /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 0 */
- /*{{ 4, 4, 4, 4, 4, 4, 4, 3, 2, 2, 1, 0, 0, 0, 0},
- { 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 5, 4, 3},
- { 1, 2, 3, 4, 5, 5, 6, 6, 6, 6, 6, 7, 8, 8, 8},
- { 12,12.5, 13,13.5, 14,14.5, 15, 99, 99, 99, 99, 99, 99, 99, 99}},*/
- {{ 4, 4, 4, 4, 4, 4, 4, 3, 2, 1, 0, 0, 0, 0, 0},
- { 8, 8, 8, 8, 6, 6, 5, 5, 5, 5, 5, 5, 5, 4, 3},
- { 1, 2, 3, 4, 4, 5, 6, 6, 6, 6, 6, 8, 8, 8, 8},
- { 12,12.5, 13,13.5, 14,14.5, 15, 99, 99, 99, 99, 99, 99, 99, 99}},
-
- /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 1 */
- {{ 3, 3, 3, 3, 3, 3, 3, 3, 2, 1, 0, 0, 0, 0, 0},
- { 8, 8, 8, 8, 6, 6, 5, 5, 5, 5, 5, 5, 5, 4, 3},
- { 1, 2, 3, 4, 4, 5, 6, 6, 6, 6, 6, 8, 8, 8, 8},
- { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}},
-
- /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 2 */
- /* {{ 3, 3, 3, 3, 3, 3, 2, 2, 2, 1, 0, 0, 0, 0, 0},
- { 8, 8, 8, 6, 5, 5, 5, 5, 5, 5, 5, 4, 3, 2, 1},
- { 3, 4, 4, 4, 5, 6, 6, 6, 6, 6, 6, 8, 8, 8, 8},
- { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}}, */
- {{ 3, 3, 3, 3, 3, 3, 3, 2, 1, 1, 0, 0, 0, 0, 0},
- { 8, 8, 6, 6, 5, 5, 4, 4, 4, 4, 4, 4, 3, 2, 1},
- { 3, 4, 4, 5, 5, 6, 6, 6, 6, 6, 6, 8, 8, 8, 8},
- { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}},
- /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 3 */
- {{ 2, 2, 2, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0},
- { 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 2, 1},
- { 4, 4, 5, 6, 6, 6, 6, 6, 8, 8, 10, 10, 10, 10, 10},
- { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}},
- /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 4 */
- {{ 2, 2, 2, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 2, 1, 0},
- { 6, 6, 6, 8, 8, 8, 8, 8, 8, 8, 10, 10, 10, 10, 10},
- { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}},
- /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 5 */
- /* {{ 2, 2, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- { 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0},
- { 6, 6, 8, 8, 8, 8, 10, 10, 10, 10, 10, 10, 10, 10, 10},
- { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}},*/
- {{ 2, 2, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- { 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0},
- { 6, 7, 8, 8, 8, 10, 10, 12, 12, 12, 12, 12, 12, 12, 12},
- { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}},
- /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 6 */
- /* {{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- { 3, 3, 3, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- { 8, 8, 8, 8, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10},
- { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}}, */
- {{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- { 3, 3, 3, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- { 8, 8, 8, 10, 10, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12},
- { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}},
- /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 7 */
- /* {{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- { 3, 3, 3, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- { 8, 8, 8, 8, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10},
- { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}},*/
- {{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- { 3, 3, 3, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- { 8, 8, 10, 10, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12},
- { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}},
- /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 8 */
- /* {{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- { 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- { 8, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10},
- { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}},*/
- {{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- { 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- { 8, 10, 10, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12},
- { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}},
- /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 9 */
- {{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4},
- { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}},
- /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 10 */
- {{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4},
- { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}},
- };
-
- /* tone master attenuation by base quality mode and bitrate tweak */
- static att3 _psy_tone_masteratt_44[12]={
- {{ 35, 21, 9}, 0, 0}, /* -1 */
- {{ 30, 20, 8}, -2, 1.25}, /* 0 */
- /* {{ 25, 14, 4}, 0, 0}, *//* 1 */
- {{ 25, 12, 2}, 0, 0}, /* 1 */
- /* {{ 20, 10, -2}, 0, 0}, *//* 2 */
- {{ 20, 9, -3}, 0, 0}, /* 2 */
- {{ 20, 9, -4}, 0, 0}, /* 3 */
- {{ 20, 9, -4}, 0, 0}, /* 4 */
- {{ 20, 6, -6}, 0, 0}, /* 5 */
- {{ 20, 3, -10}, 0, 0}, /* 6 */
- {{ 18, 1, -14}, 0, 0}, /* 7 */
- {{ 18, 0, -16}, 0, 0}, /* 8 */
- {{ 18, -2, -16}, 0, 0}, /* 9 */
- {{ 12, -2, -20}, 0, 0}, /* 10 */
- };
-
- /* lowpass by mode **************/
- static double _psy_lowpass_44[12]={
- /* 15.1,15.8,16.5,17.9,20.5,48.,999.,999.,999.,999.,999. */
- 13.9,15.1,15.8,16.5,17.2,18.9,20.1,48.,999.,999.,999.,999.
- };
-
- /* noise normalization **********/
-
- static int _noise_start_short_44[11]={
- /* 16,16,16,16,32,32,9999,9999,9999,9999 */
- 32,16,16,16,32,9999,9999,9999,9999,9999,9999
- };
- static int _noise_start_long_44[11]={
- /* 128,128,128,256,512,512,9999,9999,9999,9999 */
- 256,128,128,256,512,9999,9999,9999,9999,9999,9999
- };
-
- static int _noise_part_short_44[11]={
- 8,8,8,8,8,8,8,8,8,8,8
- };
- static int _noise_part_long_44[11]={
- 32,32,32,32,32,32,32,32,32,32,32
- };
-
- static double _noise_thresh_44[11]={
- /* .2,.2,.3,.4,.5,.5,9999.,9999.,9999.,9999., */
- .2,.2,.2,.4,.6,9999.,9999.,9999.,9999.,9999.,9999.,
- };
-
- static double _noise_thresh_5only[2]={
- .5,.5,
- };
- /********* End of inlined file: psych_44.h *********/
-
- static double rate_mapping_44_stereo[12]={
- 22500.,32000.,40000.,48000.,56000.,64000.,
- 80000.,96000.,112000.,128000.,160000.,250001.
- };
-
- static double quality_mapping_44[12]={
- -.1,.0,.1,.2,.3,.4,.5,.6,.7,.8,.9,1.0
- };
-
- static int blocksize_short_44[11]={
- 512,256,256,256,256,256,256,256,256,256,256
- };
- static int blocksize_long_44[11]={
- 4096,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048
- };
-
- static double _psy_compand_short_mapping[12]={
- 0.5, 1., 1., 1.3, 1.6, 2., 2., 2., 2., 2., 2., 2.
- };
- static double _psy_compand_long_mapping[12]={
- 3.5, 4., 4., 4.3, 4.6, 5., 5., 5., 5., 5., 5., 5.
- };
-
- static double _global_mapping_44[12]={
- /* 1., 1., 1.5, 2., 2., 2.5, 2.7, 3.0, 3.5, 4., 4. */
- 0., 1., 1., 1.5, 2., 2., 2.5, 2.7, 3.0, 3.7, 4., 4.
- };
-
- static int _floor_short_mapping_44[11]={
- 1,0,0,2,2,4,5,5,5,5,5
- };
- static int _floor_long_mapping_44[11]={
- 8,7,7,7,7,7,7,7,7,7,7
- };
-
- ve_setup_data_template ve_setup_44_stereo={
- 11,
- rate_mapping_44_stereo,
- quality_mapping_44,
- 2,
- 40000,
- 50000,
-
- blocksize_short_44,
- blocksize_long_44,
-
- _psy_tone_masteratt_44,
- _psy_tone_0dB,
- _psy_tone_suppress,
-
- _vp_tonemask_adj_otherblock,
- _vp_tonemask_adj_longblock,
- _vp_tonemask_adj_otherblock,
-
- _psy_noiseguards_44,
- _psy_noisebias_impulse,
- _psy_noisebias_padding,
- _psy_noisebias_trans,
- _psy_noisebias_long,
- _psy_noise_suppress,
-
- _psy_compand_44,
- _psy_compand_short_mapping,
- _psy_compand_long_mapping,
-
- {_noise_start_short_44,_noise_start_long_44},
- {_noise_part_short_44,_noise_part_long_44},
- _noise_thresh_44,
-
- _psy_ath_floater,
- _psy_ath_abs,
-
- _psy_lowpass_44,
-
- _psy_global_44,
- _global_mapping_44,
- _psy_stereo_modes_44,
-
- _floor_books,
- _floor,
- _floor_short_mapping_44,
- _floor_long_mapping_44,
-
- _mapres_template_44_stereo
- };
- /********* End of inlined file: setup_44.h *********/
-
- /********* Start of inlined file: setup_44u.h *********/
-
- /********* Start of inlined file: residue_44u.h *********/
-
- /********* Start of inlined file: res_books_uncoupled.h *********/
-
- static long _vq_quantlist__16u0__p1_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__16u0__p1_0[] = {
- 1, 4, 4, 5, 7, 7, 5, 7, 8, 5, 8, 8, 8,10,10, 8,
- 10,11, 5, 8, 8, 8,10,10, 8,10,10, 4, 9, 9, 9,12,
- 11, 8,11,11, 8,12,11,10,12,14,10,13,13, 7,11,11,
- 10,14,12,11,14,14, 4, 9, 9, 8,11,11, 9,11,12, 7,
- 11,11,10,13,14,10,12,14, 8,11,12,10,14,14,10,13,
- 12,
- };
-
- static float _vq_quantthresh__16u0__p1_0[] = {
- -0.5, 0.5,
- };
-
- static long _vq_quantmap__16u0__p1_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__16u0__p1_0 = {
- _vq_quantthresh__16u0__p1_0,
- _vq_quantmap__16u0__p1_0,
- 3,
- 3
- };
-
- static static_codebook _16u0__p1_0 = {
- 4, 81,
- _vq_lengthlist__16u0__p1_0,
- 1, -535822336, 1611661312, 2, 0,
- _vq_quantlist__16u0__p1_0,
- NULL,
- &_vq_auxt__16u0__p1_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16u0__p2_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__16u0__p2_0[] = {
- 2, 4, 4, 5, 6, 6, 5, 6, 6, 5, 7, 7, 7, 8, 9, 7,
- 8, 9, 5, 7, 7, 7, 9, 8, 7, 9, 7, 4, 7, 7, 7, 9,
- 9, 7, 8, 8, 6, 9, 8, 7, 8,11, 9,11,10, 6, 8, 9,
- 8,11, 8, 9,10,11, 4, 7, 7, 7, 8, 8, 7, 9, 9, 6,
- 9, 8, 9,11,10, 8, 8,11, 6, 8, 9, 9,10,11, 8,11,
- 8,
- };
-
- static float _vq_quantthresh__16u0__p2_0[] = {
- -0.5, 0.5,
- };
-
- static long _vq_quantmap__16u0__p2_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__16u0__p2_0 = {
- _vq_quantthresh__16u0__p2_0,
- _vq_quantmap__16u0__p2_0,
- 3,
- 3
- };
-
- static static_codebook _16u0__p2_0 = {
- 4, 81,
- _vq_lengthlist__16u0__p2_0,
- 1, -535822336, 1611661312, 2, 0,
- _vq_quantlist__16u0__p2_0,
- NULL,
- &_vq_auxt__16u0__p2_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16u0__p3_0[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__16u0__p3_0[] = {
- 1, 5, 5, 7, 7, 6, 7, 7, 8, 8, 6, 7, 8, 8, 8, 8,
- 9, 9,11,11, 8, 9, 9,11,11, 6, 9, 8,10,10, 8,10,
- 10,11,11, 8,10,10,11,11,10,11,10,13,12, 9,11,10,
- 13,13, 6, 8, 9,10,10, 8,10,10,11,11, 8,10,10,11,
- 11, 9,10,11,13,12,10,10,11,12,12, 8,11,11,14,13,
- 10,12,11,15,13, 9,12,11,15,14,12,14,13,16,14,12,
- 13,13,17,14, 8,11,11,13,14, 9,11,12,14,15,10,11,
- 12,13,15,11,13,13,14,16,12,13,14,14,16, 5, 9, 9,
- 11,11, 9,11,11,12,12, 8,11,11,12,12,11,12,12,15,
- 14,10,12,12,15,15, 8,11,11,13,12,10,12,12,13,13,
- 10,12,12,14,13,12,12,13,14,15,11,13,13,17,16, 7,
- 11,11,13,13,10,12,12,14,13,10,12,12,13,14,12,13,
- 12,15,14,11,13,13,15,14, 9,12,12,16,15,11,13,13,
- 17,16,10,13,13,16,16,13,14,15,15,16,13,15,14,19,
- 17, 9,12,12,14,16,11,13,13,15,16,10,13,13,17,16,
- 13,14,13,17,15,12,15,15,16,17, 5, 9, 9,11,11, 8,
- 11,11,13,12, 9,11,11,12,12,10,12,12,14,15,11,12,
- 12,14,14, 7,11,10,13,12,10,12,12,14,13,10,11,12,
- 13,13,11,13,13,15,16,12,12,13,15,15, 7,11,11,13,
- 13,10,13,13,14,14,10,12,12,13,13,11,13,13,16,15,
- 12,13,13,15,14, 9,12,12,15,15,10,13,13,17,16,11,
- 12,13,15,15,12,15,14,18,18,13,14,14,16,17, 9,12,
- 12,15,16,10,13,13,15,16,11,13,13,15,16,13,15,15,
- 17,17,13,15,14,16,15, 7,11,11,15,16,10,13,12,16,
- 17,10,12,13,15,17,15,16,16,18,17,13,15,15,17,18,
- 8,12,12,16,16,11,13,14,17,18,11,13,13,18,16,15,
- 17,16,17,19,14,15,15,17,16, 8,12,12,16,15,11,14,
- 13,18,17,11,13,14,18,17,15,16,16,18,17,13,16,16,
- 18,18,11,15,14,18,17,13,14,15,18, 0,12,15,15, 0,
- 17,17,16,17,17,18,14,16,18,18, 0,11,14,14,17, 0,
- 12,15,14,17,19,12,15,14,18, 0,15,18,16, 0,17,14,
- 18,16,18, 0, 7,11,11,16,15,10,12,12,18,16,10,13,
- 13,16,15,13,15,14,17,17,14,16,16,19,18, 8,12,12,
- 16,16,11,13,13,18,16,11,13,14,17,16,14,15,15,19,
- 18,15,16,16, 0,19, 8,12,12,16,17,11,13,13,17,17,
- 11,14,13,17,17,13,15,15,17,19,15,17,17,19, 0,11,
- 14,15,19,17,12,15,16,18,18,12,14,15,19,17,14,16,
- 17, 0,18,16,16,19,17, 0,11,14,14,18,19,12,15,14,
- 17,17,13,16,14,17,16,14,17,16,18,18,15,18,15, 0,
- 18,
- };
-
- static float _vq_quantthresh__16u0__p3_0[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__16u0__p3_0[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__16u0__p3_0 = {
- _vq_quantthresh__16u0__p3_0,
- _vq_quantmap__16u0__p3_0,
- 5,
- 5
- };
-
- static static_codebook _16u0__p3_0 = {
- 4, 625,
- _vq_lengthlist__16u0__p3_0,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__16u0__p3_0,
- NULL,
- &_vq_auxt__16u0__p3_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16u0__p4_0[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__16u0__p4_0[] = {
- 3, 5, 5, 8, 8, 6, 6, 6, 9, 9, 6, 6, 6, 9, 9, 9,
- 10, 9,11,11, 9, 9, 9,11,11, 6, 7, 7,10,10, 7, 7,
- 8,10,10, 7, 7, 8,10,10,10,10,10,11,12, 9,10,10,
- 11,12, 6, 7, 7,10,10, 7, 8, 7,10,10, 7, 8, 7,10,
- 10,10,11,10,12,11,10,10,10,13,10, 9,10,10,12,12,
- 10,11,10,14,12, 9,11,11,13,13,11,12,13,13,13,11,
- 12,12,15,13, 9,10,10,12,13, 9,11,10,12,13,10,10,
- 11,12,13,11,12,12,12,13,11,12,12,13,13, 5, 7, 7,
- 10,10, 7, 8, 8,10,10, 7, 8, 8,10,10,10,11,10,12,
- 13,10,10,11,12,12, 6, 8, 8,11,10, 7, 8, 9,10,12,
- 8, 9, 9,11,11,11,10,11,11,12,10,11,11,13,12, 7,
- 8, 8,10,11, 8, 9, 8,11,10, 8, 9, 9,11,11,10,12,
- 10,13,11,10,11,11,13,13,10,11,10,14,13,10,10,11,
- 13,13,10,12,11,14,13,12,11,13,12,13,13,12,13,14,
- 14,10,11,11,13,13,10,11,10,12,13,10,12,12,12,14,
- 12,12,12,14,12,12,13,12,17,15, 5, 7, 7,10,10, 7,
- 8, 8,10,10, 7, 8, 8,11,10,10,10,11,12,12,10,11,
- 11,12,13, 6, 8, 8,11,10, 8, 9, 9,11,11, 7, 8, 9,
- 10,11,11,11,11,12,12,10,10,11,12,13, 6, 8, 8,10,
- 11, 8, 9, 9,11,11, 7, 9, 7,11,10,10,12,12,13,13,
- 11,11,10,13,11, 9,11,10,14,13,11,11,11,15,13,10,
- 10,11,13,13,12,13,13,14,14,12,11,12,12,13,10,11,
- 11,12,13,10,11,12,13,13,10,11,10,13,12,12,12,13,
- 14, 0,12,13,11,13,11, 8,10,10,13,13,10,11,11,14,
- 13,10,11,11,13,12,13,14,14,14,15,12,12,12,15,14,
- 9,11,10,13,12,10,10,11,13,14,11,11,11,15,12,13,
- 12,14,15,16,13,13,13,14,13, 9,11,11,12,12,10,12,
- 11,13,13,10,11,11,13,14,13,13,13,15,15,13,13,14,
- 17,15,11,12,12,14,14,10,11,12,13,15,12,13,13, 0,
- 15,13,11,14,12,16,14,16,14, 0,15,11,12,12,14,16,
- 11,13,12,16,15,12,13,13,14,15,12,14,12,15,13,15,
- 14,14,16,16, 8,10,10,13,13,10,11,10,13,14,10,11,
- 11,13,13,13,13,12,14,14,14,13,13,16,17, 9,10,10,
- 12,14,10,12,11,14,13,10,11,12,13,14,12,12,12,15,
- 15,13,13,13,14,14, 9,10,10,13,13,10,11,12,12,14,
- 10,11,10,13,13,13,13,13,14,16,13,13,13,14,14,11,
- 12,13,15,13,12,14,13,14,16,12,12,13,13,14,13,14,
- 14,17,15,13,12,17,13,16,11,12,13,14,15,12,13,14,
- 14,17,11,12,11,14,14,13,16,14,16, 0,14,15,11,15,
- 11,
- };
-
- static float _vq_quantthresh__16u0__p4_0[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__16u0__p4_0[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__16u0__p4_0 = {
- _vq_quantthresh__16u0__p4_0,
- _vq_quantmap__16u0__p4_0,
- 5,
- 5
- };
-
- static static_codebook _16u0__p4_0 = {
- 4, 625,
- _vq_lengthlist__16u0__p4_0,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__16u0__p4_0,
- NULL,
- &_vq_auxt__16u0__p4_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16u0__p5_0[] = {
- 4,
- 3,
- 5,
- 2,
- 6,
- 1,
- 7,
- 0,
- 8,
- };
-
- static long _vq_lengthlist__16u0__p5_0[] = {
- 1, 4, 4, 7, 7, 7, 7, 9, 9, 4, 6, 6, 8, 8, 8, 8,
- 9, 9, 4, 6, 6, 8, 8, 8, 8, 9, 9, 7, 8, 8, 9, 9,
- 9, 9,11,10, 7, 8, 8, 9, 9, 9, 9,10,11, 7, 8, 8,
- 9, 9,10,10,11,11, 7, 8, 8, 9, 9,10,10,11,11, 9,
- 9, 9,10,10,11,11,12,12, 9, 9, 9,10,10,11,11,12,
- 12,
- };
-
- static float _vq_quantthresh__16u0__p5_0[] = {
- -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5,
- };
-
- static long _vq_quantmap__16u0__p5_0[] = {
- 7, 5, 3, 1, 0, 2, 4, 6,
- 8,
- };
-
- static encode_aux_threshmatch _vq_auxt__16u0__p5_0 = {
- _vq_quantthresh__16u0__p5_0,
- _vq_quantmap__16u0__p5_0,
- 9,
- 9
- };
-
- static static_codebook _16u0__p5_0 = {
- 2, 81,
- _vq_lengthlist__16u0__p5_0,
- 1, -531628032, 1611661312, 4, 0,
- _vq_quantlist__16u0__p5_0,
- NULL,
- &_vq_auxt__16u0__p5_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16u0__p6_0[] = {
- 6,
- 5,
- 7,
- 4,
- 8,
- 3,
- 9,
- 2,
- 10,
- 1,
- 11,
- 0,
- 12,
- };
-
- static long _vq_lengthlist__16u0__p6_0[] = {
- 1, 4, 4, 7, 7,10,10,12,12,13,13,18,17, 3, 6, 6,
- 9, 9,11,11,13,13,14,14,18,17, 3, 6, 6, 9, 9,11,
- 11,13,13,14,14,17,18, 7, 9, 9,11,11,13,13,14,14,
- 15,15, 0, 0, 7, 9, 9,11,11,13,13,14,14,15,16,19,
- 18,10,11,11,13,13,14,14,16,15,17,18, 0, 0,10,11,
- 11,13,13,14,14,15,15,16,18, 0, 0,11,13,13,14,14,
- 15,15,17,17, 0,19, 0, 0,11,13,13,14,14,14,15,16,
- 18, 0,19, 0, 0,13,14,14,15,15,18,17,18,18, 0,19,
- 0, 0,13,14,14,15,16,16,16,18,18,19, 0, 0, 0,16,
- 17,17, 0,17,19,19, 0,19, 0, 0, 0, 0,16,19,16,17,
- 18, 0,19, 0, 0, 0, 0, 0, 0,
- };
-
- static float _vq_quantthresh__16u0__p6_0[] = {
- -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5,
- 12.5, 17.5, 22.5, 27.5,
- };
-
- static long _vq_quantmap__16u0__p6_0[] = {
- 11, 9, 7, 5, 3, 1, 0, 2,
- 4, 6, 8, 10, 12,
- };
-
- static encode_aux_threshmatch _vq_auxt__16u0__p6_0 = {
- _vq_quantthresh__16u0__p6_0,
- _vq_quantmap__16u0__p6_0,
- 13,
- 13
- };
-
- static static_codebook _16u0__p6_0 = {
- 2, 169,
- _vq_lengthlist__16u0__p6_0,
- 1, -526516224, 1616117760, 4, 0,
- _vq_quantlist__16u0__p6_0,
- NULL,
- &_vq_auxt__16u0__p6_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16u0__p6_1[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__16u0__p6_1[] = {
- 1, 4, 5, 6, 6, 4, 6, 6, 6, 6, 4, 6, 6, 6, 6, 6,
- 6, 6, 7, 7, 6, 6, 6, 7, 7,
- };
-
- static float _vq_quantthresh__16u0__p6_1[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__16u0__p6_1[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__16u0__p6_1 = {
- _vq_quantthresh__16u0__p6_1,
- _vq_quantmap__16u0__p6_1,
- 5,
- 5
- };
-
- static static_codebook _16u0__p6_1 = {
- 2, 25,
- _vq_lengthlist__16u0__p6_1,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__16u0__p6_1,
- NULL,
- &_vq_auxt__16u0__p6_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16u0__p7_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__16u0__p7_0[] = {
- 1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7,
- };
-
- static float _vq_quantthresh__16u0__p7_0[] = {
- -157.5, 157.5,
- };
-
- static long _vq_quantmap__16u0__p7_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__16u0__p7_0 = {
- _vq_quantthresh__16u0__p7_0,
- _vq_quantmap__16u0__p7_0,
- 3,
- 3
- };
-
- static static_codebook _16u0__p7_0 = {
- 4, 81,
- _vq_lengthlist__16u0__p7_0,
- 1, -518803456, 1628680192, 2, 0,
- _vq_quantlist__16u0__p7_0,
- NULL,
- &_vq_auxt__16u0__p7_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16u0__p7_1[] = {
- 7,
- 6,
- 8,
- 5,
- 9,
- 4,
- 10,
- 3,
- 11,
- 2,
- 12,
- 1,
- 13,
- 0,
- 14,
- };
-
- static long _vq_lengthlist__16u0__p7_1[] = {
- 1, 5, 5, 6, 5, 9,10,11,11,10,10,10,10,10,10, 5,
- 8, 8, 8,10,10,10,10,10,10,10,10,10,10,10, 5, 8,
- 9, 9, 9,10,10,10,10,10,10,10,10,10,10, 5,10, 8,
- 10,10,10,10,10,10,10,10,10,10,10,10, 4, 8, 9,10,
- 10,10,10,10,10,10,10,10,10,10,10, 9,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10, 9,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,
- };
-
- static float _vq_quantthresh__16u0__p7_1[] = {
- -136.5, -115.5, -94.5, -73.5, -52.5, -31.5, -10.5, 10.5,
- 31.5, 52.5, 73.5, 94.5, 115.5, 136.5,
- };
-
- static long _vq_quantmap__16u0__p7_1[] = {
- 13, 11, 9, 7, 5, 3, 1, 0,
- 2, 4, 6, 8, 10, 12, 14,
- };
-
- static encode_aux_threshmatch _vq_auxt__16u0__p7_1 = {
- _vq_quantthresh__16u0__p7_1,
- _vq_quantmap__16u0__p7_1,
- 15,
- 15
- };
-
- static static_codebook _16u0__p7_1 = {
- 2, 225,
- _vq_lengthlist__16u0__p7_1,
- 1, -520986624, 1620377600, 4, 0,
- _vq_quantlist__16u0__p7_1,
- NULL,
- &_vq_auxt__16u0__p7_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16u0__p7_2[] = {
- 10,
- 9,
- 11,
- 8,
- 12,
- 7,
- 13,
- 6,
- 14,
- 5,
- 15,
- 4,
- 16,
- 3,
- 17,
- 2,
- 18,
- 1,
- 19,
- 0,
- 20,
- };
-
- static long _vq_lengthlist__16u0__p7_2[] = {
- 1, 6, 6, 7, 8, 7, 7,10, 9,10, 9,11,10, 9,11,10,
- 9, 9, 9, 9,10, 6, 8, 7, 9, 9, 8, 8,10,10, 9,11,
- 11,12,12,10, 9,11, 9,12,10, 9, 6, 9, 8, 9,12, 8,
- 8,11, 9,11,11,12,11,12,12,10,11,11,10,10,11, 7,
- 10, 9, 9, 9, 9, 9,10, 9,10, 9,10,10,12,10,10,10,
- 11,12,10,10, 7, 9, 9, 9,10, 9, 9,10,10, 9, 9, 9,
- 11,11,10,10,10,10, 9, 9,12, 7, 9,10, 9,11, 9,10,
- 9,10,11,11,11,10,11,12, 9,12,11,10,10,10, 7, 9,
- 9, 9, 9,10,12,10, 9,11,12,10,11,12,12,11, 9,10,
- 11,10,11, 7, 9,10,10,11,10, 9,10,11,11,11,10,12,
- 12,12,11,11,10,11,11,12, 8, 9,10,12,11,10,10,12,
- 12,12,12,12,10,11,11, 9,11,10,12,11,11, 8, 9,10,
- 10,11,12,11,11,10,10,10,12,12,12, 9,10,12,12,12,
- 12,12, 8,10,11,10,10,12, 9,11,12,12,11,12,12,12,
- 12,10,12,10,10,10,10, 8,12,11,11,11,10,10,11,12,
- 12,12,12,11,12,12,12,11,11,11,12,10, 9,10,10,12,
- 10,12,10,12,12,10,10,10,11,12,12,12,11,12,12,12,
- 11,10,11,12,12,12,11,12,12,11,12,12,11,12,12,12,
- 12,11,12,12,10,10,10,10,11,11,12,11,12,12,12,12,
- 12,12,12,11,12,11,10,11,11,12,11,11, 9,10,10,10,
- 12,10,10,11, 9,11,12,11,12,11,12,12,10,11,10,12,
- 9, 9, 9,12,11,10,11,10,12,10,12,10,12,12,12,11,
- 11,11,11,11,10, 9,10,10,11,10,11,11,12,11,10,11,
- 12,12,12,11,11, 9,12,10,12, 9,10,12,10,10,11,10,
- 11,11,12,11,10,11,10,11,11,11,11,12,11,11,10, 9,
- 10,10,10, 9,11,11,10, 9,12,10,11,12,11,12,12,11,
- 12,11,12,11,10,11,10,12,11,12,11,12,11,12,10,11,
- 10,10,12,11,10,11,11,11,10,
- };
-
- static float _vq_quantthresh__16u0__p7_2[] = {
- -9.5, -8.5, -7.5, -6.5, -5.5, -4.5, -3.5, -2.5,
- -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5.5,
- 6.5, 7.5, 8.5, 9.5,
- };
-
- static long _vq_quantmap__16u0__p7_2[] = {
- 19, 17, 15, 13, 11, 9, 7, 5,
- 3, 1, 0, 2, 4, 6, 8, 10,
- 12, 14, 16, 18, 20,
- };
-
- static encode_aux_threshmatch _vq_auxt__16u0__p7_2 = {
- _vq_quantthresh__16u0__p7_2,
- _vq_quantmap__16u0__p7_2,
- 21,
- 21
- };
-
- static static_codebook _16u0__p7_2 = {
- 2, 441,
- _vq_lengthlist__16u0__p7_2,
- 1, -529268736, 1611661312, 5, 0,
- _vq_quantlist__16u0__p7_2,
- NULL,
- &_vq_auxt__16u0__p7_2,
- NULL,
- 0
- };
-
- static long _huff_lengthlist__16u0__single[] = {
- 3, 5, 8, 7,14, 8, 9,19, 5, 2, 5, 5, 9, 6, 9,19,
- 8, 4, 5, 7, 8, 9,13,19, 7, 4, 6, 5, 9, 6, 9,19,
- 12, 8, 7, 9,10,11,13,19, 8, 5, 8, 6, 9, 6, 7,19,
- 8, 8,10, 7, 7, 4, 5,19,12,17,19,15,18,13,11,18,
- };
-
- static static_codebook _huff_book__16u0__single = {
- 2, 64,
- _huff_lengthlist__16u0__single,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist__16u1__long[] = {
- 3, 6,10, 8,12, 8,14, 8,14,19, 5, 3, 5, 5, 7, 6,
- 11, 7,16,19, 7, 5, 6, 7, 7, 9,11,12,19,19, 6, 4,
- 7, 5, 7, 6,10, 7,18,18, 8, 6, 7, 7, 7, 7, 8, 9,
- 18,18, 7, 5, 8, 5, 7, 5, 8, 6,18,18,12, 9,10, 9,
- 9, 9, 8, 9,18,18, 8, 7,10, 6, 8, 5, 6, 4,11,18,
- 11,15,16,12,11, 8, 8, 6, 9,18,14,18,18,18,16,16,
- 16,13,16,18,
- };
-
- static static_codebook _huff_book__16u1__long = {
- 2, 100,
- _huff_lengthlist__16u1__long,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16u1__p1_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__16u1__p1_0[] = {
- 1, 4, 4, 5, 7, 7, 5, 7, 7, 5, 8, 7, 7,10,10, 7,
- 9,10, 5, 7, 8, 7,10, 9, 7,10,10, 5, 8, 8, 8,10,
- 10, 8,10,10, 7,10,10,10,11,12,10,12,13, 7,10,10,
- 9,13,11,10,12,13, 5, 8, 8, 8,10,10, 8,10,10, 7,
- 10,10,10,12,12, 9,11,12, 7,10,11,10,12,12,10,13,
- 11,
- };
-
- static float _vq_quantthresh__16u1__p1_0[] = {
- -0.5, 0.5,
- };
-
- static long _vq_quantmap__16u1__p1_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__16u1__p1_0 = {
- _vq_quantthresh__16u1__p1_0,
- _vq_quantmap__16u1__p1_0,
- 3,
- 3
- };
-
- static static_codebook _16u1__p1_0 = {
- 4, 81,
- _vq_lengthlist__16u1__p1_0,
- 1, -535822336, 1611661312, 2, 0,
- _vq_quantlist__16u1__p1_0,
- NULL,
- &_vq_auxt__16u1__p1_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16u1__p2_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__16u1__p2_0[] = {
- 3, 4, 4, 5, 6, 6, 5, 6, 6, 5, 6, 6, 6, 7, 8, 6,
- 7, 8, 5, 6, 6, 6, 8, 7, 6, 8, 7, 5, 6, 6, 6, 8,
- 8, 6, 8, 8, 6, 8, 8, 7, 7,10, 8, 9, 9, 6, 8, 8,
- 7, 9, 8, 8, 9,10, 5, 6, 6, 6, 8, 8, 7, 8, 8, 6,
- 8, 8, 8,10, 9, 7, 8, 9, 6, 8, 8, 8, 9, 9, 7,10,
- 8,
- };
-
- static float _vq_quantthresh__16u1__p2_0[] = {
- -0.5, 0.5,
- };
-
- static long _vq_quantmap__16u1__p2_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__16u1__p2_0 = {
- _vq_quantthresh__16u1__p2_0,
- _vq_quantmap__16u1__p2_0,
- 3,
- 3
- };
-
- static static_codebook _16u1__p2_0 = {
- 4, 81,
- _vq_lengthlist__16u1__p2_0,
- 1, -535822336, 1611661312, 2, 0,
- _vq_quantlist__16u1__p2_0,
- NULL,
- &_vq_auxt__16u1__p2_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16u1__p3_0[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__16u1__p3_0[] = {
- 1, 5, 5, 8, 8, 6, 7, 7, 9, 9, 5, 7, 7, 9, 9, 9,
- 10, 9,11,11, 9, 9,10,11,11, 6, 8, 8,10,10, 8, 9,
- 10,11,11, 8, 9,10,11,11,10,11,11,12,13,10,11,11,
- 13,13, 6, 8, 8,10,10, 8,10, 9,11,11, 8,10, 9,11,
- 11,10,11,11,13,13,10,11,11,13,12, 9,11,11,14,13,
- 10,12,12,15,14,10,12,11,14,13,12,13,13,15,15,12,
- 13,13,16,14, 9,11,11,13,14,10,11,12,14,14,10,12,
- 12,14,15,12,13,13,14,15,12,13,14,15,16, 5, 8, 8,
- 11,11, 8,10,10,12,12, 8,10,10,12,12,11,12,12,14,
- 14,11,12,12,14,14, 8,10,10,12,12, 9,11,12,12,13,
- 10,12,12,13,13,12,12,13,14,15,11,13,13,15,15, 7,
- 10,10,12,12, 9,12,11,13,12,10,11,12,13,13,12,13,
- 12,15,14,11,12,13,15,15,10,12,12,15,14,11,13,13,
- 16,15,11,13,13,16,15,14,13,14,15,16,13,15,15,17,
- 17,10,12,12,14,15,11,12,12,15,15,11,13,13,15,16,
- 13,15,13,16,15,13,15,15,16,17, 5, 8, 8,11,11, 8,
- 10,10,12,12, 8,10,10,12,12,11,12,12,14,14,11,12,
- 12,14,14, 7,10,10,12,12,10,12,12,14,13, 9,11,12,
- 12,13,12,13,13,15,15,12,12,13,13,15, 7,10,10,12,
- 13,10,11,12,13,13,10,12,11,13,13,11,13,13,15,15,
- 12,13,12,15,14, 9,12,12,15,14,11,13,13,15,15,11,
- 12,13,15,15,13,14,14,17,19,13,13,14,16,16,10,12,
- 12,14,15,11,13,13,15,16,11,13,12,16,15,13,15,15,
- 17,18,14,15,13,16,15, 8,11,11,15,14,10,12,12,16,
- 15,10,12,12,16,16,14,15,15,18,17,13,14,15,16,18,
- 9,12,12,15,15,11,12,14,16,17,11,13,13,16,15,15,
- 15,15,17,18,14,15,16,17,17, 9,12,12,15,15,11,14,
- 13,16,16,11,13,13,16,16,15,16,15,17,18,14,16,15,
- 17,16,12,14,14,17,16,12,14,15,18,17,13,15,15,17,
- 17,15,15,18,16,20,15,16,17,18,18,11,14,14,16,17,
- 13,15,14,18,17,13,15,15,17,17,15,17,15,18,17,15,
- 17,16,19,18, 8,11,11,14,15,10,12,12,15,15,10,12,
- 12,16,16,13,14,14,17,16,14,15,15,17,17, 9,12,12,
- 15,16,11,13,13,16,16,11,12,13,16,16,14,16,15,20,
- 17,14,16,16,17,17, 9,12,12,15,16,11,13,13,16,17,
- 11,13,13,17,16,14,15,15,17,18,15,15,15,18,18,11,
- 14,14,17,16,13,15,15,17,17,13,14,14,18,17,15,16,
- 16,18,19,15,15,17,17,19,11,14,14,16,17,13,15,14,
- 17,19,13,15,14,18,17,15,17,16,18,18,15,17,15,18,
- 16,
- };
-
- static float _vq_quantthresh__16u1__p3_0[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__16u1__p3_0[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__16u1__p3_0 = {
- _vq_quantthresh__16u1__p3_0,
- _vq_quantmap__16u1__p3_0,
- 5,
- 5
- };
-
- static static_codebook _16u1__p3_0 = {
- 4, 625,
- _vq_lengthlist__16u1__p3_0,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__16u1__p3_0,
- NULL,
- &_vq_auxt__16u1__p3_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16u1__p4_0[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__16u1__p4_0[] = {
- 4, 5, 5, 8, 8, 6, 6, 7, 9, 9, 6, 6, 6, 9, 9, 9,
- 10, 9,11,11, 9, 9,10,11,11, 6, 7, 7,10, 9, 7, 7,
- 8, 9,10, 7, 7, 8,10,10,10,10,10,10,12, 9, 9,10,
- 11,12, 6, 7, 7, 9, 9, 7, 8, 7,10,10, 7, 8, 7,10,
- 10, 9,10, 9,12,11,10,10, 9,12,10, 9,10,10,12,11,
- 10,10,10,12,12, 9,10,10,12,12,12,11,12,13,13,11,
- 11,12,12,13, 9,10,10,11,12, 9,10,10,12,12,10,10,
- 10,12,12,11,12,11,14,13,11,12,12,14,13, 5, 7, 7,
- 10,10, 7, 8, 8,10,10, 7, 8, 7,10,10,10,10,10,12,
- 12,10,10,10,12,12, 6, 8, 7,10,10, 7, 7, 9,10,11,
- 8, 9, 9,11,10,10,10,11,11,13,10,10,11,12,13, 6,
- 8, 8,10,10, 7, 9, 8,11,10, 8, 9, 9,10,11,10,11,
- 10,13,11,10,11,10,12,12,10,11,10,12,11,10,10,10,
- 12,13,10,11,11,13,12,11,11,13,11,14,12,12,13,14,
- 14, 9,10,10,12,13,10,11,10,13,12,10,11,11,12,13,
- 11,12,11,14,12,12,13,13,15,14, 5, 7, 7,10,10, 7,
- 7, 8,10,10, 7, 8, 8,10,10,10,10,10,11,12,10,10,
- 10,12,12, 7, 8, 8,10,10, 8, 9, 8,11,10, 7, 8, 9,
- 10,11,10,11,11,12,12,10,10,11,11,13, 7, 7, 8,10,
- 10, 8, 8, 9,10,11, 7, 9, 7,11,10,10,11,11,13,12,
- 11,11,10,13,11, 9,10,10,12,12,10,11,11,13,12,10,
- 10,11,12,12,12,13,13,14,14,11,11,12,12,14,10,10,
- 11,12,12,10,11,11,12,13,10,10,10,13,12,12,13,13,
- 15,14,12,13,10,14,11, 8,10,10,12,12,10,11,10,13,
- 13, 9,10,10,12,12,12,13,13,15,14,11,12,12,13,13,
- 9,10,10,13,12,10,10,11,13,13,10,11,10,13,12,12,
- 12,13,14,15,12,13,12,15,13, 9,10,10,12,13,10,11,
- 10,13,12,10,10,11,12,13,12,14,12,15,13,12,12,13,
- 14,15,11,12,11,14,13,11,11,12,14,15,12,13,12,15,
- 14,13,11,15,11,16,13,14,14,16,15,11,12,12,14,14,
- 11,12,11,14,13,12,12,13,14,15,13,14,12,16,12,14,
- 14,14,15,15, 8,10,10,12,12, 9,10,10,12,12,10,10,
- 11,13,13,11,12,12,13,13,12,13,13,14,15, 9,10,10,
- 13,12,10,11,11,13,12,10,10,11,13,13,12,13,12,15,
- 14,12,12,13,13,16, 9, 9,10,12,13,10,10,11,12,13,
- 10,11,10,13,13,12,12,13,13,15,13,13,12,15,13,11,
- 12,12,14,14,12,13,12,15,14,11,11,12,13,14,14,14,
- 14,16,15,13,12,15,12,16,11,11,12,13,14,12,13,13,
- 14,15,10,12,11,14,13,14,15,14,16,16,13,14,11,15,
- 11,
- };
-
- static float _vq_quantthresh__16u1__p4_0[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__16u1__p4_0[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__16u1__p4_0 = {
- _vq_quantthresh__16u1__p4_0,
- _vq_quantmap__16u1__p4_0,
- 5,
- 5
- };
-
- static static_codebook _16u1__p4_0 = {
- 4, 625,
- _vq_lengthlist__16u1__p4_0,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__16u1__p4_0,
- NULL,
- &_vq_auxt__16u1__p4_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16u1__p5_0[] = {
- 4,
- 3,
- 5,
- 2,
- 6,
- 1,
- 7,
- 0,
- 8,
- };
-
- static long _vq_lengthlist__16u1__p5_0[] = {
- 1, 4, 4, 7, 7, 7, 7, 9, 9, 4, 6, 6, 8, 8, 8, 8,
- 10,10, 4, 5, 6, 8, 8, 8, 8,10,10, 7, 8, 8, 9, 9,
- 9, 9,11,11, 7, 8, 8, 9, 9, 9, 9,11,11, 7, 8, 8,
- 10, 9,11,11,12,11, 7, 8, 8, 9, 9,11,11,12,12, 9,
- 10,10,11,11,12,12,13,12, 9,10,10,11,11,12,12,12,
- 13,
- };
-
- static float _vq_quantthresh__16u1__p5_0[] = {
- -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5,
- };
-
- static long _vq_quantmap__16u1__p5_0[] = {
- 7, 5, 3, 1, 0, 2, 4, 6,
- 8,
- };
-
- static encode_aux_threshmatch _vq_auxt__16u1__p5_0 = {
- _vq_quantthresh__16u1__p5_0,
- _vq_quantmap__16u1__p5_0,
- 9,
- 9
- };
-
- static static_codebook _16u1__p5_0 = {
- 2, 81,
- _vq_lengthlist__16u1__p5_0,
- 1, -531628032, 1611661312, 4, 0,
- _vq_quantlist__16u1__p5_0,
- NULL,
- &_vq_auxt__16u1__p5_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16u1__p6_0[] = {
- 4,
- 3,
- 5,
- 2,
- 6,
- 1,
- 7,
- 0,
- 8,
- };
-
- static long _vq_lengthlist__16u1__p6_0[] = {
- 3, 4, 4, 6, 6, 7, 7, 9, 9, 4, 4, 4, 6, 6, 8, 8,
- 9, 9, 4, 4, 4, 6, 6, 7, 7, 9, 9, 6, 6, 6, 7, 7,
- 8, 8,10, 9, 6, 6, 6, 7, 7, 8, 8, 9,10, 7, 8, 7,
- 8, 8, 9, 9,10,10, 7, 8, 8, 8, 8, 9, 9,10,10, 9,
- 9, 9,10,10,10,10,11,11, 9, 9, 9,10,10,10,10,11,
- 11,
- };
-
- static float _vq_quantthresh__16u1__p6_0[] = {
- -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5,
- };
-
- static long _vq_quantmap__16u1__p6_0[] = {
- 7, 5, 3, 1, 0, 2, 4, 6,
- 8,
- };
-
- static encode_aux_threshmatch _vq_auxt__16u1__p6_0 = {
- _vq_quantthresh__16u1__p6_0,
- _vq_quantmap__16u1__p6_0,
- 9,
- 9
- };
-
- static static_codebook _16u1__p6_0 = {
- 2, 81,
- _vq_lengthlist__16u1__p6_0,
- 1, -531628032, 1611661312, 4, 0,
- _vq_quantlist__16u1__p6_0,
- NULL,
- &_vq_auxt__16u1__p6_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16u1__p7_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__16u1__p7_0[] = {
- 1, 4, 4, 4, 8, 8, 4, 8, 8, 5,11, 9, 8,12,11, 8,
- 12,11, 5,10,11, 8,11,12, 8,11,12, 4,11,11,11,14,
- 13,10,13,13, 8,14,13,12,14,16,12,16,15, 8,14,14,
- 13,16,14,12,15,16, 4,11,11,10,14,13,11,14,14, 8,
- 15,14,12,15,15,12,14,16, 8,14,14,11,16,15,12,15,
- 13,
- };
-
- static float _vq_quantthresh__16u1__p7_0[] = {
- -5.5, 5.5,
- };
-
- static long _vq_quantmap__16u1__p7_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__16u1__p7_0 = {
- _vq_quantthresh__16u1__p7_0,
- _vq_quantmap__16u1__p7_0,
- 3,
- 3
- };
-
- static static_codebook _16u1__p7_0 = {
- 4, 81,
- _vq_lengthlist__16u1__p7_0,
- 1, -529137664, 1618345984, 2, 0,
- _vq_quantlist__16u1__p7_0,
- NULL,
- &_vq_auxt__16u1__p7_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16u1__p7_1[] = {
- 5,
- 4,
- 6,
- 3,
- 7,
- 2,
- 8,
- 1,
- 9,
- 0,
- 10,
- };
-
- static long _vq_lengthlist__16u1__p7_1[] = {
- 2, 4, 4, 6, 6, 7, 7, 8, 8, 8, 8, 4, 6, 5, 7, 7,
- 8, 8, 8, 8, 8, 8, 4, 5, 6, 7, 7, 8, 8, 8, 8, 8,
- 8, 6, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 6, 7, 7, 8,
- 8, 8, 8, 9, 9, 9, 9, 7, 8, 8, 8, 8, 9, 9, 9,10,
- 9,10, 7, 8, 8, 8, 8, 9, 9, 9, 9,10, 9, 8, 8, 8,
- 9, 9,10,10,10,10,10,10, 8, 8, 8, 9, 9, 9, 9,10,
- 10,10,10, 8, 8, 8, 9, 9, 9,10,10,10,10,10, 8, 8,
- 8, 9, 9,10,10,10,10,10,10,
- };
-
- static float _vq_quantthresh__16u1__p7_1[] = {
- -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5,
- 3.5, 4.5,
- };
-
- static long _vq_quantmap__16u1__p7_1[] = {
- 9, 7, 5, 3, 1, 0, 2, 4,
- 6, 8, 10,
- };
-
- static encode_aux_threshmatch _vq_auxt__16u1__p7_1 = {
- _vq_quantthresh__16u1__p7_1,
- _vq_quantmap__16u1__p7_1,
- 11,
- 11
- };
-
- static static_codebook _16u1__p7_1 = {
- 2, 121,
- _vq_lengthlist__16u1__p7_1,
- 1, -531365888, 1611661312, 4, 0,
- _vq_quantlist__16u1__p7_1,
- NULL,
- &_vq_auxt__16u1__p7_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16u1__p8_0[] = {
- 5,
- 4,
- 6,
- 3,
- 7,
- 2,
- 8,
- 1,
- 9,
- 0,
- 10,
- };
-
- static long _vq_lengthlist__16u1__p8_0[] = {
- 1, 4, 4, 5, 5, 8, 8,10,10,12,12, 4, 7, 7, 8, 8,
- 9, 9,12,11,14,13, 4, 7, 7, 7, 8, 9,10,11,11,13,
- 12, 5, 8, 8, 9, 9,11,11,12,13,15,14, 5, 7, 8, 9,
- 9,11,11,13,13,17,15, 8, 9,10,11,11,12,13,17,14,
- 17,16, 8,10, 9,11,11,12,12,13,15,15,17,10,11,11,
- 12,13,14,15,15,16,16,17, 9,11,11,12,12,14,15,17,
- 15,15,16,11,14,12,14,15,16,15,16,16,16,15,11,13,
- 13,14,14,15,15,16,16,15,16,
- };
-
- static float _vq_quantthresh__16u1__p8_0[] = {
- -49.5, -38.5, -27.5, -16.5, -5.5, 5.5, 16.5, 27.5,
- 38.5, 49.5,
- };
-
- static long _vq_quantmap__16u1__p8_0[] = {
- 9, 7, 5, 3, 1, 0, 2, 4,
- 6, 8, 10,
- };
-
- static encode_aux_threshmatch _vq_auxt__16u1__p8_0 = {
- _vq_quantthresh__16u1__p8_0,
- _vq_quantmap__16u1__p8_0,
- 11,
- 11
- };
-
- static static_codebook _16u1__p8_0 = {
- 2, 121,
- _vq_lengthlist__16u1__p8_0,
- 1, -524582912, 1618345984, 4, 0,
- _vq_quantlist__16u1__p8_0,
- NULL,
- &_vq_auxt__16u1__p8_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16u1__p8_1[] = {
- 5,
- 4,
- 6,
- 3,
- 7,
- 2,
- 8,
- 1,
- 9,
- 0,
- 10,
- };
-
- static long _vq_lengthlist__16u1__p8_1[] = {
- 2, 5, 5, 6, 6, 7, 7, 8, 8, 8, 8, 4, 6, 6, 7, 7,
- 8, 7, 8, 8, 8, 8, 4, 6, 6, 7, 7, 7, 7, 8, 8, 8,
- 8, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 9, 6, 7, 7, 7,
- 7, 8, 8, 8, 8, 9, 9, 7, 7, 7, 8, 8, 8, 8, 9, 9,
- 9, 9, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 8, 8, 8,
- 8, 8, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 9, 9, 9,
- 9, 9, 9, 8, 8, 8, 9, 8, 9, 9, 9, 9, 9, 9, 8, 8,
- 8, 9, 9, 9, 9, 9, 9, 9, 9,
- };
-
- static float _vq_quantthresh__16u1__p8_1[] = {
- -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5,
- 3.5, 4.5,
- };
-
- static long _vq_quantmap__16u1__p8_1[] = {
- 9, 7, 5, 3, 1, 0, 2, 4,
- 6, 8, 10,
- };
-
- static encode_aux_threshmatch _vq_auxt__16u1__p8_1 = {
- _vq_quantthresh__16u1__p8_1,
- _vq_quantmap__16u1__p8_1,
- 11,
- 11
- };
-
- static static_codebook _16u1__p8_1 = {
- 2, 121,
- _vq_lengthlist__16u1__p8_1,
- 1, -531365888, 1611661312, 4, 0,
- _vq_quantlist__16u1__p8_1,
- NULL,
- &_vq_auxt__16u1__p8_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16u1__p9_0[] = {
- 7,
- 6,
- 8,
- 5,
- 9,
- 4,
- 10,
- 3,
- 11,
- 2,
- 12,
- 1,
- 13,
- 0,
- 14,
- };
-
- static long _vq_lengthlist__16u1__p9_0[] = {
- 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8,
- };
-
- static float _vq_quantthresh__16u1__p9_0[] = {
- -1657.5, -1402.5, -1147.5, -892.5, -637.5, -382.5, -127.5, 127.5,
- 382.5, 637.5, 892.5, 1147.5, 1402.5, 1657.5,
- };
-
- static long _vq_quantmap__16u1__p9_0[] = {
- 13, 11, 9, 7, 5, 3, 1, 0,
- 2, 4, 6, 8, 10, 12, 14,
- };
-
- static encode_aux_threshmatch _vq_auxt__16u1__p9_0 = {
- _vq_quantthresh__16u1__p9_0,
- _vq_quantmap__16u1__p9_0,
- 15,
- 15
- };
-
- static static_codebook _16u1__p9_0 = {
- 2, 225,
- _vq_lengthlist__16u1__p9_0,
- 1, -514071552, 1627381760, 4, 0,
- _vq_quantlist__16u1__p9_0,
- NULL,
- &_vq_auxt__16u1__p9_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16u1__p9_1[] = {
- 7,
- 6,
- 8,
- 5,
- 9,
- 4,
- 10,
- 3,
- 11,
- 2,
- 12,
- 1,
- 13,
- 0,
- 14,
- };
-
- static long _vq_lengthlist__16u1__p9_1[] = {
- 1, 6, 5, 9, 9,10,10, 6, 7, 9, 9,10,10,10,10, 5,
- 10, 8,10, 8,10,10, 8, 8,10, 9,10,10,10,10, 5, 8,
- 9,10,10,10,10, 8,10,10,10,10,10,10,10, 9,10,10,
- 10,10,10,10, 9, 9,10,10,10,10,10,10, 9, 9, 8, 9,
- 10,10,10, 9,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10, 8,10,10,10,10,
- 10,10,10,10,10,10,10,10,10, 6, 8, 8,10,10,10, 8,
- 10,10,10,10,10,10,10,10, 5, 8, 8,10,10,10, 9, 9,
- 10,10,10,10,10,10,10,10, 9,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9,
- };
-
- static float _vq_quantthresh__16u1__p9_1[] = {
- -110.5, -93.5, -76.5, -59.5, -42.5, -25.5, -8.5, 8.5,
- 25.5, 42.5, 59.5, 76.5, 93.5, 110.5,
- };
-
- static long _vq_quantmap__16u1__p9_1[] = {
- 13, 11, 9, 7, 5, 3, 1, 0,
- 2, 4, 6, 8, 10, 12, 14,
- };
-
- static encode_aux_threshmatch _vq_auxt__16u1__p9_1 = {
- _vq_quantthresh__16u1__p9_1,
- _vq_quantmap__16u1__p9_1,
- 15,
- 15
- };
-
- static static_codebook _16u1__p9_1 = {
- 2, 225,
- _vq_lengthlist__16u1__p9_1,
- 1, -522338304, 1620115456, 4, 0,
- _vq_quantlist__16u1__p9_1,
- NULL,
- &_vq_auxt__16u1__p9_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16u1__p9_2[] = {
- 8,
- 7,
- 9,
- 6,
- 10,
- 5,
- 11,
- 4,
- 12,
- 3,
- 13,
- 2,
- 14,
- 1,
- 15,
- 0,
- 16,
- };
-
- static long _vq_lengthlist__16u1__p9_2[] = {
- 1, 6, 6, 7, 8, 8,11,10, 9, 9,11, 9,10, 9,11,11,
- 9, 6, 7, 6,11, 8,11, 9,10,10,11, 9,11,10,10,10,
- 11, 9, 5, 7, 7, 8, 8,10,11, 8, 8,11, 9, 9,10,11,
- 9,10,11, 8, 9, 6, 8, 8, 9, 9,10,10,11,11,11, 9,
- 11,10, 9,11, 8, 8, 8, 9, 8, 9,10,11, 9, 9,11,11,
- 10, 9, 9,11,10, 8,11, 8, 9, 8,11, 9,10, 9,10,11,
- 11,10,10, 9,10,10, 8, 8, 9,10,10,10, 9,11, 9,10,
- 11,11,11,11,10, 9,11, 9, 9,11,11,10, 8,11,11,11,
- 9,10,10,11,10,11,11, 9,11,10, 9,11,10,10,10,10,
- 9,11,10,11,10, 9, 9,10,11, 9, 8,10,11,11,10,10,
- 11, 9,11,10,11,11,10,11, 9, 9, 8,10, 8, 9,11, 9,
- 8,10,10, 9,11,10,11,10,11, 9,11, 8,10,11,11,11,
- 11,10,10,11,11,11,11,10,11,11,10, 9, 8,10,10, 9,
- 11,10,11,11,11, 9, 9, 9,11,11,11,10,10, 9, 9,10,
- 9,11,11,11,11, 8,10,11,10,11,11,10,11,11, 9, 9,
- 9,10, 9,11, 9,11,11,11,11,11,10,11,11,10,11,10,
- 11,11, 9,11,10,11,10, 9,10, 9,10,10,11,11,11,11,
- 9,10, 9,10,11,11,10,11,11,11,11,11,11,10,11,11,
- 10,
- };
-
- static float _vq_quantthresh__16u1__p9_2[] = {
- -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5,
- 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5,
- };
-
- static long _vq_quantmap__16u1__p9_2[] = {
- 15, 13, 11, 9, 7, 5, 3, 1,
- 0, 2, 4, 6, 8, 10, 12, 14,
- 16,
- };
-
- static encode_aux_threshmatch _vq_auxt__16u1__p9_2 = {
- _vq_quantthresh__16u1__p9_2,
- _vq_quantmap__16u1__p9_2,
- 17,
- 17
- };
-
- static static_codebook _16u1__p9_2 = {
- 2, 289,
- _vq_lengthlist__16u1__p9_2,
- 1, -529530880, 1611661312, 5, 0,
- _vq_quantlist__16u1__p9_2,
- NULL,
- &_vq_auxt__16u1__p9_2,
- NULL,
- 0
- };
-
- static long _huff_lengthlist__16u1__short[] = {
- 5, 7,10, 9,11,10,15,11,13,16, 6, 4, 6, 6, 7, 7,
- 10, 9,12,16,10, 6, 5, 6, 6, 7,10,11,16,16, 9, 6,
- 7, 6, 7, 7,10, 8,14,16,11, 6, 5, 4, 5, 6, 8, 9,
- 15,16, 9, 6, 6, 5, 6, 6, 9, 8,14,16,12, 7, 6, 6,
- 5, 6, 6, 7,13,16, 8, 6, 7, 6, 5, 5, 4, 4,11,16,
- 9, 8, 9, 9, 7, 7, 6, 5,13,16,14,14,16,15,16,15,
- 16,16,16,16,
- };
-
- static static_codebook _huff_book__16u1__short = {
- 2, 100,
- _huff_lengthlist__16u1__short,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist__16u2__long[] = {
- 5, 7,10,10,10,11,11,13,18,19, 6, 5, 5, 6, 7, 8,
- 9,12,19,19, 8, 5, 4, 4, 6, 7, 9,13,19,19, 8, 5,
- 4, 4, 5, 6, 8,12,17,19, 7, 5, 5, 4, 4, 5, 7,12,
- 18,18, 8, 7, 7, 6, 5, 5, 6,10,18,18, 9, 9, 9, 8,
- 6, 5, 6, 9,18,18,11,13,13,13, 8, 7, 7, 9,16,18,
- 13,17,18,16,11, 9, 9, 9,17,18,15,18,18,18,15,13,
- 13,14,18,18,
- };
-
- static static_codebook _huff_book__16u2__long = {
- 2, 100,
- _huff_lengthlist__16u2__long,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist__16u2__short[] = {
- 8,11,12,12,14,15,16,16,16,16, 9, 7, 7, 8, 9,11,
- 13,14,16,16,13, 7, 6, 6, 7, 9,12,13,15,16,15, 7,
- 6, 5, 4, 6,10,11,14,16,12, 8, 7, 4, 2, 4, 7,10,
- 14,16,11, 9, 7, 5, 3, 4, 6, 9,14,16,11,10, 9, 7,
- 5, 5, 6, 9,16,16,10,10, 9, 8, 6, 6, 7,10,16,16,
- 11,11,11,10,10,10,11,14,16,16,16,14,14,13,14,16,
- 16,16,16,16,
- };
-
- static static_codebook _huff_book__16u2__short = {
- 2, 100,
- _huff_lengthlist__16u2__short,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16u2_p1_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__16u2_p1_0[] = {
- 1, 5, 5, 5, 7, 7, 5, 7, 7, 5, 7, 7, 7, 9, 9, 7,
- 9, 9, 5, 7, 7, 7, 9, 9, 7, 9, 9, 5, 7, 7, 8, 9,
- 9, 7, 9, 9, 7, 9, 9, 9,10,10, 9,10,10, 7, 9, 9,
- 9,10,10, 9,10,11, 5, 7, 8, 8, 9, 9, 8, 9, 9, 7,
- 9, 9, 9,10,10, 9, 9,10, 7, 9, 9, 9,10,10, 9,11,
- 10,
- };
-
- static float _vq_quantthresh__16u2_p1_0[] = {
- -0.5, 0.5,
- };
-
- static long _vq_quantmap__16u2_p1_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__16u2_p1_0 = {
- _vq_quantthresh__16u2_p1_0,
- _vq_quantmap__16u2_p1_0,
- 3,
- 3
- };
-
- static static_codebook _16u2_p1_0 = {
- 4, 81,
- _vq_lengthlist__16u2_p1_0,
- 1, -535822336, 1611661312, 2, 0,
- _vq_quantlist__16u2_p1_0,
- NULL,
- &_vq_auxt__16u2_p1_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16u2_p2_0[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__16u2_p2_0[] = {
- 3, 5, 5, 8, 8, 5, 7, 7, 9, 9, 5, 7, 7, 9, 9, 9,
- 10, 9,11,11, 9, 9, 9,11,11, 5, 7, 7, 9, 9, 7, 8,
- 8,10,10, 7, 8, 8,10,10,10,10,10,12,12, 9,10,10,
- 11,12, 5, 7, 7, 9, 9, 7, 8, 8,10,10, 7, 8, 8,10,
- 10, 9,10,10,12,11,10,10,10,12,12, 9,10,10,12,12,
- 10,11,10,13,12, 9,10,10,12,12,12,12,12,14,14,11,
- 12,12,13,14, 9,10,10,12,12, 9,10,10,12,12,10,10,
- 10,12,12,11,12,12,14,13,12,13,12,14,14, 5, 7, 7,
- 9, 9, 7, 8, 8,10,10, 7, 8, 8,10,10,10,11,10,12,
- 12,10,10,11,12,12, 7, 8, 8,10,10, 8, 9, 9,11,11,
- 8, 9, 9,11,11,11,11,11,12,13,10,11,11,12,13, 7,
- 8, 8,10,10, 8, 9, 8,11,10, 8, 9, 9,11,11,10,11,
- 10,13,12,10,11,11,13,13, 9,11,10,13,13,10,11,11,
- 13,13,10,11,11,13,13,12,12,13,13,15,12,12,13,14,
- 15, 9,10,10,12,12,10,11,10,13,12,10,11,11,13,13,
- 11,13,11,14,13,12,13,13,15,15, 5, 7, 7, 9, 9, 7,
- 8, 8,10,10, 7, 8, 8,10,10,10,10,10,12,12,10,10,
- 11,12,12, 7, 8, 8,10,10, 8, 9, 9,11,11, 8, 8, 9,
- 10,11,10,11,11,13,13,10,10,11,12,13, 7, 8, 8,10,
- 11, 8, 9, 9,11,11, 8, 9, 9,11,11,10,11,11,13,12,
- 11,11,11,13,12, 9,10,10,12,12,10,11,11,13,13,10,
- 10,11,12,13,12,13,13,15,14,11,11,13,12,14,10,10,
- 11,13,13,10,11,11,13,13,10,11,11,13,13,12,13,13,
- 14,14,12,13,12,14,13, 8,10, 9,12,12, 9,11,10,13,
- 13, 9,10,10,12,13,12,13,13,14,14,12,12,13,14,14,
- 9,11,10,13,13,10,11,11,13,13,10,11,11,13,13,12,
- 13,13,15,15,13,13,13,14,15, 9,10,10,12,13,10,11,
- 10,13,12,10,11,11,13,13,12,13,12,15,14,13,13,13,
- 14,15,11,12,12,15,14,12,12,13,15,15,12,13,13,15,
- 14,14,13,15,14,16,13,14,15,16,16,11,12,12,14,14,
- 11,12,12,15,14,12,13,13,15,15,13,14,13,16,14,14,
- 14,14,16,16, 8, 9, 9,12,12, 9,10,10,13,12, 9,10,
- 10,13,13,12,12,12,14,14,12,12,13,15,15, 9,10,10,
- 13,12,10,11,11,13,13,10,10,11,13,14,12,13,13,15,
- 15,12,12,13,14,15, 9,10,10,13,13,10,11,11,13,13,
- 10,11,11,13,13,12,13,13,14,14,13,14,13,15,14,11,
- 12,12,14,14,12,13,13,15,14,11,12,12,14,15,14,14,
- 14,16,15,13,12,14,14,16,11,12,13,14,15,12,13,13,
- 14,16,12,13,12,15,14,13,15,14,16,16,14,15,13,16,
- 13,
- };
-
- static float _vq_quantthresh__16u2_p2_0[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__16u2_p2_0[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__16u2_p2_0 = {
- _vq_quantthresh__16u2_p2_0,
- _vq_quantmap__16u2_p2_0,
- 5,
- 5
- };
-
- static static_codebook _16u2_p2_0 = {
- 4, 625,
- _vq_lengthlist__16u2_p2_0,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__16u2_p2_0,
- NULL,
- &_vq_auxt__16u2_p2_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16u2_p3_0[] = {
- 4,
- 3,
- 5,
- 2,
- 6,
- 1,
- 7,
- 0,
- 8,
- };
-
- static long _vq_lengthlist__16u2_p3_0[] = {
- 2, 4, 4, 6, 6, 7, 7, 9, 9, 4, 5, 5, 6, 6, 8, 7,
- 9, 9, 4, 5, 5, 6, 6, 7, 8, 9, 9, 6, 6, 6, 7, 7,
- 8, 8,10,10, 6, 6, 6, 7, 7, 8, 8, 9,10, 7, 8, 7,
- 8, 8, 9, 9,10,10, 7, 8, 8, 8, 8, 9, 9,10,10, 9,
- 9, 9,10, 9,10,10,11,11, 9, 9, 9,10,10,10,10,11,
- 11,
- };
-
- static float _vq_quantthresh__16u2_p3_0[] = {
- -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5,
- };
-
- static long _vq_quantmap__16u2_p3_0[] = {
- 7, 5, 3, 1, 0, 2, 4, 6,
- 8,
- };
-
- static encode_aux_threshmatch _vq_auxt__16u2_p3_0 = {
- _vq_quantthresh__16u2_p3_0,
- _vq_quantmap__16u2_p3_0,
- 9,
- 9
- };
-
- static static_codebook _16u2_p3_0 = {
- 2, 81,
- _vq_lengthlist__16u2_p3_0,
- 1, -531628032, 1611661312, 4, 0,
- _vq_quantlist__16u2_p3_0,
- NULL,
- &_vq_auxt__16u2_p3_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16u2_p4_0[] = {
- 8,
- 7,
- 9,
- 6,
- 10,
- 5,
- 11,
- 4,
- 12,
- 3,
- 13,
- 2,
- 14,
- 1,
- 15,
- 0,
- 16,
- };
-
- static long _vq_lengthlist__16u2_p4_0[] = {
- 2, 4, 4, 6, 6, 7, 7, 8, 8, 9, 9,10,10,11,11,11,
- 11, 5, 5, 5, 7, 7, 8, 8, 9, 9, 9, 9,10,10,11,11,
- 12,11, 5, 5, 5, 7, 7, 8, 8, 9, 9, 9, 9,10,10,11,
- 11,12,12, 6, 7, 7, 7, 7, 8, 8, 9, 9, 9, 9,10,10,
- 11,11,12,12, 6, 7, 7, 7, 7, 8, 8, 9, 9, 9, 9,10,
- 10,11,11,12,12, 7, 8, 8, 8, 8, 9, 9, 9, 9,10,10,
- 11,11,12,12,12,12, 7, 8, 8, 8, 8, 9, 9, 9, 9,10,
- 10,11,11,11,12,12,12, 9, 9, 9, 9, 9, 9,10,10,10,
- 10,10,11,11,12,12,13,13, 8, 9, 9, 9, 9,10, 9,10,
- 10,10,10,11,11,12,12,13,13, 9, 9, 9, 9, 9,10,10,
- 10,10,11,11,11,12,12,12,13,13, 9, 9, 9, 9, 9,10,
- 10,10,10,11,11,12,11,12,12,13,13,10,10,10,10,10,
- 11,11,11,11,11,12,12,12,12,13,13,14,10,10,10,10,
- 10,11,11,11,11,12,11,12,12,13,12,13,13,11,11,11,
- 11,11,12,12,12,12,12,12,13,13,13,13,14,14,11,11,
- 11,11,11,12,12,12,12,12,12,13,12,13,13,14,14,11,
- 12,12,12,12,12,12,13,13,13,13,13,13,14,14,14,14,
- 11,12,12,12,12,12,12,13,13,13,13,14,13,14,14,14,
- 14,
- };
-
- static float _vq_quantthresh__16u2_p4_0[] = {
- -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5,
- 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5,
- };
-
- static long _vq_quantmap__16u2_p4_0[] = {
- 15, 13, 11, 9, 7, 5, 3, 1,
- 0, 2, 4, 6, 8, 10, 12, 14,
- 16,
- };
-
- static encode_aux_threshmatch _vq_auxt__16u2_p4_0 = {
- _vq_quantthresh__16u2_p4_0,
- _vq_quantmap__16u2_p4_0,
- 17,
- 17
- };
-
- static static_codebook _16u2_p4_0 = {
- 2, 289,
- _vq_lengthlist__16u2_p4_0,
- 1, -529530880, 1611661312, 5, 0,
- _vq_quantlist__16u2_p4_0,
- NULL,
- &_vq_auxt__16u2_p4_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16u2_p5_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__16u2_p5_0[] = {
- 1, 4, 4, 5, 7, 7, 5, 7, 7, 5, 9, 8, 7,10, 9, 7,
- 10, 9, 5, 8, 9, 7, 9,10, 7, 9,10, 4, 9, 9, 9,11,
- 11, 8,11,11, 7,11,11,10,10,13,10,14,13, 7,11,11,
- 10,13,11,10,13,14, 5, 9, 9, 8,11,11, 9,11,11, 7,
- 11,11,10,14,13,10,12,14, 7,11,11,10,13,13,10,13,
- 10,
- };
-
- static float _vq_quantthresh__16u2_p5_0[] = {
- -5.5, 5.5,
- };
-
- static long _vq_quantmap__16u2_p5_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__16u2_p5_0 = {
- _vq_quantthresh__16u2_p5_0,
- _vq_quantmap__16u2_p5_0,
- 3,
- 3
- };
-
- static static_codebook _16u2_p5_0 = {
- 4, 81,
- _vq_lengthlist__16u2_p5_0,
- 1, -529137664, 1618345984, 2, 0,
- _vq_quantlist__16u2_p5_0,
- NULL,
- &_vq_auxt__16u2_p5_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16u2_p5_1[] = {
- 5,
- 4,
- 6,
- 3,
- 7,
- 2,
- 8,
- 1,
- 9,
- 0,
- 10,
- };
-
- static long _vq_lengthlist__16u2_p5_1[] = {
- 2, 5, 5, 6, 6, 7, 7, 8, 8, 8, 8, 5, 5, 5, 7, 7,
- 7, 7, 8, 8, 8, 8, 5, 5, 6, 7, 7, 7, 7, 8, 8, 8,
- 8, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 6, 7, 7, 7,
- 7, 8, 8, 8, 8, 8, 8, 7, 7, 7, 8, 8, 8, 8, 9, 9,
- 9, 9, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 8, 8, 8,
- 8, 8, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 9, 9, 9,
- 9, 9, 9, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 8, 8,
- 8, 8, 8, 9, 9, 9, 9, 9, 9,
- };
-
- static float _vq_quantthresh__16u2_p5_1[] = {
- -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5,
- 3.5, 4.5,
- };
-
- static long _vq_quantmap__16u2_p5_1[] = {
- 9, 7, 5, 3, 1, 0, 2, 4,
- 6, 8, 10,
- };
-
- static encode_aux_threshmatch _vq_auxt__16u2_p5_1 = {
- _vq_quantthresh__16u2_p5_1,
- _vq_quantmap__16u2_p5_1,
- 11,
- 11
- };
-
- static static_codebook _16u2_p5_1 = {
- 2, 121,
- _vq_lengthlist__16u2_p5_1,
- 1, -531365888, 1611661312, 4, 0,
- _vq_quantlist__16u2_p5_1,
- NULL,
- &_vq_auxt__16u2_p5_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16u2_p6_0[] = {
- 6,
- 5,
- 7,
- 4,
- 8,
- 3,
- 9,
- 2,
- 10,
- 1,
- 11,
- 0,
- 12,
- };
-
- static long _vq_lengthlist__16u2_p6_0[] = {
- 1, 4, 4, 7, 7, 8, 8, 8, 8, 9, 9,10,10, 4, 6, 6,
- 8, 8, 9, 9, 9, 9,10,10,12,11, 4, 6, 6, 8, 8, 9,
- 9, 9, 9,10,10,11,12, 7, 8, 8, 9, 9,10,10,10,10,
- 12,12,13,12, 7, 8, 8, 9, 9,10,10,10,10,11,12,12,
- 12, 8, 9, 9,10,10,11,11,11,11,12,12,13,13, 8, 9,
- 9,10,10,11,11,11,11,12,13,13,13, 8, 9, 9,10,10,
- 11,11,12,12,13,13,14,14, 8, 9, 9,10,10,11,11,12,
- 12,13,13,14,14, 9,10,10,11,12,13,12,13,14,14,14,
- 14,14, 9,10,10,11,12,12,13,13,13,14,14,14,14,10,
- 11,11,12,12,13,13,14,14,15,15,15,15,10,11,11,12,
- 12,13,13,14,14,14,14,15,15,
- };
-
- static float _vq_quantthresh__16u2_p6_0[] = {
- -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5,
- 12.5, 17.5, 22.5, 27.5,
- };
-
- static long _vq_quantmap__16u2_p6_0[] = {
- 11, 9, 7, 5, 3, 1, 0, 2,
- 4, 6, 8, 10, 12,
- };
-
- static encode_aux_threshmatch _vq_auxt__16u2_p6_0 = {
- _vq_quantthresh__16u2_p6_0,
- _vq_quantmap__16u2_p6_0,
- 13,
- 13
- };
-
- static static_codebook _16u2_p6_0 = {
- 2, 169,
- _vq_lengthlist__16u2_p6_0,
- 1, -526516224, 1616117760, 4, 0,
- _vq_quantlist__16u2_p6_0,
- NULL,
- &_vq_auxt__16u2_p6_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16u2_p6_1[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__16u2_p6_1[] = {
- 2, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 6, 6, 5, 5, 5, 6, 6,
- };
-
- static float _vq_quantthresh__16u2_p6_1[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__16u2_p6_1[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__16u2_p6_1 = {
- _vq_quantthresh__16u2_p6_1,
- _vq_quantmap__16u2_p6_1,
- 5,
- 5
- };
-
- static static_codebook _16u2_p6_1 = {
- 2, 25,
- _vq_lengthlist__16u2_p6_1,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__16u2_p6_1,
- NULL,
- &_vq_auxt__16u2_p6_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16u2_p7_0[] = {
- 6,
- 5,
- 7,
- 4,
- 8,
- 3,
- 9,
- 2,
- 10,
- 1,
- 11,
- 0,
- 12,
- };
-
- static long _vq_lengthlist__16u2_p7_0[] = {
- 1, 4, 4, 7, 7, 7, 7, 8, 8, 9, 9,10,10, 4, 6, 6,
- 9, 9, 9, 9, 9, 9,10,10,11,11, 4, 6, 6, 8, 9, 9,
- 9, 9, 9,10,11,12,11, 7, 8, 9,10,10,10,10,11,10,
- 11,12,12,13, 7, 9, 9,10,10,10,10,10,10,11,12,13,
- 13, 7, 9, 8,10,10,11,11,11,12,12,13,13,14, 7, 9,
- 9,10,10,11,11,11,12,13,13,13,13, 8, 9, 9,10,11,
- 11,12,12,12,13,13,13,13, 8, 9, 9,10,11,11,11,12,
- 12,13,13,14,14, 9,10,10,12,11,12,13,13,13,14,13,
- 13,13, 9,10,10,11,11,12,12,13,14,13,13,14,13,10,
- 11,11,12,13,14,14,14,15,14,14,14,14,10,11,11,12,
- 12,13,13,13,14,14,14,15,14,
- };
-
- static float _vq_quantthresh__16u2_p7_0[] = {
- -60.5, -49.5, -38.5, -27.5, -16.5, -5.5, 5.5, 16.5,
- 27.5, 38.5, 49.5, 60.5,
- };
-
- static long _vq_quantmap__16u2_p7_0[] = {
- 11, 9, 7, 5, 3, 1, 0, 2,
- 4, 6, 8, 10, 12,
- };
-
- static encode_aux_threshmatch _vq_auxt__16u2_p7_0 = {
- _vq_quantthresh__16u2_p7_0,
- _vq_quantmap__16u2_p7_0,
- 13,
- 13
- };
-
- static static_codebook _16u2_p7_0 = {
- 2, 169,
- _vq_lengthlist__16u2_p7_0,
- 1, -523206656, 1618345984, 4, 0,
- _vq_quantlist__16u2_p7_0,
- NULL,
- &_vq_auxt__16u2_p7_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16u2_p7_1[] = {
- 5,
- 4,
- 6,
- 3,
- 7,
- 2,
- 8,
- 1,
- 9,
- 0,
- 10,
- };
-
- static long _vq_lengthlist__16u2_p7_1[] = {
- 3, 5, 5, 6, 6, 7, 7, 7, 7, 7, 7, 5, 6, 6, 7, 7,
- 7, 7, 7, 7, 8, 8, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8,
- 8, 6, 6, 7, 7, 7, 8, 7, 8, 8, 8, 8, 6, 7, 7, 7,
- 7, 7, 7, 8, 8, 8, 8, 7, 7, 7, 7, 7, 8, 8, 8, 8,
- 8, 8, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7,
- 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 8, 8, 8, 8, 8,
- 8, 8, 8, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8,
- };
-
- static float _vq_quantthresh__16u2_p7_1[] = {
- -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5,
- 3.5, 4.5,
- };
-
- static long _vq_quantmap__16u2_p7_1[] = {
- 9, 7, 5, 3, 1, 0, 2, 4,
- 6, 8, 10,
- };
-
- static encode_aux_threshmatch _vq_auxt__16u2_p7_1 = {
- _vq_quantthresh__16u2_p7_1,
- _vq_quantmap__16u2_p7_1,
- 11,
- 11
- };
-
- static static_codebook _16u2_p7_1 = {
- 2, 121,
- _vq_lengthlist__16u2_p7_1,
- 1, -531365888, 1611661312, 4, 0,
- _vq_quantlist__16u2_p7_1,
- NULL,
- &_vq_auxt__16u2_p7_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16u2_p8_0[] = {
- 7,
- 6,
- 8,
- 5,
- 9,
- 4,
- 10,
- 3,
- 11,
- 2,
- 12,
- 1,
- 13,
- 0,
- 14,
- };
-
- static long _vq_lengthlist__16u2_p8_0[] = {
- 1, 5, 5, 7, 7, 8, 8, 7, 7, 8, 8,10, 9,11,11, 4,
- 6, 6, 8, 8,10, 9, 9, 8, 9, 9,10,10,12,14, 4, 6,
- 7, 8, 9, 9,10, 9, 8, 9, 9,10,12,12,11, 7, 8, 8,
- 10,10,10,10, 9, 9,10,10,11,13,13,12, 7, 8, 8, 9,
- 11,11,10, 9, 9,11,10,12,11,11,14, 8, 9, 9,11,10,
- 11,11,10,10,11,11,13,12,14,12, 8, 9, 9,11,12,11,
- 11,10,10,12,11,12,12,12,14, 7, 8, 8, 9, 9,10,10,
- 10,11,12,11,13,13,14,12, 7, 8, 9, 9, 9,10,10,11,
- 11,11,12,12,14,14,14, 8,10, 9,10,11,11,11,11,14,
- 12,12,13,14,14,13, 9, 9, 9,10,11,11,11,12,12,12,
- 14,12,14,13,14,10,10,10,12,11,12,11,14,13,14,13,
- 14,14,13,14, 9,10,10,11,12,11,13,12,13,13,14,14,
- 14,13,14,10,13,13,12,12,11,12,14,13,14,13,14,12,
- 14,13,10,11,11,12,11,12,12,14,14,14,13,14,14,14,
- 14,
- };
-
- static float _vq_quantthresh__16u2_p8_0[] = {
- -136.5, -115.5, -94.5, -73.5, -52.5, -31.5, -10.5, 10.5,
- 31.5, 52.5, 73.5, 94.5, 115.5, 136.5,
- };
-
- static long _vq_quantmap__16u2_p8_0[] = {
- 13, 11, 9, 7, 5, 3, 1, 0,
- 2, 4, 6, 8, 10, 12, 14,
- };
-
- static encode_aux_threshmatch _vq_auxt__16u2_p8_0 = {
- _vq_quantthresh__16u2_p8_0,
- _vq_quantmap__16u2_p8_0,
- 15,
- 15
- };
-
- static static_codebook _16u2_p8_0 = {
- 2, 225,
- _vq_lengthlist__16u2_p8_0,
- 1, -520986624, 1620377600, 4, 0,
- _vq_quantlist__16u2_p8_0,
- NULL,
- &_vq_auxt__16u2_p8_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16u2_p8_1[] = {
- 10,
- 9,
- 11,
- 8,
- 12,
- 7,
- 13,
- 6,
- 14,
- 5,
- 15,
- 4,
- 16,
- 3,
- 17,
- 2,
- 18,
- 1,
- 19,
- 0,
- 20,
- };
-
- static long _vq_lengthlist__16u2_p8_1[] = {
- 2, 5, 5, 7, 7, 8, 8, 8, 8, 9, 9,10, 9,10, 9, 9,
- 9,10,10,10,10, 5, 6, 6, 7, 7, 8, 8, 9, 9, 9, 9,
- 10, 9,10,10,10,10,10,10,11,10, 5, 6, 6, 7, 7, 8,
- 8, 8, 9, 9,10,10,10,10,10,10,10,10,10,10,10, 7,
- 7, 7, 8, 8, 9, 8, 9, 9,10, 9,10,10,10,10,10,10,
- 11,10,11,10, 7, 7, 7, 8, 8, 8, 9, 9, 9,10, 9,10,
- 10,10,10,10,10,10,10,10,10, 8, 8, 8, 9, 9, 9, 9,
- 10, 9,10,10,10,10,10,10,10,11,10,10,11,10, 8, 8,
- 8, 8, 9, 9, 9, 9,10,10,10,10,10,10,10,10,10,11,
- 11,10,10, 8, 9, 9, 9, 9, 9, 9,10,10,10,10,10,10,
- 11,10,11,10,11,10,11,10, 8, 9, 9, 9, 9, 9,10,10,
- 10,10,10,10,10,10,10,10,11,11,10,10,10, 9,10, 9,
- 9,10,10,10,11,10,10,10,10,10,10,10,10,11,11,11,
- 11,11, 9, 9, 9,10, 9,10,10,10,10,10,10,11,10,11,
- 10,11,11,11,11,10,10, 9,10, 9,10,10,10,10,11,10,
- 10,10,10,10,11,10,11,10,11,10,10,11, 9,10,10,10,
- 10,10,10,10,10,10,11,10,10,11,11,10,11,11,11,11,
- 11, 9, 9,10,10,10,10,10,11,10,10,11,10,10,11,10,
- 10,11,11,11,11,11, 9,10,10,10,10,10,10,10,11,10,
- 11,10,11,10,11,11,11,11,11,10,11,10,10,10,10,10,
- 10,10,10,10,11,11,11,11,11,11,11,11,11,10,11,11,
- 10,10,10,10,10,11,10,10,10,11,10,11,11,11,11,10,
- 12,11,11,11,10,10,10,10,10,10,11,10,10,10,11,11,
- 12,11,11,11,11,11,11,11,11,11,10,10,10,11,10,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,10,
- 10,10,11,10,11,10,10,11,11,11,11,11,11,11,11,11,
- 11,11,11,10,10,10,10,10,10,10,11,11,10,11,11,10,
- 11,11,10,11,11,11,10,11,11,
- };
-
- static float _vq_quantthresh__16u2_p8_1[] = {
- -9.5, -8.5, -7.5, -6.5, -5.5, -4.5, -3.5, -2.5,
- -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5.5,
- 6.5, 7.5, 8.5, 9.5,
- };
-
- static long _vq_quantmap__16u2_p8_1[] = {
- 19, 17, 15, 13, 11, 9, 7, 5,
- 3, 1, 0, 2, 4, 6, 8, 10,
- 12, 14, 16, 18, 20,
- };
-
- static encode_aux_threshmatch _vq_auxt__16u2_p8_1 = {
- _vq_quantthresh__16u2_p8_1,
- _vq_quantmap__16u2_p8_1,
- 21,
- 21
- };
-
- static static_codebook _16u2_p8_1 = {
- 2, 441,
- _vq_lengthlist__16u2_p8_1,
- 1, -529268736, 1611661312, 5, 0,
- _vq_quantlist__16u2_p8_1,
- NULL,
- &_vq_auxt__16u2_p8_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16u2_p9_0[] = {
- 5586,
- 4655,
- 6517,
- 3724,
- 7448,
- 2793,
- 8379,
- 1862,
- 9310,
- 931,
- 10241,
- 0,
- 11172,
- 5521,
- 5651,
- };
-
- static long _vq_lengthlist__16u2_p9_0[] = {
- 1,10,10,10,10,10,10,10,10,10,10,10,10, 5, 4,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10, 4,10,10,10,10,10,10,10,10,10,10,10,10,
- 6, 6, 5,10,10,10,10, 9, 9, 9, 9, 9, 9, 9, 9, 5,
- 5,
- };
-
- static float _vq_quantthresh__16u2_p9_0[] = {
- -5120.5, -4189.5, -3258.5, -2327.5, -1396.5, -498, -32.5, 32.5,
- 498, 1396.5, 2327.5, 3258.5, 4189.5, 5120.5,
- };
-
- static long _vq_quantmap__16u2_p9_0[] = {
- 11, 9, 7, 5, 3, 1, 13, 0,
- 14, 2, 4, 6, 8, 10, 12,
- };
-
- static encode_aux_threshmatch _vq_auxt__16u2_p9_0 = {
- _vq_quantthresh__16u2_p9_0,
- _vq_quantmap__16u2_p9_0,
- 15,
- 15
- };
-
- static static_codebook _16u2_p9_0 = {
- 2, 225,
- _vq_lengthlist__16u2_p9_0,
- 1, -510275072, 1611661312, 14, 0,
- _vq_quantlist__16u2_p9_0,
- NULL,
- &_vq_auxt__16u2_p9_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16u2_p9_1[] = {
- 392,
- 343,
- 441,
- 294,
- 490,
- 245,
- 539,
- 196,
- 588,
- 147,
- 637,
- 98,
- 686,
- 49,
- 735,
- 0,
- 784,
- 388,
- 396,
- };
-
- static long _vq_lengthlist__16u2_p9_1[] = {
- 1,12,10,12,10,12,10,12,11,12,12,12,12,12,12,12,
- 12, 5, 5, 9,10,12,11,11,12,12,12,12,12,12,12,12,
- 12,12,12,12,10, 9, 9,11, 9,11,11,12,11,12,12,12,
- 12,12,12,12,12,12,12, 8, 8,10,11, 9,12,11,12,12,
- 12,12,12,12,12,12,12,12,12,12, 9, 8,10,11,12,11,
- 12,11,12,12,12,12,12,12,12,12,12,12,12, 8, 9,11,
- 11,10,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
- 9,10,11,12,11,12,11,12,12,12,12,12,12,12,12,12,
- 12,12,12, 9, 9,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,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,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,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
- 12,12,12,12,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11, 5, 8, 9, 9, 8,11, 9,11,11,11,11,11,11,
- 11,11,11,11, 5, 5, 4, 8, 8, 8, 8,10, 9,10,10,11,
- 11,11,11,11,11,11,11, 5, 4,
- };
-
- static float _vq_quantthresh__16u2_p9_1[] = {
- -367.5, -318.5, -269.5, -220.5, -171.5, -122.5, -73.5, -26.5,
- -2, 2, 26.5, 73.5, 122.5, 171.5, 220.5, 269.5,
- 318.5, 367.5,
- };
-
- static long _vq_quantmap__16u2_p9_1[] = {
- 15, 13, 11, 9, 7, 5, 3, 1,
- 17, 0, 18, 2, 4, 6, 8, 10,
- 12, 14, 16,
- };
-
- static encode_aux_threshmatch _vq_auxt__16u2_p9_1 = {
- _vq_quantthresh__16u2_p9_1,
- _vq_quantmap__16u2_p9_1,
- 19,
- 19
- };
-
- static static_codebook _16u2_p9_1 = {
- 2, 361,
- _vq_lengthlist__16u2_p9_1,
- 1, -518488064, 1611661312, 10, 0,
- _vq_quantlist__16u2_p9_1,
- NULL,
- &_vq_auxt__16u2_p9_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__16u2_p9_2[] = {
- 24,
- 23,
- 25,
- 22,
- 26,
- 21,
- 27,
- 20,
- 28,
- 19,
- 29,
- 18,
- 30,
- 17,
- 31,
- 16,
- 32,
- 15,
- 33,
- 14,
- 34,
- 13,
- 35,
- 12,
- 36,
- 11,
- 37,
- 10,
- 38,
- 9,
- 39,
- 8,
- 40,
- 7,
- 41,
- 6,
- 42,
- 5,
- 43,
- 4,
- 44,
- 3,
- 45,
- 2,
- 46,
- 1,
- 47,
- 0,
- 48,
- };
-
- static long _vq_lengthlist__16u2_p9_2[] = {
- 1, 3, 3, 4, 7, 7, 7, 8, 7, 7, 7, 7, 8, 8, 8, 8,
- 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 9, 9, 8, 9, 9,
- 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,12,12,10,
- 11,
- };
-
- static float _vq_quantthresh__16u2_p9_2[] = {
- -23.5, -22.5, -21.5, -20.5, -19.5, -18.5, -17.5, -16.5,
- -15.5, -14.5, -13.5, -12.5, -11.5, -10.5, -9.5, -8.5,
- -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5,
- 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5,
- 8.5, 9.5, 10.5, 11.5, 12.5, 13.5, 14.5, 15.5,
- 16.5, 17.5, 18.5, 19.5, 20.5, 21.5, 22.5, 23.5,
- };
-
- static long _vq_quantmap__16u2_p9_2[] = {
- 47, 45, 43, 41, 39, 37, 35, 33,
- 31, 29, 27, 25, 23, 21, 19, 17,
- 15, 13, 11, 9, 7, 5, 3, 1,
- 0, 2, 4, 6, 8, 10, 12, 14,
- 16, 18, 20, 22, 24, 26, 28, 30,
- 32, 34, 36, 38, 40, 42, 44, 46,
- 48,
- };
-
- static encode_aux_threshmatch _vq_auxt__16u2_p9_2 = {
- _vq_quantthresh__16u2_p9_2,
- _vq_quantmap__16u2_p9_2,
- 49,
- 49
- };
-
- static static_codebook _16u2_p9_2 = {
- 1, 49,
- _vq_lengthlist__16u2_p9_2,
- 1, -526909440, 1611661312, 6, 0,
- _vq_quantlist__16u2_p9_2,
- NULL,
- &_vq_auxt__16u2_p9_2,
- NULL,
- 0
- };
-
- static long _vq_quantlist__8u0__p1_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__8u0__p1_0[] = {
- 1, 4, 4, 5, 7, 7, 5, 7, 7, 5, 8, 8, 8,10,10, 7,
- 10,10, 5, 8, 8, 7,10,10, 8,10,10, 4, 9, 8, 8,11,
- 11, 8,11,11, 7,11,11,10,11,13,10,13,13, 7,11,11,
- 10,13,12,10,13,13, 5, 9, 8, 8,11,11, 8,11,11, 7,
- 11,11, 9,13,13,10,12,13, 7,11,11,10,13,13,10,13,
- 11,
- };
-
- static float _vq_quantthresh__8u0__p1_0[] = {
- -0.5, 0.5,
- };
-
- static long _vq_quantmap__8u0__p1_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__8u0__p1_0 = {
- _vq_quantthresh__8u0__p1_0,
- _vq_quantmap__8u0__p1_0,
- 3,
- 3
- };
-
- static static_codebook _8u0__p1_0 = {
- 4, 81,
- _vq_lengthlist__8u0__p1_0,
- 1, -535822336, 1611661312, 2, 0,
- _vq_quantlist__8u0__p1_0,
- NULL,
- &_vq_auxt__8u0__p1_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__8u0__p2_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__8u0__p2_0[] = {
- 2, 4, 4, 5, 6, 6, 5, 6, 6, 5, 7, 7, 6, 7, 8, 6,
- 7, 8, 5, 7, 7, 6, 8, 8, 7, 9, 7, 5, 7, 7, 7, 9,
- 9, 7, 8, 8, 6, 9, 8, 7, 7,10, 8,10,10, 6, 8, 8,
- 8,10, 8, 8,10,10, 5, 7, 7, 7, 8, 8, 7, 8, 9, 6,
- 8, 8, 8,10,10, 8, 8,10, 6, 8, 9, 8,10,10, 7,10,
- 8,
- };
-
- static float _vq_quantthresh__8u0__p2_0[] = {
- -0.5, 0.5,
- };
-
- static long _vq_quantmap__8u0__p2_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__8u0__p2_0 = {
- _vq_quantthresh__8u0__p2_0,
- _vq_quantmap__8u0__p2_0,
- 3,
- 3
- };
-
- static static_codebook _8u0__p2_0 = {
- 4, 81,
- _vq_lengthlist__8u0__p2_0,
- 1, -535822336, 1611661312, 2, 0,
- _vq_quantlist__8u0__p2_0,
- NULL,
- &_vq_auxt__8u0__p2_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__8u0__p3_0[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__8u0__p3_0[] = {
- 1, 5, 5, 7, 7, 6, 7, 7, 9, 9, 6, 7, 7, 9, 9, 8,
- 10, 9,11,11, 8, 9, 9,11,11, 6, 8, 8,10,10, 8,10,
- 10,11,11, 8,10,10,11,11,10,11,11,12,12,10,11,11,
- 12,13, 6, 8, 8,10,10, 8,10,10,11,11, 8,10,10,11,
- 11, 9,10,11,12,12,10,11,11,12,12, 8,11,11,14,13,
- 10,12,11,15,13,10,12,11,14,14,12,13,12,16,14,12,
- 14,12,16,15, 8,11,11,13,14,10,11,12,13,15,10,11,
- 12,13,15,11,12,13,14,15,12,12,14,14,16, 5, 8, 8,
- 11,11, 9,11,11,12,12, 8,10,11,12,12,11,12,12,15,
- 14,11,12,12,14,14, 7,11,10,13,12,10,11,12,13,14,
- 10,12,12,14,13,12,13,13,14,15,12,13,13,15,15, 7,
- 10,11,12,13,10,12,11,14,13,10,12,13,13,15,12,13,
- 12,14,14,11,13,13,15,16, 9,12,12,15,14,11,13,13,
- 15,16,11,13,13,16,16,13,14,15,15,15,12,14,15,17,
- 16, 9,12,12,14,15,11,13,13,15,16,11,13,13,16,18,
- 13,14,14,17,16,13,15,15,17,18, 5, 8, 9,11,11, 8,
- 11,11,12,12, 8,10,11,12,12,11,12,12,14,14,11,12,
- 12,14,15, 7,11,10,12,13,10,12,12,14,13,10,11,12,
- 13,14,11,13,13,15,14,12,13,13,14,15, 7,10,11,13,
- 13,10,12,12,13,14,10,12,12,13,13,11,13,13,16,16,
- 12,13,13,15,14, 9,12,12,16,15,10,13,13,15,15,11,
- 13,13,17,15,12,15,15,18,17,13,14,14,15,16, 9,12,
- 12,15,15,11,13,13,15,16,11,13,13,15,15,12,15,15,
- 16,16,13,15,14,17,15, 7,11,11,15,15,10,13,13,16,
- 15,10,13,13,15,16,14,15,15,17,19,13,15,14,15,18,
- 9,12,12,16,16,11,13,14,17,16,11,13,13,17,16,15,
- 15,16,17,19,13,15,16, 0,18, 9,12,12,16,15,11,14,
- 13,17,17,11,13,14,16,16,15,16,16,19,18,13,15,15,
- 17,19,11,14,14,19,16,12,14,15, 0,18,12,16,15,18,
- 17,15,15,18,16,19,14,15,17,19,19,11,14,14,18,19,
- 13,15,14,19,19,12,16,15,18,17,15,17,15, 0,16,14,
- 17,16,19, 0, 7,11,11,14,14,10,12,12,15,15,10,13,
- 13,16,15,13,15,15,17, 0,14,15,15,16,19, 9,12,12,
- 16,16,11,14,14,16,16,11,13,13,16,16,14,17,16,19,
- 0,14,18,17,17,19, 9,12,12,15,16,11,13,13,15,17,
- 12,14,13,19,16,13,15,15,17,19,15,17,16,17,19,11,
- 14,14,19,16,12,15,15,19,17,13,14,15,17,19,14,16,
- 17,19,19,16,15,16,17,19,11,15,14,16,16,12,15,15,
- 19, 0,12,14,15,19,19,14,16,16, 0,18,15,19,14,18,
- 16,
- };
-
- static float _vq_quantthresh__8u0__p3_0[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__8u0__p3_0[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__8u0__p3_0 = {
- _vq_quantthresh__8u0__p3_0,
- _vq_quantmap__8u0__p3_0,
- 5,
- 5
- };
-
- static static_codebook _8u0__p3_0 = {
- 4, 625,
- _vq_lengthlist__8u0__p3_0,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__8u0__p3_0,
- NULL,
- &_vq_auxt__8u0__p3_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__8u0__p4_0[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__8u0__p4_0[] = {
- 3, 5, 5, 8, 8, 5, 6, 7, 9, 9, 6, 7, 6, 9, 9, 9,
- 9, 9,10,11, 9, 9, 9,11,10, 6, 7, 7,10,10, 7, 7,
- 8,10,10, 7, 8, 8,10,10,10,10,10,10,11, 9,10,10,
- 11,12, 6, 7, 7,10,10, 7, 8, 8,10,10, 7, 8, 7,10,
- 10, 9,10,10,12,11,10,10,10,11,10, 9,10,10,12,11,
- 10,10,10,13,11, 9,10,10,12,12,11,11,12,12,13,11,
- 11,11,12,13, 9,10,10,12,12,10,10,11,12,12,10,10,
- 11,12,12,11,11,11,13,13,11,12,12,13,13, 5, 7, 7,
- 10,10, 7, 8, 8,10,10, 7, 8, 8,10,10,10,11,11,12,
- 12,10,11,10,12,12, 7, 8, 8,11,11, 7, 8, 9,10,11,
- 8, 9, 9,11,11,11,10,11,10,12,10,11,11,12,13, 7,
- 8, 8,10,11, 8, 9, 8,12,10, 8, 9, 9,11,12,10,11,
- 10,13,11,10,11,11,13,12, 9,11,10,13,12,10,10,11,
- 12,12,10,11,11,13,13,12,10,13,11,14,11,12,12,15,
- 13, 9,11,11,13,13,10,11,11,13,12,10,11,11,12,14,
- 12,13,11,14,12,12,12,12,14,14, 5, 7, 7,10,10, 7,
- 8, 8,10,10, 7, 8, 8,11,10,10,11,11,12,12,10,11,
- 10,12,12, 7, 8, 8,10,11, 8, 9, 9,12,11, 8, 8, 9,
- 10,11,10,11,11,12,13,11,10,11,11,13, 6, 8, 8,10,
- 11, 8, 9, 9,11,11, 7, 9, 7,11,10,10,11,11,12,12,
- 10,11,10,13,10, 9,11,10,13,12,10,12,11,13,13,10,
- 10,11,12,13,11,12,13,15,14,11,11,13,12,13, 9,10,
- 11,12,13,10,11,11,12,13,10,11,10,13,12,12,13,13,
- 13,14,12,12,11,14,11, 8,10,10,12,13,10,11,11,13,
- 13,10,11,10,13,13,12,13,14,15,14,12,12,12,14,13,
- 9,10,10,13,12,10,10,12,13,13,10,11,11,15,12,12,
- 12,13,15,14,12,13,13,15,13, 9,10,11,12,13,10,12,
- 10,13,12,10,11,11,12,13,12,14,12,15,13,12,12,12,
- 15,14,11,12,11,14,13,11,11,12,14,14,12,13,13,14,
- 13,13,11,15,11,15,14,14,14,16,15,11,12,12,13,14,
- 11,13,11,14,14,12,12,13,14,15,12,14,12,15,12,13,
- 15,14,16,15, 8,10,10,12,12,10,10,10,12,13,10,11,
- 11,13,13,12,12,12,13,14,13,13,13,15,15, 9,10,10,
- 12,12,10,11,11,13,12,10,10,11,13,13,12,12,12,14,
- 14,12,12,13,15,14, 9,10,10,13,12,10,10,12,12,13,
- 10,11,10,13,13,12,13,13,14,14,12,13,12,14,13,11,
- 12,12,14,13,12,13,12,14,14,10,12,12,14,14,14,14,
- 14,16,14,13,12,14,12,15,10,12,12,14,15,12,13,13,
- 14,16,11,12,11,15,14,13,14,14,14,15,13,14,11,14,
- 12,
- };
-
- static float _vq_quantthresh__8u0__p4_0[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__8u0__p4_0[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__8u0__p4_0 = {
- _vq_quantthresh__8u0__p4_0,
- _vq_quantmap__8u0__p4_0,
- 5,
- 5
- };
-
- static static_codebook _8u0__p4_0 = {
- 4, 625,
- _vq_lengthlist__8u0__p4_0,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__8u0__p4_0,
- NULL,
- &_vq_auxt__8u0__p4_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__8u0__p5_0[] = {
- 4,
- 3,
- 5,
- 2,
- 6,
- 1,
- 7,
- 0,
- 8,
- };
-
- static long _vq_lengthlist__8u0__p5_0[] = {
- 1, 4, 4, 7, 7, 7, 7, 9, 9, 4, 6, 6, 8, 7, 8, 8,
- 10,10, 4, 6, 6, 8, 8, 8, 8,10,10, 6, 8, 8, 9, 9,
- 9, 9,11,11, 7, 8, 8, 9, 9, 9, 9,11,11, 7, 8, 8,
- 9, 9,10,10,12,11, 7, 8, 8, 9, 9,10,10,11,11, 9,
- 10,10,11,11,11,12,12,12, 9,10,10,11,11,12,12,12,
- 12,
- };
-
- static float _vq_quantthresh__8u0__p5_0[] = {
- -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5,
- };
-
- static long _vq_quantmap__8u0__p5_0[] = {
- 7, 5, 3, 1, 0, 2, 4, 6,
- 8,
- };
-
- static encode_aux_threshmatch _vq_auxt__8u0__p5_0 = {
- _vq_quantthresh__8u0__p5_0,
- _vq_quantmap__8u0__p5_0,
- 9,
- 9
- };
-
- static static_codebook _8u0__p5_0 = {
- 2, 81,
- _vq_lengthlist__8u0__p5_0,
- 1, -531628032, 1611661312, 4, 0,
- _vq_quantlist__8u0__p5_0,
- NULL,
- &_vq_auxt__8u0__p5_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__8u0__p6_0[] = {
- 6,
- 5,
- 7,
- 4,
- 8,
- 3,
- 9,
- 2,
- 10,
- 1,
- 11,
- 0,
- 12,
- };
-
- static long _vq_lengthlist__8u0__p6_0[] = {
- 1, 4, 4, 7, 7, 9, 9,11,11,12,12,16,16, 3, 6, 6,
- 9, 9,11,11,12,12,13,14,18,16, 3, 6, 7, 9, 9,11,
- 11,13,12,14,14,17,16, 7, 9, 9,11,11,12,12,14,14,
- 14,14,17,16, 7, 9, 9,11,11,13,12,13,13,14,14,17,
- 0, 9,11,11,12,13,14,14,14,13,15,14,17,17, 9,11,
- 11,12,12,14,14,13,14,14,15, 0, 0,11,12,12,15,14,
- 15,14,15,14,15,16,17, 0,11,12,13,13,13,14,14,15,
- 14,15,15, 0, 0,12,14,14,15,15,14,16,15,15,17,16,
- 0,18,13,14,14,15,14,15,14,15,16,17,16, 0, 0,17,
- 17,18, 0,16,18,16, 0, 0, 0,17, 0, 0,16, 0, 0,16,
- 16, 0,15, 0,17, 0, 0, 0, 0,
- };
-
- static float _vq_quantthresh__8u0__p6_0[] = {
- -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5,
- 12.5, 17.5, 22.5, 27.5,
- };
-
- static long _vq_quantmap__8u0__p6_0[] = {
- 11, 9, 7, 5, 3, 1, 0, 2,
- 4, 6, 8, 10, 12,
- };
-
- static encode_aux_threshmatch _vq_auxt__8u0__p6_0 = {
- _vq_quantthresh__8u0__p6_0,
- _vq_quantmap__8u0__p6_0,
- 13,
- 13
- };
-
- static static_codebook _8u0__p6_0 = {
- 2, 169,
- _vq_lengthlist__8u0__p6_0,
- 1, -526516224, 1616117760, 4, 0,
- _vq_quantlist__8u0__p6_0,
- NULL,
- &_vq_auxt__8u0__p6_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__8u0__p6_1[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__8u0__p6_1[] = {
- 1, 4, 4, 6, 6, 4, 6, 5, 7, 7, 4, 5, 6, 7, 7, 6,
- 7, 7, 7, 7, 6, 7, 7, 7, 7,
- };
-
- static float _vq_quantthresh__8u0__p6_1[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__8u0__p6_1[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__8u0__p6_1 = {
- _vq_quantthresh__8u0__p6_1,
- _vq_quantmap__8u0__p6_1,
- 5,
- 5
- };
-
- static static_codebook _8u0__p6_1 = {
- 2, 25,
- _vq_lengthlist__8u0__p6_1,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__8u0__p6_1,
- NULL,
- &_vq_auxt__8u0__p6_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__8u0__p7_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__8u0__p7_0[] = {
- 1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7,
- };
-
- static float _vq_quantthresh__8u0__p7_0[] = {
- -157.5, 157.5,
- };
-
- static long _vq_quantmap__8u0__p7_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__8u0__p7_0 = {
- _vq_quantthresh__8u0__p7_0,
- _vq_quantmap__8u0__p7_0,
- 3,
- 3
- };
-
- static static_codebook _8u0__p7_0 = {
- 4, 81,
- _vq_lengthlist__8u0__p7_0,
- 1, -518803456, 1628680192, 2, 0,
- _vq_quantlist__8u0__p7_0,
- NULL,
- &_vq_auxt__8u0__p7_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__8u0__p7_1[] = {
- 7,
- 6,
- 8,
- 5,
- 9,
- 4,
- 10,
- 3,
- 11,
- 2,
- 12,
- 1,
- 13,
- 0,
- 14,
- };
-
- static long _vq_lengthlist__8u0__p7_1[] = {
- 1, 5, 5, 5, 5,10,10,11,11,11,11,11,11,11,11, 5,
- 7, 6, 8, 8, 9,10,11,11,11,11,11,11,11,11, 6, 6,
- 7, 9, 7,11,10,11,11,11,11,11,11,11,11, 5, 6, 6,
- 11, 8,11,11,11,11,11,11,11,11,11,11, 5, 6, 6, 9,
- 10,11,10,11,11,11,11,11,11,11,11, 7,10,10,11,11,
- 11,11,11,11,11,11,11,11,11,11, 7,11, 8,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,
- };
-
- static float _vq_quantthresh__8u0__p7_1[] = {
- -136.5, -115.5, -94.5, -73.5, -52.5, -31.5, -10.5, 10.5,
- 31.5, 52.5, 73.5, 94.5, 115.5, 136.5,
- };
-
- static long _vq_quantmap__8u0__p7_1[] = {
- 13, 11, 9, 7, 5, 3, 1, 0,
- 2, 4, 6, 8, 10, 12, 14,
- };
-
- static encode_aux_threshmatch _vq_auxt__8u0__p7_1 = {
- _vq_quantthresh__8u0__p7_1,
- _vq_quantmap__8u0__p7_1,
- 15,
- 15
- };
-
- static static_codebook _8u0__p7_1 = {
- 2, 225,
- _vq_lengthlist__8u0__p7_1,
- 1, -520986624, 1620377600, 4, 0,
- _vq_quantlist__8u0__p7_1,
- NULL,
- &_vq_auxt__8u0__p7_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__8u0__p7_2[] = {
- 10,
- 9,
- 11,
- 8,
- 12,
- 7,
- 13,
- 6,
- 14,
- 5,
- 15,
- 4,
- 16,
- 3,
- 17,
- 2,
- 18,
- 1,
- 19,
- 0,
- 20,
- };
-
- static long _vq_lengthlist__8u0__p7_2[] = {
- 1, 6, 5, 7, 7, 9, 9, 9, 9,10,12,12,10,11,11,10,
- 11,11,11,10,11, 6, 8, 8, 9, 9,10,10, 9,10,11,11,
- 10,11,11,11,11,10,11,11,11,11, 6, 7, 8, 9, 9, 9,
- 10,11,10,11,12,11,10,11,11,11,11,11,11,12,10, 8,
- 9, 9,10, 9,10,10, 9,10,10,10,10,10, 9,10,10,10,
- 10, 9,10,10, 9, 9, 9, 9,10,10, 9, 9,10,10,11,10,
- 9,12,10,11,10, 9,10,10,10, 8, 9, 9,10, 9,10, 9,
- 9,10,10, 9,10, 9,11,10,10,10,10,10, 9,10, 8, 8,
- 9, 9,10, 9,11, 9, 8, 9, 9,10,11,10,10,10,11,12,
- 9, 9,11, 8, 9, 8,11,10,11,10,10, 9,11,10,10,10,
- 10,10,10,10,11,11,11,11, 8, 9, 9, 9,10,10,10,11,
- 11,12,11,12,11,10,10,10,12,11,11,11,10, 8,10, 9,
- 11,10,10,11,12,10,11,12,11,11,12,11,12,12,10,11,
- 11,10, 9, 9,10,11,12,10,10,10,11,10,11,11,10,12,
- 12,10,11,10,11,12,10, 9,10,10,11,10,11,11,11,11,
- 11,12,11,11,11, 9,11,10,11,10,11,10, 9, 9,10,11,
- 11,11,10,10,11,12,12,11,12,11,11,11,12,12,12,12,
- 11, 9,11,11,12,10,11,11,11,11,11,11,12,11,11,12,
- 11,11,11,10,11,11, 9,11,10,11,11,11,10,10,10,11,
- 11,11,12,10,11,10,11,11,11,11,12, 9,11,10,11,11,
- 10,10,11,11, 9,11,11,12,10,10,10,10,10,11,11,10,
- 9,10,11,11,12,11,10,10,12,11,11,12,11,12,11,11,
- 10,10,11,11,10,12,11,10,11,10,11,10,10,10,11,11,
- 10,10,11,11,11,11,10,10,10,12,11,11,11,11,10, 9,
- 10,11,11,11,12,11,11,11,12,10,11,11,11, 9,10,11,
- 11,11,11,11,11,10,10,11,11,12,11,10,11,12,11,10,
- 10,11, 9,10,11,11,11,11,11,10,11,11,10,12,11,11,
- 11,12,11,11,11,10,10,11,11,
- };
-
- static float _vq_quantthresh__8u0__p7_2[] = {
- -9.5, -8.5, -7.5, -6.5, -5.5, -4.5, -3.5, -2.5,
- -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5.5,
- 6.5, 7.5, 8.5, 9.5,
- };
-
- static long _vq_quantmap__8u0__p7_2[] = {
- 19, 17, 15, 13, 11, 9, 7, 5,
- 3, 1, 0, 2, 4, 6, 8, 10,
- 12, 14, 16, 18, 20,
- };
-
- static encode_aux_threshmatch _vq_auxt__8u0__p7_2 = {
- _vq_quantthresh__8u0__p7_2,
- _vq_quantmap__8u0__p7_2,
- 21,
- 21
- };
-
- static static_codebook _8u0__p7_2 = {
- 2, 441,
- _vq_lengthlist__8u0__p7_2,
- 1, -529268736, 1611661312, 5, 0,
- _vq_quantlist__8u0__p7_2,
- NULL,
- &_vq_auxt__8u0__p7_2,
- NULL,
- 0
- };
-
- static long _huff_lengthlist__8u0__single[] = {
- 4, 7,11, 9,12, 8, 7,10, 6, 4, 5, 5, 7, 5, 6,16,
- 9, 5, 5, 6, 7, 7, 9,16, 7, 4, 6, 5, 7, 5, 7,17,
- 10, 7, 7, 8, 7, 7, 8,18, 7, 5, 6, 4, 5, 4, 5,15,
- 7, 6, 7, 5, 6, 4, 5,15,12,13,18,12,17,11, 9,17,
- };
-
- static static_codebook _huff_book__8u0__single = {
- 2, 64,
- _huff_lengthlist__8u0__single,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _vq_quantlist__8u1__p1_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__8u1__p1_0[] = {
- 1, 4, 4, 5, 7, 7, 5, 7, 7, 5, 8, 8, 7, 9,10, 7,
- 9, 9, 5, 8, 8, 7,10, 9, 7, 9, 9, 5, 8, 8, 8,10,
- 10, 8,10,10, 7,10,10, 9,10,12,10,12,12, 7,10,10,
- 9,12,11,10,12,12, 5, 8, 8, 8,10,10, 8,10,10, 7,
- 10,10,10,12,12, 9,11,12, 7,10,10,10,12,12, 9,12,
- 10,
- };
-
- static float _vq_quantthresh__8u1__p1_0[] = {
- -0.5, 0.5,
- };
-
- static long _vq_quantmap__8u1__p1_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__8u1__p1_0 = {
- _vq_quantthresh__8u1__p1_0,
- _vq_quantmap__8u1__p1_0,
- 3,
- 3
- };
-
- static static_codebook _8u1__p1_0 = {
- 4, 81,
- _vq_lengthlist__8u1__p1_0,
- 1, -535822336, 1611661312, 2, 0,
- _vq_quantlist__8u1__p1_0,
- NULL,
- &_vq_auxt__8u1__p1_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__8u1__p2_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__8u1__p2_0[] = {
- 3, 4, 5, 5, 6, 6, 5, 6, 6, 5, 7, 6, 6, 7, 8, 6,
- 7, 8, 5, 6, 6, 6, 8, 7, 6, 8, 7, 5, 6, 6, 7, 8,
- 8, 6, 7, 7, 6, 8, 7, 7, 7, 9, 8, 9, 9, 6, 7, 8,
- 7, 9, 7, 8, 9, 9, 5, 6, 6, 6, 7, 7, 7, 8, 8, 6,
- 8, 7, 8, 9, 9, 7, 7, 9, 6, 7, 8, 8, 9, 9, 7, 9,
- 7,
- };
-
- static float _vq_quantthresh__8u1__p2_0[] = {
- -0.5, 0.5,
- };
-
- static long _vq_quantmap__8u1__p2_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__8u1__p2_0 = {
- _vq_quantthresh__8u1__p2_0,
- _vq_quantmap__8u1__p2_0,
- 3,
- 3
- };
-
- static static_codebook _8u1__p2_0 = {
- 4, 81,
- _vq_lengthlist__8u1__p2_0,
- 1, -535822336, 1611661312, 2, 0,
- _vq_quantlist__8u1__p2_0,
- NULL,
- &_vq_auxt__8u1__p2_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__8u1__p3_0[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__8u1__p3_0[] = {
- 1, 5, 5, 7, 7, 6, 7, 7, 9, 9, 6, 7, 7, 9, 9, 8,
- 10, 9,11,11, 9, 9, 9,11,11, 6, 8, 8,10,10, 8,10,
- 10,11,11, 8, 9,10,11,11,10,11,11,12,12,10,11,11,
- 12,13, 6, 8, 8,10,10, 8,10, 9,11,11, 8,10, 9,11,
- 11,10,11,11,12,12,10,11,11,12,12, 9,11,11,14,13,
- 10,12,11,14,14,10,12,11,14,13,12,13,13,15,14,12,
- 13,13,15,14, 8,11,11,13,14,10,11,12,13,15,10,11,
- 12,14,14,12,13,13,14,15,12,13,13,14,15, 5, 8, 8,
- 11,11, 8,10,10,12,12, 8,10,10,12,12,11,12,12,14,
- 13,11,12,12,13,14, 8,10,10,12,12, 9,11,12,13,14,
- 10,12,12,13,13,12,12,13,14,14,11,13,13,15,15, 7,
- 10,10,12,12, 9,12,11,14,12,10,11,12,13,14,12,13,
- 12,14,14,12,13,13,15,16,10,12,12,15,14,11,12,13,
- 15,15,11,13,13,15,16,14,14,15,15,16,13,14,15,17,
- 15, 9,12,12,14,15,11,13,12,15,15,11,13,13,15,15,
- 13,14,13,15,14,13,14,14,17, 0, 5, 8, 8,11,11, 8,
- 10,10,12,12, 8,10,10,12,12,11,12,12,14,14,11,12,
- 12,14,14, 7,10,10,12,12,10,12,12,13,13, 9,11,12,
- 12,13,11,12,13,15,15,11,12,13,14,15, 8,10,10,12,
- 12,10,12,11,13,13,10,12,11,13,13,11,13,13,15,14,
- 12,13,12,15,13, 9,12,12,14,14,11,13,13,16,15,11,
- 12,13,16,15,13,14,15,16,16,13,13,15,15,16,10,12,
- 12,15,14,11,13,13,14,16,11,13,13,15,16,13,15,15,
- 16,17,13,15,14,16,15, 8,11,11,14,15,10,12,12,15,
- 15,10,12,12,15,16,14,15,15,16,17,13,14,14,16,16,
- 9,12,12,15,15,11,13,14,15,17,11,13,13,15,16,14,
- 15,16,19,17,13,15,15, 0,17, 9,12,12,15,15,11,14,
- 13,16,15,11,13,13,15,16,15,15,15,18,17,13,15,15,
- 17,17,11,15,14,18,16,12,14,15,17,17,12,15,15,18,
- 18,15,15,16,15,19,14,16,16, 0, 0,11,14,14,16,17,
- 12,15,14,18,17,12,15,15,18,18,15,17,15,18,16,14,
- 16,16,18,18, 7,11,11,14,14,10,12,12,15,15,10,12,
- 13,15,15,13,14,15,16,16,14,15,15,18,18, 9,12,12,
- 15,15,11,13,13,16,15,11,12,13,16,16,14,15,15,17,
- 16,15,16,16,17,17, 9,12,12,15,15,11,13,13,15,17,
- 11,14,13,16,15,13,15,15,17,17,15,15,15,18,17,11,
- 14,14,17,15,12,14,15,17,18,13,13,15,17,17,14,16,
- 16,19,18,16,15,17,17, 0,11,14,14,17,17,12,15,15,
- 18, 0,12,15,14,18,16,14,17,17,19, 0,16,18,15, 0,
- 16,
- };
-
- static float _vq_quantthresh__8u1__p3_0[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__8u1__p3_0[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__8u1__p3_0 = {
- _vq_quantthresh__8u1__p3_0,
- _vq_quantmap__8u1__p3_0,
- 5,
- 5
- };
-
- static static_codebook _8u1__p3_0 = {
- 4, 625,
- _vq_lengthlist__8u1__p3_0,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__8u1__p3_0,
- NULL,
- &_vq_auxt__8u1__p3_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__8u1__p4_0[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__8u1__p4_0[] = {
- 4, 5, 5, 9, 9, 6, 7, 7, 9, 9, 6, 7, 7, 9, 9, 9,
- 9, 9,11,11, 9, 9, 9,11,11, 6, 7, 7, 9, 9, 7, 7,
- 8, 9,10, 7, 7, 8, 9,10, 9, 9,10,10,11, 9, 9,10,
- 10,12, 6, 7, 7, 9, 9, 7, 8, 7,10, 9, 7, 8, 7,10,
- 9, 9,10, 9,12,11,10,10, 9,12,10, 9,10,10,12,11,
- 9,10,10,12,11, 9,10,10,12,12,11,11,12,12,13,11,
- 11,12,12,13, 9, 9,10,12,11, 9,10,10,12,12,10,10,
- 10,12,12,11,12,11,13,12,11,12,11,13,12, 6, 7, 7,
- 9, 9, 7, 8, 8,10,10, 7, 8, 7,10, 9,10,10,10,12,
- 12,10,10,10,12,11, 7, 8, 7,10,10, 7, 7, 9,10,11,
- 8, 9, 9,11,10,10,10,11,10,12,10,10,11,12,12, 7,
- 8, 8,10,10, 7, 9, 8,11,10, 8, 8, 9,11,11,10,11,
- 10,12,11,10,11,11,12,12, 9,10,10,12,12, 9,10,10,
- 12,12,10,11,11,13,12,11,10,12,10,14,12,12,12,13,
- 14, 9,10,10,12,12, 9,11,10,12,12,10,11,11,12,12,
- 11,12,11,14,12,12,12,12,14,14, 5, 7, 7, 9, 9, 7,
- 7, 7, 9,10, 7, 8, 8,10,10,10,10,10,11,11,10,10,
- 10,12,12, 7, 8, 8,10,10, 8, 9, 8,11,10, 7, 8, 9,
- 10,11,10,10,10,11,12,10,10,11,11,13, 6, 7, 8,10,
- 10, 8, 9, 9,10,10, 7, 9, 7,11,10,10,11,10,12,12,
- 10,11,10,12,10, 9,10,10,12,12,10,11,11,13,12, 9,
- 10,10,12,12,12,12,12,14,13,11,11,12,11,14, 9,10,
- 10,11,12,10,11,11,12,13, 9,10,10,12,12,12,12,12,
- 14,13,11,12,10,14,11, 9, 9,10,11,12, 9,10,10,12,
- 12, 9,10,10,12,12,12,12,12,14,14,11,12,12,13,12,
- 9,10, 9,12,12, 9,10,11,12,13,10,11,10,13,11,12,
- 12,13,13,14,12,12,12,13,13, 9,10,10,12,12,10,11,
- 10,13,12,10,10,11,12,13,12,13,12,14,13,12,12,12,
- 13,14,11,12,11,14,13,10,10,11,13,13,12,12,12,14,
- 13,12,10,14,10,15,13,14,14,14,14,11,11,12,13,14,
- 10,12,11,13,13,12,12,12,13,15,12,13,11,15,12,13,
- 13,14,14,14, 9,10, 9,12,12, 9,10,10,12,12,10,10,
- 10,12,12,11,11,12,12,13,12,12,12,14,14, 9,10,10,
- 12,12,10,11,10,13,12,10,10,11,12,13,12,12,12,14,
- 13,12,12,13,13,14, 9,10,10,12,13,10,10,11,11,12,
- 9,11,10,13,12,12,12,12,13,14,12,13,12,14,13,11,
- 12,11,13,13,12,13,12,14,13,10,11,12,13,13,13,13,
- 13,14,15,12,11,14,12,14,11,11,12,12,13,12,12,12,
- 13,14,10,12,10,14,13,13,13,13,14,15,12,14,11,15,
- 10,
- };
-
- static float _vq_quantthresh__8u1__p4_0[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__8u1__p4_0[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__8u1__p4_0 = {
- _vq_quantthresh__8u1__p4_0,
- _vq_quantmap__8u1__p4_0,
- 5,
- 5
- };
-
- static static_codebook _8u1__p4_0 = {
- 4, 625,
- _vq_lengthlist__8u1__p4_0,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__8u1__p4_0,
- NULL,
- &_vq_auxt__8u1__p4_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__8u1__p5_0[] = {
- 4,
- 3,
- 5,
- 2,
- 6,
- 1,
- 7,
- 0,
- 8,
- };
-
- static long _vq_lengthlist__8u1__p5_0[] = {
- 1, 4, 4, 7, 7, 7, 7, 9, 9, 4, 6, 5, 8, 7, 8, 8,
- 10,10, 4, 6, 6, 8, 8, 8, 8,10,10, 7, 8, 8, 9, 9,
- 9, 9,11,11, 7, 8, 8, 9, 9, 9, 9,11,11, 8, 8, 8,
- 9, 9,10,10,12,11, 8, 8, 8, 9, 9,10,10,11,11, 9,
- 10,10,11,11,11,11,13,12, 9,10,10,11,11,12,12,12,
- 13,
- };
-
- static float _vq_quantthresh__8u1__p5_0[] = {
- -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5,
- };
-
- static long _vq_quantmap__8u1__p5_0[] = {
- 7, 5, 3, 1, 0, 2, 4, 6,
- 8,
- };
-
- static encode_aux_threshmatch _vq_auxt__8u1__p5_0 = {
- _vq_quantthresh__8u1__p5_0,
- _vq_quantmap__8u1__p5_0,
- 9,
- 9
- };
-
- static static_codebook _8u1__p5_0 = {
- 2, 81,
- _vq_lengthlist__8u1__p5_0,
- 1, -531628032, 1611661312, 4, 0,
- _vq_quantlist__8u1__p5_0,
- NULL,
- &_vq_auxt__8u1__p5_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__8u1__p6_0[] = {
- 4,
- 3,
- 5,
- 2,
- 6,
- 1,
- 7,
- 0,
- 8,
- };
-
- static long _vq_lengthlist__8u1__p6_0[] = {
- 3, 4, 4, 6, 6, 7, 7, 9, 9, 4, 4, 5, 6, 6, 7, 7,
- 9, 9, 4, 4, 4, 6, 6, 7, 7, 9, 9, 6, 6, 6, 7, 7,
- 8, 8, 9, 9, 6, 6, 6, 7, 7, 8, 8, 9, 9, 7, 7, 7,
- 8, 8, 8, 9,10,10, 7, 7, 7, 8, 8, 9, 8,10,10, 9,
- 9, 9, 9, 9,10,10,10,10, 9, 9, 9, 9, 9,10,10,10,
- 10,
- };
-
- static float _vq_quantthresh__8u1__p6_0[] = {
- -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5,
- };
-
- static long _vq_quantmap__8u1__p6_0[] = {
- 7, 5, 3, 1, 0, 2, 4, 6,
- 8,
- };
-
- static encode_aux_threshmatch _vq_auxt__8u1__p6_0 = {
- _vq_quantthresh__8u1__p6_0,
- _vq_quantmap__8u1__p6_0,
- 9,
- 9
- };
-
- static static_codebook _8u1__p6_0 = {
- 2, 81,
- _vq_lengthlist__8u1__p6_0,
- 1, -531628032, 1611661312, 4, 0,
- _vq_quantlist__8u1__p6_0,
- NULL,
- &_vq_auxt__8u1__p6_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__8u1__p7_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__8u1__p7_0[] = {
- 1, 4, 4, 5, 7, 7, 5, 7, 7, 5, 9, 9, 8,10,10, 8,
- 10,10, 5, 9, 9, 7,10,10, 8,10,10, 4,10,10, 9,12,
- 12, 9,11,11, 7,12,11,10,11,13,10,13,13, 7,12,12,
- 10,13,12,10,13,13, 4,10,10, 9,12,12, 9,12,12, 7,
- 12,12,10,13,13,10,12,13, 7,11,12,10,13,13,10,13,
- 11,
- };
-
- static float _vq_quantthresh__8u1__p7_0[] = {
- -5.5, 5.5,
- };
-
- static long _vq_quantmap__8u1__p7_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__8u1__p7_0 = {
- _vq_quantthresh__8u1__p7_0,
- _vq_quantmap__8u1__p7_0,
- 3,
- 3
- };
-
- static static_codebook _8u1__p7_0 = {
- 4, 81,
- _vq_lengthlist__8u1__p7_0,
- 1, -529137664, 1618345984, 2, 0,
- _vq_quantlist__8u1__p7_0,
- NULL,
- &_vq_auxt__8u1__p7_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__8u1__p7_1[] = {
- 5,
- 4,
- 6,
- 3,
- 7,
- 2,
- 8,
- 1,
- 9,
- 0,
- 10,
- };
-
- static long _vq_lengthlist__8u1__p7_1[] = {
- 2, 4, 4, 6, 6, 7, 7, 8, 8, 8, 8, 4, 5, 5, 7, 7,
- 8, 8, 9, 9, 9, 9, 4, 5, 5, 7, 7, 8, 8, 9, 9, 9,
- 9, 6, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 6, 7, 7, 8,
- 8, 8, 8, 9, 9, 9, 9, 8, 8, 8, 8, 8, 9, 9, 9, 9,
- 9, 9, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 8, 9, 9,
- 9, 9, 9, 9,10,10,10,10, 8, 9, 9, 9, 9, 9, 9,10,
- 10,10,10, 8, 9, 9, 9, 9, 9, 9,10,10,10,10, 8, 9,
- 9, 9, 9, 9, 9,10,10,10,10,
- };
-
- static float _vq_quantthresh__8u1__p7_1[] = {
- -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5,
- 3.5, 4.5,
- };
-
- static long _vq_quantmap__8u1__p7_1[] = {
- 9, 7, 5, 3, 1, 0, 2, 4,
- 6, 8, 10,
- };
-
- static encode_aux_threshmatch _vq_auxt__8u1__p7_1 = {
- _vq_quantthresh__8u1__p7_1,
- _vq_quantmap__8u1__p7_1,
- 11,
- 11
- };
-
- static static_codebook _8u1__p7_1 = {
- 2, 121,
- _vq_lengthlist__8u1__p7_1,
- 1, -531365888, 1611661312, 4, 0,
- _vq_quantlist__8u1__p7_1,
- NULL,
- &_vq_auxt__8u1__p7_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__8u1__p8_0[] = {
- 5,
- 4,
- 6,
- 3,
- 7,
- 2,
- 8,
- 1,
- 9,
- 0,
- 10,
- };
-
- static long _vq_lengthlist__8u1__p8_0[] = {
- 1, 4, 4, 6, 6, 8, 8,10,10,11,11, 4, 6, 6, 7, 7,
- 9, 9,11,11,13,12, 4, 6, 6, 7, 7, 9, 9,11,11,12,
- 12, 6, 7, 7, 9, 9,11,11,12,12,13,13, 6, 7, 7, 9,
- 9,11,11,12,12,13,13, 8, 9, 9,11,11,12,12,13,13,
- 14,14, 8, 9, 9,11,11,12,12,13,13,14,14, 9,11,11,
- 12,12,13,13,14,14,15,15, 9,11,11,12,12,13,13,14,
- 14,15,14,11,12,12,13,13,14,14,15,15,16,16,11,12,
- 12,13,13,14,14,15,15,15,15,
- };
-
- static float _vq_quantthresh__8u1__p8_0[] = {
- -49.5, -38.5, -27.5, -16.5, -5.5, 5.5, 16.5, 27.5,
- 38.5, 49.5,
- };
-
- static long _vq_quantmap__8u1__p8_0[] = {
- 9, 7, 5, 3, 1, 0, 2, 4,
- 6, 8, 10,
- };
-
- static encode_aux_threshmatch _vq_auxt__8u1__p8_0 = {
- _vq_quantthresh__8u1__p8_0,
- _vq_quantmap__8u1__p8_0,
- 11,
- 11
- };
-
- static static_codebook _8u1__p8_0 = {
- 2, 121,
- _vq_lengthlist__8u1__p8_0,
- 1, -524582912, 1618345984, 4, 0,
- _vq_quantlist__8u1__p8_0,
- NULL,
- &_vq_auxt__8u1__p8_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__8u1__p8_1[] = {
- 5,
- 4,
- 6,
- 3,
- 7,
- 2,
- 8,
- 1,
- 9,
- 0,
- 10,
- };
-
- static long _vq_lengthlist__8u1__p8_1[] = {
- 2, 5, 5, 6, 6, 7, 7, 7, 7, 8, 8, 5, 6, 6, 7, 7,
- 7, 7, 8, 8, 8, 8, 5, 6, 6, 7, 7, 7, 7, 8, 8, 8,
- 8, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 6, 7, 7, 7,
- 7, 8, 8, 8, 8, 8, 8, 7, 7, 7, 8, 8, 8, 8, 8, 8,
- 8, 8, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 9, 8, 9, 9, 7, 8, 8, 8, 8, 8, 8, 9,
- 8, 9, 9, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 8, 8,
- 8, 8, 8, 8, 8, 9, 9, 9, 9,
- };
-
- static float _vq_quantthresh__8u1__p8_1[] = {
- -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5,
- 3.5, 4.5,
- };
-
- static long _vq_quantmap__8u1__p8_1[] = {
- 9, 7, 5, 3, 1, 0, 2, 4,
- 6, 8, 10,
- };
-
- static encode_aux_threshmatch _vq_auxt__8u1__p8_1 = {
- _vq_quantthresh__8u1__p8_1,
- _vq_quantmap__8u1__p8_1,
- 11,
- 11
- };
-
- static static_codebook _8u1__p8_1 = {
- 2, 121,
- _vq_lengthlist__8u1__p8_1,
- 1, -531365888, 1611661312, 4, 0,
- _vq_quantlist__8u1__p8_1,
- NULL,
- &_vq_auxt__8u1__p8_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__8u1__p9_0[] = {
- 7,
- 6,
- 8,
- 5,
- 9,
- 4,
- 10,
- 3,
- 11,
- 2,
- 12,
- 1,
- 13,
- 0,
- 14,
- };
-
- static long _vq_lengthlist__8u1__p9_0[] = {
- 1, 4, 4,11,11,11,11,11,11,11,11,11,11,11,11, 3,
- 11, 8,11,11,11,11,11,11,11,11,11,11,11,11, 3, 9,
- 9,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,
- };
-
- static float _vq_quantthresh__8u1__p9_0[] = {
- -1657.5, -1402.5, -1147.5, -892.5, -637.5, -382.5, -127.5, 127.5,
- 382.5, 637.5, 892.5, 1147.5, 1402.5, 1657.5,
- };
-
- static long _vq_quantmap__8u1__p9_0[] = {
- 13, 11, 9, 7, 5, 3, 1, 0,
- 2, 4, 6, 8, 10, 12, 14,
- };
-
- static encode_aux_threshmatch _vq_auxt__8u1__p9_0 = {
- _vq_quantthresh__8u1__p9_0,
- _vq_quantmap__8u1__p9_0,
- 15,
- 15
- };
-
- static static_codebook _8u1__p9_0 = {
- 2, 225,
- _vq_lengthlist__8u1__p9_0,
- 1, -514071552, 1627381760, 4, 0,
- _vq_quantlist__8u1__p9_0,
- NULL,
- &_vq_auxt__8u1__p9_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__8u1__p9_1[] = {
- 7,
- 6,
- 8,
- 5,
- 9,
- 4,
- 10,
- 3,
- 11,
- 2,
- 12,
- 1,
- 13,
- 0,
- 14,
- };
-
- static long _vq_lengthlist__8u1__p9_1[] = {
- 1, 4, 4, 7, 7, 9, 9, 7, 7, 8, 8,10,10,11,11, 4,
- 7, 7, 9, 9,10,10, 8, 8,10,10,10,11,10,11, 4, 7,
- 7, 9, 9,10,10, 8, 8,10, 9,11,11,11,11, 7, 9, 9,
- 12,12,11,12,10,10,11,10,12,11,11,11, 7, 9, 9,11,
- 11,13,12, 9, 9,11,10,11,11,12,11, 9,10,10,12,12,
- 14,14,10,10,11,12,12,11,11,11, 9,10,11,11,13,14,
- 13,10,11,11,11,12,11,12,12, 7, 8, 8,10, 9,11,10,
- 11,12,12,11,12,14,12,13, 7, 8, 8, 9,10,10,11,12,
- 12,12,11,12,12,12,13, 9, 9, 9,11,11,13,12,12,12,
- 12,11,12,12,13,12, 8,10,10,11,10,11,12,12,12,12,
- 12,12,14,12,12, 9,11,11,11,12,12,12,12,13,13,12,
- 12,13,13,12,10,11,11,12,11,12,12,12,11,12,13,12,
- 12,12,13,11,11,12,12,12,13,12,12,11,12,13,13,12,
- 12,13,12,11,12,12,13,13,12,13,12,13,13,13,13,14,
- 13,
- };
-
- static float _vq_quantthresh__8u1__p9_1[] = {
- -110.5, -93.5, -76.5, -59.5, -42.5, -25.5, -8.5, 8.5,
- 25.5, 42.5, 59.5, 76.5, 93.5, 110.5,
- };
-
- static long _vq_quantmap__8u1__p9_1[] = {
- 13, 11, 9, 7, 5, 3, 1, 0,
- 2, 4, 6, 8, 10, 12, 14,
- };
-
- static encode_aux_threshmatch _vq_auxt__8u1__p9_1 = {
- _vq_quantthresh__8u1__p9_1,
- _vq_quantmap__8u1__p9_1,
- 15,
- 15
- };
-
- static static_codebook _8u1__p9_1 = {
- 2, 225,
- _vq_lengthlist__8u1__p9_1,
- 1, -522338304, 1620115456, 4, 0,
- _vq_quantlist__8u1__p9_1,
- NULL,
- &_vq_auxt__8u1__p9_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__8u1__p9_2[] = {
- 8,
- 7,
- 9,
- 6,
- 10,
- 5,
- 11,
- 4,
- 12,
- 3,
- 13,
- 2,
- 14,
- 1,
- 15,
- 0,
- 16,
- };
-
- static long _vq_lengthlist__8u1__p9_2[] = {
- 2, 5, 4, 6, 6, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9,
- 9, 5, 6, 6, 7, 7, 8, 8, 9, 8, 9, 9, 9, 9, 9, 9,
- 9, 9, 5, 6, 6, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 7, 7, 7, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9,
- 9,10,10, 9, 7, 7, 7, 8, 8, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9,10,10, 8, 8, 8, 9, 9, 9, 9,10,10,10, 9,
- 10,10,10,10,10,10, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9,
- 10,10,10,10,10,10,10, 9, 9, 9, 9, 9, 9, 9, 9,10,
- 10,10,10,10,10,10,10,10, 9, 9, 9, 9, 9,10,10,10,
- 10,10,10,10,10,10,10,10,10, 9, 9, 9, 9, 9, 9,10,
- 10,10,10,10,10,10,10,10,10,10, 9, 9, 9, 9, 9,10,
- 10,10,10,10,10,10,10,10,10,10,10, 9, 9, 9, 9,10,
- 10,10,10,10,10,10,10,10,10,10,10,10, 9, 9, 9, 9,
- 9,10,10,10,10,10,10,10,10,10,10,10,10, 9, 9, 9,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10, 9,10,
- 9, 9, 9,10,10,10,10,10,10,10,10,10,10,10,10, 9,
- 10, 9,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 9, 9,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,
- };
-
- static float _vq_quantthresh__8u1__p9_2[] = {
- -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5,
- 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5,
- };
-
- static long _vq_quantmap__8u1__p9_2[] = {
- 15, 13, 11, 9, 7, 5, 3, 1,
- 0, 2, 4, 6, 8, 10, 12, 14,
- 16,
- };
-
- static encode_aux_threshmatch _vq_auxt__8u1__p9_2 = {
- _vq_quantthresh__8u1__p9_2,
- _vq_quantmap__8u1__p9_2,
- 17,
- 17
- };
-
- static static_codebook _8u1__p9_2 = {
- 2, 289,
- _vq_lengthlist__8u1__p9_2,
- 1, -529530880, 1611661312, 5, 0,
- _vq_quantlist__8u1__p9_2,
- NULL,
- &_vq_auxt__8u1__p9_2,
- NULL,
- 0
- };
-
- static long _huff_lengthlist__8u1__single[] = {
- 4, 7,13, 9,15, 9,16, 8,10,13, 7, 5, 8, 6, 9, 7,
- 10, 7,10,11,11, 6, 7, 8, 8, 9, 9, 9,12,16, 8, 5,
- 8, 6, 8, 6, 9, 7,10,12,11, 7, 7, 7, 6, 7, 7, 7,
- 11,15, 7, 5, 8, 6, 7, 5, 7, 6, 9,13,13, 9, 9, 8,
- 6, 6, 5, 5, 9,14, 8, 6, 8, 6, 6, 4, 5, 3, 5,13,
- 9, 9,11, 8,10, 7, 8, 4, 5,12,11,16,17,15,17,12,
- 13, 8, 8,15,
- };
-
- static static_codebook _huff_book__8u1__single = {
- 2, 100,
- _huff_lengthlist__8u1__single,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist__44u0__long[] = {
- 5, 8,13,10,17,11,11,15, 7, 2, 4, 5, 8, 7, 9,16,
- 13, 4, 3, 5, 6, 8,11,20,10, 4, 5, 5, 7, 6, 8,18,
- 15, 7, 6, 7, 8,10,14,20,10, 6, 7, 6, 9, 7, 8,17,
- 9, 8,10, 8,10, 5, 4,11,12,17,19,14,16,10, 7,12,
- };
-
- static static_codebook _huff_book__44u0__long = {
- 2, 64,
- _huff_lengthlist__44u0__long,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u0__p1_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__44u0__p1_0[] = {
- 1, 4, 4, 5, 8, 7, 5, 7, 8, 5, 8, 8, 8,11,11, 8,
- 10,10, 5, 8, 8, 8,11,10, 8,11,11, 4, 8, 8, 8,11,
- 11, 8,11,11, 8,12,11,11,13,13,11,13,14, 7,11,11,
- 10,13,12,11,13,14, 4, 8, 8, 8,11,11, 8,11,12, 8,
- 11,11,11,13,13,10,12,13, 8,11,11,11,14,13,11,14,
- 13,
- };
-
- static float _vq_quantthresh__44u0__p1_0[] = {
- -0.5, 0.5,
- };
-
- static long _vq_quantmap__44u0__p1_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u0__p1_0 = {
- _vq_quantthresh__44u0__p1_0,
- _vq_quantmap__44u0__p1_0,
- 3,
- 3
- };
-
- static static_codebook _44u0__p1_0 = {
- 4, 81,
- _vq_lengthlist__44u0__p1_0,
- 1, -535822336, 1611661312, 2, 0,
- _vq_quantlist__44u0__p1_0,
- NULL,
- &_vq_auxt__44u0__p1_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u0__p2_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__44u0__p2_0[] = {
- 2, 4, 4, 5, 6, 6, 5, 6, 6, 5, 7, 7, 7, 8, 8, 6,
- 8, 8, 5, 7, 7, 6, 8, 8, 7, 8, 8, 4, 7, 7, 7, 8,
- 8, 7, 8, 8, 7, 8, 8, 8, 9,10, 8,10,10, 6, 8, 8,
- 8,10, 8, 8,10,10, 5, 7, 7, 7, 8, 8, 7, 8, 8, 6,
- 8, 8, 8,10,10, 8, 8,10, 6, 8, 8, 8,10,10, 8,10,
- 9,
- };
-
- static float _vq_quantthresh__44u0__p2_0[] = {
- -0.5, 0.5,
- };
-
- static long _vq_quantmap__44u0__p2_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u0__p2_0 = {
- _vq_quantthresh__44u0__p2_0,
- _vq_quantmap__44u0__p2_0,
- 3,
- 3
- };
-
- static static_codebook _44u0__p2_0 = {
- 4, 81,
- _vq_lengthlist__44u0__p2_0,
- 1, -535822336, 1611661312, 2, 0,
- _vq_quantlist__44u0__p2_0,
- NULL,
- &_vq_auxt__44u0__p2_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u0__p3_0[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__44u0__p3_0[] = {
- 1, 5, 5, 8, 8, 5, 8, 7, 9, 9, 5, 7, 8, 9, 9, 9,
- 10, 9,12,12, 9, 9,10,12,12, 6, 8, 8,11,10, 8,10,
- 10,11,11, 8, 9,10,11,11,10,11,11,14,13,10,11,11,
- 13,13, 5, 8, 8,10,10, 8,10,10,11,11, 8,10,10,11,
- 11,10,11,11,13,13,10,11,11,13,13, 9,11,11,15,14,
- 10,12,12,15,14,10,12,11,15,14,13,14,14,16,16,12,
- 14,13,17,15, 9,11,11,14,15,10,11,12,14,16,10,11,
- 12,14,16,12,13,14,16,16,13,13,15,15,18, 5, 8, 8,
- 11,11, 8,10,10,12,12, 8,10,10,12,13,11,12,12,14,
- 14,11,12,12,15,15, 8,10,10,13,13,10,12,12,13,13,
- 10,12,12,14,14,12,13,13,15,15,12,13,13,16,16, 7,
- 10,10,12,12,10,12,11,13,13,10,12,12,13,14,12,13,
- 12,15,14,12,13,13,16,16,10,12,12,17,16,12,13,13,
- 16,15,11,13,13,17,17,15,15,15,16,17,14,15,15,19,
- 19,10,12,12,15,16,11,13,12,15,18,11,13,13,16,16,
- 14,15,15,17,17,14,15,15,17,19, 5, 8, 8,11,11, 8,
- 10,10,12,12, 8,10,10,12,12,11,12,12,16,15,11,12,
- 12,14,15, 7,10,10,13,13,10,12,12,14,13,10,11,12,
- 13,13,12,13,13,16,16,12,12,13,15,15, 8,10,10,13,
- 13,10,12,12,14,14,10,12,12,13,13,12,13,13,16,16,
- 12,13,13,15,15,10,12,12,16,15,11,13,13,17,16,11,
- 12,13,16,15,13,15,15,19,17,14,15,14,17,16,10,12,
- 12,16,16,11,13,13,16,17,12,13,13,15,17,14,15,15,
- 17,19,14,15,15,17,17, 8,11,11,16,16,10,13,12,17,
- 17,10,12,13,16,16,15,17,16,20,19,14,15,17,18,19,
- 9,12,12,16,17,11,13,14,17,18,11,13,13,19,18,16,
- 17,18,19,19,15,16,16,19,19, 9,12,12,16,17,11,14,
- 13,18,17,11,13,13,17,17,16,17,16,20,19,14,16,16,
- 18,18,12,15,15,19,17,14,15,16, 0,20,13,15,16,20,
- 17,18,16,20, 0, 0,15,16,19,20, 0,12,15,14,18,19,
- 13,16,15,20,19,13,16,15,20,18,17,18,17, 0,20,16,
- 17,16, 0, 0, 8,11,11,16,15,10,12,12,17,17,10,13,
- 13,17,16,14,16,15,18,20,15,16,16,19,19, 9,12,12,
- 16,16,11,13,13,17,16,11,13,14,17,18,15,15,16,20,
- 20,16,16,17,19,19, 9,13,12,16,17,11,14,13,17,17,
- 11,14,14,18,17,14,16,15,18,19,16,17,18,18,19,12,
- 14,15,19,18,13,15,16,18, 0,13,14,15, 0, 0,16,16,
- 17,20, 0,17,17,20,20, 0,12,15,15,19,20,13,15,15,
- 0, 0,14,16,15, 0, 0,15,18,16, 0, 0,17,18,16, 0,
- 19,
- };
-
- static float _vq_quantthresh__44u0__p3_0[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__44u0__p3_0[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u0__p3_0 = {
- _vq_quantthresh__44u0__p3_0,
- _vq_quantmap__44u0__p3_0,
- 5,
- 5
- };
-
- static static_codebook _44u0__p3_0 = {
- 4, 625,
- _vq_lengthlist__44u0__p3_0,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__44u0__p3_0,
- NULL,
- &_vq_auxt__44u0__p3_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u0__p4_0[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__44u0__p4_0[] = {
- 4, 5, 5, 9, 9, 5, 6, 6, 9, 9, 5, 6, 6, 9, 9, 9,
- 10, 9,12,12, 9, 9,10,12,12, 5, 7, 7,10,10, 7, 7,
- 8,10,10, 6, 7, 8,10,10,10,10,10,11,13,10, 9,10,
- 12,13, 5, 7, 7,10,10, 6, 8, 7,10,10, 7, 8, 7,10,
- 10, 9,10,10,12,12,10,10,10,13,11, 9,10,10,13,13,
- 10,11,10,13,13,10,10,10,13,13,12,12,13,14,14,12,
- 12,13,14,14, 9,10,10,13,13,10,10,10,13,13,10,10,
- 10,13,13,12,13,12,15,14,12,13,12,15,15, 5, 7, 6,
- 10,10, 7, 8, 8,10,10, 7, 8, 8,10,10,10,11,10,13,
- 13,10,10,10,12,12, 7, 8, 8,11,10, 8, 8, 9,10,11,
- 8, 9, 9,11,11,11,10,11,11,14,11,11,11,13,13, 6,
- 8, 8,10,10, 7, 9, 8,11,10, 8, 9, 9,11,11,10,11,
- 10,14,11,10,11,11,13,13,10,11,11,14,13,10,10,11,
- 14,13,10,11,11,14,14,12,11,13,12,16,13,14,14,15,
- 15,10,10,11,13,14,10,11,10,14,13,10,11,11,14,14,
- 12,13,12,15,13,13,13,14,15,16, 5, 7, 7,10,10, 7,
- 8, 8,10,10, 7, 8, 8,10,10,10,10,10,13,13,10,10,
- 11,12,13, 6, 8, 8,11,10, 8, 9, 9,11,11, 7, 8, 9,
- 10,11,10,11,11,13,13,10,10,11,11,13, 6, 8, 8,10,
- 11, 8, 9, 9,11,11, 8, 9, 8,12,10,10,11,11,13,13,
- 10,11,10,14,11,10,10,10,14,13,10,11,11,14,13,10,
- 10,11,13,13,12,14,14,16,16,12,12,13,13,15,10,11,
- 11,13,14,10,11,11,14,15,10,11,10,13,13,13,14,13,
- 16,16,12,13,11,15,12, 9,10,10,13,13,10,11,11,14,
- 13,10,10,11,13,14,13,14,13,16,16,13,13,13,15,16,
- 9,10,10,13,13,10,10,11,13,14,10,11,11,15,13,13,
- 13,14,14,18,13,13,14,16,15, 9,10,10,13,14,10,11,
- 10,14,13,10,11,11,13,14,13,14,13,16,15,13,13,14,
- 15,16,12,13,12,16,14,11,11,13,15,15,13,14,13,16,
- 15,15,12,16,12,17,14,15,15,17,17,12,13,13,14,16,
- 11,13,11,16,15,12,13,14,15,16,14,15,13, 0,14,14,
- 16,16, 0, 0, 9,10,10,13,13,10,11,10,14,14,10,11,
- 11,13,13,12,13,13,14,16,13,14,14,16,16, 9,10,10,
- 14,14,11,11,11,14,13,10,10,11,14,14,13,13,13,16,
- 16,13,13,14,14,17, 9,10,10,13,14,10,11,11,13,15,
- 10,11,10,14,14,13,13,13,14,17,13,14,13,17,14,12,
- 13,13,16,14,13,14,13,16,15,12,12,13,15,16,15,15,
- 16,18,16,15,13,15,14, 0,12,12,13,14,16,13,13,14,
- 15,16,11,12,11,16,14,15,16,16,17,17,14,15,12,17,
- 12,
- };
-
- static float _vq_quantthresh__44u0__p4_0[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__44u0__p4_0[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u0__p4_0 = {
- _vq_quantthresh__44u0__p4_0,
- _vq_quantmap__44u0__p4_0,
- 5,
- 5
- };
-
- static static_codebook _44u0__p4_0 = {
- 4, 625,
- _vq_lengthlist__44u0__p4_0,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__44u0__p4_0,
- NULL,
- &_vq_auxt__44u0__p4_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u0__p5_0[] = {
- 4,
- 3,
- 5,
- 2,
- 6,
- 1,
- 7,
- 0,
- 8,
- };
-
- static long _vq_lengthlist__44u0__p5_0[] = {
- 1, 4, 4, 7, 7, 7, 7, 9, 9, 4, 6, 6, 8, 8, 8, 8,
- 9, 9, 4, 6, 6, 8, 8, 8, 8, 9, 9, 7, 8, 8, 9, 9,
- 9, 9,11,10, 7, 8, 8, 9, 9, 9, 9,10,10, 7, 8, 8,
- 9, 9,10,10,11,11, 7, 8, 8, 9, 9,10,10,11,11, 9,
- 9, 9,10,10,11,11,12,12, 9, 9, 9,10,11,11,11,12,
- 12,
- };
-
- static float _vq_quantthresh__44u0__p5_0[] = {
- -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5,
- };
-
- static long _vq_quantmap__44u0__p5_0[] = {
- 7, 5, 3, 1, 0, 2, 4, 6,
- 8,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u0__p5_0 = {
- _vq_quantthresh__44u0__p5_0,
- _vq_quantmap__44u0__p5_0,
- 9,
- 9
- };
-
- static static_codebook _44u0__p5_0 = {
- 2, 81,
- _vq_lengthlist__44u0__p5_0,
- 1, -531628032, 1611661312, 4, 0,
- _vq_quantlist__44u0__p5_0,
- NULL,
- &_vq_auxt__44u0__p5_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u0__p6_0[] = {
- 6,
- 5,
- 7,
- 4,
- 8,
- 3,
- 9,
- 2,
- 10,
- 1,
- 11,
- 0,
- 12,
- };
-
- static long _vq_lengthlist__44u0__p6_0[] = {
- 1, 4, 4, 6, 6, 8, 8,10, 9,11,10,14,13, 4, 6, 5,
- 8, 8, 9, 9,11,10,11,11,14,14, 4, 5, 6, 8, 8, 9,
- 9,10,10,11,11,14,14, 6, 8, 8, 9, 9,10,10,11,11,
- 12,12,16,15, 7, 8, 8, 9, 9,10,10,11,11,12,12,15,
- 15, 9,10,10,10,10,11,11,12,12,12,12,15,15, 9,10,
- 9,10,11,11,11,12,12,12,13,15,15,10,10,11,11,11,
- 12,12,13,12,13,13,16,15,10,11,11,11,11,12,12,13,
- 12,13,13,16,17,11,11,12,12,12,13,13,13,14,14,15,
- 17,17,11,11,12,12,12,13,13,13,14,14,14,16,18,14,
- 15,15,15,15,16,16,16,16,17,18, 0, 0,14,15,15,15,
- 15,17,16,17,18,17,17,18, 0,
- };
-
- static float _vq_quantthresh__44u0__p6_0[] = {
- -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5,
- 12.5, 17.5, 22.5, 27.5,
- };
-
- static long _vq_quantmap__44u0__p6_0[] = {
- 11, 9, 7, 5, 3, 1, 0, 2,
- 4, 6, 8, 10, 12,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u0__p6_0 = {
- _vq_quantthresh__44u0__p6_0,
- _vq_quantmap__44u0__p6_0,
- 13,
- 13
- };
-
- static static_codebook _44u0__p6_0 = {
- 2, 169,
- _vq_lengthlist__44u0__p6_0,
- 1, -526516224, 1616117760, 4, 0,
- _vq_quantlist__44u0__p6_0,
- NULL,
- &_vq_auxt__44u0__p6_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u0__p6_1[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__44u0__p6_1[] = {
- 2, 4, 4, 5, 5, 4, 5, 5, 5, 5, 4, 5, 5, 5, 5, 5,
- 6, 6, 6, 6, 5, 6, 6, 6, 6,
- };
-
- static float _vq_quantthresh__44u0__p6_1[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__44u0__p6_1[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u0__p6_1 = {
- _vq_quantthresh__44u0__p6_1,
- _vq_quantmap__44u0__p6_1,
- 5,
- 5
- };
-
- static static_codebook _44u0__p6_1 = {
- 2, 25,
- _vq_lengthlist__44u0__p6_1,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__44u0__p6_1,
- NULL,
- &_vq_auxt__44u0__p6_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u0__p7_0[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__44u0__p7_0[] = {
- 1, 4, 4,11,11, 9,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11, 9,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,10,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,
- };
-
- static float _vq_quantthresh__44u0__p7_0[] = {
- -253.5, -84.5, 84.5, 253.5,
- };
-
- static long _vq_quantmap__44u0__p7_0[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u0__p7_0 = {
- _vq_quantthresh__44u0__p7_0,
- _vq_quantmap__44u0__p7_0,
- 5,
- 5
- };
-
- static static_codebook _44u0__p7_0 = {
- 4, 625,
- _vq_lengthlist__44u0__p7_0,
- 1, -518709248, 1626677248, 3, 0,
- _vq_quantlist__44u0__p7_0,
- NULL,
- &_vq_auxt__44u0__p7_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u0__p7_1[] = {
- 6,
- 5,
- 7,
- 4,
- 8,
- 3,
- 9,
- 2,
- 10,
- 1,
- 11,
- 0,
- 12,
- };
-
- static long _vq_lengthlist__44u0__p7_1[] = {
- 1, 4, 4, 6, 6, 6, 6, 7, 7, 8, 8, 9, 9, 5, 7, 7,
- 8, 7, 7, 7, 9, 8,10, 9,10,11, 5, 7, 7, 8, 8, 7,
- 7, 8, 9,10,10,11,11, 6, 8, 8, 9, 9, 9, 9,11,10,
- 12,12,15,12, 6, 8, 8, 9, 9, 9, 9,11,11,12,11,14,
- 12, 7, 8, 8,10,10,12,12,13,13,13,15,13,13, 7, 8,
- 8,10,10,11,11,13,12,14,15,15,15, 9,10,10,11,12,
- 13,13,14,15,14,15,14,15, 8,10,10,12,12,14,14,15,
- 14,14,15,15,14,10,12,12,14,14,15,14,15,15,15,14,
- 15,15,10,12,12,13,14,15,14,15,15,14,15,15,15,12,
- 15,13,15,14,15,15,15,15,15,15,15,15,13,13,15,15,
- 15,15,15,15,15,15,15,15,15,
- };
-
- static float _vq_quantthresh__44u0__p7_1[] = {
- -71.5, -58.5, -45.5, -32.5, -19.5, -6.5, 6.5, 19.5,
- 32.5, 45.5, 58.5, 71.5,
- };
-
- static long _vq_quantmap__44u0__p7_1[] = {
- 11, 9, 7, 5, 3, 1, 0, 2,
- 4, 6, 8, 10, 12,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u0__p7_1 = {
- _vq_quantthresh__44u0__p7_1,
- _vq_quantmap__44u0__p7_1,
- 13,
- 13
- };
-
- static static_codebook _44u0__p7_1 = {
- 2, 169,
- _vq_lengthlist__44u0__p7_1,
- 1, -523010048, 1618608128, 4, 0,
- _vq_quantlist__44u0__p7_1,
- NULL,
- &_vq_auxt__44u0__p7_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u0__p7_2[] = {
- 6,
- 5,
- 7,
- 4,
- 8,
- 3,
- 9,
- 2,
- 10,
- 1,
- 11,
- 0,
- 12,
- };
-
- static long _vq_lengthlist__44u0__p7_2[] = {
- 2, 5, 4, 6, 6, 7, 7, 8, 8, 8, 8, 9, 8, 5, 5, 6,
- 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 5, 6, 5, 7, 7, 8,
- 8, 8, 8, 9, 9, 9, 9, 6, 7, 7, 8, 8, 8, 8, 9, 8,
- 9, 9, 9, 9, 6, 7, 7, 8, 7, 8, 8, 9, 9, 9, 9, 9,
- 9, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 7, 8,
- 8, 9, 8, 9, 8, 9, 9, 9, 9, 9, 9, 8, 9, 8, 9, 9,
- 9, 9, 9, 9, 9, 9,10,10, 8, 8, 9, 9, 9, 9, 9, 9,
- 9, 9,10, 9,10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9,10,10,10, 9, 9, 9, 9, 9,
- 9, 9, 9,10, 9, 9,10,10, 9,
- };
-
- static float _vq_quantthresh__44u0__p7_2[] = {
- -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5,
- 2.5, 3.5, 4.5, 5.5,
- };
-
- static long _vq_quantmap__44u0__p7_2[] = {
- 11, 9, 7, 5, 3, 1, 0, 2,
- 4, 6, 8, 10, 12,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u0__p7_2 = {
- _vq_quantthresh__44u0__p7_2,
- _vq_quantmap__44u0__p7_2,
- 13,
- 13
- };
-
- static static_codebook _44u0__p7_2 = {
- 2, 169,
- _vq_lengthlist__44u0__p7_2,
- 1, -531103744, 1611661312, 4, 0,
- _vq_quantlist__44u0__p7_2,
- NULL,
- &_vq_auxt__44u0__p7_2,
- NULL,
- 0
- };
-
- static long _huff_lengthlist__44u0__short[] = {
- 12,13,14,13,17,12,15,17, 5, 5, 6,10,10,11,15,16,
- 4, 3, 3, 7, 5, 7,10,16, 7, 7, 7,10, 9,11,12,16,
- 6, 5, 5, 9, 5, 6,10,16, 8, 7, 7, 9, 6, 7, 9,16,
- 11, 7, 3, 6, 4, 5, 8,16,12, 9, 4, 8, 5, 7, 9,16,
- };
-
- static static_codebook _huff_book__44u0__short = {
- 2, 64,
- _huff_lengthlist__44u0__short,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist__44u1__long[] = {
- 5, 8,13,10,17,11,11,15, 7, 2, 4, 5, 8, 7, 9,16,
- 13, 4, 3, 5, 6, 8,11,20,10, 4, 5, 5, 7, 6, 8,18,
- 15, 7, 6, 7, 8,10,14,20,10, 6, 7, 6, 9, 7, 8,17,
- 9, 8,10, 8,10, 5, 4,11,12,17,19,14,16,10, 7,12,
- };
-
- static static_codebook _huff_book__44u1__long = {
- 2, 64,
- _huff_lengthlist__44u1__long,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u1__p1_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__44u1__p1_0[] = {
- 1, 4, 4, 5, 8, 7, 5, 7, 8, 5, 8, 8, 8,11,11, 8,
- 10,10, 5, 8, 8, 8,11,10, 8,11,11, 4, 8, 8, 8,11,
- 11, 8,11,11, 8,12,11,11,13,13,11,13,14, 7,11,11,
- 10,13,12,11,13,14, 4, 8, 8, 8,11,11, 8,11,12, 8,
- 11,11,11,13,13,10,12,13, 8,11,11,11,14,13,11,14,
- 13,
- };
-
- static float _vq_quantthresh__44u1__p1_0[] = {
- -0.5, 0.5,
- };
-
- static long _vq_quantmap__44u1__p1_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u1__p1_0 = {
- _vq_quantthresh__44u1__p1_0,
- _vq_quantmap__44u1__p1_0,
- 3,
- 3
- };
-
- static static_codebook _44u1__p1_0 = {
- 4, 81,
- _vq_lengthlist__44u1__p1_0,
- 1, -535822336, 1611661312, 2, 0,
- _vq_quantlist__44u1__p1_0,
- NULL,
- &_vq_auxt__44u1__p1_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u1__p2_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__44u1__p2_0[] = {
- 2, 4, 4, 5, 6, 6, 5, 6, 6, 5, 7, 7, 7, 8, 8, 6,
- 8, 8, 5, 7, 7, 6, 8, 8, 7, 8, 8, 4, 7, 7, 7, 8,
- 8, 7, 8, 8, 7, 8, 8, 8, 9,10, 8,10,10, 6, 8, 8,
- 8,10, 8, 8,10,10, 5, 7, 7, 7, 8, 8, 7, 8, 8, 6,
- 8, 8, 8,10,10, 8, 8,10, 6, 8, 8, 8,10,10, 8,10,
- 9,
- };
-
- static float _vq_quantthresh__44u1__p2_0[] = {
- -0.5, 0.5,
- };
-
- static long _vq_quantmap__44u1__p2_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u1__p2_0 = {
- _vq_quantthresh__44u1__p2_0,
- _vq_quantmap__44u1__p2_0,
- 3,
- 3
- };
-
- static static_codebook _44u1__p2_0 = {
- 4, 81,
- _vq_lengthlist__44u1__p2_0,
- 1, -535822336, 1611661312, 2, 0,
- _vq_quantlist__44u1__p2_0,
- NULL,
- &_vq_auxt__44u1__p2_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u1__p3_0[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__44u1__p3_0[] = {
- 1, 5, 5, 8, 8, 5, 8, 7, 9, 9, 5, 7, 8, 9, 9, 9,
- 10, 9,12,12, 9, 9,10,12,12, 6, 8, 8,11,10, 8,10,
- 10,11,11, 8, 9,10,11,11,10,11,11,14,13,10,11,11,
- 13,13, 5, 8, 8,10,10, 8,10,10,11,11, 8,10,10,11,
- 11,10,11,11,13,13,10,11,11,13,13, 9,11,11,15,14,
- 10,12,12,15,14,10,12,11,15,14,13,14,14,16,16,12,
- 14,13,17,15, 9,11,11,14,15,10,11,12,14,16,10,11,
- 12,14,16,12,13,14,16,16,13,13,15,15,18, 5, 8, 8,
- 11,11, 8,10,10,12,12, 8,10,10,12,13,11,12,12,14,
- 14,11,12,12,15,15, 8,10,10,13,13,10,12,12,13,13,
- 10,12,12,14,14,12,13,13,15,15,12,13,13,16,16, 7,
- 10,10,12,12,10,12,11,13,13,10,12,12,13,14,12,13,
- 12,15,14,12,13,13,16,16,10,12,12,17,16,12,13,13,
- 16,15,11,13,13,17,17,15,15,15,16,17,14,15,15,19,
- 19,10,12,12,15,16,11,13,12,15,18,11,13,13,16,16,
- 14,15,15,17,17,14,15,15,17,19, 5, 8, 8,11,11, 8,
- 10,10,12,12, 8,10,10,12,12,11,12,12,16,15,11,12,
- 12,14,15, 7,10,10,13,13,10,12,12,14,13,10,11,12,
- 13,13,12,13,13,16,16,12,12,13,15,15, 8,10,10,13,
- 13,10,12,12,14,14,10,12,12,13,13,12,13,13,16,16,
- 12,13,13,15,15,10,12,12,16,15,11,13,13,17,16,11,
- 12,13,16,15,13,15,15,19,17,14,15,14,17,16,10,12,
- 12,16,16,11,13,13,16,17,12,13,13,15,17,14,15,15,
- 17,19,14,15,15,17,17, 8,11,11,16,16,10,13,12,17,
- 17,10,12,13,16,16,15,17,16,20,19,14,15,17,18,19,
- 9,12,12,16,17,11,13,14,17,18,11,13,13,19,18,16,
- 17,18,19,19,15,16,16,19,19, 9,12,12,16,17,11,14,
- 13,18,17,11,13,13,17,17,16,17,16,20,19,14,16,16,
- 18,18,12,15,15,19,17,14,15,16, 0,20,13,15,16,20,
- 17,18,16,20, 0, 0,15,16,19,20, 0,12,15,14,18,19,
- 13,16,15,20,19,13,16,15,20,18,17,18,17, 0,20,16,
- 17,16, 0, 0, 8,11,11,16,15,10,12,12,17,17,10,13,
- 13,17,16,14,16,15,18,20,15,16,16,19,19, 9,12,12,
- 16,16,11,13,13,17,16,11,13,14,17,18,15,15,16,20,
- 20,16,16,17,19,19, 9,13,12,16,17,11,14,13,17,17,
- 11,14,14,18,17,14,16,15,18,19,16,17,18,18,19,12,
- 14,15,19,18,13,15,16,18, 0,13,14,15, 0, 0,16,16,
- 17,20, 0,17,17,20,20, 0,12,15,15,19,20,13,15,15,
- 0, 0,14,16,15, 0, 0,15,18,16, 0, 0,17,18,16, 0,
- 19,
- };
-
- static float _vq_quantthresh__44u1__p3_0[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__44u1__p3_0[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u1__p3_0 = {
- _vq_quantthresh__44u1__p3_0,
- _vq_quantmap__44u1__p3_0,
- 5,
- 5
- };
-
- static static_codebook _44u1__p3_0 = {
- 4, 625,
- _vq_lengthlist__44u1__p3_0,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__44u1__p3_0,
- NULL,
- &_vq_auxt__44u1__p3_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u1__p4_0[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__44u1__p4_0[] = {
- 4, 5, 5, 9, 9, 5, 6, 6, 9, 9, 5, 6, 6, 9, 9, 9,
- 10, 9,12,12, 9, 9,10,12,12, 5, 7, 7,10,10, 7, 7,
- 8,10,10, 6, 7, 8,10,10,10,10,10,11,13,10, 9,10,
- 12,13, 5, 7, 7,10,10, 6, 8, 7,10,10, 7, 8, 7,10,
- 10, 9,10,10,12,12,10,10,10,13,11, 9,10,10,13,13,
- 10,11,10,13,13,10,10,10,13,13,12,12,13,14,14,12,
- 12,13,14,14, 9,10,10,13,13,10,10,10,13,13,10,10,
- 10,13,13,12,13,12,15,14,12,13,12,15,15, 5, 7, 6,
- 10,10, 7, 8, 8,10,10, 7, 8, 8,10,10,10,11,10,13,
- 13,10,10,10,12,12, 7, 8, 8,11,10, 8, 8, 9,10,11,
- 8, 9, 9,11,11,11,10,11,11,14,11,11,11,13,13, 6,
- 8, 8,10,10, 7, 9, 8,11,10, 8, 9, 9,11,11,10,11,
- 10,14,11,10,11,11,13,13,10,11,11,14,13,10,10,11,
- 14,13,10,11,11,14,14,12,11,13,12,16,13,14,14,15,
- 15,10,10,11,13,14,10,11,10,14,13,10,11,11,14,14,
- 12,13,12,15,13,13,13,14,15,16, 5, 7, 7,10,10, 7,
- 8, 8,10,10, 7, 8, 8,10,10,10,10,10,13,13,10,10,
- 11,12,13, 6, 8, 8,11,10, 8, 9, 9,11,11, 7, 8, 9,
- 10,11,10,11,11,13,13,10,10,11,11,13, 6, 8, 8,10,
- 11, 8, 9, 9,11,11, 8, 9, 8,12,10,10,11,11,13,13,
- 10,11,10,14,11,10,10,10,14,13,10,11,11,14,13,10,
- 10,11,13,13,12,14,14,16,16,12,12,13,13,15,10,11,
- 11,13,14,10,11,11,14,15,10,11,10,13,13,13,14,13,
- 16,16,12,13,11,15,12, 9,10,10,13,13,10,11,11,14,
- 13,10,10,11,13,14,13,14,13,16,16,13,13,13,15,16,
- 9,10,10,13,13,10,10,11,13,14,10,11,11,15,13,13,
- 13,14,14,18,13,13,14,16,15, 9,10,10,13,14,10,11,
- 10,14,13,10,11,11,13,14,13,14,13,16,15,13,13,14,
- 15,16,12,13,12,16,14,11,11,13,15,15,13,14,13,16,
- 15,15,12,16,12,17,14,15,15,17,17,12,13,13,14,16,
- 11,13,11,16,15,12,13,14,15,16,14,15,13, 0,14,14,
- 16,16, 0, 0, 9,10,10,13,13,10,11,10,14,14,10,11,
- 11,13,13,12,13,13,14,16,13,14,14,16,16, 9,10,10,
- 14,14,11,11,11,14,13,10,10,11,14,14,13,13,13,16,
- 16,13,13,14,14,17, 9,10,10,13,14,10,11,11,13,15,
- 10,11,10,14,14,13,13,13,14,17,13,14,13,17,14,12,
- 13,13,16,14,13,14,13,16,15,12,12,13,15,16,15,15,
- 16,18,16,15,13,15,14, 0,12,12,13,14,16,13,13,14,
- 15,16,11,12,11,16,14,15,16,16,17,17,14,15,12,17,
- 12,
- };
-
- static float _vq_quantthresh__44u1__p4_0[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__44u1__p4_0[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u1__p4_0 = {
- _vq_quantthresh__44u1__p4_0,
- _vq_quantmap__44u1__p4_0,
- 5,
- 5
- };
-
- static static_codebook _44u1__p4_0 = {
- 4, 625,
- _vq_lengthlist__44u1__p4_0,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__44u1__p4_0,
- NULL,
- &_vq_auxt__44u1__p4_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u1__p5_0[] = {
- 4,
- 3,
- 5,
- 2,
- 6,
- 1,
- 7,
- 0,
- 8,
- };
-
- static long _vq_lengthlist__44u1__p5_0[] = {
- 1, 4, 4, 7, 7, 7, 7, 9, 9, 4, 6, 6, 8, 8, 8, 8,
- 9, 9, 4, 6, 6, 8, 8, 8, 8, 9, 9, 7, 8, 8, 9, 9,
- 9, 9,11,10, 7, 8, 8, 9, 9, 9, 9,10,10, 7, 8, 8,
- 9, 9,10,10,11,11, 7, 8, 8, 9, 9,10,10,11,11, 9,
- 9, 9,10,10,11,11,12,12, 9, 9, 9,10,11,11,11,12,
- 12,
- };
-
- static float _vq_quantthresh__44u1__p5_0[] = {
- -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5,
- };
-
- static long _vq_quantmap__44u1__p5_0[] = {
- 7, 5, 3, 1, 0, 2, 4, 6,
- 8,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u1__p5_0 = {
- _vq_quantthresh__44u1__p5_0,
- _vq_quantmap__44u1__p5_0,
- 9,
- 9
- };
-
- static static_codebook _44u1__p5_0 = {
- 2, 81,
- _vq_lengthlist__44u1__p5_0,
- 1, -531628032, 1611661312, 4, 0,
- _vq_quantlist__44u1__p5_0,
- NULL,
- &_vq_auxt__44u1__p5_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u1__p6_0[] = {
- 6,
- 5,
- 7,
- 4,
- 8,
- 3,
- 9,
- 2,
- 10,
- 1,
- 11,
- 0,
- 12,
- };
-
- static long _vq_lengthlist__44u1__p6_0[] = {
- 1, 4, 4, 6, 6, 8, 8,10, 9,11,10,14,13, 4, 6, 5,
- 8, 8, 9, 9,11,10,11,11,14,14, 4, 5, 6, 8, 8, 9,
- 9,10,10,11,11,14,14, 6, 8, 8, 9, 9,10,10,11,11,
- 12,12,16,15, 7, 8, 8, 9, 9,10,10,11,11,12,12,15,
- 15, 9,10,10,10,10,11,11,12,12,12,12,15,15, 9,10,
- 9,10,11,11,11,12,12,12,13,15,15,10,10,11,11,11,
- 12,12,13,12,13,13,16,15,10,11,11,11,11,12,12,13,
- 12,13,13,16,17,11,11,12,12,12,13,13,13,14,14,15,
- 17,17,11,11,12,12,12,13,13,13,14,14,14,16,18,14,
- 15,15,15,15,16,16,16,16,17,18, 0, 0,14,15,15,15,
- 15,17,16,17,18,17,17,18, 0,
- };
-
- static float _vq_quantthresh__44u1__p6_0[] = {
- -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5,
- 12.5, 17.5, 22.5, 27.5,
- };
-
- static long _vq_quantmap__44u1__p6_0[] = {
- 11, 9, 7, 5, 3, 1, 0, 2,
- 4, 6, 8, 10, 12,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u1__p6_0 = {
- _vq_quantthresh__44u1__p6_0,
- _vq_quantmap__44u1__p6_0,
- 13,
- 13
- };
-
- static static_codebook _44u1__p6_0 = {
- 2, 169,
- _vq_lengthlist__44u1__p6_0,
- 1, -526516224, 1616117760, 4, 0,
- _vq_quantlist__44u1__p6_0,
- NULL,
- &_vq_auxt__44u1__p6_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u1__p6_1[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__44u1__p6_1[] = {
- 2, 4, 4, 5, 5, 4, 5, 5, 5, 5, 4, 5, 5, 5, 5, 5,
- 6, 6, 6, 6, 5, 6, 6, 6, 6,
- };
-
- static float _vq_quantthresh__44u1__p6_1[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__44u1__p6_1[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u1__p6_1 = {
- _vq_quantthresh__44u1__p6_1,
- _vq_quantmap__44u1__p6_1,
- 5,
- 5
- };
-
- static static_codebook _44u1__p6_1 = {
- 2, 25,
- _vq_lengthlist__44u1__p6_1,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__44u1__p6_1,
- NULL,
- &_vq_auxt__44u1__p6_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u1__p7_0[] = {
- 3,
- 2,
- 4,
- 1,
- 5,
- 0,
- 6,
- };
-
- static long _vq_lengthlist__44u1__p7_0[] = {
- 1, 3, 2, 9, 9, 7, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8,
- };
-
- static float _vq_quantthresh__44u1__p7_0[] = {
- -422.5, -253.5, -84.5, 84.5, 253.5, 422.5,
- };
-
- static long _vq_quantmap__44u1__p7_0[] = {
- 5, 3, 1, 0, 2, 4, 6,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u1__p7_0 = {
- _vq_quantthresh__44u1__p7_0,
- _vq_quantmap__44u1__p7_0,
- 7,
- 7
- };
-
- static static_codebook _44u1__p7_0 = {
- 2, 49,
- _vq_lengthlist__44u1__p7_0,
- 1, -518017024, 1626677248, 3, 0,
- _vq_quantlist__44u1__p7_0,
- NULL,
- &_vq_auxt__44u1__p7_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u1__p7_1[] = {
- 6,
- 5,
- 7,
- 4,
- 8,
- 3,
- 9,
- 2,
- 10,
- 1,
- 11,
- 0,
- 12,
- };
-
- static long _vq_lengthlist__44u1__p7_1[] = {
- 1, 4, 4, 6, 6, 6, 6, 7, 7, 8, 8, 9, 9, 5, 7, 7,
- 8, 7, 7, 7, 9, 8,10, 9,10,11, 5, 7, 7, 8, 8, 7,
- 7, 8, 9,10,10,11,11, 6, 8, 8, 9, 9, 9, 9,11,10,
- 12,12,15,12, 6, 8, 8, 9, 9, 9, 9,11,11,12,11,14,
- 12, 7, 8, 8,10,10,12,12,13,13,13,15,13,13, 7, 8,
- 8,10,10,11,11,13,12,14,15,15,15, 9,10,10,11,12,
- 13,13,14,15,14,15,14,15, 8,10,10,12,12,14,14,15,
- 14,14,15,15,14,10,12,12,14,14,15,14,15,15,15,14,
- 15,15,10,12,12,13,14,15,14,15,15,14,15,15,15,12,
- 15,13,15,14,15,15,15,15,15,15,15,15,13,13,15,15,
- 15,15,15,15,15,15,15,15,15,
- };
-
- static float _vq_quantthresh__44u1__p7_1[] = {
- -71.5, -58.5, -45.5, -32.5, -19.5, -6.5, 6.5, 19.5,
- 32.5, 45.5, 58.5, 71.5,
- };
-
- static long _vq_quantmap__44u1__p7_1[] = {
- 11, 9, 7, 5, 3, 1, 0, 2,
- 4, 6, 8, 10, 12,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u1__p7_1 = {
- _vq_quantthresh__44u1__p7_1,
- _vq_quantmap__44u1__p7_1,
- 13,
- 13
- };
-
- static static_codebook _44u1__p7_1 = {
- 2, 169,
- _vq_lengthlist__44u1__p7_1,
- 1, -523010048, 1618608128, 4, 0,
- _vq_quantlist__44u1__p7_1,
- NULL,
- &_vq_auxt__44u1__p7_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u1__p7_2[] = {
- 6,
- 5,
- 7,
- 4,
- 8,
- 3,
- 9,
- 2,
- 10,
- 1,
- 11,
- 0,
- 12,
- };
-
- static long _vq_lengthlist__44u1__p7_2[] = {
- 2, 5, 4, 6, 6, 7, 7, 8, 8, 8, 8, 9, 8, 5, 5, 6,
- 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 5, 6, 5, 7, 7, 8,
- 8, 8, 8, 9, 9, 9, 9, 6, 7, 7, 8, 8, 8, 8, 9, 8,
- 9, 9, 9, 9, 6, 7, 7, 8, 7, 8, 8, 9, 9, 9, 9, 9,
- 9, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 7, 8,
- 8, 9, 8, 9, 8, 9, 9, 9, 9, 9, 9, 8, 9, 8, 9, 9,
- 9, 9, 9, 9, 9, 9,10,10, 8, 8, 9, 9, 9, 9, 9, 9,
- 9, 9,10, 9,10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9,10,10,10, 9, 9, 9, 9, 9,
- 9, 9, 9,10, 9, 9,10,10, 9,
- };
-
- static float _vq_quantthresh__44u1__p7_2[] = {
- -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5,
- 2.5, 3.5, 4.5, 5.5,
- };
-
- static long _vq_quantmap__44u1__p7_2[] = {
- 11, 9, 7, 5, 3, 1, 0, 2,
- 4, 6, 8, 10, 12,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u1__p7_2 = {
- _vq_quantthresh__44u1__p7_2,
- _vq_quantmap__44u1__p7_2,
- 13,
- 13
- };
-
- static static_codebook _44u1__p7_2 = {
- 2, 169,
- _vq_lengthlist__44u1__p7_2,
- 1, -531103744, 1611661312, 4, 0,
- _vq_quantlist__44u1__p7_2,
- NULL,
- &_vq_auxt__44u1__p7_2,
- NULL,
- 0
- };
-
- static long _huff_lengthlist__44u1__short[] = {
- 12,13,14,13,17,12,15,17, 5, 5, 6,10,10,11,15,16,
- 4, 3, 3, 7, 5, 7,10,16, 7, 7, 7,10, 9,11,12,16,
- 6, 5, 5, 9, 5, 6,10,16, 8, 7, 7, 9, 6, 7, 9,16,
- 11, 7, 3, 6, 4, 5, 8,16,12, 9, 4, 8, 5, 7, 9,16,
- };
-
- static static_codebook _huff_book__44u1__short = {
- 2, 64,
- _huff_lengthlist__44u1__short,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist__44u2__long[] = {
- 5, 9,14,12,15,13,10,13, 7, 4, 5, 6, 8, 7, 8,12,
- 13, 4, 3, 5, 5, 6, 9,15,12, 6, 5, 6, 6, 6, 7,14,
- 14, 7, 4, 6, 4, 6, 8,15,12, 6, 6, 5, 5, 5, 6,14,
- 9, 7, 8, 6, 7, 5, 4,10,10,13,14,14,15,10, 6, 8,
- };
-
- static static_codebook _huff_book__44u2__long = {
- 2, 64,
- _huff_lengthlist__44u2__long,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u2__p1_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__44u2__p1_0[] = {
- 1, 4, 4, 5, 8, 7, 5, 7, 8, 5, 8, 8, 8,11,11, 8,
- 10,11, 5, 8, 8, 8,11,10, 8,11,11, 4, 8, 8, 8,11,
- 11, 8,11,11, 8,11,11,11,13,14,11,13,13, 7,11,11,
- 10,13,12,11,14,14, 4, 8, 8, 8,11,11, 8,11,11, 8,
- 11,11,11,14,13,10,12,13, 8,11,11,11,13,13,11,13,
- 13,
- };
-
- static float _vq_quantthresh__44u2__p1_0[] = {
- -0.5, 0.5,
- };
-
- static long _vq_quantmap__44u2__p1_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u2__p1_0 = {
- _vq_quantthresh__44u2__p1_0,
- _vq_quantmap__44u2__p1_0,
- 3,
- 3
- };
-
- static static_codebook _44u2__p1_0 = {
- 4, 81,
- _vq_lengthlist__44u2__p1_0,
- 1, -535822336, 1611661312, 2, 0,
- _vq_quantlist__44u2__p1_0,
- NULL,
- &_vq_auxt__44u2__p1_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u2__p2_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__44u2__p2_0[] = {
- 2, 5, 5, 5, 6, 6, 5, 6, 6, 5, 6, 6, 7, 8, 8, 6,
- 8, 8, 5, 6, 6, 6, 8, 7, 7, 8, 8, 5, 6, 6, 7, 8,
- 8, 6, 8, 8, 6, 8, 8, 8, 9,10, 8,10,10, 6, 8, 8,
- 7,10, 8, 8,10,10, 5, 6, 6, 6, 8, 8, 7, 8, 8, 6,
- 8, 8, 8,10,10, 8, 8,10, 6, 8, 8, 8,10,10, 8,10,
- 9,
- };
-
- static float _vq_quantthresh__44u2__p2_0[] = {
- -0.5, 0.5,
- };
-
- static long _vq_quantmap__44u2__p2_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u2__p2_0 = {
- _vq_quantthresh__44u2__p2_0,
- _vq_quantmap__44u2__p2_0,
- 3,
- 3
- };
-
- static static_codebook _44u2__p2_0 = {
- 4, 81,
- _vq_lengthlist__44u2__p2_0,
- 1, -535822336, 1611661312, 2, 0,
- _vq_quantlist__44u2__p2_0,
- NULL,
- &_vq_auxt__44u2__p2_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u2__p3_0[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__44u2__p3_0[] = {
- 2, 4, 4, 7, 8, 5, 7, 7, 9, 9, 5, 7, 7, 9, 9, 8,
- 9, 9,12,11, 8, 9, 9,11,12, 5, 7, 7,10,10, 7, 9,
- 9,11,11, 7, 9, 9,10,11,10,11,11,13,13, 9,10,11,
- 12,13, 5, 7, 7,10,10, 7, 9, 9,11,10, 7, 9, 9,11,
- 11, 9,11,10,13,13,10,11,11,13,13, 8,10,10,14,13,
- 10,11,11,15,14, 9,11,11,15,14,13,14,13,16,14,12,
- 13,13,15,16, 8,10,10,13,14, 9,11,11,14,15,10,11,
- 11,14,15,12,13,13,15,15,12,13,14,15,16, 5, 7, 7,
- 10,10, 7, 9, 9,11,11, 7, 9, 9,11,12,10,11,11,14,
- 13,10,11,11,14,14, 7, 9, 9,12,12, 9,11,11,13,13,
- 9,11,11,13,13,12,13,12,14,14,11,12,13,15,15, 7,
- 9, 9,12,12, 8,11,10,13,12, 9,11,11,13,13,11,13,
- 12,15,13,11,13,13,15,16, 9,12,11,15,15,11,12,12,
- 16,15,11,12,13,16,16,13,14,15,16,15,13,15,15,17,
- 17, 9,11,11,14,15,10,12,12,15,15,11,13,12,15,16,
- 13,15,14,16,16,13,15,15,17,19, 5, 7, 7,10,10, 7,
- 9, 9,12,11, 7, 9, 9,11,11,10,11,11,14,14,10,11,
- 11,13,14, 7, 9, 9,12,12, 9,11,11,13,13, 9,10,11,
- 12,13,11,13,12,16,15,11,12,12,14,15, 7, 9, 9,12,
- 12, 9,11,11,13,13, 9,11,11,13,12,11,13,12,15,16,
- 12,13,13,15,14, 9,11,11,15,14,11,13,12,16,15,10,
- 11,12,15,15,13,14,14,18,17,13,14,14,15,17,10,11,
- 11,14,15,11,13,12,15,17,11,13,12,15,16,13,15,14,
- 18,17,14,15,15,16,18, 7,10,10,14,14,10,12,12,15,
- 15,10,12,12,15,15,14,15,15,18,17,13,15,15,16,16,
- 9,11,11,16,15,11,13,13,16,18,11,13,13,16,16,15,
- 16,16, 0, 0,14,15,16,18,17, 9,11,11,15,15,10,13,
- 12,17,16,11,12,13,16,17,14,15,16,19,19,14,15,15,
- 0,20,12,14,14, 0, 0,13,14,16,19,18,13,15,16,20,
- 17,16,18, 0, 0, 0,15,16,17,18,19,11,14,14, 0,19,
- 12,15,14,17,17,13,15,15, 0, 0,16,17,15,20,19,15,
- 17,16,19, 0, 8,10,10,14,15,10,12,11,15,15,10,11,
- 12,16,15,13,14,14,19,17,14,15,15, 0, 0, 9,11,11,
- 16,15,11,13,13,17,16,10,12,13,16,17,14,15,15,18,
- 18,14,15,16,20,19, 9,12,12, 0,15,11,13,13,16,17,
- 11,13,13,19,17,14,16,16,18,17,15,16,16,17,19,11,
- 14,14,18,18,13,14,15, 0, 0,12,14,15,19,18,15,16,
- 19, 0,19,15,16,19,19,17,12,14,14,16,19,13,15,15,
- 0,17,13,15,14,18,18,15,16,15, 0,18,16,17,17, 0,
- 0,
- };
-
- static float _vq_quantthresh__44u2__p3_0[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__44u2__p3_0[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u2__p3_0 = {
- _vq_quantthresh__44u2__p3_0,
- _vq_quantmap__44u2__p3_0,
- 5,
- 5
- };
-
- static static_codebook _44u2__p3_0 = {
- 4, 625,
- _vq_lengthlist__44u2__p3_0,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__44u2__p3_0,
- NULL,
- &_vq_auxt__44u2__p3_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u2__p4_0[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__44u2__p4_0[] = {
- 4, 5, 5, 8, 8, 5, 7, 6, 9, 9, 5, 6, 7, 9, 9, 9,
- 9, 9,11,11, 9, 9, 9,11,11, 5, 7, 7, 9, 9, 7, 8,
- 8,10,10, 7, 7, 8,10,10,10,10,10,11,12, 9,10,10,
- 11,12, 5, 7, 7, 9, 9, 6, 8, 7,10,10, 7, 8, 8,10,
- 10, 9,10,10,12,11, 9,10,10,12,11, 9,10,10,12,12,
- 10,10,10,13,12, 9,10,10,12,13,12,12,12,14,14,11,
- 12,12,13,14, 9,10,10,12,12, 9,10,10,12,13,10,10,
- 10,12,13,11,12,12,14,13,12,12,12,14,13, 5, 7, 7,
- 10, 9, 7, 8, 8,10,10, 7, 8, 8,10,10,10,10,10,12,
- 12,10,10,10,12,12, 7, 8, 8,11,10, 8, 8, 9,11,11,
- 8, 9, 9,11,11,10,11,11,12,13,10,11,11,13,13, 6,
- 8, 8,10,10, 7, 9, 8,11,10, 8, 9, 9,11,11,10,11,
- 10,13,11,10,11,11,13,13, 9,10,10,13,13,10,11,11,
- 13,13,10,11,11,14,13,12,11,13,12,15,12,13,13,15,
- 15, 9,10,10,12,13,10,11,10,13,13,10,11,11,13,13,
- 12,13,11,15,13,12,13,13,15,15, 5, 7, 7, 9,10, 7,
- 8, 8,10,10, 7, 8, 8,10,10,10,10,10,12,12,10,10,
- 11,12,12, 6, 8, 8,10,10, 8, 9, 9,11,11, 7, 8, 9,
- 10,11,10,11,11,13,13,10,10,11,11,13, 7, 8, 8,10,
- 11, 8, 9, 9,11,11, 8, 9, 8,11,11,10,11,11,13,13,
- 10,11,11,13,12, 9,10,10,13,12,10,11,11,14,13,10,
- 10,11,13,13,12,13,13,15,15,12,11,13,12,14, 9,10,
- 10,12,13,10,11,11,13,14,10,11,11,13,13,12,13,13,
- 15,15,12,13,12,15,12, 8, 9, 9,12,12, 9,11,10,13,
- 13, 9,10,10,13,13,12,13,13,15,15,12,12,12,14,14,
- 9,10,10,13,13,10,11,11,13,14,10,11,11,14,12,13,
- 13,14,14,16,12,13,13,15,14, 9,10,10,13,13,10,11,
- 10,14,13,10,11,11,13,14,12,14,13,16,14,13,13,13,
- 14,15,11,13,12,15,14,11,12,13,14,15,12,13,13,16,
- 15,14,12,15,12,16,14,15,15,17,16,11,12,12,14,15,
- 11,13,11,15,14,12,13,13,15,16,13,15,12,17,13,14,
- 15,15,16,16, 8, 9, 9,12,12, 9,10,10,13,13, 9,10,
- 10,13,13,12,13,12,14,14,12,13,13,15,15, 9,10,10,
- 13,13,10,11,11,14,13,10,10,11,13,14,12,13,13,15,
- 14,12,12,14,14,16, 9,10,10,13,13,10,11,11,13,14,
- 10,11,11,14,13,13,13,13,15,15,13,14,13,16,14,11,
- 12,12,14,14,12,13,13,16,15,11,12,13,14,15,14,15,
- 15,16,16,14,13,15,13,17,11,12,12,14,15,12,13,13,
- 15,16,11,13,12,15,15,14,15,14,16,16,14,15,12,17,
- 13,
- };
-
- static float _vq_quantthresh__44u2__p4_0[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__44u2__p4_0[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u2__p4_0 = {
- _vq_quantthresh__44u2__p4_0,
- _vq_quantmap__44u2__p4_0,
- 5,
- 5
- };
-
- static static_codebook _44u2__p4_0 = {
- 4, 625,
- _vq_lengthlist__44u2__p4_0,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__44u2__p4_0,
- NULL,
- &_vq_auxt__44u2__p4_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u2__p5_0[] = {
- 4,
- 3,
- 5,
- 2,
- 6,
- 1,
- 7,
- 0,
- 8,
- };
-
- static long _vq_lengthlist__44u2__p5_0[] = {
- 1, 4, 4, 7, 7, 8, 8, 9, 9, 4, 6, 5, 8, 8, 8, 8,
- 10,10, 4, 5, 6, 8, 8, 8, 8,10,10, 7, 8, 8, 9, 9,
- 9, 9,11,11, 7, 8, 8, 9, 9, 9, 9,11,11, 8, 8, 8,
- 9, 9,10,11,12,12, 8, 8, 8, 9, 9,10,10,12,12,10,
- 10,10,11,11,12,12,13,13,10,10,10,11,11,12,12,13,
- 13,
- };
-
- static float _vq_quantthresh__44u2__p5_0[] = {
- -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5,
- };
-
- static long _vq_quantmap__44u2__p5_0[] = {
- 7, 5, 3, 1, 0, 2, 4, 6,
- 8,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u2__p5_0 = {
- _vq_quantthresh__44u2__p5_0,
- _vq_quantmap__44u2__p5_0,
- 9,
- 9
- };
-
- static static_codebook _44u2__p5_0 = {
- 2, 81,
- _vq_lengthlist__44u2__p5_0,
- 1, -531628032, 1611661312, 4, 0,
- _vq_quantlist__44u2__p5_0,
- NULL,
- &_vq_auxt__44u2__p5_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u2__p6_0[] = {
- 6,
- 5,
- 7,
- 4,
- 8,
- 3,
- 9,
- 2,
- 10,
- 1,
- 11,
- 0,
- 12,
- };
-
- static long _vq_lengthlist__44u2__p6_0[] = {
- 1, 4, 4, 6, 6, 8, 8,10,10,11,11,14,13, 4, 6, 5,
- 8, 8, 9, 9,11,10,12,11,15,14, 4, 5, 6, 8, 8, 9,
- 9,11,11,11,11,14,14, 6, 8, 8,10, 9,11,11,11,11,
- 12,12,15,15, 6, 8, 8, 9, 9,11,11,11,12,12,12,15,
- 15, 8,10,10,11,11,11,11,12,12,13,13,15,16, 8,10,
- 10,11,11,11,11,12,12,13,13,16,16,10,11,11,12,12,
- 12,12,13,13,13,13,17,16,10,11,11,12,12,12,12,13,
- 13,13,14,16,17,11,12,12,13,13,13,13,14,14,15,14,
- 18,17,11,12,12,13,13,13,13,14,14,14,15,19,18,14,
- 15,15,15,15,16,16,18,19,18,18, 0, 0,14,15,15,16,
- 15,17,17,16,18,17,18, 0, 0,
- };
-
- static float _vq_quantthresh__44u2__p6_0[] = {
- -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5,
- 12.5, 17.5, 22.5, 27.5,
- };
-
- static long _vq_quantmap__44u2__p6_0[] = {
- 11, 9, 7, 5, 3, 1, 0, 2,
- 4, 6, 8, 10, 12,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u2__p6_0 = {
- _vq_quantthresh__44u2__p6_0,
- _vq_quantmap__44u2__p6_0,
- 13,
- 13
- };
-
- static static_codebook _44u2__p6_0 = {
- 2, 169,
- _vq_lengthlist__44u2__p6_0,
- 1, -526516224, 1616117760, 4, 0,
- _vq_quantlist__44u2__p6_0,
- NULL,
- &_vq_auxt__44u2__p6_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u2__p6_1[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__44u2__p6_1[] = {
- 2, 4, 4, 5, 5, 4, 5, 5, 6, 5, 4, 5, 5, 5, 6, 5,
- 6, 5, 6, 6, 5, 5, 6, 6, 6,
- };
-
- static float _vq_quantthresh__44u2__p6_1[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__44u2__p6_1[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u2__p6_1 = {
- _vq_quantthresh__44u2__p6_1,
- _vq_quantmap__44u2__p6_1,
- 5,
- 5
- };
-
- static static_codebook _44u2__p6_1 = {
- 2, 25,
- _vq_lengthlist__44u2__p6_1,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__44u2__p6_1,
- NULL,
- &_vq_auxt__44u2__p6_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u2__p7_0[] = {
- 4,
- 3,
- 5,
- 2,
- 6,
- 1,
- 7,
- 0,
- 8,
- };
-
- static long _vq_lengthlist__44u2__p7_0[] = {
- 1, 3, 2,12,12,12,12,12,12, 4,12,12,12,12,12,12,
- 12,12, 5,12,12,12,12,12,12,12,12,12,12,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,
- };
-
- static float _vq_quantthresh__44u2__p7_0[] = {
- -591.5, -422.5, -253.5, -84.5, 84.5, 253.5, 422.5, 591.5,
- };
-
- static long _vq_quantmap__44u2__p7_0[] = {
- 7, 5, 3, 1, 0, 2, 4, 6,
- 8,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u2__p7_0 = {
- _vq_quantthresh__44u2__p7_0,
- _vq_quantmap__44u2__p7_0,
- 9,
- 9
- };
-
- static static_codebook _44u2__p7_0 = {
- 2, 81,
- _vq_lengthlist__44u2__p7_0,
- 1, -516612096, 1626677248, 4, 0,
- _vq_quantlist__44u2__p7_0,
- NULL,
- &_vq_auxt__44u2__p7_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u2__p7_1[] = {
- 6,
- 5,
- 7,
- 4,
- 8,
- 3,
- 9,
- 2,
- 10,
- 1,
- 11,
- 0,
- 12,
- };
-
- static long _vq_lengthlist__44u2__p7_1[] = {
- 1, 4, 4, 7, 6, 7, 6, 8, 7, 9, 7, 9, 8, 4, 7, 6,
- 8, 8, 9, 8,10, 9,10,10,11,11, 4, 7, 7, 8, 8, 8,
- 8, 9,10,11,11,11,11, 6, 8, 8,10,10,10,10,11,11,
- 12,12,12,12, 7, 8, 8,10,10,10,10,11,11,12,12,13,
- 13, 7, 9, 9,11,10,12,12,13,13,14,13,14,14, 7, 9,
- 9,10,11,11,12,13,13,13,13,16,14, 9,10,10,12,12,
- 13,13,14,14,15,16,15,16, 9,10,10,12,12,12,13,14,
- 14,14,15,16,15,10,12,12,13,13,15,13,16,16,15,17,
- 17,17,10,11,11,12,14,14,14,15,15,17,17,15,17,11,
- 12,12,14,14,14,15,15,15,17,16,17,17,10,12,12,13,
- 14,14,14,17,15,17,17,17,17,
- };
-
- static float _vq_quantthresh__44u2__p7_1[] = {
- -71.5, -58.5, -45.5, -32.5, -19.5, -6.5, 6.5, 19.5,
- 32.5, 45.5, 58.5, 71.5,
- };
-
- static long _vq_quantmap__44u2__p7_1[] = {
- 11, 9, 7, 5, 3, 1, 0, 2,
- 4, 6, 8, 10, 12,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u2__p7_1 = {
- _vq_quantthresh__44u2__p7_1,
- _vq_quantmap__44u2__p7_1,
- 13,
- 13
- };
-
- static static_codebook _44u2__p7_1 = {
- 2, 169,
- _vq_lengthlist__44u2__p7_1,
- 1, -523010048, 1618608128, 4, 0,
- _vq_quantlist__44u2__p7_1,
- NULL,
- &_vq_auxt__44u2__p7_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u2__p7_2[] = {
- 6,
- 5,
- 7,
- 4,
- 8,
- 3,
- 9,
- 2,
- 10,
- 1,
- 11,
- 0,
- 12,
- };
-
- static long _vq_lengthlist__44u2__p7_2[] = {
- 2, 5, 5, 6, 6, 7, 7, 8, 7, 8, 8, 8, 8, 5, 6, 6,
- 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 5, 6, 6, 7, 7, 8,
- 7, 8, 8, 8, 8, 8, 8, 6, 7, 7, 7, 8, 8, 8, 8, 8,
- 9, 9, 9, 9, 6, 7, 7, 8, 7, 8, 8, 9, 9, 9, 9, 9,
- 9, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 7, 8,
- 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9,
- };
-
- static float _vq_quantthresh__44u2__p7_2[] = {
- -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5,
- 2.5, 3.5, 4.5, 5.5,
- };
-
- static long _vq_quantmap__44u2__p7_2[] = {
- 11, 9, 7, 5, 3, 1, 0, 2,
- 4, 6, 8, 10, 12,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u2__p7_2 = {
- _vq_quantthresh__44u2__p7_2,
- _vq_quantmap__44u2__p7_2,
- 13,
- 13
- };
-
- static static_codebook _44u2__p7_2 = {
- 2, 169,
- _vq_lengthlist__44u2__p7_2,
- 1, -531103744, 1611661312, 4, 0,
- _vq_quantlist__44u2__p7_2,
- NULL,
- &_vq_auxt__44u2__p7_2,
- NULL,
- 0
- };
-
- static long _huff_lengthlist__44u2__short[] = {
- 13,15,17,17,15,15,12,17,11, 9, 7,10,10, 9,12,17,
- 10, 6, 3, 6, 5, 7,10,17,15,10, 6, 9, 8, 9,11,17,
- 15, 8, 4, 7, 3, 5, 9,16,16,10, 5, 8, 4, 5, 8,16,
- 13,11, 5, 8, 3, 3, 5,14,13,12, 7,10, 5, 5, 7,14,
- };
-
- static static_codebook _huff_book__44u2__short = {
- 2, 64,
- _huff_lengthlist__44u2__short,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist__44u3__long[] = {
- 6, 9,13,12,14,11,10,13, 8, 4, 5, 7, 8, 7, 8,12,
- 11, 4, 3, 5, 5, 7, 9,14,11, 6, 5, 6, 6, 6, 7,13,
- 13, 7, 5, 6, 4, 5, 7,14,11, 7, 6, 6, 5, 5, 6,13,
- 9, 7, 8, 6, 7, 5, 3, 9, 9,12,13,12,14,10, 6, 7,
- };
-
- static static_codebook _huff_book__44u3__long = {
- 2, 64,
- _huff_lengthlist__44u3__long,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u3__p1_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__44u3__p1_0[] = {
- 1, 4, 4, 5, 8, 7, 5, 7, 8, 5, 8, 8, 8,10,11, 8,
- 10,11, 5, 8, 8, 8,11,10, 8,11,11, 4, 8, 8, 8,11,
- 11, 8,11,11, 8,11,11,11,13,14,11,14,14, 8,11,11,
- 10,14,12,11,14,14, 4, 8, 8, 8,11,11, 8,11,11, 7,
- 11,11,11,14,14,10,12,14, 8,11,11,11,14,14,11,14,
- 13,
- };
-
- static float _vq_quantthresh__44u3__p1_0[] = {
- -0.5, 0.5,
- };
-
- static long _vq_quantmap__44u3__p1_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u3__p1_0 = {
- _vq_quantthresh__44u3__p1_0,
- _vq_quantmap__44u3__p1_0,
- 3,
- 3
- };
-
- static static_codebook _44u3__p1_0 = {
- 4, 81,
- _vq_lengthlist__44u3__p1_0,
- 1, -535822336, 1611661312, 2, 0,
- _vq_quantlist__44u3__p1_0,
- NULL,
- &_vq_auxt__44u3__p1_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u3__p2_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__44u3__p2_0[] = {
- 2, 5, 4, 5, 6, 6, 5, 6, 6, 5, 6, 6, 7, 8, 8, 6,
- 8, 8, 5, 6, 6, 6, 8, 8, 7, 8, 8, 5, 7, 6, 7, 8,
- 8, 6, 8, 8, 7, 8, 8, 8, 9,10, 8,10,10, 6, 8, 8,
- 8,10, 8, 8,10,10, 5, 6, 6, 6, 8, 8, 7, 8, 8, 6,
- 8, 8, 8,10,10, 8, 8,10, 7, 8, 8, 8,10,10, 8,10,
- 9,
- };
-
- static float _vq_quantthresh__44u3__p2_0[] = {
- -0.5, 0.5,
- };
-
- static long _vq_quantmap__44u3__p2_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u3__p2_0 = {
- _vq_quantthresh__44u3__p2_0,
- _vq_quantmap__44u3__p2_0,
- 3,
- 3
- };
-
- static static_codebook _44u3__p2_0 = {
- 4, 81,
- _vq_lengthlist__44u3__p2_0,
- 1, -535822336, 1611661312, 2, 0,
- _vq_quantlist__44u3__p2_0,
- NULL,
- &_vq_auxt__44u3__p2_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u3__p3_0[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__44u3__p3_0[] = {
- 2, 4, 4, 7, 7, 5, 7, 7, 9, 9, 5, 7, 7, 9, 9, 8,
- 9, 9,12,12, 8, 9, 9,11,12, 5, 7, 7,10,10, 7, 9,
- 9,11,11, 7, 9, 9,10,11,10,11,11,13,13, 9,10,11,
- 13,13, 5, 7, 7,10,10, 7, 9, 9,11,10, 7, 9, 9,11,
- 11, 9,11,10,13,13,10,11,11,14,13, 8,10,10,14,13,
- 10,11,11,15,14, 9,11,11,14,14,13,14,13,16,16,12,
- 13,13,15,15, 8,10,10,13,14, 9,11,11,14,14,10,11,
- 11,14,15,12,13,13,15,15,13,14,14,15,16, 5, 7, 7,
- 10,10, 7, 9, 9,11,11, 7, 9, 9,11,12,10,11,11,14,
- 14,10,11,11,14,14, 7, 9, 9,12,12, 9,11,11,13,13,
- 9,11,11,13,13,12,12,13,15,15,11,12,13,15,16, 7,
- 9, 9,11,11, 8,11,10,13,12, 9,11,11,13,13,11,13,
- 12,15,13,11,13,13,15,16, 9,12,11,15,14,11,12,13,
- 16,15,11,13,13,15,16,14,14,15,17,16,13,15,16, 0,
- 17, 9,11,11,15,15,10,13,12,15,15,11,13,13,15,16,
- 13,15,13,16,15,14,16,15, 0,19, 5, 7, 7,10,10, 7,
- 9, 9,11,11, 7, 9, 9,11,11,10,12,11,14,14,10,11,
- 12,14,14, 7, 9, 9,12,12, 9,11,11,14,13, 9,10,11,
- 12,13,11,13,13,16,16,11,12,13,13,16, 7, 9, 9,12,
- 12, 9,11,11,13,13, 9,11,11,13,13,11,13,13,15,15,
- 12,13,12,15,14, 9,11,11,15,14,11,13,12,16,16,10,
- 12,12,15,15,13,15,15,17,19,13,14,15,16,17,10,12,
- 12,15,15,11,13,13,16,16,11,13,13,15,16,13,15,15,
- 0, 0,14,15,15,16,16, 8,10,10,14,14,10,12,12,15,
- 15,10,12,11,15,16,14,15,15,19,20,13,14,14,18,16,
- 9,11,11,15,15,11,13,13,17,16,11,13,13,16,16,15,
- 17,17,20,20,14,15,16,17,20, 9,11,11,15,15,10,13,
- 12,16,15,11,13,13,15,17,14,16,15,18, 0,14,16,15,
- 18,20,12,14,14, 0, 0,14,14,16, 0, 0,13,16,15, 0,
- 0,17,17,18, 0, 0,16,17,19,19, 0,12,14,14,18, 0,
- 12,16,14, 0,17,13,15,15,18, 0,16,18,17, 0,17,16,
- 18,17, 0, 0, 7,10,10,14,14,10,12,11,15,15,10,12,
- 12,16,15,13,15,15,18, 0,14,15,15,17, 0, 9,11,11,
- 15,15,11,13,13,16,16,11,12,13,16,16,14,15,16,17,
- 17,14,16,16,16,18, 9,11,12,16,16,11,13,13,17,17,
- 11,14,13,20,17,15,16,16,19, 0,15,16,17, 0,19,11,
- 13,14,17,16,14,15,15,20,18,13,14,15,17,19,16,18,
- 18, 0,20,16,16,19,17, 0,12,15,14,17, 0,14,15,15,
- 18,19,13,16,15,19,20,15,18,18, 0,20,17, 0,16, 0,
- 0,
- };
-
- static float _vq_quantthresh__44u3__p3_0[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__44u3__p3_0[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u3__p3_0 = {
- _vq_quantthresh__44u3__p3_0,
- _vq_quantmap__44u3__p3_0,
- 5,
- 5
- };
-
- static static_codebook _44u3__p3_0 = {
- 4, 625,
- _vq_lengthlist__44u3__p3_0,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__44u3__p3_0,
- NULL,
- &_vq_auxt__44u3__p3_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u3__p4_0[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__44u3__p4_0[] = {
- 4, 5, 5, 8, 8, 5, 7, 6, 9, 9, 5, 6, 7, 9, 9, 9,
- 9, 9,11,11, 9, 9, 9,11,11, 5, 7, 7, 9, 9, 7, 8,
- 8,10,10, 7, 7, 8,10,10, 9,10,10,11,12, 9,10,10,
- 11,12, 5, 7, 7, 9, 9, 7, 8, 7,10,10, 7, 8, 8,10,
- 10, 9,10, 9,12,11, 9,10,10,12,11, 9,10, 9,12,12,
- 9,10,10,13,12, 9,10,10,12,13,12,12,12,14,14,11,
- 12,12,13,14, 9, 9,10,12,12, 9,10,10,12,12, 9,10,
- 10,12,13,11,12,11,14,13,12,12,12,14,13, 5, 7, 7,
- 9, 9, 7, 8, 8,10,10, 7, 8, 8,10,10,10,10,10,12,
- 12, 9,10,10,12,12, 7, 8, 8,11,10, 8, 8, 9,11,11,
- 8, 9, 9,11,11,11,11,11,12,13,10,11,11,13,13, 6,
- 8, 8,10,10, 7, 9, 8,11,10, 8, 9, 9,11,11,10,11,
- 10,13,11,10,11,11,13,13, 9,11,10,13,12,10,11,11,
- 13,13,10,11,11,13,13,12,12,13,12,15,12,13,13,15,
- 15, 9,10,10,12,13,10,11,10,13,12,10,11,11,13,14,
- 12,13,11,15,13,12,13,13,15,15, 5, 7, 7, 9, 9, 7,
- 8, 8,10,10, 7, 8, 8,10,10, 9,10,10,12,12,10,10,
- 11,12,12, 6, 8, 8,10,10, 8, 9, 9,11,11, 7, 8, 9,
- 10,11,10,11,11,13,13,10,10,11,11,13, 7, 8, 8,10,
- 10, 8, 9, 9,11,11, 8, 9, 9,11,11,10,11,11,13,13,
- 11,11,11,13,12, 9,10,10,13,12,10,11,11,14,13,10,
- 10,11,12,13,12,13,13,15,15,12,11,13,13,14, 9,10,
- 11,12,13,10,11,11,13,13,10,11,11,13,13,12,13,13,
- 15,15,12,13,12,15,12, 8, 9, 9,12,12, 9,11,10,13,
- 13, 9,10,10,13,13,12,13,13,15,14,12,12,12,14,13,
- 9,10,10,13,12,10,11,11,13,13,10,11,11,14,12,13,
- 13,14,14,16,12,13,13,15,15, 9,10,10,13,13,10,11,
- 10,14,13,10,11,11,13,14,12,14,13,15,14,13,13,13,
- 15,15,11,13,12,15,14,11,12,13,14,15,12,13,13,16,
- 14,14,12,15,12,16,14,15,15,17,15,11,12,12,14,14,
- 11,13,11,15,14,12,13,13,15,15,13,15,12,17,13,14,
- 15,15,16,16, 8, 9, 9,12,12, 9,10,10,12,13, 9,10,
- 10,13,13,12,12,12,14,14,12,13,13,15,15, 9,10,10,
- 13,12,10,11,11,14,13,10,10,11,13,14,12,13,13,15,
- 15,12,12,13,14,16, 9,10,10,13,13,10,11,11,13,14,
- 10,11,11,14,13,12,13,13,14,15,13,14,13,16,14,11,
- 12,12,14,14,12,13,13,15,14,11,12,13,14,15,14,15,
- 15,16,16,13,13,15,13,16,11,12,12,14,15,12,13,13,
- 14,15,11,13,12,15,14,14,15,15,16,16,14,15,12,16,
- 13,
- };
-
- static float _vq_quantthresh__44u3__p4_0[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__44u3__p4_0[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u3__p4_0 = {
- _vq_quantthresh__44u3__p4_0,
- _vq_quantmap__44u3__p4_0,
- 5,
- 5
- };
-
- static static_codebook _44u3__p4_0 = {
- 4, 625,
- _vq_lengthlist__44u3__p4_0,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__44u3__p4_0,
- NULL,
- &_vq_auxt__44u3__p4_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u3__p5_0[] = {
- 4,
- 3,
- 5,
- 2,
- 6,
- 1,
- 7,
- 0,
- 8,
- };
-
- static long _vq_lengthlist__44u3__p5_0[] = {
- 2, 3, 3, 6, 6, 7, 7, 9, 9, 4, 5, 5, 7, 7, 8, 8,
- 10,10, 4, 5, 5, 7, 7, 8, 8,10,10, 6, 7, 7, 8, 8,
- 9, 9,11,10, 6, 7, 7, 8, 8, 9, 9,10,10, 7, 8, 8,
- 9, 9,10,10,11,11, 7, 8, 8, 9, 9,10,10,11,11, 9,
- 10,10,11,10,11,11,12,12, 9,10,10,10,10,11,11,12,
- 12,
- };
-
- static float _vq_quantthresh__44u3__p5_0[] = {
- -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5,
- };
-
- static long _vq_quantmap__44u3__p5_0[] = {
- 7, 5, 3, 1, 0, 2, 4, 6,
- 8,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u3__p5_0 = {
- _vq_quantthresh__44u3__p5_0,
- _vq_quantmap__44u3__p5_0,
- 9,
- 9
- };
-
- static static_codebook _44u3__p5_0 = {
- 2, 81,
- _vq_lengthlist__44u3__p5_0,
- 1, -531628032, 1611661312, 4, 0,
- _vq_quantlist__44u3__p5_0,
- NULL,
- &_vq_auxt__44u3__p5_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u3__p6_0[] = {
- 6,
- 5,
- 7,
- 4,
- 8,
- 3,
- 9,
- 2,
- 10,
- 1,
- 11,
- 0,
- 12,
- };
-
- static long _vq_lengthlist__44u3__p6_0[] = {
- 1, 4, 4, 6, 6, 8, 8, 9, 9,10,11,13,14, 4, 6, 5,
- 8, 8, 9, 9,10,10,11,11,14,14, 4, 6, 6, 8, 8, 9,
- 9,10,10,11,11,14,14, 6, 8, 8, 9, 9,10,10,11,11,
- 12,12,15,15, 6, 8, 8, 9, 9,10,11,11,11,12,12,15,
- 15, 8, 9, 9,11,10,11,11,12,12,13,13,15,16, 8, 9,
- 9,10,11,11,11,12,12,13,13,16,16,10,10,11,11,11,
- 12,12,13,13,13,14,17,16, 9,10,11,12,11,12,12,13,
- 13,13,13,16,18,11,12,11,12,12,13,13,13,14,15,14,
- 17,17,11,11,12,12,12,13,13,13,14,14,15,18,17,14,
- 15,15,15,15,16,16,17,17,19,18, 0,20,14,15,14,15,
- 15,16,16,16,17,18,16,20,18,
- };
-
- static float _vq_quantthresh__44u3__p6_0[] = {
- -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5,
- 12.5, 17.5, 22.5, 27.5,
- };
-
- static long _vq_quantmap__44u3__p6_0[] = {
- 11, 9, 7, 5, 3, 1, 0, 2,
- 4, 6, 8, 10, 12,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u3__p6_0 = {
- _vq_quantthresh__44u3__p6_0,
- _vq_quantmap__44u3__p6_0,
- 13,
- 13
- };
-
- static static_codebook _44u3__p6_0 = {
- 2, 169,
- _vq_lengthlist__44u3__p6_0,
- 1, -526516224, 1616117760, 4, 0,
- _vq_quantlist__44u3__p6_0,
- NULL,
- &_vq_auxt__44u3__p6_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u3__p6_1[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__44u3__p6_1[] = {
- 2, 4, 4, 5, 5, 4, 5, 5, 6, 5, 4, 5, 5, 5, 6, 5,
- 6, 5, 6, 6, 5, 5, 6, 6, 6,
- };
-
- static float _vq_quantthresh__44u3__p6_1[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__44u3__p6_1[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u3__p6_1 = {
- _vq_quantthresh__44u3__p6_1,
- _vq_quantmap__44u3__p6_1,
- 5,
- 5
- };
-
- static static_codebook _44u3__p6_1 = {
- 2, 25,
- _vq_lengthlist__44u3__p6_1,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__44u3__p6_1,
- NULL,
- &_vq_auxt__44u3__p6_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u3__p7_0[] = {
- 4,
- 3,
- 5,
- 2,
- 6,
- 1,
- 7,
- 0,
- 8,
- };
-
- static long _vq_lengthlist__44u3__p7_0[] = {
- 1, 3, 3,10,10,10,10,10,10, 4,10,10,10,10,10,10,
- 10,10, 4,10,10,10,10,10,10,10,10,10,10, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9,
- };
-
- static float _vq_quantthresh__44u3__p7_0[] = {
- -892.5, -637.5, -382.5, -127.5, 127.5, 382.5, 637.5, 892.5,
- };
-
- static long _vq_quantmap__44u3__p7_0[] = {
- 7, 5, 3, 1, 0, 2, 4, 6,
- 8,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u3__p7_0 = {
- _vq_quantthresh__44u3__p7_0,
- _vq_quantmap__44u3__p7_0,
- 9,
- 9
- };
-
- static static_codebook _44u3__p7_0 = {
- 2, 81,
- _vq_lengthlist__44u3__p7_0,
- 1, -515907584, 1627381760, 4, 0,
- _vq_quantlist__44u3__p7_0,
- NULL,
- &_vq_auxt__44u3__p7_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u3__p7_1[] = {
- 7,
- 6,
- 8,
- 5,
- 9,
- 4,
- 10,
- 3,
- 11,
- 2,
- 12,
- 1,
- 13,
- 0,
- 14,
- };
-
- static long _vq_lengthlist__44u3__p7_1[] = {
- 1, 4, 4, 6, 6, 7, 6, 8, 7, 9, 8,10, 9,11,11, 4,
- 7, 7, 8, 7, 9, 9,10,10,11,11,11,11,12,12, 4, 7,
- 7, 7, 7, 9, 9,10,10,11,11,12,12,12,11, 6, 8, 8,
- 9, 9,10,10,11,11,12,12,13,12,13,13, 6, 8, 8, 9,
- 9,10,11,11,11,12,12,13,14,13,13, 8, 9, 9,11,11,
- 12,12,12,13,14,13,14,14,14,15, 8, 9, 9,11,11,11,
- 12,13,14,13,14,15,17,14,15, 9,10,10,12,12,13,13,
- 13,14,15,15,15,16,16,16, 9,11,11,12,12,13,13,14,
- 14,14,15,16,16,16,16,10,12,12,13,13,14,14,15,15,
- 15,16,17,17,17,17,10,12,11,13,13,15,14,15,14,16,
- 17,16,16,16,16,11,13,12,14,14,14,14,15,16,17,16,
- 17,17,17,17,11,13,12,14,14,14,15,17,16,17,17,17,
- 17,17,17,12,13,13,15,16,15,16,17,17,16,16,17,17,
- 17,17,12,13,13,15,15,15,16,17,17,17,16,17,16,17,
- 17,
- };
-
- static float _vq_quantthresh__44u3__p7_1[] = {
- -110.5, -93.5, -76.5, -59.5, -42.5, -25.5, -8.5, 8.5,
- 25.5, 42.5, 59.5, 76.5, 93.5, 110.5,
- };
-
- static long _vq_quantmap__44u3__p7_1[] = {
- 13, 11, 9, 7, 5, 3, 1, 0,
- 2, 4, 6, 8, 10, 12, 14,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u3__p7_1 = {
- _vq_quantthresh__44u3__p7_1,
- _vq_quantmap__44u3__p7_1,
- 15,
- 15
- };
-
- static static_codebook _44u3__p7_1 = {
- 2, 225,
- _vq_lengthlist__44u3__p7_1,
- 1, -522338304, 1620115456, 4, 0,
- _vq_quantlist__44u3__p7_1,
- NULL,
- &_vq_auxt__44u3__p7_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u3__p7_2[] = {
- 8,
- 7,
- 9,
- 6,
- 10,
- 5,
- 11,
- 4,
- 12,
- 3,
- 13,
- 2,
- 14,
- 1,
- 15,
- 0,
- 16,
- };
-
- static long _vq_lengthlist__44u3__p7_2[] = {
- 2, 5, 5, 7, 6, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9,
- 9, 5, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9,
- 10,10, 5, 6, 6, 7, 7, 8, 8, 8, 8, 9, 8, 9, 9, 9,
- 9,10, 9, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9,
- 10,10,10,10, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9,10,
- 9,10,10,10,10, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9,
- 10,10,10,10,10,10, 7, 8, 8, 9, 8, 9, 9, 9, 9,10,
- 9,10,10,10,10,10,10, 8, 8, 8, 9, 9, 9, 9, 9, 9,
- 9,10,10,10,10,10,10,10, 8, 9, 8, 9, 9, 9, 9,10,
- 9,10,10,10,10,10,10,10,10, 9, 9, 9, 9, 9, 9,10,
- 9,10,10,10,10,10,10,10,10,10, 9, 9, 9, 9, 9,10,
- 9,10,10,10,10,10,10,10,10,10,10, 9, 9, 9,10, 9,
- 10,10,10,10,10,10,10,10,10,10,10,10, 9, 9, 9,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10, 9, 9, 9,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,11, 9,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,11, 9,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 9,10,10,10,10,10,10,10,10,10,10,10,11,11,11,10,
- 11,
- };
-
- static float _vq_quantthresh__44u3__p7_2[] = {
- -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5,
- 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5,
- };
-
- static long _vq_quantmap__44u3__p7_2[] = {
- 15, 13, 11, 9, 7, 5, 3, 1,
- 0, 2, 4, 6, 8, 10, 12, 14,
- 16,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u3__p7_2 = {
- _vq_quantthresh__44u3__p7_2,
- _vq_quantmap__44u3__p7_2,
- 17,
- 17
- };
-
- static static_codebook _44u3__p7_2 = {
- 2, 289,
- _vq_lengthlist__44u3__p7_2,
- 1, -529530880, 1611661312, 5, 0,
- _vq_quantlist__44u3__p7_2,
- NULL,
- &_vq_auxt__44u3__p7_2,
- NULL,
- 0
- };
-
- static long _huff_lengthlist__44u3__short[] = {
- 14,14,14,15,13,15,12,16,10, 8, 7, 9, 9, 8,12,16,
- 10, 5, 4, 6, 5, 6, 9,16,14, 8, 6, 8, 7, 8,10,16,
- 14, 7, 4, 6, 3, 5, 8,16,15, 9, 5, 7, 4, 4, 7,16,
- 13,10, 6, 7, 4, 3, 4,13,13,12, 7, 9, 5, 5, 6,12,
- };
-
- static static_codebook _huff_book__44u3__short = {
- 2, 64,
- _huff_lengthlist__44u3__short,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist__44u4__long[] = {
- 3, 8,12,12,13,12,11,13, 5, 4, 6, 7, 8, 8, 9,13,
- 9, 5, 4, 5, 5, 7, 9,13, 9, 6, 5, 6, 6, 7, 8,12,
- 12, 7, 5, 6, 4, 5, 8,13,11, 7, 6, 6, 5, 5, 6,12,
- 10, 8, 8, 7, 7, 5, 3, 8,10,12,13,12,12, 9, 6, 7,
- };
-
- static static_codebook _huff_book__44u4__long = {
- 2, 64,
- _huff_lengthlist__44u4__long,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u4__p1_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__44u4__p1_0[] = {
- 1, 4, 4, 5, 8, 7, 5, 7, 8, 5, 8, 8, 8,10,11, 8,
- 10,11, 5, 8, 8, 8,11,10, 8,11,11, 4, 8, 8, 8,11,
- 11, 8,11,11, 8,11,11,11,13,14,11,15,14, 8,11,11,
- 10,13,12,11,14,14, 4, 8, 8, 8,11,11, 8,11,11, 7,
- 11,11,11,15,14,10,12,14, 8,11,11,11,14,14,11,14,
- 13,
- };
-
- static float _vq_quantthresh__44u4__p1_0[] = {
- -0.5, 0.5,
- };
-
- static long _vq_quantmap__44u4__p1_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u4__p1_0 = {
- _vq_quantthresh__44u4__p1_0,
- _vq_quantmap__44u4__p1_0,
- 3,
- 3
- };
-
- static static_codebook _44u4__p1_0 = {
- 4, 81,
- _vq_lengthlist__44u4__p1_0,
- 1, -535822336, 1611661312, 2, 0,
- _vq_quantlist__44u4__p1_0,
- NULL,
- &_vq_auxt__44u4__p1_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u4__p2_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__44u4__p2_0[] = {
- 2, 5, 5, 5, 6, 6, 5, 6, 6, 5, 6, 6, 7, 8, 8, 6,
- 8, 8, 5, 6, 6, 6, 8, 8, 7, 8, 8, 5, 7, 6, 6, 8,
- 8, 6, 8, 8, 6, 8, 8, 8, 9,10, 8,10,10, 6, 8, 8,
- 8,10, 8, 8,10,10, 5, 6, 6, 6, 8, 8, 6, 8, 8, 6,
- 8, 8, 8,10,10, 8, 8,10, 6, 8, 8, 8,10,10, 8,10,
- 9,
- };
-
- static float _vq_quantthresh__44u4__p2_0[] = {
- -0.5, 0.5,
- };
-
- static long _vq_quantmap__44u4__p2_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u4__p2_0 = {
- _vq_quantthresh__44u4__p2_0,
- _vq_quantmap__44u4__p2_0,
- 3,
- 3
- };
-
- static static_codebook _44u4__p2_0 = {
- 4, 81,
- _vq_lengthlist__44u4__p2_0,
- 1, -535822336, 1611661312, 2, 0,
- _vq_quantlist__44u4__p2_0,
- NULL,
- &_vq_auxt__44u4__p2_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u4__p3_0[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__44u4__p3_0[] = {
- 2, 4, 4, 8, 8, 5, 7, 7, 9, 9, 5, 7, 7, 9, 9, 8,
- 10, 9,12,12, 8, 9,10,12,12, 5, 7, 7,10,10, 7, 9,
- 9,11,11, 7, 9, 9,11,11,10,12,11,14,14, 9,10,11,
- 13,14, 5, 7, 7,10,10, 7, 9, 9,11,11, 7, 9, 9,11,
- 11, 9,11,10,14,13,10,11,11,14,14, 8,10,10,14,13,
- 10,12,12,15,14, 9,11,11,15,14,13,14,14,17,17,12,
- 14,14,16,16, 8,10,10,14,14, 9,11,11,14,15,10,12,
- 12,14,15,12,14,13,16,16,13,14,15,15,18, 4, 7, 7,
- 10,10, 7, 9, 9,12,11, 7, 9, 9,11,12,10,12,11,15,
- 14,10,11,12,14,15, 7, 9, 9,12,12, 9,11,12,13,13,
- 9,11,12,13,13,12,13,13,15,16,11,13,13,15,16, 7,
- 9, 9,12,12, 9,11,10,13,12, 9,11,12,13,14,11,13,
- 12,16,14,12,13,13,15,16,10,12,12,16,15,11,13,13,
- 17,16,11,13,13,17,16,14,15,15,17,17,14,16,16,18,
- 20, 9,11,11,15,16,11,13,12,16,16,11,13,13,16,17,
- 14,15,14,18,16,14,16,16,17,20, 5, 7, 7,10,10, 7,
- 9, 9,12,11, 7, 9,10,11,12,10,12,11,15,15,10,12,
- 12,14,14, 7, 9, 9,12,12, 9,12,11,14,13, 9,10,11,
- 12,13,12,13,14,16,16,11,12,13,14,16, 7, 9, 9,12,
- 12, 9,12,11,13,13, 9,12,11,13,13,11,13,13,16,16,
- 12,13,13,16,15, 9,11,11,16,14,11,13,13,16,16,11,
- 12,13,16,16,14,16,16,17,17,13,14,15,16,17,10,12,
- 12,15,15,11,13,13,16,17,11,13,13,16,16,14,16,15,
- 19,19,14,15,15,17,18, 8,10,10,14,14,10,12,12,15,
- 15,10,12,12,16,16,14,16,15,20,19,13,15,15,17,16,
- 9,12,12,16,16,11,13,13,16,18,11,14,13,16,17,16,
- 17,16,20, 0,15,16,18,18,20, 9,11,11,15,15,11,14,
- 12,17,16,11,13,13,17,17,15,17,15,20,20,14,16,16,
- 17, 0,13,15,14,18,16,14,15,16, 0,18,14,16,16, 0,
- 0,18,16, 0, 0,20,16,18,18, 0, 0,12,14,14,17,18,
- 13,15,14,20,18,14,16,15,19,19,16,20,16, 0,18,16,
- 19,17,19, 0, 8,10,10,14,14,10,12,12,16,15,10,12,
- 12,16,16,13,15,15,18,17,14,16,16,19, 0, 9,11,11,
- 16,15,11,14,13,18,17,11,12,13,17,18,14,17,16,18,
- 18,15,16,17,18,18, 9,12,12,16,16,11,13,13,16,18,
- 11,14,13,17,17,15,16,16,18,20,16,17,17,20,20,12,
- 14,14,18,17,14,16,16, 0,19,13,14,15,18, 0,16, 0,
- 0, 0, 0,16,16, 0,19,20,13,15,14, 0, 0,14,16,16,
- 18,19,14,16,15, 0,20,16,20,18, 0,20,17,20,17, 0,
- 0,
- };
-
- static float _vq_quantthresh__44u4__p3_0[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__44u4__p3_0[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u4__p3_0 = {
- _vq_quantthresh__44u4__p3_0,
- _vq_quantmap__44u4__p3_0,
- 5,
- 5
- };
-
- static static_codebook _44u4__p3_0 = {
- 4, 625,
- _vq_lengthlist__44u4__p3_0,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__44u4__p3_0,
- NULL,
- &_vq_auxt__44u4__p3_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u4__p4_0[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__44u4__p4_0[] = {
- 4, 5, 5, 8, 8, 5, 7, 6, 9, 9, 5, 6, 7, 9, 9, 9,
- 9, 9,11,11, 8, 9, 9,11,11, 5, 7, 7, 9, 9, 7, 8,
- 8,10,10, 7, 7, 8,10,10, 9,10,10,11,12, 9,10,10,
- 11,12, 5, 7, 7, 9, 9, 7, 8, 7,10,10, 7, 8, 8,10,
- 10, 9,10,10,12,11, 9,10,10,12,11, 9,10, 9,12,12,
- 9,10,10,13,12, 9,10,10,12,12,12,12,12,14,14,11,
- 12,12,13,14, 9, 9,10,12,12, 9,10,10,13,13, 9,10,
- 10,12,13,11,12,12,14,13,11,12,12,14,14, 5, 7, 7,
- 9, 9, 7, 8, 8,10,10, 7, 8, 8,10,10,10,10,10,12,
- 12, 9,10,10,12,12, 7, 8, 8,11,10, 8, 8, 9,11,11,
- 8, 9, 9,11,11,11,11,11,12,13,10,11,11,13,13, 6,
- 8, 8,10,10, 7, 9, 8,11,10, 8, 9, 9,11,11,10,11,
- 10,13,11,10,11,11,13,13, 9,11,10,13,12,10,11,11,
- 13,14,10,11,11,14,13,12,12,13,12,15,12,13,13,15,
- 15, 9,10,10,12,13,10,11,10,13,12,10,11,11,13,14,
- 12,13,11,15,13,13,13,13,15,15, 5, 7, 7, 9, 9, 7,
- 8, 8,10,10, 7, 8, 8,10,10, 9,10,10,12,12,10,10,
- 11,12,13, 6, 8, 8,10,10, 8, 9, 9,11,11, 7, 8, 9,
- 10,11,10,11,11,13,13,10,10,11,11,13, 7, 8, 8,10,
- 11, 8, 9, 9,11,11, 8, 9, 8,11,11,10,11,11,13,13,
- 11,12,11,13,12, 9,10,10,13,12,10,11,11,14,13,10,
- 10,11,12,13,12,13,13,15,15,12,11,13,13,14, 9,10,
- 11,12,13,10,11,11,13,14,10,11,11,13,13,12,13,13,
- 15,15,12,13,12,15,12, 8, 9, 9,12,12, 9,11,10,13,
- 13, 9,10,10,13,13,12,13,13,15,15,12,12,12,14,14,
- 9,10,10,13,13,10,11,11,13,14,10,11,11,14,13,13,
- 13,14,14,16,13,13,13,15,15, 9,10,10,13,13,10,11,
- 10,14,13,10,11,11,13,14,12,14,13,16,14,12,13,13,
- 14,15,11,12,12,15,14,11,12,13,14,15,12,13,13,16,
- 15,14,12,15,12,16,14,15,15,16,16,11,12,12,14,14,
- 11,13,12,15,14,12,13,13,15,16,13,15,13,17,13,14,
- 15,15,16,17, 8, 9, 9,12,12, 9,10,10,12,13, 9,10,
- 10,13,13,12,12,12,14,14,12,13,13,15,15, 9,10,10,
- 13,12,10,11,11,14,13,10,10,11,13,14,13,13,13,15,
- 15,12,13,14,14,16, 9,10,10,13,13,10,11,11,13,14,
- 10,11,11,14,14,13,13,13,15,15,13,14,13,16,14,11,
- 12,12,15,14,12,13,13,16,15,11,12,13,14,15,14,15,
- 15,17,16,13,13,15,13,16,11,12,13,14,15,13,13,13,
- 15,16,11,13,12,15,14,14,15,15,16,16,14,15,12,17,
- 13,
- };
-
- static float _vq_quantthresh__44u4__p4_0[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__44u4__p4_0[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u4__p4_0 = {
- _vq_quantthresh__44u4__p4_0,
- _vq_quantmap__44u4__p4_0,
- 5,
- 5
- };
-
- static static_codebook _44u4__p4_0 = {
- 4, 625,
- _vq_lengthlist__44u4__p4_0,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__44u4__p4_0,
- NULL,
- &_vq_auxt__44u4__p4_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u4__p5_0[] = {
- 4,
- 3,
- 5,
- 2,
- 6,
- 1,
- 7,
- 0,
- 8,
- };
-
- static long _vq_lengthlist__44u4__p5_0[] = {
- 2, 3, 3, 6, 6, 7, 7, 9, 9, 4, 5, 5, 7, 7, 8, 8,
- 10, 9, 4, 5, 5, 7, 7, 8, 8,10,10, 6, 7, 7, 8, 8,
- 9, 9,11,10, 6, 7, 7, 8, 8, 9, 9,10,11, 7, 8, 8,
- 9, 9,10,10,11,11, 7, 8, 8, 9, 9,10,10,11,11, 9,
- 10,10,11,10,11,11,12,12, 9,10,10,10,11,11,11,12,
- 12,
- };
-
- static float _vq_quantthresh__44u4__p5_0[] = {
- -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5,
- };
-
- static long _vq_quantmap__44u4__p5_0[] = {
- 7, 5, 3, 1, 0, 2, 4, 6,
- 8,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u4__p5_0 = {
- _vq_quantthresh__44u4__p5_0,
- _vq_quantmap__44u4__p5_0,
- 9,
- 9
- };
-
- static static_codebook _44u4__p5_0 = {
- 2, 81,
- _vq_lengthlist__44u4__p5_0,
- 1, -531628032, 1611661312, 4, 0,
- _vq_quantlist__44u4__p5_0,
- NULL,
- &_vq_auxt__44u4__p5_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u4__p6_0[] = {
- 6,
- 5,
- 7,
- 4,
- 8,
- 3,
- 9,
- 2,
- 10,
- 1,
- 11,
- 0,
- 12,
- };
-
- static long _vq_lengthlist__44u4__p6_0[] = {
- 1, 4, 4, 6, 6, 8, 8, 9, 9,11,10,13,13, 4, 6, 5,
- 8, 8, 9, 9,10,10,11,11,14,14, 4, 6, 6, 8, 8, 9,
- 9,10,10,11,11,14,14, 6, 8, 8, 9, 9,10,10,11,11,
- 12,12,15,15, 6, 8, 8, 9, 9,10,11,11,11,12,12,15,
- 15, 8, 9, 9,11,10,11,11,12,12,13,13,16,16, 8, 9,
- 9,10,10,11,11,12,12,13,13,16,16,10,10,10,12,11,
- 12,12,13,13,14,14,16,16,10,10,10,11,12,12,12,13,
- 13,13,14,16,17,11,12,11,12,12,13,13,14,14,15,14,
- 18,17,11,11,12,12,12,13,13,14,14,14,15,19,18,14,
- 15,14,15,15,17,16,17,17,17,17,21, 0,14,15,15,16,
- 16,16,16,17,17,18,17,20,21,
- };
-
- static float _vq_quantthresh__44u4__p6_0[] = {
- -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5,
- 12.5, 17.5, 22.5, 27.5,
- };
-
- static long _vq_quantmap__44u4__p6_0[] = {
- 11, 9, 7, 5, 3, 1, 0, 2,
- 4, 6, 8, 10, 12,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u4__p6_0 = {
- _vq_quantthresh__44u4__p6_0,
- _vq_quantmap__44u4__p6_0,
- 13,
- 13
- };
-
- static static_codebook _44u4__p6_0 = {
- 2, 169,
- _vq_lengthlist__44u4__p6_0,
- 1, -526516224, 1616117760, 4, 0,
- _vq_quantlist__44u4__p6_0,
- NULL,
- &_vq_auxt__44u4__p6_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u4__p6_1[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__44u4__p6_1[] = {
- 2, 4, 4, 5, 5, 4, 5, 5, 6, 5, 4, 5, 5, 5, 6, 5,
- 6, 5, 6, 6, 5, 5, 6, 6, 6,
- };
-
- static float _vq_quantthresh__44u4__p6_1[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__44u4__p6_1[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u4__p6_1 = {
- _vq_quantthresh__44u4__p6_1,
- _vq_quantmap__44u4__p6_1,
- 5,
- 5
- };
-
- static static_codebook _44u4__p6_1 = {
- 2, 25,
- _vq_lengthlist__44u4__p6_1,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__44u4__p6_1,
- NULL,
- &_vq_auxt__44u4__p6_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u4__p7_0[] = {
- 6,
- 5,
- 7,
- 4,
- 8,
- 3,
- 9,
- 2,
- 10,
- 1,
- 11,
- 0,
- 12,
- };
-
- static long _vq_lengthlist__44u4__p7_0[] = {
- 1, 3, 3,12,12,12,12,12,12,12,12,12,12, 3,12,11,
- 12,12,12,12,12,12,12,12,12,12, 4,11,10,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,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,12,
- 12,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,
- };
-
- static float _vq_quantthresh__44u4__p7_0[] = {
- -1402.5, -1147.5, -892.5, -637.5, -382.5, -127.5, 127.5, 382.5,
- 637.5, 892.5, 1147.5, 1402.5,
- };
-
- static long _vq_quantmap__44u4__p7_0[] = {
- 11, 9, 7, 5, 3, 1, 0, 2,
- 4, 6, 8, 10, 12,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u4__p7_0 = {
- _vq_quantthresh__44u4__p7_0,
- _vq_quantmap__44u4__p7_0,
- 13,
- 13
- };
-
- static static_codebook _44u4__p7_0 = {
- 2, 169,
- _vq_lengthlist__44u4__p7_0,
- 1, -514332672, 1627381760, 4, 0,
- _vq_quantlist__44u4__p7_0,
- NULL,
- &_vq_auxt__44u4__p7_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u4__p7_1[] = {
- 7,
- 6,
- 8,
- 5,
- 9,
- 4,
- 10,
- 3,
- 11,
- 2,
- 12,
- 1,
- 13,
- 0,
- 14,
- };
-
- static long _vq_lengthlist__44u4__p7_1[] = {
- 1, 4, 4, 6, 6, 7, 7, 9, 8,10, 8,10, 9,11,11, 4,
- 7, 6, 8, 7, 9, 9,10,10,11,10,11,10,12,10, 4, 6,
- 7, 8, 8, 9, 9,10,10,11,11,11,11,12,12, 6, 8, 8,
- 10, 9,11,10,12,11,12,12,12,12,13,13, 6, 8, 8,10,
- 10,10,11,11,11,12,12,13,12,13,13, 8, 9, 9,11,11,
- 12,11,12,12,13,13,13,13,13,13, 8, 9, 9,11,11,11,
- 12,12,12,13,13,13,13,13,13, 9,10,10,12,11,13,13,
- 13,13,14,13,13,14,14,14, 9,10,11,11,12,12,13,13,
- 13,13,13,14,15,14,14,10,11,11,12,12,13,13,14,14,
- 14,14,14,15,16,16,10,11,11,12,13,13,13,13,15,14,
- 14,15,16,15,16,10,12,12,13,13,14,14,14,15,15,15,
- 15,15,15,16,11,12,12,13,13,14,14,14,15,15,15,16,
- 15,17,16,11,12,12,13,13,13,15,15,14,16,16,16,16,
- 16,17,11,12,12,13,13,14,14,15,14,15,15,17,17,16,
- 16,
- };
-
- static float _vq_quantthresh__44u4__p7_1[] = {
- -110.5, -93.5, -76.5, -59.5, -42.5, -25.5, -8.5, 8.5,
- 25.5, 42.5, 59.5, 76.5, 93.5, 110.5,
- };
-
- static long _vq_quantmap__44u4__p7_1[] = {
- 13, 11, 9, 7, 5, 3, 1, 0,
- 2, 4, 6, 8, 10, 12, 14,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u4__p7_1 = {
- _vq_quantthresh__44u4__p7_1,
- _vq_quantmap__44u4__p7_1,
- 15,
- 15
- };
-
- static static_codebook _44u4__p7_1 = {
- 2, 225,
- _vq_lengthlist__44u4__p7_1,
- 1, -522338304, 1620115456, 4, 0,
- _vq_quantlist__44u4__p7_1,
- NULL,
- &_vq_auxt__44u4__p7_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u4__p7_2[] = {
- 8,
- 7,
- 9,
- 6,
- 10,
- 5,
- 11,
- 4,
- 12,
- 3,
- 13,
- 2,
- 14,
- 1,
- 15,
- 0,
- 16,
- };
-
- static long _vq_lengthlist__44u4__p7_2[] = {
- 2, 5, 5, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9,
- 9, 5, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9,
- 9, 9, 5, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9,
- 9, 9, 9, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9,
- 10,10,10,10, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9,10,
- 9,10, 9,10,10, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9,
- 10,10,10,10,10,10, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9,
- 9,10,10,10,10,10,10, 8, 9, 8, 9, 9, 9, 9, 9, 9,
- 10,10,10,10,10,10,10,10, 8, 8, 8, 9, 9, 9, 9, 9,
- 10,10,10,10,10,10,10,10,10, 9, 9, 9, 9, 9,10,10,
- 10,10,10,10,10,10,10,10,10,10, 9, 9, 9, 9, 9,10,
- 10,10,10,10,10,10,10,10,10,10,10, 9, 9, 9, 9,10,
- 10,10,10,10,10,10,10,10,10,10,10,10, 9, 9, 9, 9,
- 10,10,10,10,10,10,10,10,10,11,10,10,10, 9, 9, 9,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10, 9, 9,
- 9,10,10,10,10,10,10,10,10,10,10,10,10,10,10, 9,
- 10, 9,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 9,10, 9,10,10,10,10,10,10,10,10,10,10,11,10,10,
- 10,
- };
-
- static float _vq_quantthresh__44u4__p7_2[] = {
- -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5,
- 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5,
- };
-
- static long _vq_quantmap__44u4__p7_2[] = {
- 15, 13, 11, 9, 7, 5, 3, 1,
- 0, 2, 4, 6, 8, 10, 12, 14,
- 16,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u4__p7_2 = {
- _vq_quantthresh__44u4__p7_2,
- _vq_quantmap__44u4__p7_2,
- 17,
- 17
- };
-
- static static_codebook _44u4__p7_2 = {
- 2, 289,
- _vq_lengthlist__44u4__p7_2,
- 1, -529530880, 1611661312, 5, 0,
- _vq_quantlist__44u4__p7_2,
- NULL,
- &_vq_auxt__44u4__p7_2,
- NULL,
- 0
- };
-
- static long _huff_lengthlist__44u4__short[] = {
- 14,17,15,17,16,14,13,16,10, 7, 7,10,13,10,15,16,
- 9, 4, 4, 6, 5, 7, 9,16,12, 8, 7, 8, 8, 8,11,16,
- 14, 7, 4, 6, 3, 5, 8,15,13, 8, 5, 7, 4, 5, 7,16,
- 12, 9, 6, 8, 3, 3, 5,16,14,13, 7,10, 5, 5, 7,15,
- };
-
- static static_codebook _huff_book__44u4__short = {
- 2, 64,
- _huff_lengthlist__44u4__short,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist__44u5__long[] = {
- 3, 8,13,12,14,12,16,11,13,14, 5, 4, 5, 6, 7, 8,
- 10, 9,12,15,10, 5, 5, 5, 6, 8, 9, 9,13,15,10, 5,
- 5, 6, 6, 7, 8, 8,11,13,12, 7, 5, 6, 4, 6, 7, 7,
- 11,14,11, 7, 7, 6, 6, 6, 7, 6,10,14,14, 9, 8, 8,
- 6, 7, 7, 7,11,16,11, 8, 8, 7, 6, 6, 7, 4, 7,12,
- 10,10,12,10,10, 9,10, 5, 6, 9,10,12,15,13,14,14,
- 14, 8, 7, 8,
- };
-
- static static_codebook _huff_book__44u5__long = {
- 2, 100,
- _huff_lengthlist__44u5__long,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u5__p1_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__44u5__p1_0[] = {
- 1, 4, 4, 5, 8, 7, 5, 7, 7, 5, 8, 8, 8,10,10, 7,
- 9,10, 5, 8, 8, 7,10, 9, 8,10,10, 5, 8, 8, 8,10,
- 10, 8,10,10, 8,10,10,10,12,13,10,13,13, 7,10,10,
- 10,13,11,10,13,13, 4, 8, 8, 8,11,10, 8,10,10, 7,
- 10,10,10,13,13,10,11,13, 8,10,11,10,13,13,10,13,
- 12,
- };
-
- static float _vq_quantthresh__44u5__p1_0[] = {
- -0.5, 0.5,
- };
-
- static long _vq_quantmap__44u5__p1_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u5__p1_0 = {
- _vq_quantthresh__44u5__p1_0,
- _vq_quantmap__44u5__p1_0,
- 3,
- 3
- };
-
- static static_codebook _44u5__p1_0 = {
- 4, 81,
- _vq_lengthlist__44u5__p1_0,
- 1, -535822336, 1611661312, 2, 0,
- _vq_quantlist__44u5__p1_0,
- NULL,
- &_vq_auxt__44u5__p1_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u5__p2_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__44u5__p2_0[] = {
- 3, 4, 4, 5, 6, 6, 5, 6, 6, 5, 6, 6, 6, 8, 8, 6,
- 7, 8, 5, 6, 6, 6, 8, 7, 6, 8, 8, 5, 6, 6, 6, 8,
- 8, 6, 8, 8, 6, 8, 8, 8, 9, 9, 8, 9, 9, 6, 8, 7,
- 7, 9, 8, 8, 9, 9, 5, 6, 6, 6, 8, 7, 6, 8, 8, 6,
- 8, 7, 8, 9, 9, 7, 8, 9, 6, 8, 8, 8, 9, 9, 8, 9,
- 9,
- };
-
- static float _vq_quantthresh__44u5__p2_0[] = {
- -0.5, 0.5,
- };
-
- static long _vq_quantmap__44u5__p2_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u5__p2_0 = {
- _vq_quantthresh__44u5__p2_0,
- _vq_quantmap__44u5__p2_0,
- 3,
- 3
- };
-
- static static_codebook _44u5__p2_0 = {
- 4, 81,
- _vq_lengthlist__44u5__p2_0,
- 1, -535822336, 1611661312, 2, 0,
- _vq_quantlist__44u5__p2_0,
- NULL,
- &_vq_auxt__44u5__p2_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u5__p3_0[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__44u5__p3_0[] = {
- 2, 4, 5, 8, 8, 5, 7, 6, 9, 9, 5, 6, 7, 9, 9, 8,
- 10, 9,13,12, 8, 9,10,12,12, 5, 7, 7,10,10, 7, 9,
- 9,11,11, 6, 8, 9,11,11,10,11,11,14,14, 9,10,11,
- 13,14, 5, 7, 7, 9,10, 7, 9, 8,11,11, 7, 9, 9,11,
- 11, 9,11,10,14,13,10,11,11,14,14, 8,10,10,13,13,
- 10,11,11,15,14, 9,11,11,14,14,13,14,14,17,16,12,
- 13,13,15,16, 8,10,10,13,13, 9,11,11,14,15,10,11,
- 11,14,15,12,14,13,16,16,13,15,14,15,17, 5, 7, 7,
- 10,10, 7, 9, 9,11,11, 7, 9, 9,11,11,10,11,11,14,
- 14,10,11,12,14,14, 7, 9, 9,12,11, 9,11,11,13,13,
- 9,11,11,13,13,12,13,13,15,16,11,12,13,15,16, 6,
- 9, 9,11,11, 8,11,10,13,12, 9,11,11,13,14,11,13,
- 12,16,14,11,13,13,16,17,10,12,11,15,15,11,13,13,
- 16,16,11,13,13,17,16,14,15,15,17,17,14,16,16,17,
- 18, 9,11,11,14,15,10,12,12,15,15,11,13,13,16,17,
- 13,15,13,17,15,14,15,16,18, 0, 5, 7, 7,10,10, 7,
- 9, 9,11,11, 7, 9, 9,11,11,10,11,11,14,14,10,11,
- 12,14,15, 6, 9, 9,12,11, 9,11,11,13,13, 8,10,11,
- 12,13,11,13,13,16,15,11,12,13,14,15, 7, 9, 9,11,
- 12, 9,11,11,13,13, 9,11,11,13,13,11,13,13,15,16,
- 11,13,13,15,14, 9,11,11,15,14,11,13,13,17,15,10,
- 12,12,15,15,14,16,16,17,17,13,13,15,15,17,10,11,
- 12,15,15,11,13,13,16,16,11,13,13,15,15,14,15,15,
- 18,18,14,15,15,17,17, 8,10,10,13,13,10,12,11,15,
- 15,10,11,12,15,15,14,15,15,18,18,13,14,14,18,18,
- 9,11,11,15,16,11,13,13,17,17,11,13,13,16,16,15,
- 15,16,17, 0,14,15,17, 0, 0, 9,11,11,15,15,10,13,
- 12,18,16,11,13,13,15,16,14,16,15,20,20,14,15,16,
- 17, 0,13,14,14,20,16,14,15,16,19,18,14,15,15,19,
- 0,18,16, 0,20,20,16,18,18, 0, 0,12,14,14,18,18,
- 13,15,14,18,16,14,15,16,18,20,16,19,16, 0,17,17,
- 18,18,19, 0, 8,10,10,14,14,10,11,11,14,15,10,11,
- 12,15,15,13,15,14,19,17,13,15,15,17, 0, 9,11,11,
- 16,15,11,13,13,16,16,10,12,13,15,17,14,16,16,18,
- 18,14,15,15,18, 0, 9,11,11,15,15,11,13,13,16,17,
- 11,13,13,18,17,14,18,16,18,18,15,17,17,18, 0,12,
- 14,14,18,18,14,15,15,20, 0,13,14,15,17, 0,16,18,
- 17, 0, 0,16,16, 0,17,20,12,14,14,18,18,14,16,15,
- 0,18,14,16,15,18, 0,16,19,17, 0, 0,17,18,16, 0,
- 0,
- };
-
- static float _vq_quantthresh__44u5__p3_0[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__44u5__p3_0[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u5__p3_0 = {
- _vq_quantthresh__44u5__p3_0,
- _vq_quantmap__44u5__p3_0,
- 5,
- 5
- };
-
- static static_codebook _44u5__p3_0 = {
- 4, 625,
- _vq_lengthlist__44u5__p3_0,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__44u5__p3_0,
- NULL,
- &_vq_auxt__44u5__p3_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u5__p4_0[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__44u5__p4_0[] = {
- 4, 5, 5, 8, 8, 6, 7, 6, 9, 9, 6, 6, 7, 9, 9, 8,
- 9, 9,11,11, 8, 9, 9,11,11, 6, 7, 7, 9, 9, 7, 8,
- 8,10,10, 6, 7, 8, 9,10, 9,10,10,11,12, 9, 9,10,
- 11,12, 6, 7, 7, 9, 9, 6, 8, 7,10, 9, 7, 8, 8,10,
- 10, 9,10, 9,12,11, 9,10,10,12,11, 8, 9, 9,12,11,
- 9,10,10,12,12, 9,10,10,12,12,11,12,12,13,14,11,
- 11,12,13,14, 8, 9, 9,11,12, 9,10,10,12,12, 9,10,
- 10,12,12,11,12,11,14,13,11,12,12,13,13, 5, 7, 7,
- 9, 9, 7, 8, 8,10,10, 7, 8, 8,10,10, 9,10,10,12,
- 12, 9,10,10,12,12, 7, 8, 8,10,10, 8, 8, 9,10,11,
- 8, 9, 9,11,11,10,10,11,11,13,10,11,11,12,13, 6,
- 7, 8,10,10, 7, 9, 8,11,10, 8, 9, 9,11,11,10,11,
- 10,13,11,10,11,11,12,12, 9,10,10,12,12,10,10,11,
- 12,13,10,11,11,13,13,12,11,13,12,15,12,13,13,14,
- 15, 9,10,10,12,12, 9,11,10,13,12,10,11,11,13,13,
- 11,13,11,14,12,12,13,13,14,15, 5, 7, 7, 9, 9, 7,
- 8, 8,10,10, 7, 8, 8,10,10, 9,10,10,12,12, 9,10,
- 10,12,12, 6, 8, 7,10,10, 8, 9, 9,11,11, 7, 8, 9,
- 10,11,10,11,11,12,12,10,10,11,11,13, 7, 8, 8,10,
- 10, 8, 9, 9,11,11, 8, 9, 8,11,10,10,11,11,13,12,
- 10,11,10,13,11, 9,10,10,12,12,10,11,11,13,12, 9,
- 10,10,12,13,12,13,13,14,15,11,11,13,12,14, 9,10,
- 10,12,12,10,11,11,13,13,10,11,10,13,12,12,13,13,
- 14,14,12,13,11,14,12, 8, 9, 9,12,12, 9,10,10,12,
- 12, 9,10,10,12,12,12,12,12,14,14,11,12,12,14,13,
- 9,10,10,12,12,10,11,11,13,13,10,11,11,13,12,12,
- 12,13,14,15,12,13,13,15,14, 9,10,10,12,12,10,11,
- 10,13,12,10,11,11,12,13,12,13,12,15,13,12,13,13,
- 14,15,11,12,12,14,13,11,12,12,14,15,12,13,13,15,
- 14,13,12,14,12,16,13,14,14,15,15,11,11,12,14,14,
- 11,12,11,14,13,12,13,13,14,15,13,14,12,16,12,14,
- 14,15,16,16, 8, 9, 9,11,12, 9,10,10,12,12, 9,10,
- 10,12,13,11,12,12,13,13,12,12,13,14,14, 9,10,10,
- 12,12,10,11,10,13,12,10,10,11,12,13,12,13,13,15,
- 14,12,12,13,13,15, 9,10,10,12,13,10,11,11,12,13,
- 10,11,11,13,13,12,13,13,14,15,12,13,12,15,14,11,
- 12,11,14,13,12,13,13,15,14,11,11,12,13,14,14,15,
- 14,16,15,13,12,14,13,16,11,12,12,13,14,12,13,13,
- 14,15,11,12,11,14,14,14,14,14,15,16,13,15,12,16,
- 12,
- };
-
- static float _vq_quantthresh__44u5__p4_0[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__44u5__p4_0[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u5__p4_0 = {
- _vq_quantthresh__44u5__p4_0,
- _vq_quantmap__44u5__p4_0,
- 5,
- 5
- };
-
- static static_codebook _44u5__p4_0 = {
- 4, 625,
- _vq_lengthlist__44u5__p4_0,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__44u5__p4_0,
- NULL,
- &_vq_auxt__44u5__p4_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u5__p5_0[] = {
- 4,
- 3,
- 5,
- 2,
- 6,
- 1,
- 7,
- 0,
- 8,
- };
-
- static long _vq_lengthlist__44u5__p5_0[] = {
- 2, 3, 3, 6, 6, 8, 8,10,10, 4, 5, 5, 8, 7, 8, 8,
- 11,10, 3, 5, 5, 7, 8, 8, 8,10,11, 6, 8, 7,10, 9,
- 10,10,11,11, 6, 7, 8, 9, 9, 9,10,11,12, 8, 8, 8,
- 10,10,11,11,13,12, 8, 8, 9, 9,10,11,11,12,13,10,
- 11,10,12,11,13,12,14,14,10,10,11,11,12,12,13,14,
- 14,
- };
-
- static float _vq_quantthresh__44u5__p5_0[] = {
- -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5,
- };
-
- static long _vq_quantmap__44u5__p5_0[] = {
- 7, 5, 3, 1, 0, 2, 4, 6,
- 8,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u5__p5_0 = {
- _vq_quantthresh__44u5__p5_0,
- _vq_quantmap__44u5__p5_0,
- 9,
- 9
- };
-
- static static_codebook _44u5__p5_0 = {
- 2, 81,
- _vq_lengthlist__44u5__p5_0,
- 1, -531628032, 1611661312, 4, 0,
- _vq_quantlist__44u5__p5_0,
- NULL,
- &_vq_auxt__44u5__p5_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u5__p6_0[] = {
- 4,
- 3,
- 5,
- 2,
- 6,
- 1,
- 7,
- 0,
- 8,
- };
-
- static long _vq_lengthlist__44u5__p6_0[] = {
- 3, 4, 4, 5, 5, 7, 7, 9, 9, 4, 5, 4, 6, 6, 7, 7,
- 9, 9, 4, 4, 5, 6, 6, 7, 7, 9, 9, 5, 6, 6, 7, 7,
- 8, 8,10,10, 6, 6, 6, 7, 7, 8, 8,10,10, 7, 7, 7,
- 8, 8, 9, 9,11,10, 7, 7, 7, 8, 8, 9, 9,10,11, 9,
- 9, 9,10,10,11,10,11,11, 9, 9, 9,10,10,11,10,11,
- 11,
- };
-
- static float _vq_quantthresh__44u5__p6_0[] = {
- -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5,
- };
-
- static long _vq_quantmap__44u5__p6_0[] = {
- 7, 5, 3, 1, 0, 2, 4, 6,
- 8,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u5__p6_0 = {
- _vq_quantthresh__44u5__p6_0,
- _vq_quantmap__44u5__p6_0,
- 9,
- 9
- };
-
- static static_codebook _44u5__p6_0 = {
- 2, 81,
- _vq_lengthlist__44u5__p6_0,
- 1, -531628032, 1611661312, 4, 0,
- _vq_quantlist__44u5__p6_0,
- NULL,
- &_vq_auxt__44u5__p6_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u5__p7_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__44u5__p7_0[] = {
- 1, 4, 4, 5, 7, 7, 5, 7, 7, 5, 9, 9, 8,11,10, 7,
- 11,10, 5, 9, 9, 7,10,10, 8,10,11, 4, 9, 9, 9,12,
- 12, 9,12,12, 8,12,12,11,12,12,10,12,13, 7,12,12,
- 11,12,12,10,12,13, 4, 9, 9, 9,12,12, 9,12,12, 7,
- 12,11,10,13,13,11,12,12, 7,12,12,10,13,13,11,12,
- 12,
- };
-
- static float _vq_quantthresh__44u5__p7_0[] = {
- -5.5, 5.5,
- };
-
- static long _vq_quantmap__44u5__p7_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u5__p7_0 = {
- _vq_quantthresh__44u5__p7_0,
- _vq_quantmap__44u5__p7_0,
- 3,
- 3
- };
-
- static static_codebook _44u5__p7_0 = {
- 4, 81,
- _vq_lengthlist__44u5__p7_0,
- 1, -529137664, 1618345984, 2, 0,
- _vq_quantlist__44u5__p7_0,
- NULL,
- &_vq_auxt__44u5__p7_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u5__p7_1[] = {
- 5,
- 4,
- 6,
- 3,
- 7,
- 2,
- 8,
- 1,
- 9,
- 0,
- 10,
- };
-
- static long _vq_lengthlist__44u5__p7_1[] = {
- 2, 4, 4, 6, 6, 7, 7, 8, 8, 8, 8, 4, 5, 5, 7, 7,
- 8, 8, 9, 8, 8, 9, 4, 5, 5, 7, 7, 8, 8, 9, 9, 8,
- 9, 6, 7, 7, 8, 8, 9, 8, 9, 9, 9, 9, 6, 7, 7, 8,
- 8, 9, 9, 9, 9, 9, 9, 7, 8, 8, 9, 9, 9, 9, 9, 9,
- 9, 9, 7, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 8, 9, 9,
- 9, 9, 9, 9,10,10,10,10, 8, 9, 9, 9, 9, 9, 9,10,
- 10,10,10, 8, 9, 9, 9, 9, 9, 9,10,10,10,10, 8, 9,
- 9, 9, 9, 9, 9,10,10,10,10,
- };
-
- static float _vq_quantthresh__44u5__p7_1[] = {
- -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5,
- 3.5, 4.5,
- };
-
- static long _vq_quantmap__44u5__p7_1[] = {
- 9, 7, 5, 3, 1, 0, 2, 4,
- 6, 8, 10,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u5__p7_1 = {
- _vq_quantthresh__44u5__p7_1,
- _vq_quantmap__44u5__p7_1,
- 11,
- 11
- };
-
- static static_codebook _44u5__p7_1 = {
- 2, 121,
- _vq_lengthlist__44u5__p7_1,
- 1, -531365888, 1611661312, 4, 0,
- _vq_quantlist__44u5__p7_1,
- NULL,
- &_vq_auxt__44u5__p7_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u5__p8_0[] = {
- 5,
- 4,
- 6,
- 3,
- 7,
- 2,
- 8,
- 1,
- 9,
- 0,
- 10,
- };
-
- static long _vq_lengthlist__44u5__p8_0[] = {
- 1, 4, 4, 6, 6, 8, 8, 9, 9,10,10, 4, 6, 6, 7, 7,
- 9, 9,10,10,11,11, 4, 6, 6, 7, 7, 9, 9,10,10,11,
- 11, 6, 8, 7, 9, 9,10,10,11,11,13,12, 6, 8, 8, 9,
- 9,10,10,11,11,12,13, 8, 9, 9,10,10,12,12,13,12,
- 14,13, 8, 9, 9,10,10,12,12,13,13,14,14, 9,11,11,
- 12,12,13,13,14,14,15,14, 9,11,11,12,12,13,13,14,
- 14,15,14,11,12,12,13,13,14,14,15,14,15,14,11,11,
- 12,13,13,14,14,14,14,15,15,
- };
-
- static float _vq_quantthresh__44u5__p8_0[] = {
- -49.5, -38.5, -27.5, -16.5, -5.5, 5.5, 16.5, 27.5,
- 38.5, 49.5,
- };
-
- static long _vq_quantmap__44u5__p8_0[] = {
- 9, 7, 5, 3, 1, 0, 2, 4,
- 6, 8, 10,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u5__p8_0 = {
- _vq_quantthresh__44u5__p8_0,
- _vq_quantmap__44u5__p8_0,
- 11,
- 11
- };
-
- static static_codebook _44u5__p8_0 = {
- 2, 121,
- _vq_lengthlist__44u5__p8_0,
- 1, -524582912, 1618345984, 4, 0,
- _vq_quantlist__44u5__p8_0,
- NULL,
- &_vq_auxt__44u5__p8_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u5__p8_1[] = {
- 5,
- 4,
- 6,
- 3,
- 7,
- 2,
- 8,
- 1,
- 9,
- 0,
- 10,
- };
-
- static long _vq_lengthlist__44u5__p8_1[] = {
- 3, 5, 5, 6, 6, 7, 7, 7, 7, 7, 7, 5, 6, 5, 7, 6,
- 7, 7, 8, 8, 8, 8, 5, 5, 5, 6, 6, 7, 7, 8, 8, 8,
- 8, 6, 7, 6, 7, 7, 8, 8, 8, 8, 8, 8, 6, 6, 7, 7,
- 7, 8, 8, 8, 8, 8, 8, 7, 7, 7, 8, 8, 8, 8, 8, 8,
- 8, 8, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 7, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 7, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8,
- };
-
- static float _vq_quantthresh__44u5__p8_1[] = {
- -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5,
- 3.5, 4.5,
- };
-
- static long _vq_quantmap__44u5__p8_1[] = {
- 9, 7, 5, 3, 1, 0, 2, 4,
- 6, 8, 10,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u5__p8_1 = {
- _vq_quantthresh__44u5__p8_1,
- _vq_quantmap__44u5__p8_1,
- 11,
- 11
- };
-
- static static_codebook _44u5__p8_1 = {
- 2, 121,
- _vq_lengthlist__44u5__p8_1,
- 1, -531365888, 1611661312, 4, 0,
- _vq_quantlist__44u5__p8_1,
- NULL,
- &_vq_auxt__44u5__p8_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u5__p9_0[] = {
- 6,
- 5,
- 7,
- 4,
- 8,
- 3,
- 9,
- 2,
- 10,
- 1,
- 11,
- 0,
- 12,
- };
-
- static long _vq_lengthlist__44u5__p9_0[] = {
- 1, 3, 2,12,10,13,13,13,13,13,13,13,13, 4, 9, 9,
- 13,13,13,13,13,13,13,13,13,13, 5,10, 9,13,13,13,
- 13,13,13,13,13,13,13,12,13,13,13,13,13,13,13,13,
- 13,13,13,13,11,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,
- 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,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,13,13,13,13,13,13,13,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,12,12,12,
- };
-
- static float _vq_quantthresh__44u5__p9_0[] = {
- -1402.5, -1147.5, -892.5, -637.5, -382.5, -127.5, 127.5, 382.5,
- 637.5, 892.5, 1147.5, 1402.5,
- };
-
- static long _vq_quantmap__44u5__p9_0[] = {
- 11, 9, 7, 5, 3, 1, 0, 2,
- 4, 6, 8, 10, 12,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u5__p9_0 = {
- _vq_quantthresh__44u5__p9_0,
- _vq_quantmap__44u5__p9_0,
- 13,
- 13
- };
-
- static static_codebook _44u5__p9_0 = {
- 2, 169,
- _vq_lengthlist__44u5__p9_0,
- 1, -514332672, 1627381760, 4, 0,
- _vq_quantlist__44u5__p9_0,
- NULL,
- &_vq_auxt__44u5__p9_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u5__p9_1[] = {
- 7,
- 6,
- 8,
- 5,
- 9,
- 4,
- 10,
- 3,
- 11,
- 2,
- 12,
- 1,
- 13,
- 0,
- 14,
- };
-
- static long _vq_lengthlist__44u5__p9_1[] = {
- 1, 4, 4, 7, 7, 8, 8, 8, 7, 8, 7, 9, 8, 9, 9, 4,
- 7, 6, 9, 8,10,10, 9, 8, 9, 9, 9, 9, 9, 8, 5, 6,
- 6, 8, 9,10,10, 9, 9, 9,10,10,10,10,11, 7, 8, 8,
- 10,10,11,11,10,10,11,11,11,12,11,11, 7, 8, 8,10,
- 10,11,11,10,10,11,11,12,11,11,11, 8, 9, 9,11,11,
- 12,12,11,11,12,11,12,12,12,12, 8, 9,10,11,11,12,
- 12,11,11,12,12,12,12,12,12, 8, 9, 9,10,10,12,11,
- 12,12,12,12,12,12,12,13, 8, 9, 9,11,11,11,11,12,
- 12,12,12,13,12,13,13, 9,10,10,11,11,12,12,12,13,
- 12,13,13,13,14,13, 9,10,10,11,11,12,12,12,13,13,
- 12,13,13,14,13, 9,11,10,12,11,13,12,12,13,13,13,
- 13,13,13,14, 9,10,10,12,12,12,12,12,13,13,13,13,
- 13,14,14,10,11,11,12,12,12,13,13,13,14,14,13,14,
- 14,14,10,11,11,12,12,12,12,13,12,13,14,13,14,14,
- 14,
- };
-
- static float _vq_quantthresh__44u5__p9_1[] = {
- -110.5, -93.5, -76.5, -59.5, -42.5, -25.5, -8.5, 8.5,
- 25.5, 42.5, 59.5, 76.5, 93.5, 110.5,
- };
-
- static long _vq_quantmap__44u5__p9_1[] = {
- 13, 11, 9, 7, 5, 3, 1, 0,
- 2, 4, 6, 8, 10, 12, 14,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u5__p9_1 = {
- _vq_quantthresh__44u5__p9_1,
- _vq_quantmap__44u5__p9_1,
- 15,
- 15
- };
-
- static static_codebook _44u5__p9_1 = {
- 2, 225,
- _vq_lengthlist__44u5__p9_1,
- 1, -522338304, 1620115456, 4, 0,
- _vq_quantlist__44u5__p9_1,
- NULL,
- &_vq_auxt__44u5__p9_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u5__p9_2[] = {
- 8,
- 7,
- 9,
- 6,
- 10,
- 5,
- 11,
- 4,
- 12,
- 3,
- 13,
- 2,
- 14,
- 1,
- 15,
- 0,
- 16,
- };
-
- static long _vq_lengthlist__44u5__p9_2[] = {
- 2, 5, 5, 7, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9,
- 9, 5, 6, 6, 7, 7, 8, 8, 9, 8, 9, 9, 9, 9, 9, 9,
- 9, 9, 5, 6, 6, 7, 7, 8, 8, 9, 8, 9, 9, 9, 9, 9,
- 9, 9, 9, 7, 7, 7, 8, 8, 9, 8, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 7, 7, 7, 8, 8, 9, 8, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9,
- 9,10, 9,10,10,10, 8, 8, 8, 9, 8, 9, 9, 9, 9, 9,
- 9, 9,10, 9,10, 9,10, 8, 9, 9, 9, 9, 9, 9, 9, 9,
- 9,10, 9,10,10,10,10,10, 8, 9, 9, 9, 9, 9, 9,10,
- 9,10, 9,10,10,10,10,10,10, 9, 9, 9, 9, 9,10, 9,
- 10,10,10,10,10,10,10,10,10,10, 9, 9, 9, 9, 9, 9,
- 9,10, 9,10, 9,10,10,10,10,10,10, 9, 9, 9, 9, 9,
- 10,10,10,10,10,10,10,10,10,10,10,10, 9, 9, 9, 9,
- 9, 9,10,10,10,10,10,10,10,10,10,10,10, 9, 9, 9,
- 9,10,10, 9,10,10,10,10,10,10,10,10,10,10, 9, 9,
- 9, 9, 9,10,10,10,10,10,10,10,10,10,10,10,10, 9,
- 9, 9, 9, 9,10,10,10,10,10,10,10,10,10,10,10,10,
- 9, 9, 9,10, 9,10,10,10,10,10,10,10,10,10,10,10,
- 10,
- };
-
- static float _vq_quantthresh__44u5__p9_2[] = {
- -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5,
- 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5,
- };
-
- static long _vq_quantmap__44u5__p9_2[] = {
- 15, 13, 11, 9, 7, 5, 3, 1,
- 0, 2, 4, 6, 8, 10, 12, 14,
- 16,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u5__p9_2 = {
- _vq_quantthresh__44u5__p9_2,
- _vq_quantmap__44u5__p9_2,
- 17,
- 17
- };
-
- static static_codebook _44u5__p9_2 = {
- 2, 289,
- _vq_lengthlist__44u5__p9_2,
- 1, -529530880, 1611661312, 5, 0,
- _vq_quantlist__44u5__p9_2,
- NULL,
- &_vq_auxt__44u5__p9_2,
- NULL,
- 0
- };
-
- static long _huff_lengthlist__44u5__short[] = {
- 4,10,17,13,17,13,17,17,17,17, 3, 6, 8, 9,11, 9,
- 15,12,16,17, 6, 5, 5, 7, 7, 8,10,11,17,17, 7, 8,
- 7, 9, 9,10,13,13,17,17, 8, 6, 5, 7, 4, 7, 5, 8,
- 14,17, 9, 9, 8, 9, 7, 9, 8,10,16,17,12,10, 7, 8,
- 4, 7, 4, 7,16,17,12,11, 9,10, 6, 9, 5, 7,14,17,
- 14,13,10,15, 4, 8, 3, 5,14,17,17,14,11,15, 6,10,
- 6, 8,15,17,
- };
-
- static static_codebook _huff_book__44u5__short = {
- 2, 100,
- _huff_lengthlist__44u5__short,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist__44u6__long[] = {
- 3, 9,14,13,14,13,16,12,13,14, 5, 4, 6, 6, 8, 9,
- 11,10,12,15,10, 5, 5, 6, 6, 8,10,10,13,16,10, 6,
- 6, 6, 6, 8, 9, 9,12,14,13, 7, 6, 6, 4, 6, 6, 7,
- 11,14,10, 7, 7, 7, 6, 6, 6, 7,10,13,15,10, 9, 8,
- 5, 6, 5, 6,10,14,10, 9, 8, 8, 6, 6, 5, 4, 6,11,
- 11,11,12,11,10, 9, 9, 5, 5, 9,10,12,15,13,13,13,
- 13, 8, 7, 7,
- };
-
- static static_codebook _huff_book__44u6__long = {
- 2, 100,
- _huff_lengthlist__44u6__long,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u6__p1_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__44u6__p1_0[] = {
- 1, 4, 4, 4, 8, 7, 5, 7, 7, 5, 8, 8, 8,10,10, 7,
- 9,10, 5, 8, 8, 7,10, 9, 8,10,10, 5, 8, 8, 8,10,
- 10, 8,10,10, 8,10,10,10,12,13,10,13,13, 7,10,10,
- 10,13,11,10,13,13, 5, 8, 8, 8,11,10, 8,10,10, 7,
- 10,10,10,13,13,10,11,13, 8,10,11,10,13,13,10,13,
- 12,
- };
-
- static float _vq_quantthresh__44u6__p1_0[] = {
- -0.5, 0.5,
- };
-
- static long _vq_quantmap__44u6__p1_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u6__p1_0 = {
- _vq_quantthresh__44u6__p1_0,
- _vq_quantmap__44u6__p1_0,
- 3,
- 3
- };
-
- static static_codebook _44u6__p1_0 = {
- 4, 81,
- _vq_lengthlist__44u6__p1_0,
- 1, -535822336, 1611661312, 2, 0,
- _vq_quantlist__44u6__p1_0,
- NULL,
- &_vq_auxt__44u6__p1_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u6__p2_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__44u6__p2_0[] = {
- 3, 4, 4, 5, 6, 6, 5, 6, 6, 5, 6, 6, 6, 8, 8, 6,
- 7, 8, 5, 6, 6, 6, 8, 7, 6, 8, 8, 5, 6, 6, 6, 8,
- 8, 6, 8, 8, 6, 8, 8, 8, 9, 9, 8, 9, 9, 6, 7, 7,
- 7, 9, 8, 8, 9, 9, 5, 6, 6, 6, 8, 7, 6, 8, 8, 6,
- 8, 8, 8, 9, 9, 7, 8, 9, 6, 8, 8, 8, 9, 9, 8, 9,
- 9,
- };
-
- static float _vq_quantthresh__44u6__p2_0[] = {
- -0.5, 0.5,
- };
-
- static long _vq_quantmap__44u6__p2_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u6__p2_0 = {
- _vq_quantthresh__44u6__p2_0,
- _vq_quantmap__44u6__p2_0,
- 3,
- 3
- };
-
- static static_codebook _44u6__p2_0 = {
- 4, 81,
- _vq_lengthlist__44u6__p2_0,
- 1, -535822336, 1611661312, 2, 0,
- _vq_quantlist__44u6__p2_0,
- NULL,
- &_vq_auxt__44u6__p2_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u6__p3_0[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__44u6__p3_0[] = {
- 2, 5, 4, 8, 8, 5, 7, 6, 9, 9, 5, 6, 7, 9, 9, 8,
- 9, 9,13,12, 8, 9,10,12,13, 5, 7, 7,10, 9, 7, 9,
- 9,11,11, 7, 8, 9,11,11,10,11,11,14,14, 9,10,11,
- 13,14, 5, 7, 7, 9,10, 6, 9, 8,11,11, 7, 9, 9,11,
- 11, 9,11,10,14,13,10,11,11,14,13, 8,10,10,13,13,
- 10,11,11,15,15, 9,11,11,14,14,13,14,14,17,16,12,
- 13,14,16,16, 8,10,10,13,14, 9,11,11,14,15,10,11,
- 12,14,15,12,14,13,16,15,13,14,14,15,17, 5, 7, 7,
- 10,10, 7, 9, 9,11,11, 7, 9, 9,11,11,10,12,11,14,
- 14,10,11,11,14,14, 7, 9, 9,12,11, 9,11,11,13,13,
- 9,11,11,13,13,11,13,13,14,15,11,12,13,15,16, 6,
- 9, 9,11,12, 8,11,10,13,12, 9,11,11,13,14,11,13,
- 12,16,14,11,13,13,15,16,10,12,11,14,15,11,13,13,
- 15,17,11,13,13,17,16,15,15,16,17,16,14,15,16,18,
- 0, 9,11,11,14,15,10,12,12,16,15,11,13,13,16,16,
- 13,15,14,18,15,14,16,16, 0, 0, 5, 7, 7,10,10, 7,
- 9, 9,11,11, 7, 9, 9,11,11,10,11,11,14,14,10,11,
- 12,14,14, 6, 9, 9,11,11, 9,11,11,13,13, 8,10,11,
- 12,13,11,13,13,16,15,11,12,13,14,16, 7, 9, 9,11,
- 12, 9,11,11,13,13, 9,11,11,13,13,11,13,13,16,15,
- 11,13,12,15,15, 9,11,11,15,14,11,13,13,17,16,10,
- 12,13,15,16,14,16,16, 0,18,14,14,15,15,17,10,11,
- 12,15,15,11,13,13,16,16,11,13,13,16,16,14,16,16,
- 19,17,14,15,15,17,17, 8,10,10,14,14,10,12,11,15,
- 15,10,11,12,16,15,14,15,15,18,20,13,14,16,17,18,
- 9,11,11,15,16,11,13,13,17,17,11,13,13,17,16,15,
- 16,16, 0, 0,15,16,16, 0, 0, 9,11,11,15,15,10,13,
- 12,17,15,11,13,13,17,16,15,17,15,20,19,15,16,16,
- 19, 0,13,15,14, 0,17,14,15,16, 0,20,15,16,16, 0,
- 19,17,18, 0, 0, 0,16,17,18, 0, 0,12,14,14,19,18,
- 13,15,14, 0,17,14,15,16,19,19,16,18,16, 0,19,19,
- 20,17,20, 0, 8,10,10,13,14,10,11,11,15,15,10,12,
- 12,15,16,14,15,14,19,16,14,15,15, 0,18, 9,11,11,
- 16,15,11,13,13, 0,16,11,12,13,16,17,14,16,17, 0,
- 19,15,16,16,18, 0, 9,11,11,15,16,11,13,13,16,16,
- 11,14,13,18,17,15,16,16,18,20,15,17,19, 0, 0,12,
- 14,14,17,17,14,16,15, 0, 0,13,14,15,19, 0,16,18,
- 20, 0, 0,16,16,18,18, 0,12,14,14,17,20,14,16,16,
- 19, 0,14,16,14, 0,20,16,20,17, 0, 0,17, 0,15, 0,
- 19,
- };
-
- static float _vq_quantthresh__44u6__p3_0[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__44u6__p3_0[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u6__p3_0 = {
- _vq_quantthresh__44u6__p3_0,
- _vq_quantmap__44u6__p3_0,
- 5,
- 5
- };
-
- static static_codebook _44u6__p3_0 = {
- 4, 625,
- _vq_lengthlist__44u6__p3_0,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__44u6__p3_0,
- NULL,
- &_vq_auxt__44u6__p3_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u6__p4_0[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__44u6__p4_0[] = {
- 4, 5, 5, 8, 8, 6, 7, 6, 9, 9, 6, 6, 7, 9, 9, 8,
- 9, 9,11,11, 8, 9, 9,11,11, 6, 7, 7, 9, 9, 7, 8,
- 8,10,10, 7, 7, 8, 9,10, 9,10,10,11,11, 9, 9,10,
- 11,12, 6, 7, 7, 9, 9, 7, 8, 7,10, 9, 7, 8, 8,10,
- 10, 9,10, 9,12,11, 9,10,10,12,11, 8, 9, 9,11,11,
- 9,10,10,12,12, 9,10,10,12,12,11,12,12,14,13,11,
- 11,12,13,13, 8, 9, 9,11,11, 9,10,10,12,12, 9,10,
- 10,12,12,11,12,11,13,12,11,12,12,13,13, 5, 7, 7,
- 9, 9, 7, 8, 7,10,10, 7, 7, 8,10,10, 9,10,10,12,
- 11, 9,10,10,11,12, 7, 8, 8,10,10, 8, 8, 9,11,11,
- 8, 9, 9,11,11,10,10,11,12,13,10,10,11,12,12, 6,
- 7, 7,10,10, 7, 9, 8,11,10, 8, 8, 9,10,11,10,11,
- 10,13,11,10,11,11,12,12, 9,10,10,12,12,10,10,11,
- 13,13,10,11,11,12,13,12,12,12,13,14,12,12,13,14,
- 14, 9,10,10,12,12, 9,10,10,13,12,10,11,11,13,13,
- 11,12,11,14,12,12,13,13,14,14, 6, 7, 7, 9, 9, 7,
- 8, 7,10,10, 7, 8, 8,10,10, 9,10,10,12,11, 9,10,
- 10,11,12, 6, 7, 7,10,10, 8, 9, 8,11,10, 7, 8, 9,
- 10,11,10,11,11,12,12,10,10,11,11,13, 7, 8, 8,10,
- 10, 8, 9, 9,11,11, 8, 9, 8,11,11,10,11,10,13,12,
- 10,11,11,13,12, 9,10,10,12,12,10,11,11,13,12, 9,
- 10,10,12,13,12,13,12,14,14,11,11,12,12,14, 9,10,
- 10,12,12,10,11,11,13,13,10,11,10,13,12,12,12,12,
- 14,14,12,13,12,14,13, 8, 9, 9,11,11, 9,10,10,12,
- 12, 9,10,10,12,12,11,12,12,14,13,11,12,12,13,14,
- 9,10,10,12,12,10,11,11,13,13,10,11,11,13,13,12,
- 12,13,14,15,12,12,13,14,14, 9,10,10,12,12, 9,11,
- 10,13,12,10,10,11,12,13,12,13,12,14,13,12,12,13,
- 14,15,11,12,12,14,13,11,12,12,14,14,12,13,13,14,
- 14,13,13,14,14,16,13,14,14,15,15,11,12,11,13,13,
- 11,12,11,14,13,12,12,13,14,15,12,14,12,15,12,13,
- 14,15,15,16, 8, 9, 9,11,11, 9,10,10,12,12, 9,10,
- 10,12,12,11,12,12,14,13,11,12,12,13,13, 9,10,10,
- 12,12,10,11,10,13,12, 9,10,11,12,13,12,13,12,14,
- 14,12,12,13,13,14, 9,10,10,12,12,10,11,11,13,13,
- 10,11,11,13,13,12,13,12,14,14,12,13,13,14,14,11,
- 11,11,13,13,12,13,12,14,14,11,11,12,13,14,14,14,
- 14,16,15,12,12,14,12,15,11,12,12,13,14,12,13,13,
- 14,15,11,12,12,14,14,13,14,14,16,16,13,14,13,16,
- 13,
- };
-
- static float _vq_quantthresh__44u6__p4_0[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__44u6__p4_0[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u6__p4_0 = {
- _vq_quantthresh__44u6__p4_0,
- _vq_quantmap__44u6__p4_0,
- 5,
- 5
- };
-
- static static_codebook _44u6__p4_0 = {
- 4, 625,
- _vq_lengthlist__44u6__p4_0,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__44u6__p4_0,
- NULL,
- &_vq_auxt__44u6__p4_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u6__p5_0[] = {
- 4,
- 3,
- 5,
- 2,
- 6,
- 1,
- 7,
- 0,
- 8,
- };
-
- static long _vq_lengthlist__44u6__p5_0[] = {
- 2, 3, 3, 6, 6, 8, 8,10,10, 4, 5, 5, 8, 7, 8, 8,
- 11,11, 3, 5, 5, 7, 8, 8, 8,11,11, 6, 8, 7, 9, 9,
- 10, 9,12,11, 6, 7, 8, 9, 9, 9,10,11,12, 8, 8, 8,
- 10, 9,12,11,13,13, 8, 8, 9, 9,10,11,12,13,13,10,
- 11,11,12,12,13,13,14,14,10,10,11,11,12,13,13,14,
- 14,
- };
-
- static float _vq_quantthresh__44u6__p5_0[] = {
- -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5,
- };
-
- static long _vq_quantmap__44u6__p5_0[] = {
- 7, 5, 3, 1, 0, 2, 4, 6,
- 8,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u6__p5_0 = {
- _vq_quantthresh__44u6__p5_0,
- _vq_quantmap__44u6__p5_0,
- 9,
- 9
- };
-
- static static_codebook _44u6__p5_0 = {
- 2, 81,
- _vq_lengthlist__44u6__p5_0,
- 1, -531628032, 1611661312, 4, 0,
- _vq_quantlist__44u6__p5_0,
- NULL,
- &_vq_auxt__44u6__p5_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u6__p6_0[] = {
- 4,
- 3,
- 5,
- 2,
- 6,
- 1,
- 7,
- 0,
- 8,
- };
-
- static long _vq_lengthlist__44u6__p6_0[] = {
- 3, 4, 4, 5, 5, 7, 7, 9, 9, 4, 5, 4, 6, 6, 7, 7,
- 9, 9, 4, 4, 5, 6, 6, 7, 8, 9, 9, 5, 6, 6, 7, 7,
- 8, 8,10,10, 5, 6, 6, 7, 7, 8, 8,10,10, 7, 8, 7,
- 8, 8,10, 9,11,11, 7, 7, 8, 8, 8, 9,10,10,11, 9,
- 9, 9,10,10,11,11,12,11, 9, 9, 9,10,10,11,11,11,
- 12,
- };
-
- static float _vq_quantthresh__44u6__p6_0[] = {
- -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5,
- };
-
- static long _vq_quantmap__44u6__p6_0[] = {
- 7, 5, 3, 1, 0, 2, 4, 6,
- 8,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u6__p6_0 = {
- _vq_quantthresh__44u6__p6_0,
- _vq_quantmap__44u6__p6_0,
- 9,
- 9
- };
-
- static static_codebook _44u6__p6_0 = {
- 2, 81,
- _vq_lengthlist__44u6__p6_0,
- 1, -531628032, 1611661312, 4, 0,
- _vq_quantlist__44u6__p6_0,
- NULL,
- &_vq_auxt__44u6__p6_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u6__p7_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__44u6__p7_0[] = {
- 1, 4, 4, 5, 7, 7, 5, 7, 7, 5, 9, 8, 7,10,10, 8,
- 10,10, 5, 8, 9, 7,10,10, 7,10, 9, 4, 8, 8, 9,11,
- 11, 8,11,11, 7,11,11,10,10,13,10,13,13, 7,11,11,
- 10,13,12,10,13,13, 5, 9, 8, 8,11,11, 9,11,11, 7,
- 11,11,10,13,13,10,12,13, 7,11,11,10,13,13, 9,13,
- 10,
- };
-
- static float _vq_quantthresh__44u6__p7_0[] = {
- -5.5, 5.5,
- };
-
- static long _vq_quantmap__44u6__p7_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u6__p7_0 = {
- _vq_quantthresh__44u6__p7_0,
- _vq_quantmap__44u6__p7_0,
- 3,
- 3
- };
-
- static static_codebook _44u6__p7_0 = {
- 4, 81,
- _vq_lengthlist__44u6__p7_0,
- 1, -529137664, 1618345984, 2, 0,
- _vq_quantlist__44u6__p7_0,
- NULL,
- &_vq_auxt__44u6__p7_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u6__p7_1[] = {
- 5,
- 4,
- 6,
- 3,
- 7,
- 2,
- 8,
- 1,
- 9,
- 0,
- 10,
- };
-
- static long _vq_lengthlist__44u6__p7_1[] = {
- 3, 4, 4, 6, 6, 7, 7, 8, 8, 8, 8, 4, 5, 5, 7, 6,
- 8, 8, 8, 8, 8, 8, 4, 5, 5, 6, 7, 8, 8, 8, 8, 8,
- 8, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 6, 7, 7, 7,
- 7, 8, 8, 8, 8, 8, 8, 7, 8, 8, 8, 8, 8, 8, 9, 9,
- 9, 9, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 8, 8, 8,
- 8, 8, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 9, 9, 9,
- 9, 9, 9, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 8, 8,
- 8, 8, 8, 9, 9, 9, 9, 9, 9,
- };
-
- static float _vq_quantthresh__44u6__p7_1[] = {
- -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5,
- 3.5, 4.5,
- };
-
- static long _vq_quantmap__44u6__p7_1[] = {
- 9, 7, 5, 3, 1, 0, 2, 4,
- 6, 8, 10,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u6__p7_1 = {
- _vq_quantthresh__44u6__p7_1,
- _vq_quantmap__44u6__p7_1,
- 11,
- 11
- };
-
- static static_codebook _44u6__p7_1 = {
- 2, 121,
- _vq_lengthlist__44u6__p7_1,
- 1, -531365888, 1611661312, 4, 0,
- _vq_quantlist__44u6__p7_1,
- NULL,
- &_vq_auxt__44u6__p7_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u6__p8_0[] = {
- 5,
- 4,
- 6,
- 3,
- 7,
- 2,
- 8,
- 1,
- 9,
- 0,
- 10,
- };
-
- static long _vq_lengthlist__44u6__p8_0[] = {
- 1, 4, 4, 6, 6, 8, 8, 9, 9,10,10, 4, 6, 6, 7, 7,
- 9, 9,10,10,11,11, 4, 6, 6, 7, 7, 9, 9,10,10,11,
- 11, 6, 8, 8, 9, 9,10,10,11,11,12,12, 6, 8, 8, 9,
- 9,10,10,11,11,12,12, 8, 9, 9,10,10,11,11,12,12,
- 13,13, 8, 9, 9,10,10,11,11,12,12,13,13,10,10,10,
- 11,11,13,13,13,13,15,14, 9,10,10,12,11,12,13,13,
- 13,14,15,11,12,12,13,13,13,13,15,14,15,15,11,11,
- 12,13,13,14,14,14,15,15,15,
- };
-
- static float _vq_quantthresh__44u6__p8_0[] = {
- -49.5, -38.5, -27.5, -16.5, -5.5, 5.5, 16.5, 27.5,
- 38.5, 49.5,
- };
-
- static long _vq_quantmap__44u6__p8_0[] = {
- 9, 7, 5, 3, 1, 0, 2, 4,
- 6, 8, 10,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u6__p8_0 = {
- _vq_quantthresh__44u6__p8_0,
- _vq_quantmap__44u6__p8_0,
- 11,
- 11
- };
-
- static static_codebook _44u6__p8_0 = {
- 2, 121,
- _vq_lengthlist__44u6__p8_0,
- 1, -524582912, 1618345984, 4, 0,
- _vq_quantlist__44u6__p8_0,
- NULL,
- &_vq_auxt__44u6__p8_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u6__p8_1[] = {
- 5,
- 4,
- 6,
- 3,
- 7,
- 2,
- 8,
- 1,
- 9,
- 0,
- 10,
- };
-
- static long _vq_lengthlist__44u6__p8_1[] = {
- 3, 5, 5, 6, 6, 7, 7, 7, 7, 7, 7, 5, 6, 5, 7, 7,
- 7, 7, 8, 7, 8, 8, 5, 5, 6, 6, 7, 7, 7, 7, 7, 8,
- 8, 6, 7, 7, 7, 7, 8, 7, 8, 8, 8, 8, 6, 6, 7, 7,
- 7, 7, 8, 8, 8, 8, 8, 7, 7, 7, 8, 8, 8, 8, 8, 8,
- 8, 8, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7,
- 8, 8, 8, 8, 8, 8, 8, 8, 7, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8,
- };
-
- static float _vq_quantthresh__44u6__p8_1[] = {
- -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5,
- 3.5, 4.5,
- };
-
- static long _vq_quantmap__44u6__p8_1[] = {
- 9, 7, 5, 3, 1, 0, 2, 4,
- 6, 8, 10,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u6__p8_1 = {
- _vq_quantthresh__44u6__p8_1,
- _vq_quantmap__44u6__p8_1,
- 11,
- 11
- };
-
- static static_codebook _44u6__p8_1 = {
- 2, 121,
- _vq_lengthlist__44u6__p8_1,
- 1, -531365888, 1611661312, 4, 0,
- _vq_quantlist__44u6__p8_1,
- NULL,
- &_vq_auxt__44u6__p8_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u6__p9_0[] = {
- 7,
- 6,
- 8,
- 5,
- 9,
- 4,
- 10,
- 3,
- 11,
- 2,
- 12,
- 1,
- 13,
- 0,
- 14,
- };
-
- static long _vq_lengthlist__44u6__p9_0[] = {
- 1, 3, 2, 9, 8,15,15,15,15,15,15,15,15,15,15, 4,
- 8, 9,13,14,14,14,14,14,14,14,14,14,14,14, 5, 8,
- 9,14,14,14,14,14,14,14,14,14,14,14,14,11,14,14,
- 14,14,14,14,14,14,14,14,14,14,14,14,11,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,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,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,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,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,14,14,
- 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,
- 14,
- };
-
- static float _vq_quantthresh__44u6__p9_0[] = {
- -1657.5, -1402.5, -1147.5, -892.5, -637.5, -382.5, -127.5, 127.5,
- 382.5, 637.5, 892.5, 1147.5, 1402.5, 1657.5,
- };
-
- static long _vq_quantmap__44u6__p9_0[] = {
- 13, 11, 9, 7, 5, 3, 1, 0,
- 2, 4, 6, 8, 10, 12, 14,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u6__p9_0 = {
- _vq_quantthresh__44u6__p9_0,
- _vq_quantmap__44u6__p9_0,
- 15,
- 15
- };
-
- static static_codebook _44u6__p9_0 = {
- 2, 225,
- _vq_lengthlist__44u6__p9_0,
- 1, -514071552, 1627381760, 4, 0,
- _vq_quantlist__44u6__p9_0,
- NULL,
- &_vq_auxt__44u6__p9_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u6__p9_1[] = {
- 7,
- 6,
- 8,
- 5,
- 9,
- 4,
- 10,
- 3,
- 11,
- 2,
- 12,
- 1,
- 13,
- 0,
- 14,
- };
-
- static long _vq_lengthlist__44u6__p9_1[] = {
- 1, 4, 4, 7, 7, 8, 9, 8, 8, 9, 8, 9, 8, 9, 9, 4,
- 7, 6, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 4, 7,
- 6, 9, 9,10,10, 9, 9,10,10,10,10,11,11, 7, 9, 8,
- 10,10,11,11,10,10,11,11,11,11,11,11, 7, 8, 9,10,
- 10,11,11,10,10,11,11,11,11,11,12, 8,10,10,11,11,
- 12,12,11,11,12,12,12,12,13,12, 8,10,10,11,11,12,
- 11,11,11,11,12,12,12,12,13, 8, 9, 9,11,10,11,11,
- 12,12,12,12,13,12,13,12, 8, 9, 9,11,11,11,11,12,
- 12,12,12,12,13,13,13, 9,10,10,11,12,12,12,12,12,
- 13,13,13,13,13,13, 9,10,10,11,11,12,12,12,12,13,
- 13,13,13,14,13,10,10,10,12,11,12,12,13,13,13,13,
- 13,13,13,13,10,10,11,11,11,12,12,13,13,13,13,13,
- 13,13,13,10,11,11,12,12,13,12,12,13,13,13,13,13,
- 13,14,10,11,11,12,12,13,12,13,13,13,14,13,13,14,
- 13,
- };
-
- static float _vq_quantthresh__44u6__p9_1[] = {
- -110.5, -93.5, -76.5, -59.5, -42.5, -25.5, -8.5, 8.5,
- 25.5, 42.5, 59.5, 76.5, 93.5, 110.5,
- };
-
- static long _vq_quantmap__44u6__p9_1[] = {
- 13, 11, 9, 7, 5, 3, 1, 0,
- 2, 4, 6, 8, 10, 12, 14,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u6__p9_1 = {
- _vq_quantthresh__44u6__p9_1,
- _vq_quantmap__44u6__p9_1,
- 15,
- 15
- };
-
- static static_codebook _44u6__p9_1 = {
- 2, 225,
- _vq_lengthlist__44u6__p9_1,
- 1, -522338304, 1620115456, 4, 0,
- _vq_quantlist__44u6__p9_1,
- NULL,
- &_vq_auxt__44u6__p9_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u6__p9_2[] = {
- 8,
- 7,
- 9,
- 6,
- 10,
- 5,
- 11,
- 4,
- 12,
- 3,
- 13,
- 2,
- 14,
- 1,
- 15,
- 0,
- 16,
- };
-
- static long _vq_lengthlist__44u6__p9_2[] = {
- 3, 5, 5, 7, 7, 8, 8, 8, 8, 8, 8, 9, 8, 8, 9, 9,
- 9, 5, 6, 6, 7, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9,
- 9, 9, 5, 6, 6, 7, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9,
- 9, 9, 9, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9,10, 9, 8, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9,10,10, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9,10, 9, 9, 9,10, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9,10, 9, 9, 9,10, 9, 9,10, 9,
- 9, 9, 9, 9, 9, 9, 9, 9,10,10,10, 9,10, 9,10,10,
- 9, 9, 9, 9, 9, 9, 9, 9, 9,10,10, 9,10,10, 9, 9,
- 10,
- };
-
- static float _vq_quantthresh__44u6__p9_2[] = {
- -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5,
- 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5,
- };
-
- static long _vq_quantmap__44u6__p9_2[] = {
- 15, 13, 11, 9, 7, 5, 3, 1,
- 0, 2, 4, 6, 8, 10, 12, 14,
- 16,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u6__p9_2 = {
- _vq_quantthresh__44u6__p9_2,
- _vq_quantmap__44u6__p9_2,
- 17,
- 17
- };
-
- static static_codebook _44u6__p9_2 = {
- 2, 289,
- _vq_lengthlist__44u6__p9_2,
- 1, -529530880, 1611661312, 5, 0,
- _vq_quantlist__44u6__p9_2,
- NULL,
- &_vq_auxt__44u6__p9_2,
- NULL,
- 0
- };
-
- static long _huff_lengthlist__44u6__short[] = {
- 4,11,16,13,17,13,17,16,17,17, 4, 7, 9, 9,13,10,
- 16,12,16,17, 7, 6, 5, 7, 8, 9,12,12,16,17, 6, 9,
- 7, 9,10,10,15,15,17,17, 6, 7, 5, 7, 5, 7, 7,10,
- 16,17, 7, 9, 8, 9, 8,10,11,11,15,17, 7, 7, 7, 8,
- 5, 8, 8, 9,15,17, 8, 7, 9, 9, 7, 8, 7, 2, 7,15,
- 14,13,13,15, 5,10, 4, 3, 6,17,17,15,13,17, 7,11,
- 7, 6, 9,16,
- };
-
- static static_codebook _huff_book__44u6__short = {
- 2, 100,
- _huff_lengthlist__44u6__short,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist__44u7__long[] = {
- 3, 9,14,13,15,14,16,13,13,14, 5, 5, 7, 7, 8, 9,
- 11,10,12,15,10, 6, 5, 6, 6, 9,10,10,13,16,10, 6,
- 6, 6, 6, 8, 9, 9,12,15,14, 7, 6, 6, 5, 6, 6, 8,
- 12,15,10, 8, 7, 7, 6, 7, 7, 7,11,13,14,10, 9, 8,
- 5, 6, 4, 5, 9,12,10, 9, 9, 8, 6, 6, 5, 3, 6,11,
- 12,11,12,12,10, 9, 8, 5, 5, 8,10,11,15,13,13,13,
- 12, 8, 6, 7,
- };
-
- static static_codebook _huff_book__44u7__long = {
- 2, 100,
- _huff_lengthlist__44u7__long,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u7__p1_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__44u7__p1_0[] = {
- 1, 4, 4, 4, 7, 7, 5, 7, 7, 5, 8, 8, 8,10,10, 7,
- 10,10, 5, 8, 8, 7,10,10, 8,10,10, 5, 8, 8, 8,11,
- 10, 8,10,10, 8,10,10,10,12,13,10,13,13, 7,10,10,
- 10,13,12,10,13,13, 5, 8, 8, 8,11,10, 8,10,11, 7,
- 10,10,10,13,13,10,12,13, 8,11,11,10,13,13,10,13,
- 12,
- };
-
- static float _vq_quantthresh__44u7__p1_0[] = {
- -0.5, 0.5,
- };
-
- static long _vq_quantmap__44u7__p1_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u7__p1_0 = {
- _vq_quantthresh__44u7__p1_0,
- _vq_quantmap__44u7__p1_0,
- 3,
- 3
- };
-
- static static_codebook _44u7__p1_0 = {
- 4, 81,
- _vq_lengthlist__44u7__p1_0,
- 1, -535822336, 1611661312, 2, 0,
- _vq_quantlist__44u7__p1_0,
- NULL,
- &_vq_auxt__44u7__p1_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u7__p2_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__44u7__p2_0[] = {
- 3, 4, 4, 5, 6, 6, 5, 6, 6, 5, 6, 6, 6, 8, 8, 6,
- 7, 8, 5, 6, 6, 6, 8, 7, 6, 8, 8, 5, 6, 6, 6, 8,
- 7, 6, 8, 8, 6, 8, 8, 8, 9, 9, 8, 9, 9, 6, 8, 7,
- 7, 9, 8, 8, 9, 9, 5, 6, 6, 6, 8, 7, 6, 8, 8, 6,
- 8, 8, 8, 9, 9, 7, 8, 9, 6, 8, 8, 8, 9, 9, 8, 9,
- 9,
- };
-
- static float _vq_quantthresh__44u7__p2_0[] = {
- -0.5, 0.5,
- };
-
- static long _vq_quantmap__44u7__p2_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u7__p2_0 = {
- _vq_quantthresh__44u7__p2_0,
- _vq_quantmap__44u7__p2_0,
- 3,
- 3
- };
-
- static static_codebook _44u7__p2_0 = {
- 4, 81,
- _vq_lengthlist__44u7__p2_0,
- 1, -535822336, 1611661312, 2, 0,
- _vq_quantlist__44u7__p2_0,
- NULL,
- &_vq_auxt__44u7__p2_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u7__p3_0[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__44u7__p3_0[] = {
- 2, 5, 4, 8, 8, 5, 7, 6, 9, 9, 5, 6, 7, 9, 9, 8,
- 9, 9,13,12, 8, 9,10,12,13, 5, 7, 7,10, 9, 7, 9,
- 9,11,11, 6, 8, 9,11,11,10,11,11,14,14, 9,10,11,
- 13,14, 5, 7, 7, 9, 9, 7, 9, 8,11,11, 7, 9, 9,11,
- 11, 9,11,10,14,13,10,11,11,14,14, 8,10,10,14,13,
- 10,11,12,15,14, 9,11,11,15,14,13,14,14,16,16,12,
- 13,14,17,16, 8,10,10,13,13, 9,11,11,14,15,10,11,
- 12,14,15,12,14,13,16,16,13,14,15,15,17, 5, 7, 7,
- 10,10, 7, 9, 9,11,11, 7, 9, 9,11,11,10,12,11,15,
- 14,10,11,12,14,14, 7, 9, 9,12,12, 9,11,11,13,13,
- 9,11,11,13,13,11,13,13,14,17,11,13,13,15,16, 6,
- 9, 9,11,11, 8,11,10,13,12, 9,11,11,13,13,11,13,
- 12,16,14,11,13,13,16,16,10,12,12,15,15,11,13,13,
- 16,16,11,13,13,16,15,14,16,17,17,19,14,16,16,18,
- 0, 9,11,11,14,15,10,13,12,16,15,11,13,13,16,16,
- 14,15,14, 0,16,14,16,16,18, 0, 5, 7, 7,10,10, 7,
- 9, 9,12,11, 7, 9, 9,11,12,10,11,11,15,14,10,11,
- 12,14,14, 6, 9, 9,11,11, 9,11,11,13,13, 8,10,11,
- 12,13,11,13,13,17,15,11,12,13,14,15, 7, 9, 9,11,
- 12, 9,11,11,13,13, 9,11,11,13,13,11,13,12,16,16,
- 11,13,13,15,14, 9,11,11,14,15,11,13,13,16,15,10,
- 12,13,16,16,15,16,16, 0, 0,14,13,15,16,18,10,11,
- 11,15,15,11,13,14,16,18,11,13,13,16,15,15,16,16,
- 19, 0,14,15,15,16,16, 8,10,10,13,13,10,12,11,16,
- 15,10,11,11,16,15,13,15,16,18, 0,13,14,15,17,17,
- 9,11,11,15,15,11,13,13,16,18,11,13,13,16,17,15,
- 16,16, 0, 0,15,18,16, 0,17, 9,11,11,15,15,11,13,
- 12,17,15,11,13,14,16,17,15,18,15, 0,17,15,16,16,
- 18,19,13,15,14, 0,18,14,16,16,19,18,14,16,15,19,
- 19,16,18,19, 0, 0,16,17, 0, 0, 0,12,14,14,17,17,
- 13,16,14, 0,18,14,16,15,18, 0,16,18,16,19,17,18,
- 19,17, 0, 0, 8,10,10,14,14, 9,12,11,15,15,10,11,
- 12,15,17,13,15,15,18,16,14,16,15,18,17, 9,11,11,
- 16,15,11,13,13, 0,16,11,12,13,16,15,15,16,16, 0,
- 17,15,15,16,18,17, 9,12,11,15,17,11,13,13,16,16,
- 11,14,13,16,16,15,15,16,18,19,16,18,16, 0, 0,12,
- 14,14, 0,16,14,16,16, 0,18,13,14,15,16, 0,17,16,
- 18, 0, 0,16,16,17,19, 0,13,14,14,17, 0,14,17,16,
- 0,19,14,15,15,18,19,17,16,18, 0, 0,15,19,16, 0,
- 0,
- };
-
- static float _vq_quantthresh__44u7__p3_0[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__44u7__p3_0[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u7__p3_0 = {
- _vq_quantthresh__44u7__p3_0,
- _vq_quantmap__44u7__p3_0,
- 5,
- 5
- };
-
- static static_codebook _44u7__p3_0 = {
- 4, 625,
- _vq_lengthlist__44u7__p3_0,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__44u7__p3_0,
- NULL,
- &_vq_auxt__44u7__p3_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u7__p4_0[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__44u7__p4_0[] = {
- 4, 5, 5, 8, 8, 6, 7, 6, 9, 9, 6, 6, 7, 9, 9, 8,
- 9, 9,11,11, 8, 9, 9,10,11, 6, 7, 7, 9, 9, 7, 8,
- 8,10,10, 6, 7, 8, 9,10, 9,10,10,12,12, 9, 9,10,
- 11,12, 6, 7, 7, 9, 9, 6, 8, 7,10, 9, 7, 8, 8,10,
- 10, 9,10, 9,12,11, 9,10,10,12,11, 8, 9, 9,11,11,
- 9,10,10,12,12, 9,10,10,12,12,11,12,12,13,14,11,
- 11,12,13,13, 8, 9, 9,11,11, 9,10,10,12,11, 9,10,
- 10,12,12,11,12,11,13,13,11,12,12,13,13, 6, 7, 7,
- 9, 9, 7, 8, 7,10,10, 7, 7, 8,10,10, 9,10,10,12,
- 11, 9,10,10,12,12, 7, 8, 8,10,10, 8, 8, 9,11,11,
- 8, 9, 9,11,11,10,11,11,12,12,10,10,11,12,13, 6,
- 7, 7,10,10, 7, 9, 8,11,10, 8, 8, 9,10,11,10,11,
- 10,13,11,10,11,11,12,12, 9,10,10,12,12,10,10,11,
- 13,13,10,11,11,13,12,12,12,13,13,14,12,12,13,14,
- 14, 9,10,10,12,12, 9,10,10,12,12,10,11,11,13,13,
- 11,12,11,14,12,12,13,13,14,14, 6, 7, 7, 9, 9, 7,
- 8, 7,10,10, 7, 7, 8,10,10, 9,10,10,12,11, 9,10,
- 10,11,12, 6, 7, 7,10,10, 8, 9, 8,11,10, 7, 8, 9,
- 10,11,10,11,11,13,12,10,10,11,11,13, 7, 8, 8,10,
- 10, 8, 9, 9,11,11, 8, 9, 9,11,11,10,11,10,13,12,
- 10,11,11,12,12, 9,10,10,12,12,10,11,11,13,12, 9,
- 10,10,12,13,12,13,12,14,14,11,11,12,12,14, 9,10,
- 10,12,12,10,11,11,13,13,10,11,11,13,13,12,13,12,
- 14,14,12,13,12,14,13, 8, 9, 9,11,11, 9,10,10,12,
- 12, 9,10,10,12,12,11,12,12,14,13,11,12,12,13,13,
- 9,10,10,12,12,10,11,11,13,13,10,11,11,13,12,12,
- 13,13,14,14,12,12,13,14,14, 9,10,10,12,12, 9,11,
- 10,13,12,10,10,11,12,13,11,13,12,14,13,12,12,13,
- 14,14,11,12,12,13,13,11,12,13,14,14,12,13,13,14,
- 14,13,13,14,14,16,13,14,14,16,16,11,11,11,13,13,
- 11,12,11,14,13,12,12,13,14,15,13,14,12,16,13,14,
- 14,14,15,16, 8, 9, 9,11,11, 9,10,10,12,12, 9,10,
- 10,12,12,11,12,12,14,13,11,12,12,13,14, 9,10,10,
- 12,12,10,11,10,13,12, 9,10,11,12,13,12,13,12,14,
- 14,12,12,13,13,14, 9,10,10,12,12,10,11,11,12,13,
- 10,11,11,13,13,12,13,12,14,14,12,13,13,14,14,11,
- 12,12,13,13,12,13,12,14,14,11,11,12,13,14,13,15,
- 14,16,15,13,12,14,13,16,11,12,12,13,13,12,13,13,
- 14,14,12,12,12,14,14,13,14,14,15,15,13,14,13,16,
- 14,
- };
-
- static float _vq_quantthresh__44u7__p4_0[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__44u7__p4_0[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u7__p4_0 = {
- _vq_quantthresh__44u7__p4_0,
- _vq_quantmap__44u7__p4_0,
- 5,
- 5
- };
-
- static static_codebook _44u7__p4_0 = {
- 4, 625,
- _vq_lengthlist__44u7__p4_0,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__44u7__p4_0,
- NULL,
- &_vq_auxt__44u7__p4_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u7__p5_0[] = {
- 4,
- 3,
- 5,
- 2,
- 6,
- 1,
- 7,
- 0,
- 8,
- };
-
- static long _vq_lengthlist__44u7__p5_0[] = {
- 2, 3, 3, 6, 6, 7, 8,10,10, 4, 5, 5, 8, 7, 8, 8,
- 11,11, 3, 5, 5, 7, 7, 8, 9,11,11, 6, 8, 7, 9, 9,
- 10,10,12,12, 6, 7, 8, 9,10,10,10,12,12, 8, 8, 8,
- 10,10,12,11,13,13, 8, 8, 9,10,10,11,11,13,13,10,
- 11,11,12,12,13,13,14,14,10,11,11,12,12,13,13,14,
- 14,
- };
-
- static float _vq_quantthresh__44u7__p5_0[] = {
- -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5,
- };
-
- static long _vq_quantmap__44u7__p5_0[] = {
- 7, 5, 3, 1, 0, 2, 4, 6,
- 8,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u7__p5_0 = {
- _vq_quantthresh__44u7__p5_0,
- _vq_quantmap__44u7__p5_0,
- 9,
- 9
- };
-
- static static_codebook _44u7__p5_0 = {
- 2, 81,
- _vq_lengthlist__44u7__p5_0,
- 1, -531628032, 1611661312, 4, 0,
- _vq_quantlist__44u7__p5_0,
- NULL,
- &_vq_auxt__44u7__p5_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u7__p6_0[] = {
- 4,
- 3,
- 5,
- 2,
- 6,
- 1,
- 7,
- 0,
- 8,
- };
-
- static long _vq_lengthlist__44u7__p6_0[] = {
- 3, 4, 4, 5, 5, 7, 7, 9, 9, 4, 5, 4, 6, 6, 8, 7,
- 9, 9, 4, 4, 5, 6, 6, 7, 7, 9, 9, 5, 6, 6, 7, 7,
- 8, 8,10,10, 5, 6, 6, 7, 7, 8, 8,10,10, 7, 8, 7,
- 8, 8,10, 9,11,11, 7, 7, 8, 8, 8, 9,10,11,11, 9,
- 9, 9,10,10,11,10,12,11, 9, 9, 9,10,10,11,11,11,
- 12,
- };
-
- static float _vq_quantthresh__44u7__p6_0[] = {
- -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5,
- };
-
- static long _vq_quantmap__44u7__p6_0[] = {
- 7, 5, 3, 1, 0, 2, 4, 6,
- 8,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u7__p6_0 = {
- _vq_quantthresh__44u7__p6_0,
- _vq_quantmap__44u7__p6_0,
- 9,
- 9
- };
-
- static static_codebook _44u7__p6_0 = {
- 2, 81,
- _vq_lengthlist__44u7__p6_0,
- 1, -531628032, 1611661312, 4, 0,
- _vq_quantlist__44u7__p6_0,
- NULL,
- &_vq_auxt__44u7__p6_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u7__p7_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__44u7__p7_0[] = {
- 1, 4, 4, 5, 7, 7, 5, 7, 7, 5, 9, 8, 8, 9, 9, 7,
- 10,10, 5, 8, 9, 7, 9,10, 8, 9, 9, 4, 9, 9, 9,11,
- 10, 8,10,10, 7,11,10,10,10,12,10,12,12, 7,10,10,
- 10,12,11,10,12,12, 5, 9, 9, 8,10,10, 9,11,11, 7,
- 11,10,10,12,12,10,11,12, 7,10,11,10,12,12,10,12,
- 10,
- };
-
- static float _vq_quantthresh__44u7__p7_0[] = {
- -5.5, 5.5,
- };
-
- static long _vq_quantmap__44u7__p7_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u7__p7_0 = {
- _vq_quantthresh__44u7__p7_0,
- _vq_quantmap__44u7__p7_0,
- 3,
- 3
- };
-
- static static_codebook _44u7__p7_0 = {
- 4, 81,
- _vq_lengthlist__44u7__p7_0,
- 1, -529137664, 1618345984, 2, 0,
- _vq_quantlist__44u7__p7_0,
- NULL,
- &_vq_auxt__44u7__p7_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u7__p7_1[] = {
- 5,
- 4,
- 6,
- 3,
- 7,
- 2,
- 8,
- 1,
- 9,
- 0,
- 10,
- };
-
- static long _vq_lengthlist__44u7__p7_1[] = {
- 3, 4, 4, 6, 6, 7, 7, 8, 8, 8, 8, 4, 5, 5, 6, 6,
- 8, 7, 8, 8, 8, 8, 4, 5, 5, 6, 6, 7, 8, 8, 8, 8,
- 8, 6, 7, 6, 7, 7, 8, 8, 9, 9, 9, 9, 6, 6, 7, 7,
- 7, 8, 8, 9, 9, 9, 9, 7, 8, 7, 8, 8, 9, 9, 9, 9,
- 9, 9, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9, 9, 8, 8, 8,
- 9, 9, 9, 9,10, 9, 9, 9, 8, 8, 8, 9, 9, 9, 9, 9,
- 9, 9,10, 8, 8, 8, 9, 9, 9, 9,10, 9,10,10, 8, 8,
- 8, 9, 9, 9, 9, 9,10,10,10,
- };
-
- static float _vq_quantthresh__44u7__p7_1[] = {
- -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5,
- 3.5, 4.5,
- };
-
- static long _vq_quantmap__44u7__p7_1[] = {
- 9, 7, 5, 3, 1, 0, 2, 4,
- 6, 8, 10,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u7__p7_1 = {
- _vq_quantthresh__44u7__p7_1,
- _vq_quantmap__44u7__p7_1,
- 11,
- 11
- };
-
- static static_codebook _44u7__p7_1 = {
- 2, 121,
- _vq_lengthlist__44u7__p7_1,
- 1, -531365888, 1611661312, 4, 0,
- _vq_quantlist__44u7__p7_1,
- NULL,
- &_vq_auxt__44u7__p7_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u7__p8_0[] = {
- 5,
- 4,
- 6,
- 3,
- 7,
- 2,
- 8,
- 1,
- 9,
- 0,
- 10,
- };
-
- static long _vq_lengthlist__44u7__p8_0[] = {
- 1, 4, 4, 6, 6, 8, 8,10,10,11,11, 4, 6, 6, 7, 7,
- 9, 9,11,10,12,12, 5, 6, 5, 7, 7, 9, 9,10,11,12,
- 12, 6, 7, 7, 8, 8,10,10,11,11,13,13, 6, 7, 7, 8,
- 8,10,10,11,12,13,13, 8, 9, 9,10,10,11,11,12,12,
- 14,14, 8, 9, 9,10,10,11,11,12,12,14,14,10,10,10,
- 11,11,13,12,14,14,15,15,10,10,10,12,12,13,13,14,
- 14,15,15,11,12,12,13,13,14,14,15,14,16,15,11,12,
- 12,13,13,14,14,15,15,15,16,
- };
-
- static float _vq_quantthresh__44u7__p8_0[] = {
- -49.5, -38.5, -27.5, -16.5, -5.5, 5.5, 16.5, 27.5,
- 38.5, 49.5,
- };
-
- static long _vq_quantmap__44u7__p8_0[] = {
- 9, 7, 5, 3, 1, 0, 2, 4,
- 6, 8, 10,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u7__p8_0 = {
- _vq_quantthresh__44u7__p8_0,
- _vq_quantmap__44u7__p8_0,
- 11,
- 11
- };
-
- static static_codebook _44u7__p8_0 = {
- 2, 121,
- _vq_lengthlist__44u7__p8_0,
- 1, -524582912, 1618345984, 4, 0,
- _vq_quantlist__44u7__p8_0,
- NULL,
- &_vq_auxt__44u7__p8_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u7__p8_1[] = {
- 5,
- 4,
- 6,
- 3,
- 7,
- 2,
- 8,
- 1,
- 9,
- 0,
- 10,
- };
-
- static long _vq_lengthlist__44u7__p8_1[] = {
- 4, 5, 5, 6, 6, 7, 7, 7, 7, 7, 7, 5, 6, 6, 7, 7,
- 7, 7, 7, 7, 7, 7, 5, 6, 6, 6, 7, 7, 7, 7, 7, 7,
- 7, 6, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 6, 7, 7, 7,
- 7, 7, 7, 7, 7, 8, 8, 7, 7, 7, 7, 7, 8, 7, 8, 8,
- 8, 8, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 7, 7, 7,
- 7, 7, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 8, 8, 8,
- 8, 8, 8, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7,
- 7, 8, 8, 8, 8, 8, 8, 8, 8,
- };
-
- static float _vq_quantthresh__44u7__p8_1[] = {
- -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5,
- 3.5, 4.5,
- };
-
- static long _vq_quantmap__44u7__p8_1[] = {
- 9, 7, 5, 3, 1, 0, 2, 4,
- 6, 8, 10,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u7__p8_1 = {
- _vq_quantthresh__44u7__p8_1,
- _vq_quantmap__44u7__p8_1,
- 11,
- 11
- };
-
- static static_codebook _44u7__p8_1 = {
- 2, 121,
- _vq_lengthlist__44u7__p8_1,
- 1, -531365888, 1611661312, 4, 0,
- _vq_quantlist__44u7__p8_1,
- NULL,
- &_vq_auxt__44u7__p8_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u7__p9_0[] = {
- 5,
- 4,
- 6,
- 3,
- 7,
- 2,
- 8,
- 1,
- 9,
- 0,
- 10,
- };
-
- static long _vq_lengthlist__44u7__p9_0[] = {
- 1, 3, 3,10,10,10,10,10,10,10,10, 4,10,10,10,10,
- 10,10,10,10,10,10, 4,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9,
- };
-
- static float _vq_quantthresh__44u7__p9_0[] = {
- -2866.5, -2229.5, -1592.5, -955.5, -318.5, 318.5, 955.5, 1592.5,
- 2229.5, 2866.5,
- };
-
- static long _vq_quantmap__44u7__p9_0[] = {
- 9, 7, 5, 3, 1, 0, 2, 4,
- 6, 8, 10,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u7__p9_0 = {
- _vq_quantthresh__44u7__p9_0,
- _vq_quantmap__44u7__p9_0,
- 11,
- 11
- };
-
- static static_codebook _44u7__p9_0 = {
- 2, 121,
- _vq_lengthlist__44u7__p9_0,
- 1, -512171520, 1630791680, 4, 0,
- _vq_quantlist__44u7__p9_0,
- NULL,
- &_vq_auxt__44u7__p9_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u7__p9_1[] = {
- 6,
- 5,
- 7,
- 4,
- 8,
- 3,
- 9,
- 2,
- 10,
- 1,
- 11,
- 0,
- 12,
- };
-
- static long _vq_lengthlist__44u7__p9_1[] = {
- 1, 4, 4, 6, 5, 8, 6, 9, 8,10, 9,11,10, 4, 6, 6,
- 8, 8, 9, 9,11,10,11,11,11,11, 4, 6, 6, 8, 8,10,
- 9,11,11,11,11,11,12, 6, 8, 8,10,10,11,11,12,12,
- 13,12,13,13, 6, 8, 8,10,10,11,11,12,12,12,13,14,
- 13, 8,10,10,11,11,12,13,14,14,14,14,15,15, 8,10,
- 10,11,12,12,13,13,14,14,14,14,15, 9,11,11,13,13,
- 14,14,15,14,16,15,17,15, 9,11,11,12,13,14,14,15,
- 14,15,15,15,16,10,12,12,13,14,15,15,15,15,16,17,
- 16,17,10,13,12,13,14,14,16,16,16,16,15,16,17,11,
- 13,13,14,15,14,17,15,16,17,17,17,17,11,13,13,14,
- 15,15,15,15,17,17,16,17,16,
- };
-
- static float _vq_quantthresh__44u7__p9_1[] = {
- -269.5, -220.5, -171.5, -122.5, -73.5, -24.5, 24.5, 73.5,
- 122.5, 171.5, 220.5, 269.5,
- };
-
- static long _vq_quantmap__44u7__p9_1[] = {
- 11, 9, 7, 5, 3, 1, 0, 2,
- 4, 6, 8, 10, 12,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u7__p9_1 = {
- _vq_quantthresh__44u7__p9_1,
- _vq_quantmap__44u7__p9_1,
- 13,
- 13
- };
-
- static static_codebook _44u7__p9_1 = {
- 2, 169,
- _vq_lengthlist__44u7__p9_1,
- 1, -518889472, 1622704128, 4, 0,
- _vq_quantlist__44u7__p9_1,
- NULL,
- &_vq_auxt__44u7__p9_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u7__p9_2[] = {
- 24,
- 23,
- 25,
- 22,
- 26,
- 21,
- 27,
- 20,
- 28,
- 19,
- 29,
- 18,
- 30,
- 17,
- 31,
- 16,
- 32,
- 15,
- 33,
- 14,
- 34,
- 13,
- 35,
- 12,
- 36,
- 11,
- 37,
- 10,
- 38,
- 9,
- 39,
- 8,
- 40,
- 7,
- 41,
- 6,
- 42,
- 5,
- 43,
- 4,
- 44,
- 3,
- 45,
- 2,
- 46,
- 1,
- 47,
- 0,
- 48,
- };
-
- static long _vq_lengthlist__44u7__p9_2[] = {
- 2, 4, 4, 4, 4, 5, 5, 5, 5, 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, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8,
- 8,
- };
-
- static float _vq_quantthresh__44u7__p9_2[] = {
- -23.5, -22.5, -21.5, -20.5, -19.5, -18.5, -17.5, -16.5,
- -15.5, -14.5, -13.5, -12.5, -11.5, -10.5, -9.5, -8.5,
- -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5,
- 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5,
- 8.5, 9.5, 10.5, 11.5, 12.5, 13.5, 14.5, 15.5,
- 16.5, 17.5, 18.5, 19.5, 20.5, 21.5, 22.5, 23.5,
- };
-
- static long _vq_quantmap__44u7__p9_2[] = {
- 47, 45, 43, 41, 39, 37, 35, 33,
- 31, 29, 27, 25, 23, 21, 19, 17,
- 15, 13, 11, 9, 7, 5, 3, 1,
- 0, 2, 4, 6, 8, 10, 12, 14,
- 16, 18, 20, 22, 24, 26, 28, 30,
- 32, 34, 36, 38, 40, 42, 44, 46,
- 48,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u7__p9_2 = {
- _vq_quantthresh__44u7__p9_2,
- _vq_quantmap__44u7__p9_2,
- 49,
- 49
- };
-
- static static_codebook _44u7__p9_2 = {
- 1, 49,
- _vq_lengthlist__44u7__p9_2,
- 1, -526909440, 1611661312, 6, 0,
- _vq_quantlist__44u7__p9_2,
- NULL,
- &_vq_auxt__44u7__p9_2,
- NULL,
- 0
- };
-
- static long _huff_lengthlist__44u7__short[] = {
- 5,12,17,16,16,17,17,17,17,17, 4, 7,11,11,12, 9,
- 17,10,17,17, 7, 7, 8, 9, 7, 9,11,10,15,17, 7, 9,
- 10,11,10,12,14,12,16,17, 7, 8, 5, 7, 4, 7, 7, 8,
- 16,16, 6,10, 9,10, 7,10,11,11,16,17, 6, 8, 8, 9,
- 5, 7, 5, 8,16,17, 5, 5, 8, 7, 6, 7, 7, 6, 6,14,
- 12,10,12,11, 7,11, 4, 4, 2, 7,17,15,15,15, 8,15,
- 6, 8, 5, 9,
- };
-
- static static_codebook _huff_book__44u7__short = {
- 2, 100,
- _huff_lengthlist__44u7__short,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist__44u8__long[] = {
- 3, 9,13,14,14,15,14,14,15,15, 5, 4, 6, 8,10,12,
- 12,14,15,15, 9, 5, 4, 5, 8,10,11,13,16,16,10, 7,
- 4, 3, 5, 7, 9,11,13,13,10, 9, 7, 4, 4, 6, 8,10,
- 12,14,13,11, 9, 6, 5, 5, 6, 8,12,14,13,11,10, 8,
- 7, 6, 6, 7,10,14,13,11,12,10, 8, 7, 6, 6, 9,13,
- 12,11,14,12,11, 9, 8, 7, 9,11,11,12,14,13,14,11,
- 10, 8, 8, 9,
- };
-
- static static_codebook _huff_book__44u8__long = {
- 2, 100,
- _huff_lengthlist__44u8__long,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist__44u8__short[] = {
- 6,14,18,18,17,17,17,17,17,17, 4, 7, 9, 9,10,13,
- 15,17,17,17, 6, 7, 5, 6, 8,11,16,17,16,17, 5, 7,
- 5, 4, 6,10,14,17,17,17, 6, 6, 6, 5, 7,10,13,16,
- 17,17, 7, 6, 7, 7, 7, 8, 7,10,15,16,12, 9, 9, 6,
- 6, 5, 3, 5,11,15,14,14,13, 5, 5, 7, 3, 4, 8,15,
- 17,17,13, 7, 7,10, 6, 6,10,15,17,17,16,10,11,14,
- 10,10,15,17,
- };
-
- static static_codebook _huff_book__44u8__short = {
- 2, 100,
- _huff_lengthlist__44u8__short,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u8_p1_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__44u8_p1_0[] = {
- 1, 5, 5, 5, 7, 7, 5, 7, 7, 5, 7, 7, 8, 9, 9, 7,
- 9, 9, 5, 7, 7, 7, 9, 9, 8, 9, 9, 5, 7, 7, 7, 9,
- 9, 7, 9, 9, 7, 9, 9, 9,10,11, 9,11,10, 7, 9, 9,
- 9,11,10, 9,10,11, 5, 7, 7, 7, 9, 9, 7, 9, 9, 7,
- 9, 9, 9,11,10, 9,10,10, 8, 9, 9, 9,11,11, 9,11,
- 10,
- };
-
- static float _vq_quantthresh__44u8_p1_0[] = {
- -0.5, 0.5,
- };
-
- static long _vq_quantmap__44u8_p1_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u8_p1_0 = {
- _vq_quantthresh__44u8_p1_0,
- _vq_quantmap__44u8_p1_0,
- 3,
- 3
- };
-
- static static_codebook _44u8_p1_0 = {
- 4, 81,
- _vq_lengthlist__44u8_p1_0,
- 1, -535822336, 1611661312, 2, 0,
- _vq_quantlist__44u8_p1_0,
- NULL,
- &_vq_auxt__44u8_p1_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u8_p2_0[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__44u8_p2_0[] = {
- 4, 5, 5, 8, 8, 5, 7, 6, 9, 9, 5, 6, 7, 9, 9, 8,
- 9, 9,11,11, 8, 9, 9,11,11, 5, 7, 7, 9, 9, 7, 8,
- 8,10,10, 7, 8, 8,10,10, 9,10,10,12,12, 9,10,10,
- 11,12, 5, 7, 7, 9, 9, 7, 8, 7,10,10, 7, 8, 8,10,
- 10, 9,10, 9,12,11, 9,10,10,12,12, 8, 9, 9,12,11,
- 9,10,10,12,12, 9,10,10,12,12,11,12,12,14,14,11,
- 11,12,13,14, 8, 9, 9,11,11, 9,10,10,12,12, 9,10,
- 10,12,12,11,12,11,13,13,11,12,12,14,14, 5, 7, 7,
- 9, 9, 7, 8, 8,10,10, 7, 8, 8,10,10, 9,10,10,12,
- 12, 9,10,10,11,12, 7, 8, 8,10,10, 8, 9, 9,11,11,
- 8, 9, 9,11,11,10,11,11,12,13,10,11,11,12,13, 6,
- 8, 8,10,10, 8, 9, 8,11,10, 8, 9, 9,11,11,10,11,
- 10,13,12,10,11,11,13,13, 9,10,10,12,12,10,11,11,
- 13,13,10,11,11,13,13,12,12,13,13,14,12,13,13,14,
- 14, 9,10,10,12,12,10,11,10,13,12,10,11,11,13,13,
- 11,13,12,14,13,12,13,13,14,14, 5, 7, 7, 9, 9, 7,
- 8, 8,10,10, 7, 8, 8,10,10, 9,10,10,12,12, 9,10,
- 10,12,12, 7, 8, 8,10,10, 8, 9, 9,11,11, 8, 8, 9,
- 10,11,10,11,11,13,13,10,10,11,12,13, 7, 8, 8,10,
- 10, 8, 9, 9,11,11, 8, 9, 9,11,11,10,11,11,13,13,
- 10,11,11,13,12, 9,10,10,12,12,10,11,11,13,13,10,
- 10,11,12,13,12,13,13,14,14,12,12,13,13,14, 9,10,
- 10,12,12,10,11,11,13,13,10,11,11,13,13,12,13,13,
- 15,14,12,13,13,14,13, 8, 9, 9,11,11, 9,10,10,12,
- 12, 9,10,10,12,12,12,12,12,14,13,11,12,12,14,14,
- 9,10,10,12,12,10,11,11,13,13,10,11,11,13,13,12,
- 13,13,14,15,12,13,13,14,15, 9,10,10,12,12,10,11,
- 10,13,12,10,11,11,13,13,12,13,12,15,14,12,13,13,
- 14,15,11,12,12,14,14,12,13,13,14,14,12,13,13,15,
- 14,14,14,14,14,16,14,14,15,16,16,11,12,12,14,14,
- 11,12,12,14,14,12,13,13,14,15,13,14,13,16,14,14,
- 14,14,16,16, 8, 9, 9,11,11, 9,10,10,12,12, 9,10,
- 10,12,12,11,12,12,14,13,11,12,12,14,14, 9,10,10,
- 12,12,10,11,11,13,13,10,10,11,12,13,12,13,13,15,
- 14,12,12,13,13,14, 9,10,10,12,12,10,11,11,13,13,
- 10,11,11,13,13,12,13,13,14,14,12,13,13,15,14,11,
- 12,12,14,13,12,13,13,15,14,11,12,12,13,14,14,15,
- 14,16,15,13,13,14,13,16,11,12,12,14,14,12,13,13,
- 14,15,12,13,12,15,14,14,14,14,16,15,14,15,13,16,
- 14,
- };
-
- static float _vq_quantthresh__44u8_p2_0[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__44u8_p2_0[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u8_p2_0 = {
- _vq_quantthresh__44u8_p2_0,
- _vq_quantmap__44u8_p2_0,
- 5,
- 5
- };
-
- static static_codebook _44u8_p2_0 = {
- 4, 625,
- _vq_lengthlist__44u8_p2_0,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__44u8_p2_0,
- NULL,
- &_vq_auxt__44u8_p2_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u8_p3_0[] = {
- 4,
- 3,
- 5,
- 2,
- 6,
- 1,
- 7,
- 0,
- 8,
- };
-
- static long _vq_lengthlist__44u8_p3_0[] = {
- 3, 4, 4, 5, 5, 7, 7, 9, 9, 4, 5, 4, 6, 6, 7, 7,
- 9, 9, 4, 4, 5, 6, 6, 7, 7, 9, 9, 5, 6, 6, 7, 7,
- 8, 8,10,10, 6, 6, 6, 7, 7, 8, 8,10,10, 7, 7, 7,
- 8, 8, 9, 9,11,10, 7, 7, 7, 8, 8, 9, 9,10,11, 9,
- 9, 9,10,10,11,10,12,11, 9, 9, 9, 9,10,11,11,11,
- 12,
- };
-
- static float _vq_quantthresh__44u8_p3_0[] = {
- -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5,
- };
-
- static long _vq_quantmap__44u8_p3_0[] = {
- 7, 5, 3, 1, 0, 2, 4, 6,
- 8,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u8_p3_0 = {
- _vq_quantthresh__44u8_p3_0,
- _vq_quantmap__44u8_p3_0,
- 9,
- 9
- };
-
- static static_codebook _44u8_p3_0 = {
- 2, 81,
- _vq_lengthlist__44u8_p3_0,
- 1, -531628032, 1611661312, 4, 0,
- _vq_quantlist__44u8_p3_0,
- NULL,
- &_vq_auxt__44u8_p3_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u8_p4_0[] = {
- 8,
- 7,
- 9,
- 6,
- 10,
- 5,
- 11,
- 4,
- 12,
- 3,
- 13,
- 2,
- 14,
- 1,
- 15,
- 0,
- 16,
- };
-
- static long _vq_lengthlist__44u8_p4_0[] = {
- 4, 4, 4, 6, 6, 7, 7, 8, 8, 8, 8,10,10,11,11,11,
- 11, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9,10,10,11,11,
- 12,12, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9,10,10,11,
- 11,12,12, 6, 6, 6, 7, 7, 8, 8, 9, 9, 9, 9,10,10,
- 11,11,12,12, 6, 6, 6, 7, 7, 8, 8, 9, 9, 9, 9,10,
- 10,11,11,12,12, 7, 7, 7, 8, 8, 9, 8,10, 9,10, 9,
- 11,10,12,11,13,12, 7, 7, 7, 8, 8, 8, 9, 9,10, 9,
- 10,10,11,11,12,12,13, 8, 8, 8, 9, 9, 9, 9,10,10,
- 11,10,11,11,12,12,13,13, 8, 8, 8, 9, 9, 9,10,10,
- 10,10,11,11,11,12,12,12,13, 8, 9, 9, 9, 9,10, 9,
- 11,10,11,11,12,11,13,12,13,13, 8, 9, 9, 9, 9, 9,
- 10,10,11,11,11,11,12,12,13,13,13,10,10,10,10,10,
- 11,10,11,11,12,11,13,12,13,13,14,13,10,10,10,10,
- 10,10,11,11,11,11,12,12,13,13,13,13,14,11,11,11,
- 11,11,12,11,12,12,13,12,13,13,14,13,14,14,11,11,
- 11,11,11,11,12,12,12,12,13,13,13,13,14,14,14,11,
- 12,12,12,12,13,12,13,12,13,13,14,13,14,14,14,14,
- 11,12,12,12,12,12,12,13,13,13,13,13,14,14,14,14,
- 14,
- };
-
- static float _vq_quantthresh__44u8_p4_0[] = {
- -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5,
- 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5,
- };
-
- static long _vq_quantmap__44u8_p4_0[] = {
- 15, 13, 11, 9, 7, 5, 3, 1,
- 0, 2, 4, 6, 8, 10, 12, 14,
- 16,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u8_p4_0 = {
- _vq_quantthresh__44u8_p4_0,
- _vq_quantmap__44u8_p4_0,
- 17,
- 17
- };
-
- static static_codebook _44u8_p4_0 = {
- 2, 289,
- _vq_lengthlist__44u8_p4_0,
- 1, -529530880, 1611661312, 5, 0,
- _vq_quantlist__44u8_p4_0,
- NULL,
- &_vq_auxt__44u8_p4_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u8_p5_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__44u8_p5_0[] = {
- 1, 4, 4, 5, 7, 7, 5, 7, 7, 5, 8, 8, 8, 9, 9, 7,
- 9, 9, 5, 8, 8, 7, 9, 9, 8, 9, 9, 5, 8, 8, 8,10,
- 10, 8,10,10, 7,10,10, 9,10,12, 9,12,11, 7,10,10,
- 9,11,10, 9,11,12, 5, 8, 8, 8,10,10, 8,10,10, 7,
- 10,10, 9,11,11, 9,10,11, 7,10,10, 9,11,11,10,12,
- 10,
- };
-
- static float _vq_quantthresh__44u8_p5_0[] = {
- -5.5, 5.5,
- };
-
- static long _vq_quantmap__44u8_p5_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u8_p5_0 = {
- _vq_quantthresh__44u8_p5_0,
- _vq_quantmap__44u8_p5_0,
- 3,
- 3
- };
-
- static static_codebook _44u8_p5_0 = {
- 4, 81,
- _vq_lengthlist__44u8_p5_0,
- 1, -529137664, 1618345984, 2, 0,
- _vq_quantlist__44u8_p5_0,
- NULL,
- &_vq_auxt__44u8_p5_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u8_p5_1[] = {
- 5,
- 4,
- 6,
- 3,
- 7,
- 2,
- 8,
- 1,
- 9,
- 0,
- 10,
- };
-
- static long _vq_lengthlist__44u8_p5_1[] = {
- 4, 5, 5, 6, 6, 7, 7, 7, 7, 8, 8, 5, 5, 5, 6, 6,
- 7, 7, 8, 8, 8, 8, 5, 5, 5, 6, 6, 7, 7, 7, 8, 8,
- 8, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 6, 6, 6, 7,
- 7, 7, 7, 8, 8, 8, 8, 7, 7, 7, 7, 7, 8, 8, 8, 8,
- 8, 8, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 7, 8, 7,
- 8, 8, 8, 8, 8, 8, 8, 8, 7, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 9, 9,
- };
-
- static float _vq_quantthresh__44u8_p5_1[] = {
- -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5,
- 3.5, 4.5,
- };
-
- static long _vq_quantmap__44u8_p5_1[] = {
- 9, 7, 5, 3, 1, 0, 2, 4,
- 6, 8, 10,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u8_p5_1 = {
- _vq_quantthresh__44u8_p5_1,
- _vq_quantmap__44u8_p5_1,
- 11,
- 11
- };
-
- static static_codebook _44u8_p5_1 = {
- 2, 121,
- _vq_lengthlist__44u8_p5_1,
- 1, -531365888, 1611661312, 4, 0,
- _vq_quantlist__44u8_p5_1,
- NULL,
- &_vq_auxt__44u8_p5_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u8_p6_0[] = {
- 6,
- 5,
- 7,
- 4,
- 8,
- 3,
- 9,
- 2,
- 10,
- 1,
- 11,
- 0,
- 12,
- };
-
- static long _vq_lengthlist__44u8_p6_0[] = {
- 2, 4, 4, 6, 6, 7, 7, 8, 8, 9, 9,10,10, 4, 6, 5,
- 7, 7, 8, 8, 8, 8, 9, 9,10,10, 4, 6, 6, 7, 7, 8,
- 8, 8, 8, 9, 9,10,10, 6, 7, 7, 7, 8, 8, 8, 8, 9,
- 9,10,10,10, 6, 7, 7, 8, 8, 8, 8, 9, 8,10, 9,11,
- 10, 7, 8, 8, 8, 8, 8, 9, 9, 9,10,10,11,11, 7, 8,
- 8, 8, 8, 9, 8, 9, 9,10,10,11,11, 8, 8, 8, 9, 9,
- 9, 9, 9,10,10,10,11,11, 8, 8, 8, 9, 9, 9, 9,10,
- 9,10,10,11,11, 9, 9, 9, 9,10,10,10,10,10,10,11,
- 11,12, 9, 9, 9,10, 9,10,10,10,10,11,10,12,11,10,
- 10,10,10,10,11,11,11,11,11,12,12,12,10,10,10,10,
- 11,11,11,11,11,12,11,12,12,
- };
-
- static float _vq_quantthresh__44u8_p6_0[] = {
- -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5,
- 12.5, 17.5, 22.5, 27.5,
- };
-
- static long _vq_quantmap__44u8_p6_0[] = {
- 11, 9, 7, 5, 3, 1, 0, 2,
- 4, 6, 8, 10, 12,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u8_p6_0 = {
- _vq_quantthresh__44u8_p6_0,
- _vq_quantmap__44u8_p6_0,
- 13,
- 13
- };
-
- static static_codebook _44u8_p6_0 = {
- 2, 169,
- _vq_lengthlist__44u8_p6_0,
- 1, -526516224, 1616117760, 4, 0,
- _vq_quantlist__44u8_p6_0,
- NULL,
- &_vq_auxt__44u8_p6_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u8_p6_1[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__44u8_p6_1[] = {
- 3, 4, 4, 5, 5, 4, 5, 5, 5, 5, 4, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5,
- };
-
- static float _vq_quantthresh__44u8_p6_1[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__44u8_p6_1[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u8_p6_1 = {
- _vq_quantthresh__44u8_p6_1,
- _vq_quantmap__44u8_p6_1,
- 5,
- 5
- };
-
- static static_codebook _44u8_p6_1 = {
- 2, 25,
- _vq_lengthlist__44u8_p6_1,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__44u8_p6_1,
- NULL,
- &_vq_auxt__44u8_p6_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u8_p7_0[] = {
- 6,
- 5,
- 7,
- 4,
- 8,
- 3,
- 9,
- 2,
- 10,
- 1,
- 11,
- 0,
- 12,
- };
-
- static long _vq_lengthlist__44u8_p7_0[] = {
- 1, 4, 5, 6, 6, 7, 7, 8, 8,10,10,11,11, 5, 6, 6,
- 7, 7, 8, 8, 9, 9,11,10,12,11, 5, 6, 6, 7, 7, 8,
- 8, 9, 9,10,11,11,12, 6, 7, 7, 8, 8, 9, 9,10,10,
- 11,11,12,12, 6, 7, 7, 8, 8, 9, 9,10,10,11,12,13,
- 12, 7, 8, 8, 9, 9,10,10,11,11,12,12,13,13, 8, 8,
- 8, 9, 9,10,10,11,11,12,12,13,13, 9, 9, 9,10,10,
- 11,11,12,12,13,13,14,14, 9, 9, 9,10,10,11,11,12,
- 12,13,13,14,14,10,11,11,12,11,13,12,13,13,14,14,
- 15,15,10,11,11,11,12,12,13,13,14,14,14,15,15,11,
- 12,12,13,13,14,13,15,14,15,15,16,15,11,11,12,13,
- 13,13,14,14,14,15,15,15,16,
- };
-
- static float _vq_quantthresh__44u8_p7_0[] = {
- -60.5, -49.5, -38.5, -27.5, -16.5, -5.5, 5.5, 16.5,
- 27.5, 38.5, 49.5, 60.5,
- };
-
- static long _vq_quantmap__44u8_p7_0[] = {
- 11, 9, 7, 5, 3, 1, 0, 2,
- 4, 6, 8, 10, 12,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u8_p7_0 = {
- _vq_quantthresh__44u8_p7_0,
- _vq_quantmap__44u8_p7_0,
- 13,
- 13
- };
-
- static static_codebook _44u8_p7_0 = {
- 2, 169,
- _vq_lengthlist__44u8_p7_0,
- 1, -523206656, 1618345984, 4, 0,
- _vq_quantlist__44u8_p7_0,
- NULL,
- &_vq_auxt__44u8_p7_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u8_p7_1[] = {
- 5,
- 4,
- 6,
- 3,
- 7,
- 2,
- 8,
- 1,
- 9,
- 0,
- 10,
- };
-
- static long _vq_lengthlist__44u8_p7_1[] = {
- 4, 5, 5, 6, 6, 7, 7, 7, 7, 7, 7, 5, 6, 6, 7, 7,
- 7, 7, 7, 7, 7, 7, 5, 6, 6, 7, 7, 7, 7, 7, 7, 7,
- 7, 6, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 6, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 8, 7, 7, 7, 7, 7, 7, 7, 8, 8,
- 8, 8, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 7, 7, 7,
- 8, 7, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 8, 8, 8,
- 8, 8, 8, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7,
- 7, 8, 8, 8, 8, 8, 8, 8, 8,
- };
-
- static float _vq_quantthresh__44u8_p7_1[] = {
- -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5,
- 3.5, 4.5,
- };
-
- static long _vq_quantmap__44u8_p7_1[] = {
- 9, 7, 5, 3, 1, 0, 2, 4,
- 6, 8, 10,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u8_p7_1 = {
- _vq_quantthresh__44u8_p7_1,
- _vq_quantmap__44u8_p7_1,
- 11,
- 11
- };
-
- static static_codebook _44u8_p7_1 = {
- 2, 121,
- _vq_lengthlist__44u8_p7_1,
- 1, -531365888, 1611661312, 4, 0,
- _vq_quantlist__44u8_p7_1,
- NULL,
- &_vq_auxt__44u8_p7_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u8_p8_0[] = {
- 7,
- 6,
- 8,
- 5,
- 9,
- 4,
- 10,
- 3,
- 11,
- 2,
- 12,
- 1,
- 13,
- 0,
- 14,
- };
-
- static long _vq_lengthlist__44u8_p8_0[] = {
- 1, 4, 4, 7, 7, 8, 8, 8, 7, 9, 8,10, 9,11,10, 4,
- 6, 6, 8, 8,10, 9, 9, 9,10,10,11,10,12,10, 4, 6,
- 6, 8, 8,10,10, 9, 9,10,10,11,11,11,12, 7, 8, 8,
- 10,10,11,11,11,10,12,11,12,12,13,11, 7, 8, 8,10,
- 10,11,11,10,10,11,11,12,12,13,13, 8,10,10,11,11,
- 12,11,12,11,13,12,13,12,14,13, 8,10, 9,11,11,12,
- 12,12,12,12,12,13,13,14,13, 8, 9, 9,11,10,12,11,
- 13,12,13,13,14,13,14,13, 8, 9, 9,10,11,12,12,12,
- 12,13,13,14,15,14,14, 9,10,10,12,11,13,12,13,13,
- 14,13,14,14,14,14, 9,10,10,12,12,12,12,13,13,14,
- 14,14,15,14,14,10,11,11,13,12,13,12,14,14,14,14,
- 14,14,15,15,10,11,11,12,12,13,13,14,14,14,15,15,
- 14,16,15,11,12,12,13,12,14,14,14,13,15,14,15,15,
- 15,17,11,12,12,13,13,14,14,14,15,15,14,15,15,14,
- 17,
- };
-
- static float _vq_quantthresh__44u8_p8_0[] = {
- -136.5, -115.5, -94.5, -73.5, -52.5, -31.5, -10.5, 10.5,
- 31.5, 52.5, 73.5, 94.5, 115.5, 136.5,
- };
-
- static long _vq_quantmap__44u8_p8_0[] = {
- 13, 11, 9, 7, 5, 3, 1, 0,
- 2, 4, 6, 8, 10, 12, 14,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u8_p8_0 = {
- _vq_quantthresh__44u8_p8_0,
- _vq_quantmap__44u8_p8_0,
- 15,
- 15
- };
-
- static static_codebook _44u8_p8_0 = {
- 2, 225,
- _vq_lengthlist__44u8_p8_0,
- 1, -520986624, 1620377600, 4, 0,
- _vq_quantlist__44u8_p8_0,
- NULL,
- &_vq_auxt__44u8_p8_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u8_p8_1[] = {
- 10,
- 9,
- 11,
- 8,
- 12,
- 7,
- 13,
- 6,
- 14,
- 5,
- 15,
- 4,
- 16,
- 3,
- 17,
- 2,
- 18,
- 1,
- 19,
- 0,
- 20,
- };
-
- static long _vq_lengthlist__44u8_p8_1[] = {
- 4, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 6, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 5, 6, 6, 7, 7, 8,
- 8, 9, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 7,
- 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10,10, 9,10, 8, 8,
- 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10, 9,10,
- 10, 9,10, 8, 9, 8, 9, 9, 9, 9, 9, 9, 9, 9,10, 9,
- 10,10,10,10,10,10,10,10, 8, 9, 8, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9,10,10,10,10, 9,10,10, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9,10, 9,10,10,10,10,10,10,
- 10,10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10, 9,10,
- 10,10,10,10,10,10,10, 9, 9, 9, 9, 9, 9, 9,10, 9,
- 10,10,10,10,10,10,10,10,10,10,10,10, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9,10,10,10,10,10,10,10,10,10,10,
- 10, 9, 9, 9, 9, 9, 9,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10, 9, 9, 9, 9, 9, 9, 9,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10, 9, 9, 9, 9, 9,
- 9, 9,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 9, 9, 9, 9, 9,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10, 9, 9, 9,10, 9,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10, 9, 9, 9, 9, 9,10,
- 9,10,10,10,10,10,10,10,10,10,10,10,10,10,10, 9,
- 9, 9, 9, 9, 9,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10, 9, 9, 9,10, 9,10, 9,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,
- };
-
- static float _vq_quantthresh__44u8_p8_1[] = {
- -9.5, -8.5, -7.5, -6.5, -5.5, -4.5, -3.5, -2.5,
- -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5.5,
- 6.5, 7.5, 8.5, 9.5,
- };
-
- static long _vq_quantmap__44u8_p8_1[] = {
- 19, 17, 15, 13, 11, 9, 7, 5,
- 3, 1, 0, 2, 4, 6, 8, 10,
- 12, 14, 16, 18, 20,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u8_p8_1 = {
- _vq_quantthresh__44u8_p8_1,
- _vq_quantmap__44u8_p8_1,
- 21,
- 21
- };
-
- static static_codebook _44u8_p8_1 = {
- 2, 441,
- _vq_lengthlist__44u8_p8_1,
- 1, -529268736, 1611661312, 5, 0,
- _vq_quantlist__44u8_p8_1,
- NULL,
- &_vq_auxt__44u8_p8_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u8_p9_0[] = {
- 4,
- 3,
- 5,
- 2,
- 6,
- 1,
- 7,
- 0,
- 8,
- };
-
- static long _vq_lengthlist__44u8_p9_0[] = {
- 1, 3, 3, 9, 9, 9, 9, 9, 9, 4, 9, 9, 9, 9, 9, 9,
- 9, 9, 5, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8,
- 8,
- };
-
- static float _vq_quantthresh__44u8_p9_0[] = {
- -3258.5, -2327.5, -1396.5, -465.5, 465.5, 1396.5, 2327.5, 3258.5,
- };
-
- static long _vq_quantmap__44u8_p9_0[] = {
- 7, 5, 3, 1, 0, 2, 4, 6,
- 8,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u8_p9_0 = {
- _vq_quantthresh__44u8_p9_0,
- _vq_quantmap__44u8_p9_0,
- 9,
- 9
- };
-
- static static_codebook _44u8_p9_0 = {
- 2, 81,
- _vq_lengthlist__44u8_p9_0,
- 1, -511895552, 1631393792, 4, 0,
- _vq_quantlist__44u8_p9_0,
- NULL,
- &_vq_auxt__44u8_p9_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u8_p9_1[] = {
- 9,
- 8,
- 10,
- 7,
- 11,
- 6,
- 12,
- 5,
- 13,
- 4,
- 14,
- 3,
- 15,
- 2,
- 16,
- 1,
- 17,
- 0,
- 18,
- };
-
- static long _vq_lengthlist__44u8_p9_1[] = {
- 1, 4, 4, 7, 7, 8, 7, 8, 6, 9, 7,10, 8,11,10,11,
- 11,11,11, 4, 7, 6, 9, 9,10, 9, 9, 9,10,10,11,10,
- 11,10,11,11,13,11, 4, 7, 7, 9, 9, 9, 9, 9, 9,10,
- 10,11,10,11,11,11,12,11,12, 7, 9, 8,11,11,11,11,
- 10,10,11,11,12,12,12,12,12,12,14,13, 7, 8, 9,10,
- 11,11,11,10,10,11,11,11,11,12,12,14,12,13,14, 8,
- 9, 9,11,11,11,11,11,11,12,12,14,12,15,14,14,14,
- 15,14, 8, 9, 9,11,11,11,11,12,11,12,12,13,13,13,
- 13,13,13,14,14, 8, 9, 9,11,10,12,11,12,12,13,13,
- 13,13,15,14,14,14,16,16, 8, 9, 9,10,11,11,12,12,
- 12,13,13,13,14,14,14,15,16,15,15, 9,10,10,11,12,
- 12,13,13,13,14,14,16,14,14,16,16,16,16,15, 9,10,
- 10,11,11,12,13,13,14,15,14,16,14,15,16,16,16,16,
- 15,10,11,11,12,13,13,14,15,15,15,15,15,16,15,16,
- 15,16,15,15,10,11,11,13,13,14,13,13,15,14,15,15,
- 16,15,15,15,16,15,16,10,12,12,14,14,14,14,14,16,
- 16,15,15,15,16,16,16,16,16,16,11,12,12,14,14,14,
- 14,15,15,16,15,16,15,16,15,16,16,16,16,12,12,13,
- 14,14,15,16,16,16,16,16,16,15,16,16,16,16,16,16,
- 12,13,13,14,14,14,14,15,16,15,16,16,16,16,16,16,
- 16,16,16,12,13,14,14,14,16,15,16,15,16,16,16,16,
- 16,16,16,16,16,16,12,14,13,14,15,15,15,16,15,16,
- 16,15,16,16,16,16,16,16,16,
- };
-
- static float _vq_quantthresh__44u8_p9_1[] = {
- -416.5, -367.5, -318.5, -269.5, -220.5, -171.5, -122.5, -73.5,
- -24.5, 24.5, 73.5, 122.5, 171.5, 220.5, 269.5, 318.5,
- 367.5, 416.5,
- };
-
- static long _vq_quantmap__44u8_p9_1[] = {
- 17, 15, 13, 11, 9, 7, 5, 3,
- 1, 0, 2, 4, 6, 8, 10, 12,
- 14, 16, 18,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u8_p9_1 = {
- _vq_quantthresh__44u8_p9_1,
- _vq_quantmap__44u8_p9_1,
- 19,
- 19
- };
-
- static static_codebook _44u8_p9_1 = {
- 2, 361,
- _vq_lengthlist__44u8_p9_1,
- 1, -518287360, 1622704128, 5, 0,
- _vq_quantlist__44u8_p9_1,
- NULL,
- &_vq_auxt__44u8_p9_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u8_p9_2[] = {
- 24,
- 23,
- 25,
- 22,
- 26,
- 21,
- 27,
- 20,
- 28,
- 19,
- 29,
- 18,
- 30,
- 17,
- 31,
- 16,
- 32,
- 15,
- 33,
- 14,
- 34,
- 13,
- 35,
- 12,
- 36,
- 11,
- 37,
- 10,
- 38,
- 9,
- 39,
- 8,
- 40,
- 7,
- 41,
- 6,
- 42,
- 5,
- 43,
- 4,
- 44,
- 3,
- 45,
- 2,
- 46,
- 1,
- 47,
- 0,
- 48,
- };
-
- static long _vq_lengthlist__44u8_p9_2[] = {
- 2, 3, 4, 5, 5, 5, 5, 5, 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, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7,
- };
-
- static float _vq_quantthresh__44u8_p9_2[] = {
- -23.5, -22.5, -21.5, -20.5, -19.5, -18.5, -17.5, -16.5,
- -15.5, -14.5, -13.5, -12.5, -11.5, -10.5, -9.5, -8.5,
- -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5,
- 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5,
- 8.5, 9.5, 10.5, 11.5, 12.5, 13.5, 14.5, 15.5,
- 16.5, 17.5, 18.5, 19.5, 20.5, 21.5, 22.5, 23.5,
- };
-
- static long _vq_quantmap__44u8_p9_2[] = {
- 47, 45, 43, 41, 39, 37, 35, 33,
- 31, 29, 27, 25, 23, 21, 19, 17,
- 15, 13, 11, 9, 7, 5, 3, 1,
- 0, 2, 4, 6, 8, 10, 12, 14,
- 16, 18, 20, 22, 24, 26, 28, 30,
- 32, 34, 36, 38, 40, 42, 44, 46,
- 48,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u8_p9_2 = {
- _vq_quantthresh__44u8_p9_2,
- _vq_quantmap__44u8_p9_2,
- 49,
- 49
- };
-
- static static_codebook _44u8_p9_2 = {
- 1, 49,
- _vq_lengthlist__44u8_p9_2,
- 1, -526909440, 1611661312, 6, 0,
- _vq_quantlist__44u8_p9_2,
- NULL,
- &_vq_auxt__44u8_p9_2,
- NULL,
- 0
- };
-
- static long _huff_lengthlist__44u9__long[] = {
- 3, 9,13,13,14,15,14,14,15,15, 5, 5, 9,10,12,12,
- 13,14,16,15,10, 6, 6, 6, 8,11,12,13,16,15,11, 7,
- 5, 3, 5, 8,10,12,15,15,10,10, 7, 4, 3, 5, 8,10,
- 12,12,12,12, 9, 7, 5, 4, 6, 8,10,13,13,12,11, 9,
- 7, 5, 5, 6, 9,12,14,12,12,10, 8, 6, 6, 6, 7,11,
- 13,12,14,13,10, 8, 7, 7, 7,10,11,11,12,13,12,11,
- 10, 8, 8, 9,
- };
-
- static static_codebook _huff_book__44u9__long = {
- 2, 100,
- _huff_lengthlist__44u9__long,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _huff_lengthlist__44u9__short[] = {
- 9,16,18,18,17,17,17,17,17,17, 5, 8,11,12,11,12,
- 17,17,16,16, 6, 6, 8, 8, 9,10,14,15,16,16, 6, 7,
- 7, 4, 6, 9,13,16,16,16, 6, 6, 7, 4, 5, 8,11,15,
- 17,16, 7, 6, 7, 6, 6, 8, 9,10,14,16,11, 8, 8, 7,
- 6, 6, 3, 4,10,15,14,12,12,10, 5, 6, 3, 3, 8,13,
- 15,17,15,11, 6, 8, 6, 6, 9,14,17,15,15,12, 8,10,
- 9, 9,12,15,
- };
-
- static static_codebook _huff_book__44u9__short = {
- 2, 100,
- _huff_lengthlist__44u9__short,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u9_p1_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__44u9_p1_0[] = {
- 1, 5, 5, 5, 7, 7, 5, 7, 7, 5, 7, 7, 7, 9, 9, 7,
- 9, 9, 5, 7, 7, 7, 9, 9, 7, 9, 9, 5, 7, 7, 7, 9,
- 9, 7, 9, 9, 8, 9, 9, 9,10,11, 9,11,11, 7, 9, 9,
- 9,11,10, 9,11,11, 5, 7, 7, 7, 9, 9, 8, 9,10, 7,
- 9, 9, 9,11,11, 9,10,11, 7, 9,10, 9,11,11, 9,11,
- 10,
- };
-
- static float _vq_quantthresh__44u9_p1_0[] = {
- -0.5, 0.5,
- };
-
- static long _vq_quantmap__44u9_p1_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u9_p1_0 = {
- _vq_quantthresh__44u9_p1_0,
- _vq_quantmap__44u9_p1_0,
- 3,
- 3
- };
-
- static static_codebook _44u9_p1_0 = {
- 4, 81,
- _vq_lengthlist__44u9_p1_0,
- 1, -535822336, 1611661312, 2, 0,
- _vq_quantlist__44u9_p1_0,
- NULL,
- &_vq_auxt__44u9_p1_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u9_p2_0[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__44u9_p2_0[] = {
- 3, 5, 5, 8, 8, 5, 7, 7, 9, 9, 6, 7, 7, 9, 9, 8,
- 9, 9,11,10, 8, 9, 9,11,11, 6, 7, 7, 9, 9, 7, 8,
- 8,10,10, 7, 8, 8, 9,10, 9,10,10,11,11, 9, 9,10,
- 11,11, 6, 7, 7, 9, 9, 7, 8, 8,10, 9, 7, 8, 8,10,
- 10, 9,10, 9,11,11, 9,10,10,11,11, 8, 9, 9,11,11,
- 9,10,10,12,11, 9,10,10,11,12,11,11,11,13,13,11,
- 11,11,12,13, 8, 9, 9,11,11, 9,10,10,11,11, 9,10,
- 10,12,11,11,12,11,13,12,11,11,12,13,13, 6, 7, 7,
- 9, 9, 7, 8, 8,10,10, 7, 8, 8,10,10, 9,10,10,12,
- 11, 9,10,10,11,12, 7, 8, 8,10,10, 8, 9, 9,11,11,
- 8, 9, 9,10,10,10,11,11,12,12,10,10,11,12,12, 7,
- 8, 8,10,10, 8, 9, 8,10,10, 8, 9, 9,10,10,10,11,
- 10,12,11,10,10,11,12,12, 9,10,10,11,12,10,11,11,
- 12,12,10,11,10,12,12,12,12,12,13,13,11,12,12,13,
- 13, 9,10,10,11,11, 9,10,10,12,12,10,11,11,12,13,
- 11,12,11,13,12,12,12,12,13,14, 6, 7, 7, 9, 9, 7,
- 8, 8,10,10, 7, 8, 8,10,10, 9,10,10,11,11, 9,10,
- 10,11,12, 7, 8, 8,10,10, 8, 9, 9,11,10, 8, 8, 9,
- 10,10,10,11,10,12,12,10,10,11,11,12, 7, 8, 8,10,
- 10, 8, 9, 9,10,10, 8, 9, 9,10,10,10,11,10,12,12,
- 10,11,10,12,12, 9,10,10,12,11,10,11,11,12,12, 9,
- 10,10,12,12,12,12,12,13,13,11,11,12,12,14, 9,10,
- 10,11,12,10,11,11,12,12,10,11,11,12,12,11,12,12,
- 14,14,12,12,12,13,13, 8, 9, 9,11,11, 9,10,10,12,
- 11, 9,10,10,12,12,11,12,11,13,13,11,11,12,13,13,
- 9,10,10,12,12,10,11,11,12,12,10,11,11,12,12,12,
- 12,12,14,14,12,12,12,13,13, 9,10,10,12,11,10,11,
- 10,12,12,10,11,11,12,12,11,12,12,14,13,12,12,12,
- 13,14,11,12,11,13,13,11,12,12,13,13,12,12,12,14,
- 14,13,13,13,13,15,13,13,14,15,15,11,11,11,13,13,
- 11,12,11,13,13,11,12,12,13,13,12,13,12,15,13,13,
- 13,14,14,15, 8, 9, 9,11,11, 9,10,10,11,12, 9,10,
- 10,11,12,11,12,11,13,13,11,12,12,13,13, 9,10,10,
- 11,12,10,11,10,12,12,10,10,11,12,13,12,12,12,14,
- 13,11,12,12,13,14, 9,10,10,12,12,10,11,11,12,12,
- 10,11,11,12,12,12,12,12,14,13,12,12,12,14,13,11,
- 11,11,13,13,11,12,12,14,13,11,11,12,13,13,13,13,
- 13,15,14,12,12,13,13,15,11,12,12,13,13,12,12,12,
- 13,14,11,12,12,13,13,13,13,14,14,15,13,13,13,14,
- 14,
- };
-
- static float _vq_quantthresh__44u9_p2_0[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__44u9_p2_0[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u9_p2_0 = {
- _vq_quantthresh__44u9_p2_0,
- _vq_quantmap__44u9_p2_0,
- 5,
- 5
- };
-
- static static_codebook _44u9_p2_0 = {
- 4, 625,
- _vq_lengthlist__44u9_p2_0,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__44u9_p2_0,
- NULL,
- &_vq_auxt__44u9_p2_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u9_p3_0[] = {
- 4,
- 3,
- 5,
- 2,
- 6,
- 1,
- 7,
- 0,
- 8,
- };
-
- static long _vq_lengthlist__44u9_p3_0[] = {
- 3, 4, 4, 5, 5, 7, 7, 8, 8, 4, 5, 5, 6, 6, 7, 7,
- 9, 9, 4, 4, 5, 6, 6, 7, 7, 9, 9, 5, 6, 6, 7, 7,
- 8, 8, 9, 9, 5, 6, 6, 7, 7, 8, 8, 9, 9, 7, 7, 7,
- 8, 8, 9, 9,10,10, 7, 7, 7, 8, 8, 9, 9,10,10, 8,
- 9, 9,10, 9,10,10,11,11, 8, 9, 9, 9,10,10,10,11,
- 11,
- };
-
- static float _vq_quantthresh__44u9_p3_0[] = {
- -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5,
- };
-
- static long _vq_quantmap__44u9_p3_0[] = {
- 7, 5, 3, 1, 0, 2, 4, 6,
- 8,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u9_p3_0 = {
- _vq_quantthresh__44u9_p3_0,
- _vq_quantmap__44u9_p3_0,
- 9,
- 9
- };
-
- static static_codebook _44u9_p3_0 = {
- 2, 81,
- _vq_lengthlist__44u9_p3_0,
- 1, -531628032, 1611661312, 4, 0,
- _vq_quantlist__44u9_p3_0,
- NULL,
- &_vq_auxt__44u9_p3_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u9_p4_0[] = {
- 8,
- 7,
- 9,
- 6,
- 10,
- 5,
- 11,
- 4,
- 12,
- 3,
- 13,
- 2,
- 14,
- 1,
- 15,
- 0,
- 16,
- };
-
- static long _vq_lengthlist__44u9_p4_0[] = {
- 4, 5, 5, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9,10,10,11,
- 11, 5, 5, 5, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9,10,10,
- 11,11, 5, 5, 5, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9,10,
- 10,11,11, 6, 6, 6, 7, 6, 7, 7, 8, 8, 9, 9,10,10,
- 11,11,12,11, 6, 6, 6, 6, 7, 7, 7, 8, 8, 9, 9,10,
- 10,11,11,11,12, 7, 7, 7, 7, 7, 8, 8, 9, 9, 9, 9,
- 10,10,11,11,12,12, 7, 7, 7, 7, 7, 8, 8, 9, 9, 9,
- 9,10,10,11,11,12,12, 8, 8, 8, 8, 8, 9, 8,10, 9,
- 10,10,11,10,12,11,13,12, 8, 8, 8, 8, 8, 9, 9, 9,
- 10,10,10,10,11,11,12,12,12, 8, 8, 8, 9, 9, 9, 9,
- 10,10,11,10,12,11,12,12,13,12, 8, 8, 8, 9, 9, 9,
- 9,10,10,10,11,11,11,12,12,12,13, 9, 9, 9,10,10,
- 10,10,11,10,11,11,12,11,13,12,13,13, 9, 9,10,10,
- 10,10,10,10,11,11,11,11,12,12,13,13,13,10,11,10,
- 11,11,11,11,12,11,12,12,13,12,13,13,14,13,10,10,
- 10,11,11,11,11,11,12,12,12,12,13,13,13,13,14,11,
- 11,11,12,11,12,12,12,12,13,13,13,13,14,13,14,14,
- 11,11,11,11,12,12,12,12,12,12,13,13,13,13,14,14,
- 14,
- };
-
- static float _vq_quantthresh__44u9_p4_0[] = {
- -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5,
- 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5,
- };
-
- static long _vq_quantmap__44u9_p4_0[] = {
- 15, 13, 11, 9, 7, 5, 3, 1,
- 0, 2, 4, 6, 8, 10, 12, 14,
- 16,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u9_p4_0 = {
- _vq_quantthresh__44u9_p4_0,
- _vq_quantmap__44u9_p4_0,
- 17,
- 17
- };
-
- static static_codebook _44u9_p4_0 = {
- 2, 289,
- _vq_lengthlist__44u9_p4_0,
- 1, -529530880, 1611661312, 5, 0,
- _vq_quantlist__44u9_p4_0,
- NULL,
- &_vq_auxt__44u9_p4_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u9_p5_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__44u9_p5_0[] = {
- 1, 4, 4, 5, 7, 7, 5, 7, 7, 5, 8, 8, 8, 9, 9, 7,
- 9, 9, 5, 8, 8, 7, 9, 9, 8, 9, 9, 5, 8, 8, 8,10,
- 10, 8,10,10, 7,10,10, 9,10,12, 9,11,11, 7,10,10,
- 9,11,10, 9,11,12, 5, 8, 8, 8,10,10, 8,10,10, 7,
- 10,10, 9,12,11, 9,10,11, 7,10,10, 9,11,11,10,12,
- 10,
- };
-
- static float _vq_quantthresh__44u9_p5_0[] = {
- -5.5, 5.5,
- };
-
- static long _vq_quantmap__44u9_p5_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u9_p5_0 = {
- _vq_quantthresh__44u9_p5_0,
- _vq_quantmap__44u9_p5_0,
- 3,
- 3
- };
-
- static static_codebook _44u9_p5_0 = {
- 4, 81,
- _vq_lengthlist__44u9_p5_0,
- 1, -529137664, 1618345984, 2, 0,
- _vq_quantlist__44u9_p5_0,
- NULL,
- &_vq_auxt__44u9_p5_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u9_p5_1[] = {
- 5,
- 4,
- 6,
- 3,
- 7,
- 2,
- 8,
- 1,
- 9,
- 0,
- 10,
- };
-
- static long _vq_lengthlist__44u9_p5_1[] = {
- 5, 5, 5, 6, 6, 7, 7, 7, 7, 7, 7, 5, 6, 6, 6, 6,
- 7, 7, 7, 7, 8, 7, 5, 6, 6, 6, 6, 7, 7, 7, 7, 7,
- 7, 6, 6, 6, 7, 7, 7, 7, 7, 7, 8, 8, 6, 6, 6, 7,
- 7, 7, 7, 7, 7, 8, 8, 7, 7, 7, 7, 7, 8, 7, 8, 8,
- 8, 8, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 7, 7, 7,
- 8, 7, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 8, 8, 8, 8,
- 8, 8, 8, 7, 8, 7, 8, 8, 8, 8, 8, 8, 8, 8, 7, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8,
- };
-
- static float _vq_quantthresh__44u9_p5_1[] = {
- -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5,
- 3.5, 4.5,
- };
-
- static long _vq_quantmap__44u9_p5_1[] = {
- 9, 7, 5, 3, 1, 0, 2, 4,
- 6, 8, 10,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u9_p5_1 = {
- _vq_quantthresh__44u9_p5_1,
- _vq_quantmap__44u9_p5_1,
- 11,
- 11
- };
-
- static static_codebook _44u9_p5_1 = {
- 2, 121,
- _vq_lengthlist__44u9_p5_1,
- 1, -531365888, 1611661312, 4, 0,
- _vq_quantlist__44u9_p5_1,
- NULL,
- &_vq_auxt__44u9_p5_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u9_p6_0[] = {
- 6,
- 5,
- 7,
- 4,
- 8,
- 3,
- 9,
- 2,
- 10,
- 1,
- 11,
- 0,
- 12,
- };
-
- static long _vq_lengthlist__44u9_p6_0[] = {
- 2, 4, 4, 6, 6, 7, 7, 8, 8, 9, 9,10,10, 4, 6, 5,
- 7, 7, 8, 8, 8, 8, 9, 9,10,10, 4, 5, 6, 7, 7, 8,
- 8, 8, 8, 9, 9,10,10, 6, 7, 7, 8, 8, 8, 8, 9, 9,
- 10,10,10,10, 6, 7, 7, 8, 8, 8, 8, 9, 9,10,10,10,
- 10, 7, 8, 8, 8, 8, 9, 9, 9, 9,10,10,11,11, 7, 8,
- 8, 8, 8, 9, 9, 9, 9,10,10,11,11, 8, 8, 8, 9, 9,
- 9, 9, 9,10,10,10,11,11, 8, 8, 8, 9, 9, 9, 9,10,
- 9,10,10,11,11, 9, 9, 9,10,10,10,10,10,11,11,11,
- 11,12, 9, 9, 9,10,10,10,10,10,10,11,10,12,11,10,
- 10,10,10,10,11,11,11,11,11,12,12,12,10,10,10,10,
- 10,11,11,11,11,12,11,12,12,
- };
-
- static float _vq_quantthresh__44u9_p6_0[] = {
- -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5,
- 12.5, 17.5, 22.5, 27.5,
- };
-
- static long _vq_quantmap__44u9_p6_0[] = {
- 11, 9, 7, 5, 3, 1, 0, 2,
- 4, 6, 8, 10, 12,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u9_p6_0 = {
- _vq_quantthresh__44u9_p6_0,
- _vq_quantmap__44u9_p6_0,
- 13,
- 13
- };
-
- static static_codebook _44u9_p6_0 = {
- 2, 169,
- _vq_lengthlist__44u9_p6_0,
- 1, -526516224, 1616117760, 4, 0,
- _vq_quantlist__44u9_p6_0,
- NULL,
- &_vq_auxt__44u9_p6_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u9_p6_1[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__44u9_p6_1[] = {
- 4, 4, 4, 5, 5, 4, 5, 4, 5, 5, 4, 4, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5,
- };
-
- static float _vq_quantthresh__44u9_p6_1[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__44u9_p6_1[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u9_p6_1 = {
- _vq_quantthresh__44u9_p6_1,
- _vq_quantmap__44u9_p6_1,
- 5,
- 5
- };
-
- static static_codebook _44u9_p6_1 = {
- 2, 25,
- _vq_lengthlist__44u9_p6_1,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__44u9_p6_1,
- NULL,
- &_vq_auxt__44u9_p6_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u9_p7_0[] = {
- 6,
- 5,
- 7,
- 4,
- 8,
- 3,
- 9,
- 2,
- 10,
- 1,
- 11,
- 0,
- 12,
- };
-
- static long _vq_lengthlist__44u9_p7_0[] = {
- 1, 4, 5, 6, 6, 7, 7, 8, 9,10,10,11,11, 5, 6, 6,
- 7, 7, 8, 8, 9, 9,10,10,11,11, 5, 6, 6, 7, 7, 8,
- 8, 9, 9,10,10,11,11, 6, 7, 7, 8, 8, 9, 9,10,10,
- 11,11,12,12, 6, 7, 7, 8, 8, 9, 9,10,10,11,11,12,
- 12, 8, 8, 8, 9, 9,10,10,11,11,12,12,13,13, 8, 8,
- 8, 9, 9,10,10,11,11,12,12,13,13, 9, 9, 9,10,10,
- 11,11,12,12,13,13,13,13, 9, 9, 9,10,10,11,11,12,
- 12,13,13,14,14,10,10,10,11,11,12,12,13,13,14,13,
- 15,14,10,10,10,11,11,12,12,13,13,14,14,14,14,11,
- 11,12,12,12,13,13,14,14,14,14,15,15,11,11,12,12,
- 12,13,13,14,14,14,15,15,15,
- };
-
- static float _vq_quantthresh__44u9_p7_0[] = {
- -60.5, -49.5, -38.5, -27.5, -16.5, -5.5, 5.5, 16.5,
- 27.5, 38.5, 49.5, 60.5,
- };
-
- static long _vq_quantmap__44u9_p7_0[] = {
- 11, 9, 7, 5, 3, 1, 0, 2,
- 4, 6, 8, 10, 12,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u9_p7_0 = {
- _vq_quantthresh__44u9_p7_0,
- _vq_quantmap__44u9_p7_0,
- 13,
- 13
- };
-
- static static_codebook _44u9_p7_0 = {
- 2, 169,
- _vq_lengthlist__44u9_p7_0,
- 1, -523206656, 1618345984, 4, 0,
- _vq_quantlist__44u9_p7_0,
- NULL,
- &_vq_auxt__44u9_p7_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u9_p7_1[] = {
- 5,
- 4,
- 6,
- 3,
- 7,
- 2,
- 8,
- 1,
- 9,
- 0,
- 10,
- };
-
- static long _vq_lengthlist__44u9_p7_1[] = {
- 5, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 7, 7,
- 7, 7, 7, 7, 7, 7, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 8, 8, 7, 7, 7, 7, 7, 7, 7, 8, 7, 8, 8, 7, 7,
- 7, 7, 7, 7, 7, 8, 8, 8, 8,
- };
-
- static float _vq_quantthresh__44u9_p7_1[] = {
- -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5,
- 3.5, 4.5,
- };
-
- static long _vq_quantmap__44u9_p7_1[] = {
- 9, 7, 5, 3, 1, 0, 2, 4,
- 6, 8, 10,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u9_p7_1 = {
- _vq_quantthresh__44u9_p7_1,
- _vq_quantmap__44u9_p7_1,
- 11,
- 11
- };
-
- static static_codebook _44u9_p7_1 = {
- 2, 121,
- _vq_lengthlist__44u9_p7_1,
- 1, -531365888, 1611661312, 4, 0,
- _vq_quantlist__44u9_p7_1,
- NULL,
- &_vq_auxt__44u9_p7_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u9_p8_0[] = {
- 7,
- 6,
- 8,
- 5,
- 9,
- 4,
- 10,
- 3,
- 11,
- 2,
- 12,
- 1,
- 13,
- 0,
- 14,
- };
-
- static long _vq_lengthlist__44u9_p8_0[] = {
- 1, 4, 4, 7, 7, 8, 8, 8, 8, 9, 9,10, 9,11,10, 4,
- 6, 6, 8, 8, 9, 9, 9, 9,10,10,11,10,12,10, 4, 6,
- 6, 8, 8, 9,10, 9, 9,10,10,11,11,12,12, 7, 8, 8,
- 10,10,11,11,10,10,11,11,12,12,13,12, 7, 8, 8,10,
- 10,11,11,10,10,11,11,12,12,12,13, 8,10, 9,11,11,
- 12,12,11,11,12,12,13,13,14,13, 8, 9, 9,11,11,12,
- 12,11,12,12,12,13,13,14,13, 8, 9, 9,10,10,12,11,
- 13,12,13,13,14,13,15,14, 8, 9, 9,10,10,11,12,12,
- 12,13,13,13,14,14,14, 9,10,10,12,11,13,12,13,13,
- 14,13,14,14,14,15, 9,10,10,11,12,12,12,13,13,14,
- 14,14,15,15,15,10,11,11,12,12,13,13,14,14,14,14,
- 15,14,16,15,10,11,11,12,12,13,13,13,14,14,14,14,
- 14,15,16,11,12,12,13,13,14,13,14,14,15,14,15,16,
- 16,16,11,12,12,13,13,14,13,14,14,15,15,15,16,15,
- 15,
- };
-
- static float _vq_quantthresh__44u9_p8_0[] = {
- -136.5, -115.5, -94.5, -73.5, -52.5, -31.5, -10.5, 10.5,
- 31.5, 52.5, 73.5, 94.5, 115.5, 136.5,
- };
-
- static long _vq_quantmap__44u9_p8_0[] = {
- 13, 11, 9, 7, 5, 3, 1, 0,
- 2, 4, 6, 8, 10, 12, 14,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u9_p8_0 = {
- _vq_quantthresh__44u9_p8_0,
- _vq_quantmap__44u9_p8_0,
- 15,
- 15
- };
-
- static static_codebook _44u9_p8_0 = {
- 2, 225,
- _vq_lengthlist__44u9_p8_0,
- 1, -520986624, 1620377600, 4, 0,
- _vq_quantlist__44u9_p8_0,
- NULL,
- &_vq_auxt__44u9_p8_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u9_p8_1[] = {
- 10,
- 9,
- 11,
- 8,
- 12,
- 7,
- 13,
- 6,
- 14,
- 5,
- 15,
- 4,
- 16,
- 3,
- 17,
- 2,
- 18,
- 1,
- 19,
- 0,
- 20,
- };
-
- static long _vq_lengthlist__44u9_p8_1[] = {
- 4, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 6, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 6, 6, 6, 7, 7, 8,
- 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 7,
- 7, 7, 8, 8, 8, 8, 9, 8, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9,10, 9,10,10,10, 8, 8,
- 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9,10,10, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 10, 9,10, 9,10,10,10,10, 8, 8, 8, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9,10,10, 9,10,10,10,10,10, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9,10, 9,10,10,10,10,10,10,
- 10,10, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10,10,10,
- 10,10,10,10,10,10,10, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9,10,10,10,10,10,10,10,10,10,10, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9,10,10,10,10,10,10,10,10,10,
- 10, 9, 9, 9, 9, 9, 9, 9,10, 9,10,10,10,10,10,10,
- 10,10,10,10,10,10, 9, 9, 9, 9, 9, 9, 9, 9,10,10,
- 10,10,10,10,10,10,10,10,10,10,10, 9, 9, 9, 9, 9,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 9, 9, 9, 9,10, 9, 9,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10, 9, 9, 9,10, 9,10, 9,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10, 9, 9, 9,10, 9,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, 9,
- 9, 9, 9, 9,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10, 9, 9, 9,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,
- };
-
- static float _vq_quantthresh__44u9_p8_1[] = {
- -9.5, -8.5, -7.5, -6.5, -5.5, -4.5, -3.5, -2.5,
- -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5.5,
- 6.5, 7.5, 8.5, 9.5,
- };
-
- static long _vq_quantmap__44u9_p8_1[] = {
- 19, 17, 15, 13, 11, 9, 7, 5,
- 3, 1, 0, 2, 4, 6, 8, 10,
- 12, 14, 16, 18, 20,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u9_p8_1 = {
- _vq_quantthresh__44u9_p8_1,
- _vq_quantmap__44u9_p8_1,
- 21,
- 21
- };
-
- static static_codebook _44u9_p8_1 = {
- 2, 441,
- _vq_lengthlist__44u9_p8_1,
- 1, -529268736, 1611661312, 5, 0,
- _vq_quantlist__44u9_p8_1,
- NULL,
- &_vq_auxt__44u9_p8_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u9_p9_0[] = {
- 7,
- 6,
- 8,
- 5,
- 9,
- 4,
- 10,
- 3,
- 11,
- 2,
- 12,
- 1,
- 13,
- 0,
- 14,
- };
-
- static long _vq_lengthlist__44u9_p9_0[] = {
- 1, 3, 3,11,11,11,11,11,11,11,11,11,11,11,11, 4,
- 10,11,11,11,11,11,11,11,11,11,11,11,11,11, 4,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,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,
- };
-
- static float _vq_quantthresh__44u9_p9_0[] = {
- -6051.5, -5120.5, -4189.5, -3258.5, -2327.5, -1396.5, -465.5, 465.5,
- 1396.5, 2327.5, 3258.5, 4189.5, 5120.5, 6051.5,
- };
-
- static long _vq_quantmap__44u9_p9_0[] = {
- 13, 11, 9, 7, 5, 3, 1, 0,
- 2, 4, 6, 8, 10, 12, 14,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u9_p9_0 = {
- _vq_quantthresh__44u9_p9_0,
- _vq_quantmap__44u9_p9_0,
- 15,
- 15
- };
-
- static static_codebook _44u9_p9_0 = {
- 2, 225,
- _vq_lengthlist__44u9_p9_0,
- 1, -510036736, 1631393792, 4, 0,
- _vq_quantlist__44u9_p9_0,
- NULL,
- &_vq_auxt__44u9_p9_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u9_p9_1[] = {
- 9,
- 8,
- 10,
- 7,
- 11,
- 6,
- 12,
- 5,
- 13,
- 4,
- 14,
- 3,
- 15,
- 2,
- 16,
- 1,
- 17,
- 0,
- 18,
- };
-
- static long _vq_lengthlist__44u9_p9_1[] = {
- 1, 4, 4, 7, 7, 8, 7, 8, 7, 9, 8,10, 9,10,10,11,
- 11,12,12, 4, 7, 6, 9, 9,10, 9, 9, 8,10,10,11,10,
- 12,10,13,12,13,12, 4, 6, 6, 9, 9, 9, 9, 9, 9,10,
- 10,11,11,11,12,12,12,12,12, 7, 9, 8,11,10,10,10,
- 11,10,11,11,12,12,13,12,13,13,13,13, 7, 8, 9,10,
- 10,11,11,10,10,11,11,11,12,13,13,13,13,14,14, 8,
- 9, 9,11,11,12,11,12,12,13,12,12,13,13,14,15,14,
- 14,14, 8, 9, 9,10,11,11,11,12,12,13,12,13,13,14,
- 14,14,15,14,16, 8, 9, 9,11,10,12,12,12,12,15,13,
- 13,13,17,14,15,15,15,14, 8, 9, 9,10,11,11,12,13,
- 12,13,13,13,14,15,14,14,14,16,15, 9,11,10,12,12,
- 13,13,13,13,14,14,16,15,14,14,14,15,15,17, 9,10,
- 10,11,11,13,13,13,14,14,13,15,14,15,14,15,16,15,
- 16,10,11,11,12,12,13,14,15,14,15,14,14,15,17,16,
- 15,15,17,17,10,12,11,13,12,14,14,13,14,15,15,15,
- 15,16,17,17,15,17,16,11,12,12,14,13,15,14,15,16,
- 17,15,17,15,17,15,15,16,17,15,11,11,12,14,14,14,
- 14,14,15,15,16,15,17,17,17,16,17,16,15,12,12,13,
- 14,14,14,15,14,15,15,16,16,17,16,17,15,17,17,16,
- 12,14,12,14,14,15,15,15,14,14,16,16,16,15,16,16,
- 15,17,15,12,13,13,14,15,14,15,17,15,17,16,17,17,
- 17,16,17,16,17,17,12,13,13,14,16,15,15,15,16,15,
- 17,17,15,17,15,17,16,16,17,
- };
-
- static float _vq_quantthresh__44u9_p9_1[] = {
- -416.5, -367.5, -318.5, -269.5, -220.5, -171.5, -122.5, -73.5,
- -24.5, 24.5, 73.5, 122.5, 171.5, 220.5, 269.5, 318.5,
- 367.5, 416.5,
- };
-
- static long _vq_quantmap__44u9_p9_1[] = {
- 17, 15, 13, 11, 9, 7, 5, 3,
- 1, 0, 2, 4, 6, 8, 10, 12,
- 14, 16, 18,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u9_p9_1 = {
- _vq_quantthresh__44u9_p9_1,
- _vq_quantmap__44u9_p9_1,
- 19,
- 19
- };
-
- static static_codebook _44u9_p9_1 = {
- 2, 361,
- _vq_lengthlist__44u9_p9_1,
- 1, -518287360, 1622704128, 5, 0,
- _vq_quantlist__44u9_p9_1,
- NULL,
- &_vq_auxt__44u9_p9_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44u9_p9_2[] = {
- 24,
- 23,
- 25,
- 22,
- 26,
- 21,
- 27,
- 20,
- 28,
- 19,
- 29,
- 18,
- 30,
- 17,
- 31,
- 16,
- 32,
- 15,
- 33,
- 14,
- 34,
- 13,
- 35,
- 12,
- 36,
- 11,
- 37,
- 10,
- 38,
- 9,
- 39,
- 8,
- 40,
- 7,
- 41,
- 6,
- 42,
- 5,
- 43,
- 4,
- 44,
- 3,
- 45,
- 2,
- 46,
- 1,
- 47,
- 0,
- 48,
- };
-
- static long _vq_lengthlist__44u9_p9_2[] = {
- 2, 4, 4, 5, 4, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 7, 6, 7, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7,
- };
-
- static float _vq_quantthresh__44u9_p9_2[] = {
- -23.5, -22.5, -21.5, -20.5, -19.5, -18.5, -17.5, -16.5,
- -15.5, -14.5, -13.5, -12.5, -11.5, -10.5, -9.5, -8.5,
- -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5,
- 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5,
- 8.5, 9.5, 10.5, 11.5, 12.5, 13.5, 14.5, 15.5,
- 16.5, 17.5, 18.5, 19.5, 20.5, 21.5, 22.5, 23.5,
- };
-
- static long _vq_quantmap__44u9_p9_2[] = {
- 47, 45, 43, 41, 39, 37, 35, 33,
- 31, 29, 27, 25, 23, 21, 19, 17,
- 15, 13, 11, 9, 7, 5, 3, 1,
- 0, 2, 4, 6, 8, 10, 12, 14,
- 16, 18, 20, 22, 24, 26, 28, 30,
- 32, 34, 36, 38, 40, 42, 44, 46,
- 48,
- };
-
- static encode_aux_threshmatch _vq_auxt__44u9_p9_2 = {
- _vq_quantthresh__44u9_p9_2,
- _vq_quantmap__44u9_p9_2,
- 49,
- 49
- };
-
- static static_codebook _44u9_p9_2 = {
- 1, 49,
- _vq_lengthlist__44u9_p9_2,
- 1, -526909440, 1611661312, 6, 0,
- _vq_quantlist__44u9_p9_2,
- NULL,
- &_vq_auxt__44u9_p9_2,
- NULL,
- 0
- };
-
- static long _huff_lengthlist__44un1__long[] = {
- 5, 6,12, 9,14, 9, 9,19, 6, 1, 5, 5, 8, 7, 9,19,
- 12, 4, 4, 7, 7, 9,11,18, 9, 5, 6, 6, 8, 7, 8,17,
- 14, 8, 7, 8, 8,10,12,18, 9, 6, 8, 6, 8, 6, 8,18,
- 9, 8,11, 8,11, 7, 5,15,16,18,18,18,17,15,11,18,
- };
-
- static static_codebook _huff_book__44un1__long = {
- 2, 64,
- _huff_lengthlist__44un1__long,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44un1__p1_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__44un1__p1_0[] = {
- 1, 4, 4, 5, 8, 7, 5, 7, 8, 5, 8, 8, 8,10,11, 8,
- 10,11, 5, 8, 8, 8,11,10, 8,11,10, 4, 9, 9, 8,11,
- 11, 8,11,11, 8,12,11,10,12,14,11,13,13, 7,11,11,
- 10,13,11,11,13,14, 4, 8, 9, 8,11,11, 8,11,12, 7,
- 11,11,11,14,13,10,11,13, 8,11,12,11,13,13,10,14,
- 12,
- };
-
- static float _vq_quantthresh__44un1__p1_0[] = {
- -0.5, 0.5,
- };
-
- static long _vq_quantmap__44un1__p1_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__44un1__p1_0 = {
- _vq_quantthresh__44un1__p1_0,
- _vq_quantmap__44un1__p1_0,
- 3,
- 3
- };
-
- static static_codebook _44un1__p1_0 = {
- 4, 81,
- _vq_lengthlist__44un1__p1_0,
- 1, -535822336, 1611661312, 2, 0,
- _vq_quantlist__44un1__p1_0,
- NULL,
- &_vq_auxt__44un1__p1_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44un1__p2_0[] = {
- 1,
- 0,
- 2,
- };
-
- static long _vq_lengthlist__44un1__p2_0[] = {
- 2, 4, 4, 5, 6, 6, 5, 6, 6, 5, 7, 7, 7, 8, 8, 6,
- 7, 9, 5, 7, 7, 6, 8, 7, 7, 9, 8, 4, 7, 7, 7, 9,
- 8, 7, 8, 8, 7, 9, 8, 8, 8,10, 9,10,10, 6, 8, 8,
- 7,10, 8, 9,10,10, 5, 7, 7, 7, 8, 8, 7, 8, 9, 6,
- 8, 8, 9,10,10, 7, 8,10, 6, 8, 9, 9,10,10, 8,10,
- 8,
- };
-
- static float _vq_quantthresh__44un1__p2_0[] = {
- -0.5, 0.5,
- };
-
- static long _vq_quantmap__44un1__p2_0[] = {
- 1, 0, 2,
- };
-
- static encode_aux_threshmatch _vq_auxt__44un1__p2_0 = {
- _vq_quantthresh__44un1__p2_0,
- _vq_quantmap__44un1__p2_0,
- 3,
- 3
- };
-
- static static_codebook _44un1__p2_0 = {
- 4, 81,
- _vq_lengthlist__44un1__p2_0,
- 1, -535822336, 1611661312, 2, 0,
- _vq_quantlist__44un1__p2_0,
- NULL,
- &_vq_auxt__44un1__p2_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44un1__p3_0[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__44un1__p3_0[] = {
- 1, 5, 5, 8, 8, 5, 8, 7, 9, 9, 5, 7, 8, 9, 9, 9,
- 10, 9,12,12, 9, 9,10,11,12, 6, 8, 8,10,10, 8,10,
- 10,11,11, 8, 9,10,11,11,10,11,11,13,13,10,11,11,
- 12,13, 6, 8, 8,10,10, 8,10, 9,11,11, 8,10,10,11,
- 11,10,11,11,13,12,10,11,11,13,12, 9,11,11,15,13,
- 10,12,11,15,13,10,11,11,15,14,12,14,13,16,15,12,
- 13,13,17,16, 9,11,11,13,15,10,11,12,14,15,10,11,
- 12,14,15,12,13,13,15,16,12,13,13,16,16, 5, 8, 8,
- 11,11, 8,10,10,12,12, 8,10,10,12,12,11,12,12,14,
- 14,11,12,12,14,14, 8,11,10,13,12,10,11,12,12,13,
- 10,12,12,13,13,12,12,13,13,15,11,12,13,15,14, 7,
- 10,10,12,12, 9,12,11,13,12,10,12,12,13,14,12,13,
- 12,15,13,11,13,12,14,15,10,12,12,16,14,11,12,12,
- 16,15,11,13,12,17,16,13,13,15,15,17,13,15,15,20,
- 17,10,12,12,14,16,11,12,12,15,15,11,13,13,15,18,
- 13,14,13,15,15,13,15,14,16,16, 5, 8, 8,11,11, 8,
- 10,10,12,12, 8,10,10,12,12,11,12,12,14,14,11,12,
- 12,14,15, 7,10,10,13,12,10,12,12,14,13, 9,10,12,
- 12,13,11,13,13,15,15,11,12,13,13,15, 8,10,10,12,
- 13,10,12,12,13,13,10,12,11,13,13,11,13,12,15,15,
- 12,13,12,15,13,10,12,12,16,14,11,12,12,16,15,10,
- 12,12,16,14,14,15,14,18,16,13,13,14,15,16,10,12,
- 12,14,16,11,13,13,16,16,11,13,12,14,16,13,15,15,
- 18,18,13,15,13,16,14, 8,11,11,16,16,10,13,13,17,
- 16,10,12,12,16,15,14,16,15,20,17,13,14,14,17,17,
- 9,12,12,16,16,11,13,14,16,17,11,13,13,16,16,15,
- 15,19,18, 0,14,15,15,18,18, 9,12,12,17,16,11,13,
- 12,17,16,11,12,13,15,17,15,16,15, 0,19,14,15,14,
- 19,18,12,14,14, 0,16,13,14,14,19,18,13,15,16,17,
- 16,15,15,17,18, 0,14,16,16,19, 0,12,14,14,16,18,
- 13,15,13,17,18,13,15,14,17,18,15,18,14,18,18,16,
- 17,16, 0,17, 8,11,11,15,15,10,12,12,16,16,10,13,
- 13,16,16,13,15,14,17,17,14,15,17,17,18, 9,12,12,
- 16,15,11,13,13,16,16,11,12,13,17,17,14,14,15,17,
- 17,14,15,16, 0,18, 9,12,12,16,17,11,13,13,16,17,
- 11,14,13,18,17,14,16,14,17,17,15,17,17,18,18,12,
- 14,14, 0,16,13,15,15,19, 0,12,13,15, 0, 0,14,17,
- 16,19, 0,16,15,18,18, 0,12,14,14,17, 0,13,14,14,
- 17, 0,13,15,14, 0,18,15,16,16, 0,18,15,18,15, 0,
- 17,
- };
-
- static float _vq_quantthresh__44un1__p3_0[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__44un1__p3_0[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__44un1__p3_0 = {
- _vq_quantthresh__44un1__p3_0,
- _vq_quantmap__44un1__p3_0,
- 5,
- 5
- };
-
- static static_codebook _44un1__p3_0 = {
- 4, 625,
- _vq_lengthlist__44un1__p3_0,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__44un1__p3_0,
- NULL,
- &_vq_auxt__44un1__p3_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44un1__p4_0[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__44un1__p4_0[] = {
- 3, 5, 5, 9, 9, 5, 6, 6,10, 9, 5, 6, 6, 9,10,10,
- 10,10,12,11, 9,10,10,12,12, 5, 7, 7,10,10, 7, 7,
- 8,10,11, 7, 7, 8,10,11,10,10,11,11,13,10,10,11,
- 11,13, 6, 7, 7,10,10, 7, 8, 7,11,10, 7, 8, 7,10,
- 10,10,11, 9,13,11,10,11,10,13,11,10,10,10,14,13,
- 10,11,11,14,13,10,10,11,13,14,12,12,13,15,15,12,
- 12,13,13,14,10,10,10,12,13,10,11,10,13,13,10,11,
- 11,13,13,12,13,12,14,13,12,13,13,14,13, 5, 7, 7,
- 10,10, 7, 8, 8,11,10, 7, 8, 8,10,10,11,11,11,13,
- 13,10,11,11,12,12, 7, 8, 8,11,11, 7, 8, 9,10,12,
- 8, 9, 9,11,11,11,10,12,11,14,11,11,12,13,13, 6,
- 8, 8,10,11, 7, 9, 7,12,10, 8, 9,10,11,12,10,12,
- 10,14,11,11,12,11,13,13,10,11,11,14,14,10,10,11,
- 13,14,11,12,12,15,13,12,11,14,12,16,12,13,14,15,
- 16,10,10,11,13,14,10,11,10,14,12,11,12,12,13,14,
- 12,13,11,15,12,14,14,14,15,15, 5, 7, 7,10,10, 7,
- 8, 8,10,10, 7, 8, 8,10,11,10,11,10,12,12,10,11,
- 11,12,13, 6, 8, 8,11,11, 8, 9, 9,12,11, 7, 7, 9,
- 10,12,11,11,11,12,13,11,10,12,11,15, 7, 8, 8,11,
- 11, 8, 9, 9,11,11, 7, 9, 8,12,10,11,12,11,13,12,
- 11,12,10,15,11,10,11,10,14,12,11,12,11,14,13,10,
- 10,11,13,14,13,13,13,17,15,12,11,14,12,15,10,10,
- 11,13,14,11,12,12,14,14,10,11,10,14,13,13,14,13,
- 16,17,12,14,11,16,12, 9,10,10,14,13,10,11,10,14,
- 14,10,11,11,13,13,13,14,14,16,15,12,13,13,14,14,
- 9,11,10,14,13,10,10,12,13,14,11,12,11,14,13,13,
- 14,14,14,15,13,14,14,15,15, 9,10,11,13,14,10,11,
- 10,15,13,11,11,12,12,15,13,14,12,15,14,13,13,14,
- 14,15,12,13,12,16,14,11,11,12,15,14,13,15,13,16,
- 14,13,12,15,12,17,15,16,15,16,16,12,12,13,13,15,
- 11,13,11,15,14,13,13,14,15,17,13,14,12, 0,13,14,
- 15,14,15, 0, 9,10,10,13,13,10,11,11,13,13,10,11,
- 11,13,13,12,13,12,14,14,13,14,14,15,17, 9,10,10,
- 13,13,11,12,11,15,12,10,10,11,13,16,13,14,13,15,
- 14,13,13,14,15,16,10,10,11,13,14,11,11,12,13,14,
- 10,12,11,14,14,13,13,13,14,15,13,15,13,16,15,12,
- 13,12,15,13,12,15,13,15,15,11,11,13,14,15,15,15,
- 15,15,17,13,12,14,13,17,12,12,14,14,15,13,13,14,
- 14,16,11,13,11,16,15,14,16,16,17, 0,14,13,11,16,
- 12,
- };
-
- static float _vq_quantthresh__44un1__p4_0[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__44un1__p4_0[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__44un1__p4_0 = {
- _vq_quantthresh__44un1__p4_0,
- _vq_quantmap__44un1__p4_0,
- 5,
- 5
- };
-
- static static_codebook _44un1__p4_0 = {
- 4, 625,
- _vq_lengthlist__44un1__p4_0,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__44un1__p4_0,
- NULL,
- &_vq_auxt__44un1__p4_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44un1__p5_0[] = {
- 4,
- 3,
- 5,
- 2,
- 6,
- 1,
- 7,
- 0,
- 8,
- };
-
- static long _vq_lengthlist__44un1__p5_0[] = {
- 1, 4, 4, 7, 7, 8, 8, 9, 9, 4, 6, 5, 8, 7, 8, 8,
- 10, 9, 4, 6, 6, 8, 8, 8, 8,10,10, 7, 8, 7, 9, 9,
- 9, 9,11,10, 7, 8, 8, 9, 9, 9, 9,10,11, 8, 8, 8,
- 9, 9,10,10,11,11, 8, 8, 8, 9, 9,10,10,11,11, 9,
- 10,10,11,10,11,11,12,12, 9,10,10,10,11,11,11,12,
- 12,
- };
-
- static float _vq_quantthresh__44un1__p5_0[] = {
- -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5,
- };
-
- static long _vq_quantmap__44un1__p5_0[] = {
- 7, 5, 3, 1, 0, 2, 4, 6,
- 8,
- };
-
- static encode_aux_threshmatch _vq_auxt__44un1__p5_0 = {
- _vq_quantthresh__44un1__p5_0,
- _vq_quantmap__44un1__p5_0,
- 9,
- 9
- };
-
- static static_codebook _44un1__p5_0 = {
- 2, 81,
- _vq_lengthlist__44un1__p5_0,
- 1, -531628032, 1611661312, 4, 0,
- _vq_quantlist__44un1__p5_0,
- NULL,
- &_vq_auxt__44un1__p5_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44un1__p6_0[] = {
- 6,
- 5,
- 7,
- 4,
- 8,
- 3,
- 9,
- 2,
- 10,
- 1,
- 11,
- 0,
- 12,
- };
-
- static long _vq_lengthlist__44un1__p6_0[] = {
- 1, 4, 4, 6, 6, 8, 8,10,10,11,11,15,15, 4, 5, 5,
- 8, 8, 9, 9,11,11,12,12,16,16, 4, 5, 6, 8, 8, 9,
- 9,11,11,12,12,14,14, 7, 8, 8, 9, 9,10,10,11,12,
- 13,13,16,17, 7, 8, 8, 9, 9,10,10,12,12,12,13,15,
- 15, 9,10,10,10,10,11,11,12,12,13,13,15,16, 9, 9,
- 9,10,10,11,11,13,12,13,13,17,17,10,11,11,11,12,
- 12,12,13,13,14,15, 0,18,10,11,11,12,12,12,13,14,
- 13,14,14,17,16,11,12,12,13,13,14,14,14,14,15,16,
- 17,16,11,12,12,13,13,14,14,14,14,15,15,17,17,14,
- 15,15,16,16,16,17,17,16, 0,17, 0,18,14,15,15,16,
- 16, 0,15,18,18, 0,16, 0, 0,
- };
-
- static float _vq_quantthresh__44un1__p6_0[] = {
- -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5,
- 12.5, 17.5, 22.5, 27.5,
- };
-
- static long _vq_quantmap__44un1__p6_0[] = {
- 11, 9, 7, 5, 3, 1, 0, 2,
- 4, 6, 8, 10, 12,
- };
-
- static encode_aux_threshmatch _vq_auxt__44un1__p6_0 = {
- _vq_quantthresh__44un1__p6_0,
- _vq_quantmap__44un1__p6_0,
- 13,
- 13
- };
-
- static static_codebook _44un1__p6_0 = {
- 2, 169,
- _vq_lengthlist__44un1__p6_0,
- 1, -526516224, 1616117760, 4, 0,
- _vq_quantlist__44un1__p6_0,
- NULL,
- &_vq_auxt__44un1__p6_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44un1__p6_1[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__44un1__p6_1[] = {
- 2, 4, 4, 5, 5, 4, 5, 5, 5, 5, 4, 5, 5, 6, 5, 5,
- 6, 5, 6, 6, 5, 6, 6, 6, 6,
- };
-
- static float _vq_quantthresh__44un1__p6_1[] = {
- -1.5, -0.5, 0.5, 1.5,
- };
-
- static long _vq_quantmap__44un1__p6_1[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__44un1__p6_1 = {
- _vq_quantthresh__44un1__p6_1,
- _vq_quantmap__44un1__p6_1,
- 5,
- 5
- };
-
- static static_codebook _44un1__p6_1 = {
- 2, 25,
- _vq_lengthlist__44un1__p6_1,
- 1, -533725184, 1611661312, 3, 0,
- _vq_quantlist__44un1__p6_1,
- NULL,
- &_vq_auxt__44un1__p6_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44un1__p7_0[] = {
- 2,
- 1,
- 3,
- 0,
- 4,
- };
-
- static long _vq_lengthlist__44un1__p7_0[] = {
- 1, 5, 3,11,11,11,11,11,11,11, 8,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,10,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,10,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11, 8,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,10,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11, 7,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,10,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
- 10,
- };
-
- static float _vq_quantthresh__44un1__p7_0[] = {
- -253.5, -84.5, 84.5, 253.5,
- };
-
- static long _vq_quantmap__44un1__p7_0[] = {
- 3, 1, 0, 2, 4,
- };
-
- static encode_aux_threshmatch _vq_auxt__44un1__p7_0 = {
- _vq_quantthresh__44un1__p7_0,
- _vq_quantmap__44un1__p7_0,
- 5,
- 5
- };
-
- static static_codebook _44un1__p7_0 = {
- 4, 625,
- _vq_lengthlist__44un1__p7_0,
- 1, -518709248, 1626677248, 3, 0,
- _vq_quantlist__44un1__p7_0,
- NULL,
- &_vq_auxt__44un1__p7_0,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44un1__p7_1[] = {
- 6,
- 5,
- 7,
- 4,
- 8,
- 3,
- 9,
- 2,
- 10,
- 1,
- 11,
- 0,
- 12,
- };
-
- static long _vq_lengthlist__44un1__p7_1[] = {
- 1, 4, 4, 6, 6, 6, 6, 9, 8, 9, 8, 8, 8, 5, 7, 7,
- 7, 7, 8, 8, 8,10, 8,10, 8, 9, 5, 7, 7, 8, 7, 7,
- 8,10,10,11,10,12,11, 7, 8, 8, 9, 9, 9,10,11,11,
- 11,11,11,11, 7, 8, 8, 8, 9, 9, 9,10,10,10,11,11,
- 12, 7, 8, 8, 9, 9,10,11,11,12,11,12,11,11, 7, 8,
- 8, 9, 9,10,10,11,11,11,12,12,11, 8,10,10,10,10,
- 11,11,14,11,12,12,12,13, 9,10,10,10,10,12,11,14,
- 11,14,11,12,13,10,11,11,11,11,13,11,14,14,13,13,
- 13,14,11,11,11,12,11,12,12,12,13,14,14,13,14,12,
- 11,12,12,12,12,13,13,13,14,13,14,14,11,12,12,14,
- 12,13,13,12,13,13,14,14,14,
- };
-
- static float _vq_quantthresh__44un1__p7_1[] = {
- -71.5, -58.5, -45.5, -32.5, -19.5, -6.5, 6.5, 19.5,
- 32.5, 45.5, 58.5, 71.5,
- };
-
- static long _vq_quantmap__44un1__p7_1[] = {
- 11, 9, 7, 5, 3, 1, 0, 2,
- 4, 6, 8, 10, 12,
- };
-
- static encode_aux_threshmatch _vq_auxt__44un1__p7_1 = {
- _vq_quantthresh__44un1__p7_1,
- _vq_quantmap__44un1__p7_1,
- 13,
- 13
- };
-
- static static_codebook _44un1__p7_1 = {
- 2, 169,
- _vq_lengthlist__44un1__p7_1,
- 1, -523010048, 1618608128, 4, 0,
- _vq_quantlist__44un1__p7_1,
- NULL,
- &_vq_auxt__44un1__p7_1,
- NULL,
- 0
- };
-
- static long _vq_quantlist__44un1__p7_2[] = {
- 6,
- 5,
- 7,
- 4,
- 8,
- 3,
- 9,
- 2,
- 10,
- 1,
- 11,
- 0,
- 12,
- };
-
- static long _vq_lengthlist__44un1__p7_2[] = {
- 3, 4, 4, 6, 6, 7, 7, 8, 8, 9, 9, 9, 8, 4, 5, 5,
- 6, 6, 8, 8, 9, 8, 9, 9, 9, 9, 4, 5, 5, 7, 6, 8,
- 8, 8, 8, 9, 8, 9, 8, 6, 7, 7, 7, 8, 8, 8, 9, 9,
- 9, 9, 9, 9, 6, 7, 7, 7, 7, 8, 8, 9, 9, 9, 9, 9,
- 9, 7, 8, 8, 8, 8, 9, 8, 9, 9,10, 9, 9,10, 7, 8,
- 8, 8, 8, 9, 9, 9, 9, 9, 9,10,10, 8, 9, 9, 9, 9,
- 9, 9, 9, 9,10,10, 9,10, 8, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9,10,10, 9, 9, 9,10, 9, 9,10, 9, 9,10,10,
- 10,10, 9, 9, 9, 9, 9, 9, 9,10, 9,10,10,10,10, 9,
- 9, 9,10, 9, 9,10,10, 9,10,10,10,10, 9, 9, 9,10,
- 9, 9, 9,10,10,10,10,10,10,
- };
-
- static float _vq_quantthresh__44un1__p7_2[] = {
- -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5,
- 2.5, 3.5, 4.5, 5.5,
- };
-
- static long _vq_quantmap__44un1__p7_2[] = {
- 11, 9, 7, 5, 3, 1, 0, 2,
- 4, 6, 8, 10, 12,
- };
-
- static encode_aux_threshmatch _vq_auxt__44un1__p7_2 = {
- _vq_quantthresh__44un1__p7_2,
- _vq_quantmap__44un1__p7_2,
- 13,
- 13
- };
-
- static static_codebook _44un1__p7_2 = {
- 2, 169,
- _vq_lengthlist__44un1__p7_2,
- 1, -531103744, 1611661312, 4, 0,
- _vq_quantlist__44un1__p7_2,
- NULL,
- &_vq_auxt__44un1__p7_2,
- NULL,
- 0
- };
-
- static long _huff_lengthlist__44un1__short[] = {
- 12,12,14,12,14,14,14,14,12, 6, 6, 8, 9, 9,11,14,
- 12, 4, 2, 6, 6, 7,11,14,13, 6, 5, 7, 8, 9,11,14,
- 13, 8, 5, 8, 6, 8,12,14,12, 7, 7, 8, 8, 8,10,14,
- 12, 6, 3, 4, 4, 4, 7,14,11, 7, 4, 6, 6, 6, 8,14,
- };
-
- static static_codebook _huff_book__44un1__short = {
- 2, 64,
- _huff_lengthlist__44un1__short,
- 0, 0, 0, 0, 0,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- };
- /********* End of inlined file: res_books_uncoupled.h *********/
-
- /***** residue backends *********************************************/
-
- static vorbis_info_residue0 _residue_44_low_un={
- 0,-1, -1, 8,-1,
- {0},
- {-1},
- { .5, 1.5, 1.5, 2.5, 2.5, 4.5, 28.5},
- { -1, 25, -1, 45, -1, -1, -1}
- };
-
- static vorbis_info_residue0 _residue_44_mid_un={
- 0,-1, -1, 10,-1,
- /* 0 1 2 3 4 5 6 7 8 9 */
- {0},
- {-1},
- { .5, 1.5, 1.5, 2.5, 2.5, 4.5, 4.5, 16.5, 60.5},
- { -1, 30, -1, 50, -1, 80, -1, -1, -1}
- };
-
- static vorbis_info_residue0 _residue_44_hi_un={
- 0,-1, -1, 10,-1,
- /* 0 1 2 3 4 5 6 7 8 9 */
- {0},
- {-1},
- { .5, 1.5, 2.5, 4.5, 8.5, 16.5, 32.5, 71.5,157.5},
- { -1, -1, -1, -1, -1, -1, -1, -1, -1}
- };
-
- /* mapping conventions:
- only one submap (this would change for efficient 5.1 support for example)*/
- /* Four psychoacoustic profiles are used, one for each blocktype */
- static vorbis_info_mapping0 _map_nominal_u[2]={
- {1, {0,0}, {0}, {0}, 0,{0},{0}},
- {1, {0,0}, {1}, {1}, 0,{0},{0}}
- };
-
- static static_bookblock _resbook_44u_n1={
- {
- {0},
- {0,0,&_44un1__p1_0},
- {0,0,&_44un1__p2_0},
- {0,0,&_44un1__p3_0},
- {0,0,&_44un1__p4_0},
- {0,0,&_44un1__p5_0},
- {&_44un1__p6_0,&_44un1__p6_1},
- {&_44un1__p7_0,&_44un1__p7_1,&_44un1__p7_2}
- }
- };
- static static_bookblock _resbook_44u_0={
- {
- {0},
- {0,0,&_44u0__p1_0},
- {0,0,&_44u0__p2_0},
- {0,0,&_44u0__p3_0},
- {0,0,&_44u0__p4_0},
- {0,0,&_44u0__p5_0},
- {&_44u0__p6_0,&_44u0__p6_1},
- {&_44u0__p7_0,&_44u0__p7_1,&_44u0__p7_2}
- }
- };
- static static_bookblock _resbook_44u_1={
- {
- {0},
- {0,0,&_44u1__p1_0},
- {0,0,&_44u1__p2_0},
- {0,0,&_44u1__p3_0},
- {0,0,&_44u1__p4_0},
- {0,0,&_44u1__p5_0},
- {&_44u1__p6_0,&_44u1__p6_1},
- {&_44u1__p7_0,&_44u1__p7_1,&_44u1__p7_2}
- }
- };
- static static_bookblock _resbook_44u_2={
- {
- {0},
- {0,0,&_44u2__p1_0},
- {0,0,&_44u2__p2_0},
- {0,0,&_44u2__p3_0},
- {0,0,&_44u2__p4_0},
- {0,0,&_44u2__p5_0},
- {&_44u2__p6_0,&_44u2__p6_1},
- {&_44u2__p7_0,&_44u2__p7_1,&_44u2__p7_2}
- }
- };
- static static_bookblock _resbook_44u_3={
- {
- {0},
- {0,0,&_44u3__p1_0},
- {0,0,&_44u3__p2_0},
- {0,0,&_44u3__p3_0},
- {0,0,&_44u3__p4_0},
- {0,0,&_44u3__p5_0},
- {&_44u3__p6_0,&_44u3__p6_1},
- {&_44u3__p7_0,&_44u3__p7_1,&_44u3__p7_2}
- }
- };
- static static_bookblock _resbook_44u_4={
- {
- {0},
- {0,0,&_44u4__p1_0},
- {0,0,&_44u4__p2_0},
- {0,0,&_44u4__p3_0},
- {0,0,&_44u4__p4_0},
- {0,0,&_44u4__p5_0},
- {&_44u4__p6_0,&_44u4__p6_1},
- {&_44u4__p7_0,&_44u4__p7_1,&_44u4__p7_2}
- }
- };
- static static_bookblock _resbook_44u_5={
- {
- {0},
- {0,0,&_44u5__p1_0},
- {0,0,&_44u5__p2_0},
- {0,0,&_44u5__p3_0},
- {0,0,&_44u5__p4_0},
- {0,0,&_44u5__p5_0},
- {0,0,&_44u5__p6_0},
- {&_44u5__p7_0,&_44u5__p7_1},
- {&_44u5__p8_0,&_44u5__p8_1},
- {&_44u5__p9_0,&_44u5__p9_1,&_44u5__p9_2}
- }
- };
- static static_bookblock _resbook_44u_6={
- {
- {0},
- {0,0,&_44u6__p1_0},
- {0,0,&_44u6__p2_0},
- {0,0,&_44u6__p3_0},
- {0,0,&_44u6__p4_0},
- {0,0,&_44u6__p5_0},
- {0,0,&_44u6__p6_0},
- {&_44u6__p7_0,&_44u6__p7_1},
- {&_44u6__p8_0,&_44u6__p8_1},
- {&_44u6__p9_0,&_44u6__p9_1,&_44u6__p9_2}
- }
- };
- static static_bookblock _resbook_44u_7={
- {
- {0},
- {0,0,&_44u7__p1_0},
- {0,0,&_44u7__p2_0},
- {0,0,&_44u7__p3_0},
- {0,0,&_44u7__p4_0},
- {0,0,&_44u7__p5_0},
- {0,0,&_44u7__p6_0},
- {&_44u7__p7_0,&_44u7__p7_1},
- {&_44u7__p8_0,&_44u7__p8_1},
- {&_44u7__p9_0,&_44u7__p9_1,&_44u7__p9_2}
- }
- };
- static static_bookblock _resbook_44u_8={
- {
- {0},
- {0,0,&_44u8_p1_0},
- {0,0,&_44u8_p2_0},
- {0,0,&_44u8_p3_0},
- {0,0,&_44u8_p4_0},
- {&_44u8_p5_0,&_44u8_p5_1},
- {&_44u8_p6_0,&_44u8_p6_1},
- {&_44u8_p7_0,&_44u8_p7_1},
- {&_44u8_p8_0,&_44u8_p8_1},
- {&_44u8_p9_0,&_44u8_p9_1,&_44u8_p9_2}
- }
- };
- static static_bookblock _resbook_44u_9={
- {
- {0},
- {0,0,&_44u9_p1_0},
- {0,0,&_44u9_p2_0},
- {0,0,&_44u9_p3_0},
- {0,0,&_44u9_p4_0},
- {&_44u9_p5_0,&_44u9_p5_1},
- {&_44u9_p6_0,&_44u9_p6_1},
- {&_44u9_p7_0,&_44u9_p7_1},
- {&_44u9_p8_0,&_44u9_p8_1},
- {&_44u9_p9_0,&_44u9_p9_1,&_44u9_p9_2}
- }
- };
-
- static vorbis_residue_template _res_44u_n1[]={
- {1,0, &_residue_44_low_un,
- &_huff_book__44un1__short,&_huff_book__44un1__short,
- &_resbook_44u_n1,&_resbook_44u_n1},
-
- {1,0, &_residue_44_low_un,
- &_huff_book__44un1__long,&_huff_book__44un1__long,
- &_resbook_44u_n1,&_resbook_44u_n1}
- };
- static vorbis_residue_template _res_44u_0[]={
- {1,0, &_residue_44_low_un,
- &_huff_book__44u0__short,&_huff_book__44u0__short,
- &_resbook_44u_0,&_resbook_44u_0},
-
- {1,0, &_residue_44_low_un,
- &_huff_book__44u0__long,&_huff_book__44u0__long,
- &_resbook_44u_0,&_resbook_44u_0}
- };
- static vorbis_residue_template _res_44u_1[]={
- {1,0, &_residue_44_low_un,
- &_huff_book__44u1__short,&_huff_book__44u1__short,
- &_resbook_44u_1,&_resbook_44u_1},
-
- {1,0, &_residue_44_low_un,
- &_huff_book__44u1__long,&_huff_book__44u1__long,
- &_resbook_44u_1,&_resbook_44u_1}
- };
- static vorbis_residue_template _res_44u_2[]={
- {1,0, &_residue_44_low_un,
- &_huff_book__44u2__short,&_huff_book__44u2__short,
- &_resbook_44u_2,&_resbook_44u_2},
-
- {1,0, &_residue_44_low_un,
- &_huff_book__44u2__long,&_huff_book__44u2__long,
- &_resbook_44u_2,&_resbook_44u_2}
- };
- static vorbis_residue_template _res_44u_3[]={
- {1,0, &_residue_44_low_un,
- &_huff_book__44u3__short,&_huff_book__44u3__short,
- &_resbook_44u_3,&_resbook_44u_3},
-
- {1,0, &_residue_44_low_un,
- &_huff_book__44u3__long,&_huff_book__44u3__long,
- &_resbook_44u_3,&_resbook_44u_3}
- };
- static vorbis_residue_template _res_44u_4[]={
- {1,0, &_residue_44_low_un,
- &_huff_book__44u4__short,&_huff_book__44u4__short,
- &_resbook_44u_4,&_resbook_44u_4},
-
- {1,0, &_residue_44_low_un,
- &_huff_book__44u4__long,&_huff_book__44u4__long,
- &_resbook_44u_4,&_resbook_44u_4}
- };
-
- static vorbis_residue_template _res_44u_5[]={
- {1,0, &_residue_44_mid_un,
- &_huff_book__44u5__short,&_huff_book__44u5__short,
- &_resbook_44u_5,&_resbook_44u_5},
-
- {1,0, &_residue_44_mid_un,
- &_huff_book__44u5__long,&_huff_book__44u5__long,
- &_resbook_44u_5,&_resbook_44u_5}
- };
-
- static vorbis_residue_template _res_44u_6[]={
- {1,0, &_residue_44_mid_un,
- &_huff_book__44u6__short,&_huff_book__44u6__short,
- &_resbook_44u_6,&_resbook_44u_6},
-
- {1,0, &_residue_44_mid_un,
- &_huff_book__44u6__long,&_huff_book__44u6__long,
- &_resbook_44u_6,&_resbook_44u_6}
- };
-
- static vorbis_residue_template _res_44u_7[]={
- {1,0, &_residue_44_mid_un,
- &_huff_book__44u7__short,&_huff_book__44u7__short,
- &_resbook_44u_7,&_resbook_44u_7},
-
- {1,0, &_residue_44_mid_un,
- &_huff_book__44u7__long,&_huff_book__44u7__long,
- &_resbook_44u_7,&_resbook_44u_7}
- };
-
- static vorbis_residue_template _res_44u_8[]={
- {1,0, &_residue_44_hi_un,
- &_huff_book__44u8__short,&_huff_book__44u8__short,
- &_resbook_44u_8,&_resbook_44u_8},
-
- {1,0, &_residue_44_hi_un,
- &_huff_book__44u8__long,&_huff_book__44u8__long,
- &_resbook_44u_8,&_resbook_44u_8}
- };
- static vorbis_residue_template _res_44u_9[]={
- {1,0, &_residue_44_hi_un,
- &_huff_book__44u9__short,&_huff_book__44u9__short,
- &_resbook_44u_9,&_resbook_44u_9},
-
- {1,0, &_residue_44_hi_un,
- &_huff_book__44u9__long,&_huff_book__44u9__long,
- &_resbook_44u_9,&_resbook_44u_9}
- };
-
- static vorbis_mapping_template _mapres_template_44_uncoupled[]={
- { _map_nominal_u, _res_44u_n1 }, /* -1 */
- { _map_nominal_u, _res_44u_0 }, /* 0 */
- { _map_nominal_u, _res_44u_1 }, /* 1 */
- { _map_nominal_u, _res_44u_2 }, /* 2 */
- { _map_nominal_u, _res_44u_3 }, /* 3 */
- { _map_nominal_u, _res_44u_4 }, /* 4 */
- { _map_nominal_u, _res_44u_5 }, /* 5 */
- { _map_nominal_u, _res_44u_6 }, /* 6 */
- { _map_nominal_u, _res_44u_7 }, /* 7 */
- { _map_nominal_u, _res_44u_8 }, /* 8 */
- { _map_nominal_u, _res_44u_9 }, /* 9 */
- };
- /********* End of inlined file: residue_44u.h *********/
-
- static double rate_mapping_44_un[12]={
- 32000.,48000.,60000.,70000.,80000.,86000.,
- 96000.,110000.,120000.,140000.,160000.,240001.
- };
-
- ve_setup_data_template ve_setup_44_uncoupled={
- 11,
- rate_mapping_44_un,
- quality_mapping_44,
- -1,
- 40000,
- 50000,
-
- blocksize_short_44,
- blocksize_long_44,
-
- _psy_tone_masteratt_44,
- _psy_tone_0dB,
- _psy_tone_suppress,
-
- _vp_tonemask_adj_otherblock,
- _vp_tonemask_adj_longblock,
- _vp_tonemask_adj_otherblock,
-
- _psy_noiseguards_44,
- _psy_noisebias_impulse,
- _psy_noisebias_padding,
- _psy_noisebias_trans,
- _psy_noisebias_long,
- _psy_noise_suppress,
-
- _psy_compand_44,
- _psy_compand_short_mapping,
- _psy_compand_long_mapping,
-
- {_noise_start_short_44,_noise_start_long_44},
- {_noise_part_short_44,_noise_part_long_44},
- _noise_thresh_44,
-
- _psy_ath_floater,
- _psy_ath_abs,
-
- _psy_lowpass_44,
-
- _psy_global_44,
- _global_mapping_44,
- NULL,
-
- _floor_books,
- _floor,
- _floor_short_mapping_44,
- _floor_long_mapping_44,
-
- _mapres_template_44_uncoupled
- };
- /********* End of inlined file: setup_44u.h *********/
-
- /********* Start of inlined file: setup_32.h *********/
- static double rate_mapping_32[12]={
- 18000.,28000.,35000.,45000.,56000.,60000.,
- 75000.,90000.,100000.,115000.,150000.,190000.,
- };
-
- static double rate_mapping_32_un[12]={
- 30000.,42000.,52000.,64000.,72000.,78000.,
- 86000.,92000.,110000.,120000.,140000.,190000.,
- };
-
- static double _psy_lowpass_32[12]={
- 12.3,13.,13.,14.,15.,99.,99.,99.,99.,99.,99.,99.
- };
-
- ve_setup_data_template ve_setup_32_stereo={
- 11,
- rate_mapping_32,
- quality_mapping_44,
- 2,
- 26000,
- 40000,
-
- blocksize_short_44,
- blocksize_long_44,
-
- _psy_tone_masteratt_44,
- _psy_tone_0dB,
- _psy_tone_suppress,
-
- _vp_tonemask_adj_otherblock,
- _vp_tonemask_adj_longblock,
- _vp_tonemask_adj_otherblock,
-
- _psy_noiseguards_44,
- _psy_noisebias_impulse,
- _psy_noisebias_padding,
- _psy_noisebias_trans,
- _psy_noisebias_long,
- _psy_noise_suppress,
-
- _psy_compand_44,
- _psy_compand_short_mapping,
- _psy_compand_long_mapping,
-
- {_noise_start_short_44,_noise_start_long_44},
- {_noise_part_short_44,_noise_part_long_44},
- _noise_thresh_44,
-
- _psy_ath_floater,
- _psy_ath_abs,
-
- _psy_lowpass_32,
-
- _psy_global_44,
- _global_mapping_44,
- _psy_stereo_modes_44,
-
- _floor_books,
- _floor,
- _floor_short_mapping_44,
- _floor_long_mapping_44,
-
- _mapres_template_44_stereo
- };
-
- ve_setup_data_template ve_setup_32_uncoupled={
- 11,
- rate_mapping_32_un,
- quality_mapping_44,
- -1,
- 26000,
- 40000,
-
- blocksize_short_44,
- blocksize_long_44,
-
- _psy_tone_masteratt_44,
- _psy_tone_0dB,
- _psy_tone_suppress,
-
- _vp_tonemask_adj_otherblock,
- _vp_tonemask_adj_longblock,
- _vp_tonemask_adj_otherblock,
-
- _psy_noiseguards_44,
- _psy_noisebias_impulse,
- _psy_noisebias_padding,
- _psy_noisebias_trans,
- _psy_noisebias_long,
- _psy_noise_suppress,
-
- _psy_compand_44,
- _psy_compand_short_mapping,
- _psy_compand_long_mapping,
-
- {_noise_start_short_44,_noise_start_long_44},
- {_noise_part_short_44,_noise_part_long_44},
- _noise_thresh_44,
-
- _psy_ath_floater,
- _psy_ath_abs,
-
- _psy_lowpass_32,
-
- _psy_global_44,
- _global_mapping_44,
- NULL,
-
- _floor_books,
- _floor,
- _floor_short_mapping_44,
- _floor_long_mapping_44,
-
- _mapres_template_44_uncoupled
- };
- /********* End of inlined file: setup_32.h *********/
-
- /********* Start of inlined file: setup_8.h *********/
-
- /********* Start of inlined file: psych_8.h *********/
- static att3 _psy_tone_masteratt_8[3]={
- {{ 32, 25, 12}, 0, 0}, /* 0 */
- {{ 30, 25, 12}, 0, 0}, /* 0 */
- {{ 20, 0, -14}, 0, 0}, /* 0 */
- };
-
- static vp_adjblock _vp_tonemask_adj_8[3]={
- /* adjust for mode zero */
- /* 63 125 250 500 1 2 4 8 16 */
- {{-15,-15,-15,-15,-10,-10, -6, 0, 0, 0, 0,10, 0, 0,99,99,99}}, /* 1 */
- {{-15,-15,-15,-15,-10,-10, -6, 0, 0, 0, 0,10, 0, 0,99,99,99}}, /* 1 */
- {{-15,-15,-15,-15,-10,-10, -6, 0, 0, 0, 0, 0, 0, 0,99,99,99}}, /* 1 */
- };
-
- static noise3 _psy_noisebias_8[3]={
- /* 63 125 250 500 1k 2k 4k 8k 16k*/
- {{{-10,-10,-10,-10, -5, -5, -5, 0, 4, 8, 8, 8, 10, 10, 99, 99, 99},
- {-10,-10,-10,-10, -5, -5, -5, 0, 0, 4, 4, 4, 4, 4, 99, 99, 99},
- {-30,-30,-30,-30,-30,-24,-20,-14,-10, -6, -8, -8, -6, -6, 99, 99, 99}}},
-
- {{{-10,-10,-10,-10, -5, -5, -5, 0, 4, 8, 8, 8, 10, 10, 99, 99, 99},
- {-10,-10,-10,-10,-10,-10, -5, -5, -5, 0, 0, 0, 0, 0, 99, 99, 99},
- {-30,-30,-30,-30,-30,-24,-20,-14,-10, -6, -8, -8, -6, -6, 99, 99, 99}}},
-
- {{{-15,-15,-15,-15,-15,-12,-10, -8, 0, 2, 4, 4, 5, 5, 99, 99, 99},
- {-30,-30,-30,-30,-26,-22,-20,-14,-12,-12,-10,-10,-10,-10, 99, 99, 99},
- {-30,-30,-30,-30,-26,-26,-26,-26,-26,-26,-26,-26,-26,-24, 99, 99, 99}}},
- };
-
- /* stereo mode by base quality level */
- static adj_stereo _psy_stereo_modes_8[3]={
- /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 */
- {{ 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
- { 6, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4},
- { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
- { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}},
- {{ 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
- { 6, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4},
- { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
- { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}},
- {{ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
- { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4},
- { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
- { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}},
- };
-
- static noiseguard _psy_noiseguards_8[2]={
- {10,10,-1},
- {10,10,-1},
- };
-
- static compandblock _psy_compand_8[2]={
- {{
- 0, 1, 2, 3, 4, 5, 6, 7, /* 7dB */
- 8, 8, 9, 9,10,10,11, 11, /* 15dB */
- 12,12,13,13,14,14,15, 15, /* 23dB */
- 16,16,17,17,17,18,18, 19, /* 31dB */
- 19,19,20,21,22,23,24, 25, /* 39dB */
- }},
- {{
- 0, 1, 2, 3, 4, 5, 6, 6, /* 7dB */
- 7, 7, 6, 6, 5, 5, 4, 4, /* 15dB */
- 3, 3, 3, 4, 5, 6, 7, 8, /* 23dB */
- 9,10,11,12,13,14,15, 16, /* 31dB */
- 17,18,19,20,21,22,23, 24, /* 39dB */
- }},
- };
-
- static double _psy_lowpass_8[3]={3.,4.,4.};
- static int _noise_start_8[2]={
- 64,64,
- };
- static int _noise_part_8[2]={
- 8,8,
- };
-
- static int _psy_ath_floater_8[3]={
- -100,-100,-105,
- };
-
- static int _psy_ath_abs_8[3]={
- -130,-130,-140,
- };
- /********* End of inlined file: psych_8.h *********/
-
- /********* Start of inlined file: residue_8.h *********/
-
- /***** residue backends *********************************************/
-
- static static_bookblock _resbook_8s_0={
- {
- {0},{0,0,&_8c0_s_p1_0},{0,0,&_8c0_s_p2_0},{0,0,&_8c0_s_p3_0},
- {0,0,&_8c0_s_p4_0},{0,0,&_8c0_s_p5_0},{0,0,&_8c0_s_p6_0},
- {&_8c0_s_p7_0,&_8c0_s_p7_1},{&_8c0_s_p8_0,&_8c0_s_p8_1},
- {&_8c0_s_p9_0,&_8c0_s_p9_1,&_8c0_s_p9_2}
- }
- };
- static static_bookblock _resbook_8s_1={
- {
- {0},{0,0,&_8c1_s_p1_0},{0,0,&_8c1_s_p2_0},{0,0,&_8c1_s_p3_0},
- {0,0,&_8c1_s_p4_0},{0,0,&_8c1_s_p5_0},{0,0,&_8c1_s_p6_0},
- {&_8c1_s_p7_0,&_8c1_s_p7_1},{&_8c1_s_p8_0,&_8c1_s_p8_1},
- {&_8c1_s_p9_0,&_8c1_s_p9_1,&_8c1_s_p9_2}
- }
- };
-
- static vorbis_residue_template _res_8s_0[]={
- {2,0, &_residue_44_mid,
- &_huff_book__8c0_s_single,&_huff_book__8c0_s_single,
- &_resbook_8s_0,&_resbook_8s_0},
- };
- static vorbis_residue_template _res_8s_1[]={
- {2,0, &_residue_44_mid,
- &_huff_book__8c1_s_single,&_huff_book__8c1_s_single,
- &_resbook_8s_1,&_resbook_8s_1},
- };
-
- static vorbis_mapping_template _mapres_template_8_stereo[2]={
- { _map_nominal, _res_8s_0 }, /* 0 */
- { _map_nominal, _res_8s_1 }, /* 1 */
- };
-
- static static_bookblock _resbook_8u_0={
- {
- {0},
- {0,0,&_8u0__p1_0},
- {0,0,&_8u0__p2_0},
- {0,0,&_8u0__p3_0},
- {0,0,&_8u0__p4_0},
- {0,0,&_8u0__p5_0},
- {&_8u0__p6_0,&_8u0__p6_1},
- {&_8u0__p7_0,&_8u0__p7_1,&_8u0__p7_2}
- }
- };
- static static_bookblock _resbook_8u_1={
- {
- {0},
- {0,0,&_8u1__p1_0},
- {0,0,&_8u1__p2_0},
- {0,0,&_8u1__p3_0},
- {0,0,&_8u1__p4_0},
- {0,0,&_8u1__p5_0},
- {0,0,&_8u1__p6_0},
- {&_8u1__p7_0,&_8u1__p7_1},
- {&_8u1__p8_0,&_8u1__p8_1},
- {&_8u1__p9_0,&_8u1__p9_1,&_8u1__p9_2}
- }
- };
-
- static vorbis_residue_template _res_8u_0[]={
- {1,0, &_residue_44_low_un,
- &_huff_book__8u0__single,&_huff_book__8u0__single,
- &_resbook_8u_0,&_resbook_8u_0},
- };
- static vorbis_residue_template _res_8u_1[]={
- {1,0, &_residue_44_mid_un,
- &_huff_book__8u1__single,&_huff_book__8u1__single,
- &_resbook_8u_1,&_resbook_8u_1},
- };
-
- static vorbis_mapping_template _mapres_template_8_uncoupled[2]={
- { _map_nominal_u, _res_8u_0 }, /* 0 */
- { _map_nominal_u, _res_8u_1 }, /* 1 */
- };
- /********* End of inlined file: residue_8.h *********/
-
- static int blocksize_8[2]={
- 512,512
- };
-
- static int _floor_mapping_8[2]={
- 6,6,
- };
-
- static double rate_mapping_8[3]={
- 6000.,9000.,32000.,
- };
-
- static double rate_mapping_8_uncoupled[3]={
- 8000.,14000.,42000.,
- };
-
- static double quality_mapping_8[3]={
- -.1,.0,1.
- };
-
- static double _psy_compand_8_mapping[3]={ 0., 1., 1.};
-
- static double _global_mapping_8[3]={ 1., 2., 3. };
-
- ve_setup_data_template ve_setup_8_stereo={
- 2,
- rate_mapping_8,
- quality_mapping_8,
- 2,
- 8000,
- 9000,
-
- blocksize_8,
- blocksize_8,
-
- _psy_tone_masteratt_8,
- _psy_tone_0dB,
- _psy_tone_suppress,
-
- _vp_tonemask_adj_8,
- NULL,
- _vp_tonemask_adj_8,
-
- _psy_noiseguards_8,
- _psy_noisebias_8,
- _psy_noisebias_8,
- NULL,
- NULL,
- _psy_noise_suppress,
-
- _psy_compand_8,
- _psy_compand_8_mapping,
- NULL,
-
- {_noise_start_8,_noise_start_8},
- {_noise_part_8,_noise_part_8},
- _noise_thresh_5only,
-
- _psy_ath_floater_8,
- _psy_ath_abs_8,
-
- _psy_lowpass_8,
-
- _psy_global_44,
- _global_mapping_8,
- _psy_stereo_modes_8,
-
- _floor_books,
- _floor,
- _floor_mapping_8,
- NULL,
-
- _mapres_template_8_stereo
- };
-
- ve_setup_data_template ve_setup_8_uncoupled={
- 2,
- rate_mapping_8_uncoupled,
- quality_mapping_8,
- -1,
- 8000,
- 9000,
-
- blocksize_8,
- blocksize_8,
-
- _psy_tone_masteratt_8,
- _psy_tone_0dB,
- _psy_tone_suppress,
-
- _vp_tonemask_adj_8,
- NULL,
- _vp_tonemask_adj_8,
-
- _psy_noiseguards_8,
- _psy_noisebias_8,
- _psy_noisebias_8,
- NULL,
- NULL,
- _psy_noise_suppress,
-
- _psy_compand_8,
- _psy_compand_8_mapping,
- NULL,
-
- {_noise_start_8,_noise_start_8},
- {_noise_part_8,_noise_part_8},
- _noise_thresh_5only,
-
- _psy_ath_floater_8,
- _psy_ath_abs_8,
-
- _psy_lowpass_8,
-
- _psy_global_44,
- _global_mapping_8,
- _psy_stereo_modes_8,
-
- _floor_books,
- _floor,
- _floor_mapping_8,
- NULL,
-
- _mapres_template_8_uncoupled
- };
- /********* End of inlined file: setup_8.h *********/
-
- /********* Start of inlined file: setup_11.h *********/
-
- /********* Start of inlined file: psych_11.h *********/
- static double _psy_lowpass_11[3]={4.5,5.5,30.,};
-
- static att3 _psy_tone_masteratt_11[3]={
- {{ 30, 25, 12}, 0, 0}, /* 0 */
- {{ 30, 25, 12}, 0, 0}, /* 0 */
- {{ 20, 0, -14}, 0, 0}, /* 0 */
- };
-
- static vp_adjblock _vp_tonemask_adj_11[3]={
- /* adjust for mode zero */
- /* 63 125 250 500 1 2 4 8 16 */
- {{-20,-20,-20,-20,-20,-16,-10, 0, 0, 0, 0,10, 2, 0,99,99,99}}, /* 0 */
- {{-20,-20,-20,-20,-20,-16,-10, 0, 0, 0, 0, 5, 0, 0,99,99,99}}, /* 1 */
- {{-20,-20,-20,-20,-20,-16,-10, 0, 0, 0, 0, 0, 0, 0,99,99,99}}, /* 2 */
- };
-
- static noise3 _psy_noisebias_11[3]={
- /* 63 125 250 500 1k 2k 4k 8k 16k*/
- {{{-10,-10,-10,-10, -5, -5, -5, 0, 4, 10, 10, 12, 12, 12, 99, 99, 99},
- {-15,-15,-15,-15,-10,-10, -5, 0, 0, 4, 4, 5, 5, 10, 99, 99, 99},
- {-30,-30,-30,-30,-30,-24,-20,-14,-10, -6, -8, -8, -6, -6, 99, 99, 99}}},
-
- {{{-10,-10,-10,-10, -5, -5, -5, 0, 4, 10, 10, 12, 12, 12, 99, 99, 99},
- {-15,-15,-15,-15,-10,-10, -5, -5, -5, 0, 0, 0, 0, 0, 99, 99, 99},
- {-30,-30,-30,-30,-30,-24,-20,-14,-10, -6, -8, -8, -6, -6, 99, 99, 99}}},
-
- {{{-15,-15,-15,-15,-15,-12,-10, -8, 0, 2, 4, 4, 5, 5, 99, 99, 99},
- {-30,-30,-30,-30,-26,-22,-20,-14,-12,-12,-10,-10,-10,-10, 99, 99, 99},
- {-30,-30,-30,-30,-26,-26,-26,-26,-26,-26,-26,-26,-26,-24, 99, 99, 99}}},
- };
-
- static double _noise_thresh_11[3]={ .3,.5,.5 };
- /********* End of inlined file: psych_11.h *********/
-
- static int blocksize_11[2]={
- 512,512
- };
-
- static int _floor_mapping_11[2]={
- 6,6,
- };
-
- static double rate_mapping_11[3]={
- 8000.,13000.,44000.,
- };
-
- static double rate_mapping_11_uncoupled[3]={
- 12000.,20000.,50000.,
- };
-
- static double quality_mapping_11[3]={
- -.1,.0,1.
- };
-
- ve_setup_data_template ve_setup_11_stereo={
- 2,
- rate_mapping_11,
- quality_mapping_11,
- 2,
- 9000,
- 15000,
-
- blocksize_11,
- blocksize_11,
-
- _psy_tone_masteratt_11,
- _psy_tone_0dB,
- _psy_tone_suppress,
-
- _vp_tonemask_adj_11,
- NULL,
- _vp_tonemask_adj_11,
-
- _psy_noiseguards_8,
- _psy_noisebias_11,
- _psy_noisebias_11,
- NULL,
- NULL,
- _psy_noise_suppress,
-
- _psy_compand_8,
- _psy_compand_8_mapping,
- NULL,
-
- {_noise_start_8,_noise_start_8},
- {_noise_part_8,_noise_part_8},
- _noise_thresh_11,
-
- _psy_ath_floater_8,
- _psy_ath_abs_8,
-
- _psy_lowpass_11,
-
- _psy_global_44,
- _global_mapping_8,
- _psy_stereo_modes_8,
-
- _floor_books,
- _floor,
- _floor_mapping_11,
- NULL,
-
- _mapres_template_8_stereo
- };
-
- ve_setup_data_template ve_setup_11_uncoupled={
- 2,
- rate_mapping_11_uncoupled,
- quality_mapping_11,
- -1,
- 9000,
- 15000,
-
- blocksize_11,
- blocksize_11,
-
- _psy_tone_masteratt_11,
- _psy_tone_0dB,
- _psy_tone_suppress,
-
- _vp_tonemask_adj_11,
- NULL,
- _vp_tonemask_adj_11,
-
- _psy_noiseguards_8,
- _psy_noisebias_11,
- _psy_noisebias_11,
- NULL,
- NULL,
- _psy_noise_suppress,
-
- _psy_compand_8,
- _psy_compand_8_mapping,
- NULL,
-
- {_noise_start_8,_noise_start_8},
- {_noise_part_8,_noise_part_8},
- _noise_thresh_11,
-
- _psy_ath_floater_8,
- _psy_ath_abs_8,
-
- _psy_lowpass_11,
-
- _psy_global_44,
- _global_mapping_8,
- _psy_stereo_modes_8,
-
- _floor_books,
- _floor,
- _floor_mapping_11,
- NULL,
-
- _mapres_template_8_uncoupled
- };
- /********* End of inlined file: setup_11.h *********/
-
- /********* Start of inlined file: setup_16.h *********/
-
- /********* Start of inlined file: psych_16.h *********/
- /* stereo mode by base quality level */
- static adj_stereo _psy_stereo_modes_16[4]={
- /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 */
- {{ 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
- { 6, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4},
- { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 4, 4},
- { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}},
- {{ 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
- { 6, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4},
- { 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 4, 4, 4, 4, 4},
- { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}},
- {{ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
- { 5, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
- { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4},
- { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}},
- {{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- { 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8},
- { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}},
- };
-
- static double _psy_lowpass_16[4]={6.5,8,30.,99.};
-
- static att3 _psy_tone_masteratt_16[4]={
- {{ 30, 25, 12}, 0, 0}, /* 0 */
- {{ 25, 22, 12}, 0, 0}, /* 0 */
- {{ 20, 12, 0}, 0, 0}, /* 0 */
- {{ 15, 0, -14}, 0, 0}, /* 0 */
- };
-
- static vp_adjblock _vp_tonemask_adj_16[4]={
- /* adjust for mode zero */
- /* 63 125 250 500 1 2 4 8 16 */
- {{-20,-20,-20,-20,-20,-16,-10, 0, 0, 0, 0,10, 0, 0, 0, 0, 0}}, /* 0 */
- {{-20,-20,-20,-20,-20,-16,-10, 0, 0, 0, 0,10, 0, 0, 0, 0, 0}}, /* 1 */
- {{-20,-20,-20,-20,-20,-16,-10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 2 */
- {{-30,-30,-30,-30,-30,-26,-20,-10, -5, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 2 */
- };
-
- static noise3 _psy_noisebias_16_short[4]={
- /* 63 125 250 500 1k 2k 4k 8k 16k*/
- {{{-15,-15,-15,-15,-15,-10,-10,-5, 4, 10, 10, 10, 10, 12, 12, 14, 20},
- {-15,-15,-15,-15,-15,-10,-10, -5, 0, 0, 4, 5, 5, 6, 8, 8, 15},
- {-30,-30,-30,-30,-30,-24,-20,-14,-10, -6, -8, -8, -6, -6, -6, -6, -6}}},
-
- {{{-15,-15,-15,-15,-15,-10,-10,-5, 4, 6, 6, 6, 6, 8, 10, 12, 20},
- {-15,-15,-15,-15,-15,-15,-15,-10, -5, -5, -5, 4, 5, 6, 8, 8, 15},
- {-30,-30,-30,-30,-30,-24,-20,-14,-10,-10,-10,-10,-10,-10,-10,-10,-10}}},
-
- {{{-15,-15,-15,-15,-15,-12,-10, -8, 0, 2, 4, 4, 5, 5, 5, 8, 12},
- {-20,-20,-20,-20,-16,-12,-20,-14,-10,-10, -8, 0, 0, 0, 0, 2, 5},
- {-30,-30,-30,-30,-26,-26,-26,-26,-26,-26,-26,-26,-26,-24,-20,-20,-20}}},
-
- {{{-15,-15,-15,-15,-15,-12,-10, -8, -5, -5, -5, -5, -5, 0, 0, 0, 6},
- {-30,-30,-30,-30,-26,-22,-20,-14,-12,-12,-10,-10,-10,-10,-10,-10, -6},
- {-30,-30,-30,-30,-26,-26,-26,-26,-26,-26,-26,-26,-26,-24,-20,-20,-20}}},
- };
-
- static noise3 _psy_noisebias_16_impulse[4]={
- /* 63 125 250 500 1k 2k 4k 8k 16k*/
- {{{-15,-15,-15,-15,-15,-10,-10,-5, 4, 10, 10, 10, 10, 12, 12, 14, 20},
- {-15,-15,-15,-15,-15,-10,-10, -5, 0, 0, 4, 5, 5, 6, 8, 8, 15},
- {-30,-30,-30,-30,-30,-24,-20,-14,-10, -6, -8, -8, -6, -6, -6, -6, -6}}},
-
- {{{-15,-15,-15,-15,-15,-10,-10,-5, 4, 4, 4, 4, 5, 5, 6, 8, 15},
- {-15,-15,-15,-15,-15,-15,-15,-10, -5, -5, -5, 0, 0, 0, 0, 4, 10},
- {-30,-30,-30,-30,-30,-24,-20,-14,-10,-10,-10,-10,-10,-10,-10,-10,-10}}},
-
- {{{-15,-15,-15,-15,-15,-12,-10, -8, 0, 0, 0, 0, 0, 0, 0, 4, 10},
- {-20,-20,-20,-20,-16,-12,-20,-14,-10,-10,-10,-10,-10,-10,-10, -7, -5},
- {-30,-30,-30,-30,-26,-26,-26,-26,-26,-26,-26,-26,-26,-24,-20,-20,-20}}},
-
- {{{-15,-15,-15,-15,-15,-12,-10, -8, -5, -5, -5, -5, -5, 0, 0, 0, 6},
- {-30,-30,-30,-30,-26,-22,-20,-18,-18,-18,-20,-20,-20,-20,-20,-20,-16},
- {-30,-30,-30,-30,-26,-26,-26,-26,-26,-26,-26,-26,-26,-24,-20,-20,-20}}},
- };
-
- static noise3 _psy_noisebias_16[4]={
- /* 63 125 250 500 1k 2k 4k 8k 16k*/
- {{{-10,-10,-10,-10, -5, -5, -5, 0, 4, 6, 8, 8, 10, 10, 10, 14, 20},
- {-10,-10,-10,-10,-10, -5, -2, -2, 0, 0, 0, 4, 5, 6, 8, 8, 15},
- {-30,-30,-30,-30,-30,-24,-20,-14,-10, -6, -8, -8, -6, -6, -6, -6, -6}}},
-
- {{{-10,-10,-10,-10, -5, -5, -5, 0, 4, 6, 6, 6, 6, 8, 10, 12, 20},
- {-15,-15,-15,-15,-15,-10, -5, -5, 0, 0, 0, 4, 5, 6, 8, 8, 15},
- {-30,-30,-30,-30,-30,-24,-20,-14,-10, -6, -8, -8, -6, -6, -6, -6, -6}}},
-
- {{{-15,-15,-15,-15,-15,-12,-10, -8, 0, 2, 4, 4, 5, 5, 5, 8, 12},
- {-20,-20,-20,-20,-16,-12,-20,-10, -5, -5, 0, 0, 0, 0, 0, 2, 5},
- {-30,-30,-30,-30,-26,-26,-26,-26,-26,-26,-26,-26,-26,-24,-20,-20,-20}}},
-
- {{{-15,-15,-15,-15,-15,-12,-10, -8, -5, -5, -5, -5, -5, 0, 0, 0, 6},
- {-30,-30,-30,-30,-26,-22,-20,-14,-12,-12,-10,-10,-10,-10,-10,-10, -6},
- {-30,-30,-30,-30,-26,-26,-26,-26,-26,-26,-26,-26,-26,-24,-20,-20,-20}}},
- };
-
- static double _noise_thresh_16[4]={ .3,.5,.5,.5 };
-
- static int _noise_start_16[3]={ 256,256,9999 };
- static int _noise_part_16[4]={ 8,8,8,8 };
-
- static int _psy_ath_floater_16[4]={
- -100,-100,-100,-105,
- };
-
- static int _psy_ath_abs_16[4]={
- -130,-130,-130,-140,
- };
- /********* End of inlined file: psych_16.h *********/
-
- /********* Start of inlined file: residue_16.h *********/
- /***** residue backends *********************************************/
-
- static static_bookblock _resbook_16s_0={
- {
- {0},
- {0,0,&_16c0_s_p1_0},
- {0,0,&_16c0_s_p2_0},
- {0,0,&_16c0_s_p3_0},
- {0,0,&_16c0_s_p4_0},
- {0,0,&_16c0_s_p5_0},
- {0,0,&_16c0_s_p6_0},
- {&_16c0_s_p7_0,&_16c0_s_p7_1},
- {&_16c0_s_p8_0,&_16c0_s_p8_1},
- {&_16c0_s_p9_0,&_16c0_s_p9_1,&_16c0_s_p9_2}
- }
- };
- static static_bookblock _resbook_16s_1={
- {
- {0},
- {0,0,&_16c1_s_p1_0},
- {0,0,&_16c1_s_p2_0},
- {0,0,&_16c1_s_p3_0},
- {0,0,&_16c1_s_p4_0},
- {0,0,&_16c1_s_p5_0},
- {0,0,&_16c1_s_p6_0},
- {&_16c1_s_p7_0,&_16c1_s_p7_1},
- {&_16c1_s_p8_0,&_16c1_s_p8_1},
- {&_16c1_s_p9_0,&_16c1_s_p9_1,&_16c1_s_p9_2}
- }
- };
- static static_bookblock _resbook_16s_2={
- {
- {0},
- {0,0,&_16c2_s_p1_0},
- {0,0,&_16c2_s_p2_0},
- {0,0,&_16c2_s_p3_0},
- {0,0,&_16c2_s_p4_0},
- {&_16c2_s_p5_0,&_16c2_s_p5_1},
- {&_16c2_s_p6_0,&_16c2_s_p6_1},
- {&_16c2_s_p7_0,&_16c2_s_p7_1},
- {&_16c2_s_p8_0,&_16c2_s_p8_1},
- {&_16c2_s_p9_0,&_16c2_s_p9_1,&_16c2_s_p9_2}
- }
- };
-
- static vorbis_residue_template _res_16s_0[]={
- {2,0, &_residue_44_mid,
- &_huff_book__16c0_s_single,&_huff_book__16c0_s_single,
- &_resbook_16s_0,&_resbook_16s_0},
- };
- static vorbis_residue_template _res_16s_1[]={
- {2,0, &_residue_44_mid,
- &_huff_book__16c1_s_short,&_huff_book__16c1_s_short,
- &_resbook_16s_1,&_resbook_16s_1},
-
- {2,0, &_residue_44_mid,
- &_huff_book__16c1_s_long,&_huff_book__16c1_s_long,
- &_resbook_16s_1,&_resbook_16s_1}
- };
- static vorbis_residue_template _res_16s_2[]={
- {2,0, &_residue_44_high,
- &_huff_book__16c2_s_short,&_huff_book__16c2_s_short,
- &_resbook_16s_2,&_resbook_16s_2},
-
- {2,0, &_residue_44_high,
- &_huff_book__16c2_s_long,&_huff_book__16c2_s_long,
- &_resbook_16s_2,&_resbook_16s_2}
- };
-
- static vorbis_mapping_template _mapres_template_16_stereo[3]={
- { _map_nominal, _res_16s_0 }, /* 0 */
- { _map_nominal, _res_16s_1 }, /* 1 */
- { _map_nominal, _res_16s_2 }, /* 2 */
- };
-
- static static_bookblock _resbook_16u_0={
- {
- {0},
- {0,0,&_16u0__p1_0},
- {0,0,&_16u0__p2_0},
- {0,0,&_16u0__p3_0},
- {0,0,&_16u0__p4_0},
- {0,0,&_16u0__p5_0},
- {&_16u0__p6_0,&_16u0__p6_1},
- {&_16u0__p7_0,&_16u0__p7_1,&_16u0__p7_2}
- }
- };
- static static_bookblock _resbook_16u_1={
- {
- {0},
- {0,0,&_16u1__p1_0},
- {0,0,&_16u1__p2_0},
- {0,0,&_16u1__p3_0},
- {0,0,&_16u1__p4_0},
- {0,0,&_16u1__p5_0},
- {0,0,&_16u1__p6_0},
- {&_16u1__p7_0,&_16u1__p7_1},
- {&_16u1__p8_0,&_16u1__p8_1},
- {&_16u1__p9_0,&_16u1__p9_1,&_16u1__p9_2}
- }
- };
- static static_bookblock _resbook_16u_2={
- {
- {0},
- {0,0,&_16u2_p1_0},
- {0,0,&_16u2_p2_0},
- {0,0,&_16u2_p3_0},
- {0,0,&_16u2_p4_0},
- {&_16u2_p5_0,&_16u2_p5_1},
- {&_16u2_p6_0,&_16u2_p6_1},
- {&_16u2_p7_0,&_16u2_p7_1},
- {&_16u2_p8_0,&_16u2_p8_1},
- {&_16u2_p9_0,&_16u2_p9_1,&_16u2_p9_2}
- }
- };
-
- static vorbis_residue_template _res_16u_0[]={
- {1,0, &_residue_44_low_un,
- &_huff_book__16u0__single,&_huff_book__16u0__single,
- &_resbook_16u_0,&_resbook_16u_0},
- };
- static vorbis_residue_template _res_16u_1[]={
- {1,0, &_residue_44_mid_un,
- &_huff_book__16u1__short,&_huff_book__16u1__short,
- &_resbook_16u_1,&_resbook_16u_1},
-
- {1,0, &_residue_44_mid_un,
- &_huff_book__16u1__long,&_huff_book__16u1__long,
- &_resbook_16u_1,&_resbook_16u_1}
- };
- static vorbis_residue_template _res_16u_2[]={
- {1,0, &_residue_44_hi_un,
- &_huff_book__16u2__short,&_huff_book__16u2__short,
- &_resbook_16u_2,&_resbook_16u_2},
-
- {1,0, &_residue_44_hi_un,
- &_huff_book__16u2__long,&_huff_book__16u2__long,
- &_resbook_16u_2,&_resbook_16u_2}
- };
-
- static vorbis_mapping_template _mapres_template_16_uncoupled[3]={
- { _map_nominal_u, _res_16u_0 }, /* 0 */
- { _map_nominal_u, _res_16u_1 }, /* 1 */
- { _map_nominal_u, _res_16u_2 }, /* 2 */
- };
- /********* End of inlined file: residue_16.h *********/
-
- static int blocksize_16_short[3]={
- 1024,512,512
- };
- static int blocksize_16_long[3]={
- 1024,1024,1024
- };
-
- static int _floor_mapping_16_short[3]={
- 9,3,3
- };
- static int _floor_mapping_16[3]={
- 9,9,9
- };
-
- static double rate_mapping_16[4]={
- 12000.,20000.,44000.,86000.
- };
-
- static double rate_mapping_16_uncoupled[4]={
- 16000.,28000.,64000.,100000.
- };
-
- static double _global_mapping_16[4]={ 1., 2., 3., 4. };
-
- static double quality_mapping_16[4]={ -.1,.05,.5,1. };
-
- static double _psy_compand_16_mapping[4]={ 0., .8, 1., 1.};
-
- ve_setup_data_template ve_setup_16_stereo={
- 3,
- rate_mapping_16,
- quality_mapping_16,
- 2,
- 15000,
- 19000,
-
- blocksize_16_short,
- blocksize_16_long,
-
- _psy_tone_masteratt_16,
- _psy_tone_0dB,
- _psy_tone_suppress,
-
- _vp_tonemask_adj_16,
- _vp_tonemask_adj_16,
- _vp_tonemask_adj_16,
-
- _psy_noiseguards_8,
- _psy_noisebias_16_impulse,
- _psy_noisebias_16_short,
- _psy_noisebias_16_short,
- _psy_noisebias_16,
- _psy_noise_suppress,
-
- _psy_compand_8,
- _psy_compand_16_mapping,
- _psy_compand_16_mapping,
-
- {_noise_start_16,_noise_start_16},
- { _noise_part_16, _noise_part_16},
- _noise_thresh_16,
-
- _psy_ath_floater_16,
- _psy_ath_abs_16,
-
- _psy_lowpass_16,
-
- _psy_global_44,
- _global_mapping_16,
- _psy_stereo_modes_16,
-
- _floor_books,
- _floor,
- _floor_mapping_16_short,
- _floor_mapping_16,
-
- _mapres_template_16_stereo
- };
-
- ve_setup_data_template ve_setup_16_uncoupled={
- 3,
- rate_mapping_16_uncoupled,
- quality_mapping_16,
- -1,
- 15000,
- 19000,
-
- blocksize_16_short,
- blocksize_16_long,
-
- _psy_tone_masteratt_16,
- _psy_tone_0dB,
- _psy_tone_suppress,
-
- _vp_tonemask_adj_16,
- _vp_tonemask_adj_16,
- _vp_tonemask_adj_16,
-
- _psy_noiseguards_8,
- _psy_noisebias_16_impulse,
- _psy_noisebias_16_short,
- _psy_noisebias_16_short,
- _psy_noisebias_16,
- _psy_noise_suppress,
-
- _psy_compand_8,
- _psy_compand_16_mapping,
- _psy_compand_16_mapping,
-
- {_noise_start_16,_noise_start_16},
- { _noise_part_16, _noise_part_16},
- _noise_thresh_16,
-
- _psy_ath_floater_16,
- _psy_ath_abs_16,
-
- _psy_lowpass_16,
-
- _psy_global_44,
- _global_mapping_16,
- _psy_stereo_modes_16,
-
- _floor_books,
- _floor,
- _floor_mapping_16_short,
- _floor_mapping_16,
-
- _mapres_template_16_uncoupled
- };
- /********* End of inlined file: setup_16.h *********/
-
- /********* Start of inlined file: setup_22.h *********/
- static double rate_mapping_22[4]={
- 15000.,20000.,44000.,86000.
- };
-
- static double rate_mapping_22_uncoupled[4]={
- 16000.,28000.,50000.,90000.
- };
-
- static double _psy_lowpass_22[4]={9.5,11.,30.,99.};
-
- ve_setup_data_template ve_setup_22_stereo={
- 3,
- rate_mapping_22,
- quality_mapping_16,
- 2,
- 19000,
- 26000,
-
- blocksize_16_short,
- blocksize_16_long,
-
- _psy_tone_masteratt_16,
- _psy_tone_0dB,
- _psy_tone_suppress,
-
- _vp_tonemask_adj_16,
- _vp_tonemask_adj_16,
- _vp_tonemask_adj_16,
-
- _psy_noiseguards_8,
- _psy_noisebias_16_impulse,
- _psy_noisebias_16_short,
- _psy_noisebias_16_short,
- _psy_noisebias_16,
- _psy_noise_suppress,
-
- _psy_compand_8,
- _psy_compand_8_mapping,
- _psy_compand_8_mapping,
-
- {_noise_start_16,_noise_start_16},
- { _noise_part_16, _noise_part_16},
- _noise_thresh_16,
-
- _psy_ath_floater_16,
- _psy_ath_abs_16,
-
- _psy_lowpass_22,
-
- _psy_global_44,
- _global_mapping_16,
- _psy_stereo_modes_16,
-
- _floor_books,
- _floor,
- _floor_mapping_16_short,
- _floor_mapping_16,
-
- _mapres_template_16_stereo
- };
-
- ve_setup_data_template ve_setup_22_uncoupled={
- 3,
- rate_mapping_22_uncoupled,
- quality_mapping_16,
- -1,
- 19000,
- 26000,
-
- blocksize_16_short,
- blocksize_16_long,
-
- _psy_tone_masteratt_16,
- _psy_tone_0dB,
- _psy_tone_suppress,
-
- _vp_tonemask_adj_16,
- _vp_tonemask_adj_16,
- _vp_tonemask_adj_16,
-
- _psy_noiseguards_8,
- _psy_noisebias_16_impulse,
- _psy_noisebias_16_short,
- _psy_noisebias_16_short,
- _psy_noisebias_16,
- _psy_noise_suppress,
-
- _psy_compand_8,
- _psy_compand_8_mapping,
- _psy_compand_8_mapping,
-
- {_noise_start_16,_noise_start_16},
- { _noise_part_16, _noise_part_16},
- _noise_thresh_16,
-
- _psy_ath_floater_16,
- _psy_ath_abs_16,
-
- _psy_lowpass_22,
-
- _psy_global_44,
- _global_mapping_16,
- _psy_stereo_modes_16,
-
- _floor_books,
- _floor,
- _floor_mapping_16_short,
- _floor_mapping_16,
-
- _mapres_template_16_uncoupled
- };
- /********* End of inlined file: setup_22.h *********/
-
- /********* Start of inlined file: setup_X.h *********/
- static double rate_mapping_X[12]={
- -1.,-1.,-1.,-1.,-1.,-1.,
- -1.,-1.,-1.,-1.,-1.,-1.
- };
-
- ve_setup_data_template ve_setup_X_stereo={
- 11,
- rate_mapping_X,
- quality_mapping_44,
- 2,
- 50000,
- 200000,
-
- blocksize_short_44,
- blocksize_long_44,
-
- _psy_tone_masteratt_44,
- _psy_tone_0dB,
- _psy_tone_suppress,
-
- _vp_tonemask_adj_otherblock,
- _vp_tonemask_adj_longblock,
- _vp_tonemask_adj_otherblock,
-
- _psy_noiseguards_44,
- _psy_noisebias_impulse,
- _psy_noisebias_padding,
- _psy_noisebias_trans,
- _psy_noisebias_long,
- _psy_noise_suppress,
-
- _psy_compand_44,
- _psy_compand_short_mapping,
- _psy_compand_long_mapping,
-
- {_noise_start_short_44,_noise_start_long_44},
- {_noise_part_short_44,_noise_part_long_44},
- _noise_thresh_44,
-
- _psy_ath_floater,
- _psy_ath_abs,
-
- _psy_lowpass_44,
-
- _psy_global_44,
- _global_mapping_44,
- _psy_stereo_modes_44,
-
- _floor_books,
- _floor,
- _floor_short_mapping_44,
- _floor_long_mapping_44,
-
- _mapres_template_44_stereo
- };
-
- ve_setup_data_template ve_setup_X_uncoupled={
- 11,
- rate_mapping_X,
- quality_mapping_44,
- -1,
- 50000,
- 200000,
-
- blocksize_short_44,
- blocksize_long_44,
-
- _psy_tone_masteratt_44,
- _psy_tone_0dB,
- _psy_tone_suppress,
-
- _vp_tonemask_adj_otherblock,
- _vp_tonemask_adj_longblock,
- _vp_tonemask_adj_otherblock,
-
- _psy_noiseguards_44,
- _psy_noisebias_impulse,
- _psy_noisebias_padding,
- _psy_noisebias_trans,
- _psy_noisebias_long,
- _psy_noise_suppress,
-
- _psy_compand_44,
- _psy_compand_short_mapping,
- _psy_compand_long_mapping,
-
- {_noise_start_short_44,_noise_start_long_44},
- {_noise_part_short_44,_noise_part_long_44},
- _noise_thresh_44,
-
- _psy_ath_floater,
- _psy_ath_abs,
-
- _psy_lowpass_44,
-
- _psy_global_44,
- _global_mapping_44,
- NULL,
-
- _floor_books,
- _floor,
- _floor_short_mapping_44,
- _floor_long_mapping_44,
-
- _mapres_template_44_uncoupled
- };
-
- ve_setup_data_template ve_setup_XX_stereo={
- 2,
- rate_mapping_X,
- quality_mapping_8,
- 2,
- 0,
- 8000,
-
- blocksize_8,
- blocksize_8,
-
- _psy_tone_masteratt_8,
- _psy_tone_0dB,
- _psy_tone_suppress,
-
- _vp_tonemask_adj_8,
- NULL,
- _vp_tonemask_adj_8,
-
- _psy_noiseguards_8,
- _psy_noisebias_8,
- _psy_noisebias_8,
- NULL,
- NULL,
- _psy_noise_suppress,
-
- _psy_compand_8,
- _psy_compand_8_mapping,
- NULL,
-
- {_noise_start_8,_noise_start_8},
- {_noise_part_8,_noise_part_8},
- _noise_thresh_5only,
-
- _psy_ath_floater_8,
- _psy_ath_abs_8,
-
- _psy_lowpass_8,
-
- _psy_global_44,
- _global_mapping_8,
- _psy_stereo_modes_8,
-
- _floor_books,
- _floor,
- _floor_mapping_8,
- NULL,
-
- _mapres_template_8_stereo
- };
-
- ve_setup_data_template ve_setup_XX_uncoupled={
- 2,
- rate_mapping_X,
- quality_mapping_8,
- -1,
- 0,
- 8000,
-
- blocksize_8,
- blocksize_8,
-
- _psy_tone_masteratt_8,
- _psy_tone_0dB,
- _psy_tone_suppress,
-
- _vp_tonemask_adj_8,
- NULL,
- _vp_tonemask_adj_8,
-
- _psy_noiseguards_8,
- _psy_noisebias_8,
- _psy_noisebias_8,
- NULL,
- NULL,
- _psy_noise_suppress,
-
- _psy_compand_8,
- _psy_compand_8_mapping,
- NULL,
-
- {_noise_start_8,_noise_start_8},
- {_noise_part_8,_noise_part_8},
- _noise_thresh_5only,
-
- _psy_ath_floater_8,
- _psy_ath_abs_8,
-
- _psy_lowpass_8,
-
- _psy_global_44,
- _global_mapping_8,
- _psy_stereo_modes_8,
-
- _floor_books,
- _floor,
- _floor_mapping_8,
- NULL,
-
- _mapres_template_8_uncoupled
- };
- /********* End of inlined file: setup_X.h *********/
-
- static ve_setup_data_template *setup_list[]={
- &ve_setup_44_stereo,
- &ve_setup_44_uncoupled,
-
- &ve_setup_32_stereo,
- &ve_setup_32_uncoupled,
-
- &ve_setup_22_stereo,
- &ve_setup_22_uncoupled,
- &ve_setup_16_stereo,
- &ve_setup_16_uncoupled,
-
- &ve_setup_11_stereo,
- &ve_setup_11_uncoupled,
- &ve_setup_8_stereo,
- &ve_setup_8_uncoupled,
-
- &ve_setup_X_stereo,
- &ve_setup_X_uncoupled,
- &ve_setup_XX_stereo,
- &ve_setup_XX_uncoupled,
- 0
- };
-
- static int vorbis_encode_toplevel_setup(vorbis_info *vi,int ch,long rate){
- if(vi && vi->codec_setup){
-
- vi->version=0;
- vi->channels=ch;
- vi->rate=rate;
-
- return(0);
- }
- return(OV_EINVAL);
- }
-
- static void vorbis_encode_floor_setup(vorbis_info *vi,double s,int block,
- static_codebook ***books,
- vorbis_info_floor1 *in,
- int *x){
- int i,k,is=s;
- vorbis_info_floor1 *f=(vorbis_info_floor1*) _ogg_calloc(1,sizeof(*f));
- codec_setup_info *ci=(codec_setup_info*)vi->codec_setup;
-
- memcpy(f,in+x[is],sizeof(*f));
- /* fill in the lowpass field, even if it's temporary */
- f->n=ci->blocksizes[block]>>1;
-
- /* books */
- {
- int partitions=f->partitions;
- int maxclass=-1;
- int maxbook=-1;
- for(i=0;i<partitions;i++)
- if(f->partitionclass[i]>maxclass)maxclass=f->partitionclass[i];
- for(i=0;i<=maxclass;i++){
- if(f->class_book[i]>maxbook)maxbook=f->class_book[i];
- f->class_book[i]+=ci->books;
- for(k=0;k<(1<<f->class_subs[i]);k++){
- if(f->class_subbook[i][k]>maxbook)maxbook=f->class_subbook[i][k];
- if(f->class_subbook[i][k]>=0)f->class_subbook[i][k]+=ci->books;
- }
- }
-
- for(i=0;i<=maxbook;i++)
- ci->book_param[ci->books++]=books[x[is]][i];
- }
-
- /* for now, we're only using floor 1 */
- ci->floor_type[ci->floors]=1;
- ci->floor_param[ci->floors]=f;
- ci->floors++;
-
- return;
- }
-
- static void vorbis_encode_global_psych_setup(vorbis_info *vi,double s,
- vorbis_info_psy_global *in,
- double *x){
- int i,is=s;
- double ds=s-is;
- codec_setup_info *ci=(codec_setup_info*)vi->codec_setup;
- vorbis_info_psy_global *g=&ci->psy_g_param;
-
- memcpy(g,in+(int)x[is],sizeof(*g));
-
- ds=x[is]*(1.-ds)+x[is+1]*ds;
- is=(int)ds;
- ds-=is;
- if(ds==0 && is>0){
- is--;
- ds=1.;
- }
-
- /* interpolate the trigger threshholds */
- for(i=0;i<4;i++){
- g->preecho_thresh[i]=in[is].preecho_thresh[i]*(1.-ds)+in[is+1].preecho_thresh[i]*ds;
- g->postecho_thresh[i]=in[is].postecho_thresh[i]*(1.-ds)+in[is+1].postecho_thresh[i]*ds;
- }
- g->ampmax_att_per_sec=ci->hi.amplitude_track_dBpersec;
- return;
- }
-
- static void vorbis_encode_global_stereo(vorbis_info *vi,
- highlevel_encode_setup *hi,
- adj_stereo *p){
- float s=hi->stereo_point_setting;
- int i,is=s;
- double ds=s-is;
- codec_setup_info *ci=(codec_setup_info*)vi->codec_setup;
- vorbis_info_psy_global *g=&ci->psy_g_param;
-
- if(p){
- memcpy(g->coupling_prepointamp,p[is].pre,sizeof(*p[is].pre)*PACKETBLOBS);
- memcpy(g->coupling_postpointamp,p[is].post,sizeof(*p[is].post)*PACKETBLOBS);
-
- if(hi->managed){
- /* interpolate the kHz threshholds */
- for(i=0;i<PACKETBLOBS;i++){
- float kHz=p[is].kHz[i]*(1.-ds)+p[is+1].kHz[i]*ds;
- g->coupling_pointlimit[0][i]=kHz*1000./vi->rate*ci->blocksizes[0];
- g->coupling_pointlimit[1][i]=kHz*1000./vi->rate*ci->blocksizes[1];
- g->coupling_pkHz[i]=kHz;
-
- kHz=p[is].lowpasskHz[i]*(1.-ds)+p[is+1].lowpasskHz[i]*ds;
- g->sliding_lowpass[0][i]=kHz*1000./vi->rate*ci->blocksizes[0];
- g->sliding_lowpass[1][i]=kHz*1000./vi->rate*ci->blocksizes[1];
-
- }
- }else{
- float kHz=p[is].kHz[PACKETBLOBS/2]*(1.-ds)+p[is+1].kHz[PACKETBLOBS/2]*ds;
- for(i=0;i<PACKETBLOBS;i++){
- g->coupling_pointlimit[0][i]=kHz*1000./vi->rate*ci->blocksizes[0];
- g->coupling_pointlimit[1][i]=kHz*1000./vi->rate*ci->blocksizes[1];
- g->coupling_pkHz[i]=kHz;
- }
-
- kHz=p[is].lowpasskHz[PACKETBLOBS/2]*(1.-ds)+p[is+1].lowpasskHz[PACKETBLOBS/2]*ds;
- for(i=0;i<PACKETBLOBS;i++){
- g->sliding_lowpass[0][i]=kHz*1000./vi->rate*ci->blocksizes[0];
- g->sliding_lowpass[1][i]=kHz*1000./vi->rate*ci->blocksizes[1];
- }
- }
- }else{
- for(i=0;i<PACKETBLOBS;i++){
- g->sliding_lowpass[0][i]=ci->blocksizes[0];
- g->sliding_lowpass[1][i]=ci->blocksizes[1];
- }
- }
- return;
- }
-
- static void vorbis_encode_psyset_setup(vorbis_info *vi,double s,
- int *nn_start,
- int *nn_partition,
- double *nn_thresh,
- int block){
- codec_setup_info *ci=(codec_setup_info*) vi->codec_setup;
- vorbis_info_psy *p=ci->psy_param[block];
- highlevel_encode_setup *hi=&ci->hi;
- int is=s;
-
- if(block>=ci->psys)
- ci->psys=block+1;
- if(!p){
- p=(vorbis_info_psy*)_ogg_calloc(1,sizeof(*p));
- ci->psy_param[block]=p;
- }
-
- memcpy(p,&_psy_info_template,sizeof(*p));
- p->blockflag=block>>1;
-
- if(hi->noise_normalize_p){
- p->normal_channel_p=1;
- p->normal_point_p=1;
- p->normal_start=nn_start[is];
- p->normal_partition=nn_partition[is];
- p->normal_thresh=nn_thresh[is];
- }
-
- return;
- }
-
- static void vorbis_encode_tonemask_setup(vorbis_info *vi,double s,int block,
- att3 *att,
- int *max,
- vp_adjblock *in){
- int i,is=s;
- double ds=s-is;
- codec_setup_info *ci=(codec_setup_info*) vi->codec_setup;
- vorbis_info_psy *p=ci->psy_param[block];
-
- /* 0 and 2 are only used by bitmanagement, but there's no harm to always
- filling the values in here */
- p->tone_masteratt[0]=att[is].att[0]*(1.-ds)+att[is+1].att[0]*ds;
- p->tone_masteratt[1]=att[is].att[1]*(1.-ds)+att[is+1].att[1]*ds;
- p->tone_masteratt[2]=att[is].att[2]*(1.-ds)+att[is+1].att[2]*ds;
- p->tone_centerboost=att[is].boost*(1.-ds)+att[is+1].boost*ds;
- p->tone_decay=att[is].decay*(1.-ds)+att[is+1].decay*ds;
-
- p->max_curve_dB=max[is]*(1.-ds)+max[is+1]*ds;
-
- for(i=0;i<P_BANDS;i++)
- p->toneatt[i]=in[is].block[i]*(1.-ds)+in[is+1].block[i]*ds;
- return;
- }
-
- static void vorbis_encode_compand_setup(vorbis_info *vi,double s,int block,
- compandblock *in, double *x){
- int i,is=s;
- double ds=s-is;
- codec_setup_info *ci=(codec_setup_info*)vi->codec_setup;
- vorbis_info_psy *p=ci->psy_param[block];
-
- ds=x[is]*(1.-ds)+x[is+1]*ds;
- is=(int)ds;
- ds-=is;
- if(ds==0 && is>0){
- is--;
- ds=1.;
- }
-
- /* interpolate the compander settings */
- for(i=0;i<NOISE_COMPAND_LEVELS;i++)
- p->noisecompand[i]=in[is].data[i]*(1.-ds)+in[is+1].data[i]*ds;
- return;
- }
-
- static void vorbis_encode_peak_setup(vorbis_info *vi,double s,int block,
- int *suppress){
- int is=s;
- double ds=s-is;
- codec_setup_info *ci=(codec_setup_info*)vi->codec_setup;
- vorbis_info_psy *p=ci->psy_param[block];
-
- p->tone_abs_limit=suppress[is]*(1.-ds)+suppress[is+1]*ds;
-
- return;
- }
-
- static void vorbis_encode_noisebias_setup(vorbis_info *vi,double s,int block,
- int *suppress,
- noise3 *in,
- noiseguard *guard,
- double userbias){
- int i,is=s,j;
- double ds=s-is;
- codec_setup_info *ci=(codec_setup_info*)vi->codec_setup;
- vorbis_info_psy *p=ci->psy_param[block];
-
- p->noisemaxsupp=suppress[is]*(1.-ds)+suppress[is+1]*ds;
- p->noisewindowlomin=guard[block].lo;
- p->noisewindowhimin=guard[block].hi;
- p->noisewindowfixed=guard[block].fixed;
-
- for(j=0;j<P_NOISECURVES;j++)
- for(i=0;i<P_BANDS;i++)
- p->noiseoff[j][i]=in[is].data[j][i]*(1.-ds)+in[is+1].data[j][i]*ds;
-
- /* impulse blocks may take a user specified bias to boost the
- nominal/high noise encoding depth */
- for(j=0;j<P_NOISECURVES;j++){
- float min=p->noiseoff[j][0]+6; /* the lowest it can go */
- for(i=0;i<P_BANDS;i++){
- p->noiseoff[j][i]+=userbias;
- if(p->noiseoff[j][i]<min)p->noiseoff[j][i]=min;
- }
- }
-
- return;
- }
-
- static void vorbis_encode_ath_setup(vorbis_info *vi,int block){
- codec_setup_info *ci=(codec_setup_info*)vi->codec_setup;
- vorbis_info_psy *p=ci->psy_param[block];
-
- p->ath_adjatt=ci->hi.ath_floating_dB;
- p->ath_maxatt=ci->hi.ath_absolute_dB;
- return;
- }
-
- static int book_dup_or_new(codec_setup_info *ci,static_codebook *book){
- int i;
- for(i=0;i<ci->books;i++)
- if(ci->book_param[i]==book)return(i);
-
- return(ci->books++);
- }
-
- static void vorbis_encode_blocksize_setup(vorbis_info *vi,double s,
- int *shortb,int *longb){
-
- codec_setup_info *ci=(codec_setup_info*)vi->codec_setup;
- int is=s;
-
- int blockshort=shortb[is];
- int blocklong=longb[is];
- ci->blocksizes[0]=blockshort;
- ci->blocksizes[1]=blocklong;
-
- }
-
- static void vorbis_encode_residue_setup(vorbis_info *vi,
- int number, int block,
- vorbis_residue_template *res){
-
- codec_setup_info *ci=(codec_setup_info*)vi->codec_setup;
- int i,n;
-
- vorbis_info_residue0 *r=(vorbis_info_residue0*)(ci->residue_param[number]=
- (vorbis_info_residue0*)_ogg_malloc(sizeof(*r)));
-
- memcpy(r,res->res,sizeof(*r));
- if(ci->residues<=number)ci->residues=number+1;
-
- switch(ci->blocksizes[block]){
- case 64:case 128:case 256:
- r->grouping=16;
- break;
- default:
- r->grouping=32;
- break;
- }
- ci->residue_type[number]=res->res_type;
-
- /* to be adjusted by lowpass/pointlimit later */
- n=r->end=ci->blocksizes[block]>>1;
- if(res->res_type==2)
- n=r->end*=vi->channels;
-
- /* fill in all the books */
- {
- int booklist=0,k;
-
- if(ci->hi.managed){
- for(i=0;i<r->partitions;i++)
- for(k=0;k<3;k++)
- if(res->books_base_managed->books[i][k])
- r->secondstages[i]|=(1<<k);
-
- r->groupbook=book_dup_or_new(ci,res->book_aux_managed);
- ci->book_param[r->groupbook]=res->book_aux_managed;
-
- for(i=0;i<r->partitions;i++){
- for(k=0;k<3;k++){
- if(res->books_base_managed->books[i][k]){
- int bookid=book_dup_or_new(ci,res->books_base_managed->books[i][k]);
- r->booklist[booklist++]=bookid;
- ci->book_param[bookid]=res->books_base_managed->books[i][k];
- }
- }
- }
-
- }else{
-
- for(i=0;i<r->partitions;i++)
- for(k=0;k<3;k++)
- if(res->books_base->books[i][k])
- r->secondstages[i]|=(1<<k);
-
- r->groupbook=book_dup_or_new(ci,res->book_aux);
- ci->book_param[r->groupbook]=res->book_aux;
-
- for(i=0;i<r->partitions;i++){
- for(k=0;k<3;k++){
- if(res->books_base->books[i][k]){
- int bookid=book_dup_or_new(ci,res->books_base->books[i][k]);
- r->booklist[booklist++]=bookid;
- ci->book_param[bookid]=res->books_base->books[i][k];
- }
- }
- }
- }
- }
-
- /* lowpass setup/pointlimit */
- {
- double freq=ci->hi.lowpass_kHz*1000.;
- vorbis_info_floor1 *f=(vorbis_info_floor1*)ci->floor_param[block]; /* by convention */
- double nyq=vi->rate/2.;
- long blocksize=ci->blocksizes[block]>>1;
-
- /* lowpass needs to be set in the floor and the residue. */
- if(freq>nyq)freq=nyq;
- /* in the floor, the granularity can be very fine; it doesn't alter
- the encoding structure, only the samples used to fit the floor
- approximation */
- f->n=freq/nyq*blocksize;
-
- /* this res may by limited by the maximum pointlimit of the mode,
- not the lowpass. the floor is always lowpass limited. */
- if(res->limit_type){
- if(ci->hi.managed)
- freq=ci->psy_g_param.coupling_pkHz[PACKETBLOBS-1]*1000.;
- else
- freq=ci->psy_g_param.coupling_pkHz[PACKETBLOBS/2]*1000.;
- if(freq>nyq)freq=nyq;
- }
-
- /* in the residue, we're constrained, physically, by partition
- boundaries. We still lowpass 'wherever', but we have to round up
- here to next boundary, or the vorbis spec will round it *down* to
- previous boundary in encode/decode */
- if(ci->residue_type[block]==2)
- r->end=(int)((freq/nyq*blocksize*2)/r->grouping+.9)* /* round up only if we're well past */
- r->grouping;
- else
- r->end=(int)((freq/nyq*blocksize)/r->grouping+.9)* /* round up only if we're well past */
- r->grouping;
- }
- }
-
- /* we assume two maps in this encoder */
- static void vorbis_encode_map_n_res_setup(vorbis_info *vi,double s,
- vorbis_mapping_template *maps){
-
- codec_setup_info *ci=(codec_setup_info*)vi->codec_setup;
- int i,j,is=s,modes=2;
- vorbis_info_mapping0 *map=maps[is].map;
- vorbis_info_mode *mode=_mode_template;
- vorbis_residue_template *res=maps[is].res;
-
- if(ci->blocksizes[0]==ci->blocksizes[1])modes=1;
-
- for(i=0;i<modes;i++){
-
- ci->map_param[i]=_ogg_calloc(1,sizeof(*map));
- ci->mode_param[i]=(vorbis_info_mode*)_ogg_calloc(1,sizeof(*mode));
-
- memcpy(ci->mode_param[i],mode+i,sizeof(*_mode_template));
- if(i>=ci->modes)ci->modes=i+1;
-
- ci->map_type[i]=0;
- memcpy(ci->map_param[i],map+i,sizeof(*map));
- if(i>=ci->maps)ci->maps=i+1;
-
- for(j=0;j<map[i].submaps;j++)
- vorbis_encode_residue_setup(vi,map[i].residuesubmap[j],i
- ,res+map[i].residuesubmap[j]);
- }
- }
-
- static double setting_to_approx_bitrate(vorbis_info *vi){
- codec_setup_info *ci=(codec_setup_info*)vi->codec_setup;
- highlevel_encode_setup *hi=&ci->hi;
- ve_setup_data_template *setup=(ve_setup_data_template *)hi->setup;
- int is=hi->base_setting;
- double ds=hi->base_setting-is;
- int ch=vi->channels;
- double *r=setup->rate_mapping;
-
- if(r==NULL)
- return(-1);
-
- return((r[is]*(1.-ds)+r[is+1]*ds)*ch);
- }
-
- static void get_setup_template(vorbis_info *vi,
- long ch,long srate,
- double req,int q_or_bitrate){
- int i=0,j;
- codec_setup_info *ci=(codec_setup_info*) vi->codec_setup;
- highlevel_encode_setup *hi=&ci->hi;
- if(q_or_bitrate)req/=ch;
-
- while(setup_list[i]){
- if(setup_list[i]->coupling_restriction==-1 ||
- setup_list[i]->coupling_restriction==ch){
- if(srate>=setup_list[i]->samplerate_min_restriction &&
- srate<=setup_list[i]->samplerate_max_restriction){
- int mappings=setup_list[i]->mappings;
- double *map=(q_or_bitrate?
- setup_list[i]->rate_mapping:
- setup_list[i]->quality_mapping);
-
- /* the template matches. Does the requested quality mode
- fall within this template's modes? */
- if(req<map[0]){++i;continue;}
- if(req>map[setup_list[i]->mappings]){++i;continue;}
- for(j=0;j<mappings;j++)
- if(req>=map[j] && req<map[j+1])break;
- /* an all-points match */
- hi->setup=setup_list[i];
- if(j==mappings)
- hi->base_setting=j-.001;
- else{
- float low=map[j];
- float high=map[j+1];
- float del=(req-low)/(high-low);
- hi->base_setting=j+del;
- }
-
- return;
- }
- }
- i++;
- }
-
- hi->setup=NULL;
- }
-
- /* encoders will need to use vorbis_info_init beforehand and call
- vorbis_info clear when all done */
-
- /* two interfaces; this, more detailed one, and later a convenience
- layer on top */
-
- /* the final setup call */
- int vorbis_encode_setup_init(vorbis_info *vi){
- int i0=0,singleblock=0;
- codec_setup_info *ci=(codec_setup_info*) vi->codec_setup;
- ve_setup_data_template *setup=NULL;
- highlevel_encode_setup *hi=&ci->hi;
-
- if(ci==NULL)return(OV_EINVAL);
- if(!hi->impulse_block_p)i0=1;
-
- /* too low/high an ATH floater is nonsensical, but doesn't break anything */
- if(hi->ath_floating_dB>-80)hi->ath_floating_dB=-80;
- if(hi->ath_floating_dB<-200)hi->ath_floating_dB=-200;
-
- /* again, bound this to avoid the app shooting itself int he foot
- too badly */
- if(hi->amplitude_track_dBpersec>0.)hi->amplitude_track_dBpersec=0.;
- if(hi->amplitude_track_dBpersec<-99999.)hi->amplitude_track_dBpersec=-99999.;
-
- /* get the appropriate setup template; matches the fetch in previous
- stages */
- setup=(ve_setup_data_template *)hi->setup;
- if(setup==NULL)return(OV_EINVAL);
-
- hi->set_in_stone=1;
- /* choose block sizes from configured sizes as well as paying
- attention to long_block_p and short_block_p. If the configured
- short and long blocks are the same length, we set long_block_p
- and unset short_block_p */
- vorbis_encode_blocksize_setup(vi,hi->base_setting,
- setup->blocksize_short,
- setup->blocksize_long);
- if(ci->blocksizes[0]==ci->blocksizes[1])singleblock=1;
-
- /* floor setup; choose proper floor params. Allocated on the floor
- stack in order; if we alloc only long floor, it's 0 */
- vorbis_encode_floor_setup(vi,hi->short_setting,0,
- setup->floor_books,
- setup->floor_params,
- setup->floor_short_mapping);
- if(!singleblock)
- vorbis_encode_floor_setup(vi,hi->long_setting,1,
- setup->floor_books,
- setup->floor_params,
- setup->floor_long_mapping);
-
- /* setup of [mostly] short block detection and stereo*/
- vorbis_encode_global_psych_setup(vi,hi->trigger_setting,
- setup->global_params,
- setup->global_mapping);
- vorbis_encode_global_stereo(vi,hi,setup->stereo_modes);
-
- /* basic psych setup and noise normalization */
- vorbis_encode_psyset_setup(vi,hi->short_setting,
- setup->psy_noise_normal_start[0],
- setup->psy_noise_normal_partition[0],
- setup->psy_noise_normal_thresh,
- 0);
- vorbis_encode_psyset_setup(vi,hi->short_setting,
- setup->psy_noise_normal_start[0],
- setup->psy_noise_normal_partition[0],
- setup->psy_noise_normal_thresh,
- 1);
- if(!singleblock){
- vorbis_encode_psyset_setup(vi,hi->long_setting,
- setup->psy_noise_normal_start[1],
- setup->psy_noise_normal_partition[1],
- setup->psy_noise_normal_thresh,
- 2);
- vorbis_encode_psyset_setup(vi,hi->long_setting,
- setup->psy_noise_normal_start[1],
- setup->psy_noise_normal_partition[1],
- setup->psy_noise_normal_thresh,
- 3);
- }
-
- /* tone masking setup */
- vorbis_encode_tonemask_setup(vi,hi->block[i0].tone_mask_setting,0,
- setup->psy_tone_masteratt,
- setup->psy_tone_0dB,
- setup->psy_tone_adj_impulse);
- vorbis_encode_tonemask_setup(vi,hi->block[1].tone_mask_setting,1,
- setup->psy_tone_masteratt,
- setup->psy_tone_0dB,
- setup->psy_tone_adj_other);
- if(!singleblock){
- vorbis_encode_tonemask_setup(vi,hi->block[2].tone_mask_setting,2,
- setup->psy_tone_masteratt,
- setup->psy_tone_0dB,
- setup->psy_tone_adj_other);
- vorbis_encode_tonemask_setup(vi,hi->block[3].tone_mask_setting,3,
- setup->psy_tone_masteratt,
- setup->psy_tone_0dB,
- setup->psy_tone_adj_long);
- }
-
- /* noise companding setup */
- vorbis_encode_compand_setup(vi,hi->block[i0].noise_compand_setting,0,
- setup->psy_noise_compand,
- setup->psy_noise_compand_short_mapping);
- vorbis_encode_compand_setup(vi,hi->block[1].noise_compand_setting,1,
- setup->psy_noise_compand,
- setup->psy_noise_compand_short_mapping);
- if(!singleblock){
- vorbis_encode_compand_setup(vi,hi->block[2].noise_compand_setting,2,
- setup->psy_noise_compand,
- setup->psy_noise_compand_long_mapping);
- vorbis_encode_compand_setup(vi,hi->block[3].noise_compand_setting,3,
- setup->psy_noise_compand,
- setup->psy_noise_compand_long_mapping);
- }
-
- /* peak guarding setup */
- vorbis_encode_peak_setup(vi,hi->block[i0].tone_peaklimit_setting,0,
- setup->psy_tone_dBsuppress);
- vorbis_encode_peak_setup(vi,hi->block[1].tone_peaklimit_setting,1,
- setup->psy_tone_dBsuppress);
- if(!singleblock){
- vorbis_encode_peak_setup(vi,hi->block[2].tone_peaklimit_setting,2,
- setup->psy_tone_dBsuppress);
- vorbis_encode_peak_setup(vi,hi->block[3].tone_peaklimit_setting,3,
- setup->psy_tone_dBsuppress);
- }
-
- /* noise bias setup */
- vorbis_encode_noisebias_setup(vi,hi->block[i0].noise_bias_setting,0,
- setup->psy_noise_dBsuppress,
- setup->psy_noise_bias_impulse,
- setup->psy_noiseguards,
- (i0==0?hi->impulse_noisetune:0.));
- vorbis_encode_noisebias_setup(vi,hi->block[1].noise_bias_setting,1,
- setup->psy_noise_dBsuppress,
- setup->psy_noise_bias_padding,
- setup->psy_noiseguards,0.);
- if(!singleblock){
- vorbis_encode_noisebias_setup(vi,hi->block[2].noise_bias_setting,2,
- setup->psy_noise_dBsuppress,
- setup->psy_noise_bias_trans,
- setup->psy_noiseguards,0.);
- vorbis_encode_noisebias_setup(vi,hi->block[3].noise_bias_setting,3,
- setup->psy_noise_dBsuppress,
- setup->psy_noise_bias_long,
- setup->psy_noiseguards,0.);
- }
-
- vorbis_encode_ath_setup(vi,0);
- vorbis_encode_ath_setup(vi,1);
- if(!singleblock){
- vorbis_encode_ath_setup(vi,2);
- vorbis_encode_ath_setup(vi,3);
- }
-
- vorbis_encode_map_n_res_setup(vi,hi->base_setting,setup->maps);
-
- /* set bitrate readonlies and management */
- if(hi->bitrate_av>0)
- vi->bitrate_nominal=hi->bitrate_av;
- else{
- vi->bitrate_nominal=setting_to_approx_bitrate(vi);
- }
-
- vi->bitrate_lower=hi->bitrate_min;
- vi->bitrate_upper=hi->bitrate_max;
- if(hi->bitrate_av)
- vi->bitrate_window=(double)hi->bitrate_reservoir/hi->bitrate_av;
- else
- vi->bitrate_window=0.;
-
- if(hi->managed){
- ci->bi.avg_rate=hi->bitrate_av;
- ci->bi.min_rate=hi->bitrate_min;
- ci->bi.max_rate=hi->bitrate_max;
-
- ci->bi.reservoir_bits=hi->bitrate_reservoir;
- ci->bi.reservoir_bias=
- hi->bitrate_reservoir_bias;
-
- ci->bi.slew_damp=hi->bitrate_av_damp;
-
- }
-
- return(0);
-
- }
-
- static int vorbis_encode_setup_setting(vorbis_info *vi,
- long channels,
- long rate){
- int ret=0,i,is;
- codec_setup_info *ci=(codec_setup_info*)vi->codec_setup;
- highlevel_encode_setup *hi=&ci->hi;
- ve_setup_data_template *setup=(ve_setup_data_template*) hi->setup;
- double ds;
-
- ret=vorbis_encode_toplevel_setup(vi,channels,rate);
- if(ret)return(ret);
-
- is=hi->base_setting;
- ds=hi->base_setting-is;
-
- hi->short_setting=hi->base_setting;
- hi->long_setting=hi->base_setting;
-
- hi->managed=0;
-
- hi->impulse_block_p=1;
- hi->noise_normalize_p=1;
-
- hi->stereo_point_setting=hi->base_setting;
- hi->lowpass_kHz=
- setup->psy_lowpass[is]*(1.-ds)+setup->psy_lowpass[is+1]*ds;
-
- hi->ath_floating_dB=setup->psy_ath_float[is]*(1.-ds)+
- setup->psy_ath_float[is+1]*ds;
- hi->ath_absolute_dB=setup->psy_ath_abs[is]*(1.-ds)+
- setup->psy_ath_abs[is+1]*ds;
-
- hi->amplitude_track_dBpersec=-6.;
- hi->trigger_setting=hi->base_setting;
-
- for(i=0;i<4;i++){
- hi->block[i].tone_mask_setting=hi->base_setting;
- hi->block[i].tone_peaklimit_setting=hi->base_setting;
- hi->block[i].noise_bias_setting=hi->base_setting;
- hi->block[i].noise_compand_setting=hi->base_setting;
- }
-
- return(ret);
- }
-
- int vorbis_encode_setup_vbr(vorbis_info *vi,
- long channels,
- long rate,
- float quality){
- codec_setup_info *ci=(codec_setup_info*) vi->codec_setup;
- highlevel_encode_setup *hi=&ci->hi;
-
- quality+=.0000001;
- if(quality>=1.)quality=.9999;
-
- get_setup_template(vi,channels,rate,quality,0);
- if(!hi->setup)return OV_EIMPL;
-
- return vorbis_encode_setup_setting(vi,channels,rate);
- }
-
- int vorbis_encode_init_vbr(vorbis_info *vi,
- long channels,
- long rate,
-
- float base_quality /* 0. to 1. */
- ){
- int ret=0;
-
- ret=vorbis_encode_setup_vbr(vi,channels,rate,base_quality);
-
- if(ret){
- vorbis_info_clear(vi);
- return ret;
- }
- ret=vorbis_encode_setup_init(vi);
- if(ret)
- vorbis_info_clear(vi);
- return(ret);
- }
-
- int vorbis_encode_setup_managed(vorbis_info *vi,
- long channels,
- long rate,
-
- long max_bitrate,
- long nominal_bitrate,
- long min_bitrate){
-
- codec_setup_info *ci=(codec_setup_info*)vi->codec_setup;
- highlevel_encode_setup *hi=&ci->hi;
- double tnominal=nominal_bitrate;
- int ret=0;
-
- if(nominal_bitrate<=0.){
- if(max_bitrate>0.){
- if(min_bitrate>0.)
- nominal_bitrate=(max_bitrate+min_bitrate)*.5;
- else
- nominal_bitrate=max_bitrate*.875;
- }else{
- if(min_bitrate>0.){
- nominal_bitrate=min_bitrate;
- }else{
- return(OV_EINVAL);
- }
- }
- }
-
- get_setup_template(vi,channels,rate,nominal_bitrate,1);
- if(!hi->setup)return OV_EIMPL;
-
- ret=vorbis_encode_setup_setting(vi,channels,rate);
- if(ret){
- vorbis_info_clear(vi);
- return ret;
- }
-
- /* initialize management with sane defaults */
- hi->managed=1;
- hi->bitrate_min=min_bitrate;
- hi->bitrate_max=max_bitrate;
- hi->bitrate_av=tnominal;
- hi->bitrate_av_damp=1.5f; /* full range in no less than 1.5 second */
- hi->bitrate_reservoir=nominal_bitrate*2;
- hi->bitrate_reservoir_bias=.1; /* bias toward hoarding bits */
-
- return(ret);
-
- }
-
- int vorbis_encode_init(vorbis_info *vi,
- long channels,
- long rate,
-
- long max_bitrate,
- long nominal_bitrate,
- long min_bitrate){
-
- int ret=vorbis_encode_setup_managed(vi,channels,rate,
- max_bitrate,
- nominal_bitrate,
- min_bitrate);
- if(ret){
- vorbis_info_clear(vi);
- return(ret);
- }
-
- ret=vorbis_encode_setup_init(vi);
- if(ret)
- vorbis_info_clear(vi);
- return(ret);
- }
-
- int vorbis_encode_ctl(vorbis_info *vi,int number,void *arg){
- if(vi){
- codec_setup_info *ci=(codec_setup_info*)vi->codec_setup;
- highlevel_encode_setup *hi=&ci->hi;
- int setp=(number&0xf); /* a read request has a low nibble of 0 */
-
- if(setp && hi->set_in_stone)return(OV_EINVAL);
-
- switch(number){
-
- /* now deprecated *****************/
- case OV_ECTL_RATEMANAGE_GET:
- {
-
- struct ovectl_ratemanage_arg *ai=
- (struct ovectl_ratemanage_arg *)arg;
-
- ai->management_active=hi->managed;
- ai->bitrate_hard_window=ai->bitrate_av_window=
- (double)hi->bitrate_reservoir/vi->rate;
- ai->bitrate_av_window_center=1.;
- ai->bitrate_hard_min=hi->bitrate_min;
- ai->bitrate_hard_max=hi->bitrate_max;
- ai->bitrate_av_lo=hi->bitrate_av;
- ai->bitrate_av_hi=hi->bitrate_av;
-
- }
- return(0);
-
- /* now deprecated *****************/
- case OV_ECTL_RATEMANAGE_SET:
- {
- struct ovectl_ratemanage_arg *ai=
- (struct ovectl_ratemanage_arg *)arg;
- if(ai==NULL){
- hi->managed=0;
- }else{
- hi->managed=ai->management_active;
- vorbis_encode_ctl(vi,OV_ECTL_RATEMANAGE_AVG,arg);
- vorbis_encode_ctl(vi,OV_ECTL_RATEMANAGE_HARD,arg);
- }
- }
- return 0;
-
- /* now deprecated *****************/
- case OV_ECTL_RATEMANAGE_AVG:
- {
- struct ovectl_ratemanage_arg *ai=
- (struct ovectl_ratemanage_arg *)arg;
- if(ai==NULL){
- hi->bitrate_av=0;
- }else{
- hi->bitrate_av=(ai->bitrate_av_lo+ai->bitrate_av_hi)*.5;
- }
- }
- return(0);
- /* now deprecated *****************/
- case OV_ECTL_RATEMANAGE_HARD:
- {
- struct ovectl_ratemanage_arg *ai=
- (struct ovectl_ratemanage_arg *)arg;
- if(ai==NULL){
- hi->bitrate_min=0;
- hi->bitrate_max=0;
- }else{
- hi->bitrate_min=ai->bitrate_hard_min;
- hi->bitrate_max=ai->bitrate_hard_max;
- hi->bitrate_reservoir=ai->bitrate_hard_window*
- (hi->bitrate_max+hi->bitrate_min)*.5;
- }
- if(hi->bitrate_reservoir<128.)
- hi->bitrate_reservoir=128.;
- }
- return(0);
-
- /* replacement ratemanage interface */
- case OV_ECTL_RATEMANAGE2_GET:
- {
- struct ovectl_ratemanage2_arg *ai=
- (struct ovectl_ratemanage2_arg *)arg;
- if(ai==NULL)return OV_EINVAL;
-
- ai->management_active=hi->managed;
- ai->bitrate_limit_min_kbps=hi->bitrate_min/1000;
- ai->bitrate_limit_max_kbps=hi->bitrate_max/1000;
- ai->bitrate_average_kbps=hi->bitrate_av/1000;
- ai->bitrate_average_damping=hi->bitrate_av_damp;
- ai->bitrate_limit_reservoir_bits=hi->bitrate_reservoir;
- ai->bitrate_limit_reservoir_bias=hi->bitrate_reservoir_bias;
- }
- return (0);
- case OV_ECTL_RATEMANAGE2_SET:
- {
- struct ovectl_ratemanage2_arg *ai=
- (struct ovectl_ratemanage2_arg *)arg;
- if(ai==NULL){
- hi->managed=0;
- }else{
- /* sanity check; only catch invariant violations */
- if(ai->bitrate_limit_min_kbps>0 &&
- ai->bitrate_average_kbps>0 &&
- ai->bitrate_limit_min_kbps>ai->bitrate_average_kbps)
- return OV_EINVAL;
-
- if(ai->bitrate_limit_max_kbps>0 &&
- ai->bitrate_average_kbps>0 &&
- ai->bitrate_limit_max_kbps<ai->bitrate_average_kbps)
- return OV_EINVAL;
-
- if(ai->bitrate_limit_min_kbps>0 &&
- ai->bitrate_limit_max_kbps>0 &&
- ai->bitrate_limit_min_kbps>ai->bitrate_limit_max_kbps)
- return OV_EINVAL;
-
- if(ai->bitrate_average_damping <= 0.)
- return OV_EINVAL;
-
- if(ai->bitrate_limit_reservoir_bits < 0)
- return OV_EINVAL;
-
- if(ai->bitrate_limit_reservoir_bias < 0.)
- return OV_EINVAL;
-
- if(ai->bitrate_limit_reservoir_bias > 1.)
- return OV_EINVAL;
-
- hi->managed=ai->management_active;
- hi->bitrate_min=ai->bitrate_limit_min_kbps * 1000;
- hi->bitrate_max=ai->bitrate_limit_max_kbps * 1000;
- hi->bitrate_av=ai->bitrate_average_kbps * 1000;
- hi->bitrate_av_damp=ai->bitrate_average_damping;
- hi->bitrate_reservoir=ai->bitrate_limit_reservoir_bits;
- hi->bitrate_reservoir_bias=ai->bitrate_limit_reservoir_bias;
- }
- }
- return 0;
-
- case OV_ECTL_LOWPASS_GET:
- {
- double *farg=(double *)arg;
- *farg=hi->lowpass_kHz;
- }
- return(0);
- case OV_ECTL_LOWPASS_SET:
- {
- double *farg=(double *)arg;
- hi->lowpass_kHz=*farg;
-
- if(hi->lowpass_kHz<2.)hi->lowpass_kHz=2.;
- if(hi->lowpass_kHz>99.)hi->lowpass_kHz=99.;
- }
- return(0);
- case OV_ECTL_IBLOCK_GET:
- {
- double *farg=(double *)arg;
- *farg=hi->impulse_noisetune;
- }
- return(0);
- case OV_ECTL_IBLOCK_SET:
- {
- double *farg=(double *)arg;
- hi->impulse_noisetune=*farg;
-
- if(hi->impulse_noisetune>0.)hi->impulse_noisetune=0.;
- if(hi->impulse_noisetune<-15.)hi->impulse_noisetune=-15.;
- }
- return(0);
- }
-
- return(OV_EIMPL);
- }
- return(OV_EINVAL);
- }
-
- #endif
- /********* End of inlined file: vorbisenc.c *********/
-
- /********* Start of inlined file: vorbisfile.c *********/
-
- /********* Start of inlined file: juce_OggVorbisHeader.h *********/
- // This file is included at the start of each Ogg-Vorbis .c file, just to do a few housekeeping
- // tasks..
-
- #ifdef _MSC_VER
- #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4305 4189 4706)
- #endif
- /********* End of inlined file: juce_OggVorbisHeader.h *********/
-
- #if JUCE_USE_OGGVORBIS
-
- #include <stdlib.h>
- #include <stdio.h>
- #include <errno.h>
- #include <string.h>
- #include <math.h>
-
- /* A 'chained bitstream' is a Vorbis bitstream that contains more than
- one logical bitstream arranged end to end (the only form of Ogg
- multiplexing allowed in a Vorbis bitstream; grouping [parallel
- multiplexing] is not allowed in Vorbis) */
-
- /* A Vorbis file can be played beginning to end (streamed) without
- worrying ahead of time about chaining (see decoder_example.c). If
- we have the whole file, however, and want random access
- (seeking/scrubbing) or desire to know the total length/time of a
- file, we need to account for the possibility of chaining. */
-
- /* We can handle things a number of ways; we can determine the entire
- bitstream structure right off the bat, or find pieces on demand.
- This example determines and caches structure for the entire
- bitstream, but builds a virtual decoder on the fly when moving
- between links in the chain. */
-
- /* There are also different ways to implement seeking. Enough
- information exists in an Ogg bitstream to seek to
- sample-granularity positions in the output. Or, one can seek by
- picking some portion of the stream roughly in the desired area if
- we only want coarse navigation through the stream. */
-
- /*************************************************************************
- * Many, many internal helpers. The intention is not to be confusing;
- * rampant duplication and monolithic function implementation would be
- * harder to understand anyway. The high level functions are last. Begin
- * grokking near the end of the file */
-
- /* read a little more data from the file/pipe into the ogg_sync framer
- */
- #define CHUNKSIZE 8500 /* a shade over 8k; anyone using pages well
- over 8k gets what they deserve */
- static long _get_data(OggVorbis_File *vf){
- errno=0;
- if(vf->datasource){
- char *buffer=ogg_sync_buffer(&vf->oy,CHUNKSIZE);
- long bytes=(vf->callbacks.read_func)(buffer,1,CHUNKSIZE,vf->datasource);
- if(bytes>0)ogg_sync_wrote(&vf->oy,bytes);
- if(bytes==0 && errno)return(-1);
- return(bytes);
- }else
- return(0);
- }
-
- /* save a tiny smidge of verbosity to make the code more readable */
- static void _seek_helper(OggVorbis_File *vf,ogg_int64_t offset){
- if(vf->datasource){
- (vf->callbacks.seek_func)(vf->datasource, offset, SEEK_SET);
- vf->offset=offset;
- ogg_sync_reset(&vf->oy);
- }else{
- /* shouldn't happen unless someone writes a broken callback */
- return;
- }
- }
-
- /* The read/seek functions track absolute position within the stream */
-
- /* from the head of the stream, get the next page. boundary specifies
- if the function is allowed to fetch more data from the stream (and
- how much) or only use internally buffered data.
-
- boundary: -1) unbounded search
- 0) read no additional data; use cached only
- n) search for a new page beginning for n bytes
-
- return: <0) did not find a page (OV_FALSE, OV_EOF, OV_EREAD)
- n) found a page at absolute offset n */
-
- static ogg_int64_t _get_next_page(OggVorbis_File *vf,ogg_page *og,
- ogg_int64_t boundary){
- if(boundary>0)boundary+=vf->offset;
- while(1){
- long more;
-
- if(boundary>0 && vf->offset>=boundary)return(OV_FALSE);
- more=ogg_sync_pageseek(&vf->oy,og);
-
- if(more<0){
- /* skipped n bytes */
- vf->offset-=more;
- }else{
- if(more==0){
- /* send more paramedics */
- if(!boundary)return(OV_FALSE);
- {
- long ret=_get_data(vf);
- if(ret==0)return(OV_EOF);
- if(ret<0)return(OV_EREAD);
- }
- }else{
- /* got a page. Return the offset at the page beginning,
- advance the internal offset past the page end */
- ogg_int64_t ret=vf->offset;
- vf->offset+=more;
- return(ret);
-
- }
- }
- }
- }
-
- /* find the latest page beginning before the current stream cursor
- position. Much dirtier than the above as Ogg doesn't have any
- backward search linkage. no 'readp' as it will certainly have to
- read. */
- /* returns offset or OV_EREAD, OV_FAULT */
- static ogg_int64_t _get_prev_page(OggVorbis_File *vf,ogg_page *og){
- ogg_int64_t begin=vf->offset;
- ogg_int64_t end=begin;
- ogg_int64_t ret;
- ogg_int64_t offset=-1;
-
- while(offset==-1){
- begin-=CHUNKSIZE;
- if(begin<0)
- begin=0;
- _seek_helper(vf,begin);
- while(vf->offset<end){
- ret=_get_next_page(vf,og,end-vf->offset);
- if(ret==OV_EREAD)return(OV_EREAD);
- if(ret<0){
- break;
- }else{
- offset=ret;
- }
- }
- }
-
- /* we have the offset. Actually snork and hold the page now */
- _seek_helper(vf,offset);
- ret=_get_next_page(vf,og,CHUNKSIZE);
- if(ret<0)
- /* this shouldn't be possible */
- return(OV_EFAULT);
-
- return(offset);
- }
-
- /* finds each bitstream link one at a time using a bisection search
- (has to begin by knowing the offset of the lb's initial page).
- Recurses for each link so it can alloc the link storage after
- finding them all, then unroll and fill the cache at the same time */
- static int _bisect_forward_serialno(OggVorbis_File *vf,
- ogg_int64_t begin,
- ogg_int64_t searched,
- ogg_int64_t end,
- long currentno,
- long m){
- ogg_int64_t endsearched=end;
- ogg_int64_t next=end;
- ogg_page og;
- ogg_int64_t ret;
-
- /* the below guards against garbage seperating the last and
- first pages of two links. */
- while(searched<endsearched){
- ogg_int64_t bisect;
-
- if(endsearched-searched<CHUNKSIZE){
- bisect=searched;
- }else{
- bisect=(searched+endsearched)/2;
- }
-
- _seek_helper(vf,bisect);
- ret=_get_next_page(vf,&og,-1);
- if(ret==OV_EREAD)return(OV_EREAD);
- if(ret<0 || ogg_page_serialno(&og)!=currentno){
- endsearched=bisect;
- if(ret>=0)next=ret;
- }else{
- searched=ret+og.header_len+og.body_len;
- }
- }
-
- _seek_helper(vf,next);
- ret=_get_next_page(vf,&og,-1);
- if(ret==OV_EREAD)return(OV_EREAD);
-
- if(searched>=end || ret<0){
- vf->links=m+1;
- vf->offsets=(ogg_int64_t*)_ogg_malloc((vf->links+1)*sizeof(*vf->offsets));
- vf->serialnos=(long*)_ogg_malloc(vf->links*sizeof(*vf->serialnos));
- vf->offsets[m+1]=searched;
- }else{
- ret=_bisect_forward_serialno(vf,next,vf->offset,
- end,ogg_page_serialno(&og),m+1);
- if(ret==OV_EREAD)return(OV_EREAD);
- }
-
- vf->offsets[m]=begin;
- vf->serialnos[m]=currentno;
- return(0);
- }
-
- /* uses the local ogg_stream storage in vf; this is important for
- non-streaming input sources */
- static int _fetch_headers(OggVorbis_File *vf,vorbis_info *vi,vorbis_comment *vc,
- long *serialno,ogg_page *og_ptr){
- ogg_page og;
- ogg_packet op;
- int i,ret;
-
- if(!og_ptr){
- ogg_int64_t llret=_get_next_page(vf,&og,CHUNKSIZE);
- if(llret==OV_EREAD)return(OV_EREAD);
- if(llret<0)return OV_ENOTVORBIS;
- og_ptr=&og;
- }
-
- ogg_stream_reset_serialno(&vf->os,ogg_page_serialno(og_ptr));
- if(serialno)*serialno=vf->os.serialno;
- vf->ready_state=STREAMSET;
-
- /* extract the initial header from the first page and verify that the
- Ogg bitstream is in fact Vorbis data */
-
- vorbis_info_init(vi);
- vorbis_comment_init(vc);
-
- i=0;
- while(i<3){
- ogg_stream_pagein(&vf->os,og_ptr);
- while(i<3){
- int result=ogg_stream_packetout(&vf->os,&op);
- if(result==0)break;
- if(result==-1){
- ret=OV_EBADHEADER;
- goto bail_header;
- }
- if((ret=vorbis_synthesis_headerin(vi,vc,&op))){
- goto bail_header;
- }
- i++;
- }
- if(i<3)
- if(_get_next_page(vf,og_ptr,CHUNKSIZE)<0){
- ret=OV_EBADHEADER;
- goto bail_header;
- }
- }
- return 0;
-
- bail_header:
- vorbis_info_clear(vi);
- vorbis_comment_clear(vc);
- vf->ready_state=OPENED;
-
- return ret;
- }
-
- /* last step of the OggVorbis_File initialization; get all the
- vorbis_info structs and PCM positions. Only called by the seekable
- initialization (local stream storage is hacked slightly; pay
- attention to how that's done) */
-
- /* this is void and does not propogate errors up because we want to be
- able to open and use damaged bitstreams as well as we can. Just
- watch out for missing information for links in the OggVorbis_File
- struct */
- static void _prefetch_all_headers(OggVorbis_File *vf, ogg_int64_t dataoffset){
- ogg_page og;
- int i;
- ogg_int64_t ret;
-
- vf->vi=(vorbis_info*) _ogg_realloc(vf->vi,vf->links*sizeof(*vf->vi));
- vf->vc=(vorbis_comment*) _ogg_realloc(vf->vc,vf->links*sizeof(*vf->vc));
- vf->dataoffsets=(ogg_int64_t*) _ogg_malloc(vf->links*sizeof(*vf->dataoffsets));
- vf->pcmlengths=(ogg_int64_t*) _ogg_malloc(vf->links*2*sizeof(*vf->pcmlengths));
-
- for(i=0;i<vf->links;i++){
- if(i==0){
- /* we already grabbed the initial header earlier. Just set the offset */
- vf->dataoffsets[i]=dataoffset;
- _seek_helper(vf,dataoffset);
-
- }else{
-
- /* seek to the location of the initial header */
-
- _seek_helper(vf,vf->offsets[i]);
- if(_fetch_headers(vf,vf->vi+i,vf->vc+i,NULL,NULL)<0){
- vf->dataoffsets[i]=-1;
- }else{
- vf->dataoffsets[i]=vf->offset;
- }
- }
-
- /* fetch beginning PCM offset */
-
- if(vf->dataoffsets[i]!=-1){
- ogg_int64_t accumulated=0;
- long lastblock=-1;
- int result;
-
- ogg_stream_reset_serialno(&vf->os,vf->serialnos[i]);
-
- while(1){
- ogg_packet op;
-
- ret=_get_next_page(vf,&og,-1);
- if(ret<0)
- /* this should not be possible unless the file is
- truncated/mangled */
- break;
-
- if(ogg_page_serialno(&og)!=vf->serialnos[i])
- break;
-
- /* count blocksizes of all frames in the page */
- ogg_stream_pagein(&vf->os,&og);
- while((result=ogg_stream_packetout(&vf->os,&op))){
- if(result>0){ /* ignore holes */
- long thisblock=vorbis_packet_blocksize(vf->vi+i,&op);
- if(lastblock!=-1)
- accumulated+=(lastblock+thisblock)>>2;
- lastblock=thisblock;
- }
- }
-
- if(ogg_page_granulepos(&og)!=-1){
- /* pcm offset of last packet on the first audio page */
- accumulated= ogg_page_granulepos(&og)-accumulated;
- break;
- }
- }
-
- /* less than zero? This is a stream with samples trimmed off
- the beginning, a normal occurrence; set the offset to zero */
- if(accumulated<0)accumulated=0;
-
- vf->pcmlengths[i*2]=accumulated;
- }
-
- /* get the PCM length of this link. To do this,
- get the last page of the stream */
- {
- ogg_int64_t end=vf->offsets[i+1];
- _seek_helper(vf,end);
-
- while(1){
- ret=_get_prev_page(vf,&og);
- if(ret<0){
- /* this should not be possible */
- vorbis_info_clear(vf->vi+i);
- vorbis_comment_clear(vf->vc+i);
- break;
- }
- if(ogg_page_granulepos(&og)!=-1){
- vf->pcmlengths[i*2+1]=ogg_page_granulepos(&og)-vf->pcmlengths[i*2];
- break;
- }
- vf->offset=ret;
- }
- }
- }
- }
-
- static int _make_decode_ready(OggVorbis_File *vf){
- if(vf->ready_state>STREAMSET)return 0;
- if(vf->ready_state<STREAMSET)return OV_EFAULT;
- if(vf->seekable){
- if(vorbis_synthesis_init(&vf->vd,vf->vi+vf->current_link))
- return OV_EBADLINK;
- }else{
- if(vorbis_synthesis_init(&vf->vd,vf->vi))
- return OV_EBADLINK;
- }
- vorbis_block_init(&vf->vd,&vf->vb);
- vf->ready_state=INITSET;
- vf->bittrack=0.f;
- vf->samptrack=0.f;
- return 0;
- }
-
- static int _open_seekable2(OggVorbis_File *vf){
- long serialno=vf->current_serialno;
- ogg_int64_t dataoffset=vf->offset, end;
- ogg_page og;
-
- /* we're partially open and have a first link header state in
- storage in vf */
- /* we can seek, so set out learning all about this file */
- (vf->callbacks.seek_func)(vf->datasource,0,SEEK_END);
- vf->offset=vf->end=(vf->callbacks.tell_func)(vf->datasource);
-
- /* We get the offset for the last page of the physical bitstream.
- Most OggVorbis files will contain a single logical bitstream */
- end=_get_prev_page(vf,&og);
- if(end<0)return(end);
-
- /* more than one logical bitstream? */
- if(ogg_page_serialno(&og)!=serialno){
-
- /* Chained bitstream. Bisect-search each logical bitstream
- section. Do so based on serial number only */
- if(_bisect_forward_serialno(vf,0,0,end+1,serialno,0)<0)return(OV_EREAD);
-
- }else{
-
- /* Only one logical bitstream */
- if(_bisect_forward_serialno(vf,0,end,end+1,serialno,0))return(OV_EREAD);
-
- }
-
- /* the initial header memory is referenced by vf after; don't free it */
- _prefetch_all_headers(vf,dataoffset);
- return(ov_raw_seek(vf,0));
- }
-
- /* clear out the current logical bitstream decoder */
- static void _decode_clear(OggVorbis_File *vf){
- vorbis_dsp_clear(&vf->vd);
- vorbis_block_clear(&vf->vb);
- vf->ready_state=OPENED;
- }
-
- /* fetch and process a packet. Handles the case where we're at a
- bitstream boundary and dumps the decoding machine. If the decoding
- machine is unloaded, it loads it. It also keeps pcm_offset up to
- date (seek and read both use this. seek uses a special hack with
- readp).
-
- return: <0) error, OV_HOLE (lost packet) or OV_EOF
- 0) need more data (only if readp==0)
- 1) got a packet
- */
-
- static int _fetch_and_process_packet(OggVorbis_File *vf,
- ogg_packet *op_in,
- int readp,
- int spanp){
- ogg_page og;
-
- /* handle one packet. Try to fetch it from current stream state */
- /* extract packets from page */
- while(1){
-
- /* process a packet if we can. If the machine isn't loaded,
- neither is a page */
- if(vf->ready_state==INITSET){
- while(1) {
- ogg_packet op;
- ogg_packet *op_ptr=(op_in?op_in:&op);
- int result=ogg_stream_packetout(&vf->os,op_ptr);
- ogg_int64_t granulepos;
-
- op_in=NULL;
- if(result==-1)return(OV_HOLE); /* hole in the data. */
- if(result>0){
- /* got a packet. process it */
- granulepos=op_ptr->granulepos;
- if(!vorbis_synthesis(&vf->vb,op_ptr)){ /* lazy check for lazy
- header handling. The
- header packets aren't
- audio, so if/when we
- submit them,
- vorbis_synthesis will
- reject them */
-
- /* suck in the synthesis data and track bitrate */
- {
- int oldsamples=vorbis_synthesis_pcmout(&vf->vd,NULL);
- /* for proper use of libvorbis within libvorbisfile,
- oldsamples will always be zero. */
- if(oldsamples)return(OV_EFAULT);
-
- vorbis_synthesis_blockin(&vf->vd,&vf->vb);
- vf->samptrack+=vorbis_synthesis_pcmout(&vf->vd,NULL)-oldsamples;
- vf->bittrack+=op_ptr->bytes*8;
- }
-
- /* update the pcm offset. */
- if(granulepos!=-1 && !op_ptr->e_o_s){
- int link=(vf->seekable?vf->current_link:0);
- int i,samples;
-
- /* this packet has a pcm_offset on it (the last packet
- completed on a page carries the offset) After processing
- (above), we know the pcm position of the *last* sample
- ready to be returned. Find the offset of the *first*
-
- As an aside, this trick is inaccurate if we begin
- reading anew right at the last page; the end-of-stream
- granulepos declares the last frame in the stream, and the
- last packet of the last page may be a partial frame.
- So, we need a previous granulepos from an in-sequence page
- to have a reference point. Thus the !op_ptr->e_o_s clause
- above */
-
- if(vf->seekable && link>0)
- granulepos-=vf->pcmlengths[link*2];
- if(granulepos<0)granulepos=0; /* actually, this
- shouldn't be possible
- here unless the stream
- is very broken */
-
- samples=vorbis_synthesis_pcmout(&vf->vd,NULL);
-
- granulepos-=samples;
- for(i=0;i<link;i++)
- granulepos+=vf->pcmlengths[i*2+1];
- vf->pcm_offset=granulepos;
- }
- return(1);
- }
- }
- else
- break;
- }
- }
-
- if(vf->ready_state>=OPENED){
- ogg_int64_t ret;
- if(!readp)return(0);
- if((ret=_get_next_page(vf,&og,-1))<0){
- return(OV_EOF); /* eof.
- leave unitialized */
- }
-
- /* bitrate tracking; add the header's bytes here, the body bytes
- are done by packet above */
- vf->bittrack+=og.header_len*8;
-
- /* has our decoding just traversed a bitstream boundary? */
- if(vf->ready_state==INITSET){
- if(vf->current_serialno!=ogg_page_serialno(&og)){
- if(!spanp)
- return(OV_EOF);
-
- _decode_clear(vf);
-
- if(!vf->seekable){
- vorbis_info_clear(vf->vi);
- vorbis_comment_clear(vf->vc);
- }
- }
- }
- }
-
- /* Do we need to load a new machine before submitting the page? */
- /* This is different in the seekable and non-seekable cases.
-
- In the seekable case, we already have all the header
- information loaded and cached; we just initialize the machine
- with it and continue on our merry way.
-
- In the non-seekable (streaming) case, we'll only be at a
- boundary if we just left the previous logical bitstream and
- we're now nominally at the header of the next bitstream
- */
-
- if(vf->ready_state!=INITSET){
- int link;
-
- if(vf->ready_state<STREAMSET){
- if(vf->seekable){
- vf->current_serialno=ogg_page_serialno(&og);
-
- /* match the serialno to bitstream section. We use this rather than
- offset positions to avoid problems near logical bitstream
- boundaries */
- for(link=0;link<vf->links;link++)
- if(vf->serialnos[link]==vf->current_serialno)break;
- if(link==vf->links)return(OV_EBADLINK); /* sign of a bogus
- stream. error out,
- leave machine
- uninitialized */
-
- vf->current_link=link;
-
- ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
- vf->ready_state=STREAMSET;
-
- }else{
- /* we're streaming */
- /* fetch the three header packets, build the info struct */
-
- int ret=_fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,&og);
- if(ret)return(ret);
- vf->current_link++;
- link=0;
- }
- }
-
- {
- int ret=_make_decode_ready(vf);
- if(ret<0)return ret;
- }
- }
- ogg_stream_pagein(&vf->os,&og);
- }
- }
-
- /* if, eg, 64 bit stdio is configured by default, this will build with
- fseek64 */
- static int _fseek64_wrap(FILE *f,ogg_int64_t off,int whence){
- if(f==NULL)return(-1);
- return fseek(f,off,whence);
- }
-
- static int _ov_open1(void *f,OggVorbis_File *vf,char *initial,
- long ibytes, ov_callbacks callbacks){
- int offsettest=(f?callbacks.seek_func(f,0,SEEK_CUR):-1);
- int ret;
-
- memset(vf,0,sizeof(*vf));
- vf->datasource=f;
- vf->callbacks = callbacks;
-
- /* init the framing state */
- ogg_sync_init(&vf->oy);
-
- /* perhaps some data was previously read into a buffer for testing
- against other stream types. Allow initialization from this
- previously read data (as we may be reading from a non-seekable
- stream) */
- if(initial){
- char *buffer=ogg_sync_buffer(&vf->oy,ibytes);
- memcpy(buffer,initial,ibytes);
- ogg_sync_wrote(&vf->oy,ibytes);
- }
-
- /* can we seek? Stevens suggests the seek test was portable */
- if(offsettest!=-1)vf->seekable=1;
-
- /* No seeking yet; Set up a 'single' (current) logical bitstream
- entry for partial open */
- vf->links=1;
- vf->vi=(vorbis_info*) _ogg_calloc(vf->links,sizeof(*vf->vi));
- vf->vc=(vorbis_comment*) _ogg_calloc(vf->links,sizeof(*vf->vc));
- ogg_stream_init(&vf->os,-1); /* fill in the serialno later */
-
- /* Try to fetch the headers, maintaining all the storage */
- if((ret=_fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,NULL))<0){
- vf->datasource=NULL;
- ov_clear(vf);
- }else
- vf->ready_state=PARTOPEN;
- return(ret);
- }
-
- static int _ov_open2(OggVorbis_File *vf){
- if(vf->ready_state != PARTOPEN) return OV_EINVAL;
- vf->ready_state=OPENED;
- if(vf->seekable){
- int ret=_open_seekable2(vf);
- if(ret){
- vf->datasource=NULL;
- ov_clear(vf);
- }
- return(ret);
- }else
- vf->ready_state=STREAMSET;
-
- return 0;
- }
-
- /* clear out the OggVorbis_File struct */
- int ov_clear(OggVorbis_File *vf){
- if(vf){
- vorbis_block_clear(&vf->vb);
- vorbis_dsp_clear(&vf->vd);
- ogg_stream_clear(&vf->os);
-
- if(vf->vi && vf->links){
- int i;
- for(i=0;i<vf->links;i++){
- vorbis_info_clear(vf->vi+i);
- vorbis_comment_clear(vf->vc+i);
- }
- _ogg_free(vf->vi);
- _ogg_free(vf->vc);
- }
- if(vf->dataoffsets)_ogg_free(vf->dataoffsets);
- if(vf->pcmlengths)_ogg_free(vf->pcmlengths);
- if(vf->serialnos)_ogg_free(vf->serialnos);
- if(vf->offsets)_ogg_free(vf->offsets);
- ogg_sync_clear(&vf->oy);
- if(vf->datasource)(vf->callbacks.close_func)(vf->datasource);
- memset(vf,0,sizeof(*vf));
- }
- #ifdef DEBUG_LEAKS
- _VDBG_dump();
- #endif
- return(0);
- }
-
- /* inspects the OggVorbis file and finds/documents all the logical
- bitstreams contained in it. Tries to be tolerant of logical
- bitstream sections that are truncated/woogie.
-
- return: -1) error
- 0) OK
- */
-
- int ov_open_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes,
- ov_callbacks callbacks){
- int ret=_ov_open1(f,vf,initial,ibytes,callbacks);
- if(ret)return ret;
- return _ov_open2(vf);
- }
-
- int ov_open(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){
- ov_callbacks callbacks = {
- (size_t (*)(void *, size_t, size_t, void *)) fread,
- (int (*)(void *, ogg_int64_t, int)) _fseek64_wrap,
- (int (*)(void *)) fclose,
- (long (*)(void *)) ftell
- };
-
- return ov_open_callbacks((void *)f, vf, initial, ibytes, callbacks);
- }
-
- /* cheap hack for game usage where downsampling is desirable; there's
- no need for SRC as we can just do it cheaply in libvorbis. */
-
- int ov_halfrate(OggVorbis_File *vf,int flag){
- int i;
- if(vf->vi==NULL)return OV_EINVAL;
- if(!vf->seekable)return OV_EINVAL;
- if(vf->ready_state>=STREAMSET)
- _decode_clear(vf); /* clear out stream state; later on libvorbis
- will be able to swap this on the fly, but
- for now dumping the decode machine is needed
- to reinit the MDCT lookups. 1.1 libvorbis
- is planned to be able to switch on the fly */
-
- for(i=0;i<vf->links;i++){
- if(vorbis_synthesis_halfrate(vf->vi+i,flag)){
- ov_halfrate(vf,0);
- return OV_EINVAL;
- }
- }
- return 0;
- }
-
- int ov_halfrate_p(OggVorbis_File *vf){
- if(vf->vi==NULL)return OV_EINVAL;
- return vorbis_synthesis_halfrate_p(vf->vi);
- }
-
- /* Only partially open the vorbis file; test for Vorbisness, and load
- the headers for the first chain. Do not seek (although test for
- seekability). Use ov_test_open to finish opening the file, else
- ov_clear to close/free it. Same return codes as open. */
-
- int ov_test_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes,
- ov_callbacks callbacks)
- {
- return _ov_open1(f,vf,initial,ibytes,callbacks);
- }
-
- int ov_test(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){
- ov_callbacks callbacks = {
- (size_t (*)(void *, size_t, size_t, void *)) fread,
- (int (*)(void *, ogg_int64_t, int)) _fseek64_wrap,
- (int (*)(void *)) fclose,
- (long (*)(void *)) ftell
- };
-
- return ov_test_callbacks((void *)f, vf, initial, ibytes, callbacks);
- }
-
- int ov_test_open(OggVorbis_File *vf){
- if(vf->ready_state!=PARTOPEN)return(OV_EINVAL);
- return _ov_open2(vf);
- }
-
- /* How many logical bitstreams in this physical bitstream? */
- long ov_streams(OggVorbis_File *vf){
- return vf->links;
- }
-
- /* Is the FILE * associated with vf seekable? */
- long ov_seekable(OggVorbis_File *vf){
- return vf->seekable;
- }
-
- /* returns the bitrate for a given logical bitstream or the entire
- physical bitstream. If the file is open for random access, it will
- find the *actual* average bitrate. If the file is streaming, it
- returns the nominal bitrate (if set) else the average of the
- upper/lower bounds (if set) else -1 (unset).
-
- If you want the actual bitrate field settings, get them from the
- vorbis_info structs */
-
- long ov_bitrate(OggVorbis_File *vf,int i){
- if(vf->ready_state<OPENED)return(OV_EINVAL);
- if(i>=vf->links)return(OV_EINVAL);
- if(!vf->seekable && i!=0)return(ov_bitrate(vf,0));
- if(i<0){
- ogg_int64_t bits=0;
- int i;
- float br;
- for(i=0;i<vf->links;i++)
- bits+=(vf->offsets[i+1]-vf->dataoffsets[i])*8;
- /* This once read: return(rint(bits/ov_time_total(vf,-1)));
- * gcc 3.x on x86 miscompiled this at optimisation level 2 and above,
- * so this is slightly transformed to make it work.
- */
- br = bits/ov_time_total(vf,-1);
- return(rint(br));
- }else{
- if(vf->seekable){
- /* return the actual bitrate */
- return(rint((vf->offsets[i+1]-vf->dataoffsets[i])*8/ov_time_total(vf,i)));
- }else{
- /* return nominal if set */
- if(vf->vi[i].bitrate_nominal>0){
- return vf->vi[i].bitrate_nominal;
- }else{
- if(vf->vi[i].bitrate_upper>0){
- if(vf->vi[i].bitrate_lower>0){
- return (vf->vi[i].bitrate_upper+vf->vi[i].bitrate_lower)/2;
- }else{
- return vf->vi[i].bitrate_upper;
- }
- }
- return(OV_FALSE);
- }
- }
- }
- }
-
- /* returns the actual bitrate since last call. returns -1 if no
- additional data to offer since last call (or at beginning of stream),
- EINVAL if stream is only partially open
- */
- long ov_bitrate_instant(OggVorbis_File *vf){
- int link=(vf->seekable?vf->current_link:0);
- long ret;
- if(vf->ready_state<OPENED)return(OV_EINVAL);
- if(vf->samptrack==0)return(OV_FALSE);
- ret=vf->bittrack/vf->samptrack*vf->vi[link].rate+.5;
- vf->bittrack=0.f;
- vf->samptrack=0.f;
- return(ret);
- }
-
- /* Guess */
- long ov_serialnumber(OggVorbis_File *vf,int i){
- if(i>=vf->links)return(ov_serialnumber(vf,vf->links-1));
- if(!vf->seekable && i>=0)return(ov_serialnumber(vf,-1));
- if(i<0){
- return(vf->current_serialno);
- }else{
- return(vf->serialnos[i]);
- }
- }
-
- /* returns: total raw (compressed) length of content if i==-1
- raw (compressed) length of that logical bitstream for i==0 to n
- OV_EINVAL if the stream is not seekable (we can't know the length)
- or if stream is only partially open
- */
- ogg_int64_t ov_raw_total(OggVorbis_File *vf,int i){
- if(vf->ready_state<OPENED)return(OV_EINVAL);
- if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
- if(i<0){
- ogg_int64_t acc=0;
- int i;
- for(i=0;i<vf->links;i++)
- acc+=ov_raw_total(vf,i);
- return(acc);
- }else{
- return(vf->offsets[i+1]-vf->offsets[i]);
- }
- }
-
- /* returns: total PCM length (samples) of content if i==-1 PCM length
- (samples) of that logical bitstream for i==0 to n
- OV_EINVAL if the stream is not seekable (we can't know the
- length) or only partially open
- */
- ogg_int64_t ov_pcm_total(OggVorbis_File *vf,int i){
- if(vf->ready_state<OPENED)return(OV_EINVAL);
- if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
- if(i<0){
- ogg_int64_t acc=0;
- int i;
- for(i=0;i<vf->links;i++)
- acc+=ov_pcm_total(vf,i);
- return(acc);
- }else{
- return(vf->pcmlengths[i*2+1]);
- }
- }
-
- /* returns: total seconds of content if i==-1
- seconds in that logical bitstream for i==0 to n
- OV_EINVAL if the stream is not seekable (we can't know the
- length) or only partially open
- */
- double ov_time_total(OggVorbis_File *vf,int i){
- if(vf->ready_state<OPENED)return(OV_EINVAL);
- if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
- if(i<0){
- double acc=0;
- int i;
- for(i=0;i<vf->links;i++)
- acc+=ov_time_total(vf,i);
- return(acc);
- }else{
- return((double)(vf->pcmlengths[i*2+1])/vf->vi[i].rate);
- }
- }
-
- /* seek to an offset relative to the *compressed* data. This also
- scans packets to update the PCM cursor. It will cross a logical
- bitstream boundary, but only if it can't get any packets out of the
- tail of the bitstream we seek to (so no surprises).
-
- returns zero on success, nonzero on failure */
-
- int ov_raw_seek(OggVorbis_File *vf,ogg_int64_t pos){
- ogg_stream_state work_os;
-
- if(vf->ready_state<OPENED)return(OV_EINVAL);
- if(!vf->seekable)
- return(OV_ENOSEEK); /* don't dump machine if we can't seek */
-
- if(pos<0 || pos>vf->end)return(OV_EINVAL);
-
- /* don't yet clear out decoding machine (if it's initialized), in
- the case we're in the same link. Restart the decode lapping, and
- let _fetch_and_process_packet deal with a potential bitstream
- boundary */
- vf->pcm_offset=-1;
- ogg_stream_reset_serialno(&vf->os,
- vf->current_serialno); /* must set serialno */
- vorbis_synthesis_restart(&vf->vd);
-
- _seek_helper(vf,pos);
-
- /* we need to make sure the pcm_offset is set, but we don't want to
- advance the raw cursor past good packets just to get to the first
- with a granulepos. That's not equivalent behavior to beginning
- decoding as immediately after the seek position as possible.
-
- So, a hack. We use two stream states; a local scratch state and
- the shared vf->os stream state. We use the local state to
- scan, and the shared state as a buffer for later decode.
-
- Unfortuantely, on the last page we still advance to last packet
- because the granulepos on the last page is not necessarily on a
- packet boundary, and we need to make sure the granpos is
- correct.
- */
-
- {
- ogg_page og;
- ogg_packet op;
- int lastblock=0;
- int accblock=0;
- int thisblock;
- int eosflag;
-
- ogg_stream_init(&work_os,vf->current_serialno); /* get the memory ready */
- ogg_stream_reset(&work_os); /* eliminate the spurious OV_HOLE
- return from not necessarily
- starting from the beginning */
-
- while(1){
- if(vf->ready_state>=STREAMSET){
- /* snarf/scan a packet if we can */
- int result=ogg_stream_packetout(&work_os,&op);
-
- if(result>0){
-
- if(vf->vi[vf->current_link].codec_setup){
- thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
- if(thisblock<0){
- ogg_stream_packetout(&vf->os,NULL);
- thisblock=0;
- }else{
-
- if(eosflag)
- ogg_stream_packetout(&vf->os,NULL);
- else
- if(lastblock)accblock+=(lastblock+thisblock)>>2;
- }
-
- if(op.granulepos!=-1){
- int i,link=vf->current_link;
- ogg_int64_t granulepos=op.granulepos-vf->pcmlengths[link*2];
- if(granulepos<0)granulepos=0;
-
- for(i=0;i<link;i++)
- granulepos+=vf->pcmlengths[i*2+1];
- vf->pcm_offset=granulepos-accblock;
- break;
- }
- lastblock=thisblock;
- continue;
- }else
- ogg_stream_packetout(&vf->os,NULL);
- }
- }
-
- if(!lastblock){
- if(_get_next_page(vf,&og,-1)<0){
- vf->pcm_offset=ov_pcm_total(vf,-1);
- break;
- }
- }else{
- /* huh? Bogus stream with packets but no granulepos */
- vf->pcm_offset=-1;
- break;
- }
-
- /* has our decoding just traversed a bitstream boundary? */
- if(vf->ready_state>=STREAMSET)
- if(vf->current_serialno!=ogg_page_serialno(&og)){
- _decode_clear(vf); /* clear out stream state */
- ogg_stream_clear(&work_os);
- }
-
- if(vf->ready_state<STREAMSET){
- int link;
-
- vf->current_serialno=ogg_page_serialno(&og);
- for(link=0;link<vf->links;link++)
- if(vf->serialnos[link]==vf->current_serialno)break;
- if(link==vf->links)goto seek_error; /* sign of a bogus stream.
- error out, leave
- machine uninitialized */
- vf->current_link=link;
-
- ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
- ogg_stream_reset_serialno(&work_os,vf->current_serialno);
- vf->ready_state=STREAMSET;
-
- }
-
- ogg_stream_pagein(&vf->os,&og);
- ogg_stream_pagein(&work_os,&og);
- eosflag=ogg_page_eos(&og);
- }
- }
-
- ogg_stream_clear(&work_os);
- vf->bittrack=0.f;
- vf->samptrack=0.f;
- return(0);
-
- seek_error:
- /* dump the machine so we're in a known state */
- vf->pcm_offset=-1;
- ogg_stream_clear(&work_os);
- _decode_clear(vf);
- return OV_EBADLINK;
- }
-
- /* Page granularity seek (faster than sample granularity because we
- don't do the last bit of decode to find a specific sample).
-
- Seek to the last [granule marked] page preceeding the specified pos
- location, such that decoding past the returned point will quickly
- arrive at the requested position. */
- int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos){
- int link=-1;
- ogg_int64_t result=0;
- ogg_int64_t total=ov_pcm_total(vf,-1);
-
- if(vf->ready_state<OPENED)return(OV_EINVAL);
- if(!vf->seekable)return(OV_ENOSEEK);
-
- if(pos<0 || pos>total)return(OV_EINVAL);
-
- /* which bitstream section does this pcm offset occur in? */
- for(link=vf->links-1;link>=0;link--){
- total-=vf->pcmlengths[link*2+1];
- if(pos>=total)break;
- }
-
- /* search within the logical bitstream for the page with the highest
- pcm_pos preceeding (or equal to) pos. There is a danger here;
- missing pages or incorrect frame number information in the
- bitstream could make our task impossible. Account for that (it
- would be an error condition) */
-
- /* new search algorithm by HB (Nicholas Vinen) */
- {
- ogg_int64_t end=vf->offsets[link+1];
- ogg_int64_t begin=vf->offsets[link];
- ogg_int64_t begintime = vf->pcmlengths[link*2];
- ogg_int64_t endtime = vf->pcmlengths[link*2+1]+begintime;
- ogg_int64_t target=pos-total+begintime;
- ogg_int64_t best=begin;
-
- ogg_page og;
- while(begin<end){
- ogg_int64_t bisect;
-
- if(end-begin<CHUNKSIZE){
- bisect=begin;
- }else{
- /* take a (pretty decent) guess. */
- bisect=begin +
- (target-begintime)*(end-begin)/(endtime-begintime) - CHUNKSIZE;
- if(bisect<=begin)
- bisect=begin+1;
- }
-
- _seek_helper(vf,bisect);
-
- while(begin<end){
- result=_get_next_page(vf,&og,end-vf->offset);
- if(result==OV_EREAD) goto seek_error;
- if(result<0){
- if(bisect<=begin+1)
- end=begin; /* found it */
- else{
- if(bisect==0) goto seek_error;
- bisect-=CHUNKSIZE;
- if(bisect<=begin)bisect=begin+1;
- _seek_helper(vf,bisect);
- }
- }else{
- ogg_int64_t granulepos=ogg_page_granulepos(&og);
- if(granulepos==-1)continue;
- if(granulepos<target){
- best=result; /* raw offset of packet with granulepos */
- begin=vf->offset; /* raw offset of next page */
- begintime=granulepos;
-
- if(target-begintime>44100)break;
- bisect=begin; /* *not* begin + 1 */
- }else{
- if(bisect<=begin+1)
- end=begin; /* found it */
- else{
- if(end==vf->offset){ /* we're pretty close - we'd be stuck in */
- end=result;
- bisect-=CHUNKSIZE; /* an endless loop otherwise. */
- if(bisect<=begin)bisect=begin+1;
- _seek_helper(vf,bisect);
- }else{
- end=result;
- endtime=granulepos;
- break;
- }
- }
- }
- }
- }
- }
-
- /* found our page. seek to it, update pcm offset. Easier case than
- raw_seek, don't keep packets preceeding granulepos. */
- {
- ogg_page og;
- ogg_packet op;
-
- /* seek */
- _seek_helper(vf,best);
- vf->pcm_offset=-1;
-
- if(_get_next_page(vf,&og,-1)<0)return(OV_EOF); /* shouldn't happen */
-
- if(link!=vf->current_link){
- /* Different link; dump entire decode machine */
- _decode_clear(vf);
-
- vf->current_link=link;
- vf->current_serialno=ogg_page_serialno(&og);
- vf->ready_state=STREAMSET;
-
- }else{
- vorbis_synthesis_restart(&vf->vd);
- }
-
- ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
- ogg_stream_pagein(&vf->os,&og);
-
- /* pull out all but last packet; the one with granulepos */
- while(1){
- result=ogg_stream_packetpeek(&vf->os,&op);
- if(result==0){
- /* !!! the packet finishing this page originated on a
- preceeding page. Keep fetching previous pages until we
- get one with a granulepos or without the 'continued' flag
- set. Then just use raw_seek for simplicity. */
-
- _seek_helper(vf,best);
-
- while(1){
- result=_get_prev_page(vf,&og);
- if(result<0) goto seek_error;
- if(ogg_page_granulepos(&og)>-1 ||
- !ogg_page_continued(&og)){
- return ov_raw_seek(vf,result);
- }
- vf->offset=result;
- }
- }
- if(result<0){
- result = OV_EBADPACKET;
- goto seek_error;
- }
- if(op.granulepos!=-1){
- vf->pcm_offset=op.granulepos-vf->pcmlengths[vf->current_link*2];
- if(vf->pcm_offset<0)vf->pcm_offset=0;
- vf->pcm_offset+=total;
- break;
- }else
- result=ogg_stream_packetout(&vf->os,NULL);
- }
- }
- }
-
- /* verify result */
- if(vf->pcm_offset>pos || pos>ov_pcm_total(vf,-1)){
- result=OV_EFAULT;
- goto seek_error;
- }
- vf->bittrack=0.f;
- vf->samptrack=0.f;
- return(0);
-
- seek_error:
- /* dump machine so we're in a known state */
- vf->pcm_offset=-1;
- _decode_clear(vf);
- return (int)result;
- }
-
- /* seek to a sample offset relative to the decompressed pcm stream
- returns zero on success, nonzero on failure */
-
- int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos){
- int thisblock,lastblock=0;
- int ret=ov_pcm_seek_page(vf,pos);
- if(ret<0)return(ret);
- if((ret=_make_decode_ready(vf)))return ret;
-
- /* discard leading packets we don't need for the lapping of the
- position we want; don't decode them */
-
- while(1){
- ogg_packet op;
- ogg_page og;
-
- int ret=ogg_stream_packetpeek(&vf->os,&op);
- if(ret>0){
- thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
- if(thisblock<0){
- ogg_stream_packetout(&vf->os,NULL);
- continue; /* non audio packet */
- }
- if(lastblock)vf->pcm_offset+=(lastblock+thisblock)>>2;
-
- if(vf->pcm_offset+((thisblock+
- vorbis_info_blocksize(vf->vi,1))>>2)>=pos)break;
-
- /* remove the packet from packet queue and track its granulepos */
- ogg_stream_packetout(&vf->os,NULL);
- vorbis_synthesis_trackonly(&vf->vb,&op); /* set up a vb with
- only tracking, no
- pcm_decode */
- vorbis_synthesis_blockin(&vf->vd,&vf->vb);
-
- /* end of logical stream case is hard, especially with exact
- length positioning. */
-
- if(op.granulepos>-1){
- int i;
- /* always believe the stream markers */
- vf->pcm_offset=op.granulepos-vf->pcmlengths[vf->current_link*2];
- if(vf->pcm_offset<0)vf->pcm_offset=0;
- for(i=0;i<vf->current_link;i++)
- vf->pcm_offset+=vf->pcmlengths[i*2+1];
- }
-
- lastblock=thisblock;
-
- }else{
- if(ret<0 && ret!=OV_HOLE)break;
-
- /* suck in a new page */
- if(_get_next_page(vf,&og,-1)<0)break;
- if(vf->current_serialno!=ogg_page_serialno(&og))_decode_clear(vf);
-
- if(vf->ready_state<STREAMSET){
- int link;
-
- vf->current_serialno=ogg_page_serialno(&og);
- for(link=0;link<vf->links;link++)
- if(vf->serialnos[link]==vf->current_serialno)break;
- if(link==vf->links)return(OV_EBADLINK);
- vf->current_link=link;
-
- ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
- vf->ready_state=STREAMSET;
- ret=_make_decode_ready(vf);
- if(ret)return ret;
- lastblock=0;
- }
-
- ogg_stream_pagein(&vf->os,&og);
- }
- }
-
- vf->bittrack=0.f;
- vf->samptrack=0.f;
- /* discard samples until we reach the desired position. Crossing a
- logical bitstream boundary with abandon is OK. */
- while(vf->pcm_offset<pos){
- ogg_int64_t target=pos-vf->pcm_offset;
- long samples=vorbis_synthesis_pcmout(&vf->vd,NULL);
-
- if(samples>target)samples=target;
- vorbis_synthesis_read(&vf->vd,samples);
- vf->pcm_offset+=samples;
-
- if(samples<target)
- if(_fetch_and_process_packet(vf,NULL,1,1)<=0)
- vf->pcm_offset=ov_pcm_total(vf,-1); /* eof */
- }
- return 0;
- }
-
- /* seek to a playback time relative to the decompressed pcm stream
- returns zero on success, nonzero on failure */
- int ov_time_seek(OggVorbis_File *vf,double seconds){
- /* translate time to PCM position and call ov_pcm_seek */
-
- int link=-1;
- ogg_int64_t pcm_total=ov_pcm_total(vf,-1);
- double time_total=ov_time_total(vf,-1);
-
- if(vf->ready_state<OPENED)return(OV_EINVAL);
- if(!vf->seekable)return(OV_ENOSEEK);
- if(seconds<0 || seconds>time_total)return(OV_EINVAL);
-
- /* which bitstream section does this time offset occur in? */
- for(link=vf->links-1;link>=0;link--){
- pcm_total-=vf->pcmlengths[link*2+1];
- time_total-=ov_time_total(vf,link);
- if(seconds>=time_total)break;
- }
-
- /* enough information to convert time offset to pcm offset */
- {
- ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
- return(ov_pcm_seek(vf,target));
- }
- }
-
- /* page-granularity version of ov_time_seek
- returns zero on success, nonzero on failure */
- int ov_time_seek_page(OggVorbis_File *vf,double seconds){
- /* translate time to PCM position and call ov_pcm_seek */
-
- int link=-1;
- ogg_int64_t pcm_total=ov_pcm_total(vf,-1);
- double time_total=ov_time_total(vf,-1);
-
- if(vf->ready_state<OPENED)return(OV_EINVAL);
- if(!vf->seekable)return(OV_ENOSEEK);
- if(seconds<0 || seconds>time_total)return(OV_EINVAL);
-
- /* which bitstream section does this time offset occur in? */
- for(link=vf->links-1;link>=0;link--){
- pcm_total-=vf->pcmlengths[link*2+1];
- time_total-=ov_time_total(vf,link);
- if(seconds>=time_total)break;
- }
-
- /* enough information to convert time offset to pcm offset */
- {
- ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
- return(ov_pcm_seek_page(vf,target));
- }
- }
-
- /* tell the current stream offset cursor. Note that seek followed by
- tell will likely not give the set offset due to caching */
- ogg_int64_t ov_raw_tell(OggVorbis_File *vf){
- if(vf->ready_state<OPENED)return(OV_EINVAL);
- return(vf->offset);
- }
-
- /* return PCM offset (sample) of next PCM sample to be read */
- ogg_int64_t ov_pcm_tell(OggVorbis_File *vf){
- if(vf->ready_state<OPENED)return(OV_EINVAL);
- return(vf->pcm_offset);
- }
-
- /* return time offset (seconds) of next PCM sample to be read */
- double ov_time_tell(OggVorbis_File *vf){
- int link=0;
- ogg_int64_t pcm_total=0;
- double time_total=0.f;
-
- if(vf->ready_state<OPENED)return(OV_EINVAL);
- if(vf->seekable){
- pcm_total=ov_pcm_total(vf,-1);
- time_total=ov_time_total(vf,-1);
-
- /* which bitstream section does this time offset occur in? */
- for(link=vf->links-1;link>=0;link--){
- pcm_total-=vf->pcmlengths[link*2+1];
- time_total-=ov_time_total(vf,link);
- if(vf->pcm_offset>=pcm_total)break;
- }
- }
-
- return((double)time_total+(double)(vf->pcm_offset-pcm_total)/vf->vi[link].rate);
- }
-
- /* link: -1) return the vorbis_info struct for the bitstream section
- currently being decoded
- 0-n) to request information for a specific bitstream section
-
- In the case of a non-seekable bitstream, any call returns the
- current bitstream. NULL in the case that the machine is not
- initialized */
-
- vorbis_info *ov_info(OggVorbis_File *vf,int link){
- if(vf->seekable){
- if(link<0)
- if(vf->ready_state>=STREAMSET)
- return vf->vi+vf->current_link;
- else
- return vf->vi;
- else
- if(link>=vf->links)
- return NULL;
- else
- return vf->vi+link;
- }else{
- return vf->vi;
- }
- }
-
- /* grr, strong typing, grr, no templates/inheritence, grr */
- vorbis_comment *ov_comment(OggVorbis_File *vf,int link){
- if(vf->seekable){
- if(link<0)
- if(vf->ready_state>=STREAMSET)
- return vf->vc+vf->current_link;
- else
- return vf->vc;
- else
- if(link>=vf->links)
- return NULL;
- else
- return vf->vc+link;
- }else{
- return vf->vc;
- }
- }
-
- static int host_is_big_endian() {
- ogg_int32_t pattern = 0xfeedface; /* deadbeef */
- unsigned char *bytewise = (unsigned char *)&pattern;
- if (bytewise[0] == 0xfe) return 1;
- return 0;
- }
-
- /* up to this point, everything could more or less hide the multiple
- logical bitstream nature of chaining from the toplevel application
- if the toplevel application didn't particularly care. However, at
- the point that we actually read audio back, the multiple-section
- nature must surface: Multiple bitstream sections do not necessarily
- have to have the same number of channels or sampling rate.
-
- ov_read returns the sequential logical bitstream number currently
- being decoded along with the PCM data in order that the toplevel
- application can take action on channel/sample rate changes. This
- number will be incremented even for streamed (non-seekable) streams
- (for seekable streams, it represents the actual logical bitstream
- index within the physical bitstream. Note that the accessor
- functions above are aware of this dichotomy).
-
- input values: buffer) a buffer to hold packed PCM data for return
- length) the byte length requested to be placed into buffer
- bigendianp) should the data be packed LSB first (0) or
- MSB first (1)
- word) word size for output. currently 1 (byte) or
- 2 (16 bit short)
-
- return values: <0) error/hole in data (OV_HOLE), partial open (OV_EINVAL)
- 0) EOF
- n) number of bytes of PCM actually returned. The
- below works on a packet-by-packet basis, so the
- return length is not related to the 'length' passed
- in, just guaranteed to fit.
-
- *section) set to the logical bitstream number */
-
- long ov_read(OggVorbis_File *vf,char *buffer,int length,
- int bigendianp,int word,int sgned,int *bitstream){
- int i,j;
- int host_endian = host_is_big_endian();
-
- float **pcm;
- long samples;
-
- if(vf->ready_state<OPENED)return(OV_EINVAL);
-
- while(1){
- if(vf->ready_state==INITSET){
- samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
- if(samples)break;
- }
-
- /* suck in another packet */
- {
- int ret=_fetch_and_process_packet(vf,NULL,1,1);
- if(ret==OV_EOF)
- return(0);
- if(ret<=0)
- return(ret);
- }
-
- }
-
- if(samples>0){
-
- /* yay! proceed to pack data into the byte buffer */
-
- long channels=ov_info(vf,-1)->channels;
- long bytespersample=word * channels;
- vorbis_fpu_control fpu;
- (void) fpu; // (to avoid a warning about it being unused)
- if(samples>length/bytespersample)samples=length/bytespersample;
-
- if(samples <= 0)
- return OV_EINVAL;
-
- /* a tight loop to pack each size */
- {
- int val;
- if(word==1){
- int off=(sgned?0:128);
- vorbis_fpu_setround(&fpu);
- for(j=0;j<samples;j++)
- for(i=0;i<channels;i++){
- val=vorbis_ftoi(pcm[i][j]*128.f);
- if(val>127)val=127;
- else if(val<-128)val=-128;
- *buffer++=val+off;
- }
- vorbis_fpu_restore(fpu);
- }else{
- int off=(sgned?0:32768);
-
- if(host_endian==bigendianp){
- if(sgned){
-
- vorbis_fpu_setround(&fpu);
- for(i=0;i<channels;i++) { /* It's faster in this order */
- float *src=pcm[i];
- short *dest=((short *)buffer)+i;
- for(j=0;j<samples;j++) {
- val=vorbis_ftoi(src[j]*32768.f);
- if(val>32767)val=32767;
- else if(val<-32768)val=-32768;
- *dest=val;
- dest+=channels;
- }
- }
- vorbis_fpu_restore(fpu);
-
- }else{
-
- vorbis_fpu_setround(&fpu);
- for(i=0;i<channels;i++) {
- float *src=pcm[i];
- short *dest=((short *)buffer)+i;
- for(j=0;j<samples;j++) {
- val=vorbis_ftoi(src[j]*32768.f);
- if(val>32767)val=32767;
- else if(val<-32768)val=-32768;
- *dest=val+off;
- dest+=channels;
- }
- }
- vorbis_fpu_restore(fpu);
-
- }
- }else if(bigendianp){
-
- vorbis_fpu_setround(&fpu);
- for(j=0;j<samples;j++)
- for(i=0;i<channels;i++){
- val=vorbis_ftoi(pcm[i][j]*32768.f);
- if(val>32767)val=32767;
- else if(val<-32768)val=-32768;
- val+=off;
- *buffer++=(val>>8);
- *buffer++=(val&0xff);
- }
- vorbis_fpu_restore(fpu);
-
- }else{
- int val;
- vorbis_fpu_setround(&fpu);
- for(j=0;j<samples;j++)
- for(i=0;i<channels;i++){
- val=vorbis_ftoi(pcm[i][j]*32768.f);
- if(val>32767)val=32767;
- else if(val<-32768)val=-32768;
- val+=off;
- *buffer++=(val&0xff);
- *buffer++=(val>>8);
- }
- vorbis_fpu_restore(fpu);
-
- }
- }
- }
-
- vorbis_synthesis_read(&vf->vd,samples);
- vf->pcm_offset+=samples;
- if(bitstream)*bitstream=vf->current_link;
- return(samples*bytespersample);
- }else{
- return(samples);
- }
- }
-
- /* input values: pcm_channels) a float vector per channel of output
- length) the sample length being read by the app
-
- return values: <0) error/hole in data (OV_HOLE), partial open (OV_EINVAL)
- 0) EOF
- n) number of samples of PCM actually returned. The
- below works on a packet-by-packet basis, so the
- return length is not related to the 'length' passed
- in, just guaranteed to fit.
-
- *section) set to the logical bitstream number */
-
- long ov_read_float(OggVorbis_File *vf,float ***pcm_channels,int length,
- int *bitstream){
-
- if(vf->ready_state<OPENED)return(OV_EINVAL);
-
- while(1){
- if(vf->ready_state==INITSET){
- float **pcm;
- long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
- if(samples){
- if(pcm_channels)*pcm_channels=pcm;
- if(samples>length)samples=length;
- vorbis_synthesis_read(&vf->vd,samples);
- vf->pcm_offset+=samples;
- if(bitstream)*bitstream=vf->current_link;
- return samples;
-
- }
- }
-
- /* suck in another packet */
- {
- int ret=_fetch_and_process_packet(vf,NULL,1,1);
- if(ret==OV_EOF)return(0);
- if(ret<=0)return(ret);
- }
-
- }
- }
-
- extern float *vorbis_window(vorbis_dsp_state *v,int W);
- extern void _analysis_output_always(char *base,int i,float *v,int n,int bark,int dB,
- ogg_int64_t off);
-
- static void _ov_splice(float **pcm,float **lappcm,
- int n1, int n2,
- int ch1, int ch2,
- float *w1, float *w2){
- int i,j;
- float *w=w1;
- int n=n1;
-
- if(n1>n2){
- n=n2;
- w=w2;
- }
-
- /* splice */
- for(j=0;j<ch1 && j<ch2;j++){
- float *s=lappcm[j];
- float *d=pcm[j];
-
- for(i=0;i<n;i++){
- float wd=w[i]*w[i];
- float ws=1.-wd;
- d[i]=d[i]*wd + s[i]*ws;
- }
- }
- /* window from zero */
- for(;j<ch2;j++){
- float *d=pcm[j];
- for(i=0;i<n;i++){
- float wd=w[i]*w[i];
- d[i]=d[i]*wd;
- }
- }
-
- }
-
- /* make sure vf is INITSET */
- static int _ov_initset(OggVorbis_File *vf){
- while(1){
- if(vf->ready_state==INITSET)break;
- /* suck in another packet */
- {
- int ret=_fetch_and_process_packet(vf,NULL,1,0);
- if(ret<0 && ret!=OV_HOLE)return(ret);
- }
- }
- return 0;
- }
-
- /* make sure vf is INITSET and that we have a primed buffer; if
- we're crosslapping at a stream section boundary, this also makes
- sure we're sanity checking against the right stream information */
- static int _ov_initprime(OggVorbis_File *vf){
- vorbis_dsp_state *vd=&vf->vd;
- while(1){
- if(vf->ready_state==INITSET)
- if(vorbis_synthesis_pcmout(vd,NULL))break;
-
- /* suck in another packet */
- {
- int ret=_fetch_and_process_packet(vf,NULL,1,0);
- if(ret<0 && ret!=OV_HOLE)return(ret);
- }
- }
- return 0;
- }
-
- /* grab enough data for lapping from vf; this may be in the form of
- unreturned, already-decoded pcm, remaining PCM we will need to
- decode, or synthetic postextrapolation from last packets. */
- static void _ov_getlap(OggVorbis_File *vf,vorbis_info *vi,vorbis_dsp_state *vd,
- float **lappcm,int lapsize){
- int lapcount=0,i;
- float **pcm;
-
- /* try first to decode the lapping data */
- while(lapcount<lapsize){
- int samples=vorbis_synthesis_pcmout(vd,&pcm);
- if(samples){
- if(samples>lapsize-lapcount)samples=lapsize-lapcount;
- for(i=0;i<vi->channels;i++)
- memcpy(lappcm[i]+lapcount,pcm[i],sizeof(**pcm)*samples);
- lapcount+=samples;
- vorbis_synthesis_read(vd,samples);
- }else{
- /* suck in another packet */
- int ret=_fetch_and_process_packet(vf,NULL,1,0); /* do *not* span */
- if(ret==OV_EOF)break;
- }
- }
- if(lapcount<lapsize){
- /* failed to get lapping data from normal decode; pry it from the
- postextrapolation buffering, or the second half of the MDCT
- from the last packet */
- int samples=vorbis_synthesis_lapout(&vf->vd,&pcm);
- if(samples==0){
- for(i=0;i<vi->channels;i++)
- memset(lappcm[i]+lapcount,0,sizeof(**pcm)*lapsize-lapcount);
- lapcount=lapsize;
- }else{
- if(samples>lapsize-lapcount)samples=lapsize-lapcount;
- for(i=0;i<vi->channels;i++)
- memcpy(lappcm[i]+lapcount,pcm[i],sizeof(**pcm)*samples);
- lapcount+=samples;
- }
- }
- }
-
- /* this sets up crosslapping of a sample by using trailing data from
- sample 1 and lapping it into the windowing buffer of sample 2 */
- int ov_crosslap(OggVorbis_File *vf1, OggVorbis_File *vf2){
- vorbis_info *vi1,*vi2;
- float **lappcm;
- float **pcm;
- float *w1,*w2;
- int n1,n2,i,ret,hs1,hs2;
-
- if(vf1==vf2)return(0); /* degenerate case */
- if(vf1->ready_state<OPENED)return(OV_EINVAL);
- if(vf2->ready_state<OPENED)return(OV_EINVAL);
-
- /* the relevant overlap buffers must be pre-checked and pre-primed
- before looking at settings in the event that priming would cross
- a bitstream boundary. So, do it now */
-
- ret=_ov_initset(vf1);
- if(ret)return(ret);
- ret=_ov_initprime(vf2);
- if(ret)return(ret);
-
- vi1=ov_info(vf1,-1);
- vi2=ov_info(vf2,-1);
- hs1=ov_halfrate_p(vf1);
- hs2=ov_halfrate_p(vf2);
-
- lappcm=(float**) alloca(sizeof(*lappcm)*vi1->channels);
- n1=vorbis_info_blocksize(vi1,0)>>(1+hs1);
- n2=vorbis_info_blocksize(vi2,0)>>(1+hs2);
- w1=vorbis_window(&vf1->vd,0);
- w2=vorbis_window(&vf2->vd,0);
-
- for(i=0;i<vi1->channels;i++)
- lappcm[i]=(float*) alloca(sizeof(**lappcm)*n1);
-
- _ov_getlap(vf1,vi1,&vf1->vd,lappcm,n1);
-
- /* have a lapping buffer from vf1; now to splice it into the lapping
- buffer of vf2 */
- /* consolidate and expose the buffer. */
- vorbis_synthesis_lapout(&vf2->vd,&pcm);
- _analysis_output_always("pcmL",0,pcm[0],n1*2,0,0,0);
- _analysis_output_always("pcmR",0,pcm[1],n1*2,0,0,0);
-
- /* splice */
- _ov_splice(pcm,lappcm,n1,n2,vi1->channels,vi2->channels,w1,w2);
-
- /* done */
- return(0);
- }
-
- static int _ov_64_seek_lap(OggVorbis_File *vf,ogg_int64_t pos,
- int (*localseek)(OggVorbis_File *,ogg_int64_t)){
- vorbis_info *vi;
- float **lappcm;
- float **pcm;
- float *w1,*w2;
- int n1,n2,ch1,ch2,hs;
- int i,ret;
-
- if(vf->ready_state<OPENED)return(OV_EINVAL);
- ret=_ov_initset(vf);
- if(ret)return(ret);
- vi=ov_info(vf,-1);
- hs=ov_halfrate_p(vf);
-
- ch1=vi->channels;
- n1=vorbis_info_blocksize(vi,0)>>(1+hs);
- w1=vorbis_window(&vf->vd,0); /* window arrays from libvorbis are
- persistent; even if the decode state
- from this link gets dumped, this
- window array continues to exist */
-
- lappcm=(float**) alloca(sizeof(*lappcm)*ch1);
- for(i=0;i<ch1;i++)
- lappcm[i]=(float*) alloca(sizeof(**lappcm)*n1);
- _ov_getlap(vf,vi,&vf->vd,lappcm,n1);
-
- /* have lapping data; seek and prime the buffer */
- ret=localseek(vf,pos);
- if(ret)return ret;
- ret=_ov_initprime(vf);
- if(ret)return(ret);
-
- /* Guard against cross-link changes; they're perfectly legal */
- vi=ov_info(vf,-1);
- ch2=vi->channels;
- n2=vorbis_info_blocksize(vi,0)>>(1+hs);
- w2=vorbis_window(&vf->vd,0);
-
- /* consolidate and expose the buffer. */
- vorbis_synthesis_lapout(&vf->vd,&pcm);
-
- /* splice */
- _ov_splice(pcm,lappcm,n1,n2,ch1,ch2,w1,w2);
-
- /* done */
- return(0);
- }
-
- int ov_raw_seek_lap(OggVorbis_File *vf,ogg_int64_t pos){
- return _ov_64_seek_lap(vf,pos,ov_raw_seek);
- }
-
- int ov_pcm_seek_lap(OggVorbis_File *vf,ogg_int64_t pos){
- return _ov_64_seek_lap(vf,pos,ov_pcm_seek);
- }
-
- int ov_pcm_seek_page_lap(OggVorbis_File *vf,ogg_int64_t pos){
- return _ov_64_seek_lap(vf,pos,ov_pcm_seek_page);
- }
-
- static int _ov_d_seek_lap(OggVorbis_File *vf,double pos,
- int (*localseek)(OggVorbis_File *,double)){
- vorbis_info *vi;
- float **lappcm;
- float **pcm;
- float *w1,*w2;
- int n1,n2,ch1,ch2,hs;
- int i,ret;
-
- if(vf->ready_state<OPENED)return(OV_EINVAL);
- ret=_ov_initset(vf);
- if(ret)return(ret);
- vi=ov_info(vf,-1);
- hs=ov_halfrate_p(vf);
-
- ch1=vi->channels;
- n1=vorbis_info_blocksize(vi,0)>>(1+hs);
- w1=vorbis_window(&vf->vd,0); /* window arrays from libvorbis are
- persistent; even if the decode state
- from this link gets dumped, this
- window array continues to exist */
-
- lappcm=(float**) alloca(sizeof(*lappcm)*ch1);
- for(i=0;i<ch1;i++)
- lappcm[i]=(float*) alloca(sizeof(**lappcm)*n1);
- _ov_getlap(vf,vi,&vf->vd,lappcm,n1);
-
- /* have lapping data; seek and prime the buffer */
- ret=localseek(vf,pos);
- if(ret)return ret;
- ret=_ov_initprime(vf);
- if(ret)return(ret);
-
- /* Guard against cross-link changes; they're perfectly legal */
- vi=ov_info(vf,-1);
- ch2=vi->channels;
- n2=vorbis_info_blocksize(vi,0)>>(1+hs);
- w2=vorbis_window(&vf->vd,0);
-
- /* consolidate and expose the buffer. */
- vorbis_synthesis_lapout(&vf->vd,&pcm);
-
- /* splice */
- _ov_splice(pcm,lappcm,n1,n2,ch1,ch2,w1,w2);
-
- /* done */
- return(0);
- }
-
- int ov_time_seek_lap(OggVorbis_File *vf,double pos){
- return _ov_d_seek_lap(vf,pos,ov_time_seek);
- }
-
- int ov_time_seek_page_lap(OggVorbis_File *vf,double pos){
- return _ov_d_seek_lap(vf,pos,ov_time_seek_page);
- }
-
- #endif
- /********* End of inlined file: vorbisfile.c *********/
-
- /********* Start of inlined file: window.c *********/
-
- /********* Start of inlined file: juce_OggVorbisHeader.h *********/
- // This file is included at the start of each Ogg-Vorbis .c file, just to do a few housekeeping
- // tasks..
-
- #ifdef _MSC_VER
- #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4305 4189 4706)
- #endif
- /********* End of inlined file: juce_OggVorbisHeader.h *********/
-
- #if JUCE_USE_OGGVORBIS
-
- #include <stdlib.h>
- #include <math.h>
-
- static float vwin64[32] = {
- 0.0009460463F, 0.0085006468F, 0.0235352254F, 0.0458950567F,
- 0.0753351908F, 0.1115073077F, 0.1539457973F, 0.2020557475F,
- 0.2551056759F, 0.3122276645F, 0.3724270287F, 0.4346027792F,
- 0.4975789974F, 0.5601459521F, 0.6211085051F, 0.6793382689F,
- 0.7338252629F, 0.7837245849F, 0.8283939355F, 0.8674186656F,
- 0.9006222429F, 0.9280614787F, 0.9500073081F, 0.9669131782F,
- 0.9793740220F, 0.9880792941F, 0.9937636139F, 0.9971582668F,
- 0.9989462667F, 0.9997230082F, 0.9999638688F, 0.9999995525F,
- };
-
- static float vwin128[64] = {
- 0.0002365472F, 0.0021280687F, 0.0059065254F, 0.0115626550F,
- 0.0190823442F, 0.0284463735F, 0.0396300935F, 0.0526030430F,
- 0.0673285281F, 0.0837631763F, 0.1018564887F, 0.1215504095F,
- 0.1427789367F, 0.1654677960F, 0.1895342001F, 0.2148867160F,
- 0.2414252576F, 0.2690412240F, 0.2976177952F, 0.3270303960F,
- 0.3571473350F, 0.3878306189F, 0.4189369387F, 0.4503188188F,
- 0.4818259135F, 0.5133064334F, 0.5446086751F, 0.5755826278F,
- 0.6060816248F, 0.6359640047F, 0.6650947483F, 0.6933470543F,
- 0.7206038179F, 0.7467589810F, 0.7717187213F, 0.7954024542F,
- 0.8177436264F, 0.8386902831F, 0.8582053981F, 0.8762669622F,
- 0.8928678298F, 0.9080153310F, 0.9217306608F, 0.9340480615F,
- 0.9450138200F, 0.9546851041F, 0.9631286621F, 0.9704194171F,
- 0.9766389810F, 0.9818741197F, 0.9862151938F, 0.9897546035F,
- 0.9925852598F, 0.9947991032F, 0.9964856900F, 0.9977308602F,
- 0.9986155015F, 0.9992144193F, 0.9995953200F, 0.9998179155F,
- 0.9999331503F, 0.9999825563F, 0.9999977357F, 0.9999999720F,
- };
-
- static float vwin256[128] = {
- 0.0000591390F, 0.0005321979F, 0.0014780301F, 0.0028960636F,
- 0.0047854363F, 0.0071449926F, 0.0099732775F, 0.0132685298F,
- 0.0170286741F, 0.0212513119F, 0.0259337111F, 0.0310727950F,
- 0.0366651302F, 0.0427069140F, 0.0491939614F, 0.0561216907F,
- 0.0634851102F, 0.0712788035F, 0.0794969160F, 0.0881331402F,
- 0.0971807028F, 0.1066323515F, 0.1164803426F, 0.1267164297F,
- 0.1373318534F, 0.1483173323F, 0.1596630553F, 0.1713586755F,
- 0.1833933062F, 0.1957555184F, 0.2084333404F, 0.2214142599F,
- 0.2346852280F, 0.2482326664F, 0.2620424757F, 0.2761000481F,
- 0.2903902813F, 0.3048975959F, 0.3196059553F, 0.3344988887F,
- 0.3495595160F, 0.3647705766F, 0.3801144597F, 0.3955732382F,
- 0.4111287047F, 0.4267624093F, 0.4424557009F, 0.4581897696F,
- 0.4739456913F, 0.4897044744F, 0.5054471075F, 0.5211546088F,
- 0.5368080763F, 0.5523887395F, 0.5678780103F, 0.5832575361F,
- 0.5985092508F, 0.6136154277F, 0.6285587300F, 0.6433222619F,
- 0.6578896175F, 0.6722449294F, 0.6863729144F, 0.7002589187F,
- 0.7138889597F, 0.7272497662F, 0.7403288154F, 0.7531143679F,
- 0.7655954985F, 0.7777621249F, 0.7896050322F, 0.8011158947F,
- 0.8122872932F, 0.8231127294F, 0.8335866365F, 0.8437043850F,
- 0.8534622861F, 0.8628575905F, 0.8718884835F, 0.8805540765F,
- 0.8888543947F, 0.8967903616F, 0.9043637797F, 0.9115773078F,
- 0.9184344360F, 0.9249394562F, 0.9310974312F, 0.9369141608F,
- 0.9423961446F, 0.9475505439F, 0.9523851406F, 0.9569082947F,
- 0.9611289005F, 0.9650563408F, 0.9687004405F, 0.9720714191F,
- 0.9751798427F, 0.9780365753F, 0.9806527301F, 0.9830396204F,
- 0.9852087111F, 0.9871715701F, 0.9889398207F, 0.9905250941F,
- 0.9919389832F, 0.9931929973F, 0.9942985174F, 0.9952667537F,
- 0.9961087037F, 0.9968351119F, 0.9974564312F, 0.9979827858F,
- 0.9984239359F, 0.9987892441F, 0.9990876435F, 0.9993276081F,
- 0.9995171241F, 0.9996636648F, 0.9997741654F, 0.9998550016F,
- 0.9999119692F, 0.9999502656F, 0.9999744742F, 0.9999885497F,
- 0.9999958064F, 0.9999989077F, 0.9999998584F, 0.9999999983F,
- };
-
- static float vwin512[256] = {
- 0.0000147849F, 0.0001330607F, 0.0003695946F, 0.0007243509F,
- 0.0011972759F, 0.0017882983F, 0.0024973285F, 0.0033242588F,
- 0.0042689632F, 0.0053312973F, 0.0065110982F, 0.0078081841F,
- 0.0092223540F, 0.0107533880F, 0.0124010466F, 0.0141650703F,
- 0.0160451800F, 0.0180410758F, 0.0201524373F, 0.0223789233F,
- 0.0247201710F, 0.0271757958F, 0.0297453914F, 0.0324285286F,
- 0.0352247556F, 0.0381335972F, 0.0411545545F, 0.0442871045F,
- 0.0475306997F, 0.0508847676F, 0.0543487103F, 0.0579219038F,
- 0.0616036982F, 0.0653934164F, 0.0692903546F, 0.0732937809F,
- 0.0774029356F, 0.0816170305F, 0.0859352485F, 0.0903567428F,
- 0.0948806375F, 0.0995060259F, 0.1042319712F, 0.1090575056F,
- 0.1139816300F, 0.1190033137F, 0.1241214941F, 0.1293350764F,
- 0.1346429333F, 0.1400439046F, 0.1455367974F, 0.1511203852F,
- 0.1567934083F, 0.1625545735F, 0.1684025537F, 0.1743359881F,
- 0.1803534820F, 0.1864536069F, 0.1926349000F, 0.1988958650F,
- 0.2052349715F, 0.2116506555F, 0.2181413191F, 0.2247053313F,
- 0.2313410275F, 0.2380467105F, 0.2448206500F, 0.2516610835F,
- 0.2585662164F, 0.2655342226F, 0.2725632448F, 0.2796513950F,
- 0.2867967551F, 0.2939973773F, 0.3012512852F, 0.3085564739F,
- 0.3159109111F, 0.3233125375F, 0.3307592680F, 0.3382489922F,
- 0.3457795756F, 0.3533488602F, 0.3609546657F, 0.3685947904F,
- 0.3762670121F, 0.3839690896F, 0.3916987634F, 0.3994537572F,
- 0.4072317788F, 0.4150305215F, 0.4228476653F, 0.4306808783F,
- 0.4385278181F, 0.4463861329F, 0.4542534630F, 0.4621274424F,
- 0.4700057001F, 0.4778858615F, 0.4857655502F, 0.4936423891F,
- 0.5015140023F, 0.5093780165F, 0.5172320626F, 0.5250737772F,
- 0.5329008043F, 0.5407107971F, 0.5485014192F, 0.5562703465F,
- 0.5640152688F, 0.5717338914F, 0.5794239366F, 0.5870831457F,
- 0.5947092801F, 0.6023001235F, 0.6098534829F, 0.6173671907F,
- 0.6248391059F, 0.6322671161F, 0.6396491384F, 0.6469831217F,
- 0.6542670475F, 0.6614989319F, 0.6686768267F, 0.6757988210F,
- 0.6828630426F, 0.6898676592F, 0.6968108799F, 0.7036909564F,
- 0.7105061843F, 0.7172549043F, 0.7239355032F, 0.7305464154F,
- 0.7370861235F, 0.7435531598F, 0.7499461068F, 0.7562635986F,
- 0.7625043214F, 0.7686670148F, 0.7747504721F, 0.7807535410F,
- 0.7866751247F, 0.7925141825F, 0.7982697296F, 0.8039408387F,
- 0.8095266395F, 0.8150263196F, 0.8204391248F, 0.8257643590F,
- 0.8310013848F, 0.8361496236F, 0.8412085555F, 0.8461777194F,
- 0.8510567129F, 0.8558451924F, 0.8605428730F, 0.8651495278F,
- 0.8696649882F, 0.8740891432F, 0.8784219392F, 0.8826633797F,
- 0.8868135244F, 0.8908724888F, 0.8948404441F, 0.8987176157F,
- 0.9025042831F, 0.9062007791F, 0.9098074886F, 0.9133248482F,
- 0.9167533451F, 0.9200935163F, 0.9233459472F, 0.9265112712F,
- 0.9295901680F, 0.9325833632F, 0.9354916263F, 0.9383157705F,
- 0.9410566504F, 0.9437151618F, 0.9462922398F, 0.9487888576F,
- 0.9512060252F, 0.9535447882F, 0.9558062262F, 0.9579914516F,
- 0.9601016078F, 0.9621378683F, 0.9641014348F, 0.9659935361F,
- 0.9678154261F, 0.9695683830F, 0.9712537071F, 0.9728727198F,
- 0.9744267618F, 0.9759171916F, 0.9773453842F, 0.9787127293F,
- 0.9800206298F, 0.9812705006F, 0.9824637665F, 0.9836018613F,
- 0.9846862258F, 0.9857183066F, 0.9866995544F, 0.9876314227F,
- 0.9885153662F, 0.9893528393F, 0.9901452948F, 0.9908941823F,
- 0.9916009470F, 0.9922670279F, 0.9928938570F, 0.9934828574F,
- 0.9940354423F, 0.9945530133F, 0.9950369595F, 0.9954886562F,
- 0.9959094633F, 0.9963007242F, 0.9966637649F, 0.9969998925F,
- 0.9973103939F, 0.9975965351F, 0.9978595598F, 0.9981006885F,
- 0.9983211172F, 0.9985220166F, 0.9987045311F, 0.9988697776F,
- 0.9990188449F, 0.9991527924F, 0.9992726499F, 0.9993794157F,
- 0.9994740570F, 0.9995575079F, 0.9996306699F, 0.9996944099F,
- 0.9997495605F, 0.9997969190F, 0.9998372465F, 0.9998712678F,
- 0.9998996704F, 0.9999231041F, 0.9999421807F, 0.9999574732F,
- 0.9999695157F, 0.9999788026F, 0.9999857885F, 0.9999908879F,
- 0.9999944746F, 0.9999968817F, 0.9999984010F, 0.9999992833F,
- 0.9999997377F, 0.9999999317F, 0.9999999911F, 0.9999999999F,
- };
-
- static float vwin1024[512] = {
- 0.0000036962F, 0.0000332659F, 0.0000924041F, 0.0001811086F,
- 0.0002993761F, 0.0004472021F, 0.0006245811F, 0.0008315063F,
- 0.0010679699F, 0.0013339631F, 0.0016294757F, 0.0019544965F,
- 0.0023090133F, 0.0026930125F, 0.0031064797F, 0.0035493989F,
- 0.0040217533F, 0.0045235250F, 0.0050546946F, 0.0056152418F,
- 0.0062051451F, 0.0068243817F, 0.0074729278F, 0.0081507582F,
- 0.0088578466F, 0.0095941655F, 0.0103596863F, 0.0111543789F,
- 0.0119782122F, 0.0128311538F, 0.0137131701F, 0.0146242260F,
- 0.0155642855F, 0.0165333111F, 0.0175312640F, 0.0185581042F,
- 0.0196137903F, 0.0206982797F, 0.0218115284F, 0.0229534910F,
- 0.0241241208F, 0.0253233698F, 0.0265511886F, 0.0278075263F,
- 0.0290923308F, 0.0304055484F, 0.0317471241F, 0.0331170013F,
- 0.0345151222F, 0.0359414274F, 0.0373958560F, 0.0388783456F,
- 0.0403888325F, 0.0419272511F, 0.0434935347F, 0.0450876148F,
- 0.0467094213F, 0.0483588828F, 0.0500359261F, 0.0517404765F,
- 0.0534724575F, 0.0552317913F, 0.0570183983F, 0.0588321971F,
- 0.0606731048F, 0.0625410369F, 0.0644359070F, 0.0663576272F,
- 0.0683061077F, 0.0702812571F, 0.0722829821F, 0.0743111878F,
- 0.0763657775F, 0.0784466526F, 0.0805537129F, 0.0826868561F,
- 0.0848459782F, 0.0870309736F, 0.0892417345F, 0.0914781514F,
- 0.0937401128F, 0.0960275056F, 0.0983402145F, 0.1006781223F,
- 0.1030411101F, 0.1054290568F, 0.1078418397F, 0.1102793336F,
- 0.1127414119F, 0.1152279457F, 0.1177388042F, 0.1202738544F,
- 0.1228329618F, 0.1254159892F, 0.1280227980F, 0.1306532471F,
- 0.1333071937F, 0.1359844927F, 0.1386849970F, 0.1414085575F,
- 0.1441550230F, 0.1469242403F, 0.1497160539F, 0.1525303063F,
- 0.1553668381F, 0.1582254875F, 0.1611060909F, 0.1640084822F,
- 0.1669324936F, 0.1698779549F, 0.1728446939F, 0.1758325362F,
- 0.1788413055F, 0.1818708232F, 0.1849209084F, 0.1879913785F,
- 0.1910820485F, 0.1941927312F, 0.1973232376F, 0.2004733764F,
- 0.2036429541F, 0.2068317752F, 0.2100396421F, 0.2132663552F,
- 0.2165117125F, 0.2197755102F, 0.2230575422F, 0.2263576007F,
- 0.2296754753F, 0.2330109540F, 0.2363638225F, 0.2397338646F,
- 0.2431208619F, 0.2465245941F, 0.2499448389F, 0.2533813719F,
- 0.2568339669F, 0.2603023956F, 0.2637864277F, 0.2672858312F,
- 0.2708003718F, 0.2743298135F, 0.2778739186F, 0.2814324472F,
- 0.2850051576F, 0.2885918065F, 0.2921921485F, 0.2958059366F,
- 0.2994329219F, 0.3030728538F, 0.3067254799F, 0.3103905462F,
- 0.3140677969F, 0.3177569747F, 0.3214578205F, 0.3251700736F,
- 0.3288934718F, 0.3326277513F, 0.3363726468F, 0.3401278914F,
- 0.3438932168F, 0.3476683533F, 0.3514530297F, 0.3552469734F,
- 0.3590499106F, 0.3628615659F, 0.3666816630F, 0.3705099239F,
- 0.3743460698F, 0.3781898204F, 0.3820408945F, 0.3858990095F,
- 0.3897638820F, 0.3936352274F, 0.3975127601F, 0.4013961936F,
- 0.4052852405F, 0.4091796123F, 0.4130790198F, 0.4169831732F,
- 0.4208917815F, 0.4248045534F, 0.4287211965F, 0.4326414181F,
- 0.4365649248F, 0.4404914225F, 0.4444206167F, 0.4483522125F,
- 0.4522859146F, 0.4562214270F, 0.4601584538F, 0.4640966984F,
- 0.4680358644F, 0.4719756548F, 0.4759157726F, 0.4798559209F,
- 0.4837958024F, 0.4877351199F, 0.4916735765F, 0.4956108751F,
- 0.4995467188F, 0.5034808109F, 0.5074128550F, 0.5113425550F,
- 0.5152696149F, 0.5191937395F, 0.5231146336F, 0.5270320028F,
- 0.5309455530F, 0.5348549910F, 0.5387600239F, 0.5426603597F,
- 0.5465557070F, 0.5504457754F, 0.5543302752F, 0.5582089175F,
- 0.5620814145F, 0.5659474793F, 0.5698068262F, 0.5736591704F,
- 0.5775042283F, 0.5813417176F, 0.5851713571F, 0.5889928670F,
- 0.5928059689F, 0.5966103856F, 0.6004058415F, 0.6041920626F,
- 0.6079687761F, 0.6117357113F, 0.6154925986F, 0.6192391705F,
- 0.6229751612F, 0.6267003064F, 0.6304143441F, 0.6341170137F,
- 0.6378080569F, 0.6414872173F, 0.6451542405F, 0.6488088741F,
- 0.6524508681F, 0.6560799742F, 0.6596959469F, 0.6632985424F,
- 0.6668875197F, 0.6704626398F, 0.6740236662F, 0.6775703649F,
- 0.6811025043F, 0.6846198554F, 0.6881221916F, 0.6916092892F,
- 0.6950809269F, 0.6985368861F, 0.7019769510F, 0.7054009085F,
- 0.7088085484F, 0.7121996632F, 0.7155740484F, 0.7189315023F,
- 0.7222718263F, 0.7255948245F, 0.7289003043F, 0.7321880760F,
- 0.7354579530F, 0.7387097518F, 0.7419432921F, 0.7451583966F,
- 0.7483548915F, 0.7515326059F, 0.7546913723F, 0.7578310265F,
- 0.7609514077F, 0.7640523581F, 0.7671337237F, 0.7701953535F,
- 0.7732371001F, 0.7762588195F, 0.7792603711F, 0.7822416178F,
- 0.7852024259F, 0.7881426654F, 0.7910622097F, 0.7939609356F,
- 0.7968387237F, 0.7996954579F, 0.8025310261F, 0.8053453193F,
- 0.8081382324F, 0.8109096638F, 0.8136595156F, 0.8163876936F,
- 0.8190941071F, 0.8217786690F, 0.8244412960F, 0.8270819086F,
- 0.8297004305F, 0.8322967896F, 0.8348709171F, 0.8374227481F,
- 0.8399522213F, 0.8424592789F, 0.8449438672F, 0.8474059356F,
- 0.8498454378F, 0.8522623306F, 0.8546565748F, 0.8570281348F,
- 0.8593769787F, 0.8617030779F, 0.8640064080F, 0.8662869477F,
- 0.8685446796F, 0.8707795899F, 0.8729916682F, 0.8751809079F,
- 0.8773473059F, 0.8794908626F, 0.8816115819F, 0.8837094713F,
- 0.8857845418F, 0.8878368079F, 0.8898662874F, 0.8918730019F,
- 0.8938569760F, 0.8958182380F, 0.8977568194F, 0.8996727552F,
- 0.9015660837F, 0.9034368465F, 0.9052850885F, 0.9071108577F,
- 0.9089142057F, 0.9106951869F, 0.9124538591F, 0.9141902832F,
- 0.9159045233F, 0.9175966464F, 0.9192667228F, 0.9209148257F,
- 0.9225410313F, 0.9241454187F, 0.9257280701F, 0.9272890704F,
- 0.9288285075F, 0.9303464720F, 0.9318430576F, 0.9333183603F,
- 0.9347724792F, 0.9362055158F, 0.9376175745F, 0.9390087622F,
- 0.9403791881F, 0.9417289644F, 0.9430582055F, 0.9443670283F,
- 0.9456555521F, 0.9469238986F, 0.9481721917F, 0.9494005577F,
- 0.9506091252F, 0.9517980248F, 0.9529673894F, 0.9541173540F,
- 0.9552480557F, 0.9563596334F, 0.9574522282F, 0.9585259830F,
- 0.9595810428F, 0.9606175542F, 0.9616356656F, 0.9626355274F,
- 0.9636172915F, 0.9645811114F, 0.9655271425F, 0.9664555414F,
- 0.9673664664F, 0.9682600774F, 0.9691365355F, 0.9699960034F,
- 0.9708386448F, 0.9716646250F, 0.9724741103F, 0.9732672685F,
- 0.9740442683F, 0.9748052795F, 0.9755504729F, 0.9762800205F,
- 0.9769940950F, 0.9776928703F, 0.9783765210F, 0.9790452223F,
- 0.9796991504F, 0.9803384823F, 0.9809633954F, 0.9815740679F,
- 0.9821706784F, 0.9827534063F, 0.9833224312F, 0.9838779332F,
- 0.9844200928F, 0.9849490910F, 0.9854651087F, 0.9859683274F,
- 0.9864589286F, 0.9869370940F, 0.9874030054F, 0.9878568447F,
- 0.9882987937F, 0.9887290343F, 0.9891477481F, 0.9895551169F,
- 0.9899513220F, 0.9903365446F, 0.9907109658F, 0.9910747662F,
- 0.9914281260F, 0.9917712252F, 0.9921042433F, 0.9924273593F,
- 0.9927407516F, 0.9930445982F, 0.9933390763F, 0.9936243626F,
- 0.9939006331F, 0.9941680631F, 0.9944268269F, 0.9946770982F,
- 0.9949190498F, 0.9951528537F, 0.9953786808F, 0.9955967011F,
- 0.9958070836F, 0.9960099963F, 0.9962056061F, 0.9963940787F,
- 0.9965755786F, 0.9967502693F, 0.9969183129F, 0.9970798704F,
- 0.9972351013F, 0.9973841640F, 0.9975272151F, 0.9976644103F,
- 0.9977959036F, 0.9979218476F, 0.9980423932F, 0.9981576901F,
- 0.9982678862F, 0.9983731278F, 0.9984735596F, 0.9985693247F,
- 0.9986605645F, 0.9987474186F, 0.9988300248F, 0.9989085193F,
- 0.9989830364F, 0.9990537085F, 0.9991206662F, 0.9991840382F,
- 0.9992439513F, 0.9993005303F, 0.9993538982F, 0.9994041757F,
- 0.9994514817F, 0.9994959330F, 0.9995376444F, 0.9995767286F,
- 0.9996132960F, 0.9996474550F, 0.9996793121F, 0.9997089710F,
- 0.9997365339F, 0.9997621003F, 0.9997857677F, 0.9998076311F,
- 0.9998277836F, 0.9998463156F, 0.9998633155F, 0.9998788692F,
- 0.9998930603F, 0.9999059701F, 0.9999176774F, 0.9999282586F,
- 0.9999377880F, 0.9999463370F, 0.9999539749F, 0.9999607685F,
- 0.9999667820F, 0.9999720773F, 0.9999767136F, 0.9999807479F,
- 0.9999842344F, 0.9999872249F, 0.9999897688F, 0.9999919127F,
- 0.9999937009F, 0.9999951749F, 0.9999963738F, 0.9999973342F,
- 0.9999980900F, 0.9999986724F, 0.9999991103F, 0.9999994297F,
- 0.9999996543F, 0.9999998049F, 0.9999999000F, 0.9999999552F,
- 0.9999999836F, 0.9999999957F, 0.9999999994F, 1.0000000000F,
- };
-
- static float vwin2048[1024] = {
- 0.0000009241F, 0.0000083165F, 0.0000231014F, 0.0000452785F,
- 0.0000748476F, 0.0001118085F, 0.0001561608F, 0.0002079041F,
- 0.0002670379F, 0.0003335617F, 0.0004074748F, 0.0004887765F,
- 0.0005774661F, 0.0006735427F, 0.0007770054F, 0.0008878533F,
- 0.0010060853F, 0.0011317002F, 0.0012646969F, 0.0014050742F,
- 0.0015528307F, 0.0017079650F, 0.0018704756F, 0.0020403610F,
- 0.0022176196F, 0.0024022497F, 0.0025942495F, 0.0027936173F,
- 0.0030003511F, 0.0032144490F, 0.0034359088F, 0.0036647286F,
- 0.0039009061F, 0.0041444391F, 0.0043953253F, 0.0046535621F,
- 0.0049191472F, 0.0051920781F, 0.0054723520F, 0.0057599664F,
- 0.0060549184F, 0.0063572052F, 0.0066668239F, 0.0069837715F,
- 0.0073080449F, 0.0076396410F, 0.0079785566F, 0.0083247884F,
- 0.0086783330F, 0.0090391871F, 0.0094073470F, 0.0097828092F,
- 0.0101655700F, 0.0105556258F, 0.0109529726F, 0.0113576065F,
- 0.0117695237F, 0.0121887200F, 0.0126151913F, 0.0130489335F,
- 0.0134899422F, 0.0139382130F, 0.0143937415F, 0.0148565233F,
- 0.0153265536F, 0.0158038279F, 0.0162883413F, 0.0167800889F,
- 0.0172790660F, 0.0177852675F, 0.0182986882F, 0.0188193231F,
- 0.0193471668F, 0.0198822141F, 0.0204244594F, 0.0209738974F,
- 0.0215305225F, 0.0220943289F, 0.0226653109F, 0.0232434627F,
- 0.0238287784F, 0.0244212519F, 0.0250208772F, 0.0256276481F,
- 0.0262415582F, 0.0268626014F, 0.0274907711F, 0.0281260608F,
- 0.0287684638F, 0.0294179736F, 0.0300745833F, 0.0307382859F,
- 0.0314090747F, 0.0320869424F, 0.0327718819F, 0.0334638860F,
- 0.0341629474F, 0.0348690586F, 0.0355822122F, 0.0363024004F,
- 0.0370296157F, 0.0377638502F, 0.0385050960F, 0.0392533451F,
- 0.0400085896F, 0.0407708211F, 0.0415400315F, 0.0423162123F,
- 0.0430993552F, 0.0438894515F, 0.0446864926F, 0.0454904698F,
- 0.0463013742F, 0.0471191969F, 0.0479439288F, 0.0487755607F,
- 0.0496140836F, 0.0504594879F, 0.0513117642F, 0.0521709031F,
- 0.0530368949F, 0.0539097297F, 0.0547893979F, 0.0556758894F,
- 0.0565691941F, 0.0574693019F, 0.0583762026F, 0.0592898858F,
- 0.0602103410F, 0.0611375576F, 0.0620715250F, 0.0630122324F,
- 0.0639596688F, 0.0649138234F, 0.0658746848F, 0.0668422421F,
- 0.0678164838F, 0.0687973985F, 0.0697849746F, 0.0707792005F,
- 0.0717800645F, 0.0727875547F, 0.0738016591F, 0.0748223656F,
- 0.0758496620F, 0.0768835359F, 0.0779239751F, 0.0789709668F,
- 0.0800244985F, 0.0810845574F, 0.0821511306F, 0.0832242052F,
- 0.0843037679F, 0.0853898056F, 0.0864823050F, 0.0875812525F,
- 0.0886866347F, 0.0897984378F, 0.0909166480F, 0.0920412513F,
- 0.0931722338F, 0.0943095813F, 0.0954532795F, 0.0966033140F,
- 0.0977596702F, 0.0989223336F, 0.1000912894F, 0.1012665227F,
- 0.1024480185F, 0.1036357616F, 0.1048297369F, 0.1060299290F,
- 0.1072363224F, 0.1084489014F, 0.1096676504F, 0.1108925534F,
- 0.1121235946F, 0.1133607577F, 0.1146040267F, 0.1158533850F,
- 0.1171088163F, 0.1183703040F, 0.1196378312F, 0.1209113812F,
- 0.1221909370F, 0.1234764815F, 0.1247679974F, 0.1260654674F,
- 0.1273688740F, 0.1286781995F, 0.1299934263F, 0.1313145365F,
- 0.1326415121F, 0.1339743349F, 0.1353129866F, 0.1366574490F,
- 0.1380077035F, 0.1393637315F, 0.1407255141F, 0.1420930325F,
- 0.1434662677F, 0.1448452004F, 0.1462298115F, 0.1476200814F,
- 0.1490159906F, 0.1504175195F, 0.1518246482F, 0.1532373569F,
- 0.1546556253F, 0.1560794333F, 0.1575087606F, 0.1589435866F,
- 0.1603838909F, 0.1618296526F, 0.1632808509F, 0.1647374648F,
- 0.1661994731F, 0.1676668546F, 0.1691395880F, 0.1706176516F,
- 0.1721010238F, 0.1735896829F, 0.1750836068F, 0.1765827736F,
- 0.1780871610F, 0.1795967468F, 0.1811115084F, 0.1826314234F,
- 0.1841564689F, 0.1856866221F, 0.1872218600F, 0.1887621595F,
- 0.1903074974F, 0.1918578503F, 0.1934131947F, 0.1949735068F,
- 0.1965387630F, 0.1981089393F, 0.1996840117F, 0.2012639560F,
- 0.2028487479F, 0.2044383630F, 0.2060327766F, 0.2076319642F,
- 0.2092359007F, 0.2108445614F, 0.2124579211F, 0.2140759545F,
- 0.2156986364F, 0.2173259411F, 0.2189578432F, 0.2205943168F,
- 0.2222353361F, 0.2238808751F, 0.2255309076F, 0.2271854073F,
- 0.2288443480F, 0.2305077030F, 0.2321754457F, 0.2338475493F,
- 0.2355239869F, 0.2372047315F, 0.2388897560F, 0.2405790329F,
- 0.2422725350F, 0.2439702347F, 0.2456721043F, 0.2473781159F,
- 0.2490882418F, 0.2508024539F, 0.2525207240F, 0.2542430237F,
- 0.2559693248F, 0.2576995986F, 0.2594338166F, 0.2611719498F,
- 0.2629139695F, 0.2646598466F, 0.2664095520F, 0.2681630564F,
- 0.2699203304F, 0.2716813445F, 0.2734460691F, 0.2752144744F,
- 0.2769865307F, 0.2787622079F, 0.2805414760F, 0.2823243047F,
- 0.2841106637F, 0.2859005227F, 0.2876938509F, 0.2894906179F,
- 0.2912907928F, 0.2930943447F, 0.2949012426F, 0.2967114554F,
- 0.2985249520F, 0.3003417009F, 0.3021616708F, 0.3039848301F,
- 0.3058111471F, 0.3076405901F, 0.3094731273F, 0.3113087266F,
- 0.3131473560F, 0.3149889833F, 0.3168335762F, 0.3186811024F,
- 0.3205315294F, 0.3223848245F, 0.3242409552F, 0.3260998886F,
- 0.3279615918F, 0.3298260319F, 0.3316931758F, 0.3335629903F,
- 0.3354354423F, 0.3373104982F, 0.3391881247F, 0.3410682882F,
- 0.3429509551F, 0.3448360917F, 0.3467236642F, 0.3486136387F,
- 0.3505059811F, 0.3524006575F, 0.3542976336F, 0.3561968753F,
- 0.3580983482F, 0.3600020179F, 0.3619078499F, 0.3638158096F,
- 0.3657258625F, 0.3676379737F, 0.3695521086F, 0.3714682321F,
- 0.3733863094F, 0.3753063055F, 0.3772281852F, 0.3791519134F,
- 0.3810774548F, 0.3830047742F, 0.3849338362F, 0.3868646053F,
- 0.3887970459F, 0.3907311227F, 0.3926667998F, 0.3946040417F,
- 0.3965428125F, 0.3984830765F, 0.4004247978F, 0.4023679403F,
- 0.4043124683F, 0.4062583455F, 0.4082055359F, 0.4101540034F,
- 0.4121037117F, 0.4140546246F, 0.4160067058F, 0.4179599190F,
- 0.4199142277F, 0.4218695956F, 0.4238259861F, 0.4257833627F,
- 0.4277416888F, 0.4297009279F, 0.4316610433F, 0.4336219983F,
- 0.4355837562F, 0.4375462803F, 0.4395095337F, 0.4414734797F,
- 0.4434380815F, 0.4454033021F, 0.4473691046F, 0.4493354521F,
- 0.4513023078F, 0.4532696345F, 0.4552373954F, 0.4572055533F,
- 0.4591740713F, 0.4611429123F, 0.4631120393F, 0.4650814151F,
- 0.4670510028F, 0.4690207650F, 0.4709906649F, 0.4729606651F,
- 0.4749307287F, 0.4769008185F, 0.4788708972F, 0.4808409279F,
- 0.4828108732F, 0.4847806962F, 0.4867503597F, 0.4887198264F,
- 0.4906890593F, 0.4926580213F, 0.4946266753F, 0.4965949840F,
- 0.4985629105F, 0.5005304176F, 0.5024974683F, 0.5044640255F,
- 0.5064300522F, 0.5083955114F, 0.5103603659F, 0.5123245790F,
- 0.5142881136F, 0.5162509328F, 0.5182129997F, 0.5201742774F,
- 0.5221347290F, 0.5240943178F, 0.5260530070F, 0.5280107598F,
- 0.5299675395F, 0.5319233095F, 0.5338780330F, 0.5358316736F,
- 0.5377841946F, 0.5397355596F, 0.5416857320F, 0.5436346755F,
- 0.5455823538F, 0.5475287304F, 0.5494737691F, 0.5514174337F,
- 0.5533596881F, 0.5553004962F, 0.5572398218F, 0.5591776291F,
- 0.5611138821F, 0.5630485449F, 0.5649815818F, 0.5669129570F,
- 0.5688426349F, 0.5707705799F, 0.5726967564F, 0.5746211290F,
- 0.5765436624F, 0.5784643212F, 0.5803830702F, 0.5822998743F,
- 0.5842146984F, 0.5861275076F, 0.5880382669F, 0.5899469416F,
- 0.5918534968F, 0.5937578981F, 0.5956601107F, 0.5975601004F,
- 0.5994578326F, 0.6013532732F, 0.6032463880F, 0.6051371429F,
- 0.6070255039F, 0.6089114372F, 0.6107949090F, 0.6126758856F,
- 0.6145543334F, 0.6164302191F, 0.6183035092F, 0.6201741706F,
- 0.6220421700F, 0.6239074745F, 0.6257700513F, 0.6276298674F,
- 0.6294868903F, 0.6313410873F, 0.6331924262F, 0.6350408745F,
- 0.6368864001F, 0.6387289710F, 0.6405685552F, 0.6424051209F,
- 0.6442386364F, 0.6460690702F, 0.6478963910F, 0.6497205673F,
- 0.6515415682F, 0.6533593625F, 0.6551739194F, 0.6569852082F,
- 0.6587931984F, 0.6605978593F, 0.6623991609F, 0.6641970728F,
- 0.6659915652F, 0.6677826081F, 0.6695701718F, 0.6713542268F,
- 0.6731347437F, 0.6749116932F, 0.6766850461F, 0.6784547736F,
- 0.6802208469F, 0.6819832374F, 0.6837419164F, 0.6854968559F,
- 0.6872480275F, 0.6889954034F, 0.6907389556F, 0.6924786566F,
- 0.6942144788F, 0.6959463950F, 0.6976743780F, 0.6993984008F,
- 0.7011184365F, 0.7028344587F, 0.7045464407F, 0.7062543564F,
- 0.7079581796F, 0.7096578844F, 0.7113534450F, 0.7130448359F,
- 0.7147320316F, 0.7164150070F, 0.7180937371F, 0.7197681970F,
- 0.7214383620F, 0.7231042077F, 0.7247657098F, 0.7264228443F,
- 0.7280755871F, 0.7297239147F, 0.7313678035F, 0.7330072301F,
- 0.7346421715F, 0.7362726046F, 0.7378985069F, 0.7395198556F,
- 0.7411366285F, 0.7427488034F, 0.7443563584F, 0.7459592717F,
- 0.7475575218F, 0.7491510873F, 0.7507399471F, 0.7523240803F,
- 0.7539034661F, 0.7554780839F, 0.7570479136F, 0.7586129349F,
- 0.7601731279F, 0.7617284730F, 0.7632789506F, 0.7648245416F,
- 0.7663652267F, 0.7679009872F, 0.7694318044F, 0.7709576599F,
- 0.7724785354F, 0.7739944130F, 0.7755052749F, 0.7770111035F,
- 0.7785118815F, 0.7800075916F, 0.7814982170F, 0.7829837410F,
- 0.7844641472F, 0.7859394191F, 0.7874095408F, 0.7888744965F,
- 0.7903342706F, 0.7917888476F, 0.7932382124F, 0.7946823501F,
- 0.7961212460F, 0.7975548855F, 0.7989832544F, 0.8004063386F,
- 0.8018241244F, 0.8032365981F, 0.8046437463F, 0.8060455560F,
- 0.8074420141F, 0.8088331080F, 0.8102188253F, 0.8115991536F,
- 0.8129740810F, 0.8143435957F, 0.8157076861F, 0.8170663409F,
- 0.8184195489F, 0.8197672994F, 0.8211095817F, 0.8224463853F,
- 0.8237777001F, 0.8251035161F, 0.8264238235F, 0.8277386129F,
- 0.8290478750F, 0.8303516008F, 0.8316497814F, 0.8329424083F,
- 0.8342294731F, 0.8355109677F, 0.8367868841F, 0.8380572148F,
- 0.8393219523F, 0.8405810893F, 0.8418346190F, 0.8430825345F,
- 0.8443248294F, 0.8455614974F, 0.8467925323F, 0.8480179285F,
- 0.8492376802F, 0.8504517822F, 0.8516602292F, 0.8528630164F,
- 0.8540601391F, 0.8552515928F, 0.8564373733F, 0.8576174766F,
- 0.8587918990F, 0.8599606368F, 0.8611236868F, 0.8622810460F,
- 0.8634327113F, 0.8645786802F, 0.8657189504F, 0.8668535195F,
- 0.8679823857F, 0.8691055472F, 0.8702230025F, 0.8713347503F,
- 0.8724407896F, 0.8735411194F, 0.8746357394F, 0.8757246489F,
- 0.8768078479F, 0.8778853364F, 0.8789571146F, 0.8800231832F,
- 0.8810835427F, 0.8821381942F, 0.8831871387F, 0.8842303777F,
- 0.8852679127F, 0.8862997456F, 0.8873258784F, 0.8883463132F,
- 0.8893610527F, 0.8903700994F, 0.8913734562F, 0.8923711263F,
- 0.8933631129F, 0.8943494196F, 0.8953300500F, 0.8963050083F,
- 0.8972742985F, 0.8982379249F, 0.8991958922F, 0.9001482052F,
- 0.9010948688F, 0.9020358883F, 0.9029712690F, 0.9039010165F,
- 0.9048251367F, 0.9057436357F, 0.9066565195F, 0.9075637946F,
- 0.9084654678F, 0.9093615456F, 0.9102520353F, 0.9111369440F,
- 0.9120162792F, 0.9128900484F, 0.9137582595F, 0.9146209204F,
- 0.9154780394F, 0.9163296248F, 0.9171756853F, 0.9180162296F,
- 0.9188512667F, 0.9196808057F, 0.9205048559F, 0.9213234270F,
- 0.9221365285F, 0.9229441704F, 0.9237463629F, 0.9245431160F,
- 0.9253344404F, 0.9261203465F, 0.9269008453F, 0.9276759477F,
- 0.9284456648F, 0.9292100080F, 0.9299689889F, 0.9307226190F,
- 0.9314709103F, 0.9322138747F, 0.9329515245F, 0.9336838721F,
- 0.9344109300F, 0.9351327108F, 0.9358492275F, 0.9365604931F,
- 0.9372665208F, 0.9379673239F, 0.9386629160F, 0.9393533107F,
- 0.9400385220F, 0.9407185637F, 0.9413934501F, 0.9420631954F,
- 0.9427278141F, 0.9433873208F, 0.9440417304F, 0.9446910576F,
- 0.9453353176F, 0.9459745255F, 0.9466086968F, 0.9472378469F,
- 0.9478619915F, 0.9484811463F, 0.9490953274F, 0.9497045506F,
- 0.9503088323F, 0.9509081888F, 0.9515026365F, 0.9520921921F,
- 0.9526768723F, 0.9532566940F, 0.9538316742F, 0.9544018300F,
- 0.9549671786F, 0.9555277375F, 0.9560835241F, 0.9566345562F,
- 0.9571808513F, 0.9577224275F, 0.9582593027F, 0.9587914949F,
- 0.9593190225F, 0.9598419038F, 0.9603601571F, 0.9608738012F,
- 0.9613828546F, 0.9618873361F, 0.9623872646F, 0.9628826591F,
- 0.9633735388F, 0.9638599227F, 0.9643418303F, 0.9648192808F,
- 0.9652922939F, 0.9657608890F, 0.9662250860F, 0.9666849046F,
- 0.9671403646F, 0.9675914861F, 0.9680382891F, 0.9684807937F,
- 0.9689190202F, 0.9693529890F, 0.9697827203F, 0.9702082347F,
- 0.9706295529F, 0.9710466953F, 0.9714596828F, 0.9718685362F,
- 0.9722732762F, 0.9726739240F, 0.9730705005F, 0.9734630267F,
- 0.9738515239F, 0.9742360134F, 0.9746165163F, 0.9749930540F,
- 0.9753656481F, 0.9757343198F, 0.9760990909F, 0.9764599829F,
- 0.9768170175F, 0.9771702164F, 0.9775196013F, 0.9778651941F,
- 0.9782070167F, 0.9785450909F, 0.9788794388F, 0.9792100824F,
- 0.9795370437F, 0.9798603449F, 0.9801800080F, 0.9804960554F,
- 0.9808085092F, 0.9811173916F, 0.9814227251F, 0.9817245318F,
- 0.9820228343F, 0.9823176549F, 0.9826090160F, 0.9828969402F,
- 0.9831814498F, 0.9834625674F, 0.9837403156F, 0.9840147169F,
- 0.9842857939F, 0.9845535692F, 0.9848180654F, 0.9850793052F,
- 0.9853373113F, 0.9855921062F, 0.9858437127F, 0.9860921535F,
- 0.9863374512F, 0.9865796287F, 0.9868187085F, 0.9870547136F,
- 0.9872876664F, 0.9875175899F, 0.9877445067F, 0.9879684396F,
- 0.9881894112F, 0.9884074444F, 0.9886225619F, 0.9888347863F,
- 0.9890441404F, 0.9892506468F, 0.9894543284F, 0.9896552077F,
- 0.9898533074F, 0.9900486502F, 0.9902412587F, 0.9904311555F,
- 0.9906183633F, 0.9908029045F, 0.9909848019F, 0.9911640779F,
- 0.9913407550F, 0.9915148557F, 0.9916864025F, 0.9918554179F,
- 0.9920219241F, 0.9921859437F, 0.9923474989F, 0.9925066120F,
- 0.9926633054F, 0.9928176012F, 0.9929695218F, 0.9931190891F,
- 0.9932663254F, 0.9934112527F, 0.9935538932F, 0.9936942686F,
- 0.9938324012F, 0.9939683126F, 0.9941020248F, 0.9942335597F,
- 0.9943629388F, 0.9944901841F, 0.9946153170F, 0.9947383593F,
- 0.9948593325F, 0.9949782579F, 0.9950951572F, 0.9952100516F,
- 0.9953229625F, 0.9954339111F, 0.9955429186F, 0.9956500062F,
- 0.9957551948F, 0.9958585056F, 0.9959599593F, 0.9960595769F,
- 0.9961573792F, 0.9962533869F, 0.9963476206F, 0.9964401009F,
- 0.9965308483F, 0.9966198833F, 0.9967072261F, 0.9967928971F,
- 0.9968769164F, 0.9969593041F, 0.9970400804F, 0.9971192651F,
- 0.9971968781F, 0.9972729391F, 0.9973474680F, 0.9974204842F,
- 0.9974920074F, 0.9975620569F, 0.9976306521F, 0.9976978122F,
- 0.9977635565F, 0.9978279039F, 0.9978908736F, 0.9979524842F,
- 0.9980127547F, 0.9980717037F, 0.9981293499F, 0.9981857116F,
- 0.9982408073F, 0.9982946554F, 0.9983472739F, 0.9983986810F,
- 0.9984488947F, 0.9984979328F, 0.9985458132F, 0.9985925534F,
- 0.9986381711F, 0.9986826838F, 0.9987261086F, 0.9987684630F,
- 0.9988097640F, 0.9988500286F, 0.9988892738F, 0.9989275163F,
- 0.9989647727F, 0.9990010597F, 0.9990363938F, 0.9990707911F,
- 0.9991042679F, 0.9991368404F, 0.9991685244F, 0.9991993358F,
- 0.9992292905F, 0.9992584038F, 0.9992866914F, 0.9993141686F,
- 0.9993408506F, 0.9993667526F, 0.9993918895F, 0.9994162761F,
- 0.9994399273F, 0.9994628576F, 0.9994850815F, 0.9995066133F,
- 0.9995274672F, 0.9995476574F, 0.9995671978F, 0.9995861021F,
- 0.9996043841F, 0.9996220573F, 0.9996391352F, 0.9996556310F,
- 0.9996715579F, 0.9996869288F, 0.9997017568F, 0.9997160543F,
- 0.9997298342F, 0.9997431088F, 0.9997558905F, 0.9997681914F,
- 0.9997800236F, 0.9997913990F, 0.9998023292F, 0.9998128261F,
- 0.9998229009F, 0.9998325650F, 0.9998418296F, 0.9998507058F,
- 0.9998592044F, 0.9998673362F, 0.9998751117F, 0.9998825415F,
- 0.9998896358F, 0.9998964047F, 0.9999028584F, 0.9999090066F,
- 0.9999148590F, 0.9999204253F, 0.9999257148F, 0.9999307368F,
- 0.9999355003F, 0.9999400144F, 0.9999442878F, 0.9999483293F,
- 0.9999521472F, 0.9999557499F, 0.9999591457F, 0.9999623426F,
- 0.9999653483F, 0.9999681708F, 0.9999708175F, 0.9999732959F,
- 0.9999756132F, 0.9999777765F, 0.9999797928F, 0.9999816688F,
- 0.9999834113F, 0.9999850266F, 0.9999865211F, 0.9999879009F,
- 0.9999891721F, 0.9999903405F, 0.9999914118F, 0.9999923914F,
- 0.9999932849F, 0.9999940972F, 0.9999948336F, 0.9999954989F,
- 0.9999960978F, 0.9999966349F, 0.9999971146F, 0.9999975411F,
- 0.9999979185F, 0.9999982507F, 0.9999985414F, 0.9999987944F,
- 0.9999990129F, 0.9999992003F, 0.9999993596F, 0.9999994939F,
- 0.9999996059F, 0.9999996981F, 0.9999997732F, 0.9999998333F,
- 0.9999998805F, 0.9999999170F, 0.9999999444F, 0.9999999643F,
- 0.9999999784F, 0.9999999878F, 0.9999999937F, 0.9999999972F,
- 0.9999999990F, 0.9999999997F, 1.0000000000F, 1.0000000000F,
- };
-
- static float vwin4096[2048] = {
- 0.0000002310F, 0.0000020791F, 0.0000057754F, 0.0000113197F,
- 0.0000187121F, 0.0000279526F, 0.0000390412F, 0.0000519777F,
- 0.0000667623F, 0.0000833949F, 0.0001018753F, 0.0001222036F,
- 0.0001443798F, 0.0001684037F, 0.0001942754F, 0.0002219947F,
- 0.0002515616F, 0.0002829761F, 0.0003162380F, 0.0003513472F,
- 0.0003883038F, 0.0004271076F, 0.0004677584F, 0.0005102563F,
- 0.0005546011F, 0.0006007928F, 0.0006488311F, 0.0006987160F,
- 0.0007504474F, 0.0008040251F, 0.0008594490F, 0.0009167191F,
- 0.0009758351F, 0.0010367969F, 0.0010996044F, 0.0011642574F,
- 0.0012307558F, 0.0012990994F, 0.0013692880F, 0.0014413216F,
- 0.0015151998F, 0.0015909226F, 0.0016684898F, 0.0017479011F,
- 0.0018291565F, 0.0019122556F, 0.0019971983F, 0.0020839845F,
- 0.0021726138F, 0.0022630861F, 0.0023554012F, 0.0024495588F,
- 0.0025455588F, 0.0026434008F, 0.0027430847F, 0.0028446103F,
- 0.0029479772F, 0.0030531853F, 0.0031602342F, 0.0032691238F,
- 0.0033798538F, 0.0034924239F, 0.0036068338F, 0.0037230833F,
- 0.0038411721F, 0.0039610999F, 0.0040828664F, 0.0042064714F,
- 0.0043319145F, 0.0044591954F, 0.0045883139F, 0.0047192696F,
- 0.0048520622F, 0.0049866914F, 0.0051231569F, 0.0052614583F,
- 0.0054015953F, 0.0055435676F, 0.0056873748F, 0.0058330166F,
- 0.0059804926F, 0.0061298026F, 0.0062809460F, 0.0064339226F,
- 0.0065887320F, 0.0067453738F, 0.0069038476F, 0.0070641531F,
- 0.0072262899F, 0.0073902575F, 0.0075560556F, 0.0077236838F,
- 0.0078931417F, 0.0080644288F, 0.0082375447F, 0.0084124891F,
- 0.0085892615F, 0.0087678614F, 0.0089482885F, 0.0091305422F,
- 0.0093146223F, 0.0095005281F, 0.0096882592F, 0.0098778153F,
- 0.0100691958F, 0.0102624002F, 0.0104574281F, 0.0106542791F,
- 0.0108529525F, 0.0110534480F, 0.0112557651F, 0.0114599032F,
- 0.0116658618F, 0.0118736405F, 0.0120832387F, 0.0122946560F,
- 0.0125078917F, 0.0127229454F, 0.0129398166F, 0.0131585046F,
- 0.0133790090F, 0.0136013292F, 0.0138254647F, 0.0140514149F,
- 0.0142791792F, 0.0145087572F, 0.0147401481F, 0.0149733515F,
- 0.0152083667F, 0.0154451932F, 0.0156838304F, 0.0159242777F,
- 0.0161665345F, 0.0164106001F, 0.0166564741F, 0.0169041557F,
- 0.0171536443F, 0.0174049393F, 0.0176580401F, 0.0179129461F,
- 0.0181696565F, 0.0184281708F, 0.0186884883F, 0.0189506084F,
- 0.0192145303F, 0.0194802535F, 0.0197477772F, 0.0200171008F,
- 0.0202882236F, 0.0205611449F, 0.0208358639F, 0.0211123801F,
- 0.0213906927F, 0.0216708011F, 0.0219527043F, 0.0222364019F,
- 0.0225218930F, 0.0228091769F, 0.0230982529F, 0.0233891203F,
- 0.0236817782F, 0.0239762259F, 0.0242724628F, 0.0245704880F,
- 0.0248703007F, 0.0251719002F, 0.0254752858F, 0.0257804565F,
- 0.0260874117F, 0.0263961506F, 0.0267066722F, 0.0270189760F,
- 0.0273330609F, 0.0276489263F, 0.0279665712F, 0.0282859949F,
- 0.0286071966F, 0.0289301753F, 0.0292549303F, 0.0295814607F,
- 0.0299097656F, 0.0302398442F, 0.0305716957F, 0.0309053191F,
- 0.0312407135F, 0.0315778782F, 0.0319168122F, 0.0322575145F,
- 0.0325999844F, 0.0329442209F, 0.0332902231F, 0.0336379900F,
- 0.0339875208F, 0.0343388146F, 0.0346918703F, 0.0350466871F,
- 0.0354032640F, 0.0357616000F, 0.0361216943F, 0.0364835458F,
- 0.0368471535F, 0.0372125166F, 0.0375796339F, 0.0379485046F,
- 0.0383191276F, 0.0386915020F, 0.0390656267F, 0.0394415008F,
- 0.0398191231F, 0.0401984927F, 0.0405796086F, 0.0409624698F,
- 0.0413470751F, 0.0417334235F, 0.0421215141F, 0.0425113457F,
- 0.0429029172F, 0.0432962277F, 0.0436912760F, 0.0440880610F,
- 0.0444865817F, 0.0448868370F, 0.0452888257F, 0.0456925468F,
- 0.0460979992F, 0.0465051816F, 0.0469140931F, 0.0473247325F,
- 0.0477370986F, 0.0481511902F, 0.0485670064F, 0.0489845458F,
- 0.0494038074F, 0.0498247899F, 0.0502474922F, 0.0506719131F,
- 0.0510980514F, 0.0515259060F, 0.0519554756F, 0.0523867590F,
- 0.0528197550F, 0.0532544624F, 0.0536908800F, 0.0541290066F,
- 0.0545688408F, 0.0550103815F, 0.0554536274F, 0.0558985772F,
- 0.0563452297F, 0.0567935837F, 0.0572436377F, 0.0576953907F,
- 0.0581488412F, 0.0586039880F, 0.0590608297F, 0.0595193651F,
- 0.0599795929F, 0.0604415117F, 0.0609051202F, 0.0613704170F,
- 0.0618374009F, 0.0623060704F, 0.0627764243F, 0.0632484611F,
- 0.0637221795F, 0.0641975781F, 0.0646746555F, 0.0651534104F,
- 0.0656338413F, 0.0661159469F, 0.0665997257F, 0.0670851763F,
- 0.0675722973F, 0.0680610873F, 0.0685515448F, 0.0690436684F,
- 0.0695374567F, 0.0700329081F, 0.0705300213F, 0.0710287947F,
- 0.0715292269F, 0.0720313163F, 0.0725350616F, 0.0730404612F,
- 0.0735475136F, 0.0740562172F, 0.0745665707F, 0.0750785723F,
- 0.0755922207F, 0.0761075143F, 0.0766244515F, 0.0771430307F,
- 0.0776632505F, 0.0781851092F, 0.0787086052F, 0.0792337371F,
- 0.0797605032F, 0.0802889018F, 0.0808189315F, 0.0813505905F,
- 0.0818838773F, 0.0824187903F, 0.0829553277F, 0.0834934881F,
- 0.0840332697F, 0.0845746708F, 0.0851176899F, 0.0856623252F,
- 0.0862085751F, 0.0867564379F, 0.0873059119F, 0.0878569954F,
- 0.0884096867F, 0.0889639840F, 0.0895198858F, 0.0900773902F,
- 0.0906364955F, 0.0911972000F, 0.0917595019F, 0.0923233995F,
- 0.0928888909F, 0.0934559745F, 0.0940246485F, 0.0945949110F,
- 0.0951667604F, 0.0957401946F, 0.0963152121F, 0.0968918109F,
- 0.0974699893F, 0.0980497454F, 0.0986310773F, 0.0992139832F,
- 0.0997984614F, 0.1003845098F, 0.1009721267F, 0.1015613101F,
- 0.1021520582F, 0.1027443692F, 0.1033382410F, 0.1039336718F,
- 0.1045306597F, 0.1051292027F, 0.1057292990F, 0.1063309466F,
- 0.1069341435F, 0.1075388878F, 0.1081451776F, 0.1087530108F,
- 0.1093623856F, 0.1099732998F, 0.1105857516F, 0.1111997389F,
- 0.1118152597F, 0.1124323121F, 0.1130508939F, 0.1136710032F,
- 0.1142926379F, 0.1149157960F, 0.1155404755F, 0.1161666742F,
- 0.1167943901F, 0.1174236211F, 0.1180543652F, 0.1186866202F,
- 0.1193203841F, 0.1199556548F, 0.1205924300F, 0.1212307078F,
- 0.1218704860F, 0.1225117624F, 0.1231545349F, 0.1237988013F,
- 0.1244445596F, 0.1250918074F, 0.1257405427F, 0.1263907632F,
- 0.1270424667F, 0.1276956512F, 0.1283503142F, 0.1290064537F,
- 0.1296640674F, 0.1303231530F, 0.1309837084F, 0.1316457312F,
- 0.1323092193F, 0.1329741703F, 0.1336405820F, 0.1343084520F,
- 0.1349777782F, 0.1356485582F, 0.1363207897F, 0.1369944704F,
- 0.1376695979F, 0.1383461700F, 0.1390241842F, 0.1397036384F,
- 0.1403845300F, 0.1410668567F, 0.1417506162F, 0.1424358061F,
- 0.1431224240F, 0.1438104674F, 0.1444999341F, 0.1451908216F,
- 0.1458831274F, 0.1465768492F, 0.1472719844F, 0.1479685308F,
- 0.1486664857F, 0.1493658468F, 0.1500666115F, 0.1507687775F,
- 0.1514723422F, 0.1521773031F, 0.1528836577F, 0.1535914035F,
- 0.1543005380F, 0.1550110587F, 0.1557229631F, 0.1564362485F,
- 0.1571509124F, 0.1578669524F, 0.1585843657F, 0.1593031499F,
- 0.1600233024F, 0.1607448205F, 0.1614677017F, 0.1621919433F,
- 0.1629175428F, 0.1636444975F, 0.1643728047F, 0.1651024619F,
- 0.1658334665F, 0.1665658156F, 0.1672995067F, 0.1680345371F,
- 0.1687709041F, 0.1695086050F, 0.1702476372F, 0.1709879978F,
- 0.1717296843F, 0.1724726938F, 0.1732170237F, 0.1739626711F,
- 0.1747096335F, 0.1754579079F, 0.1762074916F, 0.1769583819F,
- 0.1777105760F, 0.1784640710F, 0.1792188642F, 0.1799749529F,
- 0.1807323340F, 0.1814910049F, 0.1822509628F, 0.1830122046F,
- 0.1837747277F, 0.1845385292F, 0.1853036062F, 0.1860699558F,
- 0.1868375751F, 0.1876064613F, 0.1883766114F, 0.1891480226F,
- 0.1899206919F, 0.1906946164F, 0.1914697932F, 0.1922462194F,
- 0.1930238919F, 0.1938028079F, 0.1945829643F, 0.1953643583F,
- 0.1961469868F, 0.1969308468F, 0.1977159353F, 0.1985022494F,
- 0.1992897859F, 0.2000785420F, 0.2008685145F, 0.2016597005F,
- 0.2024520968F, 0.2032457005F, 0.2040405084F, 0.2048365175F,
- 0.2056337247F, 0.2064321269F, 0.2072317211F, 0.2080325041F,
- 0.2088344727F, 0.2096376240F, 0.2104419547F, 0.2112474618F,
- 0.2120541420F, 0.2128619923F, 0.2136710094F, 0.2144811902F,
- 0.2152925315F, 0.2161050301F, 0.2169186829F, 0.2177334866F,
- 0.2185494381F, 0.2193665340F, 0.2201847712F, 0.2210041465F,
- 0.2218246565F, 0.2226462981F, 0.2234690680F, 0.2242929629F,
- 0.2251179796F, 0.2259441147F, 0.2267713650F, 0.2275997272F,
- 0.2284291979F, 0.2292597739F, 0.2300914518F, 0.2309242283F,
- 0.2317581001F, 0.2325930638F, 0.2334291160F, 0.2342662534F,
- 0.2351044727F, 0.2359437703F, 0.2367841431F, 0.2376255875F,
- 0.2384681001F, 0.2393116776F, 0.2401563165F, 0.2410020134F,
- 0.2418487649F, 0.2426965675F, 0.2435454178F, 0.2443953122F,
- 0.2452462474F, 0.2460982199F, 0.2469512262F, 0.2478052628F,
- 0.2486603262F, 0.2495164129F, 0.2503735194F, 0.2512316421F,
- 0.2520907776F, 0.2529509222F, 0.2538120726F, 0.2546742250F,
- 0.2555373760F, 0.2564015219F, 0.2572666593F, 0.2581327845F,
- 0.2589998939F, 0.2598679840F, 0.2607370510F, 0.2616070916F,
- 0.2624781019F, 0.2633500783F, 0.2642230173F, 0.2650969152F,
- 0.2659717684F, 0.2668475731F, 0.2677243257F, 0.2686020226F,
- 0.2694806601F, 0.2703602344F, 0.2712407419F, 0.2721221789F,
- 0.2730045417F, 0.2738878265F, 0.2747720297F, 0.2756571474F,
- 0.2765431760F, 0.2774301117F, 0.2783179508F, 0.2792066895F,
- 0.2800963240F, 0.2809868505F, 0.2818782654F, 0.2827705647F,
- 0.2836637447F, 0.2845578016F, 0.2854527315F, 0.2863485307F,
- 0.2872451953F, 0.2881427215F, 0.2890411055F, 0.2899403433F,
- 0.2908404312F, 0.2917413654F, 0.2926431418F, 0.2935457567F,
- 0.2944492061F, 0.2953534863F, 0.2962585932F, 0.2971645230F,
- 0.2980712717F, 0.2989788356F, 0.2998872105F, 0.3007963927F,
- 0.3017063781F, 0.3026171629F, 0.3035287430F, 0.3044411145F,
- 0.3053542736F, 0.3062682161F, 0.3071829381F, 0.3080984356F,
- 0.3090147047F, 0.3099317413F, 0.3108495414F, 0.3117681011F,
- 0.3126874163F, 0.3136074830F, 0.3145282972F, 0.3154498548F,
- 0.3163721517F, 0.3172951841F, 0.3182189477F, 0.3191434385F,
- 0.3200686525F, 0.3209945856F, 0.3219212336F, 0.3228485927F,
- 0.3237766585F, 0.3247054271F, 0.3256348943F, 0.3265650560F,
- 0.3274959081F, 0.3284274465F, 0.3293596671F, 0.3302925657F,
- 0.3312261382F, 0.3321603804F, 0.3330952882F, 0.3340308574F,
- 0.3349670838F, 0.3359039634F, 0.3368414919F, 0.3377796651F,
- 0.3387184789F, 0.3396579290F, 0.3405980113F, 0.3415387216F,
- 0.3424800556F, 0.3434220091F, 0.3443645779F, 0.3453077578F,
- 0.3462515446F, 0.3471959340F, 0.3481409217F, 0.3490865036F,
- 0.3500326754F, 0.3509794328F, 0.3519267715F, 0.3528746873F,
- 0.3538231759F, 0.3547722330F, 0.3557218544F, 0.3566720357F,
- 0.3576227727F, 0.3585740610F, 0.3595258964F, 0.3604782745F,
- 0.3614311910F, 0.3623846417F, 0.3633386221F, 0.3642931280F,
- 0.3652481549F, 0.3662036987F, 0.3671597548F, 0.3681163191F,
- 0.3690733870F, 0.3700309544F, 0.3709890167F, 0.3719475696F,
- 0.3729066089F, 0.3738661299F, 0.3748261285F, 0.3757866002F,
- 0.3767475406F, 0.3777089453F, 0.3786708100F, 0.3796331302F,
- 0.3805959014F, 0.3815591194F, 0.3825227796F, 0.3834868777F,
- 0.3844514093F, 0.3854163698F, 0.3863817549F, 0.3873475601F,
- 0.3883137810F, 0.3892804131F, 0.3902474521F, 0.3912148933F,
- 0.3921827325F, 0.3931509650F, 0.3941195865F, 0.3950885925F,
- 0.3960579785F, 0.3970277400F, 0.3979978725F, 0.3989683716F,
- 0.3999392328F, 0.4009104516F, 0.4018820234F, 0.4028539438F,
- 0.4038262084F, 0.4047988125F, 0.4057717516F, 0.4067450214F,
- 0.4077186172F, 0.4086925345F, 0.4096667688F, 0.4106413155F,
- 0.4116161703F, 0.4125913284F, 0.4135667854F, 0.4145425368F,
- 0.4155185780F, 0.4164949044F, 0.4174715116F, 0.4184483949F,
- 0.4194255498F, 0.4204029718F, 0.4213806563F, 0.4223585987F,
- 0.4233367946F, 0.4243152392F, 0.4252939281F, 0.4262728566F,
- 0.4272520202F, 0.4282314144F, 0.4292110345F, 0.4301908760F,
- 0.4311709343F, 0.4321512047F, 0.4331316828F, 0.4341123639F,
- 0.4350932435F, 0.4360743168F, 0.4370555794F, 0.4380370267F,
- 0.4390186540F, 0.4400004567F, 0.4409824303F, 0.4419645701F,
- 0.4429468716F, 0.4439293300F, 0.4449119409F, 0.4458946996F,
- 0.4468776014F, 0.4478606418F, 0.4488438162F, 0.4498271199F,
- 0.4508105483F, 0.4517940967F, 0.4527777607F, 0.4537615355F,
- 0.4547454165F, 0.4557293991F, 0.4567134786F, 0.4576976505F,
- 0.4586819101F, 0.4596662527F, 0.4606506738F, 0.4616351687F,
- 0.4626197328F, 0.4636043614F, 0.4645890499F, 0.4655737936F,
- 0.4665585880F, 0.4675434284F, 0.4685283101F, 0.4695132286F,
- 0.4704981791F, 0.4714831570F, 0.4724681577F, 0.4734531766F,
- 0.4744382089F, 0.4754232501F, 0.4764082956F, 0.4773933406F,
- 0.4783783806F, 0.4793634108F, 0.4803484267F, 0.4813334237F,
- 0.4823183969F, 0.4833033419F, 0.4842882540F, 0.4852731285F,
- 0.4862579608F, 0.4872427462F, 0.4882274802F, 0.4892121580F,
- 0.4901967751F, 0.4911813267F, 0.4921658083F, 0.4931502151F,
- 0.4941345427F, 0.4951187863F, 0.4961029412F, 0.4970870029F,
- 0.4980709667F, 0.4990548280F, 0.5000385822F, 0.5010222245F,
- 0.5020057505F, 0.5029891553F, 0.5039724345F, 0.5049555834F,
- 0.5059385973F, 0.5069214716F, 0.5079042018F, 0.5088867831F,
- 0.5098692110F, 0.5108514808F, 0.5118335879F, 0.5128155277F,
- 0.5137972956F, 0.5147788869F, 0.5157602971F, 0.5167415215F,
- 0.5177225555F, 0.5187033945F, 0.5196840339F, 0.5206644692F,
- 0.5216446956F, 0.5226247086F, 0.5236045035F, 0.5245840759F,
- 0.5255634211F, 0.5265425344F, 0.5275214114F, 0.5285000474F,
- 0.5294784378F, 0.5304565781F, 0.5314344637F, 0.5324120899F,
- 0.5333894522F, 0.5343665461F, 0.5353433670F, 0.5363199102F,
- 0.5372961713F, 0.5382721457F, 0.5392478287F, 0.5402232159F,
- 0.5411983027F, 0.5421730845F, 0.5431475569F, 0.5441217151F,
- 0.5450955548F, 0.5460690714F, 0.5470422602F, 0.5480151169F,
- 0.5489876368F, 0.5499598155F, 0.5509316484F, 0.5519031310F,
- 0.5528742587F, 0.5538450271F, 0.5548154317F, 0.5557854680F,
- 0.5567551314F, 0.5577244174F, 0.5586933216F, 0.5596618395F,
- 0.5606299665F, 0.5615976983F, 0.5625650302F, 0.5635319580F,
- 0.5644984770F, 0.5654645828F, 0.5664302709F, 0.5673955370F,
- 0.5683603765F, 0.5693247850F, 0.5702887580F, 0.5712522912F,
- 0.5722153800F, 0.5731780200F, 0.5741402069F, 0.5751019362F,
- 0.5760632034F, 0.5770240042F, 0.5779843341F, 0.5789441889F,
- 0.5799035639F, 0.5808624549F, 0.5818208575F, 0.5827787673F,
- 0.5837361800F, 0.5846930910F, 0.5856494961F, 0.5866053910F,
- 0.5875607712F, 0.5885156324F, 0.5894699703F, 0.5904237804F,
- 0.5913770586F, 0.5923298004F, 0.5932820016F, 0.5942336578F,
- 0.5951847646F, 0.5961353179F, 0.5970853132F, 0.5980347464F,
- 0.5989836131F, 0.5999319090F, 0.6008796298F, 0.6018267713F,
- 0.6027733292F, 0.6037192993F, 0.6046646773F, 0.6056094589F,
- 0.6065536400F, 0.6074972162F, 0.6084401833F, 0.6093825372F,
- 0.6103242736F, 0.6112653884F, 0.6122058772F, 0.6131457359F,
- 0.6140849604F, 0.6150235464F, 0.6159614897F, 0.6168987862F,
- 0.6178354318F, 0.6187714223F, 0.6197067535F, 0.6206414213F,
- 0.6215754215F, 0.6225087501F, 0.6234414028F, 0.6243733757F,
- 0.6253046646F, 0.6262352654F, 0.6271651739F, 0.6280943862F,
- 0.6290228982F, 0.6299507057F, 0.6308778048F, 0.6318041913F,
- 0.6327298612F, 0.6336548105F, 0.6345790352F, 0.6355025312F,
- 0.6364252945F, 0.6373473211F, 0.6382686070F, 0.6391891483F,
- 0.6401089409F, 0.6410279808F, 0.6419462642F, 0.6428637869F,
- 0.6437805452F, 0.6446965350F, 0.6456117524F, 0.6465261935F,
- 0.6474398544F, 0.6483527311F, 0.6492648197F, 0.6501761165F,
- 0.6510866174F, 0.6519963186F, 0.6529052162F, 0.6538133064F,
- 0.6547205854F, 0.6556270492F, 0.6565326941F, 0.6574375162F,
- 0.6583415117F, 0.6592446769F, 0.6601470079F, 0.6610485009F,
- 0.6619491521F, 0.6628489578F, 0.6637479143F, 0.6646460177F,
- 0.6655432643F, 0.6664396505F, 0.6673351724F, 0.6682298264F,
- 0.6691236087F, 0.6700165157F, 0.6709085436F, 0.6717996889F,
- 0.6726899478F, 0.6735793167F, 0.6744677918F, 0.6753553697F,
- 0.6762420466F, 0.6771278190F, 0.6780126832F, 0.6788966357F,
- 0.6797796728F, 0.6806617909F, 0.6815429866F, 0.6824232562F,
- 0.6833025961F, 0.6841810030F, 0.6850584731F, 0.6859350031F,
- 0.6868105894F, 0.6876852284F, 0.6885589168F, 0.6894316510F,
- 0.6903034275F, 0.6911742430F, 0.6920440939F, 0.6929129769F,
- 0.6937808884F, 0.6946478251F, 0.6955137837F, 0.6963787606F,
- 0.6972427525F, 0.6981057560F, 0.6989677678F, 0.6998287845F,
- 0.7006888028F, 0.7015478194F, 0.7024058309F, 0.7032628340F,
- 0.7041188254F, 0.7049738019F, 0.7058277601F, 0.7066806969F,
- 0.7075326089F, 0.7083834929F, 0.7092333457F, 0.7100821640F,
- 0.7109299447F, 0.7117766846F, 0.7126223804F, 0.7134670291F,
- 0.7143106273F, 0.7151531721F, 0.7159946602F, 0.7168350885F,
- 0.7176744539F, 0.7185127534F, 0.7193499837F, 0.7201861418F,
- 0.7210212247F, 0.7218552293F, 0.7226881526F, 0.7235199914F,
- 0.7243507428F, 0.7251804039F, 0.7260089715F, 0.7268364426F,
- 0.7276628144F, 0.7284880839F, 0.7293122481F, 0.7301353040F,
- 0.7309572487F, 0.7317780794F, 0.7325977930F, 0.7334163868F,
- 0.7342338579F, 0.7350502033F, 0.7358654202F, 0.7366795059F,
- 0.7374924573F, 0.7383042718F, 0.7391149465F, 0.7399244787F,
- 0.7407328655F, 0.7415401041F, 0.7423461920F, 0.7431511261F,
- 0.7439549040F, 0.7447575227F, 0.7455589797F, 0.7463592723F,
- 0.7471583976F, 0.7479563532F, 0.7487531363F, 0.7495487443F,
- 0.7503431745F, 0.7511364244F, 0.7519284913F, 0.7527193726F,
- 0.7535090658F, 0.7542975683F, 0.7550848776F, 0.7558709910F,
- 0.7566559062F, 0.7574396205F, 0.7582221314F, 0.7590034366F,
- 0.7597835334F, 0.7605624194F, 0.7613400923F, 0.7621165495F,
- 0.7628917886F, 0.7636658072F, 0.7644386030F, 0.7652101735F,
- 0.7659805164F, 0.7667496292F, 0.7675175098F, 0.7682841556F,
- 0.7690495645F, 0.7698137341F, 0.7705766622F, 0.7713383463F,
- 0.7720987844F, 0.7728579741F, 0.7736159132F, 0.7743725994F,
- 0.7751280306F, 0.7758822046F, 0.7766351192F, 0.7773867722F,
- 0.7781371614F, 0.7788862848F, 0.7796341401F, 0.7803807253F,
- 0.7811260383F, 0.7818700769F, 0.7826128392F, 0.7833543230F,
- 0.7840945263F, 0.7848334471F, 0.7855710833F, 0.7863074330F,
- 0.7870424941F, 0.7877762647F, 0.7885087428F, 0.7892399264F,
- 0.7899698137F, 0.7906984026F, 0.7914256914F, 0.7921516780F,
- 0.7928763607F, 0.7935997375F, 0.7943218065F, 0.7950425661F,
- 0.7957620142F, 0.7964801492F, 0.7971969692F, 0.7979124724F,
- 0.7986266570F, 0.7993395214F, 0.8000510638F, 0.8007612823F,
- 0.8014701754F, 0.8021777413F, 0.8028839784F, 0.8035888849F,
- 0.8042924592F, 0.8049946997F, 0.8056956048F, 0.8063951727F,
- 0.8070934020F, 0.8077902910F, 0.8084858381F, 0.8091800419F,
- 0.8098729007F, 0.8105644130F, 0.8112545774F, 0.8119433922F,
- 0.8126308561F, 0.8133169676F, 0.8140017251F, 0.8146851272F,
- 0.8153671726F, 0.8160478598F, 0.8167271874F, 0.8174051539F,
- 0.8180817582F, 0.8187569986F, 0.8194308741F, 0.8201033831F,
- 0.8207745244F, 0.8214442966F, 0.8221126986F, 0.8227797290F,
- 0.8234453865F, 0.8241096700F, 0.8247725781F, 0.8254341097F,
- 0.8260942636F, 0.8267530385F, 0.8274104334F, 0.8280664470F,
- 0.8287210782F, 0.8293743259F, 0.8300261889F, 0.8306766662F,
- 0.8313257566F, 0.8319734591F, 0.8326197727F, 0.8332646963F,
- 0.8339082288F, 0.8345503692F, 0.8351911167F, 0.8358304700F,
- 0.8364684284F, 0.8371049907F, 0.8377401562F, 0.8383739238F,
- 0.8390062927F, 0.8396372618F, 0.8402668305F, 0.8408949977F,
- 0.8415217626F, 0.8421471245F, 0.8427710823F, 0.8433936354F,
- 0.8440147830F, 0.8446345242F, 0.8452528582F, 0.8458697844F,
- 0.8464853020F, 0.8470994102F, 0.8477121084F, 0.8483233958F,
- 0.8489332718F, 0.8495417356F, 0.8501487866F, 0.8507544243F,
- 0.8513586479F, 0.8519614568F, 0.8525628505F, 0.8531628283F,
- 0.8537613897F, 0.8543585341F, 0.8549542611F, 0.8555485699F,
- 0.8561414603F, 0.8567329315F, 0.8573229832F, 0.8579116149F,
- 0.8584988262F, 0.8590846165F, 0.8596689855F, 0.8602519327F,
- 0.8608334577F, 0.8614135603F, 0.8619922399F, 0.8625694962F,
- 0.8631453289F, 0.8637197377F, 0.8642927222F, 0.8648642821F,
- 0.8654344172F, 0.8660031272F, 0.8665704118F, 0.8671362708F,
- 0.8677007039F, 0.8682637109F, 0.8688252917F, 0.8693854460F,
- 0.8699441737F, 0.8705014745F, 0.8710573485F, 0.8716117953F,
- 0.8721648150F, 0.8727164073F, 0.8732665723F, 0.8738153098F,
- 0.8743626197F, 0.8749085021F, 0.8754529569F, 0.8759959840F,
- 0.8765375835F, 0.8770777553F, 0.8776164996F, 0.8781538162F,
- 0.8786897054F, 0.8792241670F, 0.8797572013F, 0.8802888082F,
- 0.8808189880F, 0.8813477407F, 0.8818750664F, 0.8824009653F,
- 0.8829254375F, 0.8834484833F, 0.8839701028F, 0.8844902961F,
- 0.8850090636F, 0.8855264054F, 0.8860423218F, 0.8865568131F,
- 0.8870698794F, 0.8875815212F, 0.8880917386F, 0.8886005319F,
- 0.8891079016F, 0.8896138479F, 0.8901183712F, 0.8906214719F,
- 0.8911231503F, 0.8916234067F, 0.8921222417F, 0.8926196556F,
- 0.8931156489F, 0.8936102219F, 0.8941033752F, 0.8945951092F,
- 0.8950854244F, 0.8955743212F, 0.8960618003F, 0.8965478621F,
- 0.8970325071F, 0.8975157359F, 0.8979975490F, 0.8984779471F,
- 0.8989569307F, 0.8994345004F, 0.8999106568F, 0.9003854005F,
- 0.9008587323F, 0.9013306526F, 0.9018011623F, 0.9022702619F,
- 0.9027379521F, 0.9032042337F, 0.9036691074F, 0.9041325739F,
- 0.9045946339F, 0.9050552882F, 0.9055145376F, 0.9059723828F,
- 0.9064288246F, 0.9068838638F, 0.9073375013F, 0.9077897379F,
- 0.9082405743F, 0.9086900115F, 0.9091380503F, 0.9095846917F,
- 0.9100299364F, 0.9104737854F, 0.9109162397F, 0.9113573001F,
- 0.9117969675F, 0.9122352430F, 0.9126721275F, 0.9131076219F,
- 0.9135417273F, 0.9139744447F, 0.9144057750F, 0.9148357194F,
- 0.9152642787F, 0.9156914542F, 0.9161172468F, 0.9165416576F,
- 0.9169646877F, 0.9173863382F, 0.9178066102F, 0.9182255048F,
- 0.9186430232F, 0.9190591665F, 0.9194739359F, 0.9198873324F,
- 0.9202993574F, 0.9207100120F, 0.9211192973F, 0.9215272147F,
- 0.9219337653F, 0.9223389504F, 0.9227427713F, 0.9231452290F,
- 0.9235463251F, 0.9239460607F, 0.9243444371F, 0.9247414557F,
- 0.9251371177F, 0.9255314245F, 0.9259243774F, 0.9263159778F,
- 0.9267062270F, 0.9270951264F, 0.9274826774F, 0.9278688814F,
- 0.9282537398F, 0.9286372540F, 0.9290194254F, 0.9294002555F,
- 0.9297797458F, 0.9301578976F, 0.9305347125F, 0.9309101919F,
- 0.9312843373F, 0.9316571503F, 0.9320286323F, 0.9323987849F,
- 0.9327676097F, 0.9331351080F, 0.9335012816F, 0.9338661320F,
- 0.9342296607F, 0.9345918694F, 0.9349527596F, 0.9353123330F,
- 0.9356705911F, 0.9360275357F, 0.9363831683F, 0.9367374905F,
- 0.9370905042F, 0.9374422108F, 0.9377926122F, 0.9381417099F,
- 0.9384895057F, 0.9388360014F, 0.9391811985F, 0.9395250989F,
- 0.9398677043F, 0.9402090165F, 0.9405490371F, 0.9408877680F,
- 0.9412252110F, 0.9415613678F, 0.9418962402F, 0.9422298301F,
- 0.9425621392F, 0.9428931695F, 0.9432229226F, 0.9435514005F,
- 0.9438786050F, 0.9442045381F, 0.9445292014F, 0.9448525971F,
- 0.9451747268F, 0.9454955926F, 0.9458151963F, 0.9461335399F,
- 0.9464506253F, 0.9467664545F, 0.9470810293F, 0.9473943517F,
- 0.9477064238F, 0.9480172474F, 0.9483268246F, 0.9486351573F,
- 0.9489422475F, 0.9492480973F, 0.9495527087F, 0.9498560837F,
- 0.9501582243F, 0.9504591325F, 0.9507588105F, 0.9510572603F,
- 0.9513544839F, 0.9516504834F, 0.9519452609F, 0.9522388186F,
- 0.9525311584F, 0.9528222826F, 0.9531121932F, 0.9534008923F,
- 0.9536883821F, 0.9539746647F, 0.9542597424F, 0.9545436171F,
- 0.9548262912F, 0.9551077667F, 0.9553880459F, 0.9556671309F,
- 0.9559450239F, 0.9562217272F, 0.9564972429F, 0.9567715733F,
- 0.9570447206F, 0.9573166871F, 0.9575874749F, 0.9578570863F,
- 0.9581255236F, 0.9583927890F, 0.9586588849F, 0.9589238134F,
- 0.9591875769F, 0.9594501777F, 0.9597116180F, 0.9599719003F,
- 0.9602310267F, 0.9604889995F, 0.9607458213F, 0.9610014942F,
- 0.9612560206F, 0.9615094028F, 0.9617616433F, 0.9620127443F,
- 0.9622627083F, 0.9625115376F, 0.9627592345F, 0.9630058016F,
- 0.9632512411F, 0.9634955555F, 0.9637387471F, 0.9639808185F,
- 0.9642217720F, 0.9644616100F, 0.9647003349F, 0.9649379493F,
- 0.9651744556F, 0.9654098561F, 0.9656441534F, 0.9658773499F,
- 0.9661094480F, 0.9663404504F, 0.9665703593F, 0.9667991774F,
- 0.9670269071F, 0.9672535509F, 0.9674791114F, 0.9677035909F,
- 0.9679269921F, 0.9681493174F, 0.9683705694F, 0.9685907506F,
- 0.9688098636F, 0.9690279108F, 0.9692448948F, 0.9694608182F,
- 0.9696756836F, 0.9698894934F, 0.9701022503F, 0.9703139569F,
- 0.9705246156F, 0.9707342291F, 0.9709428000F, 0.9711503309F,
- 0.9713568243F, 0.9715622829F, 0.9717667093F, 0.9719701060F,
- 0.9721724757F, 0.9723738210F, 0.9725741446F, 0.9727734490F,
- 0.9729717369F, 0.9731690109F, 0.9733652737F, 0.9735605279F,
- 0.9737547762F, 0.9739480212F, 0.9741402656F, 0.9743315120F,
- 0.9745217631F, 0.9747110216F, 0.9748992901F, 0.9750865714F,
- 0.9752728681F, 0.9754581829F, 0.9756425184F, 0.9758258775F,
- 0.9760082627F, 0.9761896768F, 0.9763701224F, 0.9765496024F,
- 0.9767281193F, 0.9769056760F, 0.9770822751F, 0.9772579193F,
- 0.9774326114F, 0.9776063542F, 0.9777791502F, 0.9779510023F,
- 0.9781219133F, 0.9782918858F, 0.9784609226F, 0.9786290264F,
- 0.9787962000F, 0.9789624461F, 0.9791277676F, 0.9792921671F,
- 0.9794556474F, 0.9796182113F, 0.9797798615F, 0.9799406009F,
- 0.9801004321F, 0.9802593580F, 0.9804173813F, 0.9805745049F,
- 0.9807307314F, 0.9808860637F, 0.9810405046F, 0.9811940568F,
- 0.9813467232F, 0.9814985065F, 0.9816494095F, 0.9817994351F,
- 0.9819485860F, 0.9820968650F, 0.9822442750F, 0.9823908186F,
- 0.9825364988F, 0.9826813184F, 0.9828252801F, 0.9829683868F,
- 0.9831106413F, 0.9832520463F, 0.9833926048F, 0.9835323195F,
- 0.9836711932F, 0.9838092288F, 0.9839464291F, 0.9840827969F,
- 0.9842183351F, 0.9843530464F, 0.9844869337F, 0.9846199998F,
- 0.9847522475F, 0.9848836798F, 0.9850142993F, 0.9851441090F,
- 0.9852731117F, 0.9854013101F, 0.9855287073F, 0.9856553058F,
- 0.9857811087F, 0.9859061188F, 0.9860303388F, 0.9861537717F,
- 0.9862764202F, 0.9863982872F, 0.9865193756F, 0.9866396882F,
- 0.9867592277F, 0.9868779972F, 0.9869959993F, 0.9871132370F,
- 0.9872297131F, 0.9873454304F, 0.9874603918F, 0.9875746001F,
- 0.9876880581F, 0.9878007688F, 0.9879127348F, 0.9880239592F,
- 0.9881344447F, 0.9882441941F, 0.9883532104F, 0.9884614962F,
- 0.9885690546F, 0.9886758883F, 0.9887820001F, 0.9888873930F,
- 0.9889920697F, 0.9890960331F, 0.9891992859F, 0.9893018312F,
- 0.9894036716F, 0.9895048100F, 0.9896052493F, 0.9897049923F,
- 0.9898040418F, 0.9899024006F, 0.9900000717F, 0.9900970577F,
- 0.9901933616F, 0.9902889862F, 0.9903839343F, 0.9904782087F,
- 0.9905718122F, 0.9906647477F, 0.9907570180F, 0.9908486259F,
- 0.9909395742F, 0.9910298658F, 0.9911195034F, 0.9912084899F,
- 0.9912968281F, 0.9913845208F, 0.9914715708F, 0.9915579810F,
- 0.9916437540F, 0.9917288928F, 0.9918134001F, 0.9918972788F,
- 0.9919805316F, 0.9920631613F, 0.9921451707F, 0.9922265626F,
- 0.9923073399F, 0.9923875052F, 0.9924670615F, 0.9925460114F,
- 0.9926243577F, 0.9927021033F, 0.9927792508F, 0.9928558032F,
- 0.9929317631F, 0.9930071333F, 0.9930819167F, 0.9931561158F,
- 0.9932297337F, 0.9933027728F, 0.9933752362F, 0.9934471264F,
- 0.9935184462F, 0.9935891985F, 0.9936593859F, 0.9937290112F,
- 0.9937980771F, 0.9938665864F, 0.9939345418F, 0.9940019460F,
- 0.9940688018F, 0.9941351118F, 0.9942008789F, 0.9942661057F,
- 0.9943307950F, 0.9943949494F, 0.9944585717F, 0.9945216645F,
- 0.9945842307F, 0.9946462728F, 0.9947077936F, 0.9947687957F,
- 0.9948292820F, 0.9948892550F, 0.9949487174F, 0.9950076719F,
- 0.9950661212F, 0.9951240679F, 0.9951815148F, 0.9952384645F,
- 0.9952949196F, 0.9953508828F, 0.9954063568F, 0.9954613442F,
- 0.9955158476F, 0.9955698697F, 0.9956234132F, 0.9956764806F,
- 0.9957290746F, 0.9957811978F, 0.9958328528F, 0.9958840423F,
- 0.9959347688F, 0.9959850351F, 0.9960348435F, 0.9960841969F,
- 0.9961330977F, 0.9961815486F, 0.9962295521F, 0.9962771108F,
- 0.9963242274F, 0.9963709043F, 0.9964171441F, 0.9964629494F,
- 0.9965083228F, 0.9965532668F, 0.9965977840F, 0.9966418768F,
- 0.9966855479F, 0.9967287998F, 0.9967716350F, 0.9968140559F,
- 0.9968560653F, 0.9968976655F, 0.9969388591F, 0.9969796485F,
- 0.9970200363F, 0.9970600250F, 0.9970996170F, 0.9971388149F,
- 0.9971776211F, 0.9972160380F, 0.9972540683F, 0.9972917142F,
- 0.9973289783F, 0.9973658631F, 0.9974023709F, 0.9974385042F,
- 0.9974742655F, 0.9975096571F, 0.9975446816F, 0.9975793413F,
- 0.9976136386F, 0.9976475759F, 0.9976811557F, 0.9977143803F,
- 0.9977472521F, 0.9977797736F, 0.9978119470F, 0.9978437748F,
- 0.9978752593F, 0.9979064029F, 0.9979372079F, 0.9979676768F,
- 0.9979978117F, 0.9980276151F, 0.9980570893F, 0.9980862367F,
- 0.9981150595F, 0.9981435600F, 0.9981717406F, 0.9981996035F,
- 0.9982271511F, 0.9982543856F, 0.9982813093F, 0.9983079246F,
- 0.9983342336F, 0.9983602386F, 0.9983859418F, 0.9984113456F,
- 0.9984364522F, 0.9984612638F, 0.9984857825F, 0.9985100108F,
- 0.9985339507F, 0.9985576044F, 0.9985809743F, 0.9986040624F,
- 0.9986268710F, 0.9986494022F, 0.9986716583F, 0.9986936413F,
- 0.9987153535F, 0.9987367969F, 0.9987579738F, 0.9987788864F,
- 0.9987995366F, 0.9988199267F, 0.9988400587F, 0.9988599348F,
- 0.9988795572F, 0.9988989278F, 0.9989180487F, 0.9989369222F,
- 0.9989555501F, 0.9989739347F, 0.9989920780F, 0.9990099820F,
- 0.9990276487F, 0.9990450803F, 0.9990622787F, 0.9990792460F,
- 0.9990959841F, 0.9991124952F, 0.9991287812F, 0.9991448440F,
- 0.9991606858F, 0.9991763084F, 0.9991917139F, 0.9992069042F,
- 0.9992218813F, 0.9992366471F, 0.9992512035F, 0.9992655525F,
- 0.9992796961F, 0.9992936361F, 0.9993073744F, 0.9993209131F,
- 0.9993342538F, 0.9993473987F, 0.9993603494F, 0.9993731080F,
- 0.9993856762F, 0.9993980559F, 0.9994102490F, 0.9994222573F,
- 0.9994340827F, 0.9994457269F, 0.9994571918F, 0.9994684793F,
- 0.9994795910F, 0.9994905288F, 0.9995012945F, 0.9995118898F,
- 0.9995223165F, 0.9995325765F, 0.9995426713F, 0.9995526029F,
- 0.9995623728F, 0.9995719829F, 0.9995814349F, 0.9995907304F,
- 0.9995998712F, 0.9996088590F, 0.9996176954F, 0.9996263821F,
- 0.9996349208F, 0.9996433132F, 0.9996515609F, 0.9996596656F,
- 0.9996676288F, 0.9996754522F, 0.9996831375F, 0.9996906862F,
- 0.9996981000F, 0.9997053804F, 0.9997125290F, 0.9997195474F,
- 0.9997264371F, 0.9997331998F, 0.9997398369F, 0.9997463500F,
- 0.9997527406F, 0.9997590103F, 0.9997651606F, 0.9997711930F,
- 0.9997771089F, 0.9997829098F, 0.9997885973F, 0.9997941728F,
- 0.9997996378F, 0.9998049936F, 0.9998102419F, 0.9998153839F,
- 0.9998204211F, 0.9998253550F, 0.9998301868F, 0.9998349182F,
- 0.9998395503F, 0.9998440847F, 0.9998485226F, 0.9998528654F,
- 0.9998571146F, 0.9998612713F, 0.9998653370F, 0.9998693130F,
- 0.9998732007F, 0.9998770012F, 0.9998807159F, 0.9998843461F,
- 0.9998878931F, 0.9998913581F, 0.9998947424F, 0.9998980473F,
- 0.9999012740F, 0.9999044237F, 0.9999074976F, 0.9999104971F,
- 0.9999134231F, 0.9999162771F, 0.9999190601F, 0.9999217733F,
- 0.9999244179F, 0.9999269950F, 0.9999295058F, 0.9999319515F,
- 0.9999343332F, 0.9999366519F, 0.9999389088F, 0.9999411050F,
- 0.9999432416F, 0.9999453196F, 0.9999473402F, 0.9999493044F,
- 0.9999512132F, 0.9999530677F, 0.9999548690F, 0.9999566180F,
- 0.9999583157F, 0.9999599633F, 0.9999615616F, 0.9999631116F,
- 0.9999646144F, 0.9999660709F, 0.9999674820F, 0.9999688487F,
- 0.9999701719F, 0.9999714526F, 0.9999726917F, 0.9999738900F,
- 0.9999750486F, 0.9999761682F, 0.9999772497F, 0.9999782941F,
- 0.9999793021F, 0.9999802747F, 0.9999812126F, 0.9999821167F,
- 0.9999829878F, 0.9999838268F, 0.9999846343F, 0.9999854113F,
- 0.9999861584F, 0.9999868765F, 0.9999875664F, 0.9999882287F,
- 0.9999888642F, 0.9999894736F, 0.9999900577F, 0.9999906172F,
- 0.9999911528F, 0.9999916651F, 0.9999921548F, 0.9999926227F,
- 0.9999930693F, 0.9999934954F, 0.9999939015F, 0.9999942883F,
- 0.9999946564F, 0.9999950064F, 0.9999953390F, 0.9999956547F,
- 0.9999959541F, 0.9999962377F, 0.9999965062F, 0.9999967601F,
- 0.9999969998F, 0.9999972260F, 0.9999974392F, 0.9999976399F,
- 0.9999978285F, 0.9999980056F, 0.9999981716F, 0.9999983271F,
- 0.9999984724F, 0.9999986081F, 0.9999987345F, 0.9999988521F,
- 0.9999989613F, 0.9999990625F, 0.9999991562F, 0.9999992426F,
- 0.9999993223F, 0.9999993954F, 0.9999994625F, 0.9999995239F,
- 0.9999995798F, 0.9999996307F, 0.9999996768F, 0.9999997184F,
- 0.9999997559F, 0.9999997895F, 0.9999998195F, 0.9999998462F,
- 0.9999998698F, 0.9999998906F, 0.9999999088F, 0.9999999246F,
- 0.9999999383F, 0.9999999500F, 0.9999999600F, 0.9999999684F,
- 0.9999999754F, 0.9999999811F, 0.9999999858F, 0.9999999896F,
- 0.9999999925F, 0.9999999948F, 0.9999999965F, 0.9999999978F,
- 0.9999999986F, 0.9999999992F, 0.9999999996F, 0.9999999998F,
- 0.9999999999F, 1.0000000000F, 1.0000000000F, 1.0000000000F,
- };
-
- static float vwin8192[4096] = {
- 0.0000000578F, 0.0000005198F, 0.0000014438F, 0.0000028299F,
- 0.0000046780F, 0.0000069882F, 0.0000097604F, 0.0000129945F,
- 0.0000166908F, 0.0000208490F, 0.0000254692F, 0.0000305515F,
- 0.0000360958F, 0.0000421021F, 0.0000485704F, 0.0000555006F,
- 0.0000628929F, 0.0000707472F, 0.0000790635F, 0.0000878417F,
- 0.0000970820F, 0.0001067842F, 0.0001169483F, 0.0001275744F,
- 0.0001386625F, 0.0001502126F, 0.0001622245F, 0.0001746984F,
- 0.0001876343F, 0.0002010320F, 0.0002148917F, 0.0002292132F,
- 0.0002439967F, 0.0002592421F, 0.0002749493F, 0.0002911184F,
- 0.0003077493F, 0.0003248421F, 0.0003423967F, 0.0003604132F,
- 0.0003788915F, 0.0003978316F, 0.0004172335F, 0.0004370971F,
- 0.0004574226F, 0.0004782098F, 0.0004994587F, 0.0005211694F,
- 0.0005433418F, 0.0005659759F, 0.0005890717F, 0.0006126292F,
- 0.0006366484F, 0.0006611292F, 0.0006860716F, 0.0007114757F,
- 0.0007373414F, 0.0007636687F, 0.0007904576F, 0.0008177080F,
- 0.0008454200F, 0.0008735935F, 0.0009022285F, 0.0009313250F,
- 0.0009608830F, 0.0009909025F, 0.0010213834F, 0.0010523257F,
- 0.0010837295F, 0.0011155946F, 0.0011479211F, 0.0011807090F,
- 0.0012139582F, 0.0012476687F, 0.0012818405F, 0.0013164736F,
- 0.0013515679F, 0.0013871235F, 0.0014231402F, 0.0014596182F,
- 0.0014965573F, 0.0015339576F, 0.0015718190F, 0.0016101415F,
- 0.0016489251F, 0.0016881698F, 0.0017278754F, 0.0017680421F,
- 0.0018086698F, 0.0018497584F, 0.0018913080F, 0.0019333185F,
- 0.0019757898F, 0.0020187221F, 0.0020621151F, 0.0021059690F,
- 0.0021502837F, 0.0021950591F, 0.0022402953F, 0.0022859921F,
- 0.0023321497F, 0.0023787679F, 0.0024258467F, 0.0024733861F,
- 0.0025213861F, 0.0025698466F, 0.0026187676F, 0.0026681491F,
- 0.0027179911F, 0.0027682935F, 0.0028190562F, 0.0028702794F,
- 0.0029219628F, 0.0029741066F, 0.0030267107F, 0.0030797749F,
- 0.0031332994F, 0.0031872841F, 0.0032417289F, 0.0032966338F,
- 0.0033519988F, 0.0034078238F, 0.0034641089F, 0.0035208539F,
- 0.0035780589F, 0.0036357237F, 0.0036938485F, 0.0037524331F,
- 0.0038114775F, 0.0038709817F, 0.0039309456F, 0.0039913692F,
- 0.0040522524F, 0.0041135953F, 0.0041753978F, 0.0042376599F,
- 0.0043003814F, 0.0043635624F, 0.0044272029F, 0.0044913028F,
- 0.0045558620F, 0.0046208806F, 0.0046863585F, 0.0047522955F,
- 0.0048186919F, 0.0048855473F, 0.0049528619F, 0.0050206356F,
- 0.0050888684F, 0.0051575601F, 0.0052267108F, 0.0052963204F,
- 0.0053663890F, 0.0054369163F, 0.0055079025F, 0.0055793474F,
- 0.0056512510F, 0.0057236133F, 0.0057964342F, 0.0058697137F,
- 0.0059434517F, 0.0060176482F, 0.0060923032F, 0.0061674166F,
- 0.0062429883F, 0.0063190183F, 0.0063955066F, 0.0064724532F,
- 0.0065498579F, 0.0066277207F, 0.0067060416F, 0.0067848205F,
- 0.0068640575F, 0.0069437523F, 0.0070239051F, 0.0071045157F,
- 0.0071855840F, 0.0072671102F, 0.0073490940F, 0.0074315355F,
- 0.0075144345F, 0.0075977911F, 0.0076816052F, 0.0077658768F,
- 0.0078506057F, 0.0079357920F, 0.0080214355F, 0.0081075363F,
- 0.0081940943F, 0.0082811094F, 0.0083685816F, 0.0084565108F,
- 0.0085448970F, 0.0086337401F, 0.0087230401F, 0.0088127969F,
- 0.0089030104F, 0.0089936807F, 0.0090848076F, 0.0091763911F,
- 0.0092684311F, 0.0093609276F, 0.0094538805F, 0.0095472898F,
- 0.0096411554F, 0.0097354772F, 0.0098302552F, 0.0099254894F,
- 0.0100211796F, 0.0101173259F, 0.0102139281F, 0.0103109863F,
- 0.0104085002F, 0.0105064700F, 0.0106048955F, 0.0107037766F,
- 0.0108031133F, 0.0109029056F, 0.0110031534F, 0.0111038565F,
- 0.0112050151F, 0.0113066289F, 0.0114086980F, 0.0115112222F,
- 0.0116142015F, 0.0117176359F, 0.0118215252F, 0.0119258695F,
- 0.0120306686F, 0.0121359225F, 0.0122416312F, 0.0123477944F,
- 0.0124544123F, 0.0125614847F, 0.0126690116F, 0.0127769928F,
- 0.0128854284F, 0.0129943182F, 0.0131036623F, 0.0132134604F,
- 0.0133237126F, 0.0134344188F, 0.0135455790F, 0.0136571929F,
- 0.0137692607F, 0.0138817821F, 0.0139947572F, 0.0141081859F,
- 0.0142220681F, 0.0143364037F, 0.0144511927F, 0.0145664350F,
- 0.0146821304F, 0.0147982791F, 0.0149148808F, 0.0150319355F,
- 0.0151494431F, 0.0152674036F, 0.0153858168F, 0.0155046828F,
- 0.0156240014F, 0.0157437726F, 0.0158639962F, 0.0159846723F,
- 0.0161058007F, 0.0162273814F, 0.0163494142F, 0.0164718991F,
- 0.0165948361F, 0.0167182250F, 0.0168420658F, 0.0169663584F,
- 0.0170911027F, 0.0172162987F, 0.0173419462F, 0.0174680452F,
- 0.0175945956F, 0.0177215974F, 0.0178490504F, 0.0179769545F,
- 0.0181053098F, 0.0182341160F, 0.0183633732F, 0.0184930812F,
- 0.0186232399F, 0.0187538494F, 0.0188849094F, 0.0190164200F,
- 0.0191483809F, 0.0192807923F, 0.0194136539F, 0.0195469656F,
- 0.0196807275F, 0.0198149394F, 0.0199496012F, 0.0200847128F,
- 0.0202202742F, 0.0203562853F, 0.0204927460F, 0.0206296561F,
- 0.0207670157F, 0.0209048245F, 0.0210430826F, 0.0211817899F,
- 0.0213209462F, 0.0214605515F, 0.0216006057F, 0.0217411086F,
- 0.0218820603F, 0.0220234605F, 0.0221653093F, 0.0223076066F,
- 0.0224503521F, 0.0225935459F, 0.0227371879F, 0.0228812779F,
- 0.0230258160F, 0.0231708018F, 0.0233162355F, 0.0234621169F,
- 0.0236084459F, 0.0237552224F, 0.0239024462F, 0.0240501175F,
- 0.0241982359F, 0.0243468015F, 0.0244958141F, 0.0246452736F,
- 0.0247951800F, 0.0249455331F, 0.0250963329F, 0.0252475792F,
- 0.0253992720F, 0.0255514111F, 0.0257039965F, 0.0258570281F,
- 0.0260105057F, 0.0261644293F, 0.0263187987F, 0.0264736139F,
- 0.0266288747F, 0.0267845811F, 0.0269407330F, 0.0270973302F,
- 0.0272543727F, 0.0274118604F, 0.0275697930F, 0.0277281707F,
- 0.0278869932F, 0.0280462604F, 0.0282059723F, 0.0283661287F,
- 0.0285267295F, 0.0286877747F, 0.0288492641F, 0.0290111976F,
- 0.0291735751F, 0.0293363965F, 0.0294996617F, 0.0296633706F,
- 0.0298275231F, 0.0299921190F, 0.0301571583F, 0.0303226409F,
- 0.0304885667F, 0.0306549354F, 0.0308217472F, 0.0309890017F,
- 0.0311566989F, 0.0313248388F, 0.0314934211F, 0.0316624459F,
- 0.0318319128F, 0.0320018220F, 0.0321721732F, 0.0323429663F,
- 0.0325142013F, 0.0326858779F, 0.0328579962F, 0.0330305559F,
- 0.0332035570F, 0.0333769994F, 0.0335508829F, 0.0337252074F,
- 0.0338999728F, 0.0340751790F, 0.0342508259F, 0.0344269134F,
- 0.0346034412F, 0.0347804094F, 0.0349578178F, 0.0351356663F,
- 0.0353139548F, 0.0354926831F, 0.0356718511F, 0.0358514588F,
- 0.0360315059F, 0.0362119924F, 0.0363929182F, 0.0365742831F,
- 0.0367560870F, 0.0369383297F, 0.0371210113F, 0.0373041315F,
- 0.0374876902F, 0.0376716873F, 0.0378561226F, 0.0380409961F,
- 0.0382263077F, 0.0384120571F, 0.0385982443F, 0.0387848691F,
- 0.0389719315F, 0.0391594313F, 0.0393473683F, 0.0395357425F,
- 0.0397245537F, 0.0399138017F, 0.0401034866F, 0.0402936080F,
- 0.0404841660F, 0.0406751603F, 0.0408665909F, 0.0410584576F,
- 0.0412507603F, 0.0414434988F, 0.0416366731F, 0.0418302829F,
- 0.0420243282F, 0.0422188088F, 0.0424137246F, 0.0426090755F,
- 0.0428048613F, 0.0430010819F, 0.0431977371F, 0.0433948269F,
- 0.0435923511F, 0.0437903095F, 0.0439887020F, 0.0441875285F,
- 0.0443867889F, 0.0445864830F, 0.0447866106F, 0.0449871717F,
- 0.0451881661F, 0.0453895936F, 0.0455914542F, 0.0457937477F,
- 0.0459964738F, 0.0461996326F, 0.0464032239F, 0.0466072475F,
- 0.0468117032F, 0.0470165910F, 0.0472219107F, 0.0474276622F,
- 0.0476338452F, 0.0478404597F, 0.0480475056F, 0.0482549827F,
- 0.0484628907F, 0.0486712297F, 0.0488799994F, 0.0490891998F,
- 0.0492988306F, 0.0495088917F, 0.0497193830F, 0.0499303043F,
- 0.0501416554F, 0.0503534363F, 0.0505656468F, 0.0507782867F,
- 0.0509913559F, 0.0512048542F, 0.0514187815F, 0.0516331376F,
- 0.0518479225F, 0.0520631358F, 0.0522787775F, 0.0524948475F,
- 0.0527113455F, 0.0529282715F, 0.0531456252F, 0.0533634066F,
- 0.0535816154F, 0.0538002515F, 0.0540193148F, 0.0542388051F,
- 0.0544587222F, 0.0546790660F, 0.0548998364F, 0.0551210331F,
- 0.0553426561F, 0.0555647051F, 0.0557871801F, 0.0560100807F,
- 0.0562334070F, 0.0564571587F, 0.0566813357F, 0.0569059378F,
- 0.0571309649F, 0.0573564168F, 0.0575822933F, 0.0578085942F,
- 0.0580353195F, 0.0582624689F, 0.0584900423F, 0.0587180396F,
- 0.0589464605F, 0.0591753049F, 0.0594045726F, 0.0596342635F,
- 0.0598643774F, 0.0600949141F, 0.0603258735F, 0.0605572555F,
- 0.0607890597F, 0.0610212862F, 0.0612539346F, 0.0614870049F,
- 0.0617204968F, 0.0619544103F, 0.0621887451F, 0.0624235010F,
- 0.0626586780F, 0.0628942758F, 0.0631302942F, 0.0633667331F,
- 0.0636035923F, 0.0638408717F, 0.0640785710F, 0.0643166901F,
- 0.0645552288F, 0.0647941870F, 0.0650335645F, 0.0652733610F,
- 0.0655135765F, 0.0657542108F, 0.0659952636F, 0.0662367348F,
- 0.0664786242F, 0.0667209316F, 0.0669636570F, 0.0672068000F,
- 0.0674503605F, 0.0676943384F, 0.0679387334F, 0.0681835454F,
- 0.0684287742F, 0.0686744196F, 0.0689204814F, 0.0691669595F,
- 0.0694138536F, 0.0696611637F, 0.0699088894F, 0.0701570307F,
- 0.0704055873F, 0.0706545590F, 0.0709039458F, 0.0711537473F,
- 0.0714039634F, 0.0716545939F, 0.0719056387F, 0.0721570975F,
- 0.0724089702F, 0.0726612565F, 0.0729139563F, 0.0731670694F,
- 0.0734205956F, 0.0736745347F, 0.0739288866F, 0.0741836510F,
- 0.0744388277F, 0.0746944166F, 0.0749504175F, 0.0752068301F,
- 0.0754636543F, 0.0757208899F, 0.0759785367F, 0.0762365946F,
- 0.0764950632F, 0.0767539424F, 0.0770132320F, 0.0772729319F,
- 0.0775330418F, 0.0777935616F, 0.0780544909F, 0.0783158298F,
- 0.0785775778F, 0.0788397349F, 0.0791023009F, 0.0793652755F,
- 0.0796286585F, 0.0798924498F, 0.0801566492F, 0.0804212564F,
- 0.0806862712F, 0.0809516935F, 0.0812175231F, 0.0814837597F,
- 0.0817504031F, 0.0820174532F, 0.0822849097F, 0.0825527724F,
- 0.0828210412F, 0.0830897158F, 0.0833587960F, 0.0836282816F,
- 0.0838981724F, 0.0841684682F, 0.0844391688F, 0.0847102740F,
- 0.0849817835F, 0.0852536973F, 0.0855260150F, 0.0857987364F,
- 0.0860718614F, 0.0863453897F, 0.0866193211F, 0.0868936554F,
- 0.0871683924F, 0.0874435319F, 0.0877190737F, 0.0879950175F,
- 0.0882713632F, 0.0885481105F, 0.0888252592F, 0.0891028091F,
- 0.0893807600F, 0.0896591117F, 0.0899378639F, 0.0902170165F,
- 0.0904965692F, 0.0907765218F, 0.0910568740F, 0.0913376258F,
- 0.0916187767F, 0.0919003268F, 0.0921822756F, 0.0924646230F,
- 0.0927473687F, 0.0930305126F, 0.0933140545F, 0.0935979940F,
- 0.0938823310F, 0.0941670653F, 0.0944521966F, 0.0947377247F,
- 0.0950236494F, 0.0953099704F, 0.0955966876F, 0.0958838007F,
- 0.0961713094F, 0.0964592136F, 0.0967475131F, 0.0970362075F,
- 0.0973252967F, 0.0976147805F, 0.0979046585F, 0.0981949307F,
- 0.0984855967F, 0.0987766563F, 0.0990681093F, 0.0993599555F,
- 0.0996521945F, 0.0999448263F, 0.1002378506F, 0.1005312671F,
- 0.1008250755F, 0.1011192757F, 0.1014138675F, 0.1017088505F,
- 0.1020042246F, 0.1022999895F, 0.1025961450F, 0.1028926909F,
- 0.1031896268F, 0.1034869526F, 0.1037846680F, 0.1040827729F,
- 0.1043812668F, 0.1046801497F, 0.1049794213F, 0.1052790813F,
- 0.1055791294F, 0.1058795656F, 0.1061803894F, 0.1064816006F,
- 0.1067831991F, 0.1070851846F, 0.1073875568F, 0.1076903155F,
- 0.1079934604F, 0.1082969913F, 0.1086009079F, 0.1089052101F,
- 0.1092098975F, 0.1095149699F, 0.1098204270F, 0.1101262687F,
- 0.1104324946F, 0.1107391045F, 0.1110460982F, 0.1113534754F,
- 0.1116612359F, 0.1119693793F, 0.1122779055F, 0.1125868142F,
- 0.1128961052F, 0.1132057781F, 0.1135158328F, 0.1138262690F,
- 0.1141370863F, 0.1144482847F, 0.1147598638F, 0.1150718233F,
- 0.1153841631F, 0.1156968828F, 0.1160099822F, 0.1163234610F,
- 0.1166373190F, 0.1169515559F, 0.1172661714F, 0.1175811654F,
- 0.1178965374F, 0.1182122874F, 0.1185284149F, 0.1188449198F,
- 0.1191618018F, 0.1194790606F, 0.1197966960F, 0.1201147076F,
- 0.1204330953F, 0.1207518587F, 0.1210709976F, 0.1213905118F,
- 0.1217104009F, 0.1220306647F, 0.1223513029F, 0.1226723153F,
- 0.1229937016F, 0.1233154615F, 0.1236375948F, 0.1239601011F,
- 0.1242829803F, 0.1246062319F, 0.1249298559F, 0.1252538518F,
- 0.1255782195F, 0.1259029586F, 0.1262280689F, 0.1265535501F,
- 0.1268794019F, 0.1272056241F, 0.1275322163F, 0.1278591784F,
- 0.1281865099F, 0.1285142108F, 0.1288422805F, 0.1291707190F,
- 0.1294995259F, 0.1298287009F, 0.1301582437F, 0.1304881542F,
- 0.1308184319F, 0.1311490766F, 0.1314800881F, 0.1318114660F,
- 0.1321432100F, 0.1324753200F, 0.1328077955F, 0.1331406364F,
- 0.1334738422F, 0.1338074129F, 0.1341413479F, 0.1344756472F,
- 0.1348103103F, 0.1351453370F, 0.1354807270F, 0.1358164801F,
- 0.1361525959F, 0.1364890741F, 0.1368259145F, 0.1371631167F,
- 0.1375006805F, 0.1378386056F, 0.1381768917F, 0.1385155384F,
- 0.1388545456F, 0.1391939129F, 0.1395336400F, 0.1398737266F,
- 0.1402141724F, 0.1405549772F, 0.1408961406F, 0.1412376623F,
- 0.1415795421F, 0.1419217797F, 0.1422643746F, 0.1426073268F,
- 0.1429506358F, 0.1432943013F, 0.1436383231F, 0.1439827008F,
- 0.1443274342F, 0.1446725229F, 0.1450179667F, 0.1453637652F,
- 0.1457099181F, 0.1460564252F, 0.1464032861F, 0.1467505006F,
- 0.1470980682F, 0.1474459888F, 0.1477942620F, 0.1481428875F,
- 0.1484918651F, 0.1488411942F, 0.1491908748F, 0.1495409065F,
- 0.1498912889F, 0.1502420218F, 0.1505931048F, 0.1509445376F,
- 0.1512963200F, 0.1516484516F, 0.1520009321F, 0.1523537612F,
- 0.1527069385F, 0.1530604638F, 0.1534143368F, 0.1537685571F,
- 0.1541231244F, 0.1544780384F, 0.1548332987F, 0.1551889052F,
- 0.1555448574F, 0.1559011550F, 0.1562577978F, 0.1566147853F,
- 0.1569721173F, 0.1573297935F, 0.1576878135F, 0.1580461771F,
- 0.1584048838F, 0.1587639334F, 0.1591233255F, 0.1594830599F,
- 0.1598431361F, 0.1602035540F, 0.1605643131F, 0.1609254131F,
- 0.1612868537F, 0.1616486346F, 0.1620107555F, 0.1623732160F,
- 0.1627360158F, 0.1630991545F, 0.1634626319F, 0.1638264476F,
- 0.1641906013F, 0.1645550926F, 0.1649199212F, 0.1652850869F,
- 0.1656505892F, 0.1660164278F, 0.1663826024F, 0.1667491127F,
- 0.1671159583F, 0.1674831388F, 0.1678506541F, 0.1682185036F,
- 0.1685866872F, 0.1689552044F, 0.1693240549F, 0.1696932384F,
- 0.1700627545F, 0.1704326029F, 0.1708027833F, 0.1711732952F,
- 0.1715441385F, 0.1719153127F, 0.1722868175F, 0.1726586526F,
- 0.1730308176F, 0.1734033121F, 0.1737761359F, 0.1741492886F,
- 0.1745227698F, 0.1748965792F, 0.1752707164F, 0.1756451812F,
- 0.1760199731F, 0.1763950918F, 0.1767705370F, 0.1771463083F,
- 0.1775224054F, 0.1778988279F, 0.1782755754F, 0.1786526477F,
- 0.1790300444F, 0.1794077651F, 0.1797858094F, 0.1801641771F,
- 0.1805428677F, 0.1809218810F, 0.1813012165F, 0.1816808739F,
- 0.1820608528F, 0.1824411530F, 0.1828217739F, 0.1832027154F,
- 0.1835839770F, 0.1839655584F, 0.1843474592F, 0.1847296790F,
- 0.1851122175F, 0.1854950744F, 0.1858782492F, 0.1862617417F,
- 0.1866455514F, 0.1870296780F, 0.1874141211F, 0.1877988804F,
- 0.1881839555F, 0.1885693461F, 0.1889550517F, 0.1893410721F,
- 0.1897274068F, 0.1901140555F, 0.1905010178F, 0.1908882933F,
- 0.1912758818F, 0.1916637828F, 0.1920519959F, 0.1924405208F,
- 0.1928293571F, 0.1932185044F, 0.1936079625F, 0.1939977308F,
- 0.1943878091F, 0.1947781969F, 0.1951688939F, 0.1955598998F,
- 0.1959512141F, 0.1963428364F, 0.1967347665F, 0.1971270038F,
- 0.1975195482F, 0.1979123990F, 0.1983055561F, 0.1986990190F,
- 0.1990927873F, 0.1994868607F, 0.1998812388F, 0.2002759212F,
- 0.2006709075F, 0.2010661974F, 0.2014617904F, 0.2018576862F,
- 0.2022538844F, 0.2026503847F, 0.2030471865F, 0.2034442897F,
- 0.2038416937F, 0.2042393982F, 0.2046374028F, 0.2050357071F,
- 0.2054343107F, 0.2058332133F, 0.2062324145F, 0.2066319138F,
- 0.2070317110F, 0.2074318055F, 0.2078321970F, 0.2082328852F,
- 0.2086338696F, 0.2090351498F, 0.2094367255F, 0.2098385962F,
- 0.2102407617F, 0.2106432213F, 0.2110459749F, 0.2114490220F,
- 0.2118523621F, 0.2122559950F, 0.2126599202F, 0.2130641373F,
- 0.2134686459F, 0.2138734456F, 0.2142785361F, 0.2146839168F,
- 0.2150895875F, 0.2154955478F, 0.2159017972F, 0.2163083353F,
- 0.2167151617F, 0.2171222761F, 0.2175296780F, 0.2179373670F,
- 0.2183453428F, 0.2187536049F, 0.2191621529F, 0.2195709864F,
- 0.2199801051F, 0.2203895085F, 0.2207991961F, 0.2212091677F,
- 0.2216194228F, 0.2220299610F, 0.2224407818F, 0.2228518850F,
- 0.2232632699F, 0.2236749364F, 0.2240868839F, 0.2244991121F,
- 0.2249116204F, 0.2253244086F, 0.2257374763F, 0.2261508229F,
- 0.2265644481F, 0.2269783514F, 0.2273925326F, 0.2278069911F,
- 0.2282217265F, 0.2286367384F, 0.2290520265F, 0.2294675902F,
- 0.2298834292F, 0.2302995431F, 0.2307159314F, 0.2311325937F,
- 0.2315495297F, 0.2319667388F, 0.2323842207F, 0.2328019749F,
- 0.2332200011F, 0.2336382988F, 0.2340568675F, 0.2344757070F,
- 0.2348948166F, 0.2353141961F, 0.2357338450F, 0.2361537629F,
- 0.2365739493F, 0.2369944038F, 0.2374151261F, 0.2378361156F,
- 0.2382573720F, 0.2386788948F, 0.2391006836F, 0.2395227380F,
- 0.2399450575F, 0.2403676417F, 0.2407904902F, 0.2412136026F,
- 0.2416369783F, 0.2420606171F, 0.2424845185F, 0.2429086820F,
- 0.2433331072F, 0.2437577936F, 0.2441827409F, 0.2446079486F,
- 0.2450334163F, 0.2454591435F, 0.2458851298F, 0.2463113747F,
- 0.2467378779F, 0.2471646389F, 0.2475916573F, 0.2480189325F,
- 0.2484464643F, 0.2488742521F, 0.2493022955F, 0.2497305940F,
- 0.2501591473F, 0.2505879549F, 0.2510170163F, 0.2514463311F,
- 0.2518758989F, 0.2523057193F, 0.2527357916F, 0.2531661157F,
- 0.2535966909F, 0.2540275169F, 0.2544585931F, 0.2548899193F,
- 0.2553214948F, 0.2557533193F, 0.2561853924F, 0.2566177135F,
- 0.2570502822F, 0.2574830981F, 0.2579161608F, 0.2583494697F,
- 0.2587830245F, 0.2592168246F, 0.2596508697F, 0.2600851593F,
- 0.2605196929F, 0.2609544701F, 0.2613894904F, 0.2618247534F,
- 0.2622602586F, 0.2626960055F, 0.2631319938F, 0.2635682230F,
- 0.2640046925F, 0.2644414021F, 0.2648783511F, 0.2653155391F,
- 0.2657529657F, 0.2661906305F, 0.2666285329F, 0.2670666725F,
- 0.2675050489F, 0.2679436616F, 0.2683825101F, 0.2688215940F,
- 0.2692609127F, 0.2697004660F, 0.2701402532F, 0.2705802739F,
- 0.2710205278F, 0.2714610142F, 0.2719017327F, 0.2723426830F,
- 0.2727838644F, 0.2732252766F, 0.2736669191F, 0.2741087914F,
- 0.2745508930F, 0.2749932235F, 0.2754357824F, 0.2758785693F,
- 0.2763215837F, 0.2767648251F, 0.2772082930F, 0.2776519870F,
- 0.2780959066F, 0.2785400513F, 0.2789844207F, 0.2794290143F,
- 0.2798738316F, 0.2803188722F, 0.2807641355F, 0.2812096211F,
- 0.2816553286F, 0.2821012574F, 0.2825474071F, 0.2829937773F,
- 0.2834403673F, 0.2838871768F, 0.2843342053F, 0.2847814523F,
- 0.2852289174F, 0.2856765999F, 0.2861244996F, 0.2865726159F,
- 0.2870209482F, 0.2874694962F, 0.2879182594F, 0.2883672372F,
- 0.2888164293F, 0.2892658350F, 0.2897154540F, 0.2901652858F,
- 0.2906153298F, 0.2910655856F, 0.2915160527F, 0.2919667306F,
- 0.2924176189F, 0.2928687171F, 0.2933200246F, 0.2937715409F,
- 0.2942232657F, 0.2946751984F, 0.2951273386F, 0.2955796856F,
- 0.2960322391F, 0.2964849986F, 0.2969379636F, 0.2973911335F,
- 0.2978445080F, 0.2982980864F, 0.2987518684F, 0.2992058534F,
- 0.2996600409F, 0.3001144305F, 0.3005690217F, 0.3010238139F,
- 0.3014788067F, 0.3019339995F, 0.3023893920F, 0.3028449835F,
- 0.3033007736F, 0.3037567618F, 0.3042129477F, 0.3046693306F,
- 0.3051259102F, 0.3055826859F, 0.3060396572F, 0.3064968236F,
- 0.3069541847F, 0.3074117399F, 0.3078694887F, 0.3083274307F,
- 0.3087855653F, 0.3092438920F, 0.3097024104F, 0.3101611199F,
- 0.3106200200F, 0.3110791103F, 0.3115383902F, 0.3119978592F,
- 0.3124575169F, 0.3129173627F, 0.3133773961F, 0.3138376166F,
- 0.3142980238F, 0.3147586170F, 0.3152193959F, 0.3156803598F,
- 0.3161415084F, 0.3166028410F, 0.3170643573F, 0.3175260566F,
- 0.3179879384F, 0.3184500023F, 0.3189122478F, 0.3193746743F,
- 0.3198372814F, 0.3203000685F, 0.3207630351F, 0.3212261807F,
- 0.3216895048F, 0.3221530069F, 0.3226166865F, 0.3230805430F,
- 0.3235445760F, 0.3240087849F, 0.3244731693F, 0.3249377285F,
- 0.3254024622F, 0.3258673698F, 0.3263324507F, 0.3267977045F,
- 0.3272631306F, 0.3277287286F, 0.3281944978F, 0.3286604379F,
- 0.3291265482F, 0.3295928284F, 0.3300592777F, 0.3305258958F,
- 0.3309926821F, 0.3314596361F, 0.3319267573F, 0.3323940451F,
- 0.3328614990F, 0.3333291186F, 0.3337969033F, 0.3342648525F,
- 0.3347329658F, 0.3352012427F, 0.3356696825F, 0.3361382849F,
- 0.3366070492F, 0.3370759749F, 0.3375450616F, 0.3380143087F,
- 0.3384837156F, 0.3389532819F, 0.3394230071F, 0.3398928905F,
- 0.3403629317F, 0.3408331302F, 0.3413034854F, 0.3417739967F,
- 0.3422446638F, 0.3427154860F, 0.3431864628F, 0.3436575938F,
- 0.3441288782F, 0.3446003158F, 0.3450719058F, 0.3455436478F,
- 0.3460155412F, 0.3464875856F, 0.3469597804F, 0.3474321250F,
- 0.3479046189F, 0.3483772617F, 0.3488500527F, 0.3493229914F,
- 0.3497960774F, 0.3502693100F, 0.3507426887F, 0.3512162131F,
- 0.3516898825F, 0.3521636965F, 0.3526376545F, 0.3531117559F,
- 0.3535860003F, 0.3540603870F, 0.3545349157F, 0.3550095856F,
- 0.3554843964F, 0.3559593474F, 0.3564344381F, 0.3569096680F,
- 0.3573850366F, 0.3578605432F, 0.3583361875F, 0.3588119687F,
- 0.3592878865F, 0.3597639402F, 0.3602401293F, 0.3607164533F,
- 0.3611929117F, 0.3616695038F, 0.3621462292F, 0.3626230873F,
- 0.3631000776F, 0.3635771995F, 0.3640544525F, 0.3645318360F,
- 0.3650093496F, 0.3654869926F, 0.3659647645F, 0.3664426648F,
- 0.3669206930F, 0.3673988484F, 0.3678771306F, 0.3683555390F,
- 0.3688340731F, 0.3693127322F, 0.3697915160F, 0.3702704237F,
- 0.3707494549F, 0.3712286091F, 0.3717078857F, 0.3721872840F,
- 0.3726668037F, 0.3731464441F, 0.3736262047F, 0.3741060850F,
- 0.3745860843F, 0.3750662023F, 0.3755464382F, 0.3760267915F,
- 0.3765072618F, 0.3769878484F, 0.3774685509F, 0.3779493686F,
- 0.3784303010F, 0.3789113475F, 0.3793925076F, 0.3798737809F,
- 0.3803551666F, 0.3808366642F, 0.3813182733F, 0.3817999932F,
- 0.3822818234F, 0.3827637633F, 0.3832458124F, 0.3837279702F,
- 0.3842102360F, 0.3846926093F, 0.3851750897F, 0.3856576764F,
- 0.3861403690F, 0.3866231670F, 0.3871060696F, 0.3875890765F,
- 0.3880721870F, 0.3885554007F, 0.3890387168F, 0.3895221349F,
- 0.3900056544F, 0.3904892748F, 0.3909729955F, 0.3914568160F,
- 0.3919407356F, 0.3924247539F, 0.3929088702F, 0.3933930841F,
- 0.3938773949F, 0.3943618021F, 0.3948463052F, 0.3953309035F,
- 0.3958155966F, 0.3963003838F, 0.3967852646F, 0.3972702385F,
- 0.3977553048F, 0.3982404631F, 0.3987257127F, 0.3992110531F,
- 0.3996964838F, 0.4001820041F, 0.4006676136F, 0.4011533116F,
- 0.4016390976F, 0.4021249710F, 0.4026109313F, 0.4030969779F,
- 0.4035831102F, 0.4040693277F, 0.4045556299F, 0.4050420160F,
- 0.4055284857F, 0.4060150383F, 0.4065016732F, 0.4069883899F,
- 0.4074751879F, 0.4079620665F, 0.4084490252F, 0.4089360635F,
- 0.4094231807F, 0.4099103763F, 0.4103976498F, 0.4108850005F,
- 0.4113724280F, 0.4118599315F, 0.4123475107F, 0.4128351648F,
- 0.4133228934F, 0.4138106959F, 0.4142985716F, 0.4147865201F,
- 0.4152745408F, 0.4157626330F, 0.4162507963F, 0.4167390301F,
- 0.4172273337F, 0.4177157067F, 0.4182041484F, 0.4186926583F,
- 0.4191812359F, 0.4196698805F, 0.4201585915F, 0.4206473685F,
- 0.4211362108F, 0.4216251179F, 0.4221140892F, 0.4226031241F,
- 0.4230922221F, 0.4235813826F, 0.4240706050F, 0.4245598887F,
- 0.4250492332F, 0.4255386379F, 0.4260281022F, 0.4265176256F,
- 0.4270072075F, 0.4274968473F, 0.4279865445F, 0.4284762984F,
- 0.4289661086F, 0.4294559743F, 0.4299458951F, 0.4304358704F,
- 0.4309258996F, 0.4314159822F, 0.4319061175F, 0.4323963050F,
- 0.4328865441F, 0.4333768342F, 0.4338671749F, 0.4343575654F,
- 0.4348480052F, 0.4353384938F, 0.4358290306F, 0.4363196149F,
- 0.4368102463F, 0.4373009241F, 0.4377916478F, 0.4382824168F,
- 0.4387732305F, 0.4392640884F, 0.4397549899F, 0.4402459343F,
- 0.4407369212F, 0.4412279499F, 0.4417190198F, 0.4422101305F,
- 0.4427012813F, 0.4431924717F, 0.4436837010F, 0.4441749686F,
- 0.4446662742F, 0.4451576169F, 0.4456489963F, 0.4461404118F,
- 0.4466318628F, 0.4471233487F, 0.4476148690F, 0.4481064230F,
- 0.4485980103F, 0.4490896302F, 0.4495812821F, 0.4500729654F,
- 0.4505646797F, 0.4510564243F, 0.4515481986F, 0.4520400021F,
- 0.4525318341F, 0.4530236942F, 0.4535155816F, 0.4540074959F,
- 0.4544994365F, 0.4549914028F, 0.4554833941F, 0.4559754100F,
- 0.4564674499F, 0.4569595131F, 0.4574515991F, 0.4579437074F,
- 0.4584358372F, 0.4589279881F, 0.4594201595F, 0.4599123508F,
- 0.4604045615F, 0.4608967908F, 0.4613890383F, 0.4618813034F,
- 0.4623735855F, 0.4628658841F, 0.4633581984F, 0.4638505281F,
- 0.4643428724F, 0.4648352308F, 0.4653276028F, 0.4658199877F,
- 0.4663123849F, 0.4668047940F, 0.4672972143F, 0.4677896451F,
- 0.4682820861F, 0.4687745365F, 0.4692669958F, 0.4697594634F,
- 0.4702519387F, 0.4707444211F, 0.4712369102F, 0.4717294052F,
- 0.4722219056F, 0.4727144109F, 0.4732069204F, 0.4736994336F,
- 0.4741919498F, 0.4746844686F, 0.4751769893F, 0.4756695113F,
- 0.4761620341F, 0.4766545571F, 0.4771470797F, 0.4776396013F,
- 0.4781321213F, 0.4786246392F, 0.4791171544F, 0.4796096663F,
- 0.4801021744F, 0.4805946779F, 0.4810871765F, 0.4815796694F,
- 0.4820721561F, 0.4825646360F, 0.4830571086F, 0.4835495732F,
- 0.4840420293F, 0.4845344763F, 0.4850269136F, 0.4855193407F,
- 0.4860117569F, 0.4865041617F, 0.4869965545F, 0.4874889347F,
- 0.4879813018F, 0.4884736551F, 0.4889659941F, 0.4894583182F,
- 0.4899506268F, 0.4904429193F, 0.4909351952F, 0.4914274538F,
- 0.4919196947F, 0.4924119172F, 0.4929041207F, 0.4933963046F,
- 0.4938884685F, 0.4943806116F, 0.4948727335F, 0.4953648335F,
- 0.4958569110F, 0.4963489656F, 0.4968409965F, 0.4973330032F,
- 0.4978249852F, 0.4983169419F, 0.4988088726F, 0.4993007768F,
- 0.4997926539F, 0.5002845034F, 0.5007763247F, 0.5012681171F,
- 0.5017598801F, 0.5022516132F, 0.5027433157F, 0.5032349871F,
- 0.5037266268F, 0.5042182341F, 0.5047098086F, 0.5052013497F,
- 0.5056928567F, 0.5061843292F, 0.5066757664F, 0.5071671679F,
- 0.5076585330F, 0.5081498613F, 0.5086411520F, 0.5091324047F,
- 0.5096236187F, 0.5101147934F, 0.5106059284F, 0.5110970230F,
- 0.5115880766F, 0.5120790887F, 0.5125700587F, 0.5130609860F,
- 0.5135518700F, 0.5140427102F, 0.5145335059F, 0.5150242566F,
- 0.5155149618F, 0.5160056208F, 0.5164962331F, 0.5169867980F,
- 0.5174773151F, 0.5179677837F, 0.5184582033F, 0.5189485733F,
- 0.5194388931F, 0.5199291621F, 0.5204193798F, 0.5209095455F,
- 0.5213996588F, 0.5218897190F, 0.5223797256F, 0.5228696779F,
- 0.5233595755F, 0.5238494177F, 0.5243392039F, 0.5248289337F,
- 0.5253186063F, 0.5258082213F, 0.5262977781F, 0.5267872760F,
- 0.5272767146F, 0.5277660932F, 0.5282554112F, 0.5287446682F,
- 0.5292338635F, 0.5297229965F, 0.5302120667F, 0.5307010736F,
- 0.5311900164F, 0.5316788947F, 0.5321677079F, 0.5326564554F,
- 0.5331451366F, 0.5336337511F, 0.5341222981F, 0.5346107771F,
- 0.5350991876F, 0.5355875290F, 0.5360758007F, 0.5365640021F,
- 0.5370521327F, 0.5375401920F, 0.5380281792F, 0.5385160939F,
- 0.5390039355F, 0.5394917034F, 0.5399793971F, 0.5404670159F,
- 0.5409545594F, 0.5414420269F, 0.5419294179F, 0.5424167318F,
- 0.5429039680F, 0.5433911261F, 0.5438782053F, 0.5443652051F,
- 0.5448521250F, 0.5453389644F, 0.5458257228F, 0.5463123995F,
- 0.5467989940F, 0.5472855057F, 0.5477719341F, 0.5482582786F,
- 0.5487445387F, 0.5492307137F, 0.5497168031F, 0.5502028063F,
- 0.5506887228F, 0.5511745520F, 0.5516602934F, 0.5521459463F,
- 0.5526315103F, 0.5531169847F, 0.5536023690F, 0.5540876626F,
- 0.5545728649F, 0.5550579755F, 0.5555429937F, 0.5560279189F,
- 0.5565127507F, 0.5569974884F, 0.5574821315F, 0.5579666794F,
- 0.5584511316F, 0.5589354875F, 0.5594197465F, 0.5599039080F,
- 0.5603879716F, 0.5608719367F, 0.5613558026F, 0.5618395689F,
- 0.5623232350F, 0.5628068002F, 0.5632902642F, 0.5637736262F,
- 0.5642568858F, 0.5647400423F, 0.5652230953F, 0.5657060442F,
- 0.5661888883F, 0.5666716272F, 0.5671542603F, 0.5676367870F,
- 0.5681192069F, 0.5686015192F, 0.5690837235F, 0.5695658192F,
- 0.5700478058F, 0.5705296827F, 0.5710114494F, 0.5714931052F,
- 0.5719746497F, 0.5724560822F, 0.5729374023F, 0.5734186094F,
- 0.5738997029F, 0.5743806823F, 0.5748615470F, 0.5753422965F,
- 0.5758229301F, 0.5763034475F, 0.5767838480F, 0.5772641310F,
- 0.5777442960F, 0.5782243426F, 0.5787042700F, 0.5791840778F,
- 0.5796637654F, 0.5801433322F, 0.5806227778F, 0.5811021016F,
- 0.5815813029F, 0.5820603814F, 0.5825393363F, 0.5830181673F,
- 0.5834968737F, 0.5839754549F, 0.5844539105F, 0.5849322399F,
- 0.5854104425F, 0.5858885179F, 0.5863664653F, 0.5868442844F,
- 0.5873219746F, 0.5877995353F, 0.5882769660F, 0.5887542661F,
- 0.5892314351F, 0.5897084724F, 0.5901853776F, 0.5906621500F,
- 0.5911387892F, 0.5916152945F, 0.5920916655F, 0.5925679016F,
- 0.5930440022F, 0.5935199669F, 0.5939957950F, 0.5944714861F,
- 0.5949470396F, 0.5954224550F, 0.5958977317F, 0.5963728692F,
- 0.5968478669F, 0.5973227244F, 0.5977974411F, 0.5982720163F,
- 0.5987464497F, 0.5992207407F, 0.5996948887F, 0.6001688932F,
- 0.6006427537F, 0.6011164696F, 0.6015900405F, 0.6020634657F,
- 0.6025367447F, 0.6030098770F, 0.6034828621F, 0.6039556995F,
- 0.6044283885F, 0.6049009288F, 0.6053733196F, 0.6058455606F,
- 0.6063176512F, 0.6067895909F, 0.6072613790F, 0.6077330152F,
- 0.6082044989F, 0.6086758295F, 0.6091470065F, 0.6096180294F,
- 0.6100888977F, 0.6105596108F, 0.6110301682F, 0.6115005694F,
- 0.6119708139F, 0.6124409011F, 0.6129108305F, 0.6133806017F,
- 0.6138502139F, 0.6143196669F, 0.6147889599F, 0.6152580926F,
- 0.6157270643F, 0.6161958746F, 0.6166645230F, 0.6171330088F,
- 0.6176013317F, 0.6180694910F, 0.6185374863F, 0.6190053171F,
- 0.6194729827F, 0.6199404828F, 0.6204078167F, 0.6208749841F,
- 0.6213419842F, 0.6218088168F, 0.6222754811F, 0.6227419768F,
- 0.6232083032F, 0.6236744600F, 0.6241404465F, 0.6246062622F,
- 0.6250719067F, 0.6255373795F, 0.6260026799F, 0.6264678076F,
- 0.6269327619F, 0.6273975425F, 0.6278621487F, 0.6283265800F,
- 0.6287908361F, 0.6292549163F, 0.6297188201F, 0.6301825471F,
- 0.6306460966F, 0.6311094683F, 0.6315726617F, 0.6320356761F,
- 0.6324985111F, 0.6329611662F, 0.6334236410F, 0.6338859348F,
- 0.6343480472F, 0.6348099777F, 0.6352717257F, 0.6357332909F,
- 0.6361946726F, 0.6366558704F, 0.6371168837F, 0.6375777122F,
- 0.6380383552F, 0.6384988123F, 0.6389590830F, 0.6394191668F,
- 0.6398790631F, 0.6403387716F, 0.6407982916F, 0.6412576228F,
- 0.6417167645F, 0.6421757163F, 0.6426344778F, 0.6430930483F,
- 0.6435514275F, 0.6440096149F, 0.6444676098F, 0.6449254119F,
- 0.6453830207F, 0.6458404356F, 0.6462976562F, 0.6467546820F,
- 0.6472115125F, 0.6476681472F, 0.6481245856F, 0.6485808273F,
- 0.6490368717F, 0.6494927183F, 0.6499483667F, 0.6504038164F,
- 0.6508590670F, 0.6513141178F, 0.6517689684F, 0.6522236185F,
- 0.6526780673F, 0.6531323146F, 0.6535863598F, 0.6540402024F,
- 0.6544938419F, 0.6549472779F, 0.6554005099F, 0.6558535373F,
- 0.6563063598F, 0.6567589769F, 0.6572113880F, 0.6576635927F,
- 0.6581155906F, 0.6585673810F, 0.6590189637F, 0.6594703380F,
- 0.6599215035F, 0.6603724598F, 0.6608232064F, 0.6612737427F,
- 0.6617240684F, 0.6621741829F, 0.6626240859F, 0.6630737767F,
- 0.6635232550F, 0.6639725202F, 0.6644215720F, 0.6648704098F,
- 0.6653190332F, 0.6657674417F, 0.6662156348F, 0.6666636121F,
- 0.6671113731F, 0.6675589174F, 0.6680062445F, 0.6684533538F,
- 0.6689002450F, 0.6693469177F, 0.6697933712F, 0.6702396052F,
- 0.6706856193F, 0.6711314129F, 0.6715769855F, 0.6720223369F,
- 0.6724674664F, 0.6729123736F, 0.6733570581F, 0.6738015194F,
- 0.6742457570F, 0.6746897706F, 0.6751335596F, 0.6755771236F,
- 0.6760204621F, 0.6764635747F, 0.6769064609F, 0.6773491204F,
- 0.6777915525F, 0.6782337570F, 0.6786757332F, 0.6791174809F,
- 0.6795589995F, 0.6800002886F, 0.6804413477F, 0.6808821765F,
- 0.6813227743F, 0.6817631409F, 0.6822032758F, 0.6826431785F,
- 0.6830828485F, 0.6835222855F, 0.6839614890F, 0.6844004585F,
- 0.6848391936F, 0.6852776939F, 0.6857159589F, 0.6861539883F,
- 0.6865917815F, 0.6870293381F, 0.6874666576F, 0.6879037398F,
- 0.6883405840F, 0.6887771899F, 0.6892135571F, 0.6896496850F,
- 0.6900855733F, 0.6905212216F, 0.6909566294F, 0.6913917963F,
- 0.6918267218F, 0.6922614055F, 0.6926958471F, 0.6931300459F,
- 0.6935640018F, 0.6939977141F, 0.6944311825F, 0.6948644066F,
- 0.6952973859F, 0.6957301200F, 0.6961626085F, 0.6965948510F,
- 0.6970268470F, 0.6974585961F, 0.6978900980F, 0.6983213521F,
- 0.6987523580F, 0.6991831154F, 0.6996136238F, 0.7000438828F,
- 0.7004738921F, 0.7009036510F, 0.7013331594F, 0.7017624166F,
- 0.7021914224F, 0.7026201763F, 0.7030486779F, 0.7034769268F,
- 0.7039049226F, 0.7043326648F, 0.7047601531F, 0.7051873870F,
- 0.7056143662F, 0.7060410902F, 0.7064675586F, 0.7068937711F,
- 0.7073197271F, 0.7077454264F, 0.7081708684F, 0.7085960529F,
- 0.7090209793F, 0.7094456474F, 0.7098700566F, 0.7102942066F,
- 0.7107180970F, 0.7111417274F, 0.7115650974F, 0.7119882066F,
- 0.7124110545F, 0.7128336409F, 0.7132559653F, 0.7136780272F,
- 0.7140998264F, 0.7145213624F, 0.7149426348F, 0.7153636433F,
- 0.7157843874F, 0.7162048668F, 0.7166250810F, 0.7170450296F,
- 0.7174647124F, 0.7178841289F, 0.7183032786F, 0.7187221613F,
- 0.7191407765F, 0.7195591239F, 0.7199772030F, 0.7203950135F,
- 0.7208125550F, 0.7212298271F, 0.7216468294F, 0.7220635616F,
- 0.7224800233F, 0.7228962140F, 0.7233121335F, 0.7237277813F,
- 0.7241431571F, 0.7245582604F, 0.7249730910F, 0.7253876484F,
- 0.7258019322F, 0.7262159422F, 0.7266296778F, 0.7270431388F,
- 0.7274563247F, 0.7278692353F, 0.7282818700F, 0.7286942287F,
- 0.7291063108F, 0.7295181160F, 0.7299296440F, 0.7303408944F,
- 0.7307518669F, 0.7311625609F, 0.7315729763F, 0.7319831126F,
- 0.7323929695F, 0.7328025466F, 0.7332118435F, 0.7336208600F,
- 0.7340295955F, 0.7344380499F, 0.7348462226F, 0.7352541134F,
- 0.7356617220F, 0.7360690478F, 0.7364760907F, 0.7368828502F,
- 0.7372893259F, 0.7376955176F, 0.7381014249F, 0.7385070475F,
- 0.7389123849F, 0.7393174368F, 0.7397222029F, 0.7401266829F,
- 0.7405308763F, 0.7409347829F, 0.7413384023F, 0.7417417341F,
- 0.7421447780F, 0.7425475338F, 0.7429500009F, 0.7433521791F,
- 0.7437540681F, 0.7441556674F, 0.7445569769F, 0.7449579960F,
- 0.7453587245F, 0.7457591621F, 0.7461593084F, 0.7465591631F,
- 0.7469587259F, 0.7473579963F, 0.7477569741F, 0.7481556590F,
- 0.7485540506F, 0.7489521486F, 0.7493499526F, 0.7497474623F,
- 0.7501446775F, 0.7505415977F, 0.7509382227F, 0.7513345521F,
- 0.7517305856F, 0.7521263229F, 0.7525217636F, 0.7529169074F,
- 0.7533117541F, 0.7537063032F, 0.7541005545F, 0.7544945076F,
- 0.7548881623F, 0.7552815182F, 0.7556745749F, 0.7560673323F,
- 0.7564597899F, 0.7568519474F, 0.7572438046F, 0.7576353611F,
- 0.7580266166F, 0.7584175708F, 0.7588082235F, 0.7591985741F,
- 0.7595886226F, 0.7599783685F, 0.7603678116F, 0.7607569515F,
- 0.7611457879F, 0.7615343206F, 0.7619225493F, 0.7623104735F,
- 0.7626980931F, 0.7630854078F, 0.7634724171F, 0.7638591209F,
- 0.7642455188F, 0.7646316106F, 0.7650173959F, 0.7654028744F,
- 0.7657880459F, 0.7661729100F, 0.7665574664F, 0.7669417150F,
- 0.7673256553F, 0.7677092871F, 0.7680926100F, 0.7684756239F,
- 0.7688583284F, 0.7692407232F, 0.7696228080F, 0.7700045826F,
- 0.7703860467F, 0.7707671999F, 0.7711480420F, 0.7715285728F,
- 0.7719087918F, 0.7722886989F, 0.7726682938F, 0.7730475762F,
- 0.7734265458F, 0.7738052023F, 0.7741835454F, 0.7745615750F,
- 0.7749392906F, 0.7753166921F, 0.7756937791F, 0.7760705514F,
- 0.7764470087F, 0.7768231508F, 0.7771989773F, 0.7775744880F,
- 0.7779496827F, 0.7783245610F, 0.7786991227F, 0.7790733676F,
- 0.7794472953F, 0.7798209056F, 0.7801941982F, 0.7805671729F,
- 0.7809398294F, 0.7813121675F, 0.7816841869F, 0.7820558873F,
- 0.7824272684F, 0.7827983301F, 0.7831690720F, 0.7835394940F,
- 0.7839095957F, 0.7842793768F, 0.7846488373F, 0.7850179767F,
- 0.7853867948F, 0.7857552914F, 0.7861234663F, 0.7864913191F,
- 0.7868588497F, 0.7872260578F, 0.7875929431F, 0.7879595055F,
- 0.7883257445F, 0.7886916601F, 0.7890572520F, 0.7894225198F,
- 0.7897874635F, 0.7901520827F, 0.7905163772F, 0.7908803468F,
- 0.7912439912F, 0.7916073102F, 0.7919703035F, 0.7923329710F,
- 0.7926953124F, 0.7930573274F, 0.7934190158F, 0.7937803774F,
- 0.7941414120F, 0.7945021193F, 0.7948624991F, 0.7952225511F,
- 0.7955822752F, 0.7959416711F, 0.7963007387F, 0.7966594775F,
- 0.7970178875F, 0.7973759685F, 0.7977337201F, 0.7980911422F,
- 0.7984482346F, 0.7988049970F, 0.7991614292F, 0.7995175310F,
- 0.7998733022F, 0.8002287426F, 0.8005838519F, 0.8009386299F,
- 0.8012930765F, 0.8016471914F, 0.8020009744F, 0.8023544253F,
- 0.8027075438F, 0.8030603298F, 0.8034127831F, 0.8037649035F,
- 0.8041166906F, 0.8044681445F, 0.8048192647F, 0.8051700512F,
- 0.8055205038F, 0.8058706222F, 0.8062204062F, 0.8065698556F,
- 0.8069189702F, 0.8072677499F, 0.8076161944F, 0.8079643036F,
- 0.8083120772F, 0.8086595151F, 0.8090066170F, 0.8093533827F,
- 0.8096998122F, 0.8100459051F, 0.8103916613F, 0.8107370806F,
- 0.8110821628F, 0.8114269077F, 0.8117713151F, 0.8121153849F,
- 0.8124591169F, 0.8128025108F, 0.8131455666F, 0.8134882839F,
- 0.8138306627F, 0.8141727027F, 0.8145144038F, 0.8148557658F,
- 0.8151967886F, 0.8155374718F, 0.8158778154F, 0.8162178192F,
- 0.8165574830F, 0.8168968067F, 0.8172357900F, 0.8175744328F,
- 0.8179127349F, 0.8182506962F, 0.8185883164F, 0.8189255955F,
- 0.8192625332F, 0.8195991295F, 0.8199353840F, 0.8202712967F,
- 0.8206068673F, 0.8209420958F, 0.8212769820F, 0.8216115256F,
- 0.8219457266F, 0.8222795848F, 0.8226131000F, 0.8229462721F,
- 0.8232791009F, 0.8236115863F, 0.8239437280F, 0.8242755260F,
- 0.8246069801F, 0.8249380901F, 0.8252688559F, 0.8255992774F,
- 0.8259293544F, 0.8262590867F, 0.8265884741F, 0.8269175167F,
- 0.8272462141F, 0.8275745663F, 0.8279025732F, 0.8282302344F,
- 0.8285575501F, 0.8288845199F, 0.8292111437F, 0.8295374215F,
- 0.8298633530F, 0.8301889382F, 0.8305141768F, 0.8308390688F,
- 0.8311636141F, 0.8314878124F, 0.8318116637F, 0.8321351678F,
- 0.8324583246F, 0.8327811340F, 0.8331035957F, 0.8334257098F,
- 0.8337474761F, 0.8340688944F, 0.8343899647F, 0.8347106867F,
- 0.8350310605F, 0.8353510857F, 0.8356707624F, 0.8359900904F,
- 0.8363090696F, 0.8366276999F, 0.8369459811F, 0.8372639131F,
- 0.8375814958F, 0.8378987292F, 0.8382156130F, 0.8385321472F,
- 0.8388483316F, 0.8391641662F, 0.8394796508F, 0.8397947853F,
- 0.8401095697F, 0.8404240037F, 0.8407380873F, 0.8410518204F,
- 0.8413652029F, 0.8416782347F, 0.8419909156F, 0.8423032456F,
- 0.8426152245F, 0.8429268523F, 0.8432381289F, 0.8435490541F,
- 0.8438596279F, 0.8441698502F, 0.8444797208F, 0.8447892396F,
- 0.8450984067F, 0.8454072218F, 0.8457156849F, 0.8460237959F,
- 0.8463315547F, 0.8466389612F, 0.8469460154F, 0.8472527170F,
- 0.8475590661F, 0.8478650625F, 0.8481707063F, 0.8484759971F,
- 0.8487809351F, 0.8490855201F, 0.8493897521F, 0.8496936308F,
- 0.8499971564F, 0.8503003286F, 0.8506031474F, 0.8509056128F,
- 0.8512077246F, 0.8515094828F, 0.8518108872F, 0.8521119379F,
- 0.8524126348F, 0.8527129777F, 0.8530129666F, 0.8533126015F,
- 0.8536118822F, 0.8539108087F, 0.8542093809F, 0.8545075988F,
- 0.8548054623F, 0.8551029712F, 0.8554001257F, 0.8556969255F,
- 0.8559933707F, 0.8562894611F, 0.8565851968F, 0.8568805775F,
- 0.8571756034F, 0.8574702743F, 0.8577645902F, 0.8580585509F,
- 0.8583521566F, 0.8586454070F, 0.8589383021F, 0.8592308420F,
- 0.8595230265F, 0.8598148556F, 0.8601063292F, 0.8603974473F,
- 0.8606882098F, 0.8609786167F, 0.8612686680F, 0.8615583636F,
- 0.8618477034F, 0.8621366874F, 0.8624253156F, 0.8627135878F,
- 0.8630015042F, 0.8632890646F, 0.8635762690F, 0.8638631173F,
- 0.8641496096F, 0.8644357457F, 0.8647215257F, 0.8650069495F,
- 0.8652920171F, 0.8655767283F, 0.8658610833F, 0.8661450820F,
- 0.8664287243F, 0.8667120102F, 0.8669949397F, 0.8672775127F,
- 0.8675597293F, 0.8678415894F, 0.8681230929F, 0.8684042398F,
- 0.8686850302F, 0.8689654640F, 0.8692455412F, 0.8695252617F,
- 0.8698046255F, 0.8700836327F, 0.8703622831F, 0.8706405768F,
- 0.8709185138F, 0.8711960940F, 0.8714733174F, 0.8717501840F,
- 0.8720266939F, 0.8723028469F, 0.8725786430F, 0.8728540824F,
- 0.8731291648F, 0.8734038905F, 0.8736782592F, 0.8739522711F,
- 0.8742259261F, 0.8744992242F, 0.8747721653F, 0.8750447496F,
- 0.8753169770F, 0.8755888475F, 0.8758603611F, 0.8761315177F,
- 0.8764023175F, 0.8766727603F, 0.8769428462F, 0.8772125752F,
- 0.8774819474F, 0.8777509626F, 0.8780196209F, 0.8782879224F,
- 0.8785558669F, 0.8788234546F, 0.8790906854F, 0.8793575594F,
- 0.8796240765F, 0.8798902368F, 0.8801560403F, 0.8804214870F,
- 0.8806865768F, 0.8809513099F, 0.8812156863F, 0.8814797059F,
- 0.8817433687F, 0.8820066749F, 0.8822696243F, 0.8825322171F,
- 0.8827944532F, 0.8830563327F, 0.8833178556F, 0.8835790219F,
- 0.8838398316F, 0.8841002848F, 0.8843603815F, 0.8846201217F,
- 0.8848795054F, 0.8851385327F, 0.8853972036F, 0.8856555182F,
- 0.8859134764F, 0.8861710783F, 0.8864283239F, 0.8866852133F,
- 0.8869417464F, 0.8871979234F, 0.8874537443F, 0.8877092090F,
- 0.8879643177F, 0.8882190704F, 0.8884734671F, 0.8887275078F,
- 0.8889811927F, 0.8892345216F, 0.8894874948F, 0.8897401122F,
- 0.8899923738F, 0.8902442798F, 0.8904958301F, 0.8907470248F,
- 0.8909978640F, 0.8912483477F, 0.8914984759F, 0.8917482487F,
- 0.8919976662F, 0.8922467284F, 0.8924954353F, 0.8927437871F,
- 0.8929917837F, 0.8932394252F, 0.8934867118F, 0.8937336433F,
- 0.8939802199F, 0.8942264417F, 0.8944723087F, 0.8947178210F,
- 0.8949629785F, 0.8952077815F, 0.8954522299F, 0.8956963239F,
- 0.8959400634F, 0.8961834486F, 0.8964264795F, 0.8966691561F,
- 0.8969114786F, 0.8971534470F, 0.8973950614F, 0.8976363219F,
- 0.8978772284F, 0.8981177812F, 0.8983579802F, 0.8985978256F,
- 0.8988373174F, 0.8990764556F, 0.8993152405F, 0.8995536720F,
- 0.8997917502F, 0.9000294751F, 0.9002668470F, 0.9005038658F,
- 0.9007405317F, 0.9009768446F, 0.9012128048F, 0.9014484123F,
- 0.9016836671F, 0.9019185693F, 0.9021531191F, 0.9023873165F,
- 0.9026211616F, 0.9028546546F, 0.9030877954F, 0.9033205841F,
- 0.9035530210F, 0.9037851059F, 0.9040168392F, 0.9042482207F,
- 0.9044792507F, 0.9047099293F, 0.9049402564F, 0.9051702323F,
- 0.9053998569F, 0.9056291305F, 0.9058580531F, 0.9060866248F,
- 0.9063148457F, 0.9065427159F, 0.9067702355F, 0.9069974046F,
- 0.9072242233F, 0.9074506917F, 0.9076768100F, 0.9079025782F,
- 0.9081279964F, 0.9083530647F, 0.9085777833F, 0.9088021523F,
- 0.9090261717F, 0.9092498417F, 0.9094731623F, 0.9096961338F,
- 0.9099187561F, 0.9101410295F, 0.9103629540F, 0.9105845297F,
- 0.9108057568F, 0.9110266354F, 0.9112471656F, 0.9114673475F,
- 0.9116871812F, 0.9119066668F, 0.9121258046F, 0.9123445945F,
- 0.9125630367F, 0.9127811314F, 0.9129988786F, 0.9132162785F,
- 0.9134333312F, 0.9136500368F, 0.9138663954F, 0.9140824073F,
- 0.9142980724F, 0.9145133910F, 0.9147283632F, 0.9149429890F,
- 0.9151572687F, 0.9153712023F, 0.9155847900F, 0.9157980319F,
- 0.9160109282F, 0.9162234790F, 0.9164356844F, 0.9166475445F,
- 0.9168590595F, 0.9170702296F, 0.9172810548F, 0.9174915354F,
- 0.9177016714F, 0.9179114629F, 0.9181209102F, 0.9183300134F,
- 0.9185387726F, 0.9187471879F, 0.9189552595F, 0.9191629876F,
- 0.9193703723F, 0.9195774136F, 0.9197841119F, 0.9199904672F,
- 0.9201964797F, 0.9204021495F, 0.9206074767F, 0.9208124616F,
- 0.9210171043F, 0.9212214049F, 0.9214253636F, 0.9216289805F,
- 0.9218322558F, 0.9220351896F, 0.9222377821F, 0.9224400335F,
- 0.9226419439F, 0.9228435134F, 0.9230447423F, 0.9232456307F,
- 0.9234461787F, 0.9236463865F, 0.9238462543F, 0.9240457822F,
- 0.9242449704F, 0.9244438190F, 0.9246423282F, 0.9248404983F,
- 0.9250383293F, 0.9252358214F, 0.9254329747F, 0.9256297896F,
- 0.9258262660F, 0.9260224042F, 0.9262182044F, 0.9264136667F,
- 0.9266087913F, 0.9268035783F, 0.9269980280F, 0.9271921405F,
- 0.9273859160F, 0.9275793546F, 0.9277724566F, 0.9279652221F,
- 0.9281576513F, 0.9283497443F, 0.9285415014F, 0.9287329227F,
- 0.9289240084F, 0.9291147586F, 0.9293051737F, 0.9294952536F,
- 0.9296849987F, 0.9298744091F, 0.9300634850F, 0.9302522266F,
- 0.9304406340F, 0.9306287074F, 0.9308164471F, 0.9310038532F,
- 0.9311909259F, 0.9313776654F, 0.9315640719F, 0.9317501455F,
- 0.9319358865F, 0.9321212951F, 0.9323063713F, 0.9324911155F,
- 0.9326755279F, 0.9328596085F, 0.9330433577F, 0.9332267756F,
- 0.9334098623F, 0.9335926182F, 0.9337750434F, 0.9339571380F,
- 0.9341389023F, 0.9343203366F, 0.9345014409F, 0.9346822155F,
- 0.9348626606F, 0.9350427763F, 0.9352225630F, 0.9354020207F,
- 0.9355811498F, 0.9357599503F, 0.9359384226F, 0.9361165667F,
- 0.9362943830F, 0.9364718716F, 0.9366490327F, 0.9368258666F,
- 0.9370023733F, 0.9371785533F, 0.9373544066F, 0.9375299335F,
- 0.9377051341F, 0.9378800087F, 0.9380545576F, 0.9382287809F,
- 0.9384026787F, 0.9385762515F, 0.9387494993F, 0.9389224223F,
- 0.9390950209F, 0.9392672951F, 0.9394392453F, 0.9396108716F,
- 0.9397821743F, 0.9399531536F, 0.9401238096F, 0.9402941427F,
- 0.9404641530F, 0.9406338407F, 0.9408032061F, 0.9409722495F,
- 0.9411409709F, 0.9413093707F, 0.9414774491F, 0.9416452062F,
- 0.9418126424F, 0.9419797579F, 0.9421465528F, 0.9423130274F,
- 0.9424791819F, 0.9426450166F, 0.9428105317F, 0.9429757274F,
- 0.9431406039F, 0.9433051616F, 0.9434694005F, 0.9436333209F,
- 0.9437969232F, 0.9439602074F, 0.9441231739F, 0.9442858229F,
- 0.9444481545F, 0.9446101691F, 0.9447718669F, 0.9449332481F,
- 0.9450943129F, 0.9452550617F, 0.9454154945F, 0.9455756118F,
- 0.9457354136F, 0.9458949003F, 0.9460540721F, 0.9462129292F,
- 0.9463714719F, 0.9465297003F, 0.9466876149F, 0.9468452157F,
- 0.9470025031F, 0.9471594772F, 0.9473161384F, 0.9474724869F,
- 0.9476285229F, 0.9477842466F, 0.9479396584F, 0.9480947585F,
- 0.9482495470F, 0.9484040243F, 0.9485581906F, 0.9487120462F,
- 0.9488655913F, 0.9490188262F, 0.9491717511F, 0.9493243662F,
- 0.9494766718F, 0.9496286683F, 0.9497803557F, 0.9499317345F,
- 0.9500828047F, 0.9502335668F, 0.9503840209F, 0.9505341673F,
- 0.9506840062F, 0.9508335380F, 0.9509827629F, 0.9511316810F,
- 0.9512802928F, 0.9514285984F, 0.9515765982F, 0.9517242923F,
- 0.9518716810F, 0.9520187646F, 0.9521655434F, 0.9523120176F,
- 0.9524581875F, 0.9526040534F, 0.9527496154F, 0.9528948739F,
- 0.9530398292F, 0.9531844814F, 0.9533288310F, 0.9534728780F,
- 0.9536166229F, 0.9537600659F, 0.9539032071F, 0.9540460470F,
- 0.9541885858F, 0.9543308237F, 0.9544727611F, 0.9546143981F,
- 0.9547557351F, 0.9548967723F, 0.9550375100F, 0.9551779485F,
- 0.9553180881F, 0.9554579290F, 0.9555974714F, 0.9557367158F,
- 0.9558756623F, 0.9560143112F, 0.9561526628F, 0.9562907174F,
- 0.9564284752F, 0.9565659366F, 0.9567031017F, 0.9568399710F,
- 0.9569765446F, 0.9571128229F, 0.9572488061F, 0.9573844944F,
- 0.9575198883F, 0.9576549879F, 0.9577897936F, 0.9579243056F,
- 0.9580585242F, 0.9581924497F, 0.9583260824F, 0.9584594226F,
- 0.9585924705F, 0.9587252264F, 0.9588576906F, 0.9589898634F,
- 0.9591217452F, 0.9592533360F, 0.9593846364F, 0.9595156465F,
- 0.9596463666F, 0.9597767971F, 0.9599069382F, 0.9600367901F,
- 0.9601663533F, 0.9602956279F, 0.9604246143F, 0.9605533128F,
- 0.9606817236F, 0.9608098471F, 0.9609376835F, 0.9610652332F,
- 0.9611924963F, 0.9613194733F, 0.9614461644F, 0.9615725699F,
- 0.9616986901F, 0.9618245253F, 0.9619500757F, 0.9620753418F,
- 0.9622003238F, 0.9623250219F, 0.9624494365F, 0.9625735679F,
- 0.9626974163F, 0.9628209821F, 0.9629442656F, 0.9630672671F,
- 0.9631899868F, 0.9633124251F, 0.9634345822F, 0.9635564585F,
- 0.9636780543F, 0.9637993699F, 0.9639204056F, 0.9640411616F,
- 0.9641616383F, 0.9642818359F, 0.9644017549F, 0.9645213955F,
- 0.9646407579F, 0.9647598426F, 0.9648786497F, 0.9649971797F,
- 0.9651154328F, 0.9652334092F, 0.9653511095F, 0.9654685337F,
- 0.9655856823F, 0.9657025556F, 0.9658191538F, 0.9659354773F,
- 0.9660515263F, 0.9661673013F, 0.9662828024F, 0.9663980300F,
- 0.9665129845F, 0.9666276660F, 0.9667420750F, 0.9668562118F,
- 0.9669700766F, 0.9670836698F, 0.9671969917F, 0.9673100425F,
- 0.9674228227F, 0.9675353325F, 0.9676475722F, 0.9677595422F,
- 0.9678712428F, 0.9679826742F, 0.9680938368F, 0.9682047309F,
- 0.9683153569F, 0.9684257150F, 0.9685358056F, 0.9686456289F,
- 0.9687551853F, 0.9688644752F, 0.9689734987F, 0.9690822564F,
- 0.9691907483F, 0.9692989750F, 0.9694069367F, 0.9695146337F,
- 0.9696220663F, 0.9697292349F, 0.9698361398F, 0.9699427813F,
- 0.9700491597F, 0.9701552754F, 0.9702611286F, 0.9703667197F,
- 0.9704720490F, 0.9705771169F, 0.9706819236F, 0.9707864695F,
- 0.9708907549F, 0.9709947802F, 0.9710985456F, 0.9712020514F,
- 0.9713052981F, 0.9714082859F, 0.9715110151F, 0.9716134862F,
- 0.9717156993F, 0.9718176549F, 0.9719193532F, 0.9720207946F,
- 0.9721219794F, 0.9722229080F, 0.9723235806F, 0.9724239976F,
- 0.9725241593F, 0.9726240661F, 0.9727237183F, 0.9728231161F,
- 0.9729222601F, 0.9730211503F, 0.9731197873F, 0.9732181713F,
- 0.9733163027F, 0.9734141817F, 0.9735118088F, 0.9736091842F,
- 0.9737063083F, 0.9738031814F, 0.9738998039F, 0.9739961760F,
- 0.9740922981F, 0.9741881706F, 0.9742837938F, 0.9743791680F,
- 0.9744742935F, 0.9745691707F, 0.9746637999F, 0.9747581814F,
- 0.9748523157F, 0.9749462029F, 0.9750398435F, 0.9751332378F,
- 0.9752263861F, 0.9753192887F, 0.9754119461F, 0.9755043585F,
- 0.9755965262F, 0.9756884496F, 0.9757801291F, 0.9758715650F,
- 0.9759627575F, 0.9760537071F, 0.9761444141F, 0.9762348789F,
- 0.9763251016F, 0.9764150828F, 0.9765048228F, 0.9765943218F,
- 0.9766835802F, 0.9767725984F, 0.9768613767F, 0.9769499154F,
- 0.9770382149F, 0.9771262755F, 0.9772140976F, 0.9773016815F,
- 0.9773890275F, 0.9774761360F, 0.9775630073F, 0.9776496418F,
- 0.9777360398F, 0.9778222016F, 0.9779081277F, 0.9779938182F,
- 0.9780792736F, 0.9781644943F, 0.9782494805F, 0.9783342326F,
- 0.9784187509F, 0.9785030359F, 0.9785870877F, 0.9786709069F,
- 0.9787544936F, 0.9788378484F, 0.9789209714F, 0.9790038631F,
- 0.9790865238F, 0.9791689538F, 0.9792511535F, 0.9793331232F,
- 0.9794148633F, 0.9794963742F, 0.9795776561F, 0.9796587094F,
- 0.9797395345F, 0.9798201316F, 0.9799005013F, 0.9799806437F,
- 0.9800605593F, 0.9801402483F, 0.9802197112F, 0.9802989483F,
- 0.9803779600F, 0.9804567465F, 0.9805353082F, 0.9806136455F,
- 0.9806917587F, 0.9807696482F, 0.9808473143F, 0.9809247574F,
- 0.9810019778F, 0.9810789759F, 0.9811557519F, 0.9812323064F,
- 0.9813086395F, 0.9813847517F, 0.9814606433F, 0.9815363147F,
- 0.9816117662F, 0.9816869981F, 0.9817620108F, 0.9818368047F,
- 0.9819113801F, 0.9819857374F, 0.9820598769F, 0.9821337989F,
- 0.9822075038F, 0.9822809920F, 0.9823542638F, 0.9824273195F,
- 0.9825001596F, 0.9825727843F, 0.9826451940F, 0.9827173891F,
- 0.9827893700F, 0.9828611368F, 0.9829326901F, 0.9830040302F,
- 0.9830751574F, 0.9831460720F, 0.9832167745F, 0.9832872652F,
- 0.9833575444F, 0.9834276124F, 0.9834974697F, 0.9835671166F,
- 0.9836365535F, 0.9837057806F, 0.9837747983F, 0.9838436071F,
- 0.9839122072F, 0.9839805990F, 0.9840487829F, 0.9841167591F,
- 0.9841845282F, 0.9842520903F, 0.9843194459F, 0.9843865953F,
- 0.9844535389F, 0.9845202771F, 0.9845868101F, 0.9846531383F,
- 0.9847192622F, 0.9847851820F, 0.9848508980F, 0.9849164108F,
- 0.9849817205F, 0.9850468276F, 0.9851117324F, 0.9851764352F,
- 0.9852409365F, 0.9853052366F, 0.9853693358F, 0.9854332344F,
- 0.9854969330F, 0.9855604317F, 0.9856237309F, 0.9856868310F,
- 0.9857497325F, 0.9858124355F, 0.9858749404F, 0.9859372477F,
- 0.9859993577F, 0.9860612707F, 0.9861229871F, 0.9861845072F,
- 0.9862458315F, 0.9863069601F, 0.9863678936F, 0.9864286322F,
- 0.9864891764F, 0.9865495264F, 0.9866096826F, 0.9866696454F,
- 0.9867294152F, 0.9867889922F, 0.9868483769F, 0.9869075695F,
- 0.9869665706F, 0.9870253803F, 0.9870839991F, 0.9871424273F,
- 0.9872006653F, 0.9872587135F, 0.9873165721F, 0.9873742415F,
- 0.9874317222F, 0.9874890144F, 0.9875461185F, 0.9876030348F,
- 0.9876597638F, 0.9877163057F, 0.9877726610F, 0.9878288300F,
- 0.9878848130F, 0.9879406104F, 0.9879962225F, 0.9880516497F,
- 0.9881068924F, 0.9881619509F, 0.9882168256F, 0.9882715168F,
- 0.9883260249F, 0.9883803502F, 0.9884344931F, 0.9884884539F,
- 0.9885422331F, 0.9885958309F, 0.9886492477F, 0.9887024838F,
- 0.9887555397F, 0.9888084157F, 0.9888611120F, 0.9889136292F,
- 0.9889659675F, 0.9890181273F, 0.9890701089F, 0.9891219128F,
- 0.9891735392F, 0.9892249885F, 0.9892762610F, 0.9893273572F,
- 0.9893782774F, 0.9894290219F, 0.9894795911F, 0.9895299853F,
- 0.9895802049F, 0.9896302502F, 0.9896801217F, 0.9897298196F,
- 0.9897793443F, 0.9898286961F, 0.9898778755F, 0.9899268828F,
- 0.9899757183F, 0.9900243823F, 0.9900728753F, 0.9901211976F,
- 0.9901693495F, 0.9902173314F, 0.9902651436F, 0.9903127865F,
- 0.9903602605F, 0.9904075659F, 0.9904547031F, 0.9905016723F,
- 0.9905484740F, 0.9905951086F, 0.9906415763F, 0.9906878775F,
- 0.9907340126F, 0.9907799819F, 0.9908257858F, 0.9908714247F,
- 0.9909168988F, 0.9909622086F, 0.9910073543F, 0.9910523364F,
- 0.9910971552F, 0.9911418110F, 0.9911863042F, 0.9912306351F,
- 0.9912748042F, 0.9913188117F, 0.9913626580F, 0.9914063435F,
- 0.9914498684F, 0.9914932333F, 0.9915364383F, 0.9915794839F,
- 0.9916223703F, 0.9916650981F, 0.9917076674F, 0.9917500787F,
- 0.9917923323F, 0.9918344286F, 0.9918763679F, 0.9919181505F,
- 0.9919597769F, 0.9920012473F, 0.9920425621F, 0.9920837217F,
- 0.9921247263F, 0.9921655765F, 0.9922062724F, 0.9922468145F,
- 0.9922872030F, 0.9923274385F, 0.9923675211F, 0.9924074513F,
- 0.9924472294F, 0.9924868557F, 0.9925263306F, 0.9925656544F,
- 0.9926048275F, 0.9926438503F, 0.9926827230F, 0.9927214461F,
- 0.9927600199F, 0.9927984446F, 0.9928367208F, 0.9928748486F,
- 0.9929128285F, 0.9929506608F, 0.9929883459F, 0.9930258841F,
- 0.9930632757F, 0.9931005211F, 0.9931376207F, 0.9931745747F,
- 0.9932113836F, 0.9932480476F, 0.9932845671F, 0.9933209425F,
- 0.9933571742F, 0.9933932623F, 0.9934292074F, 0.9934650097F,
- 0.9935006696F, 0.9935361874F, 0.9935715635F, 0.9936067982F,
- 0.9936418919F, 0.9936768448F, 0.9937116574F, 0.9937463300F,
- 0.9937808629F, 0.9938152565F, 0.9938495111F, 0.9938836271F,
- 0.9939176047F, 0.9939514444F, 0.9939851465F, 0.9940187112F,
- 0.9940521391F, 0.9940854303F, 0.9941185853F, 0.9941516044F,
- 0.9941844879F, 0.9942172361F, 0.9942498495F, 0.9942823283F,
- 0.9943146729F, 0.9943468836F, 0.9943789608F, 0.9944109047F,
- 0.9944427158F, 0.9944743944F, 0.9945059408F, 0.9945373553F,
- 0.9945686384F, 0.9945997902F, 0.9946308112F, 0.9946617017F,
- 0.9946924621F, 0.9947230926F, 0.9947535937F, 0.9947839656F,
- 0.9948142086F, 0.9948443232F, 0.9948743097F, 0.9949041683F,
- 0.9949338995F, 0.9949635035F, 0.9949929807F, 0.9950223315F,
- 0.9950515561F, 0.9950806549F, 0.9951096282F, 0.9951384764F,
- 0.9951671998F, 0.9951957987F, 0.9952242735F, 0.9952526245F,
- 0.9952808520F, 0.9953089564F, 0.9953369380F, 0.9953647971F,
- 0.9953925340F, 0.9954201491F, 0.9954476428F, 0.9954750153F,
- 0.9955022670F, 0.9955293981F, 0.9955564092F, 0.9955833003F,
- 0.9956100720F, 0.9956367245F, 0.9956632582F, 0.9956896733F,
- 0.9957159703F, 0.9957421494F, 0.9957682110F, 0.9957941553F,
- 0.9958199828F, 0.9958456937F, 0.9958712884F, 0.9958967672F,
- 0.9959221305F, 0.9959473784F, 0.9959725115F, 0.9959975300F,
- 0.9960224342F, 0.9960472244F, 0.9960719011F, 0.9960964644F,
- 0.9961209148F, 0.9961452525F, 0.9961694779F, 0.9961935913F,
- 0.9962175930F, 0.9962414834F, 0.9962652627F, 0.9962889313F,
- 0.9963124895F, 0.9963359377F, 0.9963592761F, 0.9963825051F,
- 0.9964056250F, 0.9964286361F, 0.9964515387F, 0.9964743332F,
- 0.9964970198F, 0.9965195990F, 0.9965420709F, 0.9965644360F,
- 0.9965866946F, 0.9966088469F, 0.9966308932F, 0.9966528340F,
- 0.9966746695F, 0.9966964001F, 0.9967180260F, 0.9967395475F,
- 0.9967609651F, 0.9967822789F, 0.9968034894F, 0.9968245968F,
- 0.9968456014F, 0.9968665036F, 0.9968873037F, 0.9969080019F,
- 0.9969285987F, 0.9969490942F, 0.9969694889F, 0.9969897830F,
- 0.9970099769F, 0.9970300708F, 0.9970500651F, 0.9970699601F,
- 0.9970897561F, 0.9971094533F, 0.9971290522F, 0.9971485531F,
- 0.9971679561F, 0.9971872617F, 0.9972064702F, 0.9972255818F,
- 0.9972445968F, 0.9972635157F, 0.9972823386F, 0.9973010659F,
- 0.9973196980F, 0.9973382350F, 0.9973566773F, 0.9973750253F,
- 0.9973932791F, 0.9974114392F, 0.9974295059F, 0.9974474793F,
- 0.9974653599F, 0.9974831480F, 0.9975008438F, 0.9975184476F,
- 0.9975359598F, 0.9975533806F, 0.9975707104F, 0.9975879495F,
- 0.9976050981F, 0.9976221566F, 0.9976391252F, 0.9976560043F,
- 0.9976727941F, 0.9976894950F, 0.9977061073F, 0.9977226312F,
- 0.9977390671F, 0.9977554152F, 0.9977716759F, 0.9977878495F,
- 0.9978039361F, 0.9978199363F, 0.9978358501F, 0.9978516780F,
- 0.9978674202F, 0.9978830771F, 0.9978986488F, 0.9979141358F,
- 0.9979295383F, 0.9979448566F, 0.9979600909F, 0.9979752417F,
- 0.9979903091F, 0.9980052936F, 0.9980201952F, 0.9980350145F,
- 0.9980497515F, 0.9980644067F, 0.9980789804F, 0.9980934727F,
- 0.9981078841F, 0.9981222147F, 0.9981364649F, 0.9981506350F,
- 0.9981647253F, 0.9981787360F, 0.9981926674F, 0.9982065199F,
- 0.9982202936F, 0.9982339890F, 0.9982476062F, 0.9982611456F,
- 0.9982746074F, 0.9982879920F, 0.9983012996F, 0.9983145304F,
- 0.9983276849F, 0.9983407632F, 0.9983537657F, 0.9983666926F,
- 0.9983795442F, 0.9983923208F, 0.9984050226F, 0.9984176501F,
- 0.9984302033F, 0.9984426827F, 0.9984550884F, 0.9984674208F,
- 0.9984796802F, 0.9984918667F, 0.9985039808F, 0.9985160227F,
- 0.9985279926F, 0.9985398909F, 0.9985517177F, 0.9985634734F,
- 0.9985751583F, 0.9985867727F, 0.9985983167F, 0.9986097907F,
- 0.9986211949F, 0.9986325297F, 0.9986437953F, 0.9986549919F,
- 0.9986661199F, 0.9986771795F, 0.9986881710F, 0.9986990946F,
- 0.9987099507F, 0.9987207394F, 0.9987314611F, 0.9987421161F,
- 0.9987527045F, 0.9987632267F, 0.9987736829F, 0.9987840734F,
- 0.9987943985F, 0.9988046584F, 0.9988148534F, 0.9988249838F,
- 0.9988350498F, 0.9988450516F, 0.9988549897F, 0.9988648641F,
- 0.9988746753F, 0.9988844233F, 0.9988941086F, 0.9989037313F,
- 0.9989132918F, 0.9989227902F, 0.9989322269F, 0.9989416021F,
- 0.9989509160F, 0.9989601690F, 0.9989693613F, 0.9989784931F,
- 0.9989875647F, 0.9989965763F, 0.9990055283F, 0.9990144208F,
- 0.9990232541F, 0.9990320286F, 0.9990407443F, 0.9990494016F,
- 0.9990580008F, 0.9990665421F, 0.9990750257F, 0.9990834519F,
- 0.9990918209F, 0.9991001331F, 0.9991083886F, 0.9991165877F,
- 0.9991247307F, 0.9991328177F, 0.9991408491F, 0.9991488251F,
- 0.9991567460F, 0.9991646119F, 0.9991724232F, 0.9991801801F,
- 0.9991878828F, 0.9991955316F, 0.9992031267F, 0.9992106684F,
- 0.9992181569F, 0.9992255925F, 0.9992329753F, 0.9992403057F,
- 0.9992475839F, 0.9992548101F, 0.9992619846F, 0.9992691076F,
- 0.9992761793F, 0.9992832001F, 0.9992901701F, 0.9992970895F,
- 0.9993039587F, 0.9993107777F, 0.9993175470F, 0.9993242667F,
- 0.9993309371F, 0.9993375583F, 0.9993441307F, 0.9993506545F,
- 0.9993571298F, 0.9993635570F, 0.9993699362F, 0.9993762678F,
- 0.9993825519F, 0.9993887887F, 0.9993949785F, 0.9994011216F,
- 0.9994072181F, 0.9994132683F, 0.9994192725F, 0.9994252307F,
- 0.9994311434F, 0.9994370107F, 0.9994428327F, 0.9994486099F,
- 0.9994543423F, 0.9994600303F, 0.9994656739F, 0.9994712736F,
- 0.9994768294F, 0.9994823417F, 0.9994878105F, 0.9994932363F,
- 0.9994986191F, 0.9995039592F, 0.9995092568F, 0.9995145122F,
- 0.9995197256F, 0.9995248971F, 0.9995300270F, 0.9995351156F,
- 0.9995401630F, 0.9995451695F, 0.9995501352F, 0.9995550604F,
- 0.9995599454F, 0.9995647903F, 0.9995695953F, 0.9995743607F,
- 0.9995790866F, 0.9995837734F, 0.9995884211F, 0.9995930300F,
- 0.9995976004F, 0.9996021324F, 0.9996066263F, 0.9996110822F,
- 0.9996155004F, 0.9996198810F, 0.9996242244F, 0.9996285306F,
- 0.9996327999F, 0.9996370326F, 0.9996412287F, 0.9996453886F,
- 0.9996495125F, 0.9996536004F, 0.9996576527F, 0.9996616696F,
- 0.9996656512F, 0.9996695977F, 0.9996735094F, 0.9996773865F,
- 0.9996812291F, 0.9996850374F, 0.9996888118F, 0.9996925523F,
- 0.9996962591F, 0.9996999325F, 0.9997035727F, 0.9997071798F,
- 0.9997107541F, 0.9997142957F, 0.9997178049F, 0.9997212818F,
- 0.9997247266F, 0.9997281396F, 0.9997315209F, 0.9997348708F,
- 0.9997381893F, 0.9997414767F, 0.9997447333F, 0.9997479591F,
- 0.9997511544F, 0.9997543194F, 0.9997574542F, 0.9997605591F,
- 0.9997636342F, 0.9997666797F, 0.9997696958F, 0.9997726828F,
- 0.9997756407F, 0.9997785698F, 0.9997814703F, 0.9997843423F,
- 0.9997871860F, 0.9997900016F, 0.9997927894F, 0.9997955494F,
- 0.9997982818F, 0.9998009869F, 0.9998036648F, 0.9998063157F,
- 0.9998089398F, 0.9998115373F, 0.9998141082F, 0.9998166529F,
- 0.9998191715F, 0.9998216642F, 0.9998241311F, 0.9998265724F,
- 0.9998289884F, 0.9998313790F, 0.9998337447F, 0.9998360854F,
- 0.9998384015F, 0.9998406930F, 0.9998429602F, 0.9998452031F,
- 0.9998474221F, 0.9998496171F, 0.9998517885F, 0.9998539364F,
- 0.9998560610F, 0.9998581624F, 0.9998602407F, 0.9998622962F,
- 0.9998643291F, 0.9998663394F, 0.9998683274F, 0.9998702932F,
- 0.9998722370F, 0.9998741589F, 0.9998760591F, 0.9998779378F,
- 0.9998797952F, 0.9998816313F, 0.9998834464F, 0.9998852406F,
- 0.9998870141F, 0.9998887670F, 0.9998904995F, 0.9998922117F,
- 0.9998939039F, 0.9998955761F, 0.9998972285F, 0.9998988613F,
- 0.9999004746F, 0.9999020686F, 0.9999036434F, 0.9999051992F,
- 0.9999067362F, 0.9999082544F, 0.9999097541F, 0.9999112354F,
- 0.9999126984F, 0.9999141433F, 0.9999155703F, 0.9999169794F,
- 0.9999183709F, 0.9999197449F, 0.9999211014F, 0.9999224408F,
- 0.9999237631F, 0.9999250684F, 0.9999263570F, 0.9999276289F,
- 0.9999288843F, 0.9999301233F, 0.9999313461F, 0.9999325529F,
- 0.9999337437F, 0.9999349187F, 0.9999360780F, 0.9999372218F,
- 0.9999383503F, 0.9999394635F, 0.9999405616F, 0.9999416447F,
- 0.9999427129F, 0.9999437665F, 0.9999448055F, 0.9999458301F,
- 0.9999468404F, 0.9999478365F, 0.9999488185F, 0.9999497867F,
- 0.9999507411F, 0.9999516819F, 0.9999526091F, 0.9999535230F,
- 0.9999544236F, 0.9999553111F, 0.9999561856F, 0.9999570472F,
- 0.9999578960F, 0.9999587323F, 0.9999595560F, 0.9999603674F,
- 0.9999611666F, 0.9999619536F, 0.9999627286F, 0.9999634917F,
- 0.9999642431F, 0.9999649828F, 0.9999657110F, 0.9999664278F,
- 0.9999671334F, 0.9999678278F, 0.9999685111F, 0.9999691835F,
- 0.9999698451F, 0.9999704960F, 0.9999711364F, 0.9999717662F,
- 0.9999723858F, 0.9999729950F, 0.9999735942F, 0.9999741834F,
- 0.9999747626F, 0.9999753321F, 0.9999758919F, 0.9999764421F,
- 0.9999769828F, 0.9999775143F, 0.9999780364F, 0.9999785495F,
- 0.9999790535F, 0.9999795485F, 0.9999800348F, 0.9999805124F,
- 0.9999809813F, 0.9999814417F, 0.9999818938F, 0.9999823375F,
- 0.9999827731F, 0.9999832005F, 0.9999836200F, 0.9999840316F,
- 0.9999844353F, 0.9999848314F, 0.9999852199F, 0.9999856008F,
- 0.9999859744F, 0.9999863407F, 0.9999866997F, 0.9999870516F,
- 0.9999873965F, 0.9999877345F, 0.9999880656F, 0.9999883900F,
- 0.9999887078F, 0.9999890190F, 0.9999893237F, 0.9999896220F,
- 0.9999899140F, 0.9999901999F, 0.9999904796F, 0.9999907533F,
- 0.9999910211F, 0.9999912830F, 0.9999915391F, 0.9999917896F,
- 0.9999920345F, 0.9999922738F, 0.9999925077F, 0.9999927363F,
- 0.9999929596F, 0.9999931777F, 0.9999933907F, 0.9999935987F,
- 0.9999938018F, 0.9999940000F, 0.9999941934F, 0.9999943820F,
- 0.9999945661F, 0.9999947456F, 0.9999949206F, 0.9999950912F,
- 0.9999952575F, 0.9999954195F, 0.9999955773F, 0.9999957311F,
- 0.9999958807F, 0.9999960265F, 0.9999961683F, 0.9999963063F,
- 0.9999964405F, 0.9999965710F, 0.9999966979F, 0.9999968213F,
- 0.9999969412F, 0.9999970576F, 0.9999971707F, 0.9999972805F,
- 0.9999973871F, 0.9999974905F, 0.9999975909F, 0.9999976881F,
- 0.9999977824F, 0.9999978738F, 0.9999979624F, 0.9999980481F,
- 0.9999981311F, 0.9999982115F, 0.9999982892F, 0.9999983644F,
- 0.9999984370F, 0.9999985072F, 0.9999985750F, 0.9999986405F,
- 0.9999987037F, 0.9999987647F, 0.9999988235F, 0.9999988802F,
- 0.9999989348F, 0.9999989873F, 0.9999990379F, 0.9999990866F,
- 0.9999991334F, 0.9999991784F, 0.9999992217F, 0.9999992632F,
- 0.9999993030F, 0.9999993411F, 0.9999993777F, 0.9999994128F,
- 0.9999994463F, 0.9999994784F, 0.9999995091F, 0.9999995384F,
- 0.9999995663F, 0.9999995930F, 0.9999996184F, 0.9999996426F,
- 0.9999996657F, 0.9999996876F, 0.9999997084F, 0.9999997282F,
- 0.9999997469F, 0.9999997647F, 0.9999997815F, 0.9999997973F,
- 0.9999998123F, 0.9999998265F, 0.9999998398F, 0.9999998524F,
- 0.9999998642F, 0.9999998753F, 0.9999998857F, 0.9999998954F,
- 0.9999999045F, 0.9999999130F, 0.9999999209F, 0.9999999282F,
- 0.9999999351F, 0.9999999414F, 0.9999999472F, 0.9999999526F,
- 0.9999999576F, 0.9999999622F, 0.9999999664F, 0.9999999702F,
- 0.9999999737F, 0.9999999769F, 0.9999999798F, 0.9999999824F,
- 0.9999999847F, 0.9999999868F, 0.9999999887F, 0.9999999904F,
- 0.9999999919F, 0.9999999932F, 0.9999999943F, 0.9999999953F,
- 0.9999999961F, 0.9999999969F, 0.9999999975F, 0.9999999980F,
- 0.9999999985F, 0.9999999988F, 0.9999999991F, 0.9999999993F,
- 0.9999999995F, 0.9999999997F, 0.9999999998F, 0.9999999999F,
- 0.9999999999F, 1.0000000000F, 1.0000000000F, 1.0000000000F,
- 1.0000000000F, 1.0000000000F, 1.0000000000F, 1.0000000000F,
- };
-
- static float *vwin[8] = {
- vwin64,
- vwin128,
- vwin256,
- vwin512,
- vwin1024,
- vwin2048,
- vwin4096,
- vwin8192,
- };
-
- float *_vorbis_window_get(int n){
- return vwin[n];
- }
-
- void _vorbis_apply_window(float *d,int *winno,long *blocksizes,
- int lW,int W,int nW){
- lW=(W?lW:0);
- nW=(W?nW:0);
-
- {
- float *windowLW=vwin[winno[lW]];
- float *windowNW=vwin[winno[nW]];
-
- long n=blocksizes[W];
- long ln=blocksizes[lW];
- long rn=blocksizes[nW];
-
- long leftbegin=n/4-ln/4;
- long leftend=leftbegin+ln/2;
-
- long rightbegin=n/2+n/4-rn/4;
- long rightend=rightbegin+rn/2;
-
- int i,p;
-
- for(i=0;i<leftbegin;i++)
- d[i]=0.f;
-
- for(p=0;i<leftend;i++,p++)
- d[i]*=windowLW[p];
-
- for(i=rightbegin,p=rn/2-1;i<rightend;i++,p--)
- d[i]*=windowNW[p];
-
- for(;i<n;i++)
- d[i]=0.f;
- }
- }
-
- #endif
- /********* End of inlined file: window.c *********/
-
- }
-
- BEGIN_JUCE_NAMESPACE
-
- using namespace OggVorbisNamespace;
-
- #define oggFormatName TRANS("Ogg-Vorbis file")
- static const tchar* const oggExtensions[] = { T(".ogg"), 0 };
-
- class OggReader : public AudioFormatReader
- {
- OggVorbis_File ovFile;
- ov_callbacks callbacks;
- AudioSampleBuffer reservoir;
- int reservoirStart, samplesInReservoir;
-
- public:
-
- OggReader (InputStream* const inp)
- : AudioFormatReader (inp, oggFormatName),
- reservoir (2, 4096),
- reservoirStart (0),
- samplesInReservoir (0)
- {
- sampleRate = 0;
- usesFloatingPointData = true;
-
- callbacks.read_func = &oggReadCallback;
- callbacks.seek_func = &oggSeekCallback;
- callbacks.close_func = &oggCloseCallback;
- callbacks.tell_func = &oggTellCallback;
-
- const int err = ov_open_callbacks (input, &ovFile, 0, 0, callbacks);
-
- if (err == 0)
- {
- vorbis_info* info = ov_info (&ovFile, -1);
- lengthInSamples = (uint32) ov_pcm_total (&ovFile, -1);
- numChannels = info->channels;
- bitsPerSample = 16;
- sampleRate = info->rate;
-
- reservoir.setSize (numChannels,
- (int) jmin (lengthInSamples, (int64) reservoir.getNumSamples()));
- }
- }
-
- ~OggReader()
- {
- ov_clear (&ovFile);
- }
-
- bool read (int** destSamples,
- int64 startSampleInFile,
- int numSamples)
- {
- int writeOffset = 0;
-
- while (numSamples > 0)
- {
- const int numAvailable = reservoirStart + samplesInReservoir - startSampleInFile;
-
- if (startSampleInFile >= reservoirStart && numAvailable > 0)
- {
- // got a few samples overlapping, so use them before seeking..
-
- for (unsigned int i = 0; i < numChannels; ++i)
- {
- if (destSamples[i] == 0)
- break;
-
- memcpy (destSamples[i] + writeOffset,
- reservoir.getSampleData (jmin (i, reservoir.getNumChannels()),
- (int) (startSampleInFile - reservoirStart)),
- sizeof (float) * numSamples);
- }
-
- startSampleInFile += numAvailable;
- numSamples -= numAvailable;
- writeOffset += numAvailable;
-
- if (numSamples == 0)
- break;
- }
-
- if (startSampleInFile < reservoirStart
- || startSampleInFile + numSamples > reservoirStart + samplesInReservoir)
- {
- // buffer miss, so refill the reservoir
- int bitStream = 0;
-
- reservoirStart = jmax (0, (int) startSampleInFile);
- samplesInReservoir = reservoir.getNumSamples();
-
- if (reservoirStart != (int) ov_pcm_tell (&ovFile))
- ov_pcm_seek (&ovFile, reservoirStart);
-
- int offset = 0;
- int numToRead = samplesInReservoir;
-
- while (numToRead > 0)
- {
- float** dataIn = 0;
-
- const int samps = ov_read_float (&ovFile, &dataIn, numToRead, &bitStream);
- if (samps == 0)
- break;
-
- jassert (samps <= numToRead);
-
- for (int i = jmin (numChannels, reservoir.getNumChannels()); --i >= 0;)
- {
- memcpy (reservoir.getSampleData (i, offset),
- dataIn[i],
- sizeof (float) * samps);
- }
-
- numToRead -= samps;
- offset += samps;
- }
-
- if (numToRead > 0)
- reservoir.clear (offset, numToRead);
- }
- }
-
- return true;
- }
-
- static size_t oggReadCallback (void* ptr, size_t size, size_t nmemb, void* datasource)
- {
- return (size_t) (((InputStream*) datasource)->read (ptr, (int) (size * nmemb)) / size);
- }
-
- static int oggSeekCallback (void* datasource, ogg_int64_t offset, int whence)
- {
- InputStream* const in = (InputStream*) datasource;
-
- if (whence == SEEK_CUR)
- offset += in->getPosition();
- else if (whence == SEEK_END)
- offset += in->getTotalLength();
-
- in->setPosition (offset);
- return 0;
- }
-
- static int oggCloseCallback (void*)
- {
- return 0;
- }
-
- static long oggTellCallback (void* datasource)
- {
- return (long) ((InputStream*) datasource)->getPosition();
- }
-
- juce_UseDebuggingNewOperator
- };
-
- class OggWriter : public AudioFormatWriter
- {
- ogg_stream_state os;
- ogg_page og;
- ogg_packet op;
- vorbis_info vi;
- vorbis_comment vc;
- vorbis_dsp_state vd;
- vorbis_block vb;
-
- public:
- bool ok;
-
- OggWriter (OutputStream* const out,
- const double sampleRate,
- const int numChannels,
- const int bitsPerSample,
- const int qualityIndex)
- : AudioFormatWriter (out, oggFormatName,
- sampleRate,
- numChannels,
- bitsPerSample)
- {
- ok = false;
-
- vorbis_info_init (&vi);
-
- if (vorbis_encode_init_vbr (&vi,
- numChannels,
- (int) sampleRate,
- jlimit (0.0f, 1.0f, qualityIndex * 0.5f)) == 0)
- {
- vorbis_comment_init (&vc);
-
- if (JUCEApplication::getInstance() != 0)
- vorbis_comment_add_tag (&vc, "ENCODER",
- (char*) (const char*) JUCEApplication::getInstance()->getApplicationName());
-
- vorbis_analysis_init (&vd, &vi);
- vorbis_block_init (&vd, &vb);
-
- ogg_stream_init (&os, Random::getSystemRandom().nextInt());
-
- ogg_packet header;
- ogg_packet header_comm;
- ogg_packet header_code;
-
- vorbis_analysis_headerout (&vd, &vc, &header, &header_comm, &header_code);
-
- ogg_stream_packetin (&os, &header);
- ogg_stream_packetin (&os, &header_comm);
- ogg_stream_packetin (&os, &header_code);
-
- for (;;)
- {
- if (ogg_stream_flush (&os, &og) == 0)
- break;
-
- output->write (og.header, og.header_len);
- output->write (og.body, og.body_len);
- }
-
- ok = true;
- }
- }
-
- ~OggWriter()
- {
- if (ok)
- {
- ogg_stream_clear (&os);
- vorbis_block_clear (&vb);
- vorbis_dsp_clear (&vd);
- vorbis_comment_clear (&vc);
-
- vorbis_info_clear (&vi);
- output->flush();
- }
- else
- {
- vorbis_info_clear (&vi);
- output = 0; // to stop the base class deleting this, as it needs to be returned
- // to the caller of createWriter()
- }
- }
-
- bool write (const int** samplesToWrite, int numSamples)
- {
- if (! ok)
- return false;
-
- if (numSamples > 0)
- {
- const double gain = 1.0 / 0x80000000u;
- float** const vorbisBuffer = vorbis_analysis_buffer (&vd, numSamples);
-
- for (int i = numChannels; --i >= 0;)
- {
- float* const dst = vorbisBuffer[i];
- const int* const src = samplesToWrite [i];
-
- if (src != 0 && dst != 0)
- {
- for (int j = 0; j < numSamples; ++j)
- dst[j] = (float) (src[j] * gain);
- }
- }
- }
-
- vorbis_analysis_wrote (&vd, numSamples);
-
- while (vorbis_analysis_blockout (&vd, &vb) == 1)
- {
- vorbis_analysis (&vb, 0);
- vorbis_bitrate_addblock (&vb);
-
- while (vorbis_bitrate_flushpacket (&vd, &op))
- {
- ogg_stream_packetin (&os, &op);
-
- for (;;)
- {
- if (ogg_stream_pageout (&os, &og) == 0)
- break;
-
- output->write (og.header, og.header_len);
- output->write (og.body, og.body_len);
-
- if (ogg_page_eos (&og))
- break;
- }
- }
- }
-
- return true;
- }
-
- juce_UseDebuggingNewOperator
- };
-
- OggVorbisAudioFormat::OggVorbisAudioFormat()
- : AudioFormat (oggFormatName, (const tchar**) oggExtensions)
- {
- }
-
- OggVorbisAudioFormat::~OggVorbisAudioFormat()
- {
- }
-
- const Array <int> OggVorbisAudioFormat::getPossibleSampleRates()
- {
- const int rates[] = { 22050, 32000, 44100, 48000, 0 };
- return Array <int> (rates);
- }
-
- const Array <int> OggVorbisAudioFormat::getPossibleBitDepths()
- {
- Array <int> depths;
- depths.add (32);
- return depths;
- }
-
- bool OggVorbisAudioFormat::canDoStereo()
- {
- return true;
- }
-
- bool OggVorbisAudioFormat::canDoMono()
- {
- return true;
- }
-
- AudioFormatReader* OggVorbisAudioFormat::createReaderFor (InputStream* in,
- const bool deleteStreamIfOpeningFails)
- {
- OggReader* r = new OggReader (in);
-
- if (r->sampleRate == 0)
- {
- if (! deleteStreamIfOpeningFails)
- r->input = 0;
-
- deleteAndZero (r);
- }
-
- return r;
- }
-
- AudioFormatWriter* OggVorbisAudioFormat::createWriterFor (OutputStream* out,
- double sampleRate,
- unsigned int numChannels,
- int bitsPerSample,
- const StringPairArray& /*metadataValues*/,
- int qualityOptionIndex)
- {
- OggWriter* w = new OggWriter (out,
- sampleRate,
- numChannels,
- bitsPerSample,
- qualityOptionIndex);
-
- if (! w->ok)
- deleteAndZero (w);
-
- return w;
- }
-
- bool OggVorbisAudioFormat::isCompressed()
- {
- return true;
- }
-
- const StringArray OggVorbisAudioFormat::getQualityOptions()
- {
- StringArray s;
- s.add ("Low Quality");
- s.add ("Medium Quality");
- s.add ("High Quality");
- return s;
- }
-
- int OggVorbisAudioFormat::estimateOggFileQuality (const File& source)
- {
- FileInputStream* const in = source.createInputStream();
-
- if (in != 0)
- {
- AudioFormatReader* const r = createReaderFor (in, true);
-
- if (r != 0)
- {
- const int64 numSamps = r->lengthInSamples;
- delete r;
-
- const int64 fileNumSamps = source.getSize() / 4;
- const double ratio = numSamps / (double) fileNumSamps;
-
- if (ratio > 12.0)
- return 0;
- else if (ratio > 6.0)
- return 1;
- else
- return 2;
- }
- }
-
- return 1;
- }
-
- END_JUCE_NAMESPACE
-
- #endif
- /********* End of inlined file: juce_OggVorbisAudioFormat.cpp *********/
-
- /********* Start of inlined file: juce_JPEGLoader.cpp *********/
-
- #if JUCE_MSVC
- #pragma warning (push)
- #endif
-
- namespace jpeglibNamespace
- {
- extern "C"
- {
- #define JPEG_INTERNALS
- #undef FAR
-
- /********* Start of inlined file: jpeglib.h *********/
- #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 */
-
- /********* Start of inlined file: jconfig.h *********/
- /* see jconfig.doc for explanations */
-
- // disable all the warnings under MSVC
- #ifdef _MSC_VER
- #pragma warning (disable: 4996 4267 4100 4127 4702 4244)
- #endif
-
- #ifdef __BORLANDC__
- #pragma warn -8057
- #pragma warn -8019
- #pragma warn -8004
- #pragma warn -8008
- #endif
-
- #define HAVE_PROTOTYPES
- #define HAVE_UNSIGNED_CHAR
- #define HAVE_UNSIGNED_SHORT
- /* #define void char */
- /* #define 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 /* we presume a 32-bit flat memory model */
- #undef NEED_SHORT_EXTERNAL_NAMES
- #undef INCOMPLETE_TYPES_BROKEN
-
- /* Define "boolean" as unsigned char, not int, per Windows custom */
- #ifndef __RPCNDR_H__ /* don't conflict if rpcndr.h already read */
- typedef unsigned char boolean;
- #endif
- #define HAVE_BOOLEAN /* prevent jmorecfg.h from redefining it */
-
- #ifdef JPEG_INTERNALS
-
- #undef RIGHT_SHIFT_IS_UNSIGNED
-
- #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 */
-
- #define TWO_FILE_COMMANDLINE /* optional */
- #define USE_SETMODE /* Microsoft has setmode() */
- #undef NEED_SIGNAL_CATCHER
- #undef DONT_USE_B_MODE
- #undef PROGRESS_REPORT /* optional */
-
- #endif /* JPEG_CJPEG_DJPEG */
- /********* End of inlined file: jconfig.h *********/
-
- /* widely used configuration options */
- #endif
-
- /********* Start of inlined file: jmorecfg.h *********/
- /*
- * 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 */
- /********* End of inlined file: 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
-
- /********* Start of inlined file: jpegint.h *********/
- /* Declarations for both compression & decompression */
-
- typedef enum { /* Operating modes for buffer controllers */
- JBUF_PASS_THRU, /* Plain stripwise operation */
- /* Remaining modes require a full-image buffer to have been created */
- JBUF_SAVE_SOURCE, /* Run source subobject only, save output */
- JBUF_CRANK_DEST, /* Run dest subobject only, using saved data */
- JBUF_SAVE_AND_PASS /* Run both subobjects, save output */
- } J_BUF_MODE;
-
- /* Values of global_state field (jdapi.c has some dependencies on ordering!) */
- #define CSTATE_START 100 /* after create_compress */
- #define CSTATE_SCANNING 101 /* start_compress done, write_scanlines OK */
- #define CSTATE_RAW_OK 102 /* start_compress done, write_raw_data OK */
- #define CSTATE_WRCOEFS 103 /* jpeg_write_coefficients done */
- #define DSTATE_START 200 /* after create_decompress */
- #define DSTATE_INHEADER 201 /* reading header markers, no SOS yet */
- #define DSTATE_READY 202 /* found SOS, ready for start_decompress */
- #define DSTATE_PRELOAD 203 /* reading multiscan file in start_decompress*/
- #define DSTATE_PRESCAN 204 /* performing dummy pass for 2-pass quant */
- #define DSTATE_SCANNING 205 /* start_decompress done, read_scanlines OK */
- #define DSTATE_RAW_OK 206 /* start_decompress done, read_raw_data OK */
- #define DSTATE_BUFIMAGE 207 /* expecting jpeg_start_output */
- #define DSTATE_BUFPOST 208 /* looking for SOS/EOI in jpeg_finish_output */
- #define DSTATE_RDCOEFS 209 /* reading file in jpeg_read_coefficients */
- #define DSTATE_STOPPING 210 /* looking for EOI in jpeg_finish_decompress */
-
- /* Declarations for compression modules */
-
- /* Master control module */
- struct jpeg_comp_master {
- JMETHOD(void, prepare_for_pass, (j_compress_ptr cinfo));
- JMETHOD(void, pass_startup, (j_compress_ptr cinfo));
- JMETHOD(void, finish_pass, (j_compress_ptr cinfo));
-
- /* State variables made visible to other modules */
- boolean call_pass_startup; /* True if pass_startup must be called */
- boolean is_last_pass; /* True during last pass */
- };
-
- /* Main buffer control (downsampled-data buffer) */
- struct jpeg_c_main_controller {
- JMETHOD(void, start_pass, (j_compress_ptr cinfo, J_BUF_MODE pass_mode));
- JMETHOD(void, process_data, (j_compress_ptr cinfo,
- JSAMPARRAY input_buf, JDIMENSION *in_row_ctr,
- JDIMENSION in_rows_avail));
- };
-
- /* Compression preprocessing (downsampling input buffer control) */
- struct jpeg_c_prep_controller {
- JMETHOD(void, start_pass, (j_compress_ptr cinfo, J_BUF_MODE pass_mode));
- JMETHOD(void, pre_process_data, (j_compress_ptr cinfo,
- JSAMPARRAY input_buf,
- JDIMENSION *in_row_ctr,
- JDIMENSION in_rows_avail,
- JSAMPIMAGE output_buf,
- JDIMENSION *out_row_group_ctr,
- JDIMENSION out_row_groups_avail));
- };
-
- /* Coefficient buffer control */
- struct jpeg_c_coef_controller {
- JMETHOD(void, start_pass, (j_compress_ptr cinfo, J_BUF_MODE pass_mode));
- JMETHOD(boolean, compress_data, (j_compress_ptr cinfo,
- JSAMPIMAGE input_buf));
- };
-
- /* Colorspace conversion */
- struct jpeg_color_converter {
- JMETHOD(void, start_pass, (j_compress_ptr cinfo));
- JMETHOD(void, color_convert, (j_compress_ptr cinfo,
- JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
- JDIMENSION output_row, int num_rows));
- };
-
- /* Downsampling */
- struct jpeg_downsampler {
- JMETHOD(void, start_pass, (j_compress_ptr cinfo));
- JMETHOD(void, downsample, (j_compress_ptr cinfo,
- JSAMPIMAGE input_buf, JDIMENSION in_row_index,
- JSAMPIMAGE output_buf,
- JDIMENSION out_row_group_index));
-
- boolean need_context_rows; /* TRUE if need rows above & below */
- };
-
- /* Forward DCT (also controls coefficient quantization) */
- struct jpeg_forward_dct {
- JMETHOD(void, start_pass, (j_compress_ptr cinfo));
- /* perhaps this should be an array??? */
- JMETHOD(void, forward_DCT, (j_compress_ptr cinfo,
- jpeg_component_info * compptr,
- JSAMPARRAY sample_data, JBLOCKROW coef_blocks,
- JDIMENSION start_row, JDIMENSION start_col,
- JDIMENSION num_blocks));
- };
-
- /* Entropy encoding */
- struct jpeg_entropy_encoder {
- JMETHOD(void, start_pass, (j_compress_ptr cinfo, boolean gather_statistics));
- JMETHOD(boolean, encode_mcu, (j_compress_ptr cinfo, JBLOCKROW *MCU_data));
- JMETHOD(void, finish_pass, (j_compress_ptr cinfo));
- };
-
- /* Marker writing */
- struct jpeg_marker_writer {
- JMETHOD(void, write_file_header, (j_compress_ptr cinfo));
- JMETHOD(void, write_frame_header, (j_compress_ptr cinfo));
- JMETHOD(void, write_scan_header, (j_compress_ptr cinfo));
- JMETHOD(void, write_file_trailer, (j_compress_ptr cinfo));
- JMETHOD(void, write_tables_only, (j_compress_ptr cinfo));
- /* These routines are exported to allow insertion of extra markers */
- /* Probably only COM and APPn markers should be written this way */
- JMETHOD(void, write_marker_header, (j_compress_ptr cinfo, int marker,
- unsigned int datalen));
- JMETHOD(void, write_marker_byte, (j_compress_ptr cinfo, int val));
- };
-
- /* Declarations for decompression modules */
-
- /* Master control module */
- struct jpeg_decomp_master {
- JMETHOD(void, prepare_for_output_pass, (j_decompress_ptr cinfo));
- JMETHOD(void, finish_output_pass, (j_decompress_ptr cinfo));
-
- /* State variables made visible to other modules */
- boolean is_dummy_pass; /* True during 1st pass for 2-pass quant */
- };
-
- /* Input control module */
- struct jpeg_input_controller {
- JMETHOD(int, consume_input, (j_decompress_ptr cinfo));
- JMETHOD(void, reset_input_controller, (j_decompress_ptr cinfo));
- JMETHOD(void, start_input_pass, (j_decompress_ptr cinfo));
- JMETHOD(void, finish_input_pass, (j_decompress_ptr cinfo));
-
- /* State variables made visible to other modules */
- boolean has_multiple_scans; /* True if file has multiple scans */
- boolean eoi_reached; /* True when EOI has been consumed */
- };
-
- /* Main buffer control (downsampled-data buffer) */
- struct jpeg_d_main_controller {
- JMETHOD(void, start_pass, (j_decompress_ptr cinfo, J_BUF_MODE pass_mode));
- JMETHOD(void, process_data, (j_decompress_ptr cinfo,
- JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
- JDIMENSION out_rows_avail));
- };
-
- /* Coefficient buffer control */
- struct jpeg_d_coef_controller {
- JMETHOD(void, start_input_pass, (j_decompress_ptr cinfo));
- JMETHOD(int, consume_data, (j_decompress_ptr cinfo));
- JMETHOD(void, start_output_pass, (j_decompress_ptr cinfo));
- JMETHOD(int, decompress_data, (j_decompress_ptr cinfo,
- JSAMPIMAGE output_buf));
- /* Pointer to array of coefficient virtual arrays, or NULL if none */
- jvirt_barray_ptr *coef_arrays;
- };
-
- /* Decompression postprocessing (color quantization buffer control) */
- struct jpeg_d_post_controller {
- JMETHOD(void, start_pass, (j_decompress_ptr cinfo, J_BUF_MODE pass_mode));
- JMETHOD(void, post_process_data, (j_decompress_ptr cinfo,
- JSAMPIMAGE input_buf,
- JDIMENSION *in_row_group_ctr,
- JDIMENSION in_row_groups_avail,
- JSAMPARRAY output_buf,
- JDIMENSION *out_row_ctr,
- JDIMENSION out_rows_avail));
- };
-
- /* Marker reading & parsing */
- struct jpeg_marker_reader {
- JMETHOD(void, reset_marker_reader, (j_decompress_ptr cinfo));
- /* Read markers until SOS or EOI.
- * Returns same codes as are defined for jpeg_consume_input:
- * JPEG_SUSPENDED, JPEG_REACHED_SOS, or JPEG_REACHED_EOI.
- */
- JMETHOD(int, read_markers, (j_decompress_ptr cinfo));
- /* Read a restart marker --- exported for use by entropy decoder only */
- jpeg_marker_parser_method read_restart_marker;
-
- /* State of marker reader --- nominally internal, but applications
- * supplying COM or APPn handlers might like to know the state.
- */
- boolean saw_SOI; /* found SOI? */
- boolean saw_SOF; /* found SOF? */
- int next_restart_num; /* next restart number expected (0-7) */
- unsigned int discarded_bytes; /* # of bytes skipped looking for a marker */
- };
-
- /* Entropy decoding */
- struct jpeg_entropy_decoder {
- JMETHOD(void, start_pass, (j_decompress_ptr cinfo));
- JMETHOD(boolean, decode_mcu, (j_decompress_ptr cinfo,
- JBLOCKROW *MCU_data));
-
- /* This is here to share code between baseline and progressive decoders; */
- /* other modules probably should not use it */
- boolean insufficient_data; /* set TRUE after emitting warning */
- };
-
- /* Inverse DCT (also performs dequantization) */
- typedef JMETHOD(void, inverse_DCT_method_ptr,
- (j_decompress_ptr cinfo, jpeg_component_info * compptr,
- JCOEFPTR coef_block,
- JSAMPARRAY output_buf, JDIMENSION output_col));
-
- struct jpeg_inverse_dct {
- JMETHOD(void, start_pass, (j_decompress_ptr cinfo));
- /* It is useful to allow each component to have a separate IDCT method. */
- inverse_DCT_method_ptr inverse_DCT[MAX_COMPONENTS];
- };
-
- /* Upsampling (note that upsampler must also call color converter) */
- struct jpeg_upsampler {
- JMETHOD(void, start_pass, (j_decompress_ptr cinfo));
- JMETHOD(void, upsample, (j_decompress_ptr cinfo,
- JSAMPIMAGE input_buf,
- JDIMENSION *in_row_group_ctr,
- JDIMENSION in_row_groups_avail,
- JSAMPARRAY output_buf,
- JDIMENSION *out_row_ctr,
- JDIMENSION out_rows_avail));
-
- boolean need_context_rows; /* TRUE if need rows above & below */
- };
-
- /* Colorspace conversion */
- struct jpeg_color_deconverter {
- JMETHOD(void, start_pass, (j_decompress_ptr cinfo));
- JMETHOD(void, color_convert, (j_decompress_ptr cinfo,
- JSAMPIMAGE input_buf, JDIMENSION input_row,
- JSAMPARRAY output_buf, int num_rows));
- };
-
- /* Color quantization or color precision reduction */
- struct jpeg_color_quantizer {
- JMETHOD(void, start_pass, (j_decompress_ptr cinfo, boolean is_pre_scan));
- JMETHOD(void, color_quantize, (j_decompress_ptr cinfo,
- JSAMPARRAY input_buf, JSAMPARRAY output_buf,
- int num_rows));
- JMETHOD(void, finish_pass, (j_decompress_ptr cinfo));
- JMETHOD(void, new_color_map, (j_decompress_ptr cinfo));
- };
-
- /* Miscellaneous useful macros */
-
- #undef MAX
- #define MAX(a,b) ((a) > (b) ? (a) : (b))
- #undef MIN
- #define MIN(a,b) ((a) < (b) ? (a) : (b))
-
- /* We assume that right shift corresponds to signed division by 2 with
- * rounding towards minus infinity. This is correct for typical "arithmetic
- * shift" instructions that shift in copies of the sign bit. But some
- * C compilers implement >> with an unsigned shift. For these machines you
- * must define RIGHT_SHIFT_IS_UNSIGNED.
- * RIGHT_SHIFT provides a proper signed right shift of an INT32 quantity.
- * It is only applied with constant shift counts. SHIFT_TEMPS must be
- * included in the variables of any routine using RIGHT_SHIFT.
- */
-
- #ifdef RIGHT_SHIFT_IS_UNSIGNED
- #define SHIFT_TEMPS INT32 shift_temp;
- #define RIGHT_SHIFT(x,shft) \
- ((shift_temp = (x)) < 0 ? \
- (shift_temp >> (shft)) | ((~((INT32) 0)) << (32-(shft))) : \
- (shift_temp >> (shft)))
- #else
- #define SHIFT_TEMPS
- #define RIGHT_SHIFT(x,shft) ((x) >> (shft))
- #endif
-
- /* Short forms of external names for systems with brain-damaged linkers. */
-
- #ifdef NEED_SHORT_EXTERNAL_NAMES
- #define jinit_compress_master jICompress
- #define jinit_c_master_control jICMaster
- #define jinit_c_main_controller jICMainC
- #define jinit_c_prep_controller jICPrepC
- #define jinit_c_coef_controller jICCoefC
- #define jinit_color_converter jICColor
- #define jinit_downsampler jIDownsampler
- #define jinit_forward_dct jIFDCT
- #define jinit_huff_encoder jIHEncoder
- #define jinit_phuff_encoder jIPHEncoder
- #define jinit_marker_writer jIMWriter
- #define jinit_master_decompress jIDMaster
- #define jinit_d_main_controller jIDMainC
- #define jinit_d_coef_controller jIDCoefC
- #define jinit_d_post_controller jIDPostC
- #define jinit_input_controller jIInCtlr
- #define jinit_marker_reader jIMReader
- #define jinit_huff_decoder jIHDecoder
- #define jinit_phuff_decoder jIPHDecoder
- #define jinit_inverse_dct jIIDCT
- #define jinit_upsampler jIUpsampler
- #define jinit_color_deconverter jIDColor
- #define jinit_1pass_quantizer jI1Quant
- #define jinit_2pass_quantizer jI2Quant
- #define jinit_merged_upsampler jIMUpsampler
- #define jinit_memory_mgr jIMemMgr
- #define jdiv_round_up jDivRound
- #define jround_up jRound
- #define jcopy_sample_rows jCopySamples
- #define jcopy_block_row jCopyBlocks
- #define jzero_far jZeroFar
- #define jpeg_zigzag_order jZIGTable
- #define jpeg_natural_order jZAGTable
- #endif /* NEED_SHORT_EXTERNAL_NAMES */
-
- /* Compression module initialization routines */
- EXTERN(void) jinit_compress_master JPP((j_compress_ptr cinfo));
- EXTERN(void) jinit_c_master_control JPP((j_compress_ptr cinfo,
- boolean transcode_only));
- EXTERN(void) jinit_c_main_controller JPP((j_compress_ptr cinfo,
- boolean need_full_buffer));
- EXTERN(void) jinit_c_prep_controller JPP((j_compress_ptr cinfo,
- boolean need_full_buffer));
- EXTERN(void) jinit_c_coef_controller JPP((j_compress_ptr cinfo,
- boolean need_full_buffer));
- EXTERN(void) jinit_color_converter JPP((j_compress_ptr cinfo));
- EXTERN(void) jinit_downsampler JPP((j_compress_ptr cinfo));
- EXTERN(void) jinit_forward_dct JPP((j_compress_ptr cinfo));
- EXTERN(void) jinit_huff_encoder JPP((j_compress_ptr cinfo));
- EXTERN(void) jinit_phuff_encoder JPP((j_compress_ptr cinfo));
- EXTERN(void) jinit_marker_writer JPP((j_compress_ptr cinfo));
- /* Decompression module initialization routines */
- EXTERN(void) jinit_master_decompress JPP((j_decompress_ptr cinfo));
- EXTERN(void) jinit_d_main_controller JPP((j_decompress_ptr cinfo,
- boolean need_full_buffer));
- EXTERN(void) jinit_d_coef_controller JPP((j_decompress_ptr cinfo,
- boolean need_full_buffer));
- EXTERN(void) jinit_d_post_controller JPP((j_decompress_ptr cinfo,
- boolean need_full_buffer));
- EXTERN(void) jinit_input_controller JPP((j_decompress_ptr cinfo));
- EXTERN(void) jinit_marker_reader JPP((j_decompress_ptr cinfo));
- EXTERN(void) jinit_huff_decoder JPP((j_decompress_ptr cinfo));
- EXTERN(void) jinit_phuff_decoder JPP((j_decompress_ptr cinfo));
- EXTERN(void) jinit_inverse_dct JPP((j_decompress_ptr cinfo));
- EXTERN(void) jinit_upsampler JPP((j_decompress_ptr cinfo));
- EXTERN(void) jinit_color_deconverter JPP((j_decompress_ptr cinfo));
- EXTERN(void) jinit_1pass_quantizer JPP((j_decompress_ptr cinfo));
- EXTERN(void) jinit_2pass_quantizer JPP((j_decompress_ptr cinfo));
- EXTERN(void) jinit_merged_upsampler JPP((j_decompress_ptr cinfo));
- /* Memory manager initialization */
- EXTERN(void) jinit_memory_mgr JPP((j_common_ptr cinfo));
-
- /* Utility routines in jutils.c */
- EXTERN(long) jdiv_round_up JPP((long a, long b));
- EXTERN(long) jround_up JPP((long a, long b));
- EXTERN(void) jcopy_sample_rows JPP((JSAMPARRAY input_array, int source_row,
- JSAMPARRAY output_array, int dest_row,
- int num_rows, JDIMENSION num_cols));
- EXTERN(void) jcopy_block_row JPP((JBLOCKROW input_row, JBLOCKROW output_row,
- JDIMENSION num_blocks));
- EXTERN(void) jzero_far JPP((void FAR * target, size_t bytestozero));
- /* Constant tables in jutils.c */
- #if 0 /* This table is not actually needed in v6a */
- extern const int jpeg_zigzag_order[]; /* natural coef order to zigzag order */
- #endif
- extern const int jpeg_natural_order[]; /* zigzag coef order to natural order */
-
- /* Suppress undefined-structure complaints if necessary. */
-
- #ifdef INCOMPLETE_TYPES_BROKEN
- #ifndef AM_MEMORY_MANAGER /* only jmemmgr.c defines these */
- struct jvirt_sarray_control { long dummy; };
- struct jvirt_barray_control { long dummy; };
- #endif
- #endif /* INCOMPLETE_TYPES_BROKEN */
- /********* End of inlined file: jpegint.h *********/
-
- /* fetch private declarations */
-
- /********* Start of inlined file: jerror.h *********/
- /*
- * 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 */
- /********* End of inlined file: jerror.h *********/
-
- /* fetch error codes too */
- #endif
-
- #endif /* JPEGLIB_H */
- /********* End of inlined file: jpeglib.h *********/
-
- /********* Start of inlined file: jcapimin.c *********/
- #define JPEG_INTERNALS
-
- /********* Start of inlined file: jinclude.h *********/
- /* Include auto-config file to find out which system include files we need. */
-
- #ifndef __jinclude_h__
- #define __jinclude_h__
-
- /********* Start of inlined file: jconfig.h *********/
- /* see jconfig.doc for explanations */
-
- // disable all the warnings under MSVC
- #ifdef _MSC_VER
- #pragma warning (disable: 4996 4267 4100 4127 4702 4244)
- #endif
-
- #ifdef __BORLANDC__
- #pragma warn -8057
- #pragma warn -8019
- #pragma warn -8004
- #pragma warn -8008
- #endif
-
- #define HAVE_PROTOTYPES
- #define HAVE_UNSIGNED_CHAR
- #define HAVE_UNSIGNED_SHORT
- /* #define void char */
- /* #define 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 /* we presume a 32-bit flat memory model */
- #undef NEED_SHORT_EXTERNAL_NAMES
- #undef INCOMPLETE_TYPES_BROKEN
-
- /* Define "boolean" as unsigned char, not int, per Windows custom */
- #ifndef __RPCNDR_H__ /* don't conflict if rpcndr.h already read */
- typedef unsigned char boolean;
- #endif
- #define HAVE_BOOLEAN /* prevent jmorecfg.h from redefining it */
-
- #ifdef JPEG_INTERNALS
-
- #undef RIGHT_SHIFT_IS_UNSIGNED
-
- #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 */
-
- #define TWO_FILE_COMMANDLINE /* optional */
- #define USE_SETMODE /* Microsoft has setmode() */
- #undef NEED_SIGNAL_CATCHER
- #undef DONT_USE_B_MODE
- #undef PROGRESS_REPORT /* optional */
-
- #endif /* JPEG_CJPEG_DJPEG */
- /********* End of inlined file: jconfig.h *********/
-
- /* auto configuration options */
- #define JCONFIG_INCLUDED /* so that jpeglib.h doesn't do it again */
-
- /*
- * We need the NULL macro and size_t typedef.
- * On an ANSI-conforming system it is sufficient to include <stddef.h>.
- * Otherwise, we get them from <stdlib.h> or <stdio.h>; we may have to
- * pull in <sys/types.h> as well.
- * Note that the core JPEG library does not require <stdio.h>;
- * only the default error handler and data source/destination modules do.
- * But we must pull it in because of the references to FILE in jpeglib.h.
- * You can remove those references if you want to compile without <stdio.h>.
- */
-
- #ifdef HAVE_STDDEF_H
- #include <stddef.h>
- #endif
-
- #ifdef HAVE_STDLIB_H
- #include <stdlib.h>
- #endif
-
- #ifdef NEED_SYS_TYPES_H
- #include <sys/types.h>
- #endif
-
- #include <stdio.h>
-
- /*
- * We need memory copying and zeroing functions, plus strncpy().
- * ANSI and System V implementations declare these in <string.h>.
- * BSD doesn't have the mem() functions, but it does have bcopy()/bzero().
- * Some systems may declare memset and memcpy in <memory.h>.
- *
- * NOTE: we assume the size parameters to these functions are of type size_t.
- * Change the casts in these macros if not!
- */
-
- #ifdef NEED_BSD_STRINGS
-
- #include <strings.h>
- #define MEMZERO(target,size) bzero((void *)(target), (size_t)(size))
- #define MEMCOPY(dest,src,size) bcopy((const void *)(src), (void *)(dest), (size_t)(size))
-
- #else /* not BSD, assume ANSI/SysV string lib */
-
- #include <string.h>
- #define MEMZERO(target,size) memset((void *)(target), 0, (size_t)(size))
- #define MEMCOPY(dest,src,size) memcpy((void *)(dest), (const void *)(src), (size_t)(size))
-
- #endif
-
- /*
- * In ANSI C, and indeed any rational implementation, size_t is also the
- * type returned by sizeof(). However, it seems there are some irrational
- * implementations out there, in which sizeof() returns an int even though
- * size_t is defined as long or unsigned long. To ensure consistent results
- * we always use this SIZEOF() macro in place of using sizeof() directly.
- */
-
- #define SIZEOF(object) ((size_t) sizeof(object))
-
- /*
- * The modules that use fread() and fwrite() always invoke them through
- * these macros. On some systems you may need to twiddle the argument casts.
- * CAUTION: argument order is different from underlying functions!
- */
-
- #define JFREAD(file,buf,sizeofbuf) \
- ((size_t) fread((void *) (buf), (size_t) 1, (size_t) (sizeofbuf), (file)))
- #define JFWRITE(file,buf,sizeofbuf) \
- ((size_t) fwrite((const void *) (buf), (size_t) 1, (size_t) (sizeofbuf), (file)))
-
- typedef enum { /* JPEG marker codes */
- M_SOF0 = 0xc0,
- M_SOF1 = 0xc1,
- M_SOF2 = 0xc2,
- M_SOF3 = 0xc3,
-
- M_SOF5 = 0xc5,
- M_SOF6 = 0xc6,
- M_SOF7 = 0xc7,
-
- M_JPG = 0xc8,
- M_SOF9 = 0xc9,
- M_SOF10 = 0xca,
- M_SOF11 = 0xcb,
-
- M_SOF13 = 0xcd,
- M_SOF14 = 0xce,
- M_SOF15 = 0xcf,
-
- M_DHT = 0xc4,
-
- M_DAC = 0xcc,
-
- M_RST0 = 0xd0,
- M_RST1 = 0xd1,
- M_RST2 = 0xd2,
- M_RST3 = 0xd3,
- M_RST4 = 0xd4,
- M_RST5 = 0xd5,
- M_RST6 = 0xd6,
- M_RST7 = 0xd7,
-
- M_SOI = 0xd8,
- M_EOI = 0xd9,
- M_SOS = 0xda,
- M_DQT = 0xdb,
- M_DNL = 0xdc,
- M_DRI = 0xdd,
- M_DHP = 0xde,
- M_EXP = 0xdf,
-
- M_APP0 = 0xe0,
- M_APP1 = 0xe1,
- M_APP2 = 0xe2,
- M_APP3 = 0xe3,
- M_APP4 = 0xe4,
- M_APP5 = 0xe5,
- M_APP6 = 0xe6,
- M_APP7 = 0xe7,
- M_APP8 = 0xe8,
- M_APP9 = 0xe9,
- M_APP10 = 0xea,
- M_APP11 = 0xeb,
- M_APP12 = 0xec,
- M_APP13 = 0xed,
- M_APP14 = 0xee,
- M_APP15 = 0xef,
-
- M_JPG0 = 0xf0,
- M_JPG13 = 0xfd,
- M_COM = 0xfe,
-
- M_TEM = 0x01,
-
- M_ERROR = 0x100
- } JPEG_MARKER;
-
- /*
- * Figure F.12: extend sign bit.
- * On some machines, a shift and add will be faster than a table lookup.
- */
-
- #ifdef AVOID_TABLES
-
- #define HUFF_EXTEND(x,s) ((x) < (1<<((s)-1)) ? (x) + (((-1)<<(s)) + 1) : (x))
-
- #else
-
- #define HUFF_EXTEND(x,s) ((x) < extend_test[s] ? (x) + extend_offset[s] : (x))
-
- static const int extend_test[16] = /* entry n is 2**(n-1) */
- { 0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
- 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000 };
-
- static const int extend_offset[16] = /* entry n is (-1 << n) + 1 */
- { 0, ((-1)<<1) + 1, ((-1)<<2) + 1, ((-1)<<3) + 1, ((-1)<<4) + 1,
- ((-1)<<5) + 1, ((-1)<<6) + 1, ((-1)<<7) + 1, ((-1)<<8) + 1,
- ((-1)<<9) + 1, ((-1)<<10) + 1, ((-1)<<11) + 1, ((-1)<<12) + 1,
- ((-1)<<13) + 1, ((-1)<<14) + 1, ((-1)<<15) + 1 };
-
- #endif /* AVOID_TABLES */
-
- #endif
- /********* End of inlined file: jinclude.h *********/
-
- /*
- * Initialization of a JPEG compression object.
- * The error manager must already be set up (in case memory manager fails).
- */
-
- GLOBAL(void)
- jpeg_CreateCompress (j_compress_ptr cinfo, int version, size_t structsize)
- {
- int i;
-
- /* Guard against version mismatches between library and caller. */
- cinfo->mem = NULL; /* so jpeg_destroy knows mem mgr not called */
- if (version != JPEG_LIB_VERSION)
- ERREXIT2(cinfo, JERR_BAD_LIB_VERSION, JPEG_LIB_VERSION, version);
- if (structsize != SIZEOF(struct jpeg_compress_struct))
- ERREXIT2(cinfo, JERR_BAD_STRUCT_SIZE,
- (int) SIZEOF(struct jpeg_compress_struct), (int) structsize);
-
- /* For debugging purposes, we zero the whole master structure.
- * But the application has already set the err pointer, and may have set
- * client_data, so we have to save and restore those fields.
- * Note: if application hasn't set client_data, tools like Purify may
- * complain here.
- */
- {
- struct jpeg_error_mgr * err = cinfo->err;
- void * client_data = cinfo->client_data; /* ignore Purify complaint here */
- MEMZERO(cinfo, SIZEOF(struct jpeg_compress_struct));
- cinfo->err = err;
- cinfo->client_data = client_data;
- }
- cinfo->is_decompressor = FALSE;
-
- /* Initialize a memory manager instance for this object */
- jinit_memory_mgr((j_common_ptr) cinfo);
-
- /* Zero out pointers to permanent structures. */
- cinfo->progress = NULL;
- cinfo->dest = NULL;
-
- cinfo->comp_info = NULL;
-
- for (i = 0; i < NUM_QUANT_TBLS; i++)
- cinfo->quant_tbl_ptrs[i] = NULL;
-
- for (i = 0; i < NUM_HUFF_TBLS; i++) {
- cinfo->dc_huff_tbl_ptrs[i] = NULL;
- cinfo->ac_huff_tbl_ptrs[i] = NULL;
- }
-
- cinfo->script_space = NULL;
-
- cinfo->input_gamma = 1.0; /* in case application forgets */
-
- /* OK, I'm ready */
- cinfo->global_state = CSTATE_START;
- }
-
- /*
- * Destruction of a JPEG compression object
- */
-
- GLOBAL(void)
- jpeg_destroy_compress (j_compress_ptr cinfo)
- {
- jpeg_destroy((j_common_ptr) cinfo); /* use common routine */
- }
-
- /*
- * Abort processing of a JPEG compression operation,
- * but don't destroy the object itself.
- */
-
- GLOBAL(void)
- jpeg_abort_compress (j_compress_ptr cinfo)
- {
- jpeg_abort((j_common_ptr) cinfo); /* use common routine */
- }
-
- /*
- * Forcibly suppress or un-suppress all quantization and Huffman tables.
- * Marks all currently defined tables as already written (if suppress)
- * or not written (if !suppress). This will control whether they get emitted
- * by a subsequent jpeg_start_compress call.
- *
- * This routine is exported for use by applications that want to produce
- * abbreviated JPEG datastreams. It logically belongs in jcparam.c, but
- * since it is called by jpeg_start_compress, we put it here --- otherwise
- * jcparam.o would be linked whether the application used it or not.
- */
-
- GLOBAL(void)
- jpeg_suppress_tables (j_compress_ptr cinfo, boolean suppress)
- {
- int i;
- JQUANT_TBL * qtbl;
- JHUFF_TBL * htbl;
-
- for (i = 0; i < NUM_QUANT_TBLS; i++) {
- if ((qtbl = cinfo->quant_tbl_ptrs[i]) != NULL)
- qtbl->sent_table = suppress;
- }
-
- for (i = 0; i < NUM_HUFF_TBLS; i++) {
- if ((htbl = cinfo->dc_huff_tbl_ptrs[i]) != NULL)
- htbl->sent_table = suppress;
- if ((htbl = cinfo->ac_huff_tbl_ptrs[i]) != NULL)
- htbl->sent_table = suppress;
- }
- }
-
- /*
- * Finish JPEG compression.
- *
- * If a multipass operating mode was selected, this may do a great deal of
- * work including most of the actual output.
- */
-
- GLOBAL(void)
- jpeg_finish_compress (j_compress_ptr cinfo)
- {
- JDIMENSION iMCU_row;
-
- if (cinfo->global_state == CSTATE_SCANNING ||
- cinfo->global_state == CSTATE_RAW_OK) {
- /* Terminate first pass */
- if (cinfo->next_scanline < cinfo->image_height)
- ERREXIT(cinfo, JERR_TOO_LITTLE_DATA);
- (*cinfo->master->finish_pass) (cinfo);
- } else if (cinfo->global_state != CSTATE_WRCOEFS)
- ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
- /* Perform any remaining passes */
- while (! cinfo->master->is_last_pass) {
- (*cinfo->master->prepare_for_pass) (cinfo);
- for (iMCU_row = 0; iMCU_row < cinfo->total_iMCU_rows; iMCU_row++) {
- if (cinfo->progress != NULL) {
- cinfo->progress->pass_counter = (long) iMCU_row;
- cinfo->progress->pass_limit = (long) cinfo->total_iMCU_rows;
- (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
- }
- /* We bypass the main controller and invoke coef controller directly;
- * all work is being done from the coefficient buffer.
- */
- if (! (*cinfo->coef->compress_data) (cinfo, (JSAMPIMAGE) NULL))
- ERREXIT(cinfo, JERR_CANT_SUSPEND);
- }
- (*cinfo->master->finish_pass) (cinfo);
- }
- /* Write EOI, do final cleanup */
- (*cinfo->marker->write_file_trailer) (cinfo);
- (*cinfo->dest->term_destination) (cinfo);
- /* We can use jpeg_abort to release memory and reset global_state */
- jpeg_abort((j_common_ptr) cinfo);
- }
-
- /*
- * Write a special marker.
- * This is only recommended for writing COM or APPn markers.
- * Must be called after jpeg_start_compress() and before
- * first call to jpeg_write_scanlines() or jpeg_write_raw_data().
- */
-
- GLOBAL(void)
- jpeg_write_marker (j_compress_ptr cinfo, int marker,
- const JOCTET *dataptr, unsigned int datalen)
- {
- JMETHOD(void, write_marker_byte, (j_compress_ptr info, int val));
-
- if (cinfo->next_scanline != 0 ||
- (cinfo->global_state != CSTATE_SCANNING &&
- cinfo->global_state != CSTATE_RAW_OK &&
- cinfo->global_state != CSTATE_WRCOEFS))
- ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
-
- (*cinfo->marker->write_marker_header) (cinfo, marker, datalen);
- write_marker_byte = cinfo->marker->write_marker_byte; /* copy for speed */
- while (datalen--) {
- (*write_marker_byte) (cinfo, *dataptr);
- dataptr++;
- }
- }
-
- /* Same, but piecemeal. */
-
- GLOBAL(void)
- jpeg_write_m_header (j_compress_ptr cinfo, int marker, unsigned int datalen)
- {
- if (cinfo->next_scanline != 0 ||
- (cinfo->global_state != CSTATE_SCANNING &&
- cinfo->global_state != CSTATE_RAW_OK &&
- cinfo->global_state != CSTATE_WRCOEFS))
- ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
-
- (*cinfo->marker->write_marker_header) (cinfo, marker, datalen);
- }
-
- GLOBAL(void)
- jpeg_write_m_byte (j_compress_ptr cinfo, int val)
- {
- (*cinfo->marker->write_marker_byte) (cinfo, val);
- }
-
- /*
- * Alternate compression function: just write an abbreviated table file.
- * Before calling this, all parameters and a data destination must be set up.
- *
- * To produce a pair of files containing abbreviated tables and abbreviated
- * image data, one would proceed as follows:
- *
- * initialize JPEG object
- * set JPEG parameters
- * set destination to table file
- * jpeg_write_tables(cinfo);
- * set destination to image file
- * jpeg_start_compress(cinfo, FALSE);
- * write data...
- * jpeg_finish_compress(cinfo);
- *
- * jpeg_write_tables has the side effect of marking all tables written
- * (same as jpeg_suppress_tables(..., TRUE)). Thus a subsequent start_compress
- * will not re-emit the tables unless it is passed write_all_tables=TRUE.
- */
-
- GLOBAL(void)
- jpeg_write_tables (j_compress_ptr cinfo)
- {
- if (cinfo->global_state != CSTATE_START)
- ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
-
- /* (Re)initialize error mgr and destination modules */
- (*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo);
- (*cinfo->dest->init_destination) (cinfo);
- /* Initialize the marker writer ... bit of a crock to do it here. */
- jinit_marker_writer(cinfo);
- /* Write them tables! */
- (*cinfo->marker->write_tables_only) (cinfo);
- /* And clean up. */
- (*cinfo->dest->term_destination) (cinfo);
- /*
- * In library releases up through v6a, we called jpeg_abort() here to free
- * any working memory allocated by the destination manager and marker
- * writer. Some applications had a problem with that: they allocated space
- * of their own from the library memory manager, and didn't want it to go
- * away during write_tables. So now we do nothing. This will cause a
- * memory leak if an app calls write_tables repeatedly without doing a full
- * compression cycle or otherwise resetting the JPEG object. However, that
- * seems less bad than unexpectedly freeing memory in the normal case.
- * An app that prefers the old behavior can call jpeg_abort for itself after
- * each call to jpeg_write_tables().
- */
- }
- /********* End of inlined file: jcapimin.c *********/
-
- /********* Start of inlined file: jcapistd.c *********/
- #define JPEG_INTERNALS
-
- /*
- * Compression initialization.
- * Before calling this, all parameters and a data destination must be set up.
- *
- * We require a write_all_tables parameter as a failsafe check when writing
- * multiple datastreams from the same compression object. Since prior runs
- * will have left all the tables marked sent_table=TRUE, a subsequent run
- * would emit an abbreviated stream (no tables) by default. This may be what
- * is wanted, but for safety's sake it should not be the default behavior:
- * programmers should have to make a deliberate choice to emit abbreviated
- * images. Therefore the documentation and examples should encourage people
- * to pass write_all_tables=TRUE; then it will take active thought to do the
- * wrong thing.
- */
-
- GLOBAL(void)
- jpeg_start_compress (j_compress_ptr cinfo, boolean write_all_tables)
- {
- if (cinfo->global_state != CSTATE_START)
- ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
-
- if (write_all_tables)
- jpeg_suppress_tables(cinfo, FALSE); /* mark all tables to be written */
-
- /* (Re)initialize error mgr and destination modules */
- (*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo);
- (*cinfo->dest->init_destination) (cinfo);
- /* Perform master selection of active modules */
- jinit_compress_master(cinfo);
- /* Set up for the first pass */
- (*cinfo->master->prepare_for_pass) (cinfo);
- /* Ready for application to drive first pass through jpeg_write_scanlines
- * or jpeg_write_raw_data.
- */
- cinfo->next_scanline = 0;
- cinfo->global_state = (cinfo->raw_data_in ? CSTATE_RAW_OK : CSTATE_SCANNING);
- }
-
- /*
- * Write some scanlines of data to the JPEG compressor.
- *
- * The return value will be the number of lines actually written.
- * This should be less than the supplied num_lines only in case that
- * the data destination module has requested suspension of the compressor,
- * or if more than image_height scanlines are passed in.
- *
- * Note: we warn about excess calls to jpeg_write_scanlines() since
- * this likely signals an application programmer error. However,
- * excess scanlines passed in the last valid call are *silently* ignored,
- * so that the application need not adjust num_lines for end-of-image
- * when using a multiple-scanline buffer.
- */
-
- GLOBAL(JDIMENSION)
- jpeg_write_scanlines (j_compress_ptr cinfo, JSAMPARRAY scanlines,
- JDIMENSION num_lines)
- {
- JDIMENSION row_ctr, rows_left;
-
- if (cinfo->global_state != CSTATE_SCANNING)
- ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
- if (cinfo->next_scanline >= cinfo->image_height)
- WARNMS(cinfo, JWRN_TOO_MUCH_DATA);
-
- /* Call progress monitor hook if present */
- if (cinfo->progress != NULL) {
- cinfo->progress->pass_counter = (long) cinfo->next_scanline;
- cinfo->progress->pass_limit = (long) cinfo->image_height;
- (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
- }
-
- /* Give master control module another chance if this is first call to
- * jpeg_write_scanlines. This lets output of the frame/scan headers be
- * delayed so that application can write COM, etc, markers between
- * jpeg_start_compress and jpeg_write_scanlines.
- */
- if (cinfo->master->call_pass_startup)
- (*cinfo->master->pass_startup) (cinfo);
-
- /* Ignore any extra scanlines at bottom of image. */
- rows_left = cinfo->image_height - cinfo->next_scanline;
- if (num_lines > rows_left)
- num_lines = rows_left;
-
- row_ctr = 0;
- (*cinfo->main->process_data) (cinfo, scanlines, &row_ctr, num_lines);
- cinfo->next_scanline += row_ctr;
- return row_ctr;
- }
-
- /*
- * Alternate entry point to write raw data.
- * Processes exactly one iMCU row per call, unless suspended.
- */
-
- GLOBAL(JDIMENSION)
- jpeg_write_raw_data (j_compress_ptr cinfo, JSAMPIMAGE data,
- JDIMENSION num_lines)
- {
- JDIMENSION lines_per_iMCU_row;
-
- if (cinfo->global_state != CSTATE_RAW_OK)
- ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
- if (cinfo->next_scanline >= cinfo->image_height) {
- WARNMS(cinfo, JWRN_TOO_MUCH_DATA);
- return 0;
- }
-
- /* Call progress monitor hook if present */
- if (cinfo->progress != NULL) {
- cinfo->progress->pass_counter = (long) cinfo->next_scanline;
- cinfo->progress->pass_limit = (long) cinfo->image_height;
- (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
- }
-
- /* Give master control module another chance if this is first call to
- * jpeg_write_raw_data. This lets output of the frame/scan headers be
- * delayed so that application can write COM, etc, markers between
- * jpeg_start_compress and jpeg_write_raw_data.
- */
- if (cinfo->master->call_pass_startup)
- (*cinfo->master->pass_startup) (cinfo);
-
- /* Verify that at least one iMCU row has been passed. */
- lines_per_iMCU_row = cinfo->max_v_samp_factor * DCTSIZE;
- if (num_lines < lines_per_iMCU_row)
- ERREXIT(cinfo, JERR_BUFFER_SIZE);
-
- /* Directly compress the row. */
- if (! (*cinfo->coef->compress_data) (cinfo, data)) {
- /* If compressor did not consume the whole row, suspend processing. */
- return 0;
- }
-
- /* OK, we processed one iMCU row. */
- cinfo->next_scanline += lines_per_iMCU_row;
- return lines_per_iMCU_row;
- }
- /********* End of inlined file: jcapistd.c *********/
-
- /********* Start of inlined file: jccoefct.c *********/
- #define JPEG_INTERNALS
-
- /* We use a full-image coefficient buffer when doing Huffman optimization,
- * and also for writing multiple-scan JPEG files. In all cases, the DCT
- * step is run during the first pass, and subsequent passes need only read
- * the buffered coefficients.
- */
- #ifdef ENTROPY_OPT_SUPPORTED
- #define FULL_COEF_BUFFER_SUPPORTED
- #else
- #ifdef C_MULTISCAN_FILES_SUPPORTED
- #define FULL_COEF_BUFFER_SUPPORTED
- #endif
- #endif
-
- /* Private buffer controller object */
-
- typedef struct {
- struct jpeg_c_coef_controller pub; /* public fields */
-
- JDIMENSION iMCU_row_num; /* iMCU row # within image */
- JDIMENSION mcu_ctr; /* counts MCUs processed in current row */
- int MCU_vert_offset; /* counts MCU rows within iMCU row */
- int MCU_rows_per_iMCU_row; /* number of such rows needed */
-
- /* For single-pass compression, it's sufficient to buffer just one MCU
- * (although this may prove a bit slow in practice). We allocate a
- * workspace of C_MAX_BLOCKS_IN_MCU coefficient blocks, and reuse it for each
- * MCU constructed and sent. (On 80x86, the workspace is FAR even though
- * it's not really very big; this is to keep the module interfaces unchanged
- * when a large coefficient buffer is necessary.)
- * In multi-pass modes, this array points to the current MCU's blocks
- * within the virtual arrays.
- */
- JBLOCKROW MCU_buffer[C_MAX_BLOCKS_IN_MCU];
-
- /* In multi-pass modes, we need a virtual block array for each component. */
- jvirt_barray_ptr whole_image[MAX_COMPONENTS];
- } my_coef_controller;
-
- typedef my_coef_controller * my_coef_ptr;
-
- /* Forward declarations */
- METHODDEF(boolean) compress_data
- JPP((j_compress_ptr cinfo, JSAMPIMAGE input_buf));
- #ifdef FULL_COEF_BUFFER_SUPPORTED
- METHODDEF(boolean) compress_first_pass
- JPP((j_compress_ptr cinfo, JSAMPIMAGE input_buf));
- METHODDEF(boolean) compress_output
- JPP((j_compress_ptr cinfo, JSAMPIMAGE input_buf));
- #endif
-
- LOCAL(void)
- start_iMCU_row (j_compress_ptr cinfo)
- /* Reset within-iMCU-row counters for a new row */
- {
- my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
-
- /* In an interleaved scan, an MCU row is the same as an iMCU row.
- * In a noninterleaved scan, an iMCU row has v_samp_factor MCU rows.
- * But at the bottom of the image, process only what's left.
- */
- if (cinfo->comps_in_scan > 1) {
- coef->MCU_rows_per_iMCU_row = 1;
- } else {
- if (coef->iMCU_row_num < (cinfo->total_iMCU_rows-1))
- coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->v_samp_factor;
- else
- coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->last_row_height;
- }
-
- coef->mcu_ctr = 0;
- coef->MCU_vert_offset = 0;
- }
-
- /*
- * Initialize for a processing pass.
- */
-
- METHODDEF(void)
- start_pass_coef (j_compress_ptr cinfo, J_BUF_MODE pass_mode)
- {
- my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
-
- coef->iMCU_row_num = 0;
- start_iMCU_row(cinfo);
-
- switch (pass_mode) {
- case JBUF_PASS_THRU:
- if (coef->whole_image[0] != NULL)
- ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
- coef->pub.compress_data = compress_data;
- break;
- #ifdef FULL_COEF_BUFFER_SUPPORTED
- case JBUF_SAVE_AND_PASS:
- if (coef->whole_image[0] == NULL)
- ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
- coef->pub.compress_data = compress_first_pass;
- break;
- case JBUF_CRANK_DEST:
- if (coef->whole_image[0] == NULL)
- ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
- coef->pub.compress_data = compress_output;
- break;
- #endif
- default:
- ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
- break;
- }
- }
-
- /*
- * Process some data in the single-pass case.
- * We process the equivalent of one fully interleaved MCU row ("iMCU" row)
- * per call, ie, v_samp_factor block rows for each component in the image.
- * Returns TRUE if the iMCU row is completed, FALSE if suspended.
- *
- * NB: input_buf contains a plane for each component in image,
- * which we index according to the component's SOF position.
- */
-
- METHODDEF(boolean)
- compress_data (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
- {
- my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
- JDIMENSION MCU_col_num; /* index of current MCU within row */
- JDIMENSION last_MCU_col = cinfo->MCUs_per_row - 1;
- JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
- int blkn, bi, ci, yindex, yoffset, blockcnt;
- JDIMENSION ypos, xpos;
- jpeg_component_info *compptr;
-
- /* Loop to write as much as one whole iMCU row */
- for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row;
- yoffset++) {
- for (MCU_col_num = coef->mcu_ctr; MCU_col_num <= last_MCU_col;
- MCU_col_num++) {
- /* Determine where data comes from in input_buf and do the DCT thing.
- * Each call on forward_DCT processes a horizontal row of DCT blocks
- * as wide as an MCU; we rely on having allocated the MCU_buffer[] blocks
- * sequentially. Dummy blocks at the right or bottom edge are filled in
- * specially. The data in them does not matter for image reconstruction,
- * so we fill them with values that will encode to the smallest amount of
- * data, viz: all zeroes in the AC entries, DC entries equal to previous
- * block's DC value. (Thanks to Thomas Kinsman for this idea.)
- */
- blkn = 0;
- for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
- compptr = cinfo->cur_comp_info[ci];
- blockcnt = (MCU_col_num < last_MCU_col) ? compptr->MCU_width
- : compptr->last_col_width;
- xpos = MCU_col_num * compptr->MCU_sample_width;
- ypos = yoffset * DCTSIZE; /* ypos == (yoffset+yindex) * DCTSIZE */
- for (yindex = 0; yindex < compptr->MCU_height; yindex++) {
- if (coef->iMCU_row_num < last_iMCU_row ||
- yoffset+yindex < compptr->last_row_height) {
- (*cinfo->fdct->forward_DCT) (cinfo, compptr,
- input_buf[compptr->component_index],
- coef->MCU_buffer[blkn],
- ypos, xpos, (JDIMENSION) blockcnt);
- if (blockcnt < compptr->MCU_width) {
- /* Create some dummy blocks at the right edge of the image. */
- jzero_far((void FAR *) coef->MCU_buffer[blkn + blockcnt],
- (compptr->MCU_width - blockcnt) * SIZEOF(JBLOCK));
- for (bi = blockcnt; bi < compptr->MCU_width; bi++) {
- coef->MCU_buffer[blkn+bi][0][0] = coef->MCU_buffer[blkn+bi-1][0][0];
- }
- }
- } else {
- /* Create a row of dummy blocks at the bottom of the image. */
- jzero_far((void FAR *) coef->MCU_buffer[blkn],
- compptr->MCU_width * SIZEOF(JBLOCK));
- for (bi = 0; bi < compptr->MCU_width; bi++) {
- coef->MCU_buffer[blkn+bi][0][0] = coef->MCU_buffer[blkn-1][0][0];
- }
- }
- blkn += compptr->MCU_width;
- ypos += DCTSIZE;
- }
- }
- /* Try to write the MCU. In event of a suspension failure, we will
- * re-DCT the MCU on restart (a bit inefficient, could be fixed...)
- */
- if (! (*cinfo->entropy->encode_mcu) (cinfo, coef->MCU_buffer)) {
- /* Suspension forced; update state counters and exit */
- coef->MCU_vert_offset = yoffset;
- coef->mcu_ctr = MCU_col_num;
- return FALSE;
- }
- }
- /* Completed an MCU row, but perhaps not an iMCU row */
- coef->mcu_ctr = 0;
- }
- /* Completed the iMCU row, advance counters for next one */
- coef->iMCU_row_num++;
- start_iMCU_row(cinfo);
- return TRUE;
- }
-
- #ifdef FULL_COEF_BUFFER_SUPPORTED
-
- /*
- * Process some data in the first pass of a multi-pass case.
- * We process the equivalent of one fully interleaved MCU row ("iMCU" row)
- * per call, ie, v_samp_factor block rows for each component in the image.
- * This amount of data is read from the source buffer, DCT'd and quantized,
- * and saved into the virtual arrays. We also generate suitable dummy blocks
- * as needed at the right and lower edges. (The dummy blocks are constructed
- * in the virtual arrays, which have been padded appropriately.) This makes
- * it possible for subsequent passes not to worry about real vs. dummy blocks.
- *
- * We must also emit the data to the entropy encoder. This is conveniently
- * done by calling compress_output() after we've loaded the current strip
- * of the virtual arrays.
- *
- * NB: input_buf contains a plane for each component in image. All
- * components are DCT'd and loaded into the virtual arrays in this pass.
- * However, it may be that only a subset of the components are emitted to
- * the entropy encoder during this first pass; be careful about looking
- * at the scan-dependent variables (MCU dimensions, etc).
- */
-
- METHODDEF(boolean)
- compress_first_pass (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
- {
- my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
- JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
- JDIMENSION blocks_across, MCUs_across, MCUindex;
- int bi, ci, h_samp_factor, block_row, block_rows, ndummy;
- JCOEF lastDC;
- jpeg_component_info *compptr;
- JBLOCKARRAY buffer;
- JBLOCKROW thisblockrow, lastblockrow;
-
- for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
- ci++, compptr++) {
- /* Align the virtual buffer for this component. */
- buffer = (*cinfo->mem->access_virt_barray)
- ((j_common_ptr) cinfo, coef->whole_image[ci],
- coef->iMCU_row_num * compptr->v_samp_factor,
- (JDIMENSION) compptr->v_samp_factor, TRUE);
- /* Count non-dummy DCT block rows in this iMCU row. */
- if (coef->iMCU_row_num < last_iMCU_row)
- block_rows = compptr->v_samp_factor;
- else {
- /* NB: can't use last_row_height here, since may not be set! */
- block_rows = (int) (compptr->height_in_blocks % compptr->v_samp_factor);
- if (block_rows == 0) block_rows = compptr->v_samp_factor;
- }
- blocks_across = compptr->width_in_blocks;
- h_samp_factor = compptr->h_samp_factor;
- /* Count number of dummy blocks to be added at the right margin. */
- ndummy = (int) (blocks_across % h_samp_factor);
- if (ndummy > 0)
- ndummy = h_samp_factor - ndummy;
- /* Perform DCT for all non-dummy blocks in this iMCU row. Each call
- * on forward_DCT processes a complete horizontal row of DCT blocks.
- */
- for (block_row = 0; block_row < block_rows; block_row++) {
- thisblockrow = buffer[block_row];
- (*cinfo->fdct->forward_DCT) (cinfo, compptr,
- input_buf[ci], thisblockrow,
- (JDIMENSION) (block_row * DCTSIZE),
- (JDIMENSION) 0, blocks_across);
- if (ndummy > 0) {
- /* Create dummy blocks at the right edge of the image. */
- thisblockrow += blocks_across; /* => first dummy block */
- jzero_far((void FAR *) thisblockrow, ndummy * SIZEOF(JBLOCK));
- lastDC = thisblockrow[-1][0];
- for (bi = 0; bi < ndummy; bi++) {
- thisblockrow[bi][0] = lastDC;
- }
- }
- }
- /* If at end of image, create dummy block rows as needed.
- * The tricky part here is that within each MCU, we want the DC values
- * of the dummy blocks to match the last real block's DC value.
- * This squeezes a few more bytes out of the resulting file...
- */
- if (coef->iMCU_row_num == last_iMCU_row) {
- blocks_across += ndummy; /* include lower right corner */
- MCUs_across = blocks_across / h_samp_factor;
- for (block_row = block_rows; block_row < compptr->v_samp_factor;
- block_row++) {
- thisblockrow = buffer[block_row];
- lastblockrow = buffer[block_row-1];
- jzero_far((void FAR *) thisblockrow,
- (size_t) (blocks_across * SIZEOF(JBLOCK)));
- for (MCUindex = 0; MCUindex < MCUs_across; MCUindex++) {
- lastDC = lastblockrow[h_samp_factor-1][0];
- for (bi = 0; bi < h_samp_factor; bi++) {
- thisblockrow[bi][0] = lastDC;
- }
- thisblockrow += h_samp_factor; /* advance to next MCU in row */
- lastblockrow += h_samp_factor;
- }
- }
- }
- }
- /* NB: compress_output will increment iMCU_row_num if successful.
- * A suspension return will result in redoing all the work above next time.
- */
-
- /* Emit data to the entropy encoder, sharing code with subsequent passes */
- return compress_output(cinfo, input_buf);
- }
-
- /*
- * Process some data in subsequent passes of a multi-pass case.
- * We process the equivalent of one fully interleaved MCU row ("iMCU" row)
- * per call, ie, v_samp_factor block rows for each component in the scan.
- * The data is obtained from the virtual arrays and fed to the entropy coder.
- * Returns TRUE if the iMCU row is completed, FALSE if suspended.
- *
- * NB: input_buf is ignored; it is likely to be a NULL pointer.
- */
-
- METHODDEF(boolean)
- compress_output (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
- {
- my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
- JDIMENSION MCU_col_num; /* index of current MCU within row */
- int blkn, ci, xindex, yindex, yoffset;
- JDIMENSION start_col;
- JBLOCKARRAY buffer[MAX_COMPS_IN_SCAN];
- JBLOCKROW buffer_ptr;
- jpeg_component_info *compptr;
-
- /* Align the virtual buffers for the components used in this scan.
- * NB: during first pass, this is safe only because the buffers will
- * already be aligned properly, so jmemmgr.c won't need to do any I/O.
- */
- for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
- compptr = cinfo->cur_comp_info[ci];
- buffer[ci] = (*cinfo->mem->access_virt_barray)
- ((j_common_ptr) cinfo, coef->whole_image[compptr->component_index],
- coef->iMCU_row_num * compptr->v_samp_factor,
- (JDIMENSION) compptr->v_samp_factor, FALSE);
- }
-
- /* Loop to process one whole iMCU row */
- for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row;
- yoffset++) {
- for (MCU_col_num = coef->mcu_ctr; MCU_col_num < cinfo->MCUs_per_row;
- MCU_col_num++) {
- /* Construct list of pointers to DCT blocks belonging to this MCU */
- blkn = 0; /* index of current DCT block within MCU */
- for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
- compptr = cinfo->cur_comp_info[ci];
- start_col = MCU_col_num * compptr->MCU_width;
- for (yindex = 0; yindex < compptr->MCU_height; yindex++) {
- buffer_ptr = buffer[ci][yindex+yoffset] + start_col;
- for (xindex = 0; xindex < compptr->MCU_width; xindex++) {
- coef->MCU_buffer[blkn++] = buffer_ptr++;
- }
- }
- }
- /* Try to write the MCU. */
- if (! (*cinfo->entropy->encode_mcu) (cinfo, coef->MCU_buffer)) {
- /* Suspension forced; update state counters and exit */
- coef->MCU_vert_offset = yoffset;
- coef->mcu_ctr = MCU_col_num;
- return FALSE;
- }
- }
- /* Completed an MCU row, but perhaps not an iMCU row */
- coef->mcu_ctr = 0;
- }
- /* Completed the iMCU row, advance counters for next one */
- coef->iMCU_row_num++;
- start_iMCU_row(cinfo);
- return TRUE;
- }
-
- #endif /* FULL_COEF_BUFFER_SUPPORTED */
-
- /*
- * Initialize coefficient buffer controller.
- */
-
- GLOBAL(void)
- jinit_c_coef_controller (j_compress_ptr cinfo, boolean need_full_buffer)
- {
- my_coef_ptr coef;
-
- coef = (my_coef_ptr)
- (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
- SIZEOF(my_coef_controller));
- cinfo->coef = (struct jpeg_c_coef_controller *) coef;
- coef->pub.start_pass = start_pass_coef;
-
- /* Create the coefficient buffer. */
- if (need_full_buffer) {
- #ifdef FULL_COEF_BUFFER_SUPPORTED
- /* Allocate a full-image virtual array for each component, */
- /* padded to a multiple of samp_factor DCT blocks in each direction. */
- int ci;
- jpeg_component_info *compptr;
-
- for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
- ci++, compptr++) {
- coef->whole_image[ci] = (*cinfo->mem->request_virt_barray)
- ((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE,
- (JDIMENSION) jround_up((long) compptr->width_in_blocks,
- (long) compptr->h_samp_factor),
- (JDIMENSION) jround_up((long) compptr->height_in_blocks,
- (long) compptr->v_samp_factor),
- (JDIMENSION) compptr->v_samp_factor);
- }
- #else
- ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
- #endif
- } else {
- /* We only need a single-MCU buffer. */
- JBLOCKROW buffer;
- int i;
-
- buffer = (JBLOCKROW)
- (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
- C_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK));
- for (i = 0; i < C_MAX_BLOCKS_IN_MCU; i++) {
- coef->MCU_buffer[i] = buffer + i;
- }
- coef->whole_image[0] = NULL; /* flag for no virtual arrays */
- }
- }
- /********* End of inlined file: jccoefct.c *********/
-
- /********* Start of inlined file: jccolor.c *********/
- #define JPEG_INTERNALS
-
- /* Private subobject */
-
- typedef struct {
- struct jpeg_color_converter pub; /* public fields */
-
- /* Private state for RGB->YCC conversion */
- INT32 * rgb_ycc_tab; /* => table for RGB to YCbCr conversion */
- } my_color_converter;
-
- typedef my_color_converter * my_cconvert_ptr;
-
- /**************** RGB -> YCbCr conversion: most common case **************/
-
- /*
- * YCbCr is defined per CCIR 601-1, except that Cb and Cr are
- * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.
- * The conversion equations to be implemented are therefore
- * Y = 0.29900 * R + 0.58700 * G + 0.11400 * B
- * Cb = -0.16874 * R - 0.33126 * G + 0.50000 * B + CENTERJSAMPLE
- * Cr = 0.50000 * R - 0.41869 * G - 0.08131 * B + CENTERJSAMPLE
- * (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.)
- * Note: older versions of the IJG code used a zero offset of MAXJSAMPLE/2,
- * rather than CENTERJSAMPLE, for Cb and Cr. This gave equal positive and
- * negative swings for Cb/Cr, but meant that grayscale values (Cb=Cr=0)
- * were not represented exactly. Now we sacrifice exact representation of
- * maximum red and maximum blue in order to get exact grayscales.
- *
- * To avoid floating-point arithmetic, we represent the fractional constants
- * as integers scaled up by 2^16 (about 4 digits precision); we have to divide
- * the products by 2^16, with appropriate rounding, to get the correct answer.
- *
- * For even more speed, we avoid doing any multiplications in the inner loop
- * by precalculating the constants times R,G,B for all possible values.
- * For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table);
- * for 12-bit samples it is still acceptable. It's not very reasonable for
- * 16-bit samples, but if you want lossless storage you shouldn't be changing
- * colorspace anyway.
- * The CENTERJSAMPLE offsets and the rounding fudge-factor of 0.5 are included
- * in the tables to save adding them separately in the inner loop.
- */
-
- #define SCALEBITS 16 /* speediest right-shift on some machines */
- #define CBCR_OFFSET ((INT32) CENTERJSAMPLE << SCALEBITS)
- #define ONE_HALF ((INT32) 1 << (SCALEBITS-1))
- #define FIX(x) ((INT32) ((x) * (1L<<SCALEBITS) + 0.5))
-
- /* We allocate one big table and divide it up into eight parts, instead of
- * doing eight alloc_small requests. This lets us use a single table base
- * address, which can be held in a register in the inner loops on many
- * machines (more than can hold all eight addresses, anyway).
- */
-
- #define R_Y_OFF 0 /* offset to R => Y section */
- #define G_Y_OFF (1*(MAXJSAMPLE+1)) /* offset to G => Y section */
- #define B_Y_OFF (2*(MAXJSAMPLE+1)) /* etc. */
- #define R_CB_OFF (3*(MAXJSAMPLE+1))
- #define G_CB_OFF (4*(MAXJSAMPLE+1))
- #define B_CB_OFF (5*(MAXJSAMPLE+1))
- #define R_CR_OFF B_CB_OFF /* B=>Cb, R=>Cr are the same */
- #define G_CR_OFF (6*(MAXJSAMPLE+1))
- #define B_CR_OFF (7*(MAXJSAMPLE+1))
- #define TABLE_SIZE (8*(MAXJSAMPLE+1))
-
- /*
- * Initialize for RGB->YCC colorspace conversion.
- */
-
- METHODDEF(void)
- rgb_ycc_start (j_compress_ptr cinfo)
- {
- my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
- INT32 * rgb_ycc_tab;
- INT32 i;
-
- /* Allocate and fill in the conversion tables. */
- cconvert->rgb_ycc_tab = rgb_ycc_tab = (INT32 *)
- (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
- (TABLE_SIZE * SIZEOF(INT32)));
-
- for (i = 0; i <= MAXJSAMPLE; i++) {
- rgb_ycc_tab[i+R_Y_OFF] = FIX(0.29900) * i;
- rgb_ycc_tab[i+G_Y_OFF] = FIX(0.58700) * i;
- rgb_ycc_tab[i+B_Y_OFF] = FIX(0.11400) * i + ONE_HALF;
- rgb_ycc_tab[i+R_CB_OFF] = (-FIX(0.16874)) * i;
- rgb_ycc_tab[i+G_CB_OFF] = (-FIX(0.33126)) * i;
- /* We use a rounding fudge-factor of 0.5-epsilon for Cb and Cr.
- * This ensures that the maximum output will round to MAXJSAMPLE
- * not MAXJSAMPLE+1, and thus that we don't have to range-limit.
- */
- rgb_ycc_tab[i+B_CB_OFF] = FIX(0.50000) * i + CBCR_OFFSET + ONE_HALF-1;
- /* B=>Cb and R=>Cr tables are the same
- rgb_ycc_tab[i+R_CR_OFF] = FIX(0.50000) * i + CBCR_OFFSET + ONE_HALF-1;
- */
- rgb_ycc_tab[i+G_CR_OFF] = (-FIX(0.41869)) * i;
- rgb_ycc_tab[i+B_CR_OFF] = (-FIX(0.08131)) * i;
- }
- }
-
- /*
- * Convert some rows of samples to the JPEG colorspace.
- *
- * Note that we change from the application's interleaved-pixel format
- * to our internal noninterleaved, one-plane-per-component format.
- * The input buffer is therefore three times as wide as the output buffer.
- *
- * A starting row offset is provided only for the output buffer. The caller
- * can easily adjust the passed input_buf value to accommodate any row
- * offset required on that side.
- */
-
- METHODDEF(void)
- rgb_ycc_convert (j_compress_ptr cinfo,
- JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
- JDIMENSION output_row, int num_rows)
- {
- my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
- register int r, g, b;
- register INT32 * ctab = cconvert->rgb_ycc_tab;
- register JSAMPROW inptr;
- register JSAMPROW outptr0, outptr1, outptr2;
- register JDIMENSION col;
- JDIMENSION num_cols = cinfo->image_width;
-
- while (--num_rows >= 0) {
- inptr = *input_buf++;
- outptr0 = output_buf[0][output_row];
- outptr1 = output_buf[1][output_row];
- outptr2 = output_buf[2][output_row];
- output_row++;
- for (col = 0; col < num_cols; col++) {
- r = GETJSAMPLE(inptr[RGB_RED]);
- g = GETJSAMPLE(inptr[RGB_GREEN]);
- b = GETJSAMPLE(inptr[RGB_BLUE]);
- inptr += RGB_PIXELSIZE;
- /* If the inputs are 0..MAXJSAMPLE, the outputs of these equations
- * must be too; we do not need an explicit range-limiting operation.
- * Hence the value being shifted is never negative, and we don't
- * need the general RIGHT_SHIFT macro.
- */
- /* Y */
- outptr0[col] = (JSAMPLE)
- ((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF])
- >> SCALEBITS);
- /* Cb */
- outptr1[col] = (JSAMPLE)
- ((ctab[r+R_CB_OFF] + ctab[g+G_CB_OFF] + ctab[b+B_CB_OFF])
- >> SCALEBITS);
- /* Cr */
- outptr2[col] = (JSAMPLE)
- ((ctab[r+R_CR_OFF] + ctab[g+G_CR_OFF] + ctab[b+B_CR_OFF])
- >> SCALEBITS);
- }
- }
- }
-
- /**************** Cases other than RGB -> YCbCr **************/
-
- /*
- * Convert some rows of samples to the JPEG colorspace.
- * This version handles RGB->grayscale conversion, which is the same
- * as the RGB->Y portion of RGB->YCbCr.
- * We assume rgb_ycc_start has been called (we only use the Y tables).
- */
-
- METHODDEF(void)
- rgb_gray_convert (j_compress_ptr cinfo,
- JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
- JDIMENSION output_row, int num_rows)
- {
- my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
- register int r, g, b;
- register INT32 * ctab = cconvert->rgb_ycc_tab;
- register JSAMPROW inptr;
- register JSAMPROW outptr;
- register JDIMENSION col;
- JDIMENSION num_cols = cinfo->image_width;
-
- while (--num_rows >= 0) {
- inptr = *input_buf++;
- outptr = output_buf[0][output_row];
- output_row++;
- for (col = 0; col < num_cols; col++) {
- r = GETJSAMPLE(inptr[RGB_RED]);
- g = GETJSAMPLE(inptr[RGB_GREEN]);
- b = GETJSAMPLE(inptr[RGB_BLUE]);
- inptr += RGB_PIXELSIZE;
- /* Y */
- outptr[col] = (JSAMPLE)
- ((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF])
- >> SCALEBITS);
- }
- }
- }
-
- /*
- * Convert some rows of samples to the JPEG colorspace.
- * This version handles Adobe-style CMYK->YCCK conversion,
- * where we convert R=1-C, G=1-M, and B=1-Y to YCbCr using the same
- * conversion as above, while passing K (black) unchanged.
- * We assume rgb_ycc_start has been called.
- */
-
- METHODDEF(void)
- cmyk_ycck_convert (j_compress_ptr cinfo,
- JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
- JDIMENSION output_row, int num_rows)
- {
- my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
- register int r, g, b;
- register INT32 * ctab = cconvert->rgb_ycc_tab;
- register JSAMPROW inptr;
- register JSAMPROW outptr0, outptr1, outptr2, outptr3;
- register JDIMENSION col;
- JDIMENSION num_cols = cinfo->image_width;
-
- while (--num_rows >= 0) {
- inptr = *input_buf++;
- outptr0 = output_buf[0][output_row];
- outptr1 = output_buf[1][output_row];
- outptr2 = output_buf[2][output_row];
- outptr3 = output_buf[3][output_row];
- output_row++;
- for (col = 0; col < num_cols; col++) {
- r = MAXJSAMPLE - GETJSAMPLE(inptr[0]);
- g = MAXJSAMPLE - GETJSAMPLE(inptr[1]);
- b = MAXJSAMPLE - GETJSAMPLE(inptr[2]);
- /* K passes through as-is */
- outptr3[col] = inptr[3]; /* don't need GETJSAMPLE here */
- inptr += 4;
- /* If the inputs are 0..MAXJSAMPLE, the outputs of these equations
- * must be too; we do not need an explicit range-limiting operation.
- * Hence the value being shifted is never negative, and we don't
- * need the general RIGHT_SHIFT macro.
- */
- /* Y */
- outptr0[col] = (JSAMPLE)
- ((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF])
- >> SCALEBITS);
- /* Cb */
- outptr1[col] = (JSAMPLE)
- ((ctab[r+R_CB_OFF] + ctab[g+G_CB_OFF] + ctab[b+B_CB_OFF])
- >> SCALEBITS);
- /* Cr */
- outptr2[col] = (JSAMPLE)
- ((ctab[r+R_CR_OFF] + ctab[g+G_CR_OFF] + ctab[b+B_CR_OFF])
- >> SCALEBITS);
- }
- }
- }
-
- /*
- * Convert some rows of samples to the JPEG colorspace.
- * This version handles grayscale output with no conversion.
- * The source can be either plain grayscale or YCbCr (since Y == gray).
- */
-
- METHODDEF(void)
- grayscale_convert (j_compress_ptr cinfo,
- JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
- JDIMENSION output_row, int num_rows)
- {
- register JSAMPROW inptr;
- register JSAMPROW outptr;
- register JDIMENSION col;
- JDIMENSION num_cols = cinfo->image_width;
- int instride = cinfo->input_components;
-
- while (--num_rows >= 0) {
- inptr = *input_buf++;
- outptr = output_buf[0][output_row];
- output_row++;
- for (col = 0; col < num_cols; col++) {
- outptr[col] = inptr[0]; /* don't need GETJSAMPLE() here */
- inptr += instride;
- }
- }
- }
-
- /*
- * Convert some rows of samples to the JPEG colorspace.
- * This version handles multi-component colorspaces without conversion.
- * We assume input_components == num_components.
- */
-
- METHODDEF(void)
- null_convert (j_compress_ptr cinfo,
- JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
- JDIMENSION output_row, int num_rows)
- {
- register JSAMPROW inptr;
- register JSAMPROW outptr;
- register JDIMENSION col;
- register int ci;
- int nc = cinfo->num_components;
- JDIMENSION num_cols = cinfo->image_width;
-
- while (--num_rows >= 0) {
- /* It seems fastest to make a separate pass for each component. */
- for (ci = 0; ci < nc; ci++) {
- inptr = *input_buf;
- outptr = output_buf[ci][output_row];
- for (col = 0; col < num_cols; col++) {
- outptr[col] = inptr[ci]; /* don't need GETJSAMPLE() here */
- inptr += nc;
- }
- }
- input_buf++;
- output_row++;
- }
- }
-
- /*
- * Empty method for start_pass.
- */
-
- METHODDEF(void)
- null_method (j_compress_ptr cinfo)
- {
- /* no work needed */
- }
-
- /*
- * Module initialization routine for input colorspace conversion.
- */
-
- GLOBAL(void)
- jinit_color_converter (j_compress_ptr cinfo)
- {
- my_cconvert_ptr cconvert;
-
- cconvert = (my_cconvert_ptr)
- (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
- SIZEOF(my_color_converter));
- cinfo->cconvert = (struct jpeg_color_converter *) cconvert;
- /* set start_pass to null method until we find out differently */
- cconvert->pub.start_pass = null_method;
-
- /* Make sure input_components agrees with in_color_space */
- switch (cinfo->in_color_space) {
- case JCS_GRAYSCALE:
- if (cinfo->input_components != 1)
- ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
- break;
-
- case JCS_RGB:
- #if RGB_PIXELSIZE != 3
- if (cinfo->input_components != RGB_PIXELSIZE)
- ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
- break;
- #endif /* else share code with YCbCr */
-
- case JCS_YCbCr:
- if (cinfo->input_components != 3)
- ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
- break;
-
- case JCS_CMYK:
- case JCS_YCCK:
- if (cinfo->input_components != 4)
- ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
- break;
-
- default: /* JCS_UNKNOWN can be anything */
- if (cinfo->input_components < 1)
- ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
- break;
- }
-
- /* Check num_components, set conversion method based on requested space */
- switch (cinfo->jpeg_color_space) {
- case JCS_GRAYSCALE:
- if (cinfo->num_components != 1)
- ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
- if (cinfo->in_color_space == JCS_GRAYSCALE)
- cconvert->pub.color_convert = grayscale_convert;
- else if (cinfo->in_color_space == JCS_RGB) {
- cconvert->pub.start_pass = rgb_ycc_start;
- cconvert->pub.color_convert = rgb_gray_convert;
- } else if (cinfo->in_color_space == JCS_YCbCr)
- cconvert->pub.color_convert = grayscale_convert;
- else
- ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
- break;
-
- case JCS_RGB:
- if (cinfo->num_components != 3)
- ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
- if (cinfo->in_color_space == JCS_RGB && RGB_PIXELSIZE == 3)
- cconvert->pub.color_convert = null_convert;
- else
- ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
- break;
-
- case JCS_YCbCr:
- if (cinfo->num_components != 3)
- ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
- if (cinfo->in_color_space == JCS_RGB) {
- cconvert->pub.start_pass = rgb_ycc_start;
- cconvert->pub.color_convert = rgb_ycc_convert;
- } else if (cinfo->in_color_space == JCS_YCbCr)
- cconvert->pub.color_convert = null_convert;
- else
- ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
- break;
-
- case JCS_CMYK:
- if (cinfo->num_components != 4)
- ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
- if (cinfo->in_color_space == JCS_CMYK)
- cconvert->pub.color_convert = null_convert;
- else
- ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
- break;
-
- case JCS_YCCK:
- if (cinfo->num_components != 4)
- ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
- if (cinfo->in_color_space == JCS_CMYK) {
- cconvert->pub.start_pass = rgb_ycc_start;
- cconvert->pub.color_convert = cmyk_ycck_convert;
- } else if (cinfo->in_color_space == JCS_YCCK)
- cconvert->pub.color_convert = null_convert;
- else
- ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
- break;
-
- default: /* allow null conversion of JCS_UNKNOWN */
- if (cinfo->jpeg_color_space != cinfo->in_color_space ||
- cinfo->num_components != cinfo->input_components)
- ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
- cconvert->pub.color_convert = null_convert;
- break;
- }
- }
- /********* End of inlined file: jccolor.c *********/
-
- #undef FIX
-
- /********* Start of inlined file: jcdctmgr.c *********/
- #define JPEG_INTERNALS
-
- /********* Start of inlined file: jdct.h *********/
- /*
- * A forward DCT routine is given a pointer to a work area of type DCTELEM[];
- * the DCT is to be performed in-place in that buffer. Type DCTELEM is int
- * for 8-bit samples, INT32 for 12-bit samples. (NOTE: Floating-point DCT
- * implementations use an array of type FAST_FLOAT, instead.)
- * The DCT inputs are expected to be signed (range +-CENTERJSAMPLE).
- * The DCT outputs are returned scaled up by a factor of 8; they therefore
- * have a range of +-8K for 8-bit data, +-128K for 12-bit data. This
- * convention improves accuracy in integer implementations and saves some
- * work in floating-point ones.
- * Quantization of the output coefficients is done by jcdctmgr.c.
- */
-
- #ifndef __jdct_h__
- #define __jdct_h__
-
- #if BITS_IN_JSAMPLE == 8
- typedef int DCTELEM; /* 16 or 32 bits is fine */
- #else
- typedef INT32 DCTELEM; /* must have 32 bits */
- #endif
-
- typedef JMETHOD(void, forward_DCT_method_ptr, (DCTELEM * data));
- typedef JMETHOD(void, float_DCT_method_ptr, (FAST_FLOAT * data));
-
- /*
- * An inverse DCT routine is given a pointer to the input JBLOCK and a pointer
- * to an output sample array. The routine must dequantize the input data as
- * well as perform the IDCT; for dequantization, it uses the multiplier table
- * pointed to by compptr->dct_table. The output data is to be placed into the
- * sample array starting at a specified column. (Any row offset needed will
- * be applied to the array pointer before it is passed to the IDCT code.)
- * Note that the number of samples emitted by the IDCT routine is
- * DCT_scaled_size * DCT_scaled_size.
- */
-
- /* typedef inverse_DCT_method_ptr is declared in jpegint.h */
-
- /*
- * Each IDCT routine has its own ideas about the best dct_table element type.
- */
-
- typedef MULTIPLIER ISLOW_MULT_TYPE; /* short or int, whichever is faster */
- #if BITS_IN_JSAMPLE == 8
- typedef MULTIPLIER IFAST_MULT_TYPE; /* 16 bits is OK, use short if faster */
- #define IFAST_SCALE_BITS 2 /* fractional bits in scale factors */
- #else
- typedef INT32 IFAST_MULT_TYPE; /* need 32 bits for scaled quantizers */
- #define IFAST_SCALE_BITS 13 /* fractional bits in scale factors */
- #endif
- typedef FAST_FLOAT FLOAT_MULT_TYPE; /* preferred floating type */
-
- /*
- * Each IDCT routine is responsible for range-limiting its results and
- * converting them to unsigned form (0..MAXJSAMPLE). The raw outputs could
- * be quite far out of range if the input data is corrupt, so a bulletproof
- * range-limiting step is required. We use a mask-and-table-lookup method
- * to do the combined operations quickly. See the comments with
- * prepare_range_limit_table (in jdmaster.c) for more info.
- */
-
- #define IDCT_range_limit(cinfo) ((cinfo)->sample_range_limit + CENTERJSAMPLE)
-
- #define RANGE_MASK (MAXJSAMPLE * 4 + 3) /* 2 bits wider than legal samples */
-
- /* Short forms of external names for systems with brain-damaged linkers. */
-
- #ifdef NEED_SHORT_EXTERNAL_NAMES
- #define jpeg_fdct_islow jFDislow
- #define jpeg_fdct_ifast jFDifast
- #define jpeg_fdct_float jFDfloat
- #define jpeg_idct_islow jRDislow
- #define jpeg_idct_ifast jRDifast
- #define jpeg_idct_float jRDfloat
- #define jpeg_idct_4x4 jRD4x4
- #define jpeg_idct_2x2 jRD2x2
- #define jpeg_idct_1x1 jRD1x1
- #endif /* NEED_SHORT_EXTERNAL_NAMES */
-
- /* Extern declarations for the forward and inverse DCT routines. */
-
- EXTERN(void) jpeg_fdct_islow JPP((DCTELEM * data));
- EXTERN(void) jpeg_fdct_ifast JPP((DCTELEM * data));
- EXTERN(void) jpeg_fdct_float JPP((FAST_FLOAT * data));
-
- EXTERN(void) jpeg_idct_islow
- JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
- JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
- EXTERN(void) jpeg_idct_ifast
- JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
- JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
- EXTERN(void) jpeg_idct_float
- JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
- JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
- EXTERN(void) jpeg_idct_4x4
- JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
- JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
- EXTERN(void) jpeg_idct_2x2
- JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
- JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
- EXTERN(void) jpeg_idct_1x1
- JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
- JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
-
- /*
- * Macros for handling fixed-point arithmetic; these are used by many
- * but not all of the DCT/IDCT modules.
- *
- * All values are expected to be of type INT32.
- * Fractional constants are scaled left by CONST_BITS bits.
- * CONST_BITS is defined within each module using these macros,
- * and may differ from one module to the next.
- */
-
- #define ONE ((INT32) 1)
- #define CONST_SCALE (ONE << CONST_BITS)
-
- /* Convert a positive real constant to an integer scaled by CONST_SCALE.
- * Caution: some C compilers fail to reduce "FIX(constant)" at compile time,
- * thus causing a lot of useless floating-point operations at run time.
- */
-
- #define FIX(x) ((INT32) ((x) * CONST_SCALE + 0.5))
-
- /* Descale and correctly round an INT32 value that's scaled by N bits.
- * We assume RIGHT_SHIFT rounds towards minus infinity, so adding
- * the fudge factor is correct for either sign of X.
- */
-
- #define DESCALE(x,n) RIGHT_SHIFT((x) + (ONE << ((n)-1)), n)
-
- /* Multiply an INT32 variable by an INT32 constant to yield an INT32 result.
- * This macro is used only when the two inputs will actually be no more than
- * 16 bits wide, so that a 16x16->32 bit multiply can be used instead of a
- * full 32x32 multiply. This provides a useful speedup on many machines.
- * Unfortunately there is no way to specify a 16x16->32 multiply portably
- * in C, but some C compilers will do the right thing if you provide the
- * correct combination of casts.
- */
-
- #ifdef SHORTxSHORT_32 /* may work if 'int' is 32 bits */
- #define MULTIPLY16C16(var,const) (((INT16) (var)) * ((INT16) (const)))
- #endif
- #ifdef SHORTxLCONST_32 /* known to work with Microsoft C 6.0 */
- #define MULTIPLY16C16(var,const) (((INT16) (var)) * ((INT32) (const)))
- #endif
-
- #ifndef MULTIPLY16C16 /* default definition */
- #define MULTIPLY16C16(var,const) ((var) * (const))
- #endif
-
- /* Same except both inputs are variables. */
-
- #ifdef SHORTxSHORT_32 /* may work if 'int' is 32 bits */
- #define MULTIPLY16V16(var1,var2) (((INT16) (var1)) * ((INT16) (var2)))
- #endif
-
- #ifndef MULTIPLY16V16 /* default definition */
- #define MULTIPLY16V16(var1,var2) ((var1) * (var2))
- #endif
-
- #endif
- /********* End of inlined file: jdct.h *********/
-
- /* Private declarations for DCT subsystem */
-
- /* Private subobject for this module */
-
- typedef struct {
- struct jpeg_forward_dct pub; /* public fields */
-
- /* Pointer to the DCT routine actually in use */
- forward_DCT_method_ptr do_dct;
-
- /* The actual post-DCT divisors --- not identical to the quant table
- * entries, because of scaling (especially for an unnormalized DCT).
- * Each table is given in normal array order.
- */
- DCTELEM * divisors[NUM_QUANT_TBLS];
-
- #ifdef DCT_FLOAT_SUPPORTED
- /* Same as above for the floating-point case. */
- float_DCT_method_ptr do_float_dct;
- FAST_FLOAT * float_divisors[NUM_QUANT_TBLS];
- #endif
- } my_fdct_controller;
-
- typedef my_fdct_controller * my_fdct_ptr;
-
- /*
- * Initialize for a processing pass.
- * Verify that all referenced Q-tables are present, and set up
- * the divisor table for each one.
- * In the current implementation, DCT of all components is done during
- * the first pass, even if only some components will be output in the
- * first scan. Hence all components should be examined here.
- */
-
- METHODDEF(void)
- start_pass_fdctmgr (j_compress_ptr cinfo)
- {
- my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct;
- int ci, qtblno, i;
- jpeg_component_info *compptr;
- JQUANT_TBL * qtbl;
- DCTELEM * dtbl;
-
- for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
- ci++, compptr++) {
- qtblno = compptr->quant_tbl_no;
- /* Make sure specified quantization table is present */
- if (qtblno < 0 || qtblno >= NUM_QUANT_TBLS ||
- cinfo->quant_tbl_ptrs[qtblno] == NULL)
- ERREXIT1(cinfo, JERR_NO_QUANT_TABLE, qtblno);
- qtbl = cinfo->quant_tbl_ptrs[qtblno];
- /* Compute divisors for this quant table */
- /* We may do this more than once for same table, but it's not a big deal */
- switch (cinfo->dct_method) {
- #ifdef DCT_ISLOW_SUPPORTED
- case JDCT_ISLOW:
- /* For LL&M IDCT method, divisors are equal to raw quantization
- * coefficients multiplied by 8 (to counteract scaling).
- */
- if (fdct->divisors[qtblno] == NULL) {
- fdct->divisors[qtblno] = (DCTELEM *)
- (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
- DCTSIZE2 * SIZEOF(DCTELEM));
- }
- dtbl = fdct->divisors[qtblno];
- for (i = 0; i < DCTSIZE2; i++) {
- dtbl[i] = ((DCTELEM) qtbl->quantval[i]) << 3;
- }
- break;
- #endif
- #ifdef DCT_IFAST_SUPPORTED
- case JDCT_IFAST:
- {
- /* For AA&N IDCT method, divisors are equal to quantization
- * coefficients scaled by scalefactor[row]*scalefactor[col], where
- * scalefactor[0] = 1
- * scalefactor[k] = cos(k*PI/16) * sqrt(2) for k=1..7
- * We apply a further scale factor of 8.
- */
- #define CONST_BITS 14
- static const INT16 aanscales[DCTSIZE2] = {
- /* precomputed values scaled up by 14 bits */
- 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520,
- 22725, 31521, 29692, 26722, 22725, 17855, 12299, 6270,
- 21407, 29692, 27969, 25172, 21407, 16819, 11585, 5906,
- 19266, 26722, 25172, 22654, 19266, 15137, 10426, 5315,
- 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520,
- 12873, 17855, 16819, 15137, 12873, 10114, 6967, 3552,
- 8867, 12299, 11585, 10426, 8867, 6967, 4799, 2446,
- 4520, 6270, 5906, 5315, 4520, 3552, 2446, 1247
- };
- SHIFT_TEMPS
-
- if (fdct->divisors[qtblno] == NULL) {
- fdct->divisors[qtblno] = (DCTELEM *)
- (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
- DCTSIZE2 * SIZEOF(DCTELEM));
- }
- dtbl = fdct->divisors[qtblno];
- for (i = 0; i < DCTSIZE2; i++) {
- dtbl[i] = (DCTELEM)
- DESCALE(MULTIPLY16V16((INT32) qtbl->quantval[i],
- (INT32) aanscales[i]),
- CONST_BITS-3);
- }
- }
- break;
- #endif
- #ifdef DCT_FLOAT_SUPPORTED
- case JDCT_FLOAT:
- {
- /* For float AA&N IDCT method, divisors are equal to quantization
- * coefficients scaled by scalefactor[row]*scalefactor[col], where
- * scalefactor[0] = 1
- * scalefactor[k] = cos(k*PI/16) * sqrt(2) for k=1..7
- * We apply a further scale factor of 8.
- * What's actually stored is 1/divisor so that the inner loop can
- * use a multiplication rather than a division.
- */
- FAST_FLOAT * fdtbl;
- int row, col;
- static const double aanscalefactor[DCTSIZE] = {
- 1.0, 1.387039845, 1.306562965, 1.175875602,
- 1.0, 0.785694958, 0.541196100, 0.275899379
- };
-
- if (fdct->float_divisors[qtblno] == NULL) {
- fdct->float_divisors[qtblno] = (FAST_FLOAT *)
- (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
- DCTSIZE2 * SIZEOF(FAST_FLOAT));
- }
- fdtbl = fdct->float_divisors[qtblno];
- i = 0;
- for (row = 0; row < DCTSIZE; row++) {
- for (col = 0; col < DCTSIZE; col++) {
- fdtbl[i] = (FAST_FLOAT)
- (1.0 / (((double) qtbl->quantval[i] *
- aanscalefactor[row] * aanscalefactor[col] * 8.0)));
- i++;
- }
- }
- }
- break;
- #endif
- default:
- ERREXIT(cinfo, JERR_NOT_COMPILED);
- break;
- }
- }
- }
-
- /*
- * Perform forward DCT on one or more blocks of a component.
- *
- * The input samples are taken from the sample_data[] array starting at
- * position start_row/start_col, and moving to the right for any additional
- * blocks. The quantized coefficients are returned in coef_blocks[].
- */
-
- METHODDEF(void)
- forward_DCT (j_compress_ptr cinfo, jpeg_component_info * compptr,
- JSAMPARRAY sample_data, JBLOCKROW coef_blocks,
- JDIMENSION start_row, JDIMENSION start_col,
- JDIMENSION num_blocks)
- /* This version is used for integer DCT implementations. */
- {
- /* This routine is heavily used, so it's worth coding it tightly. */
- my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct;
- forward_DCT_method_ptr do_dct = fdct->do_dct;
- DCTELEM * divisors = fdct->divisors[compptr->quant_tbl_no];
- DCTELEM workspace[DCTSIZE2]; /* work area for FDCT subroutine */
- JDIMENSION bi;
-
- sample_data += start_row; /* fold in the vertical offset once */
-
- for (bi = 0; bi < num_blocks; bi++, start_col += DCTSIZE) {
- /* Load data into workspace, applying unsigned->signed conversion */
- { register DCTELEM *workspaceptr;
- register JSAMPROW elemptr;
- register int elemr;
-
- workspaceptr = workspace;
- for (elemr = 0; elemr < DCTSIZE; elemr++) {
- elemptr = sample_data[elemr] + start_col;
- #if DCTSIZE == 8 /* unroll the inner loop */
- *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
- *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
- *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
- *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
- *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
- *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
- *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
- *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
- #else
- { register int elemc;
- for (elemc = DCTSIZE; elemc > 0; elemc--) {
- *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
- }
- }
- #endif
- }
- }
-
- /* Perform the DCT */
- (*do_dct) (workspace);
-
- /* Quantize/descale the coefficients, and store into coef_blocks[] */
- { register DCTELEM temp, qval;
- register int i;
- register JCOEFPTR output_ptr = coef_blocks[bi];
-
- for (i = 0; i < DCTSIZE2; i++) {
- qval = divisors[i];
- temp = workspace[i];
- /* Divide the coefficient value by qval, ensuring proper rounding.
- * Since C does not specify the direction of rounding for negative
- * quotients, we have to force the dividend positive for portability.
- *
- * In most files, at least half of the output values will be zero
- * (at default quantization settings, more like three-quarters...)
- * so we should ensure that this case is fast. On many machines,
- * a comparison is enough cheaper than a divide to make a special test
- * a win. Since both inputs will be nonnegative, we need only test
- * for a < b to discover whether a/b is 0.
- * If your machine's division is fast enough, define FAST_DIVIDE.
- */
- #ifdef FAST_DIVIDE
- #define DIVIDE_BY(a,b) a /= b
- #else
- #define DIVIDE_BY(a,b) if (a >= b) a /= b; else a = 0
- #endif
- if (temp < 0) {
- temp = -temp;
- temp += qval>>1; /* for rounding */
- DIVIDE_BY(temp, qval);
- temp = -temp;
- } else {
- temp += qval>>1; /* for rounding */
- DIVIDE_BY(temp, qval);
- }
- output_ptr[i] = (JCOEF) temp;
- }
- }
- }
- }
-
- #ifdef DCT_FLOAT_SUPPORTED
-
- METHODDEF(void)
- forward_DCT_float (j_compress_ptr cinfo, jpeg_component_info * compptr,
- JSAMPARRAY sample_data, JBLOCKROW coef_blocks,
- JDIMENSION start_row, JDIMENSION start_col,
- JDIMENSION num_blocks)
- /* This version is used for floating-point DCT implementations. */
- {
- /* This routine is heavily used, so it's worth coding it tightly. */
- my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct;
- float_DCT_method_ptr do_dct = fdct->do_float_dct;
- FAST_FLOAT * divisors = fdct->float_divisors[compptr->quant_tbl_no];
- FAST_FLOAT workspace[DCTSIZE2]; /* work area for FDCT subroutine */
- JDIMENSION bi;
-
- sample_data += start_row; /* fold in the vertical offset once */
-
- for (bi = 0; bi < num_blocks; bi++, start_col += DCTSIZE) {
- /* Load data into workspace, applying unsigned->signed conversion */
- { register FAST_FLOAT *workspaceptr;
- register JSAMPROW elemptr;
- register int elemr;
-
- workspaceptr = workspace;
- for (elemr = 0; elemr < DCTSIZE; elemr++) {
- elemptr = sample_data[elemr] + start_col;
- #if DCTSIZE == 8 /* unroll the inner loop */
- *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
- *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
- *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
- *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
- *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
- *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
- *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
- *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
- #else
- { register int elemc;
- for (elemc = DCTSIZE; elemc > 0; elemc--) {
- *workspaceptr++ = (FAST_FLOAT)
- (GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
- }
- }
- #endif
- }
- }
-
- /* Perform the DCT */
- (*do_dct) (workspace);
-
- /* Quantize/descale the coefficients, and store into coef_blocks[] */
- { register FAST_FLOAT temp;
- register int i;
- register JCOEFPTR output_ptr = coef_blocks[bi];
-
- for (i = 0; i < DCTSIZE2; i++) {
- /* Apply the quantization and scaling factor */
- temp = workspace[i] * divisors[i];
- /* Round to nearest integer.
- * Since C does not specify the direction of rounding for negative
- * quotients, we have to force the dividend positive for portability.
- * The maximum coefficient size is +-16K (for 12-bit data), so this
- * code should work for either 16-bit or 32-bit ints.
- */
- output_ptr[i] = (JCOEF) ((int) (temp + (FAST_FLOAT) 16384.5) - 16384);
- }
- }
- }
- }
-
- #endif /* DCT_FLOAT_SUPPORTED */
-
- /*
- * Initialize FDCT manager.
- */
-
- GLOBAL(void)
- jinit_forward_dct (j_compress_ptr cinfo)
- {
- my_fdct_ptr fdct;
- int i;
-
- fdct = (my_fdct_ptr)
- (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
- SIZEOF(my_fdct_controller));
- cinfo->fdct = (struct jpeg_forward_dct *) fdct;
- fdct->pub.start_pass = start_pass_fdctmgr;
-
- switch (cinfo->dct_method) {
- #ifdef DCT_ISLOW_SUPPORTED
- case JDCT_ISLOW:
- fdct->pub.forward_DCT = forward_DCT;
- fdct->do_dct = jpeg_fdct_islow;
- break;
- #endif
- #ifdef DCT_IFAST_SUPPORTED
- case JDCT_IFAST:
- fdct->pub.forward_DCT = forward_DCT;
- fdct->do_dct = jpeg_fdct_ifast;
- break;
- #endif
- #ifdef DCT_FLOAT_SUPPORTED
- case JDCT_FLOAT:
- fdct->pub.forward_DCT = forward_DCT_float;
- fdct->do_float_dct = jpeg_fdct_float;
- break;
- #endif
- default:
- ERREXIT(cinfo, JERR_NOT_COMPILED);
- break;
- }
-
- /* Mark divisor tables unallocated */
- for (i = 0; i < NUM_QUANT_TBLS; i++) {
- fdct->divisors[i] = NULL;
- #ifdef DCT_FLOAT_SUPPORTED
- fdct->float_divisors[i] = NULL;
- #endif
- }
- }
- /********* End of inlined file: jcdctmgr.c *********/
-
- #undef CONST_BITS
-
- /********* Start of inlined file: jchuff.c *********/
- #define JPEG_INTERNALS
-
- /********* Start of inlined file: jchuff.h *********/
- /* The legal range of a DCT coefficient is
- * -1024 .. +1023 for 8-bit data;
- * -16384 .. +16383 for 12-bit data.
- * Hence the magnitude should always fit in 10 or 14 bits respectively.
- */
-
- #ifndef _jchuff_h_
- #define _jchuff_h_
-
- #if BITS_IN_JSAMPLE == 8
- #define MAX_COEF_BITS 10
- #else
- #define MAX_COEF_BITS 14
- #endif
-
- /* Derived data constructed for each Huffman table */
-
- typedef struct {
- unsigned int ehufco[256]; /* code for each symbol */
- char ehufsi[256]; /* length of code for each symbol */
- /* If no code has been allocated for a symbol S, ehufsi[S] contains 0 */
- } c_derived_tbl;
-
- /* Short forms of external names for systems with brain-damaged linkers. */
-
- #ifdef NEED_SHORT_EXTERNAL_NAMES
- #define jpeg_make_c_derived_tbl jMkCDerived
- #define jpeg_gen_optimal_table jGenOptTbl
- #endif /* NEED_SHORT_EXTERNAL_NAMES */
-
- /* Expand a Huffman table definition into the derived format */
- EXTERN(void) jpeg_make_c_derived_tbl
- JPP((j_compress_ptr cinfo, boolean isDC, int tblno,
- c_derived_tbl ** pdtbl));
-
- /* Generate an optimal table definition given the specified counts */
- EXTERN(void) jpeg_gen_optimal_table
- JPP((j_compress_ptr cinfo, JHUFF_TBL * htbl, long freq[]));
-
- #endif
- /********* End of inlined file: jchuff.h *********/
-
- /* Declarations shared with jcphuff.c */
-
- /* Expanded entropy encoder object for Huffman encoding.
- *
- * The savable_state subrecord contains fields that change within an MCU,
- * but must not be updated permanently until we complete the MCU.
- */
-
- typedef struct {
- INT32 put_buffer; /* current bit-accumulation buffer */
- int put_bits; /* # of bits now in it */
- int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */
- } savable_state;
-
- /* This macro is to work around compilers with missing or broken
- * structure assignment. You'll need to fix this code if you have
- * such a compiler and you change MAX_COMPS_IN_SCAN.
- */
-
- #ifndef NO_STRUCT_ASSIGN
- #define ASSIGN_STATE(dest,src) ((dest) = (src))
- #else
- #if MAX_COMPS_IN_SCAN == 4
- #define ASSIGN_STATE(dest,src) \
- ((dest).put_buffer = (src).put_buffer, \
- (dest).put_bits = (src).put_bits, \
- (dest).last_dc_val[0] = (src).last_dc_val[0], \
- (dest).last_dc_val[1] = (src).last_dc_val[1], \
- (dest).last_dc_val[2] = (src).last_dc_val[2], \
- (dest).last_dc_val[3] = (src).last_dc_val[3])
- #endif
- #endif
-
- typedef struct {
- struct jpeg_entropy_encoder pub; /* public fields */
-
- savable_state saved; /* Bit buffer & DC state at start of MCU */
-
- /* These fields are NOT loaded into local working state. */
- unsigned int restarts_to_go; /* MCUs left in this restart interval */
- int next_restart_num; /* next restart number to write (0-7) */
-
- /* Pointers to derived tables (these workspaces have image lifespan) */
- c_derived_tbl * dc_derived_tbls[NUM_HUFF_TBLS];
- c_derived_tbl * ac_derived_tbls[NUM_HUFF_TBLS];
-
- #ifdef ENTROPY_OPT_SUPPORTED /* Statistics tables for optimization */
- long * dc_count_ptrs[NUM_HUFF_TBLS];
- long * ac_count_ptrs[NUM_HUFF_TBLS];
- #endif
- } huff_entropy_encoder;
-
- typedef huff_entropy_encoder * huff_entropy_ptr;
-
- /* Working state while writing an MCU.
- * This struct contains all the fields that are needed by subroutines.
- */
-
- typedef struct {
- JOCTET * next_output_byte; /* => next byte to write in buffer */
- size_t free_in_buffer; /* # of byte spaces remaining in buffer */
- savable_state cur; /* Current bit buffer & DC state */
- j_compress_ptr cinfo; /* dump_buffer needs access to this */
- } working_state;
-
- /* Forward declarations */
- METHODDEF(boolean) encode_mcu_huff JPP((j_compress_ptr cinfo,
- JBLOCKROW *MCU_data));
- METHODDEF(void) finish_pass_huff JPP((j_compress_ptr cinfo));
- #ifdef ENTROPY_OPT_SUPPORTED
- METHODDEF(boolean) encode_mcu_gather JPP((j_compress_ptr cinfo,
- JBLOCKROW *MCU_data));
- METHODDEF(void) finish_pass_gather JPP((j_compress_ptr cinfo));
- #endif
-
- /*
- * Initialize for a Huffman-compressed scan.
- * If gather_statistics is TRUE, we do not output anything during the scan,
- * just count the Huffman symbols used and generate Huffman code tables.
- */
-
- METHODDEF(void)
- start_pass_huff (j_compress_ptr cinfo, boolean gather_statistics)
- {
- huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
- int ci, dctbl, actbl;
- jpeg_component_info * compptr;
-
- if (gather_statistics) {
- #ifdef ENTROPY_OPT_SUPPORTED
- entropy->pub.encode_mcu = encode_mcu_gather;
- entropy->pub.finish_pass = finish_pass_gather;
- #else
- ERREXIT(cinfo, JERR_NOT_COMPILED);
- #endif
- } else {
- entropy->pub.encode_mcu = encode_mcu_huff;
- entropy->pub.finish_pass = finish_pass_huff;
- }
-
- for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
- compptr = cinfo->cur_comp_info[ci];
- dctbl = compptr->dc_tbl_no;
- actbl = compptr->ac_tbl_no;
- if (gather_statistics) {
- #ifdef ENTROPY_OPT_SUPPORTED
- /* Check for invalid table indexes */
- /* (make_c_derived_tbl does this in the other path) */
- if (dctbl < 0 || dctbl >= NUM_HUFF_TBLS)
- ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, dctbl);
- if (actbl < 0 || actbl >= NUM_HUFF_TBLS)
- ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, actbl);
- /* Allocate and zero the statistics tables */
- /* Note that jpeg_gen_optimal_table expects 257 entries in each table! */
- if (entropy->dc_count_ptrs[dctbl] == NULL)
- entropy->dc_count_ptrs[dctbl] = (long *)
- (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
- 257 * SIZEOF(long));
- MEMZERO(entropy->dc_count_ptrs[dctbl], 257 * SIZEOF(long));
- if (entropy->ac_count_ptrs[actbl] == NULL)
- entropy->ac_count_ptrs[actbl] = (long *)
- (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
- 257 * SIZEOF(long));
- MEMZERO(entropy->ac_count_ptrs[actbl], 257 * SIZEOF(long));
- #endif
- } else {
- /* Compute derived values for Huffman tables */
- /* We may do this more than once for a table, but it's not expensive */
- jpeg_make_c_derived_tbl(cinfo, TRUE, dctbl,
- & entropy->dc_derived_tbls[dctbl]);
- jpeg_make_c_derived_tbl(cinfo, FALSE, actbl,
- & entropy->ac_derived_tbls[actbl]);
- }
- /* Initialize DC predictions to 0 */
- entropy->saved.last_dc_val[ci] = 0;
- }
-
- /* Initialize bit buffer to empty */
- entropy->saved.put_buffer = 0;
- entropy->saved.put_bits = 0;
-
- /* Initialize restart stuff */
- entropy->restarts_to_go = cinfo->restart_interval;
- entropy->next_restart_num = 0;
- }
-
- /*
- * Compute the derived values for a Huffman table.
- * This routine also performs some validation checks on the table.
- *
- * Note this is also used by jcphuff.c.
- */
-
- GLOBAL(void)
- jpeg_make_c_derived_tbl (j_compress_ptr cinfo, boolean isDC, int tblno,
- c_derived_tbl ** pdtbl)
- {
- JHUFF_TBL *htbl;
- c_derived_tbl *dtbl;
- int p, i, l, lastp, si, maxsymbol;
- char huffsize[257];
- unsigned int huffcode[257];
- unsigned int code;
-
- /* Note that huffsize[] and huffcode[] are filled in code-length order,
- * paralleling the order of the symbols themselves in htbl->huffval[].
- */
-
- /* Find the input Huffman table */
- if (tblno < 0 || tblno >= NUM_HUFF_TBLS)
- ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tblno);
- htbl =
- isDC ? cinfo->dc_huff_tbl_ptrs[tblno] : cinfo->ac_huff_tbl_ptrs[tblno];
- if (htbl == NULL)
- ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tblno);
-
- /* Allocate a workspace if we haven't already done so. */
- if (*pdtbl == NULL)
- *pdtbl = (c_derived_tbl *)
- (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
- SIZEOF(c_derived_tbl));
- dtbl = *pdtbl;
-
- /* Figure C.1: make table of Huffman code length for each symbol */
-
- p = 0;
- for (l = 1; l <= 16; l++) {
- i = (int) htbl->bits[l];
- if (i < 0 || p + i > 256) /* protect against table overrun */
- ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
- while (i--)
- huffsize[p++] = (char) l;
- }
- huffsize[p] = 0;
- lastp = p;
-
- /* Figure C.2: generate the codes themselves */
- /* We also validate that the counts represent a legal Huffman code tree. */
-
- code = 0;
- si = huffsize[0];
- p = 0;
- while (huffsize[p]) {
- while (((int) huffsize[p]) == si) {
- huffcode[p++] = code;
- code++;
- }
- /* code is now 1 more than the last code used for codelength si; but
- * it must still fit in si bits, since no code is allowed to be all ones.
- */
- if (((INT32) code) >= (((INT32) 1) << si))
- ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
- code <<= 1;
- si++;
- }
-
- /* Figure C.3: generate encoding tables */
- /* These are code and size indexed by symbol value */
-
- /* Set all codeless symbols to have code length 0;
- * this lets us detect duplicate VAL entries here, and later
- * allows emit_bits to detect any attempt to emit such symbols.
- */
- MEMZERO(dtbl->ehufsi, SIZEOF(dtbl->ehufsi));
-
- /* This is also a convenient place to check for out-of-range
- * and duplicated VAL entries. We allow 0..255 for AC symbols
- * but only 0..15 for DC. (We could constrain them further
- * based on data depth and mode, but this seems enough.)
- */
- maxsymbol = isDC ? 15 : 255;
-
- for (p = 0; p < lastp; p++) {
- i = htbl->huffval[p];
- if (i < 0 || i > maxsymbol || dtbl->ehufsi[i])
- ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
- dtbl->ehufco[i] = huffcode[p];
- dtbl->ehufsi[i] = huffsize[p];
- }
- }
-
- /* Outputting bytes to the file */
-
- /* Emit a byte, taking 'action' if must suspend. */
- #define emit_byte(state,val,action) \
- { *(state)->next_output_byte++ = (JOCTET) (val); \
- if (--(state)->free_in_buffer == 0) \
- if (! dump_buffer(state)) \
- { action; } }
-
- LOCAL(boolean)
- dump_buffer (working_state * state)
- /* Empty the output buffer; return TRUE if successful, FALSE if must suspend */
- {
- struct jpeg_destination_mgr * dest = state->cinfo->dest;
-
- if (! (*dest->empty_output_buffer) (state->cinfo))
- return FALSE;
- /* After a successful buffer dump, must reset buffer pointers */
- state->next_output_byte = dest->next_output_byte;
- state->free_in_buffer = dest->free_in_buffer;
- return TRUE;
- }
-
- /* Outputting bits to the file */
-
- /* Only the right 24 bits of put_buffer are used; the valid bits are
- * left-justified in this part. At most 16 bits can be passed to emit_bits
- * in one call, and we never retain more than 7 bits in put_buffer
- * between calls, so 24 bits are sufficient.
- */
-
- INLINE
- LOCAL(boolean)
- emit_bits (working_state * state, unsigned int code, int size)
- /* Emit some bits; return TRUE if successful, FALSE if must suspend */
- {
- /* This routine is heavily used, so it's worth coding tightly. */
- register INT32 put_buffer = (INT32) code;
- register int put_bits = state->cur.put_bits;
-
- /* if size is 0, caller used an invalid Huffman table entry */
- if (size == 0)
- ERREXIT(state->cinfo, JERR_HUFF_MISSING_CODE);
-
- put_buffer &= (((INT32) 1)<<size) - 1; /* mask off any extra bits in code */
-
- put_bits += size; /* new number of bits in buffer */
-
- put_buffer <<= 24 - put_bits; /* align incoming bits */
-
- put_buffer |= state->cur.put_buffer; /* and merge with old buffer contents */
-
- while (put_bits >= 8) {
- int c = (int) ((put_buffer >> 16) & 0xFF);
-
- emit_byte(state, c, return FALSE);
- if (c == 0xFF) { /* need to stuff a zero byte? */
- emit_byte(state, 0, return FALSE);
- }
- put_buffer <<= 8;
- put_bits -= 8;
- }
-
- state->cur.put_buffer = put_buffer; /* update state variables */
- state->cur.put_bits = put_bits;
-
- return TRUE;
- }
-
- LOCAL(boolean)
- flush_bits (working_state * state)
- {
- if (! emit_bits(state, 0x7F, 7)) /* fill any partial byte with ones */
- return FALSE;
- state->cur.put_buffer = 0; /* and reset bit-buffer to empty */
- state->cur.put_bits = 0;
- return TRUE;
- }
-
- /* Encode a single block's worth of coefficients */
-
- LOCAL(boolean)
- encode_one_block (working_state * state, JCOEFPTR block, int last_dc_val,
- c_derived_tbl *dctbl, c_derived_tbl *actbl)
- {
- register int temp, temp2;
- register int nbits;
- register int k, r, i;
-
- /* Encode the DC coefficient difference per section F.1.2.1 */
-
- temp = temp2 = block[0] - last_dc_val;
-
- if (temp < 0) {
- temp = -temp; /* temp is abs value of input */
- /* For a negative input, want temp2 = bitwise complement of abs(input) */
- /* This code assumes we are on a two's complement machine */
- temp2--;
- }
-
- /* Find the number of bits needed for the magnitude of the coefficient */
- nbits = 0;
- while (temp) {
- nbits++;
- temp >>= 1;
- }
- /* Check for out-of-range coefficient values.
- * Since we're encoding a difference, the range limit is twice as much.
- */
- if (nbits > MAX_COEF_BITS+1)
- ERREXIT(state->cinfo, JERR_BAD_DCT_COEF);
-
- /* Emit the Huffman-coded symbol for the number of bits */
- if (! emit_bits(state, dctbl->ehufco[nbits], dctbl->ehufsi[nbits]))
- return FALSE;
-
- /* Emit that number of bits of the value, if positive, */
- /* or the complement of its magnitude, if negative. */
- if (nbits) /* emit_bits rejects calls with size 0 */
- if (! emit_bits(state, (unsigned int) temp2, nbits))
- return FALSE;
-
- /* Encode the AC coefficients per section F.1.2.2 */
-
- r = 0; /* r = run length of zeros */
-
- for (k = 1; k < DCTSIZE2; k++) {
- if ((temp = block[jpeg_natural_order[k]]) == 0) {
- r++;
- } else {
- /* if run length > 15, must emit special run-length-16 codes (0xF0) */
- while (r > 15) {
- if (! emit_bits(state, actbl->ehufco[0xF0], actbl->ehufsi[0xF0]))
- return FALSE;
- r -= 16;
- }
-
- temp2 = temp;
- if (temp < 0) {
- temp = -temp; /* temp is abs value of input */
- /* This code assumes we are on a two's complement machine */
- temp2--;
- }
-
- /* Find the number of bits needed for the magnitude of the coefficient */
- nbits = 1; /* there must be at least one 1 bit */
- while ((temp >>= 1))
- nbits++;
- /* Check for out-of-range coefficient values */
- if (nbits > MAX_COEF_BITS)
- ERREXIT(state->cinfo, JERR_BAD_DCT_COEF);
-
- /* Emit Huffman symbol for run length / number of bits */
- i = (r << 4) + nbits;
- if (! emit_bits(state, actbl->ehufco[i], actbl->ehufsi[i]))
- return FALSE;
-
- /* Emit that number of bits of the value, if positive, */
- /* or the complement of its magnitude, if negative. */
- if (! emit_bits(state, (unsigned int) temp2, nbits))
- return FALSE;
-
- r = 0;
- }
- }
-
- /* If the last coef(s) were zero, emit an end-of-block code */
- if (r > 0)
- if (! emit_bits(state, actbl->ehufco[0], actbl->ehufsi[0]))
- return FALSE;
-
- return TRUE;
- }
-
- /*
- * Emit a restart marker & resynchronize predictions.
- */
-
- LOCAL(boolean)
- emit_restart (working_state * state, int restart_num)
- {
- int ci;
-
- if (! flush_bits(state))
- return FALSE;
-
- emit_byte(state, 0xFF, return FALSE);
- emit_byte(state, JPEG_RST0 + restart_num, return FALSE);
-
- /* Re-initialize DC predictions to 0 */
- for (ci = 0; ci < state->cinfo->comps_in_scan; ci++)
- state->cur.last_dc_val[ci] = 0;
-
- /* The restart counter is not updated until we successfully write the MCU. */
-
- return TRUE;
- }
-
- /*
- * Encode and output one MCU's worth of Huffman-compressed coefficients.
- */
-
- METHODDEF(boolean)
- encode_mcu_huff (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
- {
- huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
- working_state state;
- int blkn, ci;
- jpeg_component_info * compptr;
-
- /* Load up working state */
- state.next_output_byte = cinfo->dest->next_output_byte;
- state.free_in_buffer = cinfo->dest->free_in_buffer;
- ASSIGN_STATE(state.cur, entropy->saved);
- state.cinfo = cinfo;
-
- /* Emit restart marker if needed */
- if (cinfo->restart_interval) {
- if (entropy->restarts_to_go == 0)
- if (! emit_restart(&state, entropy->next_restart_num))
- return FALSE;
- }
-
- /* Encode the MCU data blocks */
- for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
- ci = cinfo->MCU_membership[blkn];
- compptr = cinfo->cur_comp_info[ci];
- if (! encode_one_block(&state,
- MCU_data[blkn][0], state.cur.last_dc_val[ci],
- entropy->dc_derived_tbls[compptr->dc_tbl_no],
- entropy->ac_derived_tbls[compptr->ac_tbl_no]))
- return FALSE;
- /* Update last_dc_val */
- state.cur.last_dc_val[ci] = MCU_data[blkn][0][0];
- }
-
- /* Completed MCU, so update state */
- cinfo->dest->next_output_byte = state.next_output_byte;
- cinfo->dest->free_in_buffer = state.free_in_buffer;
- ASSIGN_STATE(entropy->saved, state.cur);
-
- /* Update restart-interval state too */
- if (cinfo->restart_interval) {
- if (entropy->restarts_to_go == 0) {
- entropy->restarts_to_go = cinfo->restart_interval;
- entropy->next_restart_num++;
- entropy->next_restart_num &= 7;
- }
- entropy->restarts_to_go--;
- }
-
- return TRUE;
- }
-
- /*
- * Finish up at the end of a Huffman-compressed scan.
- */
-
- METHODDEF(void)
- finish_pass_huff (j_compress_ptr cinfo)
- {
- huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
- working_state state;
-
- /* Load up working state ... flush_bits needs it */
- state.next_output_byte = cinfo->dest->next_output_byte;
- state.free_in_buffer = cinfo->dest->free_in_buffer;
- ASSIGN_STATE(state.cur, entropy->saved);
- state.cinfo = cinfo;
-
- /* Flush out the last data */
- if (! flush_bits(&state))
- ERREXIT(cinfo, JERR_CANT_SUSPEND);
-
- /* Update state */
- cinfo->dest->next_output_byte = state.next_output_byte;
- cinfo->dest->free_in_buffer = state.free_in_buffer;
- ASSIGN_STATE(entropy->saved, state.cur);
- }
-
- /*
- * Huffman coding optimization.
- *
- * We first scan the supplied data and count the number of uses of each symbol
- * that is to be Huffman-coded. (This process MUST agree with the code above.)
- * Then we build a Huffman coding tree for the observed counts.
- * Symbols which are not needed at all for the particular image are not
- * assigned any code, which saves space in the DHT marker as well as in
- * the compressed data.
- */
-
- #ifdef ENTROPY_OPT_SUPPORTED
-
- /* Process a single block's worth of coefficients */
-
- LOCAL(void)
- htest_one_block (j_compress_ptr cinfo, JCOEFPTR block, int last_dc_val,
- long dc_counts[], long ac_counts[])
- {
- register int temp;
- register int nbits;
- register int k, r;
-
- /* Encode the DC coefficient difference per section F.1.2.1 */
-
- temp = block[0] - last_dc_val;
- if (temp < 0)
- temp = -temp;
-
- /* Find the number of bits needed for the magnitude of the coefficient */
- nbits = 0;
- while (temp) {
- nbits++;
- temp >>= 1;
- }
- /* Check for out-of-range coefficient values.
- * Since we're encoding a difference, the range limit is twice as much.
- */
- if (nbits > MAX_COEF_BITS+1)
- ERREXIT(cinfo, JERR_BAD_DCT_COEF);
-
- /* Count the Huffman symbol for the number of bits */
- dc_counts[nbits]++;
-
- /* Encode the AC coefficients per section F.1.2.2 */
-
- r = 0; /* r = run length of zeros */
-
- for (k = 1; k < DCTSIZE2; k++) {
- if ((temp = block[jpeg_natural_order[k]]) == 0) {
- r++;
- } else {
- /* if run length > 15, must emit special run-length-16 codes (0xF0) */
- while (r > 15) {
- ac_counts[0xF0]++;
- r -= 16;
- }
-
- /* Find the number of bits needed for the magnitude of the coefficient */
- if (temp < 0)
- temp = -temp;
-
- /* Find the number of bits needed for the magnitude of the coefficient */
- nbits = 1; /* there must be at least one 1 bit */
- while ((temp >>= 1))
- nbits++;
- /* Check for out-of-range coefficient values */
- if (nbits > MAX_COEF_BITS)
- ERREXIT(cinfo, JERR_BAD_DCT_COEF);
-
- /* Count Huffman symbol for run length / number of bits */
- ac_counts[(r << 4) + nbits]++;
-
- r = 0;
- }
- }
-
- /* If the last coef(s) were zero, emit an end-of-block code */
- if (r > 0)
- ac_counts[0]++;
- }
-
- /*
- * Trial-encode one MCU's worth of Huffman-compressed coefficients.
- * No data is actually output, so no suspension return is possible.
- */
-
- METHODDEF(boolean)
- encode_mcu_gather (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
- {
- huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
- int blkn, ci;
- jpeg_component_info * compptr;
-
- /* Take care of restart intervals if needed */
- if (cinfo->restart_interval) {
- if (entropy->restarts_to_go == 0) {
- /* Re-initialize DC predictions to 0 */
- for (ci = 0; ci < cinfo->comps_in_scan; ci++)
- entropy->saved.last_dc_val[ci] = 0;
- /* Update restart state */
- entropy->restarts_to_go = cinfo->restart_interval;
- }
- entropy->restarts_to_go--;
- }
-
- for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
- ci = cinfo->MCU_membership[blkn];
- compptr = cinfo->cur_comp_info[ci];
- htest_one_block(cinfo, MCU_data[blkn][0], entropy->saved.last_dc_val[ci],
- entropy->dc_count_ptrs[compptr->dc_tbl_no],
- entropy->ac_count_ptrs[compptr->ac_tbl_no]);
- entropy->saved.last_dc_val[ci] = MCU_data[blkn][0][0];
- }
-
- return TRUE;
- }
-
- /*
- * Generate the best Huffman code table for the given counts, fill htbl.
- * Note this is also used by jcphuff.c.
- *
- * The JPEG standard requires that no symbol be assigned a codeword of all
- * one bits (so that padding bits added at the end of a compressed segment
- * can't look like a valid code). Because of the canonical ordering of
- * codewords, this just means that there must be an unused slot in the
- * longest codeword length category. Section K.2 of the JPEG spec suggests
- * reserving such a slot by pretending that symbol 256 is a valid symbol
- * with count 1. In theory that's not optimal; giving it count zero but
- * including it in the symbol set anyway should give a better Huffman code.
- * But the theoretically better code actually seems to come out worse in
- * practice, because it produces more all-ones bytes (which incur stuffed
- * zero bytes in the final file). In any case the difference is tiny.
- *
- * The JPEG standard requires Huffman codes to be no more than 16 bits long.
- * If some symbols have a very small but nonzero probability, the Huffman tree
- * must be adjusted to meet the code length restriction. We currently use
- * the adjustment method suggested in JPEG section K.2. This method is *not*
- * optimal; it may not choose the best possible limited-length code. But
- * typically only very-low-frequency symbols will be given less-than-optimal
- * lengths, so the code is almost optimal. Experimental comparisons against
- * an optimal limited-length-code algorithm indicate that the difference is
- * microscopic --- usually less than a hundredth of a percent of total size.
- * So the extra complexity of an optimal algorithm doesn't seem worthwhile.
- */
-
- GLOBAL(void)
- jpeg_gen_optimal_table (j_compress_ptr cinfo, JHUFF_TBL * htbl, long freq[])
- {
- #define MAX_CLEN 32 /* assumed maximum initial code length */
- UINT8 bits[MAX_CLEN+1]; /* bits[k] = # of symbols with code length k */
- int codesize[257]; /* codesize[k] = code length of symbol k */
- int others[257]; /* next symbol in current branch of tree */
- int c1, c2;
- int p, i, j;
- long v;
-
- /* This algorithm is explained in section K.2 of the JPEG standard */
-
- MEMZERO(bits, SIZEOF(bits));
- MEMZERO(codesize, SIZEOF(codesize));
- for (i = 0; i < 257; i++)
- others[i] = -1; /* init links to empty */
-
- freq[256] = 1; /* make sure 256 has a nonzero count */
- /* Including the pseudo-symbol 256 in the Huffman procedure guarantees
- * that no real symbol is given code-value of all ones, because 256
- * will be placed last in the largest codeword category.
- */
-
- /* Huffman's basic algorithm to assign optimal code lengths to symbols */
-
- for (;;) {
- /* Find the smallest nonzero frequency, set c1 = its symbol */
- /* In case of ties, take the larger symbol number */
- c1 = -1;
- v = 1000000000L;
- for (i = 0; i <= 256; i++) {
- if (freq[i] && freq[i] <= v) {
- v = freq[i];
- c1 = i;
- }
- }
-
- /* Find the next smallest nonzero frequency, set c2 = its symbol */
- /* In case of ties, take the larger symbol number */
- c2 = -1;
- v = 1000000000L;
- for (i = 0; i <= 256; i++) {
- if (freq[i] && freq[i] <= v && i != c1) {
- v = freq[i];
- c2 = i;
- }
- }
-
- /* Done if we've merged everything into one frequency */
- if (c2 < 0)
- break;
-
- /* Else merge the two counts/trees */
- freq[c1] += freq[c2];
- freq[c2] = 0;
-
- /* Increment the codesize of everything in c1's tree branch */
- codesize[c1]++;
- while (others[c1] >= 0) {
- c1 = others[c1];
- codesize[c1]++;
- }
-
- others[c1] = c2; /* chain c2 onto c1's tree branch */
-
- /* Increment the codesize of everything in c2's tree branch */
- codesize[c2]++;
- while (others[c2] >= 0) {
- c2 = others[c2];
- codesize[c2]++;
- }
- }
-
- /* Now count the number of symbols of each code length */
- for (i = 0; i <= 256; i++) {
- if (codesize[i]) {
- /* The JPEG standard seems to think that this can't happen, */
- /* but I'm paranoid... */
- if (codesize[i] > MAX_CLEN)
- ERREXIT(cinfo, JERR_HUFF_CLEN_OVERFLOW);
-
- bits[codesize[i]]++;
- }
- }
-
- /* JPEG doesn't allow symbols with code lengths over 16 bits, so if the pure
- * Huffman procedure assigned any such lengths, we must adjust the coding.
- * Here is what the JPEG spec says about how this next bit works:
- * Since symbols are paired for the longest Huffman code, the symbols are
- * removed from this length category two at a time. The prefix for the pair
- * (which is one bit shorter) is allocated to one of the pair; then,
- * skipping the BITS entry for that prefix length, a code word from the next
- * shortest nonzero BITS entry is converted into a prefix for two code words
- * one bit longer.
- */
-
- for (i = MAX_CLEN; i > 16; i--) {
- while (bits[i] > 0) {
- j = i - 2; /* find length of new prefix to be used */
- while (bits[j] == 0)
- j--;
-
- bits[i] -= 2; /* remove two symbols */
- bits[i-1]++; /* one goes in this length */
- bits[j+1] += 2; /* two new symbols in this length */
- bits[j]--; /* symbol of this length is now a prefix */
- }
- }
-
- /* Remove the count for the pseudo-symbol 256 from the largest codelength */
- while (bits[i] == 0) /* find largest codelength still in use */
- i--;
- bits[i]--;
-
- /* Return final symbol counts (only for lengths 0..16) */
- MEMCOPY(htbl->bits, bits, SIZEOF(htbl->bits));
-
- /* Return a list of the symbols sorted by code length */
- /* It's not real clear to me why we don't need to consider the codelength
- * changes made above, but the JPEG spec seems to think this works.
- */
- p = 0;
- for (i = 1; i <= MAX_CLEN; i++) {
- for (j = 0; j <= 255; j++) {
- if (codesize[j] == i) {
- htbl->huffval[p] = (UINT8) j;
- p++;
- }
- }
- }
-
- /* Set sent_table FALSE so updated table will be written to JPEG file. */
- htbl->sent_table = FALSE;
- }
-
- /*
- * Finish up a statistics-gathering pass and create the new Huffman tables.
- */
-
- METHODDEF(void)
- finish_pass_gather (j_compress_ptr cinfo)
- {
- huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
- int ci, dctbl, actbl;
- jpeg_component_info * compptr;
- JHUFF_TBL **htblptr;
- boolean did_dc[NUM_HUFF_TBLS];
- boolean did_ac[NUM_HUFF_TBLS];
-
- /* It's important not to apply jpeg_gen_optimal_table more than once
- * per table, because it clobbers the input frequency counts!
- */
- MEMZERO(did_dc, SIZEOF(did_dc));
- MEMZERO(did_ac, SIZEOF(did_ac));
-
- for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
- compptr = cinfo->cur_comp_info[ci];
- dctbl = compptr->dc_tbl_no;
- actbl = compptr->ac_tbl_no;
- if (! did_dc[dctbl]) {
- htblptr = & cinfo->dc_huff_tbl_ptrs[dctbl];
- if (*htblptr == NULL)
- *htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo);
- jpeg_gen_optimal_table(cinfo, *htblptr, entropy->dc_count_ptrs[dctbl]);
- did_dc[dctbl] = TRUE;
- }
- if (! did_ac[actbl]) {
- htblptr = & cinfo->ac_huff_tbl_ptrs[actbl];
- if (*htblptr == NULL)
- *htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo);
- jpeg_gen_optimal_table(cinfo, *htblptr, entropy->ac_count_ptrs[actbl]);
- did_ac[actbl] = TRUE;
- }
- }
- }
-
- #endif /* ENTROPY_OPT_SUPPORTED */
-
- /*
- * Module initialization routine for Huffman entropy encoding.
- */
-
- GLOBAL(void)
- jinit_huff_encoder (j_compress_ptr cinfo)
- {
- huff_entropy_ptr entropy;
- int i;
-
- entropy = (huff_entropy_ptr)
- (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
- SIZEOF(huff_entropy_encoder));
- cinfo->entropy = (struct jpeg_entropy_encoder *) entropy;
- entropy->pub.start_pass = start_pass_huff;
-
- /* Mark tables unallocated */
- for (i = 0; i < NUM_HUFF_TBLS; i++) {
- entropy->dc_derived_tbls[i] = entropy->ac_derived_tbls[i] = NULL;
- #ifdef ENTROPY_OPT_SUPPORTED
- entropy->dc_count_ptrs[i] = entropy->ac_count_ptrs[i] = NULL;
- #endif
- }
- }
- /********* End of inlined file: jchuff.c *********/
-
- #undef emit_byte
-
- /********* Start of inlined file: jcinit.c *********/
- #define JPEG_INTERNALS
-
- /*
- * Master selection of compression modules.
- * This is done once at the start of processing an image. We determine
- * which modules will be used and give them appropriate initialization calls.
- */
-
- GLOBAL(void)
- jinit_compress_master (j_compress_ptr cinfo)
- {
- /* Initialize master control (includes parameter checking/processing) */
- jinit_c_master_control(cinfo, FALSE /* full compression */);
-
- /* Preprocessing */
- if (! cinfo->raw_data_in) {
- jinit_color_converter(cinfo);
- jinit_downsampler(cinfo);
- jinit_c_prep_controller(cinfo, FALSE /* never need full buffer here */);
- }
- /* Forward DCT */
- jinit_forward_dct(cinfo);
- /* Entropy encoding: either Huffman or arithmetic coding. */
- if (cinfo->arith_code) {
- ERREXIT(cinfo, JERR_ARITH_NOTIMPL);
- } else {
- if (cinfo->progressive_mode) {
- #ifdef C_PROGRESSIVE_SUPPORTED
- jinit_phuff_encoder(cinfo);
- #else
- ERREXIT(cinfo, JERR_NOT_COMPILED);
- #endif
- } else
- jinit_huff_encoder(cinfo);
- }
-
- /* Need a full-image coefficient buffer in any multi-pass mode. */
- jinit_c_coef_controller(cinfo,
- (boolean) (cinfo->num_scans > 1 || cinfo->optimize_coding));
- jinit_c_main_controller(cinfo, FALSE /* never need full buffer here */);
-
- jinit_marker_writer(cinfo);
-
- /* We can now tell the memory manager to allocate virtual arrays. */
- (*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo);
-
- /* Write the datastream header (SOI) immediately.
- * Frame and scan headers are postponed till later.
- * This lets application insert special markers after the SOI.
- */
- (*cinfo->marker->write_file_header) (cinfo);
- }
- /********* End of inlined file: jcinit.c *********/
-
- /********* Start of inlined file: jcmainct.c *********/
- #define JPEG_INTERNALS
-
- /* Note: currently, there is no operating mode in which a full-image buffer
- * is needed at this step. If there were, that mode could not be used with
- * "raw data" input, since this module is bypassed in that case. However,
- * we've left the code here for possible use in special applications.
- */
- #undef FULL_MAIN_BUFFER_SUPPORTED
-
- /* Private buffer controller object */
-
- typedef struct {
- struct jpeg_c_main_controller pub; /* public fields */
-
- JDIMENSION cur_iMCU_row; /* number of current iMCU row */
- JDIMENSION rowgroup_ctr; /* counts row groups received in iMCU row */
- boolean suspended; /* remember if we suspended output */
- J_BUF_MODE pass_mode; /* current operating mode */
-
- /* If using just a strip buffer, this points to the entire set of buffers
- * (we allocate one for each component). In the full-image case, this
- * points to the currently accessible strips of the virtual arrays.
- */
- JSAMPARRAY buffer[MAX_COMPONENTS];
-
- #ifdef FULL_MAIN_BUFFER_SUPPORTED
- /* If using full-image storage, this array holds pointers to virtual-array
- * control blocks for each component. Unused if not full-image storage.
- */
- jvirt_sarray_ptr whole_image[MAX_COMPONENTS];
- #endif
- } my_main_controller;
-
- typedef my_main_controller * my_main_ptr;
-
- /* Forward declarations */
- METHODDEF(void) process_data_simple_main
- JPP((j_compress_ptr cinfo, JSAMPARRAY input_buf,
- JDIMENSION *in_row_ctr, JDIMENSION in_rows_avail));
- #ifdef FULL_MAIN_BUFFER_SUPPORTED
- METHODDEF(void) process_data_buffer_main
- JPP((j_compress_ptr cinfo, JSAMPARRAY input_buf,
- JDIMENSION *in_row_ctr, JDIMENSION in_rows_avail));
- #endif
-
- /*
- * Initialize for a processing pass.
- */
-
- METHODDEF(void)
- start_pass_main (j_compress_ptr cinfo, J_BUF_MODE pass_mode)
- {
- my_main_ptr main_ = (my_main_ptr) cinfo->main;
-
- /* Do nothing in raw-data mode. */
- if (cinfo->raw_data_in)
- return;
-
- main_->cur_iMCU_row = 0; /* initialize counters */
- main_->rowgroup_ctr = 0;
- main_->suspended = FALSE;
- main_->pass_mode = pass_mode; /* save mode for use by process_data */
-
- switch (pass_mode) {
- case JBUF_PASS_THRU:
- #ifdef FULL_MAIN_BUFFER_SUPPORTED
- if (main_->whole_image[0] != NULL)
- ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
- #endif
- main_->pub.process_data = process_data_simple_main;
- break;
- #ifdef FULL_MAIN_BUFFER_SUPPORTED
- case JBUF_SAVE_SOURCE:
- case JBUF_CRANK_DEST:
- case JBUF_SAVE_AND_PASS:
- if (main_->whole_image[0] == NULL)
- ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
- main_->pub.process_data = process_data_buffer_main;
- break;
- #endif
- default:
- ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
- break;
- }
- }
-
- /*
- * Process some data.
- * This routine handles the simple pass-through mode,
- * where we have only a strip buffer.
- */
-
- METHODDEF(void)
- process_data_simple_main (j_compress_ptr cinfo,
- JSAMPARRAY input_buf, JDIMENSION *in_row_ctr,
- JDIMENSION in_rows_avail)
- {
- my_main_ptr main_ = (my_main_ptr) cinfo->main;
-
- while (main_->cur_iMCU_row < cinfo->total_iMCU_rows) {
- /* Read input data if we haven't filled the main buffer yet */
- if (main_->rowgroup_ctr < DCTSIZE)
- (*cinfo->prep->pre_process_data) (cinfo,
- input_buf, in_row_ctr, in_rows_avail,
- main_->buffer, &main_->rowgroup_ctr,
- (JDIMENSION) DCTSIZE);
-
- /* If we don't have a full iMCU row buffered, return to application for
- * more data. Note that preprocessor will always pad to fill the iMCU row
- * at the bottom of the image.
- */
- if (main_->rowgroup_ctr != DCTSIZE)
- return;
-
- /* Send the completed row to the compressor */
- if (! (*cinfo->coef->compress_data) (cinfo, main_->buffer)) {
- /* If compressor did not consume the whole row, then we must need to
- * suspend processing and return to the application. In this situation
- * we pretend we didn't yet consume the last input row; otherwise, if
- * it happened to be the last row of the image, the application would
- * think we were done.
- */
- if (! main_->suspended) {
- (*in_row_ctr)--;
- main_->suspended = TRUE;
- }
- return;
- }
- /* We did finish the row. Undo our little suspension hack if a previous
- * call suspended; then mark the main buffer empty.
- */
- if (main_->suspended) {
- (*in_row_ctr)++;
- main_->suspended = FALSE;
- }
- main_->rowgroup_ctr = 0;
- main_->cur_iMCU_row++;
- }
- }
-
- #ifdef FULL_MAIN_BUFFER_SUPPORTED
-
- /*
- * Process some data.
- * This routine handles all of the modes that use a full-size buffer.
- */
-
- METHODDEF(void)
- process_data_buffer_main (j_compress_ptr cinfo,
- JSAMPARRAY input_buf, JDIMENSION *in_row_ctr,
- JDIMENSION in_rows_avail)
- {
- my_main_ptr main = (my_main_ptr) cinfo->main;
- int ci;
- jpeg_component_info *compptr;
- boolean writing = (main->pass_mode != JBUF_CRANK_DEST);
-
- while (main->cur_iMCU_row < cinfo->total_iMCU_rows) {
- /* Realign the virtual buffers if at the start of an iMCU row. */
- if (main->rowgroup_ctr == 0) {
- for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
- ci++, compptr++) {
- main->buffer[ci] = (*cinfo->mem->access_virt_sarray)
- ((j_common_ptr) cinfo, main->whole_image[ci],
- main->cur_iMCU_row * (compptr->v_samp_factor * DCTSIZE),
- (JDIMENSION) (compptr->v_samp_factor * DCTSIZE), writing);
- }
- /* In a read pass, pretend we just read some source data. */
- if (! writing) {
- *in_row_ctr += cinfo->max_v_samp_factor * DCTSIZE;
- main->rowgroup_ctr = DCTSIZE;
- }
- }
-
- /* If a write pass, read input data until the current iMCU row is full. */
- /* Note: preprocessor will pad if necessary to fill the last iMCU row. */
- if (writing) {
- (*cinfo->prep->pre_process_data) (cinfo,
- input_buf, in_row_ctr, in_rows_avail,
- main->buffer, &main->rowgroup_ctr,
- (JDIMENSION) DCTSIZE);
- /* Return to application if we need more data to fill the iMCU row. */
- if (main->rowgroup_ctr < DCTSIZE)
- return;
- }
-
- /* Emit data, unless this is a sink-only pass. */
- if (main->pass_mode != JBUF_SAVE_SOURCE) {
- if (! (*cinfo->coef->compress_data) (cinfo, main->buffer)) {
- /* If compressor did not consume the whole row, then we must need to
- * suspend processing and return to the application. In this situation
- * we pretend we didn't yet consume the last input row; otherwise, if
- * it happened to be the last row of the image, the application would
- * think we were done.
- */
- if (! main->suspended) {
- (*in_row_ctr)--;
- main->suspended = TRUE;
- }
- return;
- }
- /* We did finish the row. Undo our little suspension hack if a previous
- * call suspended; then mark the main buffer empty.
- */
- if (main->suspended) {
- (*in_row_ctr)++;
- main->suspended = FALSE;
- }
- }
-
- /* If get here, we are done with this iMCU row. Mark buffer empty. */
- main->rowgroup_ctr = 0;
- main->cur_iMCU_row++;
- }
- }
-
- #endif /* FULL_MAIN_BUFFER_SUPPORTED */
-
- /*
- * Initialize main buffer controller.
- */
-
- GLOBAL(void)
- jinit_c_main_controller (j_compress_ptr cinfo, boolean need_full_buffer)
- {
- my_main_ptr main_;
- int ci;
- jpeg_component_info *compptr;
-
- main_ = (my_main_ptr)
- (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
- SIZEOF(my_main_controller));
- cinfo->main = (struct jpeg_c_main_controller *) main_;
- main_->pub.start_pass = start_pass_main;
-
- /* We don't need to create a buffer in raw-data mode. */
- if (cinfo->raw_data_in)
- return;
-
- /* Create the buffer. It holds downsampled data, so each component
- * may be of a different size.
- */
- if (need_full_buffer) {
- #ifdef FULL_MAIN_BUFFER_SUPPORTED
- /* Allocate a full-image virtual array for each component */
- /* Note we pad the bottom to a multiple of the iMCU height */
- for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
- ci++, compptr++) {
- main->whole_image[ci] = (*cinfo->mem->request_virt_sarray)
- ((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE,
- compptr->width_in_blocks * DCTSIZE,
- (JDIMENSION) jround_up((long) compptr->height_in_blocks,
- (long) compptr->v_samp_factor) * DCTSIZE,
- (JDIMENSION) (compptr->v_samp_factor * DCTSIZE));
- }
- #else
- ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
- #endif
- } else {
- #ifdef FULL_MAIN_BUFFER_SUPPORTED
- main_->whole_image[0] = NULL; /* flag for no virtual arrays */
- #endif
- /* Allocate a strip buffer for each component */
- for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
- ci++, compptr++) {
- main_->buffer[ci] = (*cinfo->mem->alloc_sarray)
- ((j_common_ptr) cinfo, JPOOL_IMAGE,
- compptr->width_in_blocks * DCTSIZE,
- (JDIMENSION) (compptr->v_samp_factor * DCTSIZE));
- }
- }
- }
- /********* End of inlined file: jcmainct.c *********/
-
- /********* Start of inlined file: jcmarker.c *********/
- #define JPEG_INTERNALS
-
- /* Private state */
-
- typedef struct {
- struct jpeg_marker_writer pub; /* public fields */
-
- unsigned int last_restart_interval; /* last DRI value emitted; 0 after SOI */
- } my_marker_writer;
-
- typedef my_marker_writer * my_marker_ptr;
-
- /*
- * Basic output routines.
- *
- * Note that we do not support suspension while writing a marker.
- * Therefore, an application using suspension must ensure that there is
- * enough buffer space for the initial markers (typ. 600-700 bytes) before
- * calling jpeg_start_compress, and enough space to write the trailing EOI
- * (a few bytes) before calling jpeg_finish_compress. Multipass compression
- * modes are not supported at all with suspension, so those two are the only
- * points where markers will be written.
- */
-
- LOCAL(void)
- emit_byte (j_compress_ptr cinfo, int val)
- /* Emit a byte */
- {
- struct jpeg_destination_mgr * dest = cinfo->dest;
-
- *(dest->next_output_byte)++ = (JOCTET) val;
- if (--dest->free_in_buffer == 0) {
- if (! (*dest->empty_output_buffer) (cinfo))
- ERREXIT(cinfo, JERR_CANT_SUSPEND);
- }
- }
-
- LOCAL(void)
- emit_marker (j_compress_ptr cinfo, JPEG_MARKER mark)
- /* Emit a marker code */
- {
- emit_byte(cinfo, 0xFF);
- emit_byte(cinfo, (int) mark);
- }
-
- LOCAL(void)
- emit_2bytes (j_compress_ptr cinfo, int value)
- /* Emit a 2-byte integer; these are always MSB first in JPEG files */
- {
- emit_byte(cinfo, (value >> 8) & 0xFF);
- emit_byte(cinfo, value & 0xFF);
- }
-
- /*
- * Routines to write specific marker types.
- */
-
- LOCAL(int)
- emit_dqt (j_compress_ptr cinfo, int index)
- /* Emit a DQT marker */
- /* Returns the precision used (0 = 8bits, 1 = 16bits) for baseline checking */
- {
- JQUANT_TBL * qtbl = cinfo->quant_tbl_ptrs[index];
- int prec;
- int i;
-
- if (qtbl == NULL)
- ERREXIT1(cinfo, JERR_NO_QUANT_TABLE, index);
-
- prec = 0;
- for (i = 0; i < DCTSIZE2; i++) {
- if (qtbl->quantval[i] > 255)
- prec = 1;
- }
-
- if (! qtbl->sent_table) {
- emit_marker(cinfo, M_DQT);
-
- emit_2bytes(cinfo, prec ? DCTSIZE2*2 + 1 + 2 : DCTSIZE2 + 1 + 2);
-
- emit_byte(cinfo, index + (prec<<4));
-
- for (i = 0; i < DCTSIZE2; i++) {
- /* The table entries must be emitted in zigzag order. */
- unsigned int qval = qtbl->quantval[jpeg_natural_order[i]];
- if (prec)
- emit_byte(cinfo, (int) (qval >> 8));
- emit_byte(cinfo, (int) (qval & 0xFF));
- }
-
- qtbl->sent_table = TRUE;
- }
-
- return prec;
- }
-
- LOCAL(void)
- emit_dht (j_compress_ptr cinfo, int index, boolean is_ac)
- /* Emit a DHT marker */
- {
- JHUFF_TBL * htbl;
- int length, i;
-
- if (is_ac) {
- htbl = cinfo->ac_huff_tbl_ptrs[index];
- index += 0x10; /* output index has AC bit set */
- } else {
- htbl = cinfo->dc_huff_tbl_ptrs[index];
- }
-
- if (htbl == NULL)
- ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, index);
-
- if (! htbl->sent_table) {
- emit_marker(cinfo, M_DHT);
-
- length = 0;
- for (i = 1; i <= 16; i++)
- length += htbl->bits[i];
-
- emit_2bytes(cinfo, length + 2 + 1 + 16);
- emit_byte(cinfo, index);
-
- for (i = 1; i <= 16; i++)
- emit_byte(cinfo, htbl->bits[i]);
-
- for (i = 0; i < length; i++)
- emit_byte(cinfo, htbl->huffval[i]);
-
- htbl->sent_table = TRUE;
- }
- }
-
- LOCAL(void)
- emit_dac (j_compress_ptr cinfo)
- /* Emit a DAC marker */
- /* Since the useful info is so small, we want to emit all the tables in */
- /* one DAC marker. Therefore this routine does its own scan of the table. */
- {
- #ifdef C_ARITH_CODING_SUPPORTED
- char dc_in_use[NUM_ARITH_TBLS];
- char ac_in_use[NUM_ARITH_TBLS];
- int length, i;
- jpeg_component_info *compptr;
-
- for (i = 0; i < NUM_ARITH_TBLS; i++)
- dc_in_use[i] = ac_in_use[i] = 0;
-
- for (i = 0; i < cinfo->comps_in_scan; i++) {
- compptr = cinfo->cur_comp_info[i];
- dc_in_use[compptr->dc_tbl_no] = 1;
- ac_in_use[compptr->ac_tbl_no] = 1;
- }
-
- length = 0;
- for (i = 0; i < NUM_ARITH_TBLS; i++)
- length += dc_in_use[i] + ac_in_use[i];
-
- emit_marker(cinfo, M_DAC);
-
- emit_2bytes(cinfo, length*2 + 2);
-
- for (i = 0; i < NUM_ARITH_TBLS; i++) {
- if (dc_in_use[i]) {
- emit_byte(cinfo, i);
- emit_byte(cinfo, cinfo->arith_dc_L[i] + (cinfo->arith_dc_U[i]<<4));
- }
- if (ac_in_use[i]) {
- emit_byte(cinfo, i + 0x10);
- emit_byte(cinfo, cinfo->arith_ac_K[i]);
- }
- }
- #endif /* C_ARITH_CODING_SUPPORTED */
- }
-
- LOCAL(void)
- emit_dri (j_compress_ptr cinfo)
- /* Emit a DRI marker */
- {
- emit_marker(cinfo, M_DRI);
-
- emit_2bytes(cinfo, 4); /* fixed length */
-
- emit_2bytes(cinfo, (int) cinfo->restart_interval);
- }
-
- LOCAL(void)
- emit_sof (j_compress_ptr cinfo, JPEG_MARKER code)
- /* Emit a SOF marker */
- {
- int ci;
- jpeg_component_info *compptr;
-
- emit_marker(cinfo, code);
-
- emit_2bytes(cinfo, 3 * cinfo->num_components + 2 + 5 + 1); /* length */
-
- /* Make sure image isn't bigger than SOF field can handle */
- if ((long) cinfo->image_height > 65535L ||
- (long) cinfo->image_width > 65535L)
- ERREXIT1(cinfo, JERR_IMAGE_TOO_BIG, (unsigned int) 65535);
-
- emit_byte(cinfo, cinfo->data_precision);
- emit_2bytes(cinfo, (int) cinfo->image_height);
- emit_2bytes(cinfo, (int) cinfo->image_width);
-
- emit_byte(cinfo, cinfo->num_components);
-
- for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
- ci++, compptr++) {
- emit_byte(cinfo, compptr->component_id);
- emit_byte(cinfo, (compptr->h_samp_factor << 4) + compptr->v_samp_factor);
- emit_byte(cinfo, compptr->quant_tbl_no);
- }
- }
-
- LOCAL(void)
- emit_sos (j_compress_ptr cinfo)
- /* Emit a SOS marker */
- {
- int i, td, ta;
- jpeg_component_info *compptr;
-
- emit_marker(cinfo, M_SOS);
-
- emit_2bytes(cinfo, 2 * cinfo->comps_in_scan + 2 + 1 + 3); /* length */
-
- emit_byte(cinfo, cinfo->comps_in_scan);
-
- for (i = 0; i < cinfo->comps_in_scan; i++) {
- compptr = cinfo->cur_comp_info[i];
- emit_byte(cinfo, compptr->component_id);
- td = compptr->dc_tbl_no;
- ta = compptr->ac_tbl_no;
- if (cinfo->progressive_mode) {
- /* Progressive mode: only DC or only AC tables are used in one scan;
- * furthermore, Huffman coding of DC refinement uses no table at all.
- * We emit 0 for unused field(s); this is recommended by the P&M text
- * but does not seem to be specified in the standard.
- */
- if (cinfo->Ss == 0) {
- ta = 0; /* DC scan */
- if (cinfo->Ah != 0 && !cinfo->arith_code)
- td = 0; /* no DC table either */
- } else {
- td = 0; /* AC scan */
- }
- }
- emit_byte(cinfo, (td << 4) + ta);
- }
-
- emit_byte(cinfo, cinfo->Ss);
- emit_byte(cinfo, cinfo->Se);
- emit_byte(cinfo, (cinfo->Ah << 4) + cinfo->Al);
- }
-
- LOCAL(void)
- emit_jfif_app0 (j_compress_ptr cinfo)
- /* Emit a JFIF-compliant APP0 marker */
- {
- /*
- * Length of APP0 block (2 bytes)
- * Block ID (4 bytes - ASCII "JFIF")
- * Zero byte (1 byte to terminate the ID string)
- * Version Major, Minor (2 bytes - major first)
- * Units (1 byte - 0x00 = none, 0x01 = inch, 0x02 = cm)
- * Xdpu (2 bytes - dots per unit horizontal)
- * Ydpu (2 bytes - dots per unit vertical)
- * Thumbnail X size (1 byte)
- * Thumbnail Y size (1 byte)
- */
-
- emit_marker(cinfo, M_APP0);
-
- emit_2bytes(cinfo, 2 + 4 + 1 + 2 + 1 + 2 + 2 + 1 + 1); /* length */
-
- emit_byte(cinfo, 0x4A); /* Identifier: ASCII "JFIF" */
- emit_byte(cinfo, 0x46);
- emit_byte(cinfo, 0x49);
- emit_byte(cinfo, 0x46);
- emit_byte(cinfo, 0);
- emit_byte(cinfo, cinfo->JFIF_major_version); /* Version fields */
- emit_byte(cinfo, cinfo->JFIF_minor_version);
- emit_byte(cinfo, cinfo->density_unit); /* Pixel size information */
- emit_2bytes(cinfo, (int) cinfo->X_density);
- emit_2bytes(cinfo, (int) cinfo->Y_density);
- emit_byte(cinfo, 0); /* No thumbnail image */
- emit_byte(cinfo, 0);
- }
-
- LOCAL(void)
- emit_adobe_app14 (j_compress_ptr cinfo)
- /* Emit an Adobe APP14 marker */
- {
- /*
- * Length of APP14 block (2 bytes)
- * Block ID (5 bytes - ASCII "Adobe")
- * Version Number (2 bytes - currently 100)
- * Flags0 (2 bytes - currently 0)
- * Flags1 (2 bytes - currently 0)
- * Color transform (1 byte)
- *
- * Although Adobe TN 5116 mentions Version = 101, all the Adobe files
- * now in circulation seem to use Version = 100, so that's what we write.
- *
- * We write the color transform byte as 1 if the JPEG color space is
- * YCbCr, 2 if it's YCCK, 0 otherwise. Adobe's definition has to do with
- * whether the encoder performed a transformation, which is pretty useless.
- */
-
- emit_marker(cinfo, M_APP14);
-
- emit_2bytes(cinfo, 2 + 5 + 2 + 2 + 2 + 1); /* length */
-
- emit_byte(cinfo, 0x41); /* Identifier: ASCII "Adobe" */
- emit_byte(cinfo, 0x64);
- emit_byte(cinfo, 0x6F);
- emit_byte(cinfo, 0x62);
- emit_byte(cinfo, 0x65);
- emit_2bytes(cinfo, 100); /* Version */
- emit_2bytes(cinfo, 0); /* Flags0 */
- emit_2bytes(cinfo, 0); /* Flags1 */
- switch (cinfo->jpeg_color_space) {
- case JCS_YCbCr:
- emit_byte(cinfo, 1); /* Color transform = 1 */
- break;
- case JCS_YCCK:
- emit_byte(cinfo, 2); /* Color transform = 2 */
- break;
- default:
- emit_byte(cinfo, 0); /* Color transform = 0 */
- break;
- }
- }
-
- /*
- * These routines allow writing an arbitrary marker with parameters.
- * The only intended use is to emit COM or APPn markers after calling
- * write_file_header and before calling write_frame_header.
- * Other uses are not guaranteed to produce desirable results.
- * Counting the parameter bytes properly is the caller's responsibility.
- */
-
- METHODDEF(void)
- write_marker_header (j_compress_ptr cinfo, int marker, unsigned int datalen)
- /* Emit an arbitrary marker header */
- {
- if (datalen > (unsigned int) 65533) /* safety check */
- ERREXIT(cinfo, JERR_BAD_LENGTH);
-
- emit_marker(cinfo, (JPEG_MARKER) marker);
-
- emit_2bytes(cinfo, (int) (datalen + 2)); /* total length */
- }
-
- METHODDEF(void)
- write_marker_byte (j_compress_ptr cinfo, int val)
- /* Emit one byte of marker parameters following write_marker_header */
- {
- emit_byte(cinfo, val);
- }
-
- /*
- * Write datastream header.
- * This consists of an SOI and optional APPn markers.
- * We recommend use of the JFIF marker, but not the Adobe marker,
- * when using YCbCr or grayscale data. The JFIF marker should NOT
- * be used for any other JPEG colorspace. The Adobe marker is helpful
- * to distinguish RGB, CMYK, and YCCK colorspaces.
- * Note that an application can write additional header markers after
- * jpeg_start_compress returns.
- */
-
- METHODDEF(void)
- write_file_header (j_compress_ptr cinfo)
- {
- my_marker_ptr marker = (my_marker_ptr) cinfo->marker;
-
- emit_marker(cinfo, M_SOI); /* first the SOI */
-
- /* SOI is defined to reset restart interval to 0 */
- marker->last_restart_interval = 0;
-
- if (cinfo->write_JFIF_header) /* next an optional JFIF APP0 */
- emit_jfif_app0(cinfo);
- if (cinfo->write_Adobe_marker) /* next an optional Adobe APP14 */
- emit_adobe_app14(cinfo);
- }
-
- /*
- * Write frame header.
- * This consists of DQT and SOFn markers.
- * Note that we do not emit the SOF until we have emitted the DQT(s).
- * This avoids compatibility problems with incorrect implementations that
- * try to error-check the quant table numbers as soon as they see the SOF.
- */
-
- METHODDEF(void)
- write_frame_header (j_compress_ptr cinfo)
- {
- int ci, prec;
- boolean is_baseline;
- jpeg_component_info *compptr;
-
- /* Emit DQT for each quantization table.
- * Note that emit_dqt() suppresses any duplicate tables.
- */
- prec = 0;
- for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
- ci++, compptr++) {
- prec += emit_dqt(cinfo, compptr->quant_tbl_no);
- }
- /* now prec is nonzero iff there are any 16-bit quant tables. */
-
- /* Check for a non-baseline specification.
- * Note we assume that Huffman table numbers won't be changed later.
- */
- if (cinfo->arith_code || cinfo->progressive_mode ||
- cinfo->data_precision != 8) {
- is_baseline = FALSE;
- } else {
- is_baseline = TRUE;
- for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
- ci++, compptr++) {
- if (compptr->dc_tbl_no > 1 || compptr->ac_tbl_no > 1)
- is_baseline = FALSE;
- }
- if (prec && is_baseline) {
- is_baseline = FALSE;
- /* If it's baseline except for quantizer size, warn the user */
- TRACEMS(cinfo, 0, JTRC_16BIT_TABLES);
- }
- }
-
- /* Emit the proper SOF marker */
- if (cinfo->arith_code) {
- emit_sof(cinfo, M_SOF9); /* SOF code for arithmetic coding */
- } else {
- if (cinfo->progressive_mode)
- emit_sof(cinfo, M_SOF2); /* SOF code for progressive Huffman */
- else if (is_baseline)
- emit_sof(cinfo, M_SOF0); /* SOF code for baseline implementation */
- else
- emit_sof(cinfo, M_SOF1); /* SOF code for non-baseline Huffman file */
- }
- }
-
- /*
- * Write scan header.
- * This consists of DHT or DAC markers, optional DRI, and SOS.
- * Compressed data will be written following the SOS.
- */
-
- METHODDEF(void)
- write_scan_header (j_compress_ptr cinfo)
- {
- my_marker_ptr marker = (my_marker_ptr) cinfo->marker;
- int i;
- jpeg_component_info *compptr;
-
- if (cinfo->arith_code) {
- /* Emit arith conditioning info. We may have some duplication
- * if the file has multiple scans, but it's so small it's hardly
- * worth worrying about.
- */
- emit_dac(cinfo);
- } else {
- /* Emit Huffman tables.
- * Note that emit_dht() suppresses any duplicate tables.
- */
- for (i = 0; i < cinfo->comps_in_scan; i++) {
- compptr = cinfo->cur_comp_info[i];
- if (cinfo->progressive_mode) {
- /* Progressive mode: only DC or only AC tables are used in one scan */
- if (cinfo->Ss == 0) {
- if (cinfo->Ah == 0) /* DC needs no table for refinement scan */
- emit_dht(cinfo, compptr->dc_tbl_no, FALSE);
- } else {
- emit_dht(cinfo, compptr->ac_tbl_no, TRUE);
- }
- } else {
- /* Sequential mode: need both DC and AC tables */
- emit_dht(cinfo, compptr->dc_tbl_no, FALSE);
- emit_dht(cinfo, compptr->ac_tbl_no, TRUE);
- }
- }
- }
-
- /* Emit DRI if required --- note that DRI value could change for each scan.
- * We avoid wasting space with unnecessary DRIs, however.
- */
- if (cinfo->restart_interval != marker->last_restart_interval) {
- emit_dri(cinfo);
- marker->last_restart_interval = cinfo->restart_interval;
- }
-
- emit_sos(cinfo);
- }
-
- /*
- * Write datastream trailer.
- */
-
- METHODDEF(void)
- write_file_trailer (j_compress_ptr cinfo)
- {
- emit_marker(cinfo, M_EOI);
- }
-
- /*
- * Write an abbreviated table-specification datastream.
- * This consists of SOI, DQT and DHT tables, and EOI.
- * Any table that is defined and not marked sent_table = TRUE will be
- * emitted. Note that all tables will be marked sent_table = TRUE at exit.
- */
-
- METHODDEF(void)
- write_tables_only (j_compress_ptr cinfo)
- {
- int i;
-
- emit_marker(cinfo, M_SOI);
-
- for (i = 0; i < NUM_QUANT_TBLS; i++) {
- if (cinfo->quant_tbl_ptrs[i] != NULL)
- (void) emit_dqt(cinfo, i);
- }
-
- if (! cinfo->arith_code) {
- for (i = 0; i < NUM_HUFF_TBLS; i++) {
- if (cinfo->dc_huff_tbl_ptrs[i] != NULL)
- emit_dht(cinfo, i, FALSE);
- if (cinfo->ac_huff_tbl_ptrs[i] != NULL)
- emit_dht(cinfo, i, TRUE);
- }
- }
-
- emit_marker(cinfo, M_EOI);
- }
-
- /*
- * Initialize the marker writer module.
- */
-
- GLOBAL(void)
- jinit_marker_writer (j_compress_ptr cinfo)
- {
- my_marker_ptr marker;
-
- /* Create the subobject */
- marker = (my_marker_ptr)
- (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
- SIZEOF(my_marker_writer));
- cinfo->marker = (struct jpeg_marker_writer *) marker;
- /* Initialize method pointers */
- marker->pub.write_file_header = write_file_header;
- marker->pub.write_frame_header = write_frame_header;
- marker->pub.write_scan_header = write_scan_header;
- marker->pub.write_file_trailer = write_file_trailer;
- marker->pub.write_tables_only = write_tables_only;
- marker->pub.write_marker_header = write_marker_header;
- marker->pub.write_marker_byte = write_marker_byte;
- /* Initialize private state */
- marker->last_restart_interval = 0;
- }
- /********* End of inlined file: jcmarker.c *********/
-
- /********* Start of inlined file: jcmaster.c *********/
- #define JPEG_INTERNALS
-
- /* Private state */
-
- typedef enum {
- main_pass, /* input data, also do first output step */
- huff_opt_pass, /* Huffman code optimization pass */
- output_pass /* data output pass */
- } c_pass_type;
-
- typedef struct {
- struct jpeg_comp_master pub; /* public fields */
-
- c_pass_type pass_type; /* the type of the current pass */
-
- int pass_number; /* # of passes completed */
- int total_passes; /* total # of passes needed */
-
- int scan_number; /* current index in scan_info[] */
- } my_comp_master;
-
- typedef my_comp_master * my_master_ptr;
-
- /*
- * Support routines that do various essential calculations.
- */
-
- LOCAL(void)
- initial_setup (j_compress_ptr cinfo)
- /* Do computations that are needed before master selection phase */
- {
- int ci;
- jpeg_component_info *compptr;
- long samplesperrow;
- JDIMENSION jd_samplesperrow;
-
- /* Sanity check on image dimensions */
- if (cinfo->image_height <= 0 || cinfo->image_width <= 0
- || cinfo->num_components <= 0 || cinfo->input_components <= 0)
- ERREXIT(cinfo, JERR_EMPTY_IMAGE);
-
- /* Make sure image isn't bigger than I can handle */
- if ((long) cinfo->image_height > (long) JPEG_MAX_DIMENSION ||
- (long) cinfo->image_width > (long) JPEG_MAX_DIMENSION)
- ERREXIT1(cinfo, JERR_IMAGE_TOO_BIG, (unsigned int) JPEG_MAX_DIMENSION);
-
- /* Width of an input scanline must be representable as JDIMENSION. */
- samplesperrow = (long) cinfo->image_width * (long) cinfo->input_components;
- jd_samplesperrow = (JDIMENSION) samplesperrow;
- if ((long) jd_samplesperrow != samplesperrow)
- ERREXIT(cinfo, JERR_WIDTH_OVERFLOW);
-
- /* For now, precision must match compiled-in value... */
- if (cinfo->data_precision != BITS_IN_JSAMPLE)
- ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
-
- /* Check that number of components won't exceed internal array sizes */
- if (cinfo->num_components > MAX_COMPONENTS)
- ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->num_components,
- MAX_COMPONENTS);
-
- /* Compute maximum sampling factors; check factor validity */
- cinfo->max_h_samp_factor = 1;
- cinfo->max_v_samp_factor = 1;
- for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
- ci++, compptr++) {
- if (compptr->h_samp_factor<=0 || compptr->h_samp_factor>MAX_SAMP_FACTOR ||
- compptr->v_samp_factor<=0 || compptr->v_samp_factor>MAX_SAMP_FACTOR)
- ERREXIT(cinfo, JERR_BAD_SAMPLING);
- cinfo->max_h_samp_factor = MAX(cinfo->max_h_samp_factor,
- compptr->h_samp_factor);
- cinfo->max_v_samp_factor = MAX(cinfo->max_v_samp_factor,
- compptr->v_samp_factor);
- }
-
- /* Compute dimensions of components */
- for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
- ci++, compptr++) {
- /* Fill in the correct component_index value; don't rely on application */
- compptr->component_index = ci;
- /* For compression, we never do DCT scaling. */
- compptr->DCT_scaled_size = DCTSIZE;
- /* Size in DCT blocks */
- compptr->width_in_blocks = (JDIMENSION)
- jdiv_round_up((long) cinfo->image_width * (long) compptr->h_samp_factor,
- (long) (cinfo->max_h_samp_factor * DCTSIZE));
- compptr->height_in_blocks = (JDIMENSION)
- jdiv_round_up((long) cinfo->image_height * (long) compptr->v_samp_factor,
- (long) (cinfo->max_v_samp_factor * DCTSIZE));
- /* Size in samples */
- compptr->downsampled_width = (JDIMENSION)
- jdiv_round_up((long) cinfo->image_width * (long) compptr->h_samp_factor,
- (long) cinfo->max_h_samp_factor);
- compptr->downsampled_height = (JDIMENSION)
- jdiv_round_up((long) cinfo->image_height * (long) compptr->v_samp_factor,
- (long) cinfo->max_v_samp_factor);
- /* Mark component needed (this flag isn't actually used for compression) */
- compptr->component_needed = TRUE;
- }
-
- /* Compute number of fully interleaved MCU rows (number of times that
- * main controller will call coefficient controller).
- */
- cinfo->total_iMCU_rows = (JDIMENSION)
- jdiv_round_up((long) cinfo->image_height,
- (long) (cinfo->max_v_samp_factor*DCTSIZE));
- }
-
- #ifdef C_MULTISCAN_FILES_SUPPORTED
-
- LOCAL(void)
- validate_script (j_compress_ptr cinfo)
- /* Verify that the scan script in cinfo->scan_info[] is valid; also
- * determine whether it uses progressive JPEG, and set cinfo->progressive_mode.
- */
- {
- const jpeg_scan_info * scanptr;
- int scanno, ncomps, ci, coefi, thisi;
- int Ss, Se, Ah, Al;
- boolean component_sent[MAX_COMPONENTS];
- #ifdef C_PROGRESSIVE_SUPPORTED
- int * last_bitpos_ptr;
- int last_bitpos[MAX_COMPONENTS][DCTSIZE2];
- /* -1 until that coefficient has been seen; then last Al for it */
- #endif
-
- if (cinfo->num_scans <= 0)
- ERREXIT1(cinfo, JERR_BAD_SCAN_SCRIPT, 0);
-
- /* For sequential JPEG, all scans must have Ss=0, Se=DCTSIZE2-1;
- * for progressive JPEG, no scan can have this.
- */
- scanptr = cinfo->scan_info;
- if (scanptr->Ss != 0 || scanptr->Se != DCTSIZE2-1) {
- #ifdef C_PROGRESSIVE_SUPPORTED
- cinfo->progressive_mode = TRUE;
- last_bitpos_ptr = & last_bitpos[0][0];
- for (ci = 0; ci < cinfo->num_components; ci++)
- for (coefi = 0; coefi < DCTSIZE2; coefi++)
- *last_bitpos_ptr++ = -1;
- #else
- ERREXIT(cinfo, JERR_NOT_COMPILED);
- #endif
- } else {
- cinfo->progressive_mode = FALSE;
- for (ci = 0; ci < cinfo->num_components; ci++)
- component_sent[ci] = FALSE;
- }
-
- for (scanno = 1; scanno <= cinfo->num_scans; scanptr++, scanno++) {
- /* Validate component indexes */
- ncomps = scanptr->comps_in_scan;
- if (ncomps <= 0 || ncomps > MAX_COMPS_IN_SCAN)
- ERREXIT2(cinfo, JERR_COMPONENT_COUNT, ncomps, MAX_COMPS_IN_SCAN);
- for (ci = 0; ci < ncomps; ci++) {
- thisi = scanptr->component_index[ci];
- if (thisi < 0 || thisi >= cinfo->num_components)
- ERREXIT1(cinfo, JERR_BAD_SCAN_SCRIPT, scanno);
- /* Components must appear in SOF order within each scan */
- if (ci > 0 && thisi <= scanptr->component_index[ci-1])
- ERREXIT1(cinfo, JERR_BAD_SCAN_SCRIPT, scanno);
- }
- /* Validate progression parameters */
- Ss = scanptr->Ss;
- Se = scanptr->Se;
- Ah = scanptr->Ah;
- Al = scanptr->Al;
- if (cinfo->progressive_mode) {
- #ifdef C_PROGRESSIVE_SUPPORTED
- /* The JPEG spec simply gives the ranges 0..13 for Ah and Al, but that
- * seems wrong: the upper bound ought to depend on data precision.
- * Perhaps they really meant 0..N+1 for N-bit precision.
- * Here we allow 0..10 for 8-bit data; Al larger than 10 results in
- * out-of-range reconstructed DC values during the first DC scan,
- * which might cause problems for some decoders.
- */
- #if BITS_IN_JSAMPLE == 8
- #define MAX_AH_AL 10
- #else
- #define MAX_AH_AL 13
- #endif
- if (Ss < 0 || Ss >= DCTSIZE2 || Se < Ss || Se >= DCTSIZE2 ||
- Ah < 0 || Ah > MAX_AH_AL || Al < 0 || Al > MAX_AH_AL)
- ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
- if (Ss == 0) {
- if (Se != 0) /* DC and AC together not OK */
- ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
- } else {
- if (ncomps != 1) /* AC scans must be for only one component */
- ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
- }
- for (ci = 0; ci < ncomps; ci++) {
- last_bitpos_ptr = & last_bitpos[scanptr->component_index[ci]][0];
- if (Ss != 0 && last_bitpos_ptr[0] < 0) /* AC without prior DC scan */
- ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
- for (coefi = Ss; coefi <= Se; coefi++) {
- if (last_bitpos_ptr[coefi] < 0) {
- /* first scan of this coefficient */
- if (Ah != 0)
- ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
- } else {
- /* not first scan */
- if (Ah != last_bitpos_ptr[coefi] || Al != Ah-1)
- ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
- }
- last_bitpos_ptr[coefi] = Al;
- }
- }
- #endif
- } else {
- /* For sequential JPEG, all progression parameters must be these: */
- if (Ss != 0 || Se != DCTSIZE2-1 || Ah != 0 || Al != 0)
- ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
- /* Make sure components are not sent twice */
- for (ci = 0; ci < ncomps; ci++) {
- thisi = scanptr->component_index[ci];
- if (component_sent[thisi])
- ERREXIT1(cinfo, JERR_BAD_SCAN_SCRIPT, scanno);
- component_sent[thisi] = TRUE;
- }
- }
- }
-
- /* Now verify that everything got sent. */
- if (cinfo->progressive_mode) {
- #ifdef C_PROGRESSIVE_SUPPORTED
- /* For progressive mode, we only check that at least some DC data
- * got sent for each component; the spec does not require that all bits
- * of all coefficients be transmitted. Would it be wiser to enforce
- * transmission of all coefficient bits??
- */
- for (ci = 0; ci < cinfo->num_components; ci++) {
- if (last_bitpos[ci][0] < 0)
- ERREXIT(cinfo, JERR_MISSING_DATA);
- }
- #endif
- } else {
- for (ci = 0; ci < cinfo->num_components; ci++) {
- if (! component_sent[ci])
- ERREXIT(cinfo, JERR_MISSING_DATA);
- }
- }
- }
-
- #endif /* C_MULTISCAN_FILES_SUPPORTED */
-
- LOCAL(void)
- select_scan_parameters (j_compress_ptr cinfo)
- /* Set up the scan parameters for the current scan */
- {
- int ci;
-
- #ifdef C_MULTISCAN_FILES_SUPPORTED
- if (cinfo->scan_info != NULL) {
- /* Prepare for current scan --- the script is already validated */
- my_master_ptr master = (my_master_ptr) cinfo->master;
- const jpeg_scan_info * scanptr = cinfo->scan_info + master->scan_number;
-
- cinfo->comps_in_scan = scanptr->comps_in_scan;
- for (ci = 0; ci < scanptr->comps_in_scan; ci++) {
- cinfo->cur_comp_info[ci] =
- &cinfo->comp_info[scanptr->component_index[ci]];
- }
- cinfo->Ss = scanptr->Ss;
- cinfo->Se = scanptr->Se;
- cinfo->Ah = scanptr->Ah;
- cinfo->Al = scanptr->Al;
- }
- else
- #endif
- {
- /* Prepare for single sequential-JPEG scan containing all components */
- if (cinfo->num_components > MAX_COMPS_IN_SCAN)
- ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->num_components,
- MAX_COMPS_IN_SCAN);
- cinfo->comps_in_scan = cinfo->num_components;
- for (ci = 0; ci < cinfo->num_components; ci++) {
- cinfo->cur_comp_info[ci] = &cinfo->comp_info[ci];
- }
- cinfo->Ss = 0;
- cinfo->Se = DCTSIZE2-1;
- cinfo->Ah = 0;
- cinfo->Al = 0;
- }
- }
-
- LOCAL(void)
- per_scan_setup (j_compress_ptr cinfo)
- /* Do computations that are needed before processing a JPEG scan */
- /* cinfo->comps_in_scan and cinfo->cur_comp_info[] are already set */
- {
- int ci, mcublks, tmp;
- jpeg_component_info *compptr;
-
- if (cinfo->comps_in_scan == 1) {
-
- /* Noninterleaved (single-component) scan */
- compptr = cinfo->cur_comp_info[0];
-
- /* Overall image size in MCUs */
- cinfo->MCUs_per_row = compptr->width_in_blocks;
- cinfo->MCU_rows_in_scan = compptr->height_in_blocks;
-
- /* For noninterleaved scan, always one block per MCU */
- compptr->MCU_width = 1;
- compptr->MCU_height = 1;
- compptr->MCU_blocks = 1;
- compptr->MCU_sample_width = DCTSIZE;
- compptr->last_col_width = 1;
- /* For noninterleaved scans, it is convenient to define last_row_height
- * as the number of block rows present in the last iMCU row.
- */
- tmp = (int) (compptr->height_in_blocks % compptr->v_samp_factor);
- if (tmp == 0) tmp = compptr->v_samp_factor;
- compptr->last_row_height = tmp;
-
- /* Prepare array describing MCU composition */
- cinfo->blocks_in_MCU = 1;
- cinfo->MCU_membership[0] = 0;
-
- } else {
-
- /* Interleaved (multi-component) scan */
- if (cinfo->comps_in_scan <= 0 || cinfo->comps_in_scan > MAX_COMPS_IN_SCAN)
- ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->comps_in_scan,
- MAX_COMPS_IN_SCAN);
-
- /* Overall image size in MCUs */
- cinfo->MCUs_per_row = (JDIMENSION)
- jdiv_round_up((long) cinfo->image_width,
- (long) (cinfo->max_h_samp_factor*DCTSIZE));
- cinfo->MCU_rows_in_scan = (JDIMENSION)
- jdiv_round_up((long) cinfo->image_height,
- (long) (cinfo->max_v_samp_factor*DCTSIZE));
-
- cinfo->blocks_in_MCU = 0;
-
- for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
- compptr = cinfo->cur_comp_info[ci];
- /* Sampling factors give # of blocks of component in each MCU */
- compptr->MCU_width = compptr->h_samp_factor;
- compptr->MCU_height = compptr->v_samp_factor;
- compptr->MCU_blocks = compptr->MCU_width * compptr->MCU_height;
- compptr->MCU_sample_width = compptr->MCU_width * DCTSIZE;
- /* Figure number of non-dummy blocks in last MCU column & row */
- tmp = (int) (compptr->width_in_blocks % compptr->MCU_width);
- if (tmp == 0) tmp = compptr->MCU_width;
- compptr->last_col_width = tmp;
- tmp = (int) (compptr->height_in_blocks % compptr->MCU_height);
- if (tmp == 0) tmp = compptr->MCU_height;
- compptr->last_row_height = tmp;
- /* Prepare array describing MCU composition */
- mcublks = compptr->MCU_blocks;
- if (cinfo->blocks_in_MCU + mcublks > C_MAX_BLOCKS_IN_MCU)
- ERREXIT(cinfo, JERR_BAD_MCU_SIZE);
- while (mcublks-- > 0) {
- cinfo->MCU_membership[cinfo->blocks_in_MCU++] = ci;
- }
- }
-
- }
-
- /* Convert restart specified in rows to actual MCU count. */
- /* Note that count must fit in 16 bits, so we provide limiting. */
- if (cinfo->restart_in_rows > 0) {
- long nominal = (long) cinfo->restart_in_rows * (long) cinfo->MCUs_per_row;
- cinfo->restart_interval = (unsigned int) MIN(nominal, 65535L);
- }
- }
-
- /*
- * Per-pass setup.
- * This is called at the beginning of each pass. We determine which modules
- * will be active during this pass and give them appropriate start_pass calls.
- * We also set is_last_pass to indicate whether any more passes will be
- * required.
- */
-
- METHODDEF(void)
- prepare_for_pass (j_compress_ptr cinfo)
- {
- my_master_ptr master = (my_master_ptr) cinfo->master;
-
- switch (master->pass_type) {
- case main_pass:
- /* Initial pass: will collect input data, and do either Huffman
- * optimization or data output for the first scan.
- */
- select_scan_parameters(cinfo);
- per_scan_setup(cinfo);
- if (! cinfo->raw_data_in) {
- (*cinfo->cconvert->start_pass) (cinfo);
- (*cinfo->downsample->start_pass) (cinfo);
- (*cinfo->prep->start_pass) (cinfo, JBUF_PASS_THRU);
- }
- (*cinfo->fdct->start_pass) (cinfo);
- (*cinfo->entropy->start_pass) (cinfo, cinfo->optimize_coding);
- (*cinfo->coef->start_pass) (cinfo,
- (master->total_passes > 1 ?
- JBUF_SAVE_AND_PASS : JBUF_PASS_THRU));
- (*cinfo->main->start_pass) (cinfo, JBUF_PASS_THRU);
- if (cinfo->optimize_coding) {
- /* No immediate data output; postpone writing frame/scan headers */
- master->pub.call_pass_startup = FALSE;
- } else {
- /* Will write frame/scan headers at first jpeg_write_scanlines call */
- master->pub.call_pass_startup = TRUE;
- }
- break;
- #ifdef ENTROPY_OPT_SUPPORTED
- case huff_opt_pass:
- /* Do Huffman optimization for a scan after the first one. */
- select_scan_parameters(cinfo);
- per_scan_setup(cinfo);
- if (cinfo->Ss != 0 || cinfo->Ah == 0 || cinfo->arith_code) {
- (*cinfo->entropy->start_pass) (cinfo, TRUE);
- (*cinfo->coef->start_pass) (cinfo, JBUF_CRANK_DEST);
- master->pub.call_pass_startup = FALSE;
- break;
- }
- /* Special case: Huffman DC refinement scans need no Huffman table
- * and therefore we can skip the optimization pass for them.
- */
- master->pass_type = output_pass;
- master->pass_number++;
- /*FALLTHROUGH*/
- #endif
- case output_pass:
- /* Do a data-output pass. */
- /* We need not repeat per-scan setup if prior optimization pass did it. */
- if (! cinfo->optimize_coding) {
- select_scan_parameters(cinfo);
- per_scan_setup(cinfo);
- }
- (*cinfo->entropy->start_pass) (cinfo, FALSE);
- (*cinfo->coef->start_pass) (cinfo, JBUF_CRANK_DEST);
- /* We emit frame/scan headers now */
- if (master->scan_number == 0)
- (*cinfo->marker->write_frame_header) (cinfo);
- (*cinfo->marker->write_scan_header) (cinfo);
- master->pub.call_pass_startup = FALSE;
- break;
- default:
- ERREXIT(cinfo, JERR_NOT_COMPILED);
- }
-
- master->pub.is_last_pass = (master->pass_number == master->total_passes-1);
-
- /* Set up progress monitor's pass info if present */
- if (cinfo->progress != NULL) {
- cinfo->progress->completed_passes = master->pass_number;
- cinfo->progress->total_passes = master->total_passes;
- }
- }
-
- /*
- * Special start-of-pass hook.
- * This is called by jpeg_write_scanlines if call_pass_startup is TRUE.
- * In single-pass processing, we need this hook because we don't want to
- * write frame/scan headers during jpeg_start_compress; we want to let the
- * application write COM markers etc. between jpeg_start_compress and the
- * jpeg_write_scanlines loop.
- * In multi-pass processing, this routine is not used.
- */
-
- METHODDEF(void)
- pass_startup (j_compress_ptr cinfo)
- {
- cinfo->master->call_pass_startup = FALSE; /* reset flag so call only once */
-
- (*cinfo->marker->write_frame_header) (cinfo);
- (*cinfo->marker->write_scan_header) (cinfo);
- }
-
- /*
- * Finish up at end of pass.
- */
-
- METHODDEF(void)
- finish_pass_master (j_compress_ptr cinfo)
- {
- my_master_ptr master = (my_master_ptr) cinfo->master;
-
- /* The entropy coder always needs an end-of-pass call,
- * either to analyze statistics or to flush its output buffer.
- */
- (*cinfo->entropy->finish_pass) (cinfo);
-
- /* Update state for next pass */
- switch (master->pass_type) {
- case main_pass:
- /* next pass is either output of scan 0 (after optimization)
- * or output of scan 1 (if no optimization).
- */
- master->pass_type = output_pass;
- if (! cinfo->optimize_coding)
- master->scan_number++;
- break;
- case huff_opt_pass:
- /* next pass is always output of current scan */
- master->pass_type = output_pass;
- break;
- case output_pass:
- /* next pass is either optimization or output of next scan */
- if (cinfo->optimize_coding)
- master->pass_type = huff_opt_pass;
- master->scan_number++;
- break;
- }
-
- master->pass_number++;
- }
-
- /*
- * Initialize master compression control.
- */
-
- GLOBAL(void)
- jinit_c_master_control (j_compress_ptr cinfo, boolean transcode_only)
- {
- my_master_ptr master;
-
- master = (my_master_ptr)
- (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
- SIZEOF(my_comp_master));
- cinfo->master = (struct jpeg_comp_master *) master;
- master->pub.prepare_for_pass = prepare_for_pass;
- master->pub.pass_startup = pass_startup;
- master->pub.finish_pass = finish_pass_master;
- master->pub.is_last_pass = FALSE;
-
- /* Validate parameters, determine derived values */
- initial_setup(cinfo);
-
- if (cinfo->scan_info != NULL) {
- #ifdef C_MULTISCAN_FILES_SUPPORTED
- validate_script(cinfo);
- #else
- ERREXIT(cinfo, JERR_NOT_COMPILED);
- #endif
- } else {
- cinfo->progressive_mode = FALSE;
- cinfo->num_scans = 1;
- }
-
- if (cinfo->progressive_mode) /* TEMPORARY HACK ??? */
- cinfo->optimize_coding = TRUE; /* assume default tables no good for progressive mode */
-
- /* Initialize my private state */
- if (transcode_only) {
- /* no main pass in transcoding */
- if (cinfo->optimize_coding)
- master->pass_type = huff_opt_pass;
- else
- master->pass_type = output_pass;
- } else {
- /* for normal compression, first pass is always this type: */
- master->pass_type = main_pass;
- }
- master->scan_number = 0;
- master->pass_number = 0;
- if (cinfo->optimize_coding)
- master->total_passes = cinfo->num_scans * 2;
- else
- master->total_passes = cinfo->num_scans;
- }
- /********* End of inlined file: jcmaster.c *********/
-
- /********* Start of inlined file: jcomapi.c *********/
- #define JPEG_INTERNALS
-
- /*
- * Abort processing of a JPEG compression or decompression operation,
- * but don't destroy the object itself.
- *
- * For this, we merely clean up all the nonpermanent memory pools.
- * Note that temp files (virtual arrays) are not allowed to belong to
- * the permanent pool, so we will be able to close all temp files here.
- * Closing a data source or destination, if necessary, is the application's
- * responsibility.
- */
-
- GLOBAL(void)
- jpeg_abort (j_common_ptr cinfo)
- {
- int pool;
-
- /* Do nothing if called on a not-initialized or destroyed JPEG object. */
- if (cinfo->mem == NULL)
- return;
-
- /* Releasing pools in reverse order might help avoid fragmentation
- * with some (brain-damaged) malloc libraries.
- */
- for (pool = JPOOL_NUMPOOLS-1; pool > JPOOL_PERMANENT; pool--) {
- (*cinfo->mem->free_pool) (cinfo, pool);
- }
-
- /* Reset overall state for possible reuse of object */
- if (cinfo->is_decompressor) {
- cinfo->global_state = DSTATE_START;
- /* Try to keep application from accessing now-deleted marker list.
- * A bit kludgy to do it here, but this is the most central place.
- */
- ((j_decompress_ptr) cinfo)->marker_list = NULL;
- } else {
- cinfo->global_state = CSTATE_START;
- }
- }
-
- /*
- * Destruction of a JPEG object.
- *
- * Everything gets deallocated except the master jpeg_compress_struct itself
- * and the error manager struct. Both of these are supplied by the application
- * and must be freed, if necessary, by the application. (Often they are on
- * the stack and so don't need to be freed anyway.)
- * Closing a data source or destination, if necessary, is the application's
- * responsibility.
- */
-
- GLOBAL(void)
- jpeg_destroy (j_common_ptr cinfo)
- {
- /* We need only tell the memory manager to release everything. */
- /* NB: mem pointer is NULL if memory mgr failed to initialize. */
- if (cinfo->mem != NULL)
- (*cinfo->mem->self_destruct) (cinfo);
- cinfo->mem = NULL; /* be safe if jpeg_destroy is called twice */
- cinfo->global_state = 0; /* mark it destroyed */
- }
-
- /*
- * Convenience routines for allocating quantization and Huffman tables.
- * (Would jutils.c be a more reasonable place to put these?)
- */
-
- GLOBAL(JQUANT_TBL *)
- jpeg_alloc_quant_table (j_common_ptr cinfo)
- {
- JQUANT_TBL *tbl;
-
- tbl = (JQUANT_TBL *)
- (*cinfo->mem->alloc_small) (cinfo, JPOOL_PERMANENT, SIZEOF(JQUANT_TBL));
- tbl->sent_table = FALSE; /* make sure this is false in any new table */
- return tbl;
- }
-
- GLOBAL(JHUFF_TBL *)
- jpeg_alloc_huff_table (j_common_ptr cinfo)
- {
- JHUFF_TBL *tbl;
-
- tbl = (JHUFF_TBL *)
- (*cinfo->mem->alloc_small) (cinfo, JPOOL_PERMANENT, SIZEOF(JHUFF_TBL));
- tbl->sent_table = FALSE; /* make sure this is false in any new table */
- return tbl;
- }
- /********* End of inlined file: jcomapi.c *********/
-
- /********* Start of inlined file: jcparam.c *********/
- #define JPEG_INTERNALS
-
- /*
- * Quantization table setup routines
- */
-
- GLOBAL(void)
- jpeg_add_quant_table (j_compress_ptr cinfo, int which_tbl,
- const unsigned int *basic_table,
- int scale_factor, boolean force_baseline)
- /* Define a quantization table equal to the basic_table times
- * a scale factor (given as a percentage).
- * If force_baseline is TRUE, the computed quantization table entries
- * are limited to 1..255 for JPEG baseline compatibility.
- */
- {
- JQUANT_TBL ** qtblptr;
- int i;
- long temp;
-
- /* Safety check to ensure start_compress not called yet. */
- if (cinfo->global_state != CSTATE_START)
- ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
-
- if (which_tbl < 0 || which_tbl >= NUM_QUANT_TBLS)
- ERREXIT1(cinfo, JERR_DQT_INDEX, which_tbl);
-
- qtblptr = & cinfo->quant_tbl_ptrs[which_tbl];
-
- if (*qtblptr == NULL)
- *qtblptr = jpeg_alloc_quant_table((j_common_ptr) cinfo);
-
- for (i = 0; i < DCTSIZE2; i++) {
- temp = ((long) basic_table[i] * scale_factor + 50L) / 100L;
- /* limit the values to the valid range */
- if (temp <= 0L) temp = 1L;
- if (temp > 32767L) temp = 32767L; /* max quantizer needed for 12 bits */
- if (force_baseline && temp > 255L)
- temp = 255L; /* limit to baseline range if requested */
- (*qtblptr)->quantval[i] = (UINT16) temp;
- }
-
- /* Initialize sent_table FALSE so table will be written to JPEG file. */
- (*qtblptr)->sent_table = FALSE;
- }
-
- GLOBAL(void)
- jpeg_set_linear_quality (j_compress_ptr cinfo, int scale_factor,
- boolean force_baseline)
- /* Set or change the 'quality' (quantization) setting, using default tables
- * and a straight percentage-scaling quality scale. In most cases it's better
- * to use jpeg_set_quality (below); this entry point is provided for
- * applications that insist on a linear percentage scaling.
- */
- {
- /* These are the sample quantization tables given in JPEG spec section K.1.
- * The spec says that the values given produce "good" quality, and
- * when divided by 2, "very good" quality.
- */
- static const unsigned int std_luminance_quant_tbl[DCTSIZE2] = {
- 16, 11, 10, 16, 24, 40, 51, 61,
- 12, 12, 14, 19, 26, 58, 60, 55,
- 14, 13, 16, 24, 40, 57, 69, 56,
- 14, 17, 22, 29, 51, 87, 80, 62,
- 18, 22, 37, 56, 68, 109, 103, 77,
- 24, 35, 55, 64, 81, 104, 113, 92,
- 49, 64, 78, 87, 103, 121, 120, 101,
- 72, 92, 95, 98, 112, 100, 103, 99
- };
- static const unsigned int std_chrominance_quant_tbl[DCTSIZE2] = {
- 17, 18, 24, 47, 99, 99, 99, 99,
- 18, 21, 26, 66, 99, 99, 99, 99,
- 24, 26, 56, 99, 99, 99, 99, 99,
- 47, 66, 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
- };
-
- /* Set up two quantization tables using the specified scaling */
- jpeg_add_quant_table(cinfo, 0, std_luminance_quant_tbl,
- scale_factor, force_baseline);
- jpeg_add_quant_table(cinfo, 1, std_chrominance_quant_tbl,
- scale_factor, force_baseline);
- }
-
- GLOBAL(int)
- jpeg_quality_scaling (int quality)
- /* Convert a user-specified quality rating to a percentage scaling factor
- * for an underlying quantization table, using our recommended scaling curve.
- * The input 'quality' factor should be 0 (terrible) to 100 (very good).
- */
- {
- /* Safety limit on quality factor. Convert 0 to 1 to avoid zero divide. */
- if (quality <= 0) quality = 1;
- if (quality > 100) quality = 100;
-
- /* The basic table is used as-is (scaling 100) for a quality of 50.
- * Qualities 50..100 are converted to scaling percentage 200 - 2*Q;
- * note that at Q=100 the scaling is 0, which will cause jpeg_add_quant_table
- * to make all the table entries 1 (hence, minimum quantization loss).
- * Qualities 1..50 are converted to scaling percentage 5000/Q.
- */
- if (quality < 50)
- quality = 5000 / quality;
- else
- quality = 200 - quality*2;
-
- return quality;
- }
-
- GLOBAL(void)
- jpeg_set_quality (j_compress_ptr cinfo, int quality, boolean force_baseline)
- /* Set or change the 'quality' (quantization) setting, using default tables.
- * This is the standard quality-adjusting entry point for typical user
- * interfaces; only those who want detailed control over quantization tables
- * would use the preceding three routines directly.
- */
- {
- /* Convert user 0-100 rating to percentage scaling */
- quality = jpeg_quality_scaling(quality);
-
- /* Set up standard quality tables */
- jpeg_set_linear_quality(cinfo, quality, force_baseline);
- }
-
- /*
- * Huffman table setup routines
- */
-
- LOCAL(void)
- add_huff_table (j_compress_ptr cinfo,
- JHUFF_TBL **htblptr, const UINT8 *bits, const UINT8 *val)
- /* Define a Huffman table */
- {
- int nsymbols, len;
-
- if (*htblptr == NULL)
- *htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo);
-
- /* Copy the number-of-symbols-of-each-code-length counts */
- MEMCOPY((*htblptr)->bits, bits, SIZEOF((*htblptr)->bits));
-
- /* Validate the counts. We do this here mainly so we can copy the right
- * number of symbols from the val[] array, without risking marching off
- * the end of memory. jchuff.c will do a more thorough test later.
- */
- nsymbols = 0;
- for (len = 1; len <= 16; len++)
- nsymbols += bits[len];
- if (nsymbols < 1 || nsymbols > 256)
- ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
-
- MEMCOPY((*htblptr)->huffval, val, nsymbols * SIZEOF(UINT8));
-
- /* Initialize sent_table FALSE so table will be written to JPEG file. */
- (*htblptr)->sent_table = FALSE;
- }
-
- LOCAL(void)
- std_huff_tables (j_compress_ptr cinfo)
- /* Set up the standard Huffman tables (cf. JPEG standard section K.3) */
- /* IMPORTANT: these are only valid for 8-bit data precision! */
- {
- static const UINT8 bits_dc_luminance[17] =
- { /* 0-base */ 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 };
- static const UINT8 val_dc_luminance[] =
- { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
-
- static const UINT8 bits_dc_chrominance[17] =
- { /* 0-base */ 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 };
- static const UINT8 val_dc_chrominance[] =
- { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
-
- static const UINT8 bits_ac_luminance[17] =
- { /* 0-base */ 0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d };
- static const UINT8 val_ac_luminance[] =
- { 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
- 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
- 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
- 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
- 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
- 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
- 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
- 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
- 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
- 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
- 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
- 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
- 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
- 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
- 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
- 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
- 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
- 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
- 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
- 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
- 0xf9, 0xfa };
-
- static const UINT8 bits_ac_chrominance[17] =
- { /* 0-base */ 0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77 };
- static const UINT8 val_ac_chrominance[] =
- { 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
- 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
- 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
- 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
- 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34,
- 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
- 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
- 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
- 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
- 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
- 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
- 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
- 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
- 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
- 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
- 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
- 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
- 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
- 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
- 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
- 0xf9, 0xfa };
-
- add_huff_table(cinfo, &cinfo->dc_huff_tbl_ptrs[0],
- bits_dc_luminance, val_dc_luminance);
- add_huff_table(cinfo, &cinfo->ac_huff_tbl_ptrs[0],
- bits_ac_luminance, val_ac_luminance);
- add_huff_table(cinfo, &cinfo->dc_huff_tbl_ptrs[1],
- bits_dc_chrominance, val_dc_chrominance);
- add_huff_table(cinfo, &cinfo->ac_huff_tbl_ptrs[1],
- bits_ac_chrominance, val_ac_chrominance);
- }
-
- /*
- * Default parameter setup for compression.
- *
- * Applications that don't choose to use this routine must do their
- * own setup of all these parameters. Alternately, you can call this
- * to establish defaults and then alter parameters selectively. This
- * is the recommended approach since, if we add any new parameters,
- * your code will still work (they'll be set to reasonable defaults).
- */
-
- GLOBAL(void)
- jpeg_set_defaults (j_compress_ptr cinfo)
- {
- int i;
-
- /* Safety check to ensure start_compress not called yet. */
- if (cinfo->global_state != CSTATE_START)
- ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
-
- /* Allocate comp_info array large enough for maximum component count.
- * Array is made permanent in case application wants to compress
- * multiple images at same param settings.
- */
- if (cinfo->comp_info == NULL)
- cinfo->comp_info = (jpeg_component_info *)
- (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
- MAX_COMPONENTS * SIZEOF(jpeg_component_info));
-
- /* Initialize everything not dependent on the color space */
-
- cinfo->data_precision = BITS_IN_JSAMPLE;
- /* Set up two quantization tables using default quality of 75 */
- jpeg_set_quality(cinfo, 75, TRUE);
- /* Set up two Huffman tables */
- std_huff_tables(cinfo);
-
- /* Initialize default arithmetic coding conditioning */
- for (i = 0; i < NUM_ARITH_TBLS; i++) {
- cinfo->arith_dc_L[i] = 0;
- cinfo->arith_dc_U[i] = 1;
- cinfo->arith_ac_K[i] = 5;
- }
-
- /* Default is no multiple-scan output */
- cinfo->scan_info = NULL;
- cinfo->num_scans = 0;
-
- /* Expect normal source image, not raw downsampled data */
- cinfo->raw_data_in = FALSE;
-
- /* Use Huffman coding, not arithmetic coding, by default */
- cinfo->arith_code = FALSE;
-
- /* By default, don't do extra passes to optimize entropy coding */
- cinfo->optimize_coding = FALSE;
- /* The standard Huffman tables are only valid for 8-bit data precision.
- * If the precision is higher, force optimization on so that usable
- * tables will be computed. This test can be removed if default tables
- * are supplied that are valid for the desired precision.
- */
- if (cinfo->data_precision > 8)
- cinfo->optimize_coding = TRUE;
-
- /* By default, use the simpler non-cosited sampling alignment */
- cinfo->CCIR601_sampling = FALSE;
-
- /* No input smoothing */
- cinfo->smoothing_factor = 0;
-
- /* DCT algorithm preference */
- cinfo->dct_method = JDCT_DEFAULT;
-
- /* No restart markers */
- cinfo->restart_interval = 0;
- cinfo->restart_in_rows = 0;
-
- /* Fill in default JFIF marker parameters. Note that whether the marker
- * will actually be written is determined by jpeg_set_colorspace.
- *
- * By default, the library emits JFIF version code 1.01.
- * An application that wants to emit JFIF 1.02 extension markers should set
- * JFIF_minor_version to 2. We could probably get away with just defaulting
- * to 1.02, but there may still be some decoders in use that will complain
- * about that; saying 1.01 should minimize compatibility problems.
- */
- cinfo->JFIF_major_version = 1; /* Default JFIF version = 1.01 */
- cinfo->JFIF_minor_version = 1;
- cinfo->density_unit = 0; /* Pixel size is unknown by default */
- cinfo->X_density = 1; /* Pixel aspect ratio is square by default */
- cinfo->Y_density = 1;
-
- /* Choose JPEG colorspace based on input space, set defaults accordingly */
-
- jpeg_default_colorspace(cinfo);
- }
-
- /*
- * Select an appropriate JPEG colorspace for in_color_space.
- */
-
- GLOBAL(void)
- jpeg_default_colorspace (j_compress_ptr cinfo)
- {
- switch (cinfo->in_color_space) {
- case JCS_GRAYSCALE:
- jpeg_set_colorspace(cinfo, JCS_GRAYSCALE);
- break;
- case JCS_RGB:
- jpeg_set_colorspace(cinfo, JCS_YCbCr);
- break;
- case JCS_YCbCr:
- jpeg_set_colorspace(cinfo, JCS_YCbCr);
- break;
- case JCS_CMYK:
- jpeg_set_colorspace(cinfo, JCS_CMYK); /* By default, no translation */
- break;
- case JCS_YCCK:
- jpeg_set_colorspace(cinfo, JCS_YCCK);
- break;
- case JCS_UNKNOWN:
- jpeg_set_colorspace(cinfo, JCS_UNKNOWN);
- break;
- default:
- ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
- }
- }
-
- /*
- * Set the JPEG colorspace, and choose colorspace-dependent default values.
- */
-
- GLOBAL(void)
- jpeg_set_colorspace (j_compress_ptr cinfo, J_COLOR_SPACE colorspace)
- {
- jpeg_component_info * compptr;
- int ci;
-
- #define SET_COMP(index,id,hsamp,vsamp,quant,dctbl,actbl) \
- (compptr = &cinfo->comp_info[index], \
- compptr->component_id = (id), \
- compptr->h_samp_factor = (hsamp), \
- compptr->v_samp_factor = (vsamp), \
- compptr->quant_tbl_no = (quant), \
- compptr->dc_tbl_no = (dctbl), \
- compptr->ac_tbl_no = (actbl) )
-
- /* Safety check to ensure start_compress not called yet. */
- if (cinfo->global_state != CSTATE_START)
- ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
-
- /* For all colorspaces, we use Q and Huff tables 0 for luminance components,
- * tables 1 for chrominance components.
- */
-
- cinfo->jpeg_color_space = colorspace;
-
- cinfo->write_JFIF_header = FALSE; /* No marker for non-JFIF colorspaces */
- cinfo->write_Adobe_marker = FALSE; /* write no Adobe marker by default */
-
- switch (colorspace) {
- case JCS_GRAYSCALE:
- cinfo->write_JFIF_header = TRUE; /* Write a JFIF marker */
- cinfo->num_components = 1;
- /* JFIF specifies component ID 1 */
- SET_COMP(0, 1, 1,1, 0, 0,0);
- break;
- case JCS_RGB:
- cinfo->write_Adobe_marker = TRUE; /* write Adobe marker to flag RGB */
- cinfo->num_components = 3;
- SET_COMP(0, 0x52 /* 'R' */, 1,1, 0, 0,0);
- SET_COMP(1, 0x47 /* 'G' */, 1,1, 0, 0,0);
- SET_COMP(2, 0x42 /* 'B' */, 1,1, 0, 0,0);
- break;
- case JCS_YCbCr:
- cinfo->write_JFIF_header = TRUE; /* Write a JFIF marker */
- cinfo->num_components = 3;
- /* JFIF specifies component IDs 1,2,3 */
- /* We default to 2x2 subsamples of chrominance */
- SET_COMP(0, 1, 2,2, 0, 0,0);
- SET_COMP(1, 2, 1,1, 1, 1,1);
- SET_COMP(2, 3, 1,1, 1, 1,1);
- break;
- case JCS_CMYK:
- cinfo->write_Adobe_marker = TRUE; /* write Adobe marker to flag CMYK */
- cinfo->num_components = 4;
- SET_COMP(0, 0x43 /* 'C' */, 1,1, 0, 0,0);
- SET_COMP(1, 0x4D /* 'M' */, 1,1, 0, 0,0);
- SET_COMP(2, 0x59 /* 'Y' */, 1,1, 0, 0,0);
- SET_COMP(3, 0x4B /* 'K' */, 1,1, 0, 0,0);
- break;
- case JCS_YCCK:
- cinfo->write_Adobe_marker = TRUE; /* write Adobe marker to flag YCCK */
- cinfo->num_components = 4;
- SET_COMP(0, 1, 2,2, 0, 0,0);
- SET_COMP(1, 2, 1,1, 1, 1,1);
- SET_COMP(2, 3, 1,1, 1, 1,1);
- SET_COMP(3, 4, 2,2, 0, 0,0);
- break;
- case JCS_UNKNOWN:
- cinfo->num_components = cinfo->input_components;
- if (cinfo->num_components < 1 || cinfo->num_components > MAX_COMPONENTS)
- ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->num_components,
- MAX_COMPONENTS);
- for (ci = 0; ci < cinfo->num_components; ci++) {
- SET_COMP(ci, ci, 1,1, 0, 0,0);
- }
- break;
- default:
- ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
- }
- }
-
- #ifdef C_PROGRESSIVE_SUPPORTED
-
- LOCAL(jpeg_scan_info *)
- fill_a_scan (jpeg_scan_info * scanptr, int ci,
- int Ss, int Se, int Ah, int Al)
- /* Support routine: generate one scan for specified component */
- {
- scanptr->comps_in_scan = 1;
- scanptr->component_index[0] = ci;
- scanptr->Ss = Ss;
- scanptr->Se = Se;
- scanptr->Ah = Ah;
- scanptr->Al = Al;
- scanptr++;
- return scanptr;
- }
-
- LOCAL(jpeg_scan_info *)
- fill_scans (jpeg_scan_info * scanptr, int ncomps,
- int Ss, int Se, int Ah, int Al)
- /* Support routine: generate one scan for each component */
- {
- int ci;
-
- for (ci = 0; ci < ncomps; ci++) {
- scanptr->comps_in_scan = 1;
- scanptr->component_index[0] = ci;
- scanptr->Ss = Ss;
- scanptr->Se = Se;
- scanptr->Ah = Ah;
- scanptr->Al = Al;
- scanptr++;
- }
- return scanptr;
- }
-
- LOCAL(jpeg_scan_info *)
- fill_dc_scans (jpeg_scan_info * scanptr, int ncomps, int Ah, int Al)
- /* Support routine: generate interleaved DC scan if possible, else N scans */
- {
- int ci;
-
- if (ncomps <= MAX_COMPS_IN_SCAN) {
- /* Single interleaved DC scan */
- scanptr->comps_in_scan = ncomps;
- for (ci = 0; ci < ncomps; ci++)
- scanptr->component_index[ci] = ci;
- scanptr->Ss = scanptr->Se = 0;
- scanptr->Ah = Ah;
- scanptr->Al = Al;
- scanptr++;
- } else {
- /* Noninterleaved DC scan for each component */
- scanptr = fill_scans(scanptr, ncomps, 0, 0, Ah, Al);
- }
- return scanptr;
- }
-
- /*
- * Create a recommended progressive-JPEG script.
- * cinfo->num_components and cinfo->jpeg_color_space must be correct.
- */
-
- GLOBAL(void)
- jpeg_simple_progression (j_compress_ptr cinfo)
- {
- int ncomps = cinfo->num_components;
- int nscans;
- jpeg_scan_info * scanptr;
-
- /* Safety check to ensure start_compress not called yet. */
- if (cinfo->global_state != CSTATE_START)
- ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
-
- /* Figure space needed for script. Calculation must match code below! */
- if (ncomps == 3 && cinfo->jpeg_color_space == JCS_YCbCr) {
- /* Custom script for YCbCr color images. */
- nscans = 10;
- } else {
- /* All-purpose script for other color spaces. */
- if (ncomps > MAX_COMPS_IN_SCAN)
- nscans = 6 * ncomps; /* 2 DC + 4 AC scans per component */
- else
- nscans = 2 + 4 * ncomps; /* 2 DC scans; 4 AC scans per component */
- }
-
- /* Allocate space for script.
- * We need to put it in the permanent pool in case the application performs
- * multiple compressions without changing the settings. To avoid a memory
- * leak if jpeg_simple_progression is called repeatedly for the same JPEG
- * object, we try to re-use previously allocated space, and we allocate
- * enough space to handle YCbCr even if initially asked for grayscale.
- */
- if (cinfo->script_space == NULL || cinfo->script_space_size < nscans) {
- cinfo->script_space_size = MAX(nscans, 10);
- cinfo->script_space = (jpeg_scan_info *)
- (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
- cinfo->script_space_size * SIZEOF(jpeg_scan_info));
- }
- scanptr = cinfo->script_space;
- cinfo->scan_info = scanptr;
- cinfo->num_scans = nscans;
-
- if (ncomps == 3 && cinfo->jpeg_color_space == JCS_YCbCr) {
- /* Custom script for YCbCr color images. */
- /* Initial DC scan */
- scanptr = fill_dc_scans(scanptr, ncomps, 0, 1);
- /* Initial AC scan: get some luma data out in a hurry */
- scanptr = fill_a_scan(scanptr, 0, 1, 5, 0, 2);
- /* Chroma data is too small to be worth expending many scans on */
- scanptr = fill_a_scan(scanptr, 2, 1, 63, 0, 1);
- scanptr = fill_a_scan(scanptr, 1, 1, 63, 0, 1);
- /* Complete spectral selection for luma AC */
- scanptr = fill_a_scan(scanptr, 0, 6, 63, 0, 2);
- /* Refine next bit of luma AC */
- scanptr = fill_a_scan(scanptr, 0, 1, 63, 2, 1);
- /* Finish DC successive approximation */
- scanptr = fill_dc_scans(scanptr, ncomps, 1, 0);
- /* Finish AC successive approximation */
- scanptr = fill_a_scan(scanptr, 2, 1, 63, 1, 0);
- scanptr = fill_a_scan(scanptr, 1, 1, 63, 1, 0);
- /* Luma bottom bit comes last since it's usually largest scan */
- scanptr = fill_a_scan(scanptr, 0, 1, 63, 1, 0);
- } else {
- /* All-purpose script for other color spaces. */
- /* Successive approximation first pass */
- scanptr = fill_dc_scans(scanptr, ncomps, 0, 1);
- scanptr = fill_scans(scanptr, ncomps, 1, 5, 0, 2);
- scanptr = fill_scans(scanptr, ncomps, 6, 63, 0, 2);
- /* Successive approximation second pass */
- scanptr = fill_scans(scanptr, ncomps, 1, 63, 2, 1);
- /* Successive approximation final pass */
- scanptr = fill_dc_scans(scanptr, ncomps, 1, 0);
- scanptr = fill_scans(scanptr, ncomps, 1, 63, 1, 0);
- }
- }
-
- #endif /* C_PROGRESSIVE_SUPPORTED */
- /********* End of inlined file: jcparam.c *********/
-
- /********* Start of inlined file: jcphuff.c *********/
- #define JPEG_INTERNALS
-
- #ifdef C_PROGRESSIVE_SUPPORTED
-
- /* Expanded entropy encoder object for progressive Huffman encoding. */
-
- typedef struct {
- struct jpeg_entropy_encoder pub; /* public fields */
-
- /* Mode flag: TRUE for optimization, FALSE for actual data output */
- boolean gather_statistics;
-
- /* Bit-level coding status.
- * next_output_byte/free_in_buffer are local copies of cinfo->dest fields.
- */
- JOCTET * next_output_byte; /* => next byte to write in buffer */
- size_t free_in_buffer; /* # of byte spaces remaining in buffer */
- INT32 put_buffer; /* current bit-accumulation buffer */
- int put_bits; /* # of bits now in it */
- j_compress_ptr cinfo; /* link to cinfo (needed for dump_buffer) */
-
- /* Coding status for DC components */
- int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */
-
- /* Coding status for AC components */
- int ac_tbl_no; /* the table number of the single component */
- unsigned int EOBRUN; /* run length of EOBs */
- unsigned int BE; /* # of buffered correction bits before MCU */
- char * bit_buffer; /* buffer for correction bits (1 per char) */
- /* packing correction bits tightly would save some space but cost time... */
-
- unsigned int restarts_to_go; /* MCUs left in this restart interval */
- int next_restart_num; /* next restart number to write (0-7) */
-
- /* Pointers to derived tables (these workspaces have image lifespan).
- * Since any one scan codes only DC or only AC, we only need one set
- * of tables, not one for DC and one for AC.
- */
- c_derived_tbl * derived_tbls[NUM_HUFF_TBLS];
-
- /* Statistics tables for optimization; again, one set is enough */
- long * count_ptrs[NUM_HUFF_TBLS];
- } phuff_entropy_encoder;
-
- typedef phuff_entropy_encoder * phuff_entropy_ptr;
-
- /* MAX_CORR_BITS is the number of bits the AC refinement correction-bit
- * buffer can hold. Larger sizes may slightly improve compression, but
- * 1000 is already well into the realm of overkill.
- * The minimum safe size is 64 bits.
- */
-
- #define MAX_CORR_BITS 1000 /* Max # of correction bits I can buffer */
-
- /* IRIGHT_SHIFT is like RIGHT_SHIFT, but works on int rather than INT32.
- * We assume that int right shift is unsigned if INT32 right shift is,
- * which should be safe.
- */
-
- #ifdef RIGHT_SHIFT_IS_UNSIGNED
- #define ISHIFT_TEMPS int ishift_temp;
- #define IRIGHT_SHIFT(x,shft) \
- ((ishift_temp = (x)) < 0 ? \
- (ishift_temp >> (shft)) | ((~0) << (16-(shft))) : \
- (ishift_temp >> (shft)))
- #else
- #define ISHIFT_TEMPS
- #define IRIGHT_SHIFT(x,shft) ((x) >> (shft))
- #endif
-
- /* Forward declarations */
- METHODDEF(boolean) encode_mcu_DC_first JPP((j_compress_ptr cinfo,
- JBLOCKROW *MCU_data));
- METHODDEF(boolean) encode_mcu_AC_first JPP((j_compress_ptr cinfo,
- JBLOCKROW *MCU_data));
- METHODDEF(boolean) encode_mcu_DC_refine JPP((j_compress_ptr cinfo,
- JBLOCKROW *MCU_data));
- METHODDEF(boolean) encode_mcu_AC_refine JPP((j_compress_ptr cinfo,
- JBLOCKROW *MCU_data));
- METHODDEF(void) finish_pass_phuff JPP((j_compress_ptr cinfo));
- METHODDEF(void) finish_pass_gather_phuff JPP((j_compress_ptr cinfo));
-
- /*
- * Initialize for a Huffman-compressed scan using progressive JPEG.
- */
-
- METHODDEF(void)
- start_pass_phuff (j_compress_ptr cinfo, boolean gather_statistics)
- {
- phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
- boolean is_DC_band;
- int ci, tbl;
- jpeg_component_info * compptr;
-
- entropy->cinfo = cinfo;
- entropy->gather_statistics = gather_statistics;
-
- is_DC_band = (cinfo->Ss == 0);
-
- /* We assume jcmaster.c already validated the scan parameters. */
-
- /* Select execution routines */
- if (cinfo->Ah == 0) {
- if (is_DC_band)
- entropy->pub.encode_mcu = encode_mcu_DC_first;
- else
- entropy->pub.encode_mcu = encode_mcu_AC_first;
- } else {
- if (is_DC_band)
- entropy->pub.encode_mcu = encode_mcu_DC_refine;
- else {
- entropy->pub.encode_mcu = encode_mcu_AC_refine;
- /* AC refinement needs a correction bit buffer */
- if (entropy->bit_buffer == NULL)
- entropy->bit_buffer = (char *)
- (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
- MAX_CORR_BITS * SIZEOF(char));
- }
- }
- if (gather_statistics)
- entropy->pub.finish_pass = finish_pass_gather_phuff;
- else
- entropy->pub.finish_pass = finish_pass_phuff;
-
- /* Only DC coefficients may be interleaved, so cinfo->comps_in_scan = 1
- * for AC coefficients.
- */
- for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
- compptr = cinfo->cur_comp_info[ci];
- /* Initialize DC predictions to 0 */
- entropy->last_dc_val[ci] = 0;
- /* Get table index */
- if (is_DC_band) {
- if (cinfo->Ah != 0) /* DC refinement needs no table */
- continue;
- tbl = compptr->dc_tbl_no;
- } else {
- entropy->ac_tbl_no = tbl = compptr->ac_tbl_no;
- }
- if (gather_statistics) {
- /* Check for invalid table index */
- /* (make_c_derived_tbl does this in the other path) */
- if (tbl < 0 || tbl >= NUM_HUFF_TBLS)
- ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tbl);
- /* Allocate and zero the statistics tables */
- /* Note that jpeg_gen_optimal_table expects 257 entries in each table! */
- if (entropy->count_ptrs[tbl] == NULL)
- entropy->count_ptrs[tbl] = (long *)
- (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
- 257 * SIZEOF(long));
- MEMZERO(entropy->count_ptrs[tbl], 257 * SIZEOF(long));
- } else {
- /* Compute derived values for Huffman table */
- /* We may do this more than once for a table, but it's not expensive */
- jpeg_make_c_derived_tbl(cinfo, is_DC_band, tbl,
- & entropy->derived_tbls[tbl]);
- }
- }
-
- /* Initialize AC stuff */
- entropy->EOBRUN = 0;
- entropy->BE = 0;
-
- /* Initialize bit buffer to empty */
- entropy->put_buffer = 0;
- entropy->put_bits = 0;
-
- /* Initialize restart stuff */
- entropy->restarts_to_go = cinfo->restart_interval;
- entropy->next_restart_num = 0;
- }
-
- /* Outputting bytes to the file.
- * NB: these must be called only when actually outputting,
- * that is, entropy->gather_statistics == FALSE.
- */
-
- /* Emit a byte */
- #define emit_byte(entropy,val) \
- { *(entropy)->next_output_byte++ = (JOCTET) (val); \
- if (--(entropy)->free_in_buffer == 0) \
- dump_buffer_p(entropy); }
-
- LOCAL(void)
- dump_buffer_p (phuff_entropy_ptr entropy)
- /* Empty the output buffer; we do not support suspension in this module. */
- {
- struct jpeg_destination_mgr * dest = entropy->cinfo->dest;
-
- if (! (*dest->empty_output_buffer) (entropy->cinfo))
- ERREXIT(entropy->cinfo, JERR_CANT_SUSPEND);
- /* After a successful buffer dump, must reset buffer pointers */
- entropy->next_output_byte = dest->next_output_byte;
- entropy->free_in_buffer = dest->free_in_buffer;
- }
-
- /* Outputting bits to the file */
-
- /* Only the right 24 bits of put_buffer are used; the valid bits are
- * left-justified in this part. At most 16 bits can be passed to emit_bits
- * in one call, and we never retain more than 7 bits in put_buffer
- * between calls, so 24 bits are sufficient.
- */
-
- INLINE
- LOCAL(void)
- emit_bits_p (phuff_entropy_ptr entropy, unsigned int code, int size)
- /* Emit some bits, unless we are in gather mode */
- {
- /* This routine is heavily used, so it's worth coding tightly. */
- register INT32 put_buffer = (INT32) code;
- register int put_bits = entropy->put_bits;
-
- /* if size is 0, caller used an invalid Huffman table entry */
- if (size == 0)
- ERREXIT(entropy->cinfo, JERR_HUFF_MISSING_CODE);
-
- if (entropy->gather_statistics)
- return; /* do nothing if we're only getting stats */
-
- put_buffer &= (((INT32) 1)<<size) - 1; /* mask off any extra bits in code */
-
- put_bits += size; /* new number of bits in buffer */
-
- put_buffer <<= 24 - put_bits; /* align incoming bits */
-
- put_buffer |= entropy->put_buffer; /* and merge with old buffer contents */
-
- while (put_bits >= 8) {
- int c = (int) ((put_buffer >> 16) & 0xFF);
-
- emit_byte(entropy, c);
- if (c == 0xFF) { /* need to stuff a zero byte? */
- emit_byte(entropy, 0);
- }
- put_buffer <<= 8;
- put_bits -= 8;
- }
-
- entropy->put_buffer = put_buffer; /* update variables */
- entropy->put_bits = put_bits;
- }
-
- LOCAL(void)
- flush_bits_p (phuff_entropy_ptr entropy)
- {
- emit_bits_p(entropy, 0x7F, 7); /* fill any partial byte with ones */
- entropy->put_buffer = 0; /* and reset bit-buffer to empty */
- entropy->put_bits = 0;
- }
-
- /*
- * Emit (or just count) a Huffman symbol.
- */
-
- INLINE
- LOCAL(void)
- emit_symbol (phuff_entropy_ptr entropy, int tbl_no, int symbol)
- {
- if (entropy->gather_statistics)
- entropy->count_ptrs[tbl_no][symbol]++;
- else {
- c_derived_tbl * tbl = entropy->derived_tbls[tbl_no];
- emit_bits_p(entropy, tbl->ehufco[symbol], tbl->ehufsi[symbol]);
- }
- }
-
- /*
- * Emit bits from a correction bit buffer.
- */
-
- LOCAL(void)
- emit_buffered_bits (phuff_entropy_ptr entropy, char * bufstart,
- unsigned int nbits)
- {
- if (entropy->gather_statistics)
- return; /* no real work */
-
- while (nbits > 0) {
- emit_bits_p(entropy, (unsigned int) (*bufstart), 1);
- bufstart++;
- nbits--;
- }
- }
-
- /*
- * Emit any pending EOBRUN symbol.
- */
-
- LOCAL(void)
- emit_eobrun (phuff_entropy_ptr entropy)
- {
- register int temp, nbits;
-
- if (entropy->EOBRUN > 0) { /* if there is any pending EOBRUN */
- temp = entropy->EOBRUN;
- nbits = 0;
- while ((temp >>= 1))
- nbits++;
- /* safety check: shouldn't happen given limited correction-bit buffer */
- if (nbits > 14)
- ERREXIT(entropy->cinfo, JERR_HUFF_MISSING_CODE);
-
- emit_symbol(entropy, entropy->ac_tbl_no, nbits << 4);
- if (nbits)
- emit_bits_p(entropy, entropy->EOBRUN, nbits);
-
- entropy->EOBRUN = 0;
-
- /* Emit any buffered correction bits */
- emit_buffered_bits(entropy, entropy->bit_buffer, entropy->BE);
- entropy->BE = 0;
- }
- }
-
- /*
- * Emit a restart marker & resynchronize predictions.
- */
-
- LOCAL(void)
- emit_restart_p (phuff_entropy_ptr entropy, int restart_num)
- {
- int ci;
-
- emit_eobrun(entropy);
-
- if (! entropy->gather_statistics) {
- flush_bits_p(entropy);
- emit_byte(entropy, 0xFF);
- emit_byte(entropy, JPEG_RST0 + restart_num);
- }
-
- if (entropy->cinfo->Ss == 0) {
- /* Re-initialize DC predictions to 0 */
- for (ci = 0; ci < entropy->cinfo->comps_in_scan; ci++)
- entropy->last_dc_val[ci] = 0;
- } else {
- /* Re-initialize all AC-related fields to 0 */
- entropy->EOBRUN = 0;
- entropy->BE = 0;
- }
- }
-
- /*
- * MCU encoding for DC initial scan (either spectral selection,
- * or first pass of successive approximation).
- */
-
- METHODDEF(boolean)
- encode_mcu_DC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
- {
- phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
- register int temp, temp2;
- register int nbits;
- int blkn, ci;
- int Al = cinfo->Al;
- JBLOCKROW block;
- jpeg_component_info * compptr;
- ISHIFT_TEMPS
-
- entropy->next_output_byte = cinfo->dest->next_output_byte;
- entropy->free_in_buffer = cinfo->dest->free_in_buffer;
-
- /* Emit restart marker if needed */
- if (cinfo->restart_interval)
- if (entropy->restarts_to_go == 0)
- emit_restart_p(entropy, entropy->next_restart_num);
-
- /* Encode the MCU data blocks */
- for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
- block = MCU_data[blkn];
- ci = cinfo->MCU_membership[blkn];
- compptr = cinfo->cur_comp_info[ci];
-
- /* Compute the DC value after the required point transform by Al.
- * This is simply an arithmetic right shift.
- */
- temp2 = IRIGHT_SHIFT((int) ((*block)[0]), Al);
-
- /* DC differences are figured on the point-transformed values. */
- temp = temp2 - entropy->last_dc_val[ci];
- entropy->last_dc_val[ci] = temp2;
-
- /* Encode the DC coefficient difference per section G.1.2.1 */
- temp2 = temp;
- if (temp < 0) {
- temp = -temp; /* temp is abs value of input */
- /* For a negative input, want temp2 = bitwise complement of abs(input) */
- /* This code assumes we are on a two's complement machine */
- temp2--;
- }
-
- /* Find the number of bits needed for the magnitude of the coefficient */
- nbits = 0;
- while (temp) {
- nbits++;
- temp >>= 1;
- }
- /* Check for out-of-range coefficient values.
- * Since we're encoding a difference, the range limit is twice as much.
- */
- if (nbits > MAX_COEF_BITS+1)
- ERREXIT(cinfo, JERR_BAD_DCT_COEF);
-
- /* Count/emit the Huffman-coded symbol for the number of bits */
- emit_symbol(entropy, compptr->dc_tbl_no, nbits);
-
- /* Emit that number of bits of the value, if positive, */
- /* or the complement of its magnitude, if negative. */
- if (nbits) /* emit_bits rejects calls with size 0 */
- emit_bits_p(entropy, (unsigned int) temp2, nbits);
- }
-
- cinfo->dest->next_output_byte = entropy->next_output_byte;
- cinfo->dest->free_in_buffer = entropy->free_in_buffer;
-
- /* Update restart-interval state too */
- if (cinfo->restart_interval) {
- if (entropy->restarts_to_go == 0) {
- entropy->restarts_to_go = cinfo->restart_interval;
- entropy->next_restart_num++;
- entropy->next_restart_num &= 7;
- }
- entropy->restarts_to_go--;
- }
-
- return TRUE;
- }
-
- /*
- * MCU encoding for AC initial scan (either spectral selection,
- * or first pass of successive approximation).
- */
-
- METHODDEF(boolean)
- encode_mcu_AC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
- {
- phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
- register int temp, temp2;
- register int nbits;
- register int r, k;
- int Se = cinfo->Se;
- int Al = cinfo->Al;
- JBLOCKROW block;
-
- entropy->next_output_byte = cinfo->dest->next_output_byte;
- entropy->free_in_buffer = cinfo->dest->free_in_buffer;
-
- /* Emit restart marker if needed */
- if (cinfo->restart_interval)
- if (entropy->restarts_to_go == 0)
- emit_restart_p(entropy, entropy->next_restart_num);
-
- /* Encode the MCU data block */
- block = MCU_data[0];
-
- /* Encode the AC coefficients per section G.1.2.2, fig. G.3 */
-
- r = 0; /* r = run length of zeros */
-
- for (k = cinfo->Ss; k <= Se; k++) {
- if ((temp = (*block)[jpeg_natural_order[k]]) == 0) {
- r++;
- continue;
- }
- /* We must apply the point transform by Al. For AC coefficients this
- * is an integer division with rounding towards 0. To do this portably
- * in C, we shift after obtaining the absolute value; so the code is
- * interwoven with finding the abs value (temp) and output bits (temp2).
- */
- if (temp < 0) {
- temp = -temp; /* temp is abs value of input */
- temp >>= Al; /* apply the point transform */
- /* For a negative coef, want temp2 = bitwise complement of abs(coef) */
- temp2 = ~temp;
- } else {
- temp >>= Al; /* apply the point transform */
- temp2 = temp;
- }
- /* Watch out for case that nonzero coef is zero after point transform */
- if (temp == 0) {
- r++;
- continue;
- }
-
- /* Emit any pending EOBRUN */
- if (entropy->EOBRUN > 0)
- emit_eobrun(entropy);
- /* if run length > 15, must emit special run-length-16 codes (0xF0) */
- while (r > 15) {
- emit_symbol(entropy, entropy->ac_tbl_no, 0xF0);
- r -= 16;
- }
-
- /* Find the number of bits needed for the magnitude of the coefficient */
- nbits = 1; /* there must be at least one 1 bit */
- while ((temp >>= 1))
- nbits++;
- /* Check for out-of-range coefficient values */
- if (nbits > MAX_COEF_BITS)
- ERREXIT(cinfo, JERR_BAD_DCT_COEF);
-
- /* Count/emit Huffman symbol for run length / number of bits */
- emit_symbol(entropy, entropy->ac_tbl_no, (r << 4) + nbits);
-
- /* Emit that number of bits of the value, if positive, */
- /* or the complement of its magnitude, if negative. */
- emit_bits_p(entropy, (unsigned int) temp2, nbits);
-
- r = 0; /* reset zero run length */
- }
-
- if (r > 0) { /* If there are trailing zeroes, */
- entropy->EOBRUN++; /* count an EOB */
- if (entropy->EOBRUN == 0x7FFF)
- emit_eobrun(entropy); /* force it out to avoid overflow */
- }
-
- cinfo->dest->next_output_byte = entropy->next_output_byte;
- cinfo->dest->free_in_buffer = entropy->free_in_buffer;
-
- /* Update restart-interval state too */
- if (cinfo->restart_interval) {
- if (entropy->restarts_to_go == 0) {
- entropy->restarts_to_go = cinfo->restart_interval;
- entropy->next_restart_num++;
- entropy->next_restart_num &= 7;
- }
- entropy->restarts_to_go--;
- }
-
- return TRUE;
- }
-
- /*
- * MCU encoding for DC successive approximation refinement scan.
- * Note: we assume such scans can be multi-component, although the spec
- * is not very clear on the point.
- */
-
- METHODDEF(boolean)
- encode_mcu_DC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
- {
- phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
- register int temp;
- int blkn;
- int Al = cinfo->Al;
- JBLOCKROW block;
-
- entropy->next_output_byte = cinfo->dest->next_output_byte;
- entropy->free_in_buffer = cinfo->dest->free_in_buffer;
-
- /* Emit restart marker if needed */
- if (cinfo->restart_interval)
- if (entropy->restarts_to_go == 0)
- emit_restart_p(entropy, entropy->next_restart_num);
-
- /* Encode the MCU data blocks */
- for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
- block = MCU_data[blkn];
-
- /* We simply emit the Al'th bit of the DC coefficient value. */
- temp = (*block)[0];
- emit_bits_p(entropy, (unsigned int) (temp >> Al), 1);
- }
-
- cinfo->dest->next_output_byte = entropy->next_output_byte;
- cinfo->dest->free_in_buffer = entropy->free_in_buffer;
-
- /* Update restart-interval state too */
- if (cinfo->restart_interval) {
- if (entropy->restarts_to_go == 0) {
- entropy->restarts_to_go = cinfo->restart_interval;
- entropy->next_restart_num++;
- entropy->next_restart_num &= 7;
- }
- entropy->restarts_to_go--;
- }
-
- return TRUE;
- }
-
- /*
- * MCU encoding for AC successive approximation refinement scan.
- */
-
- METHODDEF(boolean)
- encode_mcu_AC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
- {
- phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
- register int temp;
- register int r, k;
- int EOB;
- char *BR_buffer;
- unsigned int BR;
- int Se = cinfo->Se;
- int Al = cinfo->Al;
- JBLOCKROW block;
- int absvalues[DCTSIZE2];
-
- entropy->next_output_byte = cinfo->dest->next_output_byte;
- entropy->free_in_buffer = cinfo->dest->free_in_buffer;
-
- /* Emit restart marker if needed */
- if (cinfo->restart_interval)
- if (entropy->restarts_to_go == 0)
- emit_restart_p(entropy, entropy->next_restart_num);
-
- /* Encode the MCU data block */
- block = MCU_data[0];
-
- /* It is convenient to make a pre-pass to determine the transformed
- * coefficients' absolute values and the EOB position.
- */
- EOB = 0;
- for (k = cinfo->Ss; k <= Se; k++) {
- temp = (*block)[jpeg_natural_order[k]];
- /* We must apply the point transform by Al. For AC coefficients this
- * is an integer division with rounding towards 0. To do this portably
- * in C, we shift after obtaining the absolute value.
- */
- if (temp < 0)
- temp = -temp; /* temp is abs value of input */
- temp >>= Al; /* apply the point transform */
- absvalues[k] = temp; /* save abs value for main pass */
- if (temp == 1)
- EOB = k; /* EOB = index of last newly-nonzero coef */
- }
-
- /* Encode the AC coefficients per section G.1.2.3, fig. G.7 */
-
- r = 0; /* r = run length of zeros */
- BR = 0; /* BR = count of buffered bits added now */
- BR_buffer = entropy->bit_buffer + entropy->BE; /* Append bits to buffer */
-
- for (k = cinfo->Ss; k <= Se; k++) {
- if ((temp = absvalues[k]) == 0) {
- r++;
- continue;
- }
-
- /* Emit any required ZRLs, but not if they can be folded into EOB */
- while (r > 15 && k <= EOB) {
- /* emit any pending EOBRUN and the BE correction bits */
- emit_eobrun(entropy);
- /* Emit ZRL */
- emit_symbol(entropy, entropy->ac_tbl_no, 0xF0);
- r -= 16;
- /* Emit buffered correction bits that must be associated with ZRL */
- emit_buffered_bits(entropy, BR_buffer, BR);
- BR_buffer = entropy->bit_buffer; /* BE bits are gone now */
- BR = 0;
- }
-
- /* If the coef was previously nonzero, it only needs a correction bit.
- * NOTE: a straight translation of the spec's figure G.7 would suggest
- * that we also need to test r > 15. But if r > 15, we can only get here
- * if k > EOB, which implies that this coefficient is not 1.
- */
- if (temp > 1) {
- /* The correction bit is the next bit of the absolute value. */
- BR_buffer[BR++] = (char) (temp & 1);
- continue;
- }
-
- /* Emit any pending EOBRUN and the BE correction bits */
- emit_eobrun(entropy);
-
- /* Count/emit Huffman symbol for run length / number of bits */
- emit_symbol(entropy, entropy->ac_tbl_no, (r << 4) + 1);
-
- /* Emit output bit for newly-nonzero coef */
- temp = ((*block)[jpeg_natural_order[k]] < 0) ? 0 : 1;
- emit_bits_p(entropy, (unsigned int) temp, 1);
-
- /* Emit buffered correction bits that must be associated with this code */
- emit_buffered_bits(entropy, BR_buffer, BR);
- BR_buffer = entropy->bit_buffer; /* BE bits are gone now */
- BR = 0;
- r = 0; /* reset zero run length */
- }
-
- if (r > 0 || BR > 0) { /* If there are trailing zeroes, */
- entropy->EOBRUN++; /* count an EOB */
- entropy->BE += BR; /* concat my correction bits to older ones */
- /* We force out the EOB if we risk either:
- * 1. overflow of the EOB counter;
- * 2. overflow of the correction bit buffer during the next MCU.
- */
- if (entropy->EOBRUN == 0x7FFF || entropy->BE > (MAX_CORR_BITS-DCTSIZE2+1))
- emit_eobrun(entropy);
- }
-
- cinfo->dest->next_output_byte = entropy->next_output_byte;
- cinfo->dest->free_in_buffer = entropy->free_in_buffer;
-
- /* Update restart-interval state too */
- if (cinfo->restart_interval) {
- if (entropy->restarts_to_go == 0) {
- entropy->restarts_to_go = cinfo->restart_interval;
- entropy->next_restart_num++;
- entropy->next_restart_num &= 7;
- }
- entropy->restarts_to_go--;
- }
-
- return TRUE;
- }
-
- /*
- * Finish up at the end of a Huffman-compressed progressive scan.
- */
-
- METHODDEF(void)
- finish_pass_phuff (j_compress_ptr cinfo)
- {
- phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
-
- entropy->next_output_byte = cinfo->dest->next_output_byte;
- entropy->free_in_buffer = cinfo->dest->free_in_buffer;
-
- /* Flush out any buffered data */
- emit_eobrun(entropy);
- flush_bits_p(entropy);
-
- cinfo->dest->next_output_byte = entropy->next_output_byte;
- cinfo->dest->free_in_buffer = entropy->free_in_buffer;
- }
-
- /*
- * Finish up a statistics-gathering pass and create the new Huffman tables.
- */
-
- METHODDEF(void)
- finish_pass_gather_phuff (j_compress_ptr cinfo)
- {
- phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
- boolean is_DC_band;
- int ci, tbl;
- jpeg_component_info * compptr;
- JHUFF_TBL **htblptr;
- boolean did[NUM_HUFF_TBLS];
-
- /* Flush out buffered data (all we care about is counting the EOB symbol) */
- emit_eobrun(entropy);
-
- is_DC_band = (cinfo->Ss == 0);
-
- /* It's important not to apply jpeg_gen_optimal_table more than once
- * per table, because it clobbers the input frequency counts!
- */
- MEMZERO(did, SIZEOF(did));
-
- for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
- compptr = cinfo->cur_comp_info[ci];
- if (is_DC_band) {
- if (cinfo->Ah != 0) /* DC refinement needs no table */
- continue;
- tbl = compptr->dc_tbl_no;
- } else {
- tbl = compptr->ac_tbl_no;
- }
- if (! did[tbl]) {
- if (is_DC_band)
- htblptr = & cinfo->dc_huff_tbl_ptrs[tbl];
- else
- htblptr = & cinfo->ac_huff_tbl_ptrs[tbl];
- if (*htblptr == NULL)
- *htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo);
- jpeg_gen_optimal_table(cinfo, *htblptr, entropy->count_ptrs[tbl]);
- did[tbl] = TRUE;
- }
- }
- }
-
- /*
- * Module initialization routine for progressive Huffman entropy encoding.
- */
-
- GLOBAL(void)
- jinit_phuff_encoder (j_compress_ptr cinfo)
- {
- phuff_entropy_ptr entropy;
- int i;
-
- entropy = (phuff_entropy_ptr)
- (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
- SIZEOF(phuff_entropy_encoder));
- cinfo->entropy = (struct jpeg_entropy_encoder *) entropy;
- entropy->pub.start_pass = start_pass_phuff;
-
- /* Mark tables unallocated */
- for (i = 0; i < NUM_HUFF_TBLS; i++) {
- entropy->derived_tbls[i] = NULL;
- entropy->count_ptrs[i] = NULL;
- }
- entropy->bit_buffer = NULL; /* needed only in AC refinement scan */
- }
-
- #endif /* C_PROGRESSIVE_SUPPORTED */
- /********* End of inlined file: jcphuff.c *********/
-
- /********* Start of inlined file: jcprepct.c *********/
- #define JPEG_INTERNALS
-
- /* At present, jcsample.c can request context rows only for smoothing.
- * In the future, we might also need context rows for CCIR601 sampling
- * or other more-complex downsampling procedures. The code to support
- * context rows should be compiled only if needed.
- */
- #ifdef INPUT_SMOOTHING_SUPPORTED
- #define CONTEXT_ROWS_SUPPORTED
- #endif
-
- /*
- * For the simple (no-context-row) case, we just need to buffer one
- * row group's worth of pixels for the downsampling step. At the bottom of
- * the image, we pad to a full row group by replicating the last pixel row.
- * The downsampler's last output row is then replicated if needed to pad
- * out to a full iMCU row.
- *
- * When providing context rows, we must buffer three row groups' worth of
- * pixels. Three row groups are physically allocated, but the row pointer
- * arrays are made five row groups high, with the extra pointers above and
- * below "wrapping around" to point to the last and first real row groups.
- * This allows the downsampler to access the proper context rows.
- * At the top and bottom of the image, we create dummy context rows by
- * copying the first or last real pixel row. This copying could be avoided
- * by pointer hacking as is done in jdmainct.c, but it doesn't seem worth the
- * trouble on the compression side.
- */
-
- /* Private buffer controller object */
-
- typedef struct {
- struct jpeg_c_prep_controller pub; /* public fields */
-
- /* Downsampling input buffer. This buffer holds color-converted data
- * until we have enough to do a downsample step.
- */
- JSAMPARRAY color_buf[MAX_COMPONENTS];
-
- JDIMENSION rows_to_go; /* counts rows remaining in source image */
- int next_buf_row; /* index of next row to store in color_buf */
-
- #ifdef CONTEXT_ROWS_SUPPORTED /* only needed for context case */
- int this_row_group; /* starting row index of group to process */
- int next_buf_stop; /* downsample when we reach this index */
- #endif
- } my_prep_controller;
-
- typedef my_prep_controller * my_prep_ptr;
-
- /*
- * Initialize for a processing pass.
- */
-
- METHODDEF(void)
- start_pass_prep (j_compress_ptr cinfo, J_BUF_MODE pass_mode)
- {
- my_prep_ptr prep = (my_prep_ptr) cinfo->prep;
-
- if (pass_mode != JBUF_PASS_THRU)
- ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
-
- /* Initialize total-height counter for detecting bottom of image */
- prep->rows_to_go = cinfo->image_height;
- /* Mark the conversion buffer empty */
- prep->next_buf_row = 0;
- #ifdef CONTEXT_ROWS_SUPPORTED
- /* Preset additional state variables for context mode.
- * These aren't used in non-context mode, so we needn't test which mode.
- */
- prep->this_row_group = 0;
- /* Set next_buf_stop to stop after two row groups have been read in. */
- prep->next_buf_stop = 2 * cinfo->max_v_samp_factor;
- #endif
- }
-
- /*
- * Expand an image vertically from height input_rows to height output_rows,
- * by duplicating the bottom row.
- */
-
- LOCAL(void)
- expand_bottom_edge (JSAMPARRAY image_data, JDIMENSION num_cols,
- int input_rows, int output_rows)
- {
- register int row;
-
- for (row = input_rows; row < output_rows; row++) {
- jcopy_sample_rows(image_data, input_rows-1, image_data, row,
- 1, num_cols);
- }
- }
-
- /*
- * Process some data in the simple no-context case.
- *
- * Preprocessor output data is counted in "row groups". A row group
- * is defined to be v_samp_factor sample rows of each component.
- * Downsampling will produce this much data from each max_v_samp_factor
- * input rows.
- */
-
- METHODDEF(void)
- pre_process_data (j_compress_ptr cinfo,
- JSAMPARRAY input_buf, JDIMENSION *in_row_ctr,
- JDIMENSION in_rows_avail,
- JSAMPIMAGE output_buf, JDIMENSION *out_row_group_ctr,
- JDIMENSION out_row_groups_avail)
- {
- my_prep_ptr prep = (my_prep_ptr) cinfo->prep;
- int numrows, ci;
- JDIMENSION inrows;
- jpeg_component_info * compptr;
-
- while (*in_row_ctr < in_rows_avail &&
- *out_row_group_ctr < out_row_groups_avail) {
- /* Do color conversion to fill the conversion buffer. */
- inrows = in_rows_avail - *in_row_ctr;
- numrows = cinfo->max_v_samp_factor - prep->next_buf_row;
- numrows = (int) MIN((JDIMENSION) numrows, inrows);
- (*cinfo->cconvert->color_convert) (cinfo, input_buf + *in_row_ctr,
- prep->color_buf,
- (JDIMENSION) prep->next_buf_row,
- numrows);
- *in_row_ctr += numrows;
- prep->next_buf_row += numrows;
- prep->rows_to_go -= numrows;
- /* If at bottom of image, pad to fill the conversion buffer. */
- if (prep->rows_to_go == 0 &&
- prep->next_buf_row < cinfo->max_v_samp_factor) {
- for (ci = 0; ci < cinfo->num_components; ci++) {
- expand_bottom_edge(prep->color_buf[ci], cinfo->image_width,
- prep->next_buf_row, cinfo->max_v_samp_factor);
- }
- prep->next_buf_row = cinfo->max_v_samp_factor;
- }
- /* If we've filled the conversion buffer, empty it. */
- if (prep->next_buf_row == cinfo->max_v_samp_factor) {
- (*cinfo->downsample->downsample) (cinfo,
- prep->color_buf, (JDIMENSION) 0,
- output_buf, *out_row_group_ctr);
- prep->next_buf_row = 0;
- (*out_row_group_ctr)++;
- }
- /* If at bottom of image, pad the output to a full iMCU height.
- * Note we assume the caller is providing a one-iMCU-height output buffer!
- */
- if (prep->rows_to_go == 0 &&
- *out_row_group_ctr < out_row_groups_avail) {
- for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
- ci++, compptr++) {
- expand_bottom_edge(output_buf[ci],
- compptr->width_in_blocks * DCTSIZE,
- (int) (*out_row_group_ctr * compptr->v_samp_factor),
- (int) (out_row_groups_avail * compptr->v_samp_factor));
- }
- *out_row_group_ctr = out_row_groups_avail;
- break; /* can exit outer loop without test */
- }
- }
- }
-
- #ifdef CONTEXT_ROWS_SUPPORTED
-
- /*
- * Process some data in the context case.
- */
-
- METHODDEF(void)
- pre_process_context (j_compress_ptr cinfo,
- JSAMPARRAY input_buf, JDIMENSION *in_row_ctr,
- JDIMENSION in_rows_avail,
- JSAMPIMAGE output_buf, JDIMENSION *out_row_group_ctr,
- JDIMENSION out_row_groups_avail)
- {
- my_prep_ptr prep = (my_prep_ptr) cinfo->prep;
- int numrows, ci;
- int buf_height = cinfo->max_v_samp_factor * 3;
- JDIMENSION inrows;
-
- while (*out_row_group_ctr < out_row_groups_avail) {
- if (*in_row_ctr < in_rows_avail) {
- /* Do color conversion to fill the conversion buffer. */
- inrows = in_rows_avail - *in_row_ctr;
- numrows = prep->next_buf_stop - prep->next_buf_row;
- numrows = (int) MIN((JDIMENSION) numrows, inrows);
- (*cinfo->cconvert->color_convert) (cinfo, input_buf + *in_row_ctr,
- prep->color_buf,
- (JDIMENSION) prep->next_buf_row,
- numrows);
- /* Pad at top of image, if first time through */
- if (prep->rows_to_go == cinfo->image_height) {
- for (ci = 0; ci < cinfo->num_components; ci++) {
- int row;
- for (row = 1; row <= cinfo->max_v_samp_factor; row++) {
- jcopy_sample_rows(prep->color_buf[ci], 0,
- prep->color_buf[ci], -row,
- 1, cinfo->image_width);
- }
- }
- }
- *in_row_ctr += numrows;
- prep->next_buf_row += numrows;
- prep->rows_to_go -= numrows;
- } else {
- /* Return for more data, unless we are at the bottom of the image. */
- if (prep->rows_to_go != 0)
- break;
- /* When at bottom of image, pad to fill the conversion buffer. */
- if (prep->next_buf_row < prep->next_buf_stop) {
- for (ci = 0; ci < cinfo->num_components; ci++) {
- expand_bottom_edge(prep->color_buf[ci], cinfo->image_width,
- prep->next_buf_row, prep->next_buf_stop);
- }
- prep->next_buf_row = prep->next_buf_stop;
- }
- }
- /* If we've gotten enough data, downsample a row group. */
- if (prep->next_buf_row == prep->next_buf_stop) {
- (*cinfo->downsample->downsample) (cinfo,
- prep->color_buf,
- (JDIMENSION) prep->this_row_group,
- output_buf, *out_row_group_ctr);
- (*out_row_group_ctr)++;
- /* Advance pointers with wraparound as necessary. */
- prep->this_row_group += cinfo->max_v_samp_factor;
- if (prep->this_row_group >= buf_height)
- prep->this_row_group = 0;
- if (prep->next_buf_row >= buf_height)
- prep->next_buf_row = 0;
- prep->next_buf_stop = prep->next_buf_row + cinfo->max_v_samp_factor;
- }
- }
- }
-
- /*
- * Create the wrapped-around downsampling input buffer needed for context mode.
- */
-
- LOCAL(void)
- create_context_buffer (j_compress_ptr cinfo)
- {
- my_prep_ptr prep = (my_prep_ptr) cinfo->prep;
- int rgroup_height = cinfo->max_v_samp_factor;
- int ci, i;
- jpeg_component_info * compptr;
- JSAMPARRAY true_buffer, fake_buffer;
-
- /* Grab enough space for fake row pointers for all the components;
- * we need five row groups' worth of pointers for each component.
- */
- fake_buffer = (JSAMPARRAY)
- (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
- (cinfo->num_components * 5 * rgroup_height) *
- SIZEOF(JSAMPROW));
-
- for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
- ci++, compptr++) {
- /* Allocate the actual buffer space (3 row groups) for this component.
- * We make the buffer wide enough to allow the downsampler to edge-expand
- * horizontally within the buffer, if it so chooses.
- */
- true_buffer = (*cinfo->mem->alloc_sarray)
- ((j_common_ptr) cinfo, JPOOL_IMAGE,
- (JDIMENSION) (((long) compptr->width_in_blocks * DCTSIZE *
- cinfo->max_h_samp_factor) / compptr->h_samp_factor),
- (JDIMENSION) (3 * rgroup_height));
- /* Copy true buffer row pointers into the middle of the fake row array */
- MEMCOPY(fake_buffer + rgroup_height, true_buffer,
- 3 * rgroup_height * SIZEOF(JSAMPROW));
- /* Fill in the above and below wraparound pointers */
- for (i = 0; i < rgroup_height; i++) {
- fake_buffer[i] = true_buffer[2 * rgroup_height + i];
- fake_buffer[4 * rgroup_height + i] = true_buffer[i];
- }
- prep->color_buf[ci] = fake_buffer + rgroup_height;
- fake_buffer += 5 * rgroup_height; /* point to space for next component */
- }
- }
-
- #endif /* CONTEXT_ROWS_SUPPORTED */
-
- /*
- * Initialize preprocessing controller.
- */
-
- GLOBAL(void)
- jinit_c_prep_controller (j_compress_ptr cinfo, boolean need_full_buffer)
- {
- my_prep_ptr prep;
- int ci;
- jpeg_component_info * compptr;
-
- if (need_full_buffer) /* safety check */
- ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
-
- prep = (my_prep_ptr)
- (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
- SIZEOF(my_prep_controller));
- cinfo->prep = (struct jpeg_c_prep_controller *) prep;
- prep->pub.start_pass = start_pass_prep;
-
- /* Allocate the color conversion buffer.
- * We make the buffer wide enough to allow the downsampler to edge-expand
- * horizontally within the buffer, if it so chooses.
- */
- if (cinfo->downsample->need_context_rows) {
- /* Set up to provide context rows */
- #ifdef CONTEXT_ROWS_SUPPORTED
- prep->pub.pre_process_data = pre_process_context;
- create_context_buffer(cinfo);
- #else
- ERREXIT(cinfo, JERR_NOT_COMPILED);
- #endif
- } else {
- /* No context, just make it tall enough for one row group */
- prep->pub.pre_process_data = pre_process_data;
- for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
- ci++, compptr++) {
- prep->color_buf[ci] = (*cinfo->mem->alloc_sarray)
- ((j_common_ptr) cinfo, JPOOL_IMAGE,
- (JDIMENSION) (((long) compptr->width_in_blocks * DCTSIZE *
- cinfo->max_h_samp_factor) / compptr->h_samp_factor),
- (JDIMENSION) cinfo->max_v_samp_factor);
- }
- }
- }
- /********* End of inlined file: jcprepct.c *********/
-
- /********* Start of inlined file: jcsample.c *********/
- #define JPEG_INTERNALS
-
- /* Pointer to routine to downsample a single component */
- typedef JMETHOD(void, downsample1_ptr,
- (j_compress_ptr cinfo, jpeg_component_info * compptr,
- JSAMPARRAY input_data, JSAMPARRAY output_data));
-
- /* Private subobject */
-
- typedef struct {
- struct jpeg_downsampler pub; /* public fields */
-
- /* Downsampling method pointers, one per component */
- downsample1_ptr methods[MAX_COMPONENTS];
- } my_downsampler;
-
- typedef my_downsampler * my_downsample_ptr;
-
- /*
- * Initialize for a downsampling pass.
- */
-
- METHODDEF(void)
- start_pass_downsample (j_compress_ptr cinfo)
- {
- /* no work for now */
- }
-
- /*
- * Expand a component horizontally from width input_cols to width output_cols,
- * by duplicating the rightmost samples.
- */
-
- LOCAL(void)
- expand_right_edge (JSAMPARRAY image_data, int num_rows,
- JDIMENSION input_cols, JDIMENSION output_cols)
- {
- register JSAMPROW ptr;
- register JSAMPLE pixval;
- register int count;
- int row;
- int numcols = (int) (output_cols - input_cols);
-
- if (numcols > 0) {
- for (row = 0; row < num_rows; row++) {
- ptr = image_data[row] + input_cols;
- pixval = ptr[-1]; /* don't need GETJSAMPLE() here */
- for (count = numcols; count > 0; count--)
- *ptr++ = pixval;
- }
- }
- }
-
- /*
- * Do downsampling for a whole row group (all components).
- *
- * In this version we simply downsample each component independently.
- */
-
- METHODDEF(void)
- sep_downsample (j_compress_ptr cinfo,
- JSAMPIMAGE input_buf, JDIMENSION in_row_index,
- JSAMPIMAGE output_buf, JDIMENSION out_row_group_index)
- {
- my_downsample_ptr downsample = (my_downsample_ptr) cinfo->downsample;
- int ci;
- jpeg_component_info * compptr;
- JSAMPARRAY in_ptr, out_ptr;
-
- for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
- ci++, compptr++) {
- in_ptr = input_buf[ci] + in_row_index;
- out_ptr = output_buf[ci] + (out_row_group_index * compptr->v_samp_factor);
- (*downsample->methods[ci]) (cinfo, compptr, in_ptr, out_ptr);
- }
- }
-
- /*
- * Downsample pixel values of a single component.
- * One row group is processed per call.
- * This version handles arbitrary integral sampling ratios, without smoothing.
- * Note that this version is not actually used for customary sampling ratios.
- */
-
- METHODDEF(void)
- int_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
- JSAMPARRAY input_data, JSAMPARRAY output_data)
- {
- int inrow, outrow, h_expand, v_expand, numpix, numpix2, h, v;
- JDIMENSION outcol, outcol_h; /* outcol_h == outcol*h_expand */
- JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE;
- JSAMPROW inptr, outptr;
- INT32 outvalue;
-
- h_expand = cinfo->max_h_samp_factor / compptr->h_samp_factor;
- v_expand = cinfo->max_v_samp_factor / compptr->v_samp_factor;
- numpix = h_expand * v_expand;
- numpix2 = numpix/2;
-
- /* Expand input data enough to let all the output samples be generated
- * by the standard loop. Special-casing padded output would be more
- * efficient.
- */
- expand_right_edge(input_data, cinfo->max_v_samp_factor,
- cinfo->image_width, output_cols * h_expand);
-
- inrow = 0;
- for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) {
- outptr = output_data[outrow];
- for (outcol = 0, outcol_h = 0; outcol < output_cols;
- outcol++, outcol_h += h_expand) {
- outvalue = 0;
- for (v = 0; v < v_expand; v++) {
- inptr = input_data[inrow+v] + outcol_h;
- for (h = 0; h < h_expand; h++) {
- outvalue += (INT32) GETJSAMPLE(*inptr++);
- }
- }
- *outptr++ = (JSAMPLE) ((outvalue + numpix2) / numpix);
- }
- inrow += v_expand;
- }
- }
-
- /*
- * Downsample pixel values of a single component.
- * This version handles the special case of a full-size component,
- * without smoothing.
- */
-
- METHODDEF(void)
- fullsize_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
- JSAMPARRAY input_data, JSAMPARRAY output_data)
- {
- /* Copy the data */
- jcopy_sample_rows(input_data, 0, output_data, 0,
- cinfo->max_v_samp_factor, cinfo->image_width);
- /* Edge-expand */
- expand_right_edge(output_data, cinfo->max_v_samp_factor,
- cinfo->image_width, compptr->width_in_blocks * DCTSIZE);
- }
-
- /*
- * Downsample pixel values of a single component.
- * This version handles the common case of 2:1 horizontal and 1:1 vertical,
- * without smoothing.
- *
- * A note about the "bias" calculations: when rounding fractional values to
- * integer, we do not want to always round 0.5 up to the next integer.
- * If we did that, we'd introduce a noticeable bias towards larger values.
- * Instead, this code is arranged so that 0.5 will be rounded up or down at
- * alternate pixel locations (a simple ordered dither pattern).
- */
-
- METHODDEF(void)
- h2v1_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
- JSAMPARRAY input_data, JSAMPARRAY output_data)
- {
- int outrow;
- JDIMENSION outcol;
- JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE;
- register JSAMPROW inptr, outptr;
- register int bias;
-
- /* Expand input data enough to let all the output samples be generated
- * by the standard loop. Special-casing padded output would be more
- * efficient.
- */
- expand_right_edge(input_data, cinfo->max_v_samp_factor,
- cinfo->image_width, output_cols * 2);
-
- for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) {
- outptr = output_data[outrow];
- inptr = input_data[outrow];
- bias = 0; /* bias = 0,1,0,1,... for successive samples */
- for (outcol = 0; outcol < output_cols; outcol++) {
- *outptr++ = (JSAMPLE) ((GETJSAMPLE(*inptr) + GETJSAMPLE(inptr[1])
- + bias) >> 1);
- bias ^= 1; /* 0=>1, 1=>0 */
- inptr += 2;
- }
- }
- }
-
- /*
- * Downsample pixel values of a single component.
- * This version handles the standard case of 2:1 horizontal and 2:1 vertical,
- * without smoothing.
- */
-
- METHODDEF(void)
- h2v2_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
- JSAMPARRAY input_data, JSAMPARRAY output_data)
- {
- int inrow, outrow;
- JDIMENSION outcol;
- JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE;
- register JSAMPROW inptr0, inptr1, outptr;
- register int bias;
-
- /* Expand input data enough to let all the output samples be generated
- * by the standard loop. Special-casing padded output would be more
- * efficient.
- */
- expand_right_edge(input_data, cinfo->max_v_samp_factor,
- cinfo->image_width, output_cols * 2);
-
- inrow = 0;
- for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) {
- outptr = output_data[outrow];
- inptr0 = input_data[inrow];
- inptr1 = input_data[inrow+1];
- bias = 1; /* bias = 1,2,1,2,... for successive samples */
- for (outcol = 0; outcol < output_cols; outcol++) {
- *outptr++ = (JSAMPLE) ((GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) +
- GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1])
- + bias) >> 2);
- bias ^= 3; /* 1=>2, 2=>1 */
- inptr0 += 2; inptr1 += 2;
- }
- inrow += 2;
- }
- }
-
- #ifdef INPUT_SMOOTHING_SUPPORTED
-
- /*
- * Downsample pixel values of a single component.
- * This version handles the standard case of 2:1 horizontal and 2:1 vertical,
- * with smoothing. One row of context is required.
- */
-
- METHODDEF(void)
- h2v2_smooth_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
- JSAMPARRAY input_data, JSAMPARRAY output_data)
- {
- int inrow, outrow;
- JDIMENSION colctr;
- JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE;
- register JSAMPROW inptr0, inptr1, above_ptr, below_ptr, outptr;
- INT32 membersum, neighsum, memberscale, neighscale;
-
- /* Expand input data enough to let all the output samples be generated
- * by the standard loop. Special-casing padded output would be more
- * efficient.
- */
- expand_right_edge(input_data - 1, cinfo->max_v_samp_factor + 2,
- cinfo->image_width, output_cols * 2);
-
- /* We don't bother to form the individual "smoothed" input pixel values;
- * we can directly compute the output which is the average of the four
- * smoothed values. Each of the four member pixels contributes a fraction
- * (1-8*SF) to its own smoothed image and a fraction SF to each of the three
- * other smoothed pixels, therefore a total fraction (1-5*SF)/4 to the final
- * output. The four corner-adjacent neighbor pixels contribute a fraction
- * SF to just one smoothed pixel, or SF/4 to the final output; while the
- * eight edge-adjacent neighbors contribute SF to each of two smoothed
- * pixels, or SF/2 overall. In order to use integer arithmetic, these
- * factors are scaled by 2^16 = 65536.
- * Also recall that SF = smoothing_factor / 1024.
- */
-
- memberscale = 16384 - cinfo->smoothing_factor * 80; /* scaled (1-5*SF)/4 */
- neighscale = cinfo->smoothing_factor * 16; /* scaled SF/4 */
-
- inrow = 0;
- for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) {
- outptr = output_data[outrow];
- inptr0 = input_data[inrow];
- inptr1 = input_data[inrow+1];
- above_ptr = input_data[inrow-1];
- below_ptr = input_data[inrow+2];
-
- /* Special case for first column: pretend column -1 is same as column 0 */
- membersum = GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) +
- GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1]);
- neighsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[1]) +
- GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[1]) +
- GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[2]) +
- GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[2]);
- neighsum += neighsum;
- neighsum += GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[2]) +
- GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[2]);
- membersum = membersum * memberscale + neighsum * neighscale;
- *outptr++ = (JSAMPLE) ((membersum + 32768) >> 16);
- inptr0 += 2; inptr1 += 2; above_ptr += 2; below_ptr += 2;
-
- for (colctr = output_cols - 2; colctr > 0; colctr--) {
- /* sum of pixels directly mapped to this output element */
- membersum = GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) +
- GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1]);
- /* sum of edge-neighbor pixels */
- neighsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[1]) +
- GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[1]) +
- GETJSAMPLE(inptr0[-1]) + GETJSAMPLE(inptr0[2]) +
- GETJSAMPLE(inptr1[-1]) + GETJSAMPLE(inptr1[2]);
- /* The edge-neighbors count twice as much as corner-neighbors */
- neighsum += neighsum;
- /* Add in the corner-neighbors */
- neighsum += GETJSAMPLE(above_ptr[-1]) + GETJSAMPLE(above_ptr[2]) +
- GETJSAMPLE(below_ptr[-1]) + GETJSAMPLE(below_ptr[2]);
- /* form final output scaled up by 2^16 */
- membersum = membersum * memberscale + neighsum * neighscale;
- /* round, descale and output it */
- *outptr++ = (JSAMPLE) ((membersum + 32768) >> 16);
- inptr0 += 2; inptr1 += 2; above_ptr += 2; below_ptr += 2;
- }
-
- /* Special case for last column */
- membersum = GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) +
- GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1]);
- neighsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[1]) +
- GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[1]) +
- GETJSAMPLE(inptr0[-1]) + GETJSAMPLE(inptr0[1]) +
- GETJSAMPLE(inptr1[-1]) + GETJSAMPLE(inptr1[1]);
- neighsum += neighsum;
- neighsum += GETJSAMPLE(above_ptr[-1]) + GETJSAMPLE(above_ptr[1]) +
- GETJSAMPLE(below_ptr[-1]) + GETJSAMPLE(below_ptr[1]);
- membersum = membersum * memberscale + neighsum * neighscale;
- *outptr = (JSAMPLE) ((membersum + 32768) >> 16);
-
- inrow += 2;
- }
- }
-
- /*
- * Downsample pixel values of a single component.
- * This version handles the special case of a full-size component,
- * with smoothing. One row of context is required.
- */
-
- METHODDEF(void)
- fullsize_smooth_downsample (j_compress_ptr cinfo, jpeg_component_info *compptr,
- JSAMPARRAY input_data, JSAMPARRAY output_data)
- {
- int outrow;
- JDIMENSION colctr;
- JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE;
- register JSAMPROW inptr, above_ptr, below_ptr, outptr;
- INT32 membersum, neighsum, memberscale, neighscale;
- int colsum, lastcolsum, nextcolsum;
-
- /* Expand input data enough to let all the output samples be generated
- * by the standard loop. Special-casing padded output would be more
- * efficient.
- */
- expand_right_edge(input_data - 1, cinfo->max_v_samp_factor + 2,
- cinfo->image_width, output_cols);
-
- /* Each of the eight neighbor pixels contributes a fraction SF to the
- * smoothed pixel, while the main pixel contributes (1-8*SF). In order
- * to use integer arithmetic, these factors are multiplied by 2^16 = 65536.
- * Also recall that SF = smoothing_factor / 1024.
- */
-
- memberscale = 65536L - cinfo->smoothing_factor * 512L; /* scaled 1-8*SF */
- neighscale = cinfo->smoothing_factor * 64; /* scaled SF */
-
- for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) {
- outptr = output_data[outrow];
- inptr = input_data[outrow];
- above_ptr = input_data[outrow-1];
- below_ptr = input_data[outrow+1];
-
- /* Special case for first column */
- colsum = GETJSAMPLE(*above_ptr++) + GETJSAMPLE(*below_ptr++) +
- GETJSAMPLE(*inptr);
- membersum = GETJSAMPLE(*inptr++);
- nextcolsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(*below_ptr) +
- GETJSAMPLE(*inptr);
- neighsum = colsum + (colsum - membersum) + nextcolsum;
- membersum = membersum * memberscale + neighsum * neighscale;
- *outptr++ = (JSAMPLE) ((membersum + 32768) >> 16);
- lastcolsum = colsum; colsum = nextcolsum;
-
- for (colctr = output_cols - 2; colctr > 0; colctr--) {
- membersum = GETJSAMPLE(*inptr++);
- above_ptr++; below_ptr++;
- nextcolsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(*below_ptr) +
- GETJSAMPLE(*inptr);
- neighsum = lastcolsum + (colsum - membersum) + nextcolsum;
- membersum = membersum * memberscale + neighsum * neighscale;
- *outptr++ = (JSAMPLE) ((membersum + 32768) >> 16);
- lastcolsum = colsum; colsum = nextcolsum;
- }
-
- /* Special case for last column */
- membersum = GETJSAMPLE(*inptr);
- neighsum = lastcolsum + (colsum - membersum) + colsum;
- membersum = membersum * memberscale + neighsum * neighscale;
- *outptr = (JSAMPLE) ((membersum + 32768) >> 16);
-
- }
- }
-
- #endif /* INPUT_SMOOTHING_SUPPORTED */
-
- /*
- * Module initialization routine for downsampling.
- * Note that we must select a routine for each component.
- */
-
- GLOBAL(void)
- jinit_downsampler (j_compress_ptr cinfo)
- {
- my_downsample_ptr downsample;
- int ci;
- jpeg_component_info * compptr;
- boolean smoothok = TRUE;
-
- downsample = (my_downsample_ptr)
- (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
- SIZEOF(my_downsampler));
- cinfo->downsample = (struct jpeg_downsampler *) downsample;
- downsample->pub.start_pass = start_pass_downsample;
- downsample->pub.downsample = sep_downsample;
- downsample->pub.need_context_rows = FALSE;
-
- if (cinfo->CCIR601_sampling)
- ERREXIT(cinfo, JERR_CCIR601_NOTIMPL);
-
- /* Verify we can handle the sampling factors, and set up method pointers */
- for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
- ci++, compptr++) {
- if (compptr->h_samp_factor == cinfo->max_h_samp_factor &&
- compptr->v_samp_factor == cinfo->max_v_samp_factor) {
- #ifdef INPUT_SMOOTHING_SUPPORTED
- if (cinfo->smoothing_factor) {
- downsample->methods[ci] = fullsize_smooth_downsample;
- downsample->pub.need_context_rows = TRUE;
- } else
- #endif
- downsample->methods[ci] = fullsize_downsample;
- } else if (compptr->h_samp_factor * 2 == cinfo->max_h_samp_factor &&
- compptr->v_samp_factor == cinfo->max_v_samp_factor) {
- smoothok = FALSE;
- downsample->methods[ci] = h2v1_downsample;
- } else if (compptr->h_samp_factor * 2 == cinfo->max_h_samp_factor &&
- compptr->v_samp_factor * 2 == cinfo->max_v_samp_factor) {
- #ifdef INPUT_SMOOTHING_SUPPORTED
- if (cinfo->smoothing_factor) {
- downsample->methods[ci] = h2v2_smooth_downsample;
- downsample->pub.need_context_rows = TRUE;
- } else
- #endif
- downsample->methods[ci] = h2v2_downsample;
- } else if ((cinfo->max_h_samp_factor % compptr->h_samp_factor) == 0 &&
- (cinfo->max_v_samp_factor % compptr->v_samp_factor) == 0) {
- smoothok = FALSE;
- downsample->methods[ci] = int_downsample;
- } else
- ERREXIT(cinfo, JERR_FRACT_SAMPLE_NOTIMPL);
- }
-
- #ifdef INPUT_SMOOTHING_SUPPORTED
- if (cinfo->smoothing_factor && !smoothok)
- TRACEMS(cinfo, 0, JTRC_SMOOTH_NOTIMPL);
- #endif
- }
- /********* End of inlined file: jcsample.c *********/
-
- /********* Start of inlined file: jctrans.c *********/
- #define JPEG_INTERNALS
-
- /* Forward declarations */
- LOCAL(void) transencode_master_selection
- JPP((j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays));
- LOCAL(void) transencode_coef_controller
- JPP((j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays));
-
- /*
- * Compression initialization for writing raw-coefficient data.
- * Before calling this, all parameters and a data destination must be set up.
- * Call jpeg_finish_compress() to actually write the data.
- *
- * The number of passed virtual arrays must match cinfo->num_components.
- * Note that the virtual arrays need not be filled or even realized at
- * the time write_coefficients is called; indeed, if the virtual arrays
- * were requested from this compression object's memory manager, they
- * typically will be realized during this routine and filled afterwards.
- */
-
- GLOBAL(void)
- jpeg_write_coefficients (j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays)
- {
- if (cinfo->global_state != CSTATE_START)
- ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
- /* Mark all tables to be written */
- jpeg_suppress_tables(cinfo, FALSE);
- /* (Re)initialize error mgr and destination modules */
- (*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo);
- (*cinfo->dest->init_destination) (cinfo);
- /* Perform master selection of active modules */
- transencode_master_selection(cinfo, coef_arrays);
- /* Wait for jpeg_finish_compress() call */
- cinfo->next_scanline = 0; /* so jpeg_write_marker works */
- cinfo->global_state = CSTATE_WRCOEFS;
- }
-
- /*
- * Initialize the compression object with default parameters,
- * then copy from the source object all parameters needed for lossless
- * transcoding. Parameters that can be varied without loss (such as
- * scan script and Huffman optimization) are left in their default states.
- */
-
- GLOBAL(void)
- jpeg_copy_critical_parameters (j_decompress_ptr srcinfo,
- j_compress_ptr dstinfo)
- {
- JQUANT_TBL ** qtblptr;
- jpeg_component_info *incomp, *outcomp;
- JQUANT_TBL *c_quant, *slot_quant;
- int tblno, ci, coefi;
-
- /* Safety check to ensure start_compress not called yet. */
- if (dstinfo->global_state != CSTATE_START)
- ERREXIT1(dstinfo, JERR_BAD_STATE, dstinfo->global_state);
- /* Copy fundamental image dimensions */
- dstinfo->image_width = srcinfo->image_width;
- dstinfo->image_height = srcinfo->image_height;
- dstinfo->input_components = srcinfo->num_components;
- dstinfo->in_color_space = srcinfo->jpeg_color_space;
- /* Initialize all parameters to default values */
- jpeg_set_defaults(dstinfo);
- /* jpeg_set_defaults may choose wrong colorspace, eg YCbCr if input is RGB.
- * Fix it to get the right header markers for the image colorspace.
- */
- jpeg_set_colorspace(dstinfo, srcinfo->jpeg_color_space);
- dstinfo->data_precision = srcinfo->data_precision;
- dstinfo->CCIR601_sampling = srcinfo->CCIR601_sampling;
- /* Copy the source's quantization tables. */
- for (tblno = 0; tblno < NUM_QUANT_TBLS; tblno++) {
- if (srcinfo->quant_tbl_ptrs[tblno] != NULL) {
- qtblptr = & dstinfo->quant_tbl_ptrs[tblno];
- if (*qtblptr == NULL)
- *qtblptr = jpeg_alloc_quant_table((j_common_ptr) dstinfo);
- MEMCOPY((*qtblptr)->quantval,
- srcinfo->quant_tbl_ptrs[tblno]->quantval,
- SIZEOF((*qtblptr)->quantval));
- (*qtblptr)->sent_table = FALSE;
- }
- }
- /* Copy the source's per-component info.
- * Note we assume jpeg_set_defaults has allocated the dest comp_info array.
- */
- dstinfo->num_components = srcinfo->num_components;
- if (dstinfo->num_components < 1 || dstinfo->num_components > MAX_COMPONENTS)
- ERREXIT2(dstinfo, JERR_COMPONENT_COUNT, dstinfo->num_components,
- MAX_COMPONENTS);
- for (ci = 0, incomp = srcinfo->comp_info, outcomp = dstinfo->comp_info;
- ci < dstinfo->num_components; ci++, incomp++, outcomp++) {
- outcomp->component_id = incomp->component_id;
- outcomp->h_samp_factor = incomp->h_samp_factor;
- outcomp->v_samp_factor = incomp->v_samp_factor;
- outcomp->quant_tbl_no = incomp->quant_tbl_no;
- /* Make sure saved quantization table for component matches the qtable
- * slot. If not, the input file re-used this qtable slot.
- * IJG encoder currently cannot duplicate this.
- */
- tblno = outcomp->quant_tbl_no;
- if (tblno < 0 || tblno >= NUM_QUANT_TBLS ||
- srcinfo->quant_tbl_ptrs[tblno] == NULL)
- ERREXIT1(dstinfo, JERR_NO_QUANT_TABLE, tblno);
- slot_quant = srcinfo->quant_tbl_ptrs[tblno];
- c_quant = incomp->quant_table;
- if (c_quant != NULL) {
- for (coefi = 0; coefi < DCTSIZE2; coefi++) {
- if (c_quant->quantval[coefi] != slot_quant->quantval[coefi])
- ERREXIT1(dstinfo, JERR_MISMATCHED_QUANT_TABLE, tblno);
- }
- }
- /* Note: we do not copy the source's Huffman table assignments;
- * instead we rely on jpeg_set_colorspace to have made a suitable choice.
- */
- }
- /* Also copy JFIF version and resolution information, if available.
- * Strictly speaking this isn't "critical" info, but it's nearly
- * always appropriate to copy it if available. In particular,
- * if the application chooses to copy JFIF 1.02 extension markers from
- * the source file, we need to copy the version to make sure we don't
- * emit a file that has 1.02 extensions but a claimed version of 1.01.
- * We will *not*, however, copy version info from mislabeled "2.01" files.
- */
- if (srcinfo->saw_JFIF_marker) {
- if (srcinfo->JFIF_major_version == 1) {
- dstinfo->JFIF_major_version = srcinfo->JFIF_major_version;
- dstinfo->JFIF_minor_version = srcinfo->JFIF_minor_version;
- }
- dstinfo->density_unit = srcinfo->density_unit;
- dstinfo->X_density = srcinfo->X_density;
- dstinfo->Y_density = srcinfo->Y_density;
- }
- }
-
- /*
- * Master selection of compression modules for transcoding.
- * This substitutes for jcinit.c's initialization of the full compressor.
- */
-
- LOCAL(void)
- transencode_master_selection (j_compress_ptr cinfo,
- jvirt_barray_ptr * coef_arrays)
- {
- /* Although we don't actually use input_components for transcoding,
- * jcmaster.c's initial_setup will complain if input_components is 0.
- */
- cinfo->input_components = 1;
- /* Initialize master control (includes parameter checking/processing) */
- jinit_c_master_control(cinfo, TRUE /* transcode only */);
-
- /* Entropy encoding: either Huffman or arithmetic coding. */
- if (cinfo->arith_code) {
- ERREXIT(cinfo, JERR_ARITH_NOTIMPL);
- } else {
- if (cinfo->progressive_mode) {
- #ifdef C_PROGRESSIVE_SUPPORTED
- jinit_phuff_encoder(cinfo);
- #else
- ERREXIT(cinfo, JERR_NOT_COMPILED);
- #endif
- } else
- jinit_huff_encoder(cinfo);
- }
-
- /* We need a special coefficient buffer controller. */
- transencode_coef_controller(cinfo, coef_arrays);
-
- jinit_marker_writer(cinfo);
-
- /* We can now tell the memory manager to allocate virtual arrays. */
- (*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo);
-
- /* Write the datastream header (SOI, JFIF) immediately.
- * Frame and scan headers are postponed till later.
- * This lets application insert special markers after the SOI.
- */
- (*cinfo->marker->write_file_header) (cinfo);
- }
-
- /*
- * The rest of this file is a special implementation of the coefficient
- * buffer controller. This is similar to jccoefct.c, but it handles only
- * output from presupplied virtual arrays. Furthermore, we generate any
- * dummy padding blocks on-the-fly rather than expecting them to be present
- * in the arrays.
- */
-
- /* Private buffer controller object */
-
- typedef struct {
- struct jpeg_c_coef_controller pub; /* public fields */
-
- JDIMENSION iMCU_row_num; /* iMCU row # within image */
- JDIMENSION mcu_ctr; /* counts MCUs processed in current row */
- int MCU_vert_offset; /* counts MCU rows within iMCU row */
- int MCU_rows_per_iMCU_row; /* number of such rows needed */
-
- /* Virtual block array for each component. */
- jvirt_barray_ptr * whole_image;
-
- /* Workspace for constructing dummy blocks at right/bottom edges. */
- JBLOCKROW dummy_buffer[C_MAX_BLOCKS_IN_MCU];
- } my_coef_controller2;
-
- typedef my_coef_controller2 * my_coef_ptr2;
-
- LOCAL(void)
- start_iMCU_row2 (j_compress_ptr cinfo)
- /* Reset within-iMCU-row counters for a new row */
- {
- my_coef_ptr2 coef = (my_coef_ptr2) cinfo->coef;
-
- /* In an interleaved scan, an MCU row is the same as an iMCU row.
- * In a noninterleaved scan, an iMCU row has v_samp_factor MCU rows.
- * But at the bottom of the image, process only what's left.
- */
- if (cinfo->comps_in_scan > 1) {
- coef->MCU_rows_per_iMCU_row = 1;
- } else {
- if (coef->iMCU_row_num < (cinfo->total_iMCU_rows-1))
- coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->v_samp_factor;
- else
- coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->last_row_height;
- }
-
- coef->mcu_ctr = 0;
- coef->MCU_vert_offset = 0;
- }
-
- /*
- * Initialize for a processing pass.
- */
-
- METHODDEF(void)
- start_pass_coef2 (j_compress_ptr cinfo, J_BUF_MODE pass_mode)
- {
- my_coef_ptr2 coef = (my_coef_ptr2) cinfo->coef;
-
- if (pass_mode != JBUF_CRANK_DEST)
- ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
-
- coef->iMCU_row_num = 0;
- start_iMCU_row2(cinfo);
- }
-
- /*
- * Process some data.
- * We process the equivalent of one fully interleaved MCU row ("iMCU" row)
- * per call, ie, v_samp_factor block rows for each component in the scan.
- * The data is obtained from the virtual arrays and fed to the entropy coder.
- * Returns TRUE if the iMCU row is completed, FALSE if suspended.
- *
- * NB: input_buf is ignored; it is likely to be a NULL pointer.
- */
-
- METHODDEF(boolean)
- compress_output2 (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
- {
- my_coef_ptr2 coef = (my_coef_ptr2) cinfo->coef;
- JDIMENSION MCU_col_num; /* index of current MCU within row */
- JDIMENSION last_MCU_col = cinfo->MCUs_per_row - 1;
- JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
- int blkn, ci, xindex, yindex, yoffset, blockcnt;
- JDIMENSION start_col;
- JBLOCKARRAY buffer[MAX_COMPS_IN_SCAN];
- JBLOCKROW MCU_buffer[C_MAX_BLOCKS_IN_MCU];
- JBLOCKROW buffer_ptr;
- jpeg_component_info *compptr;
-
- /* Align the virtual buffers for the components used in this scan. */
- for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
- compptr = cinfo->cur_comp_info[ci];
- buffer[ci] = (*cinfo->mem->access_virt_barray)
- ((j_common_ptr) cinfo, coef->whole_image[compptr->component_index],
- coef->iMCU_row_num * compptr->v_samp_factor,
- (JDIMENSION) compptr->v_samp_factor, FALSE);
- }
-
- /* Loop to process one whole iMCU row */
- for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row;
- yoffset++) {
- for (MCU_col_num = coef->mcu_ctr; MCU_col_num < cinfo->MCUs_per_row;
- MCU_col_num++) {
- /* Construct list of pointers to DCT blocks belonging to this MCU */
- blkn = 0; /* index of current DCT block within MCU */
- for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
- compptr = cinfo->cur_comp_info[ci];
- start_col = MCU_col_num * compptr->MCU_width;
- blockcnt = (MCU_col_num < last_MCU_col) ? compptr->MCU_width
- : compptr->last_col_width;
- for (yindex = 0; yindex < compptr->MCU_height; yindex++) {
- if (coef->iMCU_row_num < last_iMCU_row ||
- yindex+yoffset < compptr->last_row_height) {
- /* Fill in pointers to real blocks in this row */
- buffer_ptr = buffer[ci][yindex+yoffset] + start_col;
- for (xindex = 0; xindex < blockcnt; xindex++)
- MCU_buffer[blkn++] = buffer_ptr++;
- } else {
- /* At bottom of image, need a whole row of dummy blocks */
- xindex = 0;
- }
- /* Fill in any dummy blocks needed in this row.
- * Dummy blocks are filled in the same way as in jccoefct.c:
- * all zeroes in the AC entries, DC entries equal to previous
- * block's DC value. The init routine has already zeroed the
- * AC entries, so we need only set the DC entries correctly.
- */
- for (; xindex < compptr->MCU_width; xindex++) {
- MCU_buffer[blkn] = coef->dummy_buffer[blkn];
- MCU_buffer[blkn][0][0] = MCU_buffer[blkn-1][0][0];
- blkn++;
- }
- }
- }
- /* Try to write the MCU. */
- if (! (*cinfo->entropy->encode_mcu) (cinfo, MCU_buffer)) {
- /* Suspension forced; update state counters and exit */
- coef->MCU_vert_offset = yoffset;
- coef->mcu_ctr = MCU_col_num;
- return FALSE;
- }
- }
- /* Completed an MCU row, but perhaps not an iMCU row */
- coef->mcu_ctr = 0;
- }
- /* Completed the iMCU row, advance counters for next one */
- coef->iMCU_row_num++;
- start_iMCU_row2(cinfo);
- return TRUE;
- }
-
- /*
- * Initialize coefficient buffer controller.
- *
- * Each passed coefficient array must be the right size for that
- * coefficient: width_in_blocks wide and height_in_blocks high,
- * with unitheight at least v_samp_factor.
- */
-
- LOCAL(void)
- transencode_coef_controller (j_compress_ptr cinfo,
- jvirt_barray_ptr * coef_arrays)
- {
- my_coef_ptr2 coef;
- JBLOCKROW buffer;
- int i;
-
- coef = (my_coef_ptr2)
- (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
- SIZEOF(my_coef_controller2));
- cinfo->coef = (struct jpeg_c_coef_controller *) coef;
- coef->pub.start_pass = start_pass_coef2;
- coef->pub.compress_data = compress_output2;
-
- /* Save pointer to virtual arrays */
- coef->whole_image = coef_arrays;
-
- /* Allocate and pre-zero space for dummy DCT blocks. */
- buffer = (JBLOCKROW)
- (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
- C_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK));
- jzero_far((void FAR *) buffer, C_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK));
- for (i = 0; i < C_MAX_BLOCKS_IN_MCU; i++) {
- coef->dummy_buffer[i] = buffer + i;
- }
- }
- /********* End of inlined file: jctrans.c *********/
-
- /********* Start of inlined file: jdapistd.c *********/
- #define JPEG_INTERNALS
-
- /* Forward declarations */
- LOCAL(boolean) output_pass_setup JPP((j_decompress_ptr cinfo));
-
- /*
- * Decompression initialization.
- * jpeg_read_header must be completed before calling this.
- *
- * If a multipass operating mode was selected, this will do all but the
- * last pass, and thus may take a great deal of time.
- *
- * Returns FALSE if suspended. The return value need be inspected only if
- * a suspending data source is used.
- */
-
- GLOBAL(boolean)
- jpeg_start_decompress (j_decompress_ptr cinfo)
- {
- if (cinfo->global_state == DSTATE_READY) {
- /* First call: initialize master control, select active modules */
- jinit_master_decompress(cinfo);
- if (cinfo->buffered_image) {
- /* No more work here; expecting jpeg_start_output next */
- cinfo->global_state = DSTATE_BUFIMAGE;
- return TRUE;
- }
- cinfo->global_state = DSTATE_PRELOAD;
- }
- if (cinfo->global_state == DSTATE_PRELOAD) {
- /* If file has multiple scans, absorb them all into the coef buffer */
- if (cinfo->inputctl->has_multiple_scans) {
- #ifdef D_MULTISCAN_FILES_SUPPORTED
- for (;;) {
- int retcode;
- /* Call progress monitor hook if present */
- if (cinfo->progress != NULL)
- (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
- /* Absorb some more input */
- retcode = (*cinfo->inputctl->consume_input) (cinfo);
- if (retcode == JPEG_SUSPENDED)
- return FALSE;
- if (retcode == JPEG_REACHED_EOI)
- break;
- /* Advance progress counter if appropriate */
- if (cinfo->progress != NULL &&
- (retcode == JPEG_ROW_COMPLETED || retcode == JPEG_REACHED_SOS)) {
- if (++cinfo->progress->pass_counter >= cinfo->progress->pass_limit) {
- /* jdmaster underestimated number of scans; ratchet up one scan */
- cinfo->progress->pass_limit += (long) cinfo->total_iMCU_rows;
- }
- }
- }
- #else
- ERREXIT(cinfo, JERR_NOT_COMPILED);
- #endif /* D_MULTISCAN_FILES_SUPPORTED */
- }
- cinfo->output_scan_number = cinfo->input_scan_number;
- } else if (cinfo->global_state != DSTATE_PRESCAN)
- ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
- /* Perform any dummy output passes, and set up for the final pass */
- return output_pass_setup(cinfo);
- }
-
- /*
- * Set up for an output pass, and perform any dummy pass(es) needed.
- * Common subroutine for jpeg_start_decompress and jpeg_start_output.
- * Entry: global_state = DSTATE_PRESCAN only if previously suspended.
- * Exit: If done, returns TRUE and sets global_state for proper output mode.
- * If suspended, returns FALSE and sets global_state = DSTATE_PRESCAN.
- */
-
- LOCAL(boolean)
- output_pass_setup (j_decompress_ptr cinfo)
- {
- if (cinfo->global_state != DSTATE_PRESCAN) {
- /* First call: do pass setup */
- (*cinfo->master->prepare_for_output_pass) (cinfo);
- cinfo->output_scanline = 0;
- cinfo->global_state = DSTATE_PRESCAN;
- }
- /* Loop over any required dummy passes */
- while (cinfo->master->is_dummy_pass) {
- #ifdef QUANT_2PASS_SUPPORTED
- /* Crank through the dummy pass */
- while (cinfo->output_scanline < cinfo->output_height) {
- JDIMENSION last_scanline;
- /* Call progress monitor hook if present */
- if (cinfo->progress != NULL) {
- cinfo->progress->pass_counter = (long) cinfo->output_scanline;
- cinfo->progress->pass_limit = (long) cinfo->output_height;
- (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
- }
- /* Process some data */
- last_scanline = cinfo->output_scanline;
- (*cinfo->main->process_data) (cinfo, (JSAMPARRAY) NULL,
- &cinfo->output_scanline, (JDIMENSION) 0);
- if (cinfo->output_scanline == last_scanline)
- return FALSE; /* No progress made, must suspend */
- }
- /* Finish up dummy pass, and set up for another one */
- (*cinfo->master->finish_output_pass) (cinfo);
- (*cinfo->master->prepare_for_output_pass) (cinfo);
- cinfo->output_scanline = 0;
- #else
- ERREXIT(cinfo, JERR_NOT_COMPILED);
- #endif /* QUANT_2PASS_SUPPORTED */
- }
- /* Ready for application to drive output pass through
- * jpeg_read_scanlines or jpeg_read_raw_data.
- */
- cinfo->global_state = cinfo->raw_data_out ? DSTATE_RAW_OK : DSTATE_SCANNING;
- return TRUE;
- }
-
- /*
- * Read some scanlines of data from the JPEG decompressor.
- *
- * The return value will be the number of lines actually read.
- * This may be less than the number requested in several cases,
- * including bottom of image, data source suspension, and operating
- * modes that emit multiple scanlines at a time.
- *
- * Note: we warn about excess calls to jpeg_read_scanlines() since
- * this likely signals an application programmer error. However,
- * an oversize buffer (max_lines > scanlines remaining) is not an error.
- */
-
- GLOBAL(JDIMENSION)
- jpeg_read_scanlines (j_decompress_ptr cinfo, JSAMPARRAY scanlines,
- JDIMENSION max_lines)
- {
- JDIMENSION row_ctr;
-
- if (cinfo->global_state != DSTATE_SCANNING)
- ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
- if (cinfo->output_scanline >= cinfo->output_height) {
- WARNMS(cinfo, JWRN_TOO_MUCH_DATA);
- return 0;
- }
-
- /* Call progress monitor hook if present */
- if (cinfo->progress != NULL) {
- cinfo->progress->pass_counter = (long) cinfo->output_scanline;
- cinfo->progress->pass_limit = (long) cinfo->output_height;
- (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
- }
-
- /* Process some data */
- row_ctr = 0;
- (*cinfo->main->process_data) (cinfo, scanlines, &row_ctr, max_lines);
- cinfo->output_scanline += row_ctr;
- return row_ctr;
- }
-
- /*
- * Alternate entry point to read raw data.
- * Processes exactly one iMCU row per call, unless suspended.
- */
-
- GLOBAL(JDIMENSION)
- jpeg_read_raw_data (j_decompress_ptr cinfo, JSAMPIMAGE data,
- JDIMENSION max_lines)
- {
- JDIMENSION lines_per_iMCU_row;
-
- if (cinfo->global_state != DSTATE_RAW_OK)
- ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
- if (cinfo->output_scanline >= cinfo->output_height) {
- WARNMS(cinfo, JWRN_TOO_MUCH_DATA);
- return 0;
- }
-
- /* Call progress monitor hook if present */
- if (cinfo->progress != NULL) {
- cinfo->progress->pass_counter = (long) cinfo->output_scanline;
- cinfo->progress->pass_limit = (long) cinfo->output_height;
- (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
- }
-
- /* Verify that at least one iMCU row can be returned. */
- lines_per_iMCU_row = cinfo->max_v_samp_factor * cinfo->min_DCT_scaled_size;
- if (max_lines < lines_per_iMCU_row)
- ERREXIT(cinfo, JERR_BUFFER_SIZE);
-
- /* Decompress directly into user's buffer. */
- if (! (*cinfo->coef->decompress_data) (cinfo, data))
- return 0; /* suspension forced, can do nothing more */
-
- /* OK, we processed one iMCU row. */
- cinfo->output_scanline += lines_per_iMCU_row;
- return lines_per_iMCU_row;
- }
-
- /* Additional entry points for buffered-image mode. */
-
- #ifdef D_MULTISCAN_FILES_SUPPORTED
-
- /*
- * Initialize for an output pass in buffered-image mode.
- */
-
- GLOBAL(boolean)
- jpeg_start_output (j_decompress_ptr cinfo, int scan_number)
- {
- if (cinfo->global_state != DSTATE_BUFIMAGE &&
- cinfo->global_state != DSTATE_PRESCAN)
- ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
- /* Limit scan number to valid range */
- if (scan_number <= 0)
- scan_number = 1;
- if (cinfo->inputctl->eoi_reached &&
- scan_number > cinfo->input_scan_number)
- scan_number = cinfo->input_scan_number;
- cinfo->output_scan_number = scan_number;
- /* Perform any dummy output passes, and set up for the real pass */
- return output_pass_setup(cinfo);
- }
-
- /*
- * Finish up after an output pass in buffered-image mode.
- *
- * Returns FALSE if suspended. The return value need be inspected only if
- * a suspending data source is used.
- */
-
- GLOBAL(boolean)
- jpeg_finish_output (j_decompress_ptr cinfo)
- {
- if ((cinfo->global_state == DSTATE_SCANNING ||
- cinfo->global_state == DSTATE_RAW_OK) && cinfo->buffered_image) {
- /* Terminate this pass. */
- /* We do not require the whole pass to have been completed. */
- (*cinfo->master->finish_output_pass) (cinfo);
- cinfo->global_state = DSTATE_BUFPOST;
- } else if (cinfo->global_state != DSTATE_BUFPOST) {
- /* BUFPOST = repeat call after a suspension, anything else is error */
- ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
- }
- /* Read markers looking for SOS or EOI */
- while (cinfo->input_scan_number <= cinfo->output_scan_number &&
- ! cinfo->inputctl->eoi_reached) {
- if ((*cinfo->inputctl->consume_input) (cinfo) == JPEG_SUSPENDED)
- return FALSE; /* Suspend, come back later */
- }
- cinfo->global_state = DSTATE_BUFIMAGE;
- return TRUE;
- }
-
- #endif /* D_MULTISCAN_FILES_SUPPORTED */
- /********* End of inlined file: jdapistd.c *********/
-
- /********* Start of inlined file: jdapimin.c *********/
- #define JPEG_INTERNALS
-
- /*
- * Initialization of a JPEG decompression object.
- * The error manager must already be set up (in case memory manager fails).
- */
-
- GLOBAL(void)
- jpeg_CreateDecompress (j_decompress_ptr cinfo, int version, size_t structsize)
- {
- int i;
-
- /* Guard against version mismatches between library and caller. */
- cinfo->mem = NULL; /* so jpeg_destroy knows mem mgr not called */
- if (version != JPEG_LIB_VERSION)
- ERREXIT2(cinfo, JERR_BAD_LIB_VERSION, JPEG_LIB_VERSION, version);
- if (structsize != SIZEOF(struct jpeg_decompress_struct))
- ERREXIT2(cinfo, JERR_BAD_STRUCT_SIZE,
- (int) SIZEOF(struct jpeg_decompress_struct), (int) structsize);
-
- /* For debugging purposes, we zero the whole master structure.
- * But the application has already set the err pointer, and may have set
- * client_data, so we have to save and restore those fields.
- * Note: if application hasn't set client_data, tools like Purify may
- * complain here.
- */
- {
- struct jpeg_error_mgr * err = cinfo->err;
- void * client_data = cinfo->client_data; /* ignore Purify complaint here */
- MEMZERO(cinfo, SIZEOF(struct jpeg_decompress_struct));
- cinfo->err = err;
- cinfo->client_data = client_data;
- }
- cinfo->is_decompressor = TRUE;
-
- /* Initialize a memory manager instance for this object */
- jinit_memory_mgr((j_common_ptr) cinfo);
-
- /* Zero out pointers to permanent structures. */
- cinfo->progress = NULL;
- cinfo->src = NULL;
-
- for (i = 0; i < NUM_QUANT_TBLS; i++)
- cinfo->quant_tbl_ptrs[i] = NULL;
-
- for (i = 0; i < NUM_HUFF_TBLS; i++) {
- cinfo->dc_huff_tbl_ptrs[i] = NULL;
- cinfo->ac_huff_tbl_ptrs[i] = NULL;
- }
-
- /* Initialize marker processor so application can override methods
- * for COM, APPn markers before calling jpeg_read_header.
- */
- cinfo->marker_list = NULL;
- jinit_marker_reader(cinfo);
-
- /* And initialize the overall input controller. */
- jinit_input_controller(cinfo);
-
- /* OK, I'm ready */
- cinfo->global_state = DSTATE_START;
- }
-
- /*
- * Destruction of a JPEG decompression object
- */
-
- GLOBAL(void)
- jpeg_destroy_decompress (j_decompress_ptr cinfo)
- {
- jpeg_destroy((j_common_ptr) cinfo); /* use common routine */
- }
-
- /*
- * Abort processing of a JPEG decompression operation,
- * but don't destroy the object itself.
- */
-
- GLOBAL(void)
- jpeg_abort_decompress (j_decompress_ptr cinfo)
- {
- jpeg_abort((j_common_ptr) cinfo); /* use common routine */
- }
-
- /*
- * Set default decompression parameters.
- */
-
- LOCAL(void)
- default_decompress_parms (j_decompress_ptr cinfo)
- {
- /* Guess the input colorspace, and set output colorspace accordingly. */
- /* (Wish JPEG committee had provided a real way to specify this...) */
- /* Note application may override our guesses. */
- switch (cinfo->num_components) {
- case 1:
- cinfo->jpeg_color_space = JCS_GRAYSCALE;
- cinfo->out_color_space = JCS_GRAYSCALE;
- break;
-
- case 3:
- if (cinfo->saw_JFIF_marker) {
- cinfo->jpeg_color_space = JCS_YCbCr; /* JFIF implies YCbCr */
- } else if (cinfo->saw_Adobe_marker) {
- switch (cinfo->Adobe_transform) {
- case 0:
- cinfo->jpeg_color_space = JCS_RGB;
- break;
- case 1:
- cinfo->jpeg_color_space = JCS_YCbCr;
- break;
- default:
- WARNMS1(cinfo, JWRN_ADOBE_XFORM, cinfo->Adobe_transform);
- cinfo->jpeg_color_space = JCS_YCbCr; /* assume it's YCbCr */
- break;
- }
- } else {
- /* Saw no special markers, try to guess from the component IDs */
- int cid0 = cinfo->comp_info[0].component_id;
- int cid1 = cinfo->comp_info[1].component_id;
- int cid2 = cinfo->comp_info[2].component_id;
-
- if (cid0 == 1 && cid1 == 2 && cid2 == 3)
- cinfo->jpeg_color_space = JCS_YCbCr; /* assume JFIF w/out marker */
- else if (cid0 == 82 && cid1 == 71 && cid2 == 66)
- cinfo->jpeg_color_space = JCS_RGB; /* ASCII 'R', 'G', 'B' */
- else {
- TRACEMS3(cinfo, 1, JTRC_UNKNOWN_IDS, cid0, cid1, cid2);
- cinfo->jpeg_color_space = JCS_YCbCr; /* assume it's YCbCr */
- }
- }
- /* Always guess RGB is proper output colorspace. */
- cinfo->out_color_space = JCS_RGB;
- break;
-
- case 4:
- if (cinfo->saw_Adobe_marker) {
- switch (cinfo->Adobe_transform) {
- case 0:
- cinfo->jpeg_color_space = JCS_CMYK;
- break;
- case 2:
- cinfo->jpeg_color_space = JCS_YCCK;
- break;
- default:
- WARNMS1(cinfo, JWRN_ADOBE_XFORM, cinfo->Adobe_transform);
- cinfo->jpeg_color_space = JCS_YCCK; /* assume it's YCCK */
- break;
- }
- } else {
- /* No special markers, assume straight CMYK. */
- cinfo->jpeg_color_space = JCS_CMYK;
- }
- cinfo->out_color_space = JCS_CMYK;
- break;
-
- default:
- cinfo->jpeg_color_space = JCS_UNKNOWN;
- cinfo->out_color_space = JCS_UNKNOWN;
- break;
- }
-
- /* Set defaults for other decompression parameters. */
- cinfo->scale_num = 1; /* 1:1 scaling */
- cinfo->scale_denom = 1;
- cinfo->output_gamma = 1.0;
- cinfo->buffered_image = FALSE;
- cinfo->raw_data_out = FALSE;
- cinfo->dct_method = JDCT_DEFAULT;
- cinfo->do_fancy_upsampling = TRUE;
- cinfo->do_block_smoothing = TRUE;
- cinfo->quantize_colors = FALSE;
- /* We set these in case application only sets quantize_colors. */
- cinfo->dither_mode = JDITHER_FS;
- #ifdef QUANT_2PASS_SUPPORTED
- cinfo->two_pass_quantize = TRUE;
- #else
- cinfo->two_pass_quantize = FALSE;
- #endif
- cinfo->desired_number_of_colors = 256;
- cinfo->colormap = NULL;
- /* Initialize for no mode change in buffered-image mode. */
- cinfo->enable_1pass_quant = FALSE;
- cinfo->enable_external_quant = FALSE;
- cinfo->enable_2pass_quant = FALSE;
- }
-
- /*
- * Decompression startup: read start of JPEG datastream to see what's there.
- * Need only initialize JPEG object and supply a data source before calling.
- *
- * This routine will read as far as the first SOS marker (ie, actual start of
- * compressed data), and will save all tables and parameters in the JPEG
- * object. It will also initialize the decompression parameters to default
- * values, and finally return JPEG_HEADER_OK. On return, the application may
- * adjust the decompression parameters and then call jpeg_start_decompress.
- * (Or, if the application only wanted to determine the image parameters,
- * the data need not be decompressed. In that case, call jpeg_abort or
- * jpeg_destroy to release any temporary space.)
- * If an abbreviated (tables only) datastream is presented, the routine will
- * return JPEG_HEADER_TABLES_ONLY upon reaching EOI. The application may then
- * re-use the JPEG object to read the abbreviated image datastream(s).
- * It is unnecessary (but OK) to call jpeg_abort in this case.
- * The JPEG_SUSPENDED return code only occurs if the data source module
- * requests suspension of the decompressor. In this case the application
- * should load more source data and then re-call jpeg_read_header to resume
- * processing.
- * If a non-suspending data source is used and require_image is TRUE, then the
- * return code need not be inspected since only JPEG_HEADER_OK is possible.
- *
- * This routine is now just a front end to jpeg_consume_input, with some
- * extra error checking.
- */
-
- GLOBAL(int)
- jpeg_read_header (j_decompress_ptr cinfo, boolean require_image)
- {
- int retcode;
-
- if (cinfo->global_state != DSTATE_START &&
- cinfo->global_state != DSTATE_INHEADER)
- ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
-
- retcode = jpeg_consume_input(cinfo);
-
- switch (retcode) {
- case JPEG_REACHED_SOS:
- retcode = JPEG_HEADER_OK;
- break;
- case JPEG_REACHED_EOI:
- if (require_image) /* Complain if application wanted an image */
- ERREXIT(cinfo, JERR_NO_IMAGE);
- /* Reset to start state; it would be safer to require the application to
- * call jpeg_abort, but we can't change it now for compatibility reasons.
- * A side effect is to free any temporary memory (there shouldn't be any).
- */
- jpeg_abort((j_common_ptr) cinfo); /* sets state = DSTATE_START */
- retcode = JPEG_HEADER_TABLES_ONLY;
- break;
- case JPEG_SUSPENDED:
- /* no work */
- break;
- }
-
- return retcode;
- }
-
- /*
- * Consume data in advance of what the decompressor requires.
- * This can be called at any time once the decompressor object has
- * been created and a data source has been set up.
- *
- * This routine is essentially a state machine that handles a couple
- * of critical state-transition actions, namely initial setup and
- * transition from header scanning to ready-for-start_decompress.
- * All the actual input is done via the input controller's consume_input
- * method.
- */
-
- GLOBAL(int)
- jpeg_consume_input (j_decompress_ptr cinfo)
- {
- int retcode = JPEG_SUSPENDED;
-
- /* NB: every possible DSTATE value should be listed in this switch */
- switch (cinfo->global_state) {
- case DSTATE_START:
- /* Start-of-datastream actions: reset appropriate modules */
- (*cinfo->inputctl->reset_input_controller) (cinfo);
- /* Initialize application's data source module */
- (*cinfo->src->init_source) (cinfo);
- cinfo->global_state = DSTATE_INHEADER;
- /*FALLTHROUGH*/
- case DSTATE_INHEADER:
- retcode = (*cinfo->inputctl->consume_input) (cinfo);
- if (retcode == JPEG_REACHED_SOS) { /* Found SOS, prepare to decompress */
- /* Set up default parameters based on header data */
- default_decompress_parms(cinfo);
- /* Set global state: ready for start_decompress */
- cinfo->global_state = DSTATE_READY;
- }
- break;
- case DSTATE_READY:
- /* Can't advance past first SOS until start_decompress is called */
- retcode = JPEG_REACHED_SOS;
- break;
- case DSTATE_PRELOAD:
- case DSTATE_PRESCAN:
- case DSTATE_SCANNING:
- case DSTATE_RAW_OK:
- case DSTATE_BUFIMAGE:
- case DSTATE_BUFPOST:
- case DSTATE_STOPPING:
- retcode = (*cinfo->inputctl->consume_input) (cinfo);
- break;
- default:
- ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
- }
- return retcode;
- }
-
- /*
- * Have we finished reading the input file?
- */
-
- GLOBAL(boolean)
- jpeg_input_complete (j_decompress_ptr cinfo)
- {
- /* Check for valid jpeg object */
- if (cinfo->global_state < DSTATE_START ||
- cinfo->global_state > DSTATE_STOPPING)
- ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
- return cinfo->inputctl->eoi_reached;
- }
-
- /*
- * Is there more than one scan?
- */
-
- GLOBAL(boolean)
- jpeg_has_multiple_scans (j_decompress_ptr cinfo)
- {
- /* Only valid after jpeg_read_header completes */
- if (cinfo->global_state < DSTATE_READY ||
- cinfo->global_state > DSTATE_STOPPING)
- ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
- return cinfo->inputctl->has_multiple_scans;
- }
-
- /*
- * Finish JPEG decompression.
- *
- * This will normally just verify the file trailer and release temp storage.
- *
- * Returns FALSE if suspended. The return value need be inspected only if
- * a suspending data source is used.
- */
-
- GLOBAL(boolean)
- jpeg_finish_decompress (j_decompress_ptr cinfo)
- {
- if ((cinfo->global_state == DSTATE_SCANNING ||
- cinfo->global_state == DSTATE_RAW_OK) && ! cinfo->buffered_image) {
- /* Terminate final pass of non-buffered mode */
- if (cinfo->output_scanline < cinfo->output_height)
- ERREXIT(cinfo, JERR_TOO_LITTLE_DATA);
- (*cinfo->master->finish_output_pass) (cinfo);
- cinfo->global_state = DSTATE_STOPPING;
- } else if (cinfo->global_state == DSTATE_BUFIMAGE) {
- /* Finishing after a buffered-image operation */
- cinfo->global_state = DSTATE_STOPPING;
- } else if (cinfo->global_state != DSTATE_STOPPING) {
- /* STOPPING = repeat call after a suspension, anything else is error */
- ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
- }
- /* Read until EOI */
- while (! cinfo->inputctl->eoi_reached) {
- if ((*cinfo->inputctl->consume_input) (cinfo) == JPEG_SUSPENDED)
- return FALSE; /* Suspend, come back later */
- }
- /* Do final cleanup */
- (*cinfo->src->term_source) (cinfo);
- /* We can use jpeg_abort to release memory and reset global_state */
- jpeg_abort((j_common_ptr) cinfo);
- return TRUE;
- }
- /********* End of inlined file: jdapimin.c *********/
-
- /********* Start of inlined file: jdatasrc.c *********/
- /* this is not a core library module, so it doesn't define JPEG_INTERNALS */
-
- /********* Start of inlined file: jerror.h *********/
- /*
- * 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 */
- /********* End of inlined file: jerror.h *********/
-
- /* Expanded data source object for stdio input */
-
- typedef struct {
- struct jpeg_source_mgr pub; /* public fields */
-
- FILE * infile; /* source stream */
- JOCTET * buffer; /* start of buffer */
- boolean start_of_file; /* have we gotten any data yet? */
- } my_source_mgr;
-
- typedef my_source_mgr * my_src_ptr;
-
- #define INPUT_BUF_SIZE 4096 /* choose an efficiently fread'able size */
-
- /*
- * Initialize source --- called by jpeg_read_header
- * before any data is actually read.
- */
-
- METHODDEF(void)
- init_source (j_decompress_ptr cinfo)
- {
- my_src_ptr src = (my_src_ptr) cinfo->src;
-
- /* We reset the empty-input-file flag for each image,
- * but we don't clear the input buffer.
- * This is correct behavior for reading a series of images from one source.
- */
- src->start_of_file = TRUE;
- }
-
- /*
- * Fill the input buffer --- called whenever buffer is emptied.
- *
- * In typical applications, this should read fresh data into the buffer
- * (ignoring the current state of next_input_byte & bytes_in_buffer),
- * reset the pointer & count to the start of the buffer, and return TRUE
- * indicating that the buffer has been reloaded. It is not necessary to
- * fill the buffer entirely, only to obtain at least one more byte.
- *
- * There is no such thing as an EOF return. If the end of the file has been
- * reached, the routine has a choice of ERREXIT() or inserting fake data into
- * the buffer. In most cases, generating a warning message and inserting a
- * fake EOI marker is the best course of action --- this will allow the
- * decompressor to output however much of the image is there. However,
- * the resulting error message is misleading if the real problem is an empty
- * input file, so we handle that case specially.
- *
- * In applications that need to be able to suspend compression due to input
- * not being available yet, a FALSE return indicates that no more data can be
- * obtained right now, but more may be forthcoming later. In this situation,
- * the decompressor will return to its caller (with an indication of the
- * number of scanlines it has read, if any). The application should resume
- * decompression after it has loaded more data into the input buffer. Note
- * that there are substantial restrictions on the use of suspension --- see
- * the documentation.
- *
- * When suspending, the decompressor will back up to a convenient restart point
- * (typically the start of the current MCU). next_input_byte & bytes_in_buffer
- * indicate where the restart point will be if the current call returns FALSE.
- * Data beyond this point must be rescanned after resumption, so move it to
- * the front of the buffer rather than discarding it.
- */
-
- METHODDEF(boolean)
- fill_input_buffer (j_decompress_ptr cinfo)
- {
- my_src_ptr src = (my_src_ptr) cinfo->src;
- size_t nbytes;
-
- nbytes = JFREAD(src->infile, src->buffer, INPUT_BUF_SIZE);
-
- if (nbytes <= 0) {
- if (src->start_of_file) /* Treat empty input file as fatal error */
- ERREXIT(cinfo, JERR_INPUT_EMPTY);
- WARNMS(cinfo, JWRN_JPEG_EOF);
- /* Insert a fake EOI marker */
- src->buffer[0] = (JOCTET) 0xFF;
- src->buffer[1] = (JOCTET) JPEG_EOI;
- nbytes = 2;
- }
-
- src->pub.next_input_byte = src->buffer;
- src->pub.bytes_in_buffer = nbytes;
- src->start_of_file = FALSE;
-
- return TRUE;
- }
-
- /*
- * Skip data --- used to skip over a potentially large amount of
- * uninteresting data (such as an APPn marker).
- *
- * Writers of suspendable-input applications must note that skip_input_data
- * is not granted the right to give a suspension return. If the skip extends
- * beyond the data currently in the buffer, the buffer can be marked empty so
- * that the next read will cause a fill_input_buffer call that can suspend.
- * Arranging for additional bytes to be discarded before reloading the input
- * buffer is the application writer's problem.
- */
-
- METHODDEF(void)
- skip_input_data (j_decompress_ptr cinfo, long num_bytes)
- {
- my_src_ptr src = (my_src_ptr) cinfo->src;
-
- /* Just a dumb implementation for now. Could use fseek() except
- * it doesn't work on pipes. Not clear that being smart is worth
- * any trouble anyway --- large skips are infrequent.
- */
- if (num_bytes > 0) {
- while (num_bytes > (long) src->pub.bytes_in_buffer) {
- num_bytes -= (long) src->pub.bytes_in_buffer;
- (void) fill_input_buffer(cinfo);
- /* note we assume that fill_input_buffer will never return FALSE,
- * so suspension need not be handled.
- */
- }
- src->pub.next_input_byte += (size_t) num_bytes;
- src->pub.bytes_in_buffer -= (size_t) num_bytes;
- }
- }
-
- /*
- * An additional method that can be provided by data source modules is the
- * resync_to_restart method for error recovery in the presence of RST markers.
- * For the moment, this source module just uses the default resync method
- * provided by the JPEG library. That method assumes that no backtracking
- * is possible.
- */
-
- /*
- * Terminate source --- called by jpeg_finish_decompress
- * after all data has been read. Often a no-op.
- *
- * NB: *not* called by jpeg_abort or jpeg_destroy; surrounding
- * application must deal with any cleanup that should happen even
- * for error exit.
- */
-
- METHODDEF(void)
- term_source (j_decompress_ptr cinfo)
- {
- /* no work necessary here */
- }
-
- /*
- * Prepare for input from a stdio stream.
- * The caller must have already opened the stream, and is responsible
- * for closing it after finishing decompression.
- */
-
- GLOBAL(void)
- jpeg_stdio_src (j_decompress_ptr cinfo, FILE * infile)
- {
- my_src_ptr src;
-
- /* The source object and input buffer are made permanent so that a series
- * of JPEG images can be read from the same file by calling jpeg_stdio_src
- * only before the first one. (If we discarded the buffer at the end of
- * one image, we'd likely lose the start of the next one.)
- * This makes it unsafe to use this manager and a different source
- * manager serially with the same JPEG object. Caveat programmer.
- */
- if (cinfo->src == NULL) { /* first time for this JPEG object? */
- cinfo->src = (struct jpeg_source_mgr *)
- (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
- SIZEOF(my_source_mgr));
- src = (my_src_ptr) cinfo->src;
- src->buffer = (JOCTET *)
- (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
- INPUT_BUF_SIZE * SIZEOF(JOCTET));
- }
-
- src = (my_src_ptr) cinfo->src;
- src->pub.init_source = init_source;
- src->pub.fill_input_buffer = fill_input_buffer;
- src->pub.skip_input_data = skip_input_data;
- src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */
- src->pub.term_source = term_source;
- src->infile = infile;
- src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */
- src->pub.next_input_byte = NULL; /* until buffer loaded */
- }
- /********* End of inlined file: jdatasrc.c *********/
-
- /********* Start of inlined file: jdcoefct.c *********/
- #define JPEG_INTERNALS
-
- /* Block smoothing is only applicable for progressive JPEG, so: */
- #ifndef D_PROGRESSIVE_SUPPORTED
- #undef BLOCK_SMOOTHING_SUPPORTED
- #endif
-
- /* Private buffer controller object */
-
- typedef struct {
- struct jpeg_d_coef_controller pub; /* public fields */
-
- /* These variables keep track of the current location of the input side. */
- /* cinfo->input_iMCU_row is also used for this. */
- JDIMENSION MCU_ctr; /* counts MCUs processed in current row */
- int MCU_vert_offset; /* counts MCU rows within iMCU row */
- int MCU_rows_per_iMCU_row; /* number of such rows needed */
-
- /* The output side's location is represented by cinfo->output_iMCU_row. */
-
- /* In single-pass modes, it's sufficient to buffer just one MCU.
- * We allocate a workspace of D_MAX_BLOCKS_IN_MCU coefficient blocks,
- * and let the entropy decoder write into that workspace each time.
- * (On 80x86, the workspace is FAR even though it's not really very big;
- * this is to keep the module interfaces unchanged when a large coefficient
- * buffer is necessary.)
- * In multi-pass modes, this array points to the current MCU's blocks
- * within the virtual arrays; it is used only by the input side.
- */
- JBLOCKROW MCU_buffer[D_MAX_BLOCKS_IN_MCU];
-
- #ifdef D_MULTISCAN_FILES_SUPPORTED
- /* In multi-pass modes, we need a virtual block array for each component. */
- jvirt_barray_ptr whole_image[MAX_COMPONENTS];
- #endif
-
- #ifdef BLOCK_SMOOTHING_SUPPORTED
- /* When doing block smoothing, we latch coefficient Al values here */
- int * coef_bits_latch;
- #define SAVED_COEFS 6 /* we save coef_bits[0..5] */
- #endif
- } my_coef_controller3;
-
- typedef my_coef_controller3 * my_coef_ptr3;
-
- /* Forward declarations */
- METHODDEF(int) decompress_onepass
- JPP((j_decompress_ptr cinfo, JSAMPIMAGE output_buf));
- #ifdef D_MULTISCAN_FILES_SUPPORTED
- METHODDEF(int) decompress_data
- JPP((j_decompress_ptr cinfo, JSAMPIMAGE output_buf));
- #endif
- #ifdef BLOCK_SMOOTHING_SUPPORTED
- LOCAL(boolean) smoothing_ok JPP((j_decompress_ptr cinfo));
- METHODDEF(int) decompress_smooth_data
- JPP((j_decompress_ptr cinfo, JSAMPIMAGE output_buf));
- #endif
-
- LOCAL(void)
- start_iMCU_row3 (j_decompress_ptr cinfo)
- /* Reset within-iMCU-row counters for a new row (input side) */
- {
- my_coef_ptr3 coef = (my_coef_ptr3) cinfo->coef;
-
- /* In an interleaved scan, an MCU row is the same as an iMCU row.
- * In a noninterleaved scan, an iMCU row has v_samp_factor MCU rows.
- * But at the bottom of the image, process only what's left.
- */
- if (cinfo->comps_in_scan > 1) {
- coef->MCU_rows_per_iMCU_row = 1;
- } else {
- if (cinfo->input_iMCU_row < (cinfo->total_iMCU_rows-1))
- coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->v_samp_factor;
- else
- coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->last_row_height;
- }
-
- coef->MCU_ctr = 0;
- coef->MCU_vert_offset = 0;
- }
-
- /*
- * Initialize for an input processing pass.
- */
-
- METHODDEF(void)
- start_input_pass (j_decompress_ptr cinfo)
- {
- cinfo->input_iMCU_row = 0;
- start_iMCU_row3(cinfo);
- }
-
- /*
- * Initialize for an output processing pass.
- */
-
- METHODDEF(void)
- start_output_pass (j_decompress_ptr cinfo)
- {
- #ifdef BLOCK_SMOOTHING_SUPPORTED
- my_coef_ptr3 coef = (my_coef_ptr3) cinfo->coef;
-
- /* If multipass, check to see whether to use block smoothing on this pass */
- if (coef->pub.coef_arrays != NULL) {
- if (cinfo->do_block_smoothing && smoothing_ok(cinfo))
- coef->pub.decompress_data = decompress_smooth_data;
- else
- coef->pub.decompress_data = decompress_data;
- }
- #endif
- cinfo->output_iMCU_row = 0;
- }
-
- /*
- * Decompress and return some data in the single-pass case.
- * Always attempts to emit one fully interleaved MCU row ("iMCU" row).
- * Input and output must run in lockstep since we have only a one-MCU buffer.
- * Return value is JPEG_ROW_COMPLETED, JPEG_SCAN_COMPLETED, or JPEG_SUSPENDED.
- *
- * NB: output_buf contains a plane for each component in image,
- * which we index according to the component's SOF position.
- */
-
- METHODDEF(int)
- decompress_onepass (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
- {
- my_coef_ptr3 coef = (my_coef_ptr3) cinfo->coef;
- JDIMENSION MCU_col_num; /* index of current MCU within row */
- JDIMENSION last_MCU_col = cinfo->MCUs_per_row - 1;
- JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
- int blkn, ci, xindex, yindex, yoffset, useful_width;
- JSAMPARRAY output_ptr;
- JDIMENSION start_col, output_col;
- jpeg_component_info *compptr;
- inverse_DCT_method_ptr inverse_DCT;
-
- /* Loop to process as much as one whole iMCU row */
- for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row;
- yoffset++) {
- for (MCU_col_num = coef->MCU_ctr; MCU_col_num <= last_MCU_col;
- MCU_col_num++) {
- /* Try to fetch an MCU. Entropy decoder expects buffer to be zeroed. */
- jzero_far((void FAR *) coef->MCU_buffer[0],
- (size_t) (cinfo->blocks_in_MCU * SIZEOF(JBLOCK)));
- if (! (*cinfo->entropy->decode_mcu) (cinfo, coef->MCU_buffer)) {
- /* Suspension forced; update state counters and exit */
- coef->MCU_vert_offset = yoffset;
- coef->MCU_ctr = MCU_col_num;
- return JPEG_SUSPENDED;
- }
- /* Determine where data should go in output_buf and do the IDCT thing.
- * We skip dummy blocks at the right and bottom edges (but blkn gets
- * incremented past them!). Note the inner loop relies on having
- * allocated the MCU_buffer[] blocks sequentially.
- */
- blkn = 0; /* index of current DCT block within MCU */
- for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
- compptr = cinfo->cur_comp_info[ci];
- /* Don't bother to IDCT an uninteresting component. */
- if (! compptr->component_needed) {
- blkn += compptr->MCU_blocks;
- continue;
- }
- inverse_DCT = cinfo->idct->inverse_DCT[compptr->component_index];
- useful_width = (MCU_col_num < last_MCU_col) ? compptr->MCU_width
- : compptr->last_col_width;
- output_ptr = output_buf[compptr->component_index] +
- yoffset * compptr->DCT_scaled_size;
- start_col = MCU_col_num * compptr->MCU_sample_width;
- for (yindex = 0; yindex < compptr->MCU_height; yindex++) {
- if (cinfo->input_iMCU_row < last_iMCU_row ||
- yoffset+yindex < compptr->last_row_height) {
- output_col = start_col;
- for (xindex = 0; xindex < useful_width; xindex++) {
- (*inverse_DCT) (cinfo, compptr,
- (JCOEFPTR) coef->MCU_buffer[blkn+xindex],
- output_ptr, output_col);
- output_col += compptr->DCT_scaled_size;
- }
- }
- blkn += compptr->MCU_width;
- output_ptr += compptr->DCT_scaled_size;
- }
- }
- }
- /* Completed an MCU row, but perhaps not an iMCU row */
- coef->MCU_ctr = 0;
- }
- /* Completed the iMCU row, advance counters for next one */
- cinfo->output_iMCU_row++;
- if (++(cinfo->input_iMCU_row) < cinfo->total_iMCU_rows) {
- start_iMCU_row3(cinfo);
- return JPEG_ROW_COMPLETED;
- }
- /* Completed the scan */
- (*cinfo->inputctl->finish_input_pass) (cinfo);
- return JPEG_SCAN_COMPLETED;
- }
-
- /*
- * Dummy consume-input routine for single-pass operation.
- */
-
- METHODDEF(int)
- dummy_consume_data (j_decompress_ptr cinfo)
- {
- return JPEG_SUSPENDED; /* Always indicate nothing was done */
- }
-
- #ifdef D_MULTISCAN_FILES_SUPPORTED
-
- /*
- * Consume input data and store it in the full-image coefficient buffer.
- * We read as much as one fully interleaved MCU row ("iMCU" row) per call,
- * ie, v_samp_factor block rows for each component in the scan.
- * Return value is JPEG_ROW_COMPLETED, JPEG_SCAN_COMPLETED, or JPEG_SUSPENDED.
- */
-
- METHODDEF(int)
- consume_data (j_decompress_ptr cinfo)
- {
- my_coef_ptr3 coef = (my_coef_ptr3) cinfo->coef;
- JDIMENSION MCU_col_num; /* index of current MCU within row */
- int blkn, ci, xindex, yindex, yoffset;
- JDIMENSION start_col;
- JBLOCKARRAY buffer[MAX_COMPS_IN_SCAN];
- JBLOCKROW buffer_ptr;
- jpeg_component_info *compptr;
-
- /* Align the virtual buffers for the components used in this scan. */
- for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
- compptr = cinfo->cur_comp_info[ci];
- buffer[ci] = (*cinfo->mem->access_virt_barray)
- ((j_common_ptr) cinfo, coef->whole_image[compptr->component_index],
- cinfo->input_iMCU_row * compptr->v_samp_factor,
- (JDIMENSION) compptr->v_samp_factor, TRUE);
- /* Note: entropy decoder expects buffer to be zeroed,
- * but this is handled automatically by the memory manager
- * because we requested a pre-zeroed array.
- */
- }
-
- /* Loop to process one whole iMCU row */
- for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row;
- yoffset++) {
- for (MCU_col_num = coef->MCU_ctr; MCU_col_num < cinfo->MCUs_per_row;
- MCU_col_num++) {
- /* Construct list of pointers to DCT blocks belonging to this MCU */
- blkn = 0; /* index of current DCT block within MCU */
- for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
- compptr = cinfo->cur_comp_info[ci];
- start_col = MCU_col_num * compptr->MCU_width;
- for (yindex = 0; yindex < compptr->MCU_height; yindex++) {
- buffer_ptr = buffer[ci][yindex+yoffset] + start_col;
- for (xindex = 0; xindex < compptr->MCU_width; xindex++) {
- coef->MCU_buffer[blkn++] = buffer_ptr++;
- }
- }
- }
- /* Try to fetch the MCU. */
- if (! (*cinfo->entropy->decode_mcu) (cinfo, coef->MCU_buffer)) {
- /* Suspension forced; update state counters and exit */
- coef->MCU_vert_offset = yoffset;
- coef->MCU_ctr = MCU_col_num;
- return JPEG_SUSPENDED;
- }
- }
- /* Completed an MCU row, but perhaps not an iMCU row */
- coef->MCU_ctr = 0;
- }
- /* Completed the iMCU row, advance counters for next one */
- if (++(cinfo->input_iMCU_row) < cinfo->total_iMCU_rows) {
- start_iMCU_row3(cinfo);
- return JPEG_ROW_COMPLETED;
- }
- /* Completed the scan */
- (*cinfo->inputctl->finish_input_pass) (cinfo);
- return JPEG_SCAN_COMPLETED;
- }
-
- /*
- * Decompress and return some data in the multi-pass case.
- * Always attempts to emit one fully interleaved MCU row ("iMCU" row).
- * Return value is JPEG_ROW_COMPLETED, JPEG_SCAN_COMPLETED, or JPEG_SUSPENDED.
- *
- * NB: output_buf contains a plane for each component in image.
- */
-
- METHODDEF(int)
- decompress_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
- {
- my_coef_ptr3 coef = (my_coef_ptr3) cinfo->coef;
- JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
- JDIMENSION block_num;
- int ci, block_row, block_rows;
- JBLOCKARRAY buffer;
- JBLOCKROW buffer_ptr;
- JSAMPARRAY output_ptr;
- JDIMENSION output_col;
- jpeg_component_info *compptr;
- inverse_DCT_method_ptr inverse_DCT;
-
- /* Force some input to be done if we are getting ahead of the input. */
- while (cinfo->input_scan_number < cinfo->output_scan_number ||
- (cinfo->input_scan_number == cinfo->output_scan_number &&
- cinfo->input_iMCU_row <= cinfo->output_iMCU_row)) {
- if ((*cinfo->inputctl->consume_input)(cinfo) == JPEG_SUSPENDED)
- return JPEG_SUSPENDED;
- }
-
- /* OK, output from the virtual arrays. */
- for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
- ci++, compptr++) {
- /* Don't bother to IDCT an uninteresting component. */
- if (! compptr->component_needed)
- continue;
- /* Align the virtual buffer for this component. */
- buffer = (*cinfo->mem->access_virt_barray)
- ((j_common_ptr) cinfo, coef->whole_image[ci],
- cinfo->output_iMCU_row * compptr->v_samp_factor,
- (JDIMENSION) compptr->v_samp_factor, FALSE);
- /* Count non-dummy DCT block rows in this iMCU row. */
- if (cinfo->output_iMCU_row < last_iMCU_row)
- block_rows = compptr->v_samp_factor;
- else {
- /* NB: can't use last_row_height here; it is input-side-dependent! */
- block_rows = (int) (compptr->height_in_blocks % compptr->v_samp_factor);
- if (block_rows == 0) block_rows = compptr->v_samp_factor;
- }
- inverse_DCT = cinfo->idct->inverse_DCT[ci];
- output_ptr = output_buf[ci];
- /* Loop over all DCT blocks to be processed. */
- for (block_row = 0; block_row < block_rows; block_row++) {
- buffer_ptr = buffer[block_row];
- output_col = 0;
- for (block_num = 0; block_num < compptr->width_in_blocks; block_num++) {
- (*inverse_DCT) (cinfo, compptr, (JCOEFPTR) buffer_ptr,
- output_ptr, output_col);
- buffer_ptr++;
- output_col += compptr->DCT_scaled_size;
- }
- output_ptr += compptr->DCT_scaled_size;
- }
- }
-
- if (++(cinfo->output_iMCU_row) < cinfo->total_iMCU_rows)
- return JPEG_ROW_COMPLETED;
- return JPEG_SCAN_COMPLETED;
- }
-
- #endif /* D_MULTISCAN_FILES_SUPPORTED */
-
- #ifdef BLOCK_SMOOTHING_SUPPORTED
-
- /*
- * This code applies interblock smoothing as described by section K.8
- * of the JPEG standard: the first 5 AC coefficients are estimated from
- * the DC values of a DCT block and its 8 neighboring blocks.
- * We apply smoothing only for progressive JPEG decoding, and only if
- * the coefficients it can estimate are not yet known to full precision.
- */
-
- /* Natural-order array positions of the first 5 zigzag-order coefficients */
- #define Q01_POS 1
- #define Q10_POS 8
- #define Q20_POS 16
- #define Q11_POS 9
- #define Q02_POS 2
-
- /*
- * Determine whether block smoothing is applicable and safe.
- * We also latch the current states of the coef_bits[] entries for the
- * AC coefficients; otherwise, if the input side of the decompressor
- * advances into a new scan, we might think the coefficients are known
- * more accurately than they really are.
- */
-
- LOCAL(boolean)
- smoothing_ok (j_decompress_ptr cinfo)
- {
- my_coef_ptr3 coef = (my_coef_ptr3) cinfo->coef;
- boolean smoothing_useful = FALSE;
- int ci, coefi;
- jpeg_component_info *compptr;
- JQUANT_TBL * qtable;
- int * coef_bits;
- int * coef_bits_latch;
-
- if (! cinfo->progressive_mode || cinfo->coef_bits == NULL)
- return FALSE;
-
- /* Allocate latch area if not already done */
- if (coef->coef_bits_latch == NULL)
- coef->coef_bits_latch = (int *)
- (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
- cinfo->num_components *
- (SAVED_COEFS * SIZEOF(int)));
- coef_bits_latch = coef->coef_bits_latch;
-
- for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
- ci++, compptr++) {
- /* All components' quantization values must already be latched. */
- if ((qtable = compptr->quant_table) == NULL)
- return FALSE;
- /* Verify DC & first 5 AC quantizers are nonzero to avoid zero-divide. */
- if (qtable->quantval[0] == 0 ||
- qtable->quantval[Q01_POS] == 0 ||
- qtable->quantval[Q10_POS] == 0 ||
- qtable->quantval[Q20_POS] == 0 ||
- qtable->quantval[Q11_POS] == 0 ||
- qtable->quantval[Q02_POS] == 0)
- return FALSE;
- /* DC values must be at least partly known for all components. */
- coef_bits = cinfo->coef_bits[ci];
- if (coef_bits[0] < 0)
- return FALSE;
- /* Block smoothing is helpful if some AC coefficients remain inaccurate. */
- for (coefi = 1; coefi <= 5; coefi++) {
- coef_bits_latch[coefi] = coef_bits[coefi];
- if (coef_bits[coefi] != 0)
- smoothing_useful = TRUE;
- }
- coef_bits_latch += SAVED_COEFS;
- }
-
- return smoothing_useful;
- }
-
- /*
- * Variant of decompress_data for use when doing block smoothing.
- */
-
- METHODDEF(int)
- decompress_smooth_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
- {
- my_coef_ptr3 coef = (my_coef_ptr3) cinfo->coef;
- JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
- JDIMENSION block_num, last_block_column;
- int ci, block_row, block_rows, access_rows;
- JBLOCKARRAY buffer;
- JBLOCKROW buffer_ptr, prev_block_row, next_block_row;
- JSAMPARRAY output_ptr;
- JDIMENSION output_col;
- jpeg_component_info *compptr;
- inverse_DCT_method_ptr inverse_DCT;
- boolean first_row, last_row;
- JBLOCK workspace;
- int *coef_bits;
- JQUANT_TBL *quanttbl;
- INT32 Q00,Q01,Q02,Q10,Q11,Q20, num;
- int DC1,DC2,DC3,DC4,DC5,DC6,DC7,DC8,DC9;
- int Al, pred;
-
- /* Force some input to be done if we are getting ahead of the input. */
- while (cinfo->input_scan_number <= cinfo->output_scan_number &&
- ! cinfo->inputctl->eoi_reached) {
- if (cinfo->input_scan_number == cinfo->output_scan_number) {
- /* If input is working on current scan, we ordinarily want it to
- * have completed the current row. But if input scan is DC,
- * we want it to keep one row ahead so that next block row's DC
- * values are up to date.
- */
- JDIMENSION delta = (cinfo->Ss == 0) ? 1 : 0;
- if (cinfo->input_iMCU_row > cinfo->output_iMCU_row+delta)
- break;
- }
- if ((*cinfo->inputctl->consume_input)(cinfo) == JPEG_SUSPENDED)
- return JPEG_SUSPENDED;
- }
-
- /* OK, output from the virtual arrays. */
- for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
- ci++, compptr++) {
- /* Don't bother to IDCT an uninteresting component. */
- if (! compptr->component_needed)
- continue;
- /* Count non-dummy DCT block rows in this iMCU row. */
- if (cinfo->output_iMCU_row < last_iMCU_row) {
- block_rows = compptr->v_samp_factor;
- access_rows = block_rows * 2; /* this and next iMCU row */
- last_row = FALSE;
- } else {
- /* NB: can't use last_row_height here; it is input-side-dependent! */
- block_rows = (int) (compptr->height_in_blocks % compptr->v_samp_factor);
- if (block_rows == 0) block_rows = compptr->v_samp_factor;
- access_rows = block_rows; /* this iMCU row only */
- last_row = TRUE;
- }
- /* Align the virtual buffer for this component. */
- if (cinfo->output_iMCU_row > 0) {
- access_rows += compptr->v_samp_factor; /* prior iMCU row too */
- buffer = (*cinfo->mem->access_virt_barray)
- ((j_common_ptr) cinfo, coef->whole_image[ci],
- (cinfo->output_iMCU_row - 1) * compptr->v_samp_factor,
- (JDIMENSION) access_rows, FALSE);
- buffer += compptr->v_samp_factor; /* point to current iMCU row */
- first_row = FALSE;
- } else {
- buffer = (*cinfo->mem->access_virt_barray)
- ((j_common_ptr) cinfo, coef->whole_image[ci],
- (JDIMENSION) 0, (JDIMENSION) access_rows, FALSE);
- first_row = TRUE;
- }
- /* Fetch component-dependent info */
- coef_bits = coef->coef_bits_latch + (ci * SAVED_COEFS);
- quanttbl = compptr->quant_table;
- Q00 = quanttbl->quantval[0];
- Q01 = quanttbl->quantval[Q01_POS];
- Q10 = quanttbl->quantval[Q10_POS];
- Q20 = quanttbl->quantval[Q20_POS];
- Q11 = quanttbl->quantval[Q11_POS];
- Q02 = quanttbl->quantval[Q02_POS];
- inverse_DCT = cinfo->idct->inverse_DCT[ci];
- output_ptr = output_buf[ci];
- /* Loop over all DCT blocks to be processed. */
- for (block_row = 0; block_row < block_rows; block_row++) {
- buffer_ptr = buffer[block_row];
- if (first_row && block_row == 0)
- prev_block_row = buffer_ptr;
- else
- prev_block_row = buffer[block_row-1];
- if (last_row && block_row == block_rows-1)
- next_block_row = buffer_ptr;
- else
- next_block_row = buffer[block_row+1];
- /* We fetch the surrounding DC values using a sliding-register approach.
- * Initialize all nine here so as to do the right thing on narrow pics.
- */
- DC1 = DC2 = DC3 = (int) prev_block_row[0][0];
- DC4 = DC5 = DC6 = (int) buffer_ptr[0][0];
- DC7 = DC8 = DC9 = (int) next_block_row[0][0];
- output_col = 0;
- last_block_column = compptr->width_in_blocks - 1;
- for (block_num = 0; block_num <= last_block_column; block_num++) {
- /* Fetch current DCT block into workspace so we can modify it. */
- jcopy_block_row(buffer_ptr, (JBLOCKROW) workspace, (JDIMENSION) 1);
- /* Update DC values */
- if (block_num < last_block_column) {
- DC3 = (int) prev_block_row[1][0];
- DC6 = (int) buffer_ptr[1][0];
- DC9 = (int) next_block_row[1][0];
- }
- /* Compute coefficient estimates per K.8.
- * An estimate is applied only if coefficient is still zero,
- * and is not known to be fully accurate.
- */
- /* AC01 */
- if ((Al=coef_bits[1]) != 0 && workspace[1] == 0) {
- num = 36 * Q00 * (DC4 - DC6);
- if (num >= 0) {
- pred = (int) (((Q01<<7) + num) / (Q01<<8));
- if (Al > 0 && pred >= (1<<Al))
- pred = (1<<Al)-1;
- } else {
- pred = (int) (((Q01<<7) - num) / (Q01<<8));
- if (Al > 0 && pred >= (1<<Al))
- pred = (1<<Al)-1;
- pred = -pred;
- }
- workspace[1] = (JCOEF) pred;
- }
- /* AC10 */
- if ((Al=coef_bits[2]) != 0 && workspace[8] == 0) {
- num = 36 * Q00 * (DC2 - DC8);
- if (num >= 0) {
- pred = (int) (((Q10<<7) + num) / (Q10<<8));
- if (Al > 0 && pred >= (1<<Al))
- pred = (1<<Al)-1;
- } else {
- pred = (int) (((Q10<<7) - num) / (Q10<<8));
- if (Al > 0 && pred >= (1<<Al))
- pred = (1<<Al)-1;
- pred = -pred;
- }
- workspace[8] = (JCOEF) pred;
- }
- /* AC20 */
- if ((Al=coef_bits[3]) != 0 && workspace[16] == 0) {
- num = 9 * Q00 * (DC2 + DC8 - 2*DC5);
- if (num >= 0) {
- pred = (int) (((Q20<<7) + num) / (Q20<<8));
- if (Al > 0 && pred >= (1<<Al))
- pred = (1<<Al)-1;
- } else {
- pred = (int) (((Q20<<7) - num) / (Q20<<8));
- if (Al > 0 && pred >= (1<<Al))
- pred = (1<<Al)-1;
- pred = -pred;
- }
- workspace[16] = (JCOEF) pred;
- }
- /* AC11 */
- if ((Al=coef_bits[4]) != 0 && workspace[9] == 0) {
- num = 5 * Q00 * (DC1 - DC3 - DC7 + DC9);
- if (num >= 0) {
- pred = (int) (((Q11<<7) + num) / (Q11<<8));
- if (Al > 0 && pred >= (1<<Al))
- pred = (1<<Al)-1;
- } else {
- pred = (int) (((Q11<<7) - num) / (Q11<<8));
- if (Al > 0 && pred >= (1<<Al))
- pred = (1<<Al)-1;
- pred = -pred;
- }
- workspace[9] = (JCOEF) pred;
- }
- /* AC02 */
- if ((Al=coef_bits[5]) != 0 && workspace[2] == 0) {
- num = 9 * Q00 * (DC4 + DC6 - 2*DC5);
- if (num >= 0) {
- pred = (int) (((Q02<<7) + num) / (Q02<<8));
- if (Al > 0 && pred >= (1<<Al))
- pred = (1<<Al)-1;
- } else {
- pred = (int) (((Q02<<7) - num) / (Q02<<8));
- if (Al > 0 && pred >= (1<<Al))
- pred = (1<<Al)-1;
- pred = -pred;
- }
- workspace[2] = (JCOEF) pred;
- }
- /* OK, do the IDCT */
- (*inverse_DCT) (cinfo, compptr, (JCOEFPTR) workspace,
- output_ptr, output_col);
- /* Advance for next column */
- DC1 = DC2; DC2 = DC3;
- DC4 = DC5; DC5 = DC6;
- DC7 = DC8; DC8 = DC9;
- buffer_ptr++, prev_block_row++, next_block_row++;
- output_col += compptr->DCT_scaled_size;
- }
- output_ptr += compptr->DCT_scaled_size;
- }
- }
-
- if (++(cinfo->output_iMCU_row) < cinfo->total_iMCU_rows)
- return JPEG_ROW_COMPLETED;
- return JPEG_SCAN_COMPLETED;
- }
-
- #endif /* BLOCK_SMOOTHING_SUPPORTED */
-
- /*
- * Initialize coefficient buffer controller.
- */
-
- GLOBAL(void)
- jinit_d_coef_controller (j_decompress_ptr cinfo, boolean need_full_buffer)
- {
- my_coef_ptr3 coef;
-
- coef = (my_coef_ptr3)
- (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
- SIZEOF(my_coef_controller3));
- cinfo->coef = (struct jpeg_d_coef_controller *) coef;
- coef->pub.start_input_pass = start_input_pass;
- coef->pub.start_output_pass = start_output_pass;
- #ifdef BLOCK_SMOOTHING_SUPPORTED
- coef->coef_bits_latch = NULL;
- #endif
-
- /* Create the coefficient buffer. */
- if (need_full_buffer) {
- #ifdef D_MULTISCAN_FILES_SUPPORTED
- /* Allocate a full-image virtual array for each component, */
- /* padded to a multiple of samp_factor DCT blocks in each direction. */
- /* Note we ask for a pre-zeroed array. */
- int ci, access_rows;
- jpeg_component_info *compptr;
-
- for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
- ci++, compptr++) {
- access_rows = compptr->v_samp_factor;
- #ifdef BLOCK_SMOOTHING_SUPPORTED
- /* If block smoothing could be used, need a bigger window */
- if (cinfo->progressive_mode)
- access_rows *= 3;
- #endif
- coef->whole_image[ci] = (*cinfo->mem->request_virt_barray)
- ((j_common_ptr) cinfo, JPOOL_IMAGE, TRUE,
- (JDIMENSION) jround_up((long) compptr->width_in_blocks,
- (long) compptr->h_samp_factor),
- (JDIMENSION) jround_up((long) compptr->height_in_blocks,
- (long) compptr->v_samp_factor),
- (JDIMENSION) access_rows);
- }
- coef->pub.consume_data = consume_data;
- coef->pub.decompress_data = decompress_data;
- coef->pub.coef_arrays = coef->whole_image; /* link to virtual arrays */
- #else
- ERREXIT(cinfo, JERR_NOT_COMPILED);
- #endif
- } else {
- /* We only need a single-MCU buffer. */
- JBLOCKROW buffer;
- int i;
-
- buffer = (JBLOCKROW)
- (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
- D_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK));
- for (i = 0; i < D_MAX_BLOCKS_IN_MCU; i++) {
- coef->MCU_buffer[i] = buffer + i;
- }
- coef->pub.consume_data = dummy_consume_data;
- coef->pub.decompress_data = decompress_onepass;
- coef->pub.coef_arrays = NULL; /* flag for no virtual arrays */
- }
- }
- /********* End of inlined file: jdcoefct.c *********/
-
- #undef FIX
-
- /********* Start of inlined file: jdcolor.c *********/
- #define JPEG_INTERNALS
-
- /* Private subobject */
-
- typedef struct {
- struct jpeg_color_deconverter pub; /* public fields */
-
- /* Private state for YCC->RGB conversion */
- int * Cr_r_tab; /* => table for Cr to R conversion */
- int * Cb_b_tab; /* => table for Cb to B conversion */
- INT32 * Cr_g_tab; /* => table for Cr to G conversion */
- INT32 * Cb_g_tab; /* => table for Cb to G conversion */
- } my_color_deconverter2;
-
- typedef my_color_deconverter2 * my_cconvert_ptr2;
-
- /**************** YCbCr -> RGB conversion: most common case **************/
-
- /*
- * YCbCr is defined per CCIR 601-1, except that Cb and Cr are
- * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.
- * The conversion equations to be implemented are therefore
- * R = Y + 1.40200 * Cr
- * G = Y - 0.34414 * Cb - 0.71414 * Cr
- * B = Y + 1.77200 * Cb
- * where Cb and Cr represent the incoming values less CENTERJSAMPLE.
- * (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.)
- *
- * To avoid floating-point arithmetic, we represent the fractional constants
- * as integers scaled up by 2^16 (about 4 digits precision); we have to divide
- * the products by 2^16, with appropriate rounding, to get the correct answer.
- * Notice that Y, being an integral input, does not contribute any fraction
- * so it need not participate in the rounding.
- *
- * For even more speed, we avoid doing any multiplications in the inner loop
- * by precalculating the constants times Cb and Cr for all possible values.
- * For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table);
- * for 12-bit samples it is still acceptable. It's not very reasonable for
- * 16-bit samples, but if you want lossless storage you shouldn't be changing
- * colorspace anyway.
- * The Cr=>R and Cb=>B values can be rounded to integers in advance; the
- * values for the G calculation are left scaled up, since we must add them
- * together before rounding.
- */
-
- #define SCALEBITS 16 /* speediest right-shift on some machines */
- #define ONE_HALF ((INT32) 1 << (SCALEBITS-1))
- #define FIX(x) ((INT32) ((x) * (1L<<SCALEBITS) + 0.5))
-
- /*
- * Initialize tables for YCC->RGB colorspace conversion.
- */
-
- LOCAL(void)
- build_ycc_rgb_table (j_decompress_ptr cinfo)
- {
- my_cconvert_ptr2 cconvert = (my_cconvert_ptr2) cinfo->cconvert;
- int i;
- INT32 x;
- SHIFT_TEMPS
-
- cconvert->Cr_r_tab = (int *)
- (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
- (MAXJSAMPLE+1) * SIZEOF(int));
- cconvert->Cb_b_tab = (int *)
- (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
- (MAXJSAMPLE+1) * SIZEOF(int));
- cconvert->Cr_g_tab = (INT32 *)
- (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
- (MAXJSAMPLE+1) * SIZEOF(INT32));
- cconvert->Cb_g_tab = (INT32 *)
- (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
- (MAXJSAMPLE+1) * SIZEOF(INT32));
-
- for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) {
- /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
- /* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
- /* Cr=>R value is nearest int to 1.40200 * x */
- cconvert->Cr_r_tab[i] = (int)
- RIGHT_SHIFT(FIX(1.40200) * x + ONE_HALF, SCALEBITS);
- /* Cb=>B value is nearest int to 1.77200 * x */
- cconvert->Cb_b_tab[i] = (int)
- RIGHT_SHIFT(FIX(1.77200) * x + ONE_HALF, SCALEBITS);
- /* Cr=>G value is scaled-up -0.71414 * x */
- cconvert->Cr_g_tab[i] = (- FIX(0.71414)) * x;
- /* Cb=>G value is scaled-up -0.34414 * x */
- /* We also add in ONE_HALF so that need not do it in inner loop */
- cconvert->Cb_g_tab[i] = (- FIX(0.34414)) * x + ONE_HALF;
- }
- }
-
- /*
- * Convert some rows of samples to the output colorspace.
- *
- * Note that we change from noninterleaved, one-plane-per-component format
- * to interleaved-pixel format. The output buffer is therefore three times
- * as wide as the input buffer.
- * A starting row offset is provided only for the input buffer. The caller
- * can easily adjust the passed output_buf value to accommodate any row
- * offset required on that side.
- */
-
- METHODDEF(void)
- ycc_rgb_convert (j_decompress_ptr cinfo,
- JSAMPIMAGE input_buf, JDIMENSION input_row,
- JSAMPARRAY output_buf, int num_rows)
- {
- my_cconvert_ptr2 cconvert = (my_cconvert_ptr2) cinfo->cconvert;
- register int y, cb, cr;
- register JSAMPROW outptr;
- register JSAMPROW inptr0, inptr1, inptr2;
- register JDIMENSION col;
- JDIMENSION num_cols = cinfo->output_width;
- /* copy these pointers into registers if possible */
- register JSAMPLE * range_limit = cinfo->sample_range_limit;
- register int * Crrtab = cconvert->Cr_r_tab;
- register int * Cbbtab = cconvert->Cb_b_tab;
- register INT32 * Crgtab = cconvert->Cr_g_tab;
- register INT32 * Cbgtab = cconvert->Cb_g_tab;
- SHIFT_TEMPS
-
- while (--num_rows >= 0) {
- inptr0 = input_buf[0][input_row];
- inptr1 = input_buf[1][input_row];
- inptr2 = input_buf[2][input_row];
- input_row++;
- outptr = *output_buf++;
- for (col = 0; col < num_cols; col++) {
- y = GETJSAMPLE(inptr0[col]);
- cb = GETJSAMPLE(inptr1[col]);
- cr = GETJSAMPLE(inptr2[col]);
- /* Range-limiting is essential due to noise introduced by DCT losses. */
- outptr[RGB_RED] = range_limit[y + Crrtab[cr]];
- outptr[RGB_GREEN] = range_limit[y +
- ((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
- SCALEBITS))];
- outptr[RGB_BLUE] = range_limit[y + Cbbtab[cb]];
- outptr += RGB_PIXELSIZE;
- }
- }
- }
-
- /**************** Cases other than YCbCr -> RGB **************/
-
- /*
- * Color conversion for no colorspace change: just copy the data,
- * converting from separate-planes to interleaved representation.
- */
-
- METHODDEF(void)
- null_convert2 (j_decompress_ptr cinfo,
- JSAMPIMAGE input_buf, JDIMENSION input_row,
- JSAMPARRAY output_buf, int num_rows)
- {
- register JSAMPROW inptr, outptr;
- register JDIMENSION count;
- register int num_components = cinfo->num_components;
- JDIMENSION num_cols = cinfo->output_width;
- int ci;
-
- while (--num_rows >= 0) {
- for (ci = 0; ci < num_components; ci++) {
- inptr = input_buf[ci][input_row];
- outptr = output_buf[0] + ci;
- for (count = num_cols; count > 0; count--) {
- *outptr = *inptr++; /* needn't bother with GETJSAMPLE() here */
- outptr += num_components;
- }
- }
- input_row++;
- output_buf++;
- }
- }
-
- /*
- * Color conversion for grayscale: just copy the data.
- * This also works for YCbCr -> grayscale conversion, in which
- * we just copy the Y (luminance) component and ignore chrominance.
- */
-
- METHODDEF(void)
- grayscale_convert2 (j_decompress_ptr cinfo,
- JSAMPIMAGE input_buf, JDIMENSION input_row,
- JSAMPARRAY output_buf, int num_rows)
- {
- jcopy_sample_rows(input_buf[0], (int) input_row, output_buf, 0,
- num_rows, cinfo->output_width);
- }
-
- /*
- * Convert grayscale to RGB: just duplicate the graylevel three times.
- * This is provided to support applications that don't want to cope
- * with grayscale as a separate case.
- */
-
- METHODDEF(void)
- gray_rgb_convert (j_decompress_ptr cinfo,
- JSAMPIMAGE input_buf, JDIMENSION input_row,
- JSAMPARRAY output_buf, int num_rows)
- {
- register JSAMPROW inptr, outptr;
- register JDIMENSION col;
- JDIMENSION num_cols = cinfo->output_width;
-
- while (--num_rows >= 0) {
- inptr = input_buf[0][input_row++];
- outptr = *output_buf++;
- for (col = 0; col < num_cols; col++) {
- /* We can dispense with GETJSAMPLE() here */
- outptr[RGB_RED] = outptr[RGB_GREEN] = outptr[RGB_BLUE] = inptr[col];
- outptr += RGB_PIXELSIZE;
- }
- }
- }
-
- /*
- * Adobe-style YCCK->CMYK conversion.
- * We convert YCbCr to R=1-C, G=1-M, and B=1-Y using the same
- * conversion as above, while passing K (black) unchanged.
- * We assume build_ycc_rgb_table has been called.
- */
-
- METHODDEF(void)
- ycck_cmyk_convert (j_decompress_ptr cinfo,
- JSAMPIMAGE input_buf, JDIMENSION input_row,
- JSAMPARRAY output_buf, int num_rows)
- {
- my_cconvert_ptr2 cconvert = (my_cconvert_ptr2) cinfo->cconvert;
- register int y, cb, cr;
- register JSAMPROW outptr;
- register JSAMPROW inptr0, inptr1, inptr2, inptr3;
- register JDIMENSION col;
- JDIMENSION num_cols = cinfo->output_width;
- /* copy these pointers into registers if possible */
- register JSAMPLE * range_limit = cinfo->sample_range_limit;
- register int * Crrtab = cconvert->Cr_r_tab;
- register int * Cbbtab = cconvert->Cb_b_tab;
- register INT32 * Crgtab = cconvert->Cr_g_tab;
- register INT32 * Cbgtab = cconvert->Cb_g_tab;
- SHIFT_TEMPS
-
- while (--num_rows >= 0) {
- inptr0 = input_buf[0][input_row];
- inptr1 = input_buf[1][input_row];
- inptr2 = input_buf[2][input_row];
- inptr3 = input_buf[3][input_row];
- input_row++;
- outptr = *output_buf++;
- for (col = 0; col < num_cols; col++) {
- y = GETJSAMPLE(inptr0[col]);
- cb = GETJSAMPLE(inptr1[col]);
- cr = GETJSAMPLE(inptr2[col]);
- /* Range-limiting is essential due to noise introduced by DCT losses. */
- outptr[0] = range_limit[MAXJSAMPLE - (y + Crrtab[cr])]; /* red */
- outptr[1] = range_limit[MAXJSAMPLE - (y + /* green */
- ((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
- SCALEBITS)))];
- outptr[2] = range_limit[MAXJSAMPLE - (y + Cbbtab[cb])]; /* blue */
- /* K passes through unchanged */
- outptr[3] = inptr3[col]; /* don't need GETJSAMPLE here */
- outptr += 4;
- }
- }
- }
-
- /*
- * Empty method for start_pass.
- */
-
- METHODDEF(void)
- start_pass_dcolor (j_decompress_ptr cinfo)
- {
- /* no work needed */
- }
-
- /*
- * Module initialization routine for output colorspace conversion.
- */
-
- GLOBAL(void)
- jinit_color_deconverter (j_decompress_ptr cinfo)
- {
- my_cconvert_ptr2 cconvert;
- int ci;
-
- cconvert = (my_cconvert_ptr2)
- (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
- SIZEOF(my_color_deconverter2));
- cinfo->cconvert = (struct jpeg_color_deconverter *) cconvert;
- cconvert->pub.start_pass = start_pass_dcolor;
-
- /* Make sure num_components agrees with jpeg_color_space */
- switch (cinfo->jpeg_color_space) {
- case JCS_GRAYSCALE:
- if (cinfo->num_components != 1)
- ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
- break;
-
- case JCS_RGB:
- case JCS_YCbCr:
- if (cinfo->num_components != 3)
- ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
- break;
-
- case JCS_CMYK:
- case JCS_YCCK:
- if (cinfo->num_components != 4)
- ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
- break;
-
- default: /* JCS_UNKNOWN can be anything */
- if (cinfo->num_components < 1)
- ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
- break;
- }
-
- /* Set out_color_components and conversion method based on requested space.
- * Also clear the component_needed flags for any unused components,
- * so that earlier pipeline stages can avoid useless computation.
- */
-
- switch (cinfo->out_color_space) {
- case JCS_GRAYSCALE:
- cinfo->out_color_components = 1;
- if (cinfo->jpeg_color_space == JCS_GRAYSCALE ||
- cinfo->jpeg_color_space == JCS_YCbCr) {
- cconvert->pub.color_convert = grayscale_convert2;
- /* For color->grayscale conversion, only the Y (0) component is needed */
- for (ci = 1; ci < cinfo->num_components; ci++)
- cinfo->comp_info[ci].component_needed = FALSE;
- } else
- ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
- break;
-
- case JCS_RGB:
- cinfo->out_color_components = RGB_PIXELSIZE;
- if (cinfo->jpeg_color_space == JCS_YCbCr) {
- cconvert->pub.color_convert = ycc_rgb_convert;
- build_ycc_rgb_table(cinfo);
- } else if (cinfo->jpeg_color_space == JCS_GRAYSCALE) {
- cconvert->pub.color_convert = gray_rgb_convert;
- } else if (cinfo->jpeg_color_space == JCS_RGB && RGB_PIXELSIZE == 3) {
- cconvert->pub.color_convert = null_convert2;
- } else
- ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
- break;
-
- case JCS_CMYK:
- cinfo->out_color_components = 4;
- if (cinfo->jpeg_color_space == JCS_YCCK) {
- cconvert->pub.color_convert = ycck_cmyk_convert;
- build_ycc_rgb_table(cinfo);
- } else if (cinfo->jpeg_color_space == JCS_CMYK) {
- cconvert->pub.color_convert = null_convert2;
- } else
- ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
- break;
-
- default:
- /* Permit null conversion to same output space */
- if (cinfo->out_color_space == cinfo->jpeg_color_space) {
- cinfo->out_color_components = cinfo->num_components;
- cconvert->pub.color_convert = null_convert2;
- } else /* unsupported non-null conversion */
- ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
- break;
- }
-
- if (cinfo->quantize_colors)
- cinfo->output_components = 1; /* single colormapped output component */
- else
- cinfo->output_components = cinfo->out_color_components;
- }
- /********* End of inlined file: jdcolor.c *********/
-
- #undef FIX
-
- /********* Start of inlined file: jddctmgr.c *********/
- #define JPEG_INTERNALS
-
- /*
- * The decompressor input side (jdinput.c) saves away the appropriate
- * quantization table for each component at the start of the first scan
- * involving that component. (This is necessary in order to correctly
- * decode files that reuse Q-table slots.)
- * When we are ready to make an output pass, the saved Q-table is converted
- * to a multiplier table that will actually be used by the IDCT routine.
- * The multiplier table contents are IDCT-method-dependent. To support
- * application changes in IDCT method between scans, we can remake the
- * multiplier tables if necessary.
- * In buffered-image mode, the first output pass may occur before any data
- * has been seen for some components, and thus before their Q-tables have
- * been saved away. To handle this case, multiplier tables are preset
- * to zeroes; the result of the IDCT will be a neutral gray level.
- */
-
- /* Private subobject for this module */
-
- typedef struct {
- struct jpeg_inverse_dct pub; /* public fields */
-
- /* This array contains the IDCT method code that each multiplier table
- * is currently set up for, or -1 if it's not yet set up.
- * The actual multiplier tables are pointed to by dct_table in the
- * per-component comp_info structures.
- */
- int cur_method[MAX_COMPONENTS];
- } my_idct_controller;
-
- typedef my_idct_controller * my_idct_ptr;
-
- /* Allocated multiplier tables: big enough for any supported variant */
-
- typedef union {
- ISLOW_MULT_TYPE islow_array[DCTSIZE2];
- #ifdef DCT_IFAST_SUPPORTED
- IFAST_MULT_TYPE ifast_array[DCTSIZE2];
- #endif
- #ifdef DCT_FLOAT_SUPPORTED
- FLOAT_MULT_TYPE float_array[DCTSIZE2];
- #endif
- } multiplier_table;
-
- /* The current scaled-IDCT routines require ISLOW-style multiplier tables,
- * so be sure to compile that code if either ISLOW or SCALING is requested.
- */
- #ifdef DCT_ISLOW_SUPPORTED
- #define PROVIDE_ISLOW_TABLES
- #else
- #ifdef IDCT_SCALING_SUPPORTED
- #define PROVIDE_ISLOW_TABLES
- #endif
- #endif
-
- /*
- * Prepare for an output pass.
- * Here we select the proper IDCT routine for each component and build
- * a matching multiplier table.
- */
-
- METHODDEF(void)
- start_pass (j_decompress_ptr cinfo)
- {
- my_idct_ptr idct = (my_idct_ptr) cinfo->idct;
- int ci, i;
- jpeg_component_info *compptr;
- int method = 0;
- inverse_DCT_method_ptr method_ptr = NULL;
- JQUANT_TBL * qtbl;
-
- for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
- ci++, compptr++) {
- /* Select the proper IDCT routine for this component's scaling */
- switch (compptr->DCT_scaled_size) {
- #ifdef IDCT_SCALING_SUPPORTED
- case 1:
- method_ptr = jpeg_idct_1x1;
- method = JDCT_ISLOW; /* jidctred uses islow-style table */
- break;
- case 2:
- method_ptr = jpeg_idct_2x2;
- method = JDCT_ISLOW; /* jidctred uses islow-style table */
- break;
- case 4:
- method_ptr = jpeg_idct_4x4;
- method = JDCT_ISLOW; /* jidctred uses islow-style table */
- break;
- #endif
- case DCTSIZE:
- switch (cinfo->dct_method) {
- #ifdef DCT_ISLOW_SUPPORTED
- case JDCT_ISLOW:
- method_ptr = jpeg_idct_islow;
- method = JDCT_ISLOW;
- break;
- #endif
- #ifdef DCT_IFAST_SUPPORTED
- case JDCT_IFAST:
- method_ptr = jpeg_idct_ifast;
- method = JDCT_IFAST;
- break;
- #endif
- #ifdef DCT_FLOAT_SUPPORTED
- case JDCT_FLOAT:
- method_ptr = jpeg_idct_float;
- method = JDCT_FLOAT;
- break;
- #endif
- default:
- ERREXIT(cinfo, JERR_NOT_COMPILED);
- break;
- }
- break;
- default:
- ERREXIT1(cinfo, JERR_BAD_DCTSIZE, compptr->DCT_scaled_size);
- break;
- }
- idct->pub.inverse_DCT[ci] = method_ptr;
- /* Create multiplier table from quant table.
- * However, we can skip this if the component is uninteresting
- * or if we already built the table. Also, if no quant table
- * has yet been saved for the component, we leave the
- * multiplier table all-zero; we'll be reading zeroes from the
- * coefficient controller's buffer anyway.
- */
- if (! compptr->component_needed || idct->cur_method[ci] == method)
- continue;
- qtbl = compptr->quant_table;
- if (qtbl == NULL) /* happens if no data yet for component */
- continue;
- idct->cur_method[ci] = method;
- switch (method) {
- #ifdef PROVIDE_ISLOW_TABLES
- case JDCT_ISLOW:
- {
- /* For LL&M IDCT method, multipliers are equal to raw quantization
- * coefficients, but are stored as ints to ensure access efficiency.
- */
- ISLOW_MULT_TYPE * ismtbl = (ISLOW_MULT_TYPE *) compptr->dct_table;
- for (i = 0; i < DCTSIZE2; i++) {
- ismtbl[i] = (ISLOW_MULT_TYPE) qtbl->quantval[i];
- }
- }
- break;
- #endif
- #ifdef DCT_IFAST_SUPPORTED
- case JDCT_IFAST:
- {
- /* For AA&N IDCT method, multipliers are equal to quantization
- * coefficients scaled by scalefactor[row]*scalefactor[col], where
- * scalefactor[0] = 1
- * scalefactor[k] = cos(k*PI/16) * sqrt(2) for k=1..7
- * For integer operation, the multiplier table is to be scaled by
- * IFAST_SCALE_BITS.
- */
- IFAST_MULT_TYPE * ifmtbl = (IFAST_MULT_TYPE *) compptr->dct_table;
- #define CONST_BITS 14
- static const INT16 aanscales[DCTSIZE2] = {
- /* precomputed values scaled up by 14 bits */
- 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520,
- 22725, 31521, 29692, 26722, 22725, 17855, 12299, 6270,
- 21407, 29692, 27969, 25172, 21407, 16819, 11585, 5906,
- 19266, 26722, 25172, 22654, 19266, 15137, 10426, 5315,
- 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520,
- 12873, 17855, 16819, 15137, 12873, 10114, 6967, 3552,
- 8867, 12299, 11585, 10426, 8867, 6967, 4799, 2446,
- 4520, 6270, 5906, 5315, 4520, 3552, 2446, 1247
- };
- SHIFT_TEMPS
-
- for (i = 0; i < DCTSIZE2; i++) {
- ifmtbl[i] = (IFAST_MULT_TYPE)
- DESCALE(MULTIPLY16V16((INT32) qtbl->quantval[i],
- (INT32) aanscales[i]),
- CONST_BITS-IFAST_SCALE_BITS);
- }
- }
- break;
- #endif
- #ifdef DCT_FLOAT_SUPPORTED
- case JDCT_FLOAT:
- {
- /* For float AA&N IDCT method, multipliers are equal to quantization
- * coefficients scaled by scalefactor[row]*scalefactor[col], where
- * scalefactor[0] = 1
- * scalefactor[k] = cos(k*PI/16) * sqrt(2) for k=1..7
- */
- FLOAT_MULT_TYPE * fmtbl = (FLOAT_MULT_TYPE *) compptr->dct_table;
- int row, col;
- static const double aanscalefactor[DCTSIZE] = {
- 1.0, 1.387039845, 1.306562965, 1.175875602,
- 1.0, 0.785694958, 0.541196100, 0.275899379
- };
-
- i = 0;
- for (row = 0; row < DCTSIZE; row++) {
- for (col = 0; col < DCTSIZE; col++) {
- fmtbl[i] = (FLOAT_MULT_TYPE)
- ((double) qtbl->quantval[i] *
- aanscalefactor[row] * aanscalefactor[col]);
- i++;
- }
- }
- }
- break;
- #endif
- default:
- ERREXIT(cinfo, JERR_NOT_COMPILED);
- break;
- }
- }
- }
-
- /*
- * Initialize IDCT manager.
- */
-
- GLOBAL(void)
- jinit_inverse_dct (j_decompress_ptr cinfo)
- {
- my_idct_ptr idct;
- int ci;
- jpeg_component_info *compptr;
-
- idct = (my_idct_ptr)
- (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
- SIZEOF(my_idct_controller));
- cinfo->idct = (struct jpeg_inverse_dct *) idct;
- idct->pub.start_pass = start_pass;
-
- for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
- ci++, compptr++) {
- /* Allocate and pre-zero a multiplier table for each component */
- compptr->dct_table =
- (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
- SIZEOF(multiplier_table));
- MEMZERO(compptr->dct_table, SIZEOF(multiplier_table));
- /* Mark multiplier table not yet set up for any method */
- idct->cur_method[ci] = -1;
- }
- }
- /********* End of inlined file: jddctmgr.c *********/
-
- #undef CONST_BITS
- #undef ASSIGN_STATE
-
- /********* Start of inlined file: jdhuff.c *********/
- #define JPEG_INTERNALS
-
- /********* Start of inlined file: jdhuff.h *********/
- /* Short forms of external names for systems with brain-damaged linkers. */
-
- #ifndef __jdhuff_h__
- #define __jdhuff_h__
-
- #ifdef NEED_SHORT_EXTERNAL_NAMES
- #define jpeg_make_d_derived_tbl jMkDDerived
- #define jpeg_fill_bit_buffer jFilBitBuf
- #define jpeg_huff_decode jHufDecode
- #endif /* NEED_SHORT_EXTERNAL_NAMES */
-
- /* Derived data constructed for each Huffman table */
-
- #define HUFF_LOOKAHEAD 8 /* # of bits of lookahead */
-
- typedef struct {
- /* Basic tables: (element [0] of each array is unused) */
- INT32 maxcode[18]; /* largest code of length k (-1 if none) */
- /* (maxcode[17] is a sentinel to ensure jpeg_huff_decode terminates) */
- INT32 valoffset[17]; /* huffval[] offset for codes of length k */
- /* valoffset[k] = huffval[] index of 1st symbol of code length k, less
- * the smallest code of length k; so given a code of length k, the
- * corresponding symbol is huffval[code + valoffset[k]]
- */
-
- /* Link to public Huffman table (needed only in jpeg_huff_decode) */
- JHUFF_TBL *pub;
-
- /* Lookahead tables: indexed by the next HUFF_LOOKAHEAD bits of
- * the input data stream. If the next Huffman code is no more
- * than HUFF_LOOKAHEAD bits long, we can obtain its length and
- * the corresponding symbol directly from these tables.
- */
- int look_nbits[1<<HUFF_LOOKAHEAD]; /* # bits, or 0 if too long */
- UINT8 look_sym[1<<HUFF_LOOKAHEAD]; /* symbol, or unused */
- } d_derived_tbl;
-
- /* Expand a Huffman table definition into the derived format */
- EXTERN(void) jpeg_make_d_derived_tbl
- JPP((j_decompress_ptr cinfo, boolean isDC, int tblno,
- d_derived_tbl ** pdtbl));
-
- /*
- * Fetching the next N bits from the input stream is a time-critical operation
- * for the Huffman decoders. We implement it with a combination of inline
- * macros and out-of-line subroutines. Note that N (the number of bits
- * demanded at one time) never exceeds 15 for JPEG use.
- *
- * We read source bytes into get_buffer and dole out bits as needed.
- * If get_buffer already contains enough bits, they are fetched in-line
- * by the macros CHECK_BIT_BUFFER and GET_BITS. When there aren't enough
- * bits, jpeg_fill_bit_buffer is called; it will attempt to fill get_buffer
- * as full as possible (not just to the number of bits needed; this
- * prefetching reduces the overhead cost of calling jpeg_fill_bit_buffer).
- * Note that jpeg_fill_bit_buffer may return FALSE to indicate suspension.
- * On TRUE return, jpeg_fill_bit_buffer guarantees that get_buffer contains
- * at least the requested number of bits --- dummy zeroes are inserted if
- * necessary.
- */
-
- typedef INT32 bit_buf_type; /* type of bit-extraction buffer */
- #define BIT_BUF_SIZE 32 /* size of buffer in bits */
-
- /* If long is > 32 bits on your machine, and shifting/masking longs is
- * reasonably fast, making bit_buf_type be long and setting BIT_BUF_SIZE
- * appropriately should be a win. Unfortunately we can't define the size
- * with something like #define BIT_BUF_SIZE (sizeof(bit_buf_type)*8)
- * because not all machines measure sizeof in 8-bit bytes.
- */
-
- typedef struct { /* Bitreading state saved across MCUs */
- bit_buf_type get_buffer; /* current bit-extraction buffer */
- int bits_left; /* # of unused bits in it */
- } bitread_perm_state;
-
- typedef struct { /* Bitreading working state within an MCU */
- /* Current data source location */
- /* We need a copy, rather than munging the original, in case of suspension */
- const JOCTET * next_input_byte; /* => next byte to read from source */
- size_t bytes_in_buffer; /* # of bytes remaining in source buffer */
- /* Bit input buffer --- note these values are kept in register variables,
- * not in this struct, inside the inner loops.
- */
- bit_buf_type get_buffer; /* current bit-extraction buffer */
- int bits_left; /* # of unused bits in it */
- /* Pointer needed by jpeg_fill_bit_buffer. */
- j_decompress_ptr cinfo; /* back link to decompress master record */
- } bitread_working_state;
-
- /* Macros to declare and load/save bitread local variables. */
- #define BITREAD_STATE_VARS \
- register bit_buf_type get_buffer; \
- register int bits_left; \
- bitread_working_state br_state
-
- #define BITREAD_LOAD_STATE(cinfop,permstate) \
- br_state.cinfo = cinfop; \
- br_state.next_input_byte = cinfop->src->next_input_byte; \
- br_state.bytes_in_buffer = cinfop->src->bytes_in_buffer; \
- get_buffer = permstate.get_buffer; \
- bits_left = permstate.bits_left;
-
- #define BITREAD_SAVE_STATE(cinfop,permstate) \
- cinfop->src->next_input_byte = br_state.next_input_byte; \
- cinfop->src->bytes_in_buffer = br_state.bytes_in_buffer; \
- permstate.get_buffer = get_buffer; \
- permstate.bits_left = bits_left
-
- /*
- * These macros provide the in-line portion of bit fetching.
- * Use CHECK_BIT_BUFFER to ensure there are N bits in get_buffer
- * before using GET_BITS, PEEK_BITS, or DROP_BITS.
- * The variables get_buffer and bits_left are assumed to be locals,
- * but the state struct might not be (jpeg_huff_decode needs this).
- * CHECK_BIT_BUFFER(state,n,action);
- * Ensure there are N bits in get_buffer; if suspend, take action.
- * val = GET_BITS(n);
- * Fetch next N bits.
- * val = PEEK_BITS(n);
- * Fetch next N bits without removing them from the buffer.
- * DROP_BITS(n);
- * Discard next N bits.
- * The value N should be a simple variable, not an expression, because it
- * is evaluated multiple times.
- */
-
- #define CHECK_BIT_BUFFER(state,nbits,action) \
- { if (bits_left < (nbits)) { \
- if (! jpeg_fill_bit_buffer(&(state),get_buffer,bits_left,nbits)) \
- { action; } \
- get_buffer = (state).get_buffer; bits_left = (state).bits_left; } }
-
- #define GET_BITS(nbits) \
- (((int) (get_buffer >> (bits_left -= (nbits)))) & ((1<<(nbits))-1))
-
- #define PEEK_BITS(nbits) \
- (((int) (get_buffer >> (bits_left - (nbits)))) & ((1<<(nbits))-1))
-
- #define DROP_BITS(nbits) \
- (bits_left -= (nbits))
-
- /* Load up the bit buffer to a depth of at least nbits */
- EXTERN(boolean) jpeg_fill_bit_buffer
- JPP((bitread_working_state * state, register bit_buf_type get_buffer,
- register int bits_left, int nbits));
-
- /*
- * Code for extracting next Huffman-coded symbol from input bit stream.
- * Again, this is time-critical and we make the main paths be macros.
- *
- * We use a lookahead table to process codes of up to HUFF_LOOKAHEAD bits
- * without looping. Usually, more than 95% of the Huffman codes will be 8
- * or fewer bits long. The few overlength codes are handled with a loop,
- * which need not be inline code.
- *
- * Notes about the HUFF_DECODE macro:
- * 1. Near the end of the data segment, we may fail to get enough bits
- * for a lookahead. In that case, we do it the hard way.
- * 2. If the lookahead table contains no entry, the next code must be
- * more than HUFF_LOOKAHEAD bits long.
- * 3. jpeg_huff_decode returns -1 if forced to suspend.
- */
-
- #define HUFF_DECODE(result,state,htbl,failaction,slowlabel) \
- { register int nb, look; \
- if (bits_left < HUFF_LOOKAHEAD) { \
- if (! jpeg_fill_bit_buffer(&state,get_buffer,bits_left, 0)) {failaction;} \
- get_buffer = state.get_buffer; bits_left = state.bits_left; \
- if (bits_left < HUFF_LOOKAHEAD) { \
- nb = 1; goto slowlabel; \
- } \
- } \
- look = PEEK_BITS(HUFF_LOOKAHEAD); \
- if ((nb = htbl->look_nbits[look]) != 0) { \
- DROP_BITS(nb); \
- result = htbl->look_sym[look]; \
- } else { \
- nb = HUFF_LOOKAHEAD+1; \
- slowlabel: \
- if ((result=jpeg_huff_decode(&state,get_buffer,bits_left,htbl,nb)) < 0) \
- { failaction; } \
- get_buffer = state.get_buffer; bits_left = state.bits_left; \
- } \
- }
-
- /* Out-of-line case for Huffman code fetching */
- EXTERN(int) jpeg_huff_decode
- JPP((bitread_working_state * state, register bit_buf_type get_buffer,
- register int bits_left, d_derived_tbl * htbl, int min_bits));
-
- #endif
- /********* End of inlined file: jdhuff.h *********/
-
- /* Declarations shared with jdphuff.c */
-
- /*
- * Expanded entropy decoder object for Huffman decoding.
- *
- * The savable_state subrecord contains fields that change within an MCU,
- * but must not be updated permanently until we complete the MCU.
- */
-
- typedef struct {
- int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */
- } savable_state2;
-
- /* This macro is to work around compilers with missing or broken
- * structure assignment. You'll need to fix this code if you have
- * such a compiler and you change MAX_COMPS_IN_SCAN.
- */
-
- #ifndef NO_STRUCT_ASSIGN
- #define ASSIGN_STATE(dest,src) ((dest) = (src))
- #else
- #if MAX_COMPS_IN_SCAN == 4
- #define ASSIGN_STATE(dest,src) \
- ((dest).last_dc_val[0] = (src).last_dc_val[0], \
- (dest).last_dc_val[1] = (src).last_dc_val[1], \
- (dest).last_dc_val[2] = (src).last_dc_val[2], \
- (dest).last_dc_val[3] = (src).last_dc_val[3])
- #endif
- #endif
-
- typedef struct {
- struct jpeg_entropy_decoder pub; /* public fields */
-
- /* These fields are loaded into local variables at start of each MCU.
- * In case of suspension, we exit WITHOUT updating them.
- */
- bitread_perm_state bitstate; /* Bit buffer at start of MCU */
- savable_state2 saved; /* Other state at start of MCU */
-
- /* These fields are NOT loaded into local working state. */
- unsigned int restarts_to_go; /* MCUs left in this restart interval */
-
- /* Pointers to derived tables (these workspaces have image lifespan) */
- d_derived_tbl * dc_derived_tbls[NUM_HUFF_TBLS];
- d_derived_tbl * ac_derived_tbls[NUM_HUFF_TBLS];
-
- /* Precalculated info set up by start_pass for use in decode_mcu: */
-
- /* Pointers to derived tables to be used for each block within an MCU */
- d_derived_tbl * dc_cur_tbls[D_MAX_BLOCKS_IN_MCU];
- d_derived_tbl * ac_cur_tbls[D_MAX_BLOCKS_IN_MCU];
- /* Whether we care about the DC and AC coefficient values for each block */
- boolean dc_needed[D_MAX_BLOCKS_IN_MCU];
- boolean ac_needed[D_MAX_BLOCKS_IN_MCU];
- } huff_entropy_decoder2;
-
- typedef huff_entropy_decoder2 * huff_entropy_ptr2;
-
- /*
- * Initialize for a Huffman-compressed scan.
- */
-
- METHODDEF(void)
- start_pass_huff_decoder (j_decompress_ptr cinfo)
- {
- huff_entropy_ptr2 entropy = (huff_entropy_ptr2) cinfo->entropy;
- int ci, blkn, dctbl, actbl;
- jpeg_component_info * compptr;
-
- /* Check that the scan parameters Ss, Se, Ah/Al are OK for sequential JPEG.
- * This ought to be an error condition, but we make it a warning because
- * there are some baseline files out there with all zeroes in these bytes.
- */
- if (cinfo->Ss != 0 || cinfo->Se != DCTSIZE2-1 ||
- cinfo->Ah != 0 || cinfo->Al != 0)
- WARNMS(cinfo, JWRN_NOT_SEQUENTIAL);
-
- for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
- compptr = cinfo->cur_comp_info[ci];
- dctbl = compptr->dc_tbl_no;
- actbl = compptr->ac_tbl_no;
- /* Compute derived values for Huffman tables */
- /* We may do this more than once for a table, but it's not expensive */
- jpeg_make_d_derived_tbl(cinfo, TRUE, dctbl,
- & entropy->dc_derived_tbls[dctbl]);
- jpeg_make_d_derived_tbl(cinfo, FALSE, actbl,
- & entropy->ac_derived_tbls[actbl]);
- /* Initialize DC predictions to 0 */
- entropy->saved.last_dc_val[ci] = 0;
- }
-
- /* Precalculate decoding info for each block in an MCU of this scan */
- for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
- ci = cinfo->MCU_membership[blkn];
- compptr = cinfo->cur_comp_info[ci];
- /* Precalculate which table to use for each block */
- entropy->dc_cur_tbls[blkn] = entropy->dc_derived_tbls[compptr->dc_tbl_no];
- entropy->ac_cur_tbls[blkn] = entropy->ac_derived_tbls[compptr->ac_tbl_no];
- /* Decide whether we really care about the coefficient values */
- if (compptr->component_needed) {
- entropy->dc_needed[blkn] = TRUE;
- /* we don't need the ACs if producing a 1/8th-size image */
- entropy->ac_needed[blkn] = (compptr->DCT_scaled_size > 1);
- } else {
- entropy->dc_needed[blkn] = entropy->ac_needed[blkn] = FALSE;
- }
- }
-
- /* Initialize bitread state variables */
- entropy->bitstate.bits_left = 0;
- entropy->bitstate.get_buffer = 0; /* unnecessary, but keeps Purify quiet */
- entropy->pub.insufficient_data = FALSE;
-
- /* Initialize restart counter */
- entropy->restarts_to_go = cinfo->restart_interval;
- }
-
- /*
- * Compute the derived values for a Huffman table.
- * This routine also performs some validation checks on the table.
- *
- * Note this is also used by jdphuff.c.
- */
-
- GLOBAL(void)
- jpeg_make_d_derived_tbl (j_decompress_ptr cinfo, boolean isDC, int tblno,
- d_derived_tbl ** pdtbl)
- {
- JHUFF_TBL *htbl;
- d_derived_tbl *dtbl;
- int p, i, l, si, numsymbols;
- int lookbits, ctr;
- char huffsize[257];
- unsigned int huffcode[257];
- unsigned int code;
-
- /* Note that huffsize[] and huffcode[] are filled in code-length order,
- * paralleling the order of the symbols themselves in htbl->huffval[].
- */
-
- /* Find the input Huffman table */
- if (tblno < 0 || tblno >= NUM_HUFF_TBLS)
- ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tblno);
- htbl =
- isDC ? cinfo->dc_huff_tbl_ptrs[tblno] : cinfo->ac_huff_tbl_ptrs[tblno];
- if (htbl == NULL)
- ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tblno);
-
- /* Allocate a workspace if we haven't already done so. */
- if (*pdtbl == NULL)
- *pdtbl = (d_derived_tbl *)
- (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
- SIZEOF(d_derived_tbl));
- dtbl = *pdtbl;
- dtbl->pub = htbl; /* fill in back link */
-
- /* Figure C.1: make table of Huffman code length for each symbol */
-
- p = 0;
- for (l = 1; l <= 16; l++) {
- i = (int) htbl->bits[l];
- if (i < 0 || p + i > 256) /* protect against table overrun */
- ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
- while (i--)
- huffsize[p++] = (char) l;
- }
- huffsize[p] = 0;
- numsymbols = p;
-
- /* Figure C.2: generate the codes themselves */
- /* We also validate that the counts represent a legal Huffman code tree. */
-
- code = 0;
- si = huffsize[0];
- p = 0;
- while (huffsize[p]) {
- while (((int) huffsize[p]) == si) {
- huffcode[p++] = code;
- code++;
- }
- /* code is now 1 more than the last code used for codelength si; but
- * it must still fit in si bits, since no code is allowed to be all ones.
- */
- if (((INT32) code) >= (((INT32) 1) << si))
- ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
- code <<= 1;
- si++;
- }
-
- /* Figure F.15: generate decoding tables for bit-sequential decoding */
-
- p = 0;
- for (l = 1; l <= 16; l++) {
- if (htbl->bits[l]) {
- /* valoffset[l] = huffval[] index of 1st symbol of code length l,
- * minus the minimum code of length l
- */
- dtbl->valoffset[l] = (INT32) p - (INT32) huffcode[p];
- p += htbl->bits[l];
- dtbl->maxcode[l] = huffcode[p-1]; /* maximum code of length l */
- } else {
- dtbl->maxcode[l] = -1; /* -1 if no codes of this length */
- }
- }
- dtbl->maxcode[17] = 0xFFFFFL; /* ensures jpeg_huff_decode terminates */
-
- /* Compute lookahead tables to speed up decoding.
- * First we set all the table entries to 0, indicating "too long";
- * then we iterate through the Huffman codes that are short enough and
- * fill in all the entries that correspond to bit sequences starting
- * with that code.
- */
-
- MEMZERO(dtbl->look_nbits, SIZEOF(dtbl->look_nbits));
-
- p = 0;
- for (l = 1; l <= HUFF_LOOKAHEAD; l++) {
- for (i = 1; i <= (int) htbl->bits[l]; i++, p++) {
- /* l = current code's length, p = its index in huffcode[] & huffval[]. */
- /* Generate left-justified code followed by all possible bit sequences */
- lookbits = huffcode[p] << (HUFF_LOOKAHEAD-l);
- for (ctr = 1 << (HUFF_LOOKAHEAD-l); ctr > 0; ctr--) {
- dtbl->look_nbits[lookbits] = l;
- dtbl->look_sym[lookbits] = htbl->huffval[p];
- lookbits++;
- }
- }
- }
-
- /* Validate symbols as being reasonable.
- * For AC tables, we make no check, but accept all byte values 0..255.
- * For DC tables, we require the symbols to be in range 0..15.
- * (Tighter bounds could be applied depending on the data depth and mode,
- * but this is sufficient to ensure safe decoding.)
- */
- if (isDC) {
- for (i = 0; i < numsymbols; i++) {
- int sym = htbl->huffval[i];
- if (sym < 0 || sym > 15)
- ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
- }
- }
- }
-
- /*
- * Out-of-line code for bit fetching (shared with jdphuff.c).
- * See jdhuff.h for info about usage.
- * Note: current values of get_buffer and bits_left are passed as parameters,
- * but are returned in the corresponding fields of the state struct.
- *
- * On most machines MIN_GET_BITS should be 25 to allow the full 32-bit width
- * of get_buffer to be used. (On machines with wider words, an even larger
- * buffer could be used.) However, on some machines 32-bit shifts are
- * quite slow and take time proportional to the number of places shifted.
- * (This is true with most PC compilers, for instance.) In this case it may
- * be a win to set MIN_GET_BITS to the minimum value of 15. This reduces the
- * average shift distance at the cost of more calls to jpeg_fill_bit_buffer.
- */
-
- #ifdef SLOW_SHIFT_32
- #define MIN_GET_BITS 15 /* minimum allowable value */
- #else
- #define MIN_GET_BITS (BIT_BUF_SIZE-7)
- #endif
-
- GLOBAL(boolean)
- jpeg_fill_bit_buffer (bitread_working_state * state,
- register bit_buf_type get_buffer, register int bits_left,
- int nbits)
- /* Load up the bit buffer to a depth of at least nbits */
- {
- /* Copy heavily used state fields into locals (hopefully registers) */
- register const JOCTET * next_input_byte = state->next_input_byte;
- register size_t bytes_in_buffer = state->bytes_in_buffer;
- j_decompress_ptr cinfo = state->cinfo;
-
- /* Attempt to load at least MIN_GET_BITS bits into get_buffer. */
- /* (It is assumed that no request will be for more than that many bits.) */
- /* We fail to do so only if we hit a marker or are forced to suspend. */
-
- if (cinfo->unread_marker == 0) { /* cannot advance past a marker */
- while (bits_left < MIN_GET_BITS) {
- register int c;
-
- /* Attempt to read a byte */
- if (bytes_in_buffer == 0) {
- if (! (*cinfo->src->fill_input_buffer) (cinfo))
- return FALSE;
- next_input_byte = cinfo->src->next_input_byte;
- bytes_in_buffer = cinfo->src->bytes_in_buffer;
- }
- bytes_in_buffer--;
- c = GETJOCTET(*next_input_byte++);
-
- /* If it's 0xFF, check and discard stuffed zero byte */
- if (c == 0xFF) {
- /* Loop here to discard any padding FF's on terminating marker,
- * so that we can save a valid unread_marker value. NOTE: we will
- * accept multiple FF's followed by a 0 as meaning a single FF data
- * byte. This data pattern is not valid according to the standard.
- */
- do {
- if (bytes_in_buffer == 0) {
- if (! (*cinfo->src->fill_input_buffer) (cinfo))
- return FALSE;
- next_input_byte = cinfo->src->next_input_byte;
- bytes_in_buffer = cinfo->src->bytes_in_buffer;
- }
- bytes_in_buffer--;
- c = GETJOCTET(*next_input_byte++);
- } while (c == 0xFF);
-
- if (c == 0) {
- /* Found FF/00, which represents an FF data byte */
- c = 0xFF;
- } else {
- /* Oops, it's actually a marker indicating end of compressed data.
- * Save the marker code for later use.
- * Fine point: it might appear that we should save the marker into
- * bitread working state, not straight into permanent state. But
- * once we have hit a marker, we cannot need to suspend within the
- * current MCU, because we will read no more bytes from the data
- * source. So it is OK to update permanent state right away.
- */
- cinfo->unread_marker = c;
- /* See if we need to insert some fake zero bits. */
- goto no_more_bytes;
- }
- }
-
- /* OK, load c into get_buffer */
- get_buffer = (get_buffer << 8) | c;
- bits_left += 8;
- } /* end while */
- } else {
- no_more_bytes:
- /* We get here if we've read the marker that terminates the compressed
- * data segment. There should be enough bits in the buffer register
- * to satisfy the request; if so, no problem.
- */
- if (nbits > bits_left) {
- /* Uh-oh. Report corrupted data to user and stuff zeroes into
- * the data stream, so that we can produce some kind of image.
- * We use a nonvolatile flag to ensure that only one warning message
- * appears per data segment.
- */
- if (! cinfo->entropy->insufficient_data) {
- WARNMS(cinfo, JWRN_HIT_MARKER);
- cinfo->entropy->insufficient_data = TRUE;
- }
- /* Fill the buffer with zero bits */
- get_buffer <<= MIN_GET_BITS - bits_left;
- bits_left = MIN_GET_BITS;
- }
- }
-
- /* Unload the local registers */
- state->next_input_byte = next_input_byte;
- state->bytes_in_buffer = bytes_in_buffer;
- state->get_buffer = get_buffer;
- state->bits_left = bits_left;
-
- return TRUE;
- }
-
- /*
- * Out-of-line code for Huffman code decoding.
- * See jdhuff.h for info about usage.
- */
-
- GLOBAL(int)
- jpeg_huff_decode (bitread_working_state * state,
- register bit_buf_type get_buffer, register int bits_left,
- d_derived_tbl * htbl, int min_bits)
- {
- register int l = min_bits;
- register INT32 code;
-
- /* HUFF_DECODE has determined that the code is at least min_bits */
- /* bits long, so fetch that many bits in one swoop. */
-
- CHECK_BIT_BUFFER(*state, l, return -1);
- code = GET_BITS(l);
-
- /* Collect the rest of the Huffman code one bit at a time. */
- /* This is per Figure F.16 in the JPEG spec. */
-
- while (code > htbl->maxcode[l]) {
- code <<= 1;
- CHECK_BIT_BUFFER(*state, 1, return -1);
- code |= GET_BITS(1);
- l++;
- }
-
- /* Unload the local registers */
- state->get_buffer = get_buffer;
- state->bits_left = bits_left;
-
- /* With garbage input we may reach the sentinel value l = 17. */
-
- if (l > 16) {
- WARNMS(state->cinfo, JWRN_HUFF_BAD_CODE);
- return 0; /* fake a zero as the safest result */
- }
-
- return htbl->pub->huffval[ (int) (code + htbl->valoffset[l]) ];
- }
-
- /*
- * Check for a restart marker & resynchronize decoder.
- * Returns FALSE if must suspend.
- */
-
- LOCAL(boolean)
- process_restart (j_decompress_ptr cinfo)
- {
- huff_entropy_ptr2 entropy = (huff_entropy_ptr2) cinfo->entropy;
- int ci;
-
- /* Throw away any unused bits remaining in bit buffer; */
- /* include any full bytes in next_marker's count of discarded bytes */
- cinfo->marker->discarded_bytes += entropy->bitstate.bits_left / 8;
- entropy->bitstate.bits_left = 0;
-
- /* Advance past the RSTn marker */
- if (! (*cinfo->marker->read_restart_marker) (cinfo))
- return FALSE;
-
- /* Re-initialize DC predictions to 0 */
- for (ci = 0; ci < cinfo->comps_in_scan; ci++)
- entropy->saved.last_dc_val[ci] = 0;
-
- /* Reset restart counter */
- entropy->restarts_to_go = cinfo->restart_interval;
-
- /* Reset out-of-data flag, unless read_restart_marker left us smack up
- * against a marker. In that case we will end up treating the next data
- * segment as empty, and we can avoid producing bogus output pixels by
- * leaving the flag set.
- */
- if (cinfo->unread_marker == 0)
- entropy->pub.insufficient_data = FALSE;
-
- return TRUE;
- }
-
- /*
- * Decode and return one MCU's worth of Huffman-compressed coefficients.
- * The coefficients are reordered from zigzag order into natural array order,
- * but are not dequantized.
- *
- * The i'th block of the MCU is stored into the block pointed to by
- * MCU_data[i]. WE ASSUME THIS AREA HAS BEEN ZEROED BY THE CALLER.
- * (Wholesale zeroing is usually a little faster than retail...)
- *
- * Returns FALSE if data source requested suspension. In that case no
- * changes have been made to permanent state. (Exception: some output
- * coefficients may already have been assigned. This is harmless for
- * this module, since we'll just re-assign them on the next call.)
- */
-
- METHODDEF(boolean)
- decode_mcu (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
- {
- huff_entropy_ptr2 entropy = (huff_entropy_ptr2) cinfo->entropy;
- int blkn;
- BITREAD_STATE_VARS;
- savable_state2 state;
-
- /* Process restart marker if needed; may have to suspend */
- if (cinfo->restart_interval) {
- if (entropy->restarts_to_go == 0)
- if (! process_restart(cinfo))
- return FALSE;
- }
-
- /* If we've run out of data, just leave the MCU set to zeroes.
- * This way, we return uniform gray for the remainder of the segment.
- */
- if (! entropy->pub.insufficient_data) {
-
- /* Load up working state */
- BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
- ASSIGN_STATE(state, entropy->saved);
-
- /* Outer loop handles each block in the MCU */
-
- for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
- JBLOCKROW block = MCU_data[blkn];
- d_derived_tbl * dctbl = entropy->dc_cur_tbls[blkn];
- d_derived_tbl * actbl = entropy->ac_cur_tbls[blkn];
- register int s, k, r;
-
- /* Decode a single block's worth of coefficients */
-
- /* Section F.2.2.1: decode the DC coefficient difference */
- HUFF_DECODE(s, br_state, dctbl, return FALSE, label1);
- if (s) {
- CHECK_BIT_BUFFER(br_state, s, return FALSE);
- r = GET_BITS(s);
- s = HUFF_EXTEND(r, s);
- }
-
- if (entropy->dc_needed[blkn]) {
- /* Convert DC difference to actual value, update last_dc_val */
- int ci = cinfo->MCU_membership[blkn];
- s += state.last_dc_val[ci];
- state.last_dc_val[ci] = s;
- /* Output the DC coefficient (assumes jpeg_natural_order[0] = 0) */
- (*block)[0] = (JCOEF) s;
- }
-
- if (entropy->ac_needed[blkn]) {
-
- /* Section F.2.2.2: decode the AC coefficients */
- /* Since zeroes are skipped, output area must be cleared beforehand */
- for (k = 1; k < DCTSIZE2; k++) {
- HUFF_DECODE(s, br_state, actbl, return FALSE, label2);
-
- r = s >> 4;
- s &= 15;
-
- if (s) {
- k += r;
- CHECK_BIT_BUFFER(br_state, s, return FALSE);
- r = GET_BITS(s);
- s = HUFF_EXTEND(r, s);
- /* Output coefficient in natural (dezigzagged) order.
- * Note: the extra entries in jpeg_natural_order[] will save us
- * if k >= DCTSIZE2, which could happen if the data is corrupted.
- */
- (*block)[jpeg_natural_order[k]] = (JCOEF) s;
- } else {
- if (r != 15)
- break;
- k += 15;
- }
- }
-
- } else {
-
- /* Section F.2.2.2: decode the AC coefficients */
- /* In this path we just discard the values */
- for (k = 1; k < DCTSIZE2; k++) {
- HUFF_DECODE(s, br_state, actbl, return FALSE, label3);
-
- r = s >> 4;
- s &= 15;
-
- if (s) {
- k += r;
- CHECK_BIT_BUFFER(br_state, s, return FALSE);
- DROP_BITS(s);
- } else {
- if (r != 15)
- break;
- k += 15;
- }
- }
-
- }
- }
-
- /* Completed MCU, so update state */
- BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
- ASSIGN_STATE(entropy->saved, state);
- }
-
- /* Account for restart interval (no-op if not using restarts) */
- entropy->restarts_to_go--;
-
- return TRUE;
- }
-
- /*
- * Module initialization routine for Huffman entropy decoding.
- */
-
- GLOBAL(void)
- jinit_huff_decoder (j_decompress_ptr cinfo)
- {
- huff_entropy_ptr2 entropy;
- int i;
-
- entropy = (huff_entropy_ptr2)
- (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
- SIZEOF(huff_entropy_decoder2));
- cinfo->entropy = (struct jpeg_entropy_decoder *) entropy;
- entropy->pub.start_pass = start_pass_huff_decoder;
- entropy->pub.decode_mcu = decode_mcu;
-
- /* Mark tables unallocated */
- for (i = 0; i < NUM_HUFF_TBLS; i++) {
- entropy->dc_derived_tbls[i] = entropy->ac_derived_tbls[i] = NULL;
- }
- }
- /********* End of inlined file: jdhuff.c *********/
-
- /********* Start of inlined file: jdinput.c *********/
- #define JPEG_INTERNALS
-
- /* Private state */
-
- typedef struct {
- struct jpeg_input_controller pub; /* public fields */
-
- boolean inheaders; /* TRUE until first SOS is reached */
- } my_input_controller;
-
- typedef my_input_controller * my_inputctl_ptr;
-
- /* Forward declarations */
- METHODDEF(int) consume_markers JPP((j_decompress_ptr cinfo));
-
- /*
- * Routines to calculate various quantities related to the size of the image.
- */
-
- LOCAL(void)
- initial_setup2 (j_decompress_ptr cinfo)
- /* Called once, when first SOS marker is reached */
- {
- int ci;
- jpeg_component_info *compptr;
-
- /* Make sure image isn't bigger than I can handle */
- if ((long) cinfo->image_height > (long) JPEG_MAX_DIMENSION ||
- (long) cinfo->image_width > (long) JPEG_MAX_DIMENSION)
- ERREXIT1(cinfo, JERR_IMAGE_TOO_BIG, (unsigned int) JPEG_MAX_DIMENSION);
-
- /* For now, precision must match compiled-in value... */
- if (cinfo->data_precision != BITS_IN_JSAMPLE)
- ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
-
- /* Check that number of components won't exceed internal array sizes */
- if (cinfo->num_components > MAX_COMPONENTS)
- ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->num_components,
- MAX_COMPONENTS);
-
- /* Compute maximum sampling factors; check factor validity */
- cinfo->max_h_samp_factor = 1;
- cinfo->max_v_samp_factor = 1;
- for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
- ci++, compptr++) {
- if (compptr->h_samp_factor<=0 || compptr->h_samp_factor>MAX_SAMP_FACTOR ||
- compptr->v_samp_factor<=0 || compptr->v_samp_factor>MAX_SAMP_FACTOR)
- ERREXIT(cinfo, JERR_BAD_SAMPLING);
- cinfo->max_h_samp_factor = MAX(cinfo->max_h_samp_factor,
- compptr->h_samp_factor);
- cinfo->max_v_samp_factor = MAX(cinfo->max_v_samp_factor,
- compptr->v_samp_factor);
- }
-
- /* We initialize DCT_scaled_size and min_DCT_scaled_size to DCTSIZE.
- * In the full decompressor, this will be overridden by jdmaster.c;
- * but in the transcoder, jdmaster.c is not used, so we must do it here.
- */
- cinfo->min_DCT_scaled_size = DCTSIZE;
-
- /* Compute dimensions of components */
- for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
- ci++, compptr++) {
- compptr->DCT_scaled_size = DCTSIZE;
- /* Size in DCT blocks */
- compptr->width_in_blocks = (JDIMENSION)
- jdiv_round_up((long) cinfo->image_width * (long) compptr->h_samp_factor,
- (long) (cinfo->max_h_samp_factor * DCTSIZE));
- compptr->height_in_blocks = (JDIMENSION)
- jdiv_round_up((long) cinfo->image_height * (long) compptr->v_samp_factor,
- (long) (cinfo->max_v_samp_factor * DCTSIZE));
- /* downsampled_width and downsampled_height will also be overridden by
- * jdmaster.c if we are doing full decompression. The transcoder library
- * doesn't use these values, but the calling application might.
- */
- /* Size in samples */
- compptr->downsampled_width = (JDIMENSION)
- jdiv_round_up((long) cinfo->image_width * (long) compptr->h_samp_factor,
- (long) cinfo->max_h_samp_factor);
- compptr->downsampled_height = (JDIMENSION)
- jdiv_round_up((long) cinfo->image_height * (long) compptr->v_samp_factor,
- (long) cinfo->max_v_samp_factor);
- /* Mark component needed, until color conversion says otherwise */
- compptr->component_needed = TRUE;
- /* Mark no quantization table yet saved for component */
- compptr->quant_table = NULL;
- }
-
- /* Compute number of fully interleaved MCU rows. */
- cinfo->total_iMCU_rows = (JDIMENSION)
- jdiv_round_up((long) cinfo->image_height,
- (long) (cinfo->max_v_samp_factor*DCTSIZE));
-
- /* Decide whether file contains multiple scans */
- if (cinfo->comps_in_scan < cinfo->num_components || cinfo->progressive_mode)
- cinfo->inputctl->has_multiple_scans = TRUE;
- else
- cinfo->inputctl->has_multiple_scans = FALSE;
- }
-
- LOCAL(void)
- per_scan_setup2 (j_decompress_ptr cinfo)
- /* Do computations that are needed before processing a JPEG scan */
- /* cinfo->comps_in_scan and cinfo->cur_comp_info[] were set from SOS marker */
- {
- int ci, mcublks, tmp;
- jpeg_component_info *compptr;
-
- if (cinfo->comps_in_scan == 1) {
-
- /* Noninterleaved (single-component) scan */
- compptr = cinfo->cur_comp_info[0];
-
- /* Overall image size in MCUs */
- cinfo->MCUs_per_row = compptr->width_in_blocks;
- cinfo->MCU_rows_in_scan = compptr->height_in_blocks;
-
- /* For noninterleaved scan, always one block per MCU */
- compptr->MCU_width = 1;
- compptr->MCU_height = 1;
- compptr->MCU_blocks = 1;
- compptr->MCU_sample_width = compptr->DCT_scaled_size;
- compptr->last_col_width = 1;
- /* For noninterleaved scans, it is convenient to define last_row_height
- * as the number of block rows present in the last iMCU row.
- */
- tmp = (int) (compptr->height_in_blocks % compptr->v_samp_factor);
- if (tmp == 0) tmp = compptr->v_samp_factor;
- compptr->last_row_height = tmp;
-
- /* Prepare array describing MCU composition */
- cinfo->blocks_in_MCU = 1;
- cinfo->MCU_membership[0] = 0;
-
- } else {
-
- /* Interleaved (multi-component) scan */
- if (cinfo->comps_in_scan <= 0 || cinfo->comps_in_scan > MAX_COMPS_IN_SCAN)
- ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->comps_in_scan,
- MAX_COMPS_IN_SCAN);
-
- /* Overall image size in MCUs */
- cinfo->MCUs_per_row = (JDIMENSION)
- jdiv_round_up((long) cinfo->image_width,
- (long) (cinfo->max_h_samp_factor*DCTSIZE));
- cinfo->MCU_rows_in_scan = (JDIMENSION)
- jdiv_round_up((long) cinfo->image_height,
- (long) (cinfo->max_v_samp_factor*DCTSIZE));
-
- cinfo->blocks_in_MCU = 0;
-
- for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
- compptr = cinfo->cur_comp_info[ci];
- /* Sampling factors give # of blocks of component in each MCU */
- compptr->MCU_width = compptr->h_samp_factor;
- compptr->MCU_height = compptr->v_samp_factor;
- compptr->MCU_blocks = compptr->MCU_width * compptr->MCU_height;
- compptr->MCU_sample_width = compptr->MCU_width * compptr->DCT_scaled_size;
- /* Figure number of non-dummy blocks in last MCU column & row */
- tmp = (int) (compptr->width_in_blocks % compptr->MCU_width);
- if (tmp == 0) tmp = compptr->MCU_width;
- compptr->last_col_width = tmp;
- tmp = (int) (compptr->height_in_blocks % compptr->MCU_height);
- if (tmp == 0) tmp = compptr->MCU_height;
- compptr->last_row_height = tmp;
- /* Prepare array describing MCU composition */
- mcublks = compptr->MCU_blocks;
- if (cinfo->blocks_in_MCU + mcublks > D_MAX_BLOCKS_IN_MCU)
- ERREXIT(cinfo, JERR_BAD_MCU_SIZE);
- while (mcublks-- > 0) {
- cinfo->MCU_membership[cinfo->blocks_in_MCU++] = ci;
- }
- }
-
- }
- }
-
- /*
- * Save away a copy of the Q-table referenced by each component present
- * in the current scan, unless already saved during a prior scan.
- *
- * In a multiple-scan JPEG file, the encoder could assign different components
- * the same Q-table slot number, but change table definitions between scans
- * so that each component uses a different Q-table. (The IJG encoder is not
- * currently capable of doing this, but other encoders might.) Since we want
- * to be able to dequantize all the components at the end of the file, this
- * means that we have to save away the table actually used for each component.
- * We do this by copying the table at the start of the first scan containing
- * the component.
- * The JPEG spec prohibits the encoder from changing the contents of a Q-table
- * slot between scans of a component using that slot. If the encoder does so
- * anyway, this decoder will simply use the Q-table values that were current
- * at the start of the first scan for the component.
- *
- * The decompressor output side looks only at the saved quant tables,
- * not at the current Q-table slots.
- */
-
- LOCAL(void)
- latch_quant_tables (j_decompress_ptr cinfo)
- {
- int ci, qtblno;
- jpeg_component_info *compptr;
- JQUANT_TBL * qtbl;
-
- for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
- compptr = cinfo->cur_comp_info[ci];
- /* No work if we already saved Q-table for this component */
- if (compptr->quant_table != NULL)
- continue;
- /* Make sure specified quantization table is present */
- qtblno = compptr->quant_tbl_no;
- if (qtblno < 0 || qtblno >= NUM_QUANT_TBLS ||
- cinfo->quant_tbl_ptrs[qtblno] == NULL)
- ERREXIT1(cinfo, JERR_NO_QUANT_TABLE, qtblno);
- /* OK, save away the quantization table */
- qtbl = (JQUANT_TBL *)
- (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
- SIZEOF(JQUANT_TBL));
- MEMCOPY(qtbl, cinfo->quant_tbl_ptrs[qtblno], SIZEOF(JQUANT_TBL));
- compptr->quant_table = qtbl;
- }
- }
-
- /*
- * Initialize the input modules to read a scan of compressed data.
- * The first call to this is done by jdmaster.c after initializing
- * the entire decompressor (during jpeg_start_decompress).
- * Subsequent calls come from consume_markers, below.
- */
-
- METHODDEF(void)
- start_input_pass2 (j_decompress_ptr cinfo)
- {
- per_scan_setup2(cinfo);
- latch_quant_tables(cinfo);
- (*cinfo->entropy->start_pass) (cinfo);
- (*cinfo->coef->start_input_pass) (cinfo);
- cinfo->inputctl->consume_input = cinfo->coef->consume_data;
- }
-
- /*
- * Finish up after inputting a compressed-data scan.
- * This is called by the coefficient controller after it's read all
- * the expected data of the scan.
- */
-
- METHODDEF(void)
- finish_input_pass (j_decompress_ptr cinfo)
- {
- cinfo->inputctl->consume_input = consume_markers;
- }
-
- /*
- * Read JPEG markers before, between, or after compressed-data scans.
- * Change state as necessary when a new scan is reached.
- * Return value is JPEG_SUSPENDED, JPEG_REACHED_SOS, or JPEG_REACHED_EOI.
- *
- * The consume_input method pointer points either here or to the
- * coefficient controller's consume_data routine, depending on whether
- * we are reading a compressed data segment or inter-segment markers.
- */
-
- METHODDEF(int)
- consume_markers (j_decompress_ptr cinfo)
- {
- my_inputctl_ptr inputctl = (my_inputctl_ptr) cinfo->inputctl;
- int val;
-
- if (inputctl->pub.eoi_reached) /* After hitting EOI, read no further */
- return JPEG_REACHED_EOI;
-
- val = (*cinfo->marker->read_markers) (cinfo);
-
- switch (val) {
- case JPEG_REACHED_SOS: /* Found SOS */
- if (inputctl->inheaders) { /* 1st SOS */
- initial_setup2(cinfo);
- inputctl->inheaders = FALSE;
- /* Note: start_input_pass must be called by jdmaster.c
- * before any more input can be consumed. jdapimin.c is
- * responsible for enforcing this sequencing.
- */
- } else { /* 2nd or later SOS marker */
- if (! inputctl->pub.has_multiple_scans)
- ERREXIT(cinfo, JERR_EOI_EXPECTED); /* Oops, I wasn't expecting this! */
- start_input_pass2(cinfo);
- }
- break;
- case JPEG_REACHED_EOI: /* Found EOI */
- inputctl->pub.eoi_reached = TRUE;
- if (inputctl->inheaders) { /* Tables-only datastream, apparently */
- if (cinfo->marker->saw_SOF)
- ERREXIT(cinfo, JERR_SOF_NO_SOS);
- } else {
- /* Prevent infinite loop in coef ctlr's decompress_data routine
- * if user set output_scan_number larger than number of scans.
- */
- if (cinfo->output_scan_number > cinfo->input_scan_number)
- cinfo->output_scan_number = cinfo->input_scan_number;
- }
- break;
- case JPEG_SUSPENDED:
- break;
- }
-
- return val;
- }
-
- /*
- * Reset state to begin a fresh datastream.
- */
-
- METHODDEF(void)
- reset_input_controller (j_decompress_ptr cinfo)
- {
- my_inputctl_ptr inputctl = (my_inputctl_ptr) cinfo->inputctl;
-
- inputctl->pub.consume_input = consume_markers;
- inputctl->pub.has_multiple_scans = FALSE; /* "unknown" would be better */
- inputctl->pub.eoi_reached = FALSE;
- inputctl->inheaders = TRUE;
- /* Reset other modules */
- (*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo);
- (*cinfo->marker->reset_marker_reader) (cinfo);
- /* Reset progression state -- would be cleaner if entropy decoder did this */
- cinfo->coef_bits = NULL;
- }
-
- /*
- * Initialize the input controller module.
- * This is called only once, when the decompression object is created.
- */
-
- GLOBAL(void)
- jinit_input_controller (j_decompress_ptr cinfo)
- {
- my_inputctl_ptr inputctl;
-
- /* Create subobject in permanent pool */
- inputctl = (my_inputctl_ptr)
- (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
- SIZEOF(my_input_controller));
- cinfo->inputctl = (struct jpeg_input_controller *) inputctl;
- /* Initialize method pointers */
- inputctl->pub.consume_input = consume_markers;
- inputctl->pub.reset_input_controller = reset_input_controller;
- inputctl->pub.start_input_pass = start_input_pass2;
- inputctl->pub.finish_input_pass = finish_input_pass;
- /* Initialize state: can't use reset_input_controller since we don't
- * want to try to reset other modules yet.
- */
- inputctl->pub.has_multiple_scans = FALSE; /* "unknown" would be better */
- inputctl->pub.eoi_reached = FALSE;
- inputctl->inheaders = TRUE;
- }
- /********* End of inlined file: jdinput.c *********/
-
- /********* Start of inlined file: jdmainct.c *********/
- #define JPEG_INTERNALS
-
- /*
- * In the current system design, the main buffer need never be a full-image
- * buffer; any full-height buffers will be found inside the coefficient or
- * postprocessing controllers. Nonetheless, the main controller is not
- * trivial. Its responsibility is to provide context rows for upsampling/
- * rescaling, and doing this in an efficient fashion is a bit tricky.
- *
- * Postprocessor input data is counted in "row groups". A row group
- * is defined to be (v_samp_factor * DCT_scaled_size / min_DCT_scaled_size)
- * sample rows of each component. (We require DCT_scaled_size values to be
- * chosen such that these numbers are integers. In practice DCT_scaled_size
- * values will likely be powers of two, so we actually have the stronger
- * condition that DCT_scaled_size / min_DCT_scaled_size is an integer.)
- * Upsampling will typically produce max_v_samp_factor pixel rows from each
- * row group (times any additional scale factor that the upsampler is
- * applying).
- *
- * The coefficient controller will deliver data to us one iMCU row at a time;
- * each iMCU row contains v_samp_factor * DCT_scaled_size sample rows, or
- * exactly min_DCT_scaled_size row groups. (This amount of data corresponds
- * to one row of MCUs when the image is fully interleaved.) Note that the
- * number of sample rows varies across components, but the number of row
- * groups does not. Some garbage sample rows may be included in the last iMCU
- * row at the bottom of the image.
- *
- * Depending on the vertical scaling algorithm used, the upsampler may need
- * access to the sample row(s) above and below its current input row group.
- * The upsampler is required to set need_context_rows TRUE at global selection
- * time if so. When need_context_rows is FALSE, this controller can simply
- * obtain one iMCU row at a time from the coefficient controller and dole it
- * out as row groups to the postprocessor.
- *
- * When need_context_rows is TRUE, this controller guarantees that the buffer
- * passed to postprocessing contains at least one row group's worth of samples
- * above and below the row group(s) being processed. Note that the context
- * rows "above" the first passed row group appear at negative row offsets in
- * the passed buffer. At the top and bottom of the image, the required
- * context rows are manufactured by duplicating the first or last real sample
- * row; this avoids having special cases in the upsampling inner loops.
- *
- * The amount of context is fixed at one row group just because that's a
- * convenient number for this controller to work with. The existing
- * upsamplers really only need one sample row of context. An upsampler
- * supporting arbitrary output rescaling might wish for more than one row
- * group of context when shrinking the image; tough, we don't handle that.
- * (This is justified by the assumption that downsizing will be handled mostly
- * by adjusting the DCT_scaled_size values, so that the actual scale factor at
- * the upsample step needn't be much less than one.)
- *
- * To provide the desired context, we have to retain the last two row groups
- * of one iMCU row while reading in the next iMCU row. (The last row group
- * can't be processed until we have another row group for its below-context,
- * and so we have to save the next-to-last group too for its above-context.)
- * We could do this most simply by copying data around in our buffer, but
- * that'd be very slow. We can avoid copying any data by creating a rather
- * strange pointer structure. Here's how it works. We allocate a workspace
- * consisting of M+2 row groups (where M = min_DCT_scaled_size is the number
- * of row groups per iMCU row). We create two sets of redundant pointers to
- * the workspace. Labeling the physical row groups 0 to M+1, the synthesized
- * pointer lists look like this:
- * M+1 M-1
- * master pointer --> 0 master pointer --> 0
- * 1 1
- * ... ...
- * M-3 M-3
- * M-2 M
- * M-1 M+1
- * M M-2
- * M+1 M-1
- * 0 0
- * We read alternate iMCU rows using each master pointer; thus the last two
- * row groups of the previous iMCU row remain un-overwritten in the workspace.
- * The pointer lists are set up so that the required context rows appear to
- * be adjacent to the proper places when we pass the pointer lists to the
- * upsampler.
- *
- * The above pictures describe the normal state of the pointer lists.
- * At top and bottom of the image, we diddle the pointer lists to duplicate
- * the first or last sample row as necessary (this is cheaper than copying
- * sample rows around).
- *
- * This scheme breaks down if M < 2, ie, min_DCT_scaled_size is 1. In that
- * situation each iMCU row provides only one row group so the buffering logic
- * must be different (eg, we must read two iMCU rows before we can emit the
- * first row group). For now, we simply do not support providing context
- * rows when min_DCT_scaled_size is 1. That combination seems unlikely to
- * be worth providing --- if someone wants a 1/8th-size preview, they probably
- * want it quick and dirty, so a context-free upsampler is sufficient.
- */
-
- /* Private buffer controller object */
-
- typedef struct {
- struct jpeg_d_main_controller pub; /* public fields */
-
- /* Pointer to allocated workspace (M or M+2 row groups). */
- JSAMPARRAY buffer[MAX_COMPONENTS];
-
- boolean buffer_full; /* Have we gotten an iMCU row from decoder? */
- JDIMENSION rowgroup_ctr; /* counts row groups output to postprocessor */
-
- /* Remaining fields are only used in the context case. */
-
- /* These are the master pointers to the funny-order pointer lists. */
- JSAMPIMAGE xbuffer[2]; /* pointers to weird pointer lists */
-
- int whichptr; /* indicates which pointer set is now in use */
- int context_state; /* process_data state machine status */
- JDIMENSION rowgroups_avail; /* row groups available to postprocessor */
- JDIMENSION iMCU_row_ctr; /* counts iMCU rows to detect image top/bot */
- } my_main_controller4;
-
- typedef my_main_controller4 * my_main_ptr4;
-
- /* context_state values: */
- #define CTX_PREPARE_FOR_IMCU 0 /* need to prepare for MCU row */
- #define CTX_PROCESS_IMCU 1 /* feeding iMCU to postprocessor */
- #define CTX_POSTPONED_ROW 2 /* feeding postponed row group */
-
- /* Forward declarations */
- METHODDEF(void) process_data_simple_main2
- JPP((j_decompress_ptr cinfo, JSAMPARRAY output_buf,
- JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail));
- METHODDEF(void) process_data_context_main
- JPP((j_decompress_ptr cinfo, JSAMPARRAY output_buf,
- JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail));
- #ifdef QUANT_2PASS_SUPPORTED
- METHODDEF(void) process_data_crank_post
- JPP((j_decompress_ptr cinfo, JSAMPARRAY output_buf,
- JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail));
- #endif
-
- LOCAL(void)
- alloc_funny_pointers (j_decompress_ptr cinfo)
- /* Allocate space for the funny pointer lists.
- * This is done only once, not once per pass.
- */
- {
- my_main_ptr4 main_ = (my_main_ptr4) cinfo->main;
- int ci, rgroup;
- int M = cinfo->min_DCT_scaled_size;
- jpeg_component_info *compptr;
- JSAMPARRAY xbuf;
-
- /* Get top-level space for component array pointers.
- * We alloc both arrays with one call to save a few cycles.
- */
- main_->xbuffer[0] = (JSAMPIMAGE)
- (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
- cinfo->num_components * 2 * SIZEOF(JSAMPARRAY));
- main_->xbuffer[1] = main_->xbuffer[0] + cinfo->num_components;
-
- for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
- ci++, compptr++) {
- rgroup = (compptr->v_samp_factor * compptr->DCT_scaled_size) /
- cinfo->min_DCT_scaled_size; /* height of a row group of component */
- /* Get space for pointer lists --- M+4 row groups in each list.
- * We alloc both pointer lists with one call to save a few cycles.
- */
- xbuf = (JSAMPARRAY)
- (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
- 2 * (rgroup * (M + 4)) * SIZEOF(JSAMPROW));
- xbuf += rgroup; /* want one row group at negative offsets */
- main_->xbuffer[0][ci] = xbuf;
- xbuf += rgroup * (M + 4);
- main_->xbuffer[1][ci] = xbuf;
- }
- }
-
- LOCAL(void)
- make_funny_pointers (j_decompress_ptr cinfo)
- /* Create the funny pointer lists discussed in the comments above.
- * The actual workspace is already allocated (in main->buffer),
- * and the space for the pointer lists is allocated too.
- * This routine just fills in the curiously ordered lists.
- * This will be repeated at the beginning of each pass.
- */
- {
- my_main_ptr4 main_ = (my_main_ptr4) cinfo->main;
- int ci, i, rgroup;
- int M = cinfo->min_DCT_scaled_size;
- jpeg_component_info *compptr;
- JSAMPARRAY buf, xbuf0, xbuf1;
-
- for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
- ci++, compptr++) {
- rgroup = (compptr->v_samp_factor * compptr->DCT_scaled_size) /
- cinfo->min_DCT_scaled_size; /* height of a row group of component */
- xbuf0 = main_->xbuffer[0][ci];
- xbuf1 = main_->xbuffer[1][ci];
- /* First copy the workspace pointers as-is */
- buf = main_->buffer[ci];
- for (i = 0; i < rgroup * (M + 2); i++) {
- xbuf0[i] = xbuf1[i] = buf[i];
- }
- /* In the second list, put the last four row groups in swapped order */
- for (i = 0; i < rgroup * 2; i++) {
- xbuf1[rgroup*(M-2) + i] = buf[rgroup*M + i];
- xbuf1[rgroup*M + i] = buf[rgroup*(M-2) + i];
- }
- /* The wraparound pointers at top and bottom will be filled later
- * (see set_wraparound_pointers, below). Initially we want the "above"
- * pointers to duplicate the first actual data line. This only needs
- * to happen in xbuffer[0].
- */
- for (i = 0; i < rgroup; i++) {
- xbuf0[i - rgroup] = xbuf0[0];
- }
- }
- }
-
- LOCAL(void)
- set_wraparound_pointers (j_decompress_ptr cinfo)
- /* Set up the "wraparound" pointers at top and bottom of the pointer lists.
- * This changes the pointer list state from top-of-image to the normal state.
- */
- {
- my_main_ptr4 main_ = (my_main_ptr4) cinfo->main;
- int ci, i, rgroup;
- int M = cinfo->min_DCT_scaled_size;
- jpeg_component_info *compptr;
- JSAMPARRAY xbuf0, xbuf1;
-
- for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
- ci++, compptr++) {
- rgroup = (compptr->v_samp_factor * compptr->DCT_scaled_size) /
- cinfo->min_DCT_scaled_size; /* height of a row group of component */
- xbuf0 = main_->xbuffer[0][ci];
- xbuf1 = main_->xbuffer[1][ci];
- for (i = 0; i < rgroup; i++) {
- xbuf0[i - rgroup] = xbuf0[rgroup*(M+1) + i];
- xbuf1[i - rgroup] = xbuf1[rgroup*(M+1) + i];
- xbuf0[rgroup*(M+2) + i] = xbuf0[i];
- xbuf1[rgroup*(M+2) + i] = xbuf1[i];
- }
- }
- }
-
- LOCAL(void)
- set_bottom_pointers (j_decompress_ptr cinfo)
- /* Change the pointer lists to duplicate the last sample row at the bottom
- * of the image. whichptr indicates which xbuffer holds the final iMCU row.
- * Also sets rowgroups_avail to indicate number of nondummy row groups in row.
- */
- {
- my_main_ptr4 main_ = (my_main_ptr4) cinfo->main;
- int ci, i, rgroup, iMCUheight, rows_left;
- jpeg_component_info *compptr;
- JSAMPARRAY xbuf;
-
- for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
- ci++, compptr++) {
- /* Count sample rows in one iMCU row and in one row group */
- iMCUheight = compptr->v_samp_factor * compptr->DCT_scaled_size;
- rgroup = iMCUheight / cinfo->min_DCT_scaled_size;
- /* Count nondummy sample rows remaining for this component */
- rows_left = (int) (compptr->downsampled_height % (JDIMENSION) iMCUheight);
- if (rows_left == 0) rows_left = iMCUheight;
- /* Count nondummy row groups. Should get same answer for each component,
- * so we need only do it once.
- */
- if (ci == 0) {
- main_->rowgroups_avail = (JDIMENSION) ((rows_left-1) / rgroup + 1);
- }
- /* Duplicate the last real sample row rgroup*2 times; this pads out the
- * last partial rowgroup and ensures at least one full rowgroup of context.
- */
- xbuf = main_->xbuffer[main_->whichptr][ci];
- for (i = 0; i < rgroup * 2; i++) {
- xbuf[rows_left + i] = xbuf[rows_left-1];
- }
- }
- }
-
- /*
- * Initialize for a processing pass.
- */
-
- METHODDEF(void)
- start_pass_main2 (j_decompress_ptr cinfo, J_BUF_MODE pass_mode)
- {
- my_main_ptr4 main_ = (my_main_ptr4) cinfo->main;
-
- switch (pass_mode) {
- case JBUF_PASS_THRU:
- if (cinfo->upsample->need_context_rows) {
- main_->pub.process_data = process_data_context_main;
- make_funny_pointers(cinfo); /* Create the xbuffer[] lists */
- main_->whichptr = 0; /* Read first iMCU row into xbuffer[0] */
- main_->context_state = CTX_PREPARE_FOR_IMCU;
- main_->iMCU_row_ctr = 0;
- } else {
- /* Simple case with no context needed */
- main_->pub.process_data = process_data_simple_main2;
- }
- main_->buffer_full = FALSE; /* Mark buffer empty */
- main_->rowgroup_ctr = 0;
- break;
- #ifdef QUANT_2PASS_SUPPORTED
- case JBUF_CRANK_DEST:
- /* For last pass of 2-pass quantization, just crank the postprocessor */
- main_->pub.process_data = process_data_crank_post;
- break;
- #endif
- default:
- ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
- break;
- }
- }
-
- /*
- * Process some data.
- * This handles the simple case where no context is required.
- */
-
- METHODDEF(void)
- process_data_simple_main2 (j_decompress_ptr cinfo,
- JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
- JDIMENSION out_rows_avail)
- {
- my_main_ptr4 main_ = (my_main_ptr4) cinfo->main;
- JDIMENSION rowgroups_avail;
-
- /* Read input data if we haven't filled the main buffer yet */
- if (! main_->buffer_full) {
- if (! (*cinfo->coef->decompress_data) (cinfo, main_->buffer))
- return; /* suspension forced, can do nothing more */
- main_->buffer_full = TRUE; /* OK, we have an iMCU row to work with */
- }
-
- /* There are always min_DCT_scaled_size row groups in an iMCU row. */
- rowgroups_avail = (JDIMENSION) cinfo->min_DCT_scaled_size;
- /* Note: at the bottom of the image, we may pass extra garbage row groups
- * to the postprocessor. The postprocessor has to check for bottom
- * of image anyway (at row resolution), so no point in us doing it too.
- */
-
- /* Feed the postprocessor */
- (*cinfo->post->post_process_data) (cinfo, main_->buffer,
- &main_->rowgroup_ctr, rowgroups_avail,
- output_buf, out_row_ctr, out_rows_avail);
-
- /* Has postprocessor consumed all the data yet? If so, mark buffer empty */
- if (main_->rowgroup_ctr >= rowgroups_avail) {
- main_->buffer_full = FALSE;
- main_->rowgroup_ctr = 0;
- }
- }
-
- /*
- * Process some data.
- * This handles the case where context rows must be provided.
- */
-
- METHODDEF(void)
- process_data_context_main (j_decompress_ptr cinfo,
- JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
- JDIMENSION out_rows_avail)
- {
- my_main_ptr4 main_ = (my_main_ptr4) cinfo->main;
-
- /* Read input data if we haven't filled the main buffer yet */
- if (! main_->buffer_full) {
- if (! (*cinfo->coef->decompress_data) (cinfo,
- main_->xbuffer[main_->whichptr]))
- return; /* suspension forced, can do nothing more */
- main_->buffer_full = TRUE; /* OK, we have an iMCU row to work with */
- main_->iMCU_row_ctr++; /* count rows received */
- }
-
- /* Postprocessor typically will not swallow all the input data it is handed
- * in one call (due to filling the output buffer first). Must be prepared
- * to exit and restart. This switch lets us keep track of how far we got.
- * Note that each case falls through to the next on successful completion.
- */
- switch (main_->context_state) {
- case CTX_POSTPONED_ROW:
- /* Call postprocessor using previously set pointers for postponed row */
- (*cinfo->post->post_process_data) (cinfo, main_->xbuffer[main_->whichptr],
- &main_->rowgroup_ctr, main_->rowgroups_avail,
- output_buf, out_row_ctr, out_rows_avail);
- if (main_->rowgroup_ctr < main_->rowgroups_avail)
- return; /* Need to suspend */
- main_->context_state = CTX_PREPARE_FOR_IMCU;
- if (*out_row_ctr >= out_rows_avail)
- return; /* Postprocessor exactly filled output buf */
- /*FALLTHROUGH*/
- case CTX_PREPARE_FOR_IMCU:
- /* Prepare to process first M-1 row groups of this iMCU row */
- main_->rowgroup_ctr = 0;
- main_->rowgroups_avail = (JDIMENSION) (cinfo->min_DCT_scaled_size - 1);
- /* Check for bottom of image: if so, tweak pointers to "duplicate"
- * the last sample row, and adjust rowgroups_avail to ignore padding rows.
- */
- if (main_->iMCU_row_ctr == cinfo->total_iMCU_rows)
- set_bottom_pointers(cinfo);
- main_->context_state = CTX_PROCESS_IMCU;
- /*FALLTHROUGH*/
- case CTX_PROCESS_IMCU:
- /* Call postprocessor using previously set pointers */
- (*cinfo->post->post_process_data) (cinfo, main_->xbuffer[main_->whichptr],
- &main_->rowgroup_ctr, main_->rowgroups_avail,
- output_buf, out_row_ctr, out_rows_avail);
- if (main_->rowgroup_ctr < main_->rowgroups_avail)
- return; /* Need to suspend */
- /* After the first iMCU, change wraparound pointers to normal state */
- if (main_->iMCU_row_ctr == 1)
- set_wraparound_pointers(cinfo);
- /* Prepare to load new iMCU row using other xbuffer list */
- main_->whichptr ^= 1; /* 0=>1 or 1=>0 */
- main_->buffer_full = FALSE;
- /* Still need to process last row group of this iMCU row, */
- /* which is saved at index M+1 of the other xbuffer */
- main_->rowgroup_ctr = (JDIMENSION) (cinfo->min_DCT_scaled_size + 1);
- main_->rowgroups_avail = (JDIMENSION) (cinfo->min_DCT_scaled_size + 2);
- main_->context_state = CTX_POSTPONED_ROW;
- }
- }
-
- /*
- * Process some data.
- * Final pass of two-pass quantization: just call the postprocessor.
- * Source data will be the postprocessor controller's internal buffer.
- */
-
- #ifdef QUANT_2PASS_SUPPORTED
-
- METHODDEF(void)
- process_data_crank_post (j_decompress_ptr cinfo,
- JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
- JDIMENSION out_rows_avail)
- {
- (*cinfo->post->post_process_data) (cinfo, (JSAMPIMAGE) NULL,
- (JDIMENSION *) NULL, (JDIMENSION) 0,
- output_buf, out_row_ctr, out_rows_avail);
- }
-
- #endif /* QUANT_2PASS_SUPPORTED */
-
- /*
- * Initialize main buffer controller.
- */
-
- GLOBAL(void)
- jinit_d_main_controller (j_decompress_ptr cinfo, boolean need_full_buffer)
- {
- my_main_ptr4 main_;
- int ci, rgroup, ngroups;
- jpeg_component_info *compptr;
-
- main_ = (my_main_ptr4)
- (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
- SIZEOF(my_main_controller4));
- cinfo->main = (struct jpeg_d_main_controller *) main_;
- main_->pub.start_pass = start_pass_main2;
-
- if (need_full_buffer) /* shouldn't happen */
- ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
-
- /* Allocate the workspace.
- * ngroups is the number of row groups we need.
- */
- if (cinfo->upsample->need_context_rows) {
- if (cinfo->min_DCT_scaled_size < 2) /* unsupported, see comments above */
- ERREXIT(cinfo, JERR_NOTIMPL);
- alloc_funny_pointers(cinfo); /* Alloc space for xbuffer[] lists */
- ngroups = cinfo->min_DCT_scaled_size + 2;
- } else {
- ngroups = cinfo->min_DCT_scaled_size;
- }
-
- for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
- ci++, compptr++) {
- rgroup = (compptr->v_samp_factor * compptr->DCT_scaled_size) /
- cinfo->min_DCT_scaled_size; /* height of a row group of component */
- main_->buffer[ci] = (*cinfo->mem->alloc_sarray)
- ((j_common_ptr) cinfo, JPOOL_IMAGE,
- compptr->width_in_blocks * compptr->DCT_scaled_size,
- (JDIMENSION) (rgroup * ngroups));
- }
- }
- /********* End of inlined file: jdmainct.c *********/
-
- /********* Start of inlined file: jdmarker.c *********/
- #define JPEG_INTERNALS
-
- /* Private state */
-
- typedef struct {
- struct jpeg_marker_reader pub; /* public fields */
-
- /* Application-overridable marker processing methods */
- jpeg_marker_parser_method process_COM;
- jpeg_marker_parser_method process_APPn[16];
-
- /* Limit on marker data length to save for each marker type */
- unsigned int length_limit_COM;
- unsigned int length_limit_APPn[16];
-
- /* Status of COM/APPn marker saving */
- jpeg_saved_marker_ptr cur_marker; /* NULL if not processing a marker */
- unsigned int bytes_read; /* data bytes read so far in marker */
- /* Note: cur_marker is not linked into marker_list until it's all read. */
- } my_marker_reader;
-
- typedef my_marker_reader * my_marker_ptr2;
-
- /*
- * Macros for fetching data from the data source module.
- *
- * At all times, cinfo->src->next_input_byte and ->bytes_in_buffer reflect
- * the current restart point; we update them only when we have reached a
- * suitable place to restart if a suspension occurs.
- */
-
- /* Declare and initialize local copies of input pointer/count */
- #define INPUT_VARS(cinfo) \
- struct jpeg_source_mgr * datasrc = (cinfo)->src; \
- const JOCTET * next_input_byte = datasrc->next_input_byte; \
- size_t bytes_in_buffer = datasrc->bytes_in_buffer
-
- /* Unload the local copies --- do this only at a restart boundary */
- #define INPUT_SYNC(cinfo) \
- ( datasrc->next_input_byte = next_input_byte, \
- datasrc->bytes_in_buffer = bytes_in_buffer )
-
- /* Reload the local copies --- used only in MAKE_BYTE_AVAIL */
- #define INPUT_RELOAD(cinfo) \
- ( next_input_byte = datasrc->next_input_byte, \
- bytes_in_buffer = datasrc->bytes_in_buffer )
-
- /* Internal macro for INPUT_BYTE and INPUT_2BYTES: make a byte available.
- * Note we do *not* do INPUT_SYNC before calling fill_input_buffer,
- * but we must reload the local copies after a successful fill.
- */
- #define MAKE_BYTE_AVAIL(cinfo,action) \
- if (bytes_in_buffer == 0) { \
- if (! (*datasrc->fill_input_buffer) (cinfo)) \
- { action; } \
- INPUT_RELOAD(cinfo); \
- }
-
- /* Read a byte into variable V.
- * If must suspend, take the specified action (typically "return FALSE").
- */
- #define INPUT_BYTE(cinfo,V,action) \
- MAKESTMT( MAKE_BYTE_AVAIL(cinfo,action); \
- bytes_in_buffer--; \
- V = GETJOCTET(*next_input_byte++); )
-
- /* As above, but read two bytes interpreted as an unsigned 16-bit integer.
- * V should be declared unsigned int or perhaps INT32.
- */
- #define INPUT_2BYTES(cinfo,V,action) \
- MAKESTMT( MAKE_BYTE_AVAIL(cinfo,action); \
- bytes_in_buffer--; \
- V = ((unsigned int) GETJOCTET(*next_input_byte++)) << 8; \
- MAKE_BYTE_AVAIL(cinfo,action); \
- bytes_in_buffer--; \
- V += GETJOCTET(*next_input_byte++); )
-
- /*
- * Routines to process JPEG markers.
- *
- * Entry condition: JPEG marker itself has been read and its code saved
- * in cinfo->unread_marker; input restart point is just after the marker.
- *
- * Exit: if return TRUE, have read and processed any parameters, and have
- * updated the restart point to point after the parameters.
- * If return FALSE, was forced to suspend before reaching end of
- * marker parameters; restart point has not been moved. Same routine
- * will be called again after application supplies more input data.
- *
- * This approach to suspension assumes that all of a marker's parameters
- * can fit into a single input bufferload. This should hold for "normal"
- * markers. Some COM/APPn markers might have large parameter segments
- * that might not fit. If we are simply dropping such a marker, we use
- * skip_input_data to get past it, and thereby put the problem on the
- * source manager's shoulders. If we are saving the marker's contents
- * into memory, we use a slightly different convention: when forced to
- * suspend, the marker processor updates the restart point to the end of
- * what it's consumed (ie, the end of the buffer) before returning FALSE.
- * On resumption, cinfo->unread_marker still contains the marker code,
- * but the data source will point to the next chunk of marker data.
- * The marker processor must retain internal state to deal with this.
- *
- * Note that we don't bother to avoid duplicate trace messages if a
- * suspension occurs within marker parameters. Other side effects
- * require more care.
- */
-
- LOCAL(boolean)
- get_soi (j_decompress_ptr cinfo)
- /* Process an SOI marker */
- {
- int i;
-
- TRACEMS(cinfo, 1, JTRC_SOI);
-
- if (cinfo->marker->saw_SOI)
- ERREXIT(cinfo, JERR_SOI_DUPLICATE);
-
- /* Reset all parameters that are defined to be reset by SOI */
-
- for (i = 0; i < NUM_ARITH_TBLS; i++) {
- cinfo->arith_dc_L[i] = 0;
- cinfo->arith_dc_U[i] = 1;
- cinfo->arith_ac_K[i] = 5;
- }
- cinfo->restart_interval = 0;
-
- /* Set initial assumptions for colorspace etc */
-
- cinfo->jpeg_color_space = JCS_UNKNOWN;
- cinfo->CCIR601_sampling = FALSE; /* Assume non-CCIR sampling??? */
-
- cinfo->saw_JFIF_marker = FALSE;
- cinfo->JFIF_major_version = 1; /* set default JFIF APP0 values */
- cinfo->JFIF_minor_version = 1;
- cinfo->density_unit = 0;
- cinfo->X_density = 1;
- cinfo->Y_density = 1;
- cinfo->saw_Adobe_marker = FALSE;
- cinfo->Adobe_transform = 0;
-
- cinfo->marker->saw_SOI = TRUE;
-
- return TRUE;
- }
-
- LOCAL(boolean)
- get_sof (j_decompress_ptr cinfo, boolean is_prog, boolean is_arith)
- /* Process a SOFn marker */
- {
- INT32 length;
- int c, ci;
- jpeg_component_info * compptr;
- INPUT_VARS(cinfo);
-
- cinfo->progressive_mode = is_prog;
- cinfo->arith_code = is_arith;
-
- INPUT_2BYTES(cinfo, length, return FALSE);
-
- INPUT_BYTE(cinfo, cinfo->data_precision, return FALSE);
- INPUT_2BYTES(cinfo, cinfo->image_height, return FALSE);
- INPUT_2BYTES(cinfo, cinfo->image_width, return FALSE);
- INPUT_BYTE(cinfo, cinfo->num_components, return FALSE);
-
- length -= 8;
-
- TRACEMS4(cinfo, 1, JTRC_SOF, cinfo->unread_marker,
- (int) cinfo->image_width, (int) cinfo->image_height,
- cinfo->num_components);
-
- if (cinfo->marker->saw_SOF)
- ERREXIT(cinfo, JERR_SOF_DUPLICATE);
-
- /* We don't support files in which the image height is initially specified */
- /* as 0 and is later redefined by DNL. As long as we have to check that, */
- /* might as well have a general sanity check. */
- if (cinfo->image_height <= 0 || cinfo->image_width <= 0
- || cinfo->num_components <= 0)
- ERREXIT(cinfo, JERR_EMPTY_IMAGE);
-
- if (length != (cinfo->num_components * 3))
- ERREXIT(cinfo, JERR_BAD_LENGTH);
-
- if (cinfo->comp_info == NULL) /* do only once, even if suspend */
- cinfo->comp_info = (jpeg_component_info *) (*cinfo->mem->alloc_small)
- ((j_common_ptr) cinfo, JPOOL_IMAGE,
- cinfo->num_components * SIZEOF(jpeg_component_info));
-
- for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
- ci++, compptr++) {
- compptr->component_index = ci;
- INPUT_BYTE(cinfo, compptr->component_id, return FALSE);
- INPUT_BYTE(cinfo, c, return FALSE);
- compptr->h_samp_factor = (c >> 4) & 15;
- compptr->v_samp_factor = (c ) & 15;
- INPUT_BYTE(cinfo, compptr->quant_tbl_no, return FALSE);
-
- TRACEMS4(cinfo, 1, JTRC_SOF_COMPONENT,
- compptr->component_id, compptr->h_samp_factor,
- compptr->v_samp_factor, compptr->quant_tbl_no);
- }
-
- cinfo->marker->saw_SOF = TRUE;
-
- INPUT_SYNC(cinfo);
- return TRUE;
- }
-
- LOCAL(boolean)
- get_sos (j_decompress_ptr cinfo)
- /* Process a SOS marker */
- {
- INT32 length;
- int i, ci, n, c, cc;
- jpeg_component_info * compptr;
- INPUT_VARS(cinfo);
-
- if (! cinfo->marker->saw_SOF)
- ERREXIT(cinfo, JERR_SOS_NO_SOF);
-
- INPUT_2BYTES(cinfo, length, return FALSE);
-
- INPUT_BYTE(cinfo, n, return FALSE); /* Number of components */
-
- TRACEMS1(cinfo, 1, JTRC_SOS, n);
-
- if (length != (n * 2 + 6) || n < 1 || n > MAX_COMPS_IN_SCAN)
- ERREXIT(cinfo, JERR_BAD_LENGTH);
-
- cinfo->comps_in_scan = n;
-
- /* Collect the component-spec parameters */
-
- for (i = 0; i < n; i++) {
- INPUT_BYTE(cinfo, cc, return FALSE);
- INPUT_BYTE(cinfo, c, return FALSE);
-
- for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
- ci++, compptr++) {
- if (cc == compptr->component_id)
- goto id_found;
- }
-
- ERREXIT1(cinfo, JERR_BAD_COMPONENT_ID, cc);
-
- id_found:
-
- cinfo->cur_comp_info[i] = compptr;
- compptr->dc_tbl_no = (c >> 4) & 15;
- compptr->ac_tbl_no = (c ) & 15;
-
- TRACEMS3(cinfo, 1, JTRC_SOS_COMPONENT, cc,
- compptr->dc_tbl_no, compptr->ac_tbl_no);
- }
-
- /* Collect the additional scan parameters Ss, Se, Ah/Al. */
- INPUT_BYTE(cinfo, c, return FALSE);
- cinfo->Ss = c;
- INPUT_BYTE(cinfo, c, return FALSE);
- cinfo->Se = c;
- INPUT_BYTE(cinfo, c, return FALSE);
- cinfo->Ah = (c >> 4) & 15;
- cinfo->Al = (c ) & 15;
-
- TRACEMS4(cinfo, 1, JTRC_SOS_PARAMS, cinfo->Ss, cinfo->Se,
- cinfo->Ah, cinfo->Al);
-
- /* Prepare to scan data & restart markers */
- cinfo->marker->next_restart_num = 0;
-
- /* Count another SOS marker */
- cinfo->input_scan_number++;
-
- INPUT_SYNC(cinfo);
- return TRUE;
- }
-
- #ifdef D_ARITH_CODING_SUPPORTED
-
- LOCAL(boolean)
- get_dac (j_decompress_ptr cinfo)
- /* Process a DAC marker */
- {
- INT32 length;
- int index, val;
- INPUT_VARS(cinfo);
-
- INPUT_2BYTES(cinfo, length, return FALSE);
- length -= 2;
-
- while (length > 0) {
- INPUT_BYTE(cinfo, index, return FALSE);
- INPUT_BYTE(cinfo, val, return FALSE);
-
- length -= 2;
-
- TRACEMS2(cinfo, 1, JTRC_DAC, index, val);
-
- if (index < 0 || index >= (2*NUM_ARITH_TBLS))
- ERREXIT1(cinfo, JERR_DAC_INDEX, index);
-
- if (index >= NUM_ARITH_TBLS) { /* define AC table */
- cinfo->arith_ac_K[index-NUM_ARITH_TBLS] = (UINT8) val;
- } else { /* define DC table */
- cinfo->arith_dc_L[index] = (UINT8) (val & 0x0F);
- cinfo->arith_dc_U[index] = (UINT8) (val >> 4);
- if (cinfo->arith_dc_L[index] > cinfo->arith_dc_U[index])
- ERREXIT1(cinfo, JERR_DAC_VALUE, val);
- }
- }
-
- if (length != 0)
- ERREXIT(cinfo, JERR_BAD_LENGTH);
-
- INPUT_SYNC(cinfo);
- return TRUE;
- }
-
- #else /* ! D_ARITH_CODING_SUPPORTED */
-
- #define get_dac(cinfo) skip_variable(cinfo)
-
- #endif /* D_ARITH_CODING_SUPPORTED */
-
- LOCAL(boolean)
- get_dht (j_decompress_ptr cinfo)
- /* Process a DHT marker */
- {
- INT32 length;
- UINT8 bits[17];
- UINT8 huffval[256];
- int i, index, count;
- JHUFF_TBL **htblptr;
- INPUT_VARS(cinfo);
-
- INPUT_2BYTES(cinfo, length, return FALSE);
- length -= 2;
-
- while (length > 16) {
- INPUT_BYTE(cinfo, index, return FALSE);
-
- TRACEMS1(cinfo, 1, JTRC_DHT, index);
-
- bits[0] = 0;
- count = 0;
- for (i = 1; i <= 16; i++) {
- INPUT_BYTE(cinfo, bits[i], return FALSE);
- count += bits[i];
- }
-
- length -= 1 + 16;
-
- TRACEMS8(cinfo, 2, JTRC_HUFFBITS,
- bits[1], bits[2], bits[3], bits[4],
- bits[5], bits[6], bits[7], bits[8]);
- TRACEMS8(cinfo, 2, JTRC_HUFFBITS,
- bits[9], bits[10], bits[11], bits[12],
- bits[13], bits[14], bits[15], bits[16]);
-
- /* Here we just do minimal validation of the counts to avoid walking
- * off the end of our table space. jdhuff.c will check more carefully.
- */
- if (count > 256 || ((INT32) count) > length)
- ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
-
- for (i = 0; i < count; i++)
- INPUT_BYTE(cinfo, huffval[i], return FALSE);
-
- length -= count;
-
- if (index & 0x10) { /* AC table definition */
- index -= 0x10;
- htblptr = &cinfo->ac_huff_tbl_ptrs[index];
- } else { /* DC table definition */
- htblptr = &cinfo->dc_huff_tbl_ptrs[index];
- }
-
- if (index < 0 || index >= NUM_HUFF_TBLS)
- ERREXIT1(cinfo, JERR_DHT_INDEX, index);
-
- if (*htblptr == NULL)
- *htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo);
-
- MEMCOPY((*htblptr)->bits, bits, SIZEOF((*htblptr)->bits));
- MEMCOPY((*htblptr)->huffval, huffval, SIZEOF((*htblptr)->huffval));
- }
-
- if (length != 0)
- ERREXIT(cinfo, JERR_BAD_LENGTH);
-
- INPUT_SYNC(cinfo);
- return TRUE;
- }
-
- LOCAL(boolean)
- get_dqt (j_decompress_ptr cinfo)
- /* Process a DQT marker */
- {
- INT32 length;
- int n, i, prec;
- unsigned int tmp;
- JQUANT_TBL *quant_ptr;
- INPUT_VARS(cinfo);
-
- INPUT_2BYTES(cinfo, length, return FALSE);
- length -= 2;
-
- while (length > 0) {
- INPUT_BYTE(cinfo, n, return FALSE);
- prec = n >> 4;
- n &= 0x0F;
-
- TRACEMS2(cinfo, 1, JTRC_DQT, n, prec);
-
- if (n >= NUM_QUANT_TBLS)
- ERREXIT1(cinfo, JERR_DQT_INDEX, n);
-
- if (cinfo->quant_tbl_ptrs[n] == NULL)
- cinfo->quant_tbl_ptrs[n] = jpeg_alloc_quant_table((j_common_ptr) cinfo);
- quant_ptr = cinfo->quant_tbl_ptrs[n];
-
- for (i = 0; i < DCTSIZE2; i++) {
- if (prec)
- INPUT_2BYTES(cinfo, tmp, return FALSE);
- else
- INPUT_BYTE(cinfo, tmp, return FALSE);
- /* We convert the zigzag-order table to natural array order. */
- quant_ptr->quantval[jpeg_natural_order[i]] = (UINT16) tmp;
- }
-
- if (cinfo->err->trace_level >= 2) {
- for (i = 0; i < DCTSIZE2; i += 8) {
- TRACEMS8(cinfo, 2, JTRC_QUANTVALS,
- quant_ptr->quantval[i], quant_ptr->quantval[i+1],
- quant_ptr->quantval[i+2], quant_ptr->quantval[i+3],
- quant_ptr->quantval[i+4], quant_ptr->quantval[i+5],
- quant_ptr->quantval[i+6], quant_ptr->quantval[i+7]);
- }
- }
-
- length -= DCTSIZE2+1;
- if (prec) length -= DCTSIZE2;
- }
-
- if (length != 0)
- ERREXIT(cinfo, JERR_BAD_LENGTH);
-
- INPUT_SYNC(cinfo);
- return TRUE;
- }
-
- LOCAL(boolean)
- get_dri (j_decompress_ptr cinfo)
- /* Process a DRI marker */
- {
- INT32 length;
- unsigned int tmp;
- INPUT_VARS(cinfo);
-
- INPUT_2BYTES(cinfo, length, return FALSE);
-
- if (length != 4)
- ERREXIT(cinfo, JERR_BAD_LENGTH);
-
- INPUT_2BYTES(cinfo, tmp, return FALSE);
-
- TRACEMS1(cinfo, 1, JTRC_DRI, tmp);
-
- cinfo->restart_interval = tmp;
-
- INPUT_SYNC(cinfo);
- return TRUE;
- }
-
- /*
- * Routines for processing APPn and COM markers.
- * These are either saved in memory or discarded, per application request.
- * APP0 and APP14 are specially checked to see if they are
- * JFIF and Adobe markers, respectively.
- */
-
- #define APP0_DATA_LEN 14 /* Length of interesting data in APP0 */
- #define APP14_DATA_LEN 12 /* Length of interesting data in APP14 */
- #define APPN_DATA_LEN 14 /* Must be the largest of the above!! */
-
- LOCAL(void)
- examine_app0 (j_decompress_ptr cinfo, JOCTET FAR * data,
- unsigned int datalen, INT32 remaining)
- /* Examine first few bytes from an APP0.
- * Take appropriate action if it is a JFIF marker.
- * datalen is # of bytes at data[], remaining is length of rest of marker data.
- */
- {
- INT32 totallen = (INT32) datalen + remaining;
-
- if (datalen >= APP0_DATA_LEN &&
- GETJOCTET(data[0]) == 0x4A &&
- GETJOCTET(data[1]) == 0x46 &&
- GETJOCTET(data[2]) == 0x49 &&
- GETJOCTET(data[3]) == 0x46 &&
- GETJOCTET(data[4]) == 0) {
- /* Found JFIF APP0 marker: save info */
- cinfo->saw_JFIF_marker = TRUE;
- cinfo->JFIF_major_version = GETJOCTET(data[5]);
- cinfo->JFIF_minor_version = GETJOCTET(data[6]);
- cinfo->density_unit = GETJOCTET(data[7]);
- cinfo->X_density = (GETJOCTET(data[8]) << 8) + GETJOCTET(data[9]);
- cinfo->Y_density = (GETJOCTET(data[10]) << 8) + GETJOCTET(data[11]);
- /* Check version.
- * Major version must be 1, anything else signals an incompatible change.
- * (We used to treat this as an error, but now it's a nonfatal warning,
- * because some bozo at Hijaak couldn't read the spec.)
- * Minor version should be 0..2, but process anyway if newer.
- */
- if (cinfo->JFIF_major_version != 1)
- WARNMS2(cinfo, JWRN_JFIF_MAJOR,
- cinfo->JFIF_major_version, cinfo->JFIF_minor_version);
- /* Generate trace messages */
- TRACEMS5(cinfo, 1, JTRC_JFIF,
- cinfo->JFIF_major_version, cinfo->JFIF_minor_version,
- cinfo->X_density, cinfo->Y_density, cinfo->density_unit);
- /* Validate thumbnail dimensions and issue appropriate messages */
- if (GETJOCTET(data[12]) | GETJOCTET(data[13]))
- TRACEMS2(cinfo, 1, JTRC_JFIF_THUMBNAIL,
- GETJOCTET(data[12]), GETJOCTET(data[13]));
- totallen -= APP0_DATA_LEN;
- if (totallen !=
- ((INT32)GETJOCTET(data[12]) * (INT32)GETJOCTET(data[13]) * (INT32) 3))
- TRACEMS1(cinfo, 1, JTRC_JFIF_BADTHUMBNAILSIZE, (int) totallen);
- } else if (datalen >= 6 &&
- GETJOCTET(data[0]) == 0x4A &&
- GETJOCTET(data[1]) == 0x46 &&
- GETJOCTET(data[2]) == 0x58 &&
- GETJOCTET(data[3]) == 0x58 &&
- GETJOCTET(data[4]) == 0) {
- /* Found JFIF "JFXX" extension APP0 marker */
- /* The library doesn't actually do anything with these,
- * but we try to produce a helpful trace message.
- */
- switch (GETJOCTET(data[5])) {
- case 0x10:
- TRACEMS1(cinfo, 1, JTRC_THUMB_JPEG, (int) totallen);
- break;
- case 0x11:
- TRACEMS1(cinfo, 1, JTRC_THUMB_PALETTE, (int) totallen);
- break;
- case 0x13:
- TRACEMS1(cinfo, 1, JTRC_THUMB_RGB, (int) totallen);
- break;
- default:
- TRACEMS2(cinfo, 1, JTRC_JFIF_EXTENSION,
- GETJOCTET(data[5]), (int) totallen);
- break;
- }
- } else {
- /* Start of APP0 does not match "JFIF" or "JFXX", or too short */
- TRACEMS1(cinfo, 1, JTRC_APP0, (int) totallen);
- }
- }
-
- LOCAL(void)
- examine_app14 (j_decompress_ptr cinfo, JOCTET FAR * data,
- unsigned int datalen, INT32 remaining)
- /* Examine first few bytes from an APP14.
- * Take appropriate action if it is an Adobe marker.
- * datalen is # of bytes at data[], remaining is length of rest of marker data.
- */
- {
- unsigned int version, flags0, flags1, transform;
-
- if (datalen >= APP14_DATA_LEN &&
- GETJOCTET(data[0]) == 0x41 &&
- GETJOCTET(data[1]) == 0x64 &&
- GETJOCTET(data[2]) == 0x6F &&
- GETJOCTET(data[3]) == 0x62 &&
- GETJOCTET(data[4]) == 0x65) {
- /* Found Adobe APP14 marker */
- version = (GETJOCTET(data[5]) << 8) + GETJOCTET(data[6]);
- flags0 = (GETJOCTET(data[7]) << 8) + GETJOCTET(data[8]);
- flags1 = (GETJOCTET(data[9]) << 8) + GETJOCTET(data[10]);
- transform = GETJOCTET(data[11]);
- TRACEMS4(cinfo, 1, JTRC_ADOBE, version, flags0, flags1, transform);
- cinfo->saw_Adobe_marker = TRUE;
- cinfo->Adobe_transform = (UINT8) transform;
- } else {
- /* Start of APP14 does not match "Adobe", or too short */
- TRACEMS1(cinfo, 1, JTRC_APP14, (int) (datalen + remaining));
- }
- }
-
- METHODDEF(boolean)
- get_interesting_appn (j_decompress_ptr cinfo)
- /* Process an APP0 or APP14 marker without saving it */
- {
- INT32 length;
- JOCTET b[APPN_DATA_LEN];
- unsigned int i, numtoread;
- INPUT_VARS(cinfo);
-
- INPUT_2BYTES(cinfo, length, return FALSE);
- length -= 2;
-
- /* get the interesting part of the marker data */
- if (length >= APPN_DATA_LEN)
- numtoread = APPN_DATA_LEN;
- else if (length > 0)
- numtoread = (unsigned int) length;
- else
- numtoread = 0;
- for (i = 0; i < numtoread; i++)
- INPUT_BYTE(cinfo, b[i], return FALSE);
- length -= numtoread;
-
- /* process it */
- switch (cinfo->unread_marker) {
- case M_APP0:
- examine_app0(cinfo, (JOCTET FAR *) b, numtoread, length);
- break;
- case M_APP14:
- examine_app14(cinfo, (JOCTET FAR *) b, numtoread, length);
- break;
- default:
- /* can't get here unless jpeg_save_markers chooses wrong processor */
- ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, cinfo->unread_marker);
- break;
- }
-
- /* skip any remaining data -- could be lots */
- INPUT_SYNC(cinfo);
- if (length > 0)
- (*cinfo->src->skip_input_data) (cinfo, (long) length);
-
- return TRUE;
- }
-
- #ifdef SAVE_MARKERS_SUPPORTED
-
- METHODDEF(boolean)
- save_marker (j_decompress_ptr cinfo)
- /* Save an APPn or COM marker into the marker list */
- {
- my_marker_ptr2 marker = (my_marker_ptr2) cinfo->marker;
- jpeg_saved_marker_ptr cur_marker = marker->cur_marker;
- unsigned int bytes_read, data_length;
- JOCTET FAR * data;
- INT32 length = 0;
- INPUT_VARS(cinfo);
-
- if (cur_marker == NULL) {
- /* begin reading a marker */
- INPUT_2BYTES(cinfo, length, return FALSE);
- length -= 2;
- if (length >= 0) { /* watch out for bogus length word */
- /* figure out how much we want to save */
- unsigned int limit;
- if (cinfo->unread_marker == (int) M_COM)
- limit = marker->length_limit_COM;
- else
- limit = marker->length_limit_APPn[cinfo->unread_marker - (int) M_APP0];
- if ((unsigned int) length < limit)
- limit = (unsigned int) length;
- /* allocate and initialize the marker item */
- cur_marker = (jpeg_saved_marker_ptr)
- (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
- SIZEOF(struct jpeg_marker_struct) + limit);
- cur_marker->next = NULL;
- cur_marker->marker = (UINT8) cinfo->unread_marker;
- cur_marker->original_length = (unsigned int) length;
- cur_marker->data_length = limit;
- /* data area is just beyond the jpeg_marker_struct */
- data = cur_marker->data = (JOCTET FAR *) (cur_marker + 1);
- marker->cur_marker = cur_marker;
- marker->bytes_read = 0;
- bytes_read = 0;
- data_length = limit;
- } else {
- /* deal with bogus length word */
- bytes_read = data_length = 0;
- data = NULL;
- }
- } else {
- /* resume reading a marker */
- bytes_read = marker->bytes_read;
- data_length = cur_marker->data_length;
- data = cur_marker->data + bytes_read;
- }
-
- while (bytes_read < data_length) {
- INPUT_SYNC(cinfo); /* move the restart point to here */
- marker->bytes_read = bytes_read;
- /* If there's not at least one byte in buffer, suspend */
- MAKE_BYTE_AVAIL(cinfo, return FALSE);
- /* Copy bytes with reasonable rapidity */
- while (bytes_read < data_length && bytes_in_buffer > 0) {
- *data++ = *next_input_byte++;
- bytes_in_buffer--;
- bytes_read++;
- }
- }
-
- /* Done reading what we want to read */
- if (cur_marker != NULL) { /* will be NULL if bogus length word */
- /* Add new marker to end of list */
- if (cinfo->marker_list == NULL) {
- cinfo->marker_list = cur_marker;
- } else {
- jpeg_saved_marker_ptr prev = cinfo->marker_list;
- while (prev->next != NULL)
- prev = prev->next;
- prev->next = cur_marker;
- }
- /* Reset pointer & calc remaining data length */
- data = cur_marker->data;
- length = cur_marker->original_length - data_length;
- }
- /* Reset to initial state for next marker */
- marker->cur_marker = NULL;
-
- /* Process the marker if interesting; else just make a generic trace msg */
- switch (cinfo->unread_marker) {
- case M_APP0:
- examine_app0(cinfo, data, data_length, length);
- break;
- case M_APP14:
- examine_app14(cinfo, data, data_length, length);
- break;
- default:
- TRACEMS2(cinfo, 1, JTRC_MISC_MARKER, cinfo->unread_marker,
- (int) (data_length + length));
- break;
- }
-
- /* skip any remaining data -- could be lots */
- INPUT_SYNC(cinfo); /* do before skip_input_data */
- if (length > 0)
- (*cinfo->src->skip_input_data) (cinfo, (long) length);
-
- return TRUE;
- }
-
- #endif /* SAVE_MARKERS_SUPPORTED */
-
- METHODDEF(boolean)
- skip_variable (j_decompress_ptr cinfo)
- /* Skip over an unknown or uninteresting variable-length marker */
- {
- INT32 length;
- INPUT_VARS(cinfo);
-
- INPUT_2BYTES(cinfo, length, return FALSE);
- length -= 2;
-
- TRACEMS2(cinfo, 1, JTRC_MISC_MARKER, cinfo->unread_marker, (int) length);
-
- INPUT_SYNC(cinfo); /* do before skip_input_data */
- if (length > 0)
- (*cinfo->src->skip_input_data) (cinfo, (long) length);
-
- return TRUE;
- }
-
- /*
- * Find the next JPEG marker, save it in cinfo->unread_marker.
- * Returns FALSE if had to suspend before reaching a marker;
- * in that case cinfo->unread_marker is unchanged.
- *
- * Note that the result might not be a valid marker code,
- * but it will never be 0 or FF.
- */
-
- LOCAL(boolean)
- next_marker (j_decompress_ptr cinfo)
- {
- int c;
- INPUT_VARS(cinfo);
-
- for (;;) {
- INPUT_BYTE(cinfo, c, return FALSE);
- /* Skip any non-FF bytes.
- * This may look a bit inefficient, but it will not occur in a valid file.
- * We sync after each discarded byte so that a suspending data source
- * can discard the byte from its buffer.
- */
- while (c != 0xFF) {
- cinfo->marker->discarded_bytes++;
- INPUT_SYNC(cinfo);
- INPUT_BYTE(cinfo, c, return FALSE);
- }
- /* This loop swallows any duplicate FF bytes. Extra FFs are legal as
- * pad bytes, so don't count them in discarded_bytes. We assume there
- * will not be so many consecutive FF bytes as to overflow a suspending
- * data source's input buffer.
- */
- do {
- INPUT_BYTE(cinfo, c, return FALSE);
- } while (c == 0xFF);
- if (c != 0)
- break; /* found a valid marker, exit loop */
- /* Reach here if we found a stuffed-zero data sequence (FF/00).
- * Discard it and loop back to try again.
- */
- cinfo->marker->discarded_bytes += 2;
- INPUT_SYNC(cinfo);
- }
-
- if (cinfo->marker->discarded_bytes != 0) {
- WARNMS2(cinfo, JWRN_EXTRANEOUS_DATA, cinfo->marker->discarded_bytes, c);
- cinfo->marker->discarded_bytes = 0;
- }
-
- cinfo->unread_marker = c;
-
- INPUT_SYNC(cinfo);
- return TRUE;
- }
-
- LOCAL(boolean)
- first_marker (j_decompress_ptr cinfo)
- /* Like next_marker, but used to obtain the initial SOI marker. */
- /* For this marker, we do not allow preceding garbage or fill; otherwise,
- * we might well scan an entire input file before realizing it ain't JPEG.
- * If an application wants to process non-JFIF files, it must seek to the
- * SOI before calling the JPEG library.
- */
- {
- int c, c2;
- INPUT_VARS(cinfo);
-
- INPUT_BYTE(cinfo, c, return FALSE);
- INPUT_BYTE(cinfo, c2, return FALSE);
- if (c != 0xFF || c2 != (int) M_SOI)
- ERREXIT2(cinfo, JERR_NO_SOI, c, c2);
-
- cinfo->unread_marker = c2;
-
- INPUT_SYNC(cinfo);
- return TRUE;
- }
-
- /*
- * Read markers until SOS or EOI.
- *
- * Returns same codes as are defined for jpeg_consume_input:
- * JPEG_SUSPENDED, JPEG_REACHED_SOS, or JPEG_REACHED_EOI.
- */
-
- METHODDEF(int)
- read_markers (j_decompress_ptr cinfo)
- {
- /* Outer loop repeats once for each marker. */
- for (;;) {
- /* Collect the marker proper, unless we already did. */
- /* NB: first_marker() enforces the requirement that SOI appear first. */
- if (cinfo->unread_marker == 0) {
- if (! cinfo->marker->saw_SOI) {
- if (! first_marker(cinfo))
- return JPEG_SUSPENDED;
- } else {
- if (! next_marker(cinfo))
- return JPEG_SUSPENDED;
- }
- }
- /* At this point cinfo->unread_marker contains the marker code and the
- * input point is just past the marker proper, but before any parameters.
- * A suspension will cause us to return with this state still true.
- */
- switch (cinfo->unread_marker) {
- case M_SOI:
- if (! get_soi(cinfo))
- return JPEG_SUSPENDED;
- break;
-
- case M_SOF0: /* Baseline */
- case M_SOF1: /* Extended sequential, Huffman */
- if (! get_sof(cinfo, FALSE, FALSE))
- return JPEG_SUSPENDED;
- break;
-
- case M_SOF2: /* Progressive, Huffman */
- if (! get_sof(cinfo, TRUE, FALSE))
- return JPEG_SUSPENDED;
- break;
-
- case M_SOF9: /* Extended sequential, arithmetic */
- if (! get_sof(cinfo, FALSE, TRUE))
- return JPEG_SUSPENDED;
- break;
-
- case M_SOF10: /* Progressive, arithmetic */
- if (! get_sof(cinfo, TRUE, TRUE))
- return JPEG_SUSPENDED;
- break;
-
- /* Currently unsupported SOFn types */
- case M_SOF3: /* Lossless, Huffman */
- case M_SOF5: /* Differential sequential, Huffman */
- case M_SOF6: /* Differential progressive, Huffman */
- case M_SOF7: /* Differential lossless, Huffman */
- case M_JPG: /* Reserved for JPEG extensions */
- case M_SOF11: /* Lossless, arithmetic */
- case M_SOF13: /* Differential sequential, arithmetic */
- case M_SOF14: /* Differential progressive, arithmetic */
- case M_SOF15: /* Differential lossless, arithmetic */
- ERREXIT1(cinfo, JERR_SOF_UNSUPPORTED, cinfo->unread_marker);
- break;
-
- case M_SOS:
- if (! get_sos(cinfo))
- return JPEG_SUSPENDED;
- cinfo->unread_marker = 0; /* processed the marker */
- return JPEG_REACHED_SOS;
-
- case M_EOI:
- TRACEMS(cinfo, 1, JTRC_EOI);
- cinfo->unread_marker = 0; /* processed the marker */
- return JPEG_REACHED_EOI;
-
- case M_DAC:
- if (! get_dac(cinfo))
- return JPEG_SUSPENDED;
- break;
-
- case M_DHT:
- if (! get_dht(cinfo))
- return JPEG_SUSPENDED;
- break;
-
- case M_DQT:
- if (! get_dqt(cinfo))
- return JPEG_SUSPENDED;
- break;
-
- case M_DRI:
- if (! get_dri(cinfo))
- return JPEG_SUSPENDED;
- break;
-
- case M_APP0:
- case M_APP1:
- case M_APP2:
- case M_APP3:
- case M_APP4:
- case M_APP5:
- case M_APP6:
- case M_APP7:
- case M_APP8:
- case M_APP9:
- case M_APP10:
- case M_APP11:
- case M_APP12:
- case M_APP13:
- case M_APP14:
- case M_APP15:
- if (! (*((my_marker_ptr2) cinfo->marker)->process_APPn[
- cinfo->unread_marker - (int) M_APP0]) (cinfo))
- return JPEG_SUSPENDED;
- break;
-
- case M_COM:
- if (! (*((my_marker_ptr2) cinfo->marker)->process_COM) (cinfo))
- return JPEG_SUSPENDED;
- break;
-
- case M_RST0: /* these are all parameterless */
- case M_RST1:
- case M_RST2:
- case M_RST3:
- case M_RST4:
- case M_RST5:
- case M_RST6:
- case M_RST7:
- case M_TEM:
- TRACEMS1(cinfo, 1, JTRC_PARMLESS_MARKER, cinfo->unread_marker);
- break;
-
- case M_DNL: /* Ignore DNL ... perhaps the wrong thing */
- if (! skip_variable(cinfo))
- return JPEG_SUSPENDED;
- break;
-
- default: /* must be DHP, EXP, JPGn, or RESn */
- /* For now, we treat the reserved markers as fatal errors since they are
- * likely to be used to signal incompatible JPEG Part 3 extensions.
- * Once the JPEG 3 version-number marker is well defined, this code
- * ought to change!
- */
- ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, cinfo->unread_marker);
- break;
- }
- /* Successfully processed marker, so reset state variable */
- cinfo->unread_marker = 0;
- } /* end loop */
- }
-
- /*
- * Read a restart marker, which is expected to appear next in the datastream;
- * if the marker is not there, take appropriate recovery action.
- * Returns FALSE if suspension is required.
- *
- * This is called by the entropy decoder after it has read an appropriate
- * number of MCUs. cinfo->unread_marker may be nonzero if the entropy decoder
- * has already read a marker from the data source. Under normal conditions
- * cinfo->unread_marker will be reset to 0 before returning; if not reset,
- * it holds a marker which the decoder will be unable to read past.
- */
-
- METHODDEF(boolean)
- read_restart_marker (j_decompress_ptr cinfo)
- {
- /* Obtain a marker unless we already did. */
- /* Note that next_marker will complain if it skips any data. */
- if (cinfo->unread_marker == 0) {
- if (! next_marker(cinfo))
- return FALSE;
- }
-
- if (cinfo->unread_marker ==
- ((int) M_RST0 + cinfo->marker->next_restart_num)) {
- /* Normal case --- swallow the marker and let entropy decoder continue */
- TRACEMS1(cinfo, 3, JTRC_RST, cinfo->marker->next_restart_num);
- cinfo->unread_marker = 0;
- } else {
- /* Uh-oh, the restart markers have been messed up. */
- /* Let the data source manager determine how to resync. */
- if (! (*cinfo->src->resync_to_restart) (cinfo,
- cinfo->marker->next_restart_num))
- return FALSE;
- }
-
- /* Update next-restart state */
- cinfo->marker->next_restart_num = (cinfo->marker->next_restart_num + 1) & 7;
-
- return TRUE;
- }
-
- /*
- * This is the default resync_to_restart method for data source managers
- * to use if they don't have any better approach. Some data source managers
- * may be able to back up, or may have additional knowledge about the data
- * which permits a more intelligent recovery strategy; such managers would
- * presumably supply their own resync method.
- *
- * read_restart_marker calls resync_to_restart if it finds a marker other than
- * the restart marker it was expecting. (This code is *not* used unless
- * a nonzero restart interval has been declared.) cinfo->unread_marker is
- * the marker code actually found (might be anything, except 0 or FF).
- * The desired restart marker number (0..7) is passed as a parameter.
- * This routine is supposed to apply whatever error recovery strategy seems
- * appropriate in order to position the input stream to the next data segment.
- * Note that cinfo->unread_marker is treated as a marker appearing before
- * the current data-source input point; usually it should be reset to zero
- * before returning.
- * Returns FALSE if suspension is required.
- *
- * This implementation is substantially constrained by wanting to treat the
- * input as a data stream; this means we can't back up. Therefore, we have
- * only the following actions to work with:
- * 1. Simply discard the marker and let the entropy decoder resume at next
- * byte of file.
- * 2. Read forward until we find another marker, discarding intervening
- * data. (In theory we could look ahead within the current bufferload,
- * without having to discard data if we don't find the desired marker.
- * This idea is not implemented here, in part because it makes behavior
- * dependent on buffer size and chance buffer-boundary positions.)
- * 3. Leave the marker unread (by failing to zero cinfo->unread_marker).
- * This will cause the entropy decoder to process an empty data segment,
- * inserting dummy zeroes, and then we will reprocess the marker.
- *
- * #2 is appropriate if we think the desired marker lies ahead, while #3 is
- * appropriate if the found marker is a future restart marker (indicating
- * that we have missed the desired restart marker, probably because it got
- * corrupted).
- * We apply #2 or #3 if the found marker is a restart marker no more than
- * two counts behind or ahead of the expected one. We also apply #2 if the
- * found marker is not a legal JPEG marker code (it's certainly bogus data).
- * If the found marker is a restart marker more than 2 counts away, we do #1
- * (too much risk that the marker is erroneous; with luck we will be able to
- * resync at some future point).
- * For any valid non-restart JPEG marker, we apply #3. This keeps us from
- * overrunning the end of a scan. An implementation limited to single-scan
- * files might find it better to apply #2 for markers other than EOI, since
- * any other marker would have to be bogus data in that case.
- */
-
- GLOBAL(boolean)
- jpeg_resync_to_restart (j_decompress_ptr cinfo, int desired)
- {
- int marker = cinfo->unread_marker;
- int action = 1;
-
- /* Always put up a warning. */
- WARNMS2(cinfo, JWRN_MUST_RESYNC, marker, desired);
-
- /* Outer loop handles repeated decision after scanning forward. */
- for (;;) {
- if (marker < (int) M_SOF0)
- action = 2; /* invalid marker */
- else if (marker < (int) M_RST0 || marker > (int) M_RST7)
- action = 3; /* valid non-restart marker */
- else {
- if (marker == ((int) M_RST0 + ((desired+1) & 7)) ||
- marker == ((int) M_RST0 + ((desired+2) & 7)))
- action = 3; /* one of the next two expected restarts */
- else if (marker == ((int) M_RST0 + ((desired-1) & 7)) ||
- marker == ((int) M_RST0 + ((desired-2) & 7)))
- action = 2; /* a prior restart, so advance */
- else
- action = 1; /* desired restart or too far away */
- }
- TRACEMS2(cinfo, 4, JTRC_RECOVERY_ACTION, marker, action);
- switch (action) {
- case 1:
- /* Discard marker and let entropy decoder resume processing. */
- cinfo->unread_marker = 0;
- return TRUE;
- case 2:
- /* Scan to the next marker, and repeat the decision loop. */
- if (! next_marker(cinfo))
- return FALSE;
- marker = cinfo->unread_marker;
- break;
- case 3:
- /* Return without advancing past this marker. */
- /* Entropy decoder will be forced to process an empty segment. */
- return TRUE;
- }
- } /* end loop */
- }
-
- /*
- * Reset marker processing state to begin a fresh datastream.
- */
-
- METHODDEF(void)
- reset_marker_reader (j_decompress_ptr cinfo)
- {
- my_marker_ptr2 marker = (my_marker_ptr2) cinfo->marker;
-
- cinfo->comp_info = NULL; /* until allocated by get_sof */
- cinfo->input_scan_number = 0; /* no SOS seen yet */
- cinfo->unread_marker = 0; /* no pending marker */
- marker->pub.saw_SOI = FALSE; /* set internal state too */
- marker->pub.saw_SOF = FALSE;
- marker->pub.discarded_bytes = 0;
- marker->cur_marker = NULL;
- }
-
- /*
- * Initialize the marker reader module.
- * This is called only once, when the decompression object is created.
- */
-
- GLOBAL(void)
- jinit_marker_reader (j_decompress_ptr cinfo)
- {
- my_marker_ptr2 marker;
- int i;
-
- /* Create subobject in permanent pool */
- marker = (my_marker_ptr2)
- (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
- SIZEOF(my_marker_reader));
- cinfo->marker = (struct jpeg_marker_reader *) marker;
- /* Initialize public method pointers */
- marker->pub.reset_marker_reader = reset_marker_reader;
- marker->pub.read_markers = read_markers;
- marker->pub.read_restart_marker = read_restart_marker;
- /* Initialize COM/APPn processing.
- * By default, we examine and then discard APP0 and APP14,
- * but simply discard COM and all other APPn.
- */
- marker->process_COM = skip_variable;
- marker->length_limit_COM = 0;
- for (i = 0; i < 16; i++) {
- marker->process_APPn[i] = skip_variable;
- marker->length_limit_APPn[i] = 0;
- }
- marker->process_APPn[0] = get_interesting_appn;
- marker->process_APPn[14] = get_interesting_appn;
- /* Reset marker processing state */
- reset_marker_reader(cinfo);
- }
-
- /*
- * Control saving of COM and APPn markers into marker_list.
- */
-
- #ifdef SAVE_MARKERS_SUPPORTED
-
- GLOBAL(void)
- jpeg_save_markers (j_decompress_ptr cinfo, int marker_code,
- unsigned int length_limit)
- {
- my_marker_ptr2 marker = (my_marker_ptr2) cinfo->marker;
- long maxlength;
- jpeg_marker_parser_method processor;
-
- /* Length limit mustn't be larger than what we can allocate
- * (should only be a concern in a 16-bit environment).
- */
- maxlength = cinfo->mem->max_alloc_chunk - SIZEOF(struct jpeg_marker_struct);
- if (((long) length_limit) > maxlength)
- length_limit = (unsigned int) maxlength;
-
- /* Choose processor routine to use.
- * APP0/APP14 have special requirements.
- */
- if (length_limit) {
- processor = save_marker;
- /* If saving APP0/APP14, save at least enough for our internal use. */
- if (marker_code == (int) M_APP0 && length_limit < APP0_DATA_LEN)
- length_limit = APP0_DATA_LEN;
- else if (marker_code == (int) M_APP14 && length_limit < APP14_DATA_LEN)
- length_limit = APP14_DATA_LEN;
- } else {
- processor = skip_variable;
- /* If discarding APP0/APP14, use our regular on-the-fly processor. */
- if (marker_code == (int) M_APP0 || marker_code == (int) M_APP14)
- processor = get_interesting_appn;
- }
-
- if (marker_code == (int) M_COM) {
- marker->process_COM = processor;
- marker->length_limit_COM = length_limit;
- } else if (marker_code >= (int) M_APP0 && marker_code <= (int) M_APP15) {
- marker->process_APPn[marker_code - (int) M_APP0] = processor;
- marker->length_limit_APPn[marker_code - (int) M_APP0] = length_limit;
- } else
- ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, marker_code);
- }
-
- #endif /* SAVE_MARKERS_SUPPORTED */
-
- /*
- * Install a special processing method for COM or APPn markers.
- */
-
- GLOBAL(void)
- jpeg_set_marker_processor (j_decompress_ptr cinfo, int marker_code,
- jpeg_marker_parser_method routine)
- {
- my_marker_ptr2 marker = (my_marker_ptr2) cinfo->marker;
-
- if (marker_code == (int) M_COM)
- marker->process_COM = routine;
- else if (marker_code >= (int) M_APP0 && marker_code <= (int) M_APP15)
- marker->process_APPn[marker_code - (int) M_APP0] = routine;
- else
- ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, marker_code);
- }
- /********* End of inlined file: jdmarker.c *********/
-
- /********* Start of inlined file: jdmaster.c *********/
- #define JPEG_INTERNALS
-
- /* Private state */
-
- typedef struct {
- struct jpeg_decomp_master pub; /* public fields */
-
- int pass_number; /* # of passes completed */
-
- boolean using_merged_upsample; /* TRUE if using merged upsample/cconvert */
-
- /* Saved references to initialized quantizer modules,
- * in case we need to switch modes.
- */
- struct jpeg_color_quantizer * quantizer_1pass;
- struct jpeg_color_quantizer * quantizer_2pass;
- } my_decomp_master;
-
- typedef my_decomp_master * my_master_ptr6;
-
- /*
- * Determine whether merged upsample/color conversion should be used.
- * CRUCIAL: this must match the actual capabilities of jdmerge.c!
- */
-
- LOCAL(boolean)
- use_merged_upsample (j_decompress_ptr cinfo)
- {
- #ifdef UPSAMPLE_MERGING_SUPPORTED
- /* Merging is the equivalent of plain box-filter upsampling */
- if (cinfo->do_fancy_upsampling || cinfo->CCIR601_sampling)
- return FALSE;
- /* jdmerge.c only supports YCC=>RGB color conversion */
- if (cinfo->jpeg_color_space != JCS_YCbCr || cinfo->num_components != 3 ||
- cinfo->out_color_space != JCS_RGB ||
- cinfo->out_color_components != RGB_PIXELSIZE)
- return FALSE;
- /* and it only handles 2h1v or 2h2v sampling ratios */
- if (cinfo->comp_info[0].h_samp_factor != 2 ||
- cinfo->comp_info[1].h_samp_factor != 1 ||
- cinfo->comp_info[2].h_samp_factor != 1 ||
- cinfo->comp_info[0].v_samp_factor > 2 ||
- cinfo->comp_info[1].v_samp_factor != 1 ||
- cinfo->comp_info[2].v_samp_factor != 1)
- return FALSE;
- /* furthermore, it doesn't work if we've scaled the IDCTs differently */
- if (cinfo->comp_info[0].DCT_scaled_size != cinfo->min_DCT_scaled_size ||
- cinfo->comp_info[1].DCT_scaled_size != cinfo->min_DCT_scaled_size ||
- cinfo->comp_info[2].DCT_scaled_size != cinfo->min_DCT_scaled_size)
- return FALSE;
- /* ??? also need to test for upsample-time rescaling, when & if supported */
- return TRUE; /* by golly, it'll work... */
- #else
- return FALSE;
- #endif
- }
-
- /*
- * Compute output image dimensions and related values.
- * NOTE: this is exported for possible use by application.
- * Hence it mustn't do anything that can't be done twice.
- * Also note that it may be called before the master module is initialized!
- */
-
- GLOBAL(void)
- jpeg_calc_output_dimensions (j_decompress_ptr cinfo)
- /* Do computations that are needed before master selection phase */
- {
- #ifdef IDCT_SCALING_SUPPORTED
- int ci;
- jpeg_component_info *compptr;
- #endif
-
- /* Prevent application from calling me at wrong times */
- if (cinfo->global_state != DSTATE_READY)
- ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
-
- #ifdef IDCT_SCALING_SUPPORTED
-
- /* Compute actual output image dimensions and DCT scaling choices. */
- if (cinfo->scale_num * 8 <= cinfo->scale_denom) {
- /* Provide 1/8 scaling */
- cinfo->output_width = (JDIMENSION)
- jdiv_round_up((long) cinfo->image_width, 8L);
- cinfo->output_height = (JDIMENSION)
- jdiv_round_up((long) cinfo->image_height, 8L);
- cinfo->min_DCT_scaled_size = 1;
- } else if (cinfo->scale_num * 4 <= cinfo->scale_denom) {
- /* Provide 1/4 scaling */
- cinfo->output_width = (JDIMENSION)
- jdiv_round_up((long) cinfo->image_width, 4L);
- cinfo->output_height = (JDIMENSION)
- jdiv_round_up((long) cinfo->image_height, 4L);
- cinfo->min_DCT_scaled_size = 2;
- } else if (cinfo->scale_num * 2 <= cinfo->scale_denom) {
- /* Provide 1/2 scaling */
- cinfo->output_width = (JDIMENSION)
- jdiv_round_up((long) cinfo->image_width, 2L);
- cinfo->output_height = (JDIMENSION)
- jdiv_round_up((long) cinfo->image_height, 2L);
- cinfo->min_DCT_scaled_size = 4;
- } else {
- /* Provide 1/1 scaling */
- cinfo->output_width = cinfo->image_width;
- cinfo->output_height = cinfo->image_height;
- cinfo->min_DCT_scaled_size = DCTSIZE;
- }
- /* In selecting the actual DCT scaling for each component, we try to
- * scale up the chroma components via IDCT scaling rather than upsampling.
- * This saves time if the upsampler gets to use 1:1 scaling.
- * Note this code assumes that the supported DCT scalings are powers of 2.
- */
- for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
- ci++, compptr++) {
- int ssize = cinfo->min_DCT_scaled_size;
- while (ssize < DCTSIZE &&
- (compptr->h_samp_factor * ssize * 2 <=
- cinfo->max_h_samp_factor * cinfo->min_DCT_scaled_size) &&
- (compptr->v_samp_factor * ssize * 2 <=
- cinfo->max_v_samp_factor * cinfo->min_DCT_scaled_size)) {
- ssize = ssize * 2;
- }
- compptr->DCT_scaled_size = ssize;
- }
-
- /* Recompute downsampled dimensions of components;
- * application needs to know these if using raw downsampled data.
- */
- for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
- ci++, compptr++) {
- /* Size in samples, after IDCT scaling */
- compptr->downsampled_width = (JDIMENSION)
- jdiv_round_up((long) cinfo->image_width *
- (long) (compptr->h_samp_factor * compptr->DCT_scaled_size),
- (long) (cinfo->max_h_samp_factor * DCTSIZE));
- compptr->downsampled_height = (JDIMENSION)
- jdiv_round_up((long) cinfo->image_height *
- (long) (compptr->v_samp_factor * compptr->DCT_scaled_size),
- (long) (cinfo->max_v_samp_factor * DCTSIZE));
- }
-
- #else /* !IDCT_SCALING_SUPPORTED */
-
- /* Hardwire it to "no scaling" */
- cinfo->output_width = cinfo->image_width;
- cinfo->output_height = cinfo->image_height;
- /* jdinput.c has already initialized DCT_scaled_size to DCTSIZE,
- * and has computed unscaled downsampled_width and downsampled_height.
- */
-
- #endif /* IDCT_SCALING_SUPPORTED */
-
- /* Report number of components in selected colorspace. */
- /* Probably this should be in the color conversion module... */
- switch (cinfo->out_color_space) {
- case JCS_GRAYSCALE:
- cinfo->out_color_components = 1;
- break;
- case JCS_RGB:
- #if RGB_PIXELSIZE != 3
- cinfo->out_color_components = RGB_PIXELSIZE;
- break;
- #endif /* else share code with YCbCr */
- case JCS_YCbCr:
- cinfo->out_color_components = 3;
- break;
- case JCS_CMYK:
- case JCS_YCCK:
- cinfo->out_color_components = 4;
- break;
- default: /* else must be same colorspace as in file */
- cinfo->out_color_components = cinfo->num_components;
- break;
- }
- cinfo->output_components = (cinfo->quantize_colors ? 1 :
- cinfo->out_color_components);
-
- /* See if upsampler will want to emit more than one row at a time */
- if (use_merged_upsample(cinfo))
- cinfo->rec_outbuf_height = cinfo->max_v_samp_factor;
- else
- cinfo->rec_outbuf_height = 1;
- }
-
- /*
- * Several decompression processes need to range-limit values to the range
- * 0..MAXJSAMPLE; the input value may fall somewhat outside this range
- * due to noise introduced by quantization, roundoff error, etc. These
- * processes are inner loops and need to be as fast as possible. On most
- * machines, particularly CPUs with pipelines or instruction prefetch,
- * a (subscript-check-less) C table lookup
- * x = sample_range_limit[x];
- * is faster than explicit tests
- * if (x < 0) x = 0;
- * else if (x > MAXJSAMPLE) x = MAXJSAMPLE;
- * These processes all use a common table prepared by the routine below.
- *
- * For most steps we can mathematically guarantee that the initial value
- * of x is within MAXJSAMPLE+1 of the legal range, so a table running from
- * -(MAXJSAMPLE+1) to 2*MAXJSAMPLE+1 is sufficient. But for the initial
- * limiting step (just after the IDCT), a wildly out-of-range value is
- * possible if the input data is corrupt. To avoid any chance of indexing
- * off the end of memory and getting a bad-pointer trap, we perform the
- * post-IDCT limiting thus:
- * x = range_limit[x & MASK];
- * where MASK is 2 bits wider than legal sample data, ie 10 bits for 8-bit
- * samples. Under normal circumstances this is more than enough range and
- * a correct output will be generated; with bogus input data the mask will
- * cause wraparound, and we will safely generate a bogus-but-in-range output.
- * For the post-IDCT step, we want to convert the data from signed to unsigned
- * representation by adding CENTERJSAMPLE at the same time that we limit it.
- * So the post-IDCT limiting table ends up looking like this:
- * CENTERJSAMPLE,CENTERJSAMPLE+1,...,MAXJSAMPLE,
- * MAXJSAMPLE (repeat 2*(MAXJSAMPLE+1)-CENTERJSAMPLE times),
- * 0 (repeat 2*(MAXJSAMPLE+1)-CENTERJSAMPLE times),
- * 0,1,...,CENTERJSAMPLE-1
- * Negative inputs select values from the upper half of the table after
- * masking.
- *
- * We can save some space by overlapping the start of the post-IDCT table
- * with the simpler range limiting table. The post-IDCT table begins at
- * sample_range_limit + CENTERJSAMPLE.
- *
- * Note that the table is allocated in near data space on PCs; it's small
- * enough and used often enough to justify this.
- */
-
- LOCAL(void)
- prepare_range_limit_table (j_decompress_ptr cinfo)
- /* Allocate and fill in the sample_range_limit table */
- {
- JSAMPLE * table;
- int i;
-
- table = (JSAMPLE *)
- (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
- (5 * (MAXJSAMPLE+1) + CENTERJSAMPLE) * SIZEOF(JSAMPLE));
- table += (MAXJSAMPLE+1); /* allow negative subscripts of simple table */
- cinfo->sample_range_limit = table;
- /* First segment of "simple" table: limit[x] = 0 for x < 0 */
- MEMZERO(table - (MAXJSAMPLE+1), (MAXJSAMPLE+1) * SIZEOF(JSAMPLE));
- /* Main part of "simple" table: limit[x] = x */
- for (i = 0; i <= MAXJSAMPLE; i++)
- table[i] = (JSAMPLE) i;
- table += CENTERJSAMPLE; /* Point to where post-IDCT table starts */
- /* End of simple table, rest of first half of post-IDCT table */
- for (i = CENTERJSAMPLE; i < 2*(MAXJSAMPLE+1); i++)
- table[i] = MAXJSAMPLE;
- /* Second half of post-IDCT table */
- MEMZERO(table + (2 * (MAXJSAMPLE+1)),
- (2 * (MAXJSAMPLE+1) - CENTERJSAMPLE) * SIZEOF(JSAMPLE));
- MEMCOPY(table + (4 * (MAXJSAMPLE+1) - CENTERJSAMPLE),
- cinfo->sample_range_limit, CENTERJSAMPLE * SIZEOF(JSAMPLE));
- }
-
- /*
- * Master selection of decompression modules.
- * This is done once at jpeg_start_decompress time. We determine
- * which modules will be used and give them appropriate initialization calls.
- * We also initialize the decompressor input side to begin consuming data.
- *
- * Since jpeg_read_header has finished, we know what is in the SOF
- * and (first) SOS markers. We also have all the application parameter
- * settings.
- */
-
- LOCAL(void)
- master_selection (j_decompress_ptr cinfo)
- {
- my_master_ptr6 master = (my_master_ptr6) cinfo->master;
- boolean use_c_buffer;
- long samplesperrow;
- JDIMENSION jd_samplesperrow;
-
- /* Initialize dimensions and other stuff */
- jpeg_calc_output_dimensions(cinfo);
- prepare_range_limit_table(cinfo);
-
- /* Width of an output scanline must be representable as JDIMENSION. */
- samplesperrow = (long) cinfo->output_width * (long) cinfo->out_color_components;
- jd_samplesperrow = (JDIMENSION) samplesperrow;
- if ((long) jd_samplesperrow != samplesperrow)
- ERREXIT(cinfo, JERR_WIDTH_OVERFLOW);
-
- /* Initialize my private state */
- master->pass_number = 0;
- master->using_merged_upsample = use_merged_upsample(cinfo);
-
- /* Color quantizer selection */
- master->quantizer_1pass = NULL;
- master->quantizer_2pass = NULL;
- /* No mode changes if not using buffered-image mode. */
- if (! cinfo->quantize_colors || ! cinfo->buffered_image) {
- cinfo->enable_1pass_quant = FALSE;
- cinfo->enable_external_quant = FALSE;
- cinfo->enable_2pass_quant = FALSE;
- }
- if (cinfo->quantize_colors) {
- if (cinfo->raw_data_out)
- ERREXIT(cinfo, JERR_NOTIMPL);
- /* 2-pass quantizer only works in 3-component color space. */
- if (cinfo->out_color_components != 3) {
- cinfo->enable_1pass_quant = TRUE;
- cinfo->enable_external_quant = FALSE;
- cinfo->enable_2pass_quant = FALSE;
- cinfo->colormap = NULL;
- } else if (cinfo->colormap != NULL) {
- cinfo->enable_external_quant = TRUE;
- } else if (cinfo->two_pass_quantize) {
- cinfo->enable_2pass_quant = TRUE;
- } else {
- cinfo->enable_1pass_quant = TRUE;
- }
-
- if (cinfo->enable_1pass_quant) {
- #ifdef QUANT_1PASS_SUPPORTED
- jinit_1pass_quantizer(cinfo);
- master->quantizer_1pass = cinfo->cquantize;
- #else
- ERREXIT(cinfo, JERR_NOT_COMPILED);
- #endif
- }
-
- /* We use the 2-pass code to map to external colormaps. */
- if (cinfo->enable_2pass_quant || cinfo->enable_external_quant) {
- #ifdef QUANT_2PASS_SUPPORTED
- jinit_2pass_quantizer(cinfo);
- master->quantizer_2pass = cinfo->cquantize;
- #else
- ERREXIT(cinfo, JERR_NOT_COMPILED);
- #endif
- }
- /* If both quantizers are initialized, the 2-pass one is left active;
- * this is necessary for starting with quantization to an external map.
- */
- }
-
- /* Post-processing: in particular, color conversion first */
- if (! cinfo->raw_data_out) {
- if (master->using_merged_upsample) {
- #ifdef UPSAMPLE_MERGING_SUPPORTED
- jinit_merged_upsampler(cinfo); /* does color conversion too */
- #else
- ERREXIT(cinfo, JERR_NOT_COMPILED);
- #endif
- } else {
- jinit_color_deconverter(cinfo);
- jinit_upsampler(cinfo);
- }
- jinit_d_post_controller(cinfo, cinfo->enable_2pass_quant);
- }
- /* Inverse DCT */
- jinit_inverse_dct(cinfo);
- /* Entropy decoding: either Huffman or arithmetic coding. */
- if (cinfo->arith_code) {
- ERREXIT(cinfo, JERR_ARITH_NOTIMPL);
- } else {
- if (cinfo->progressive_mode) {
- #ifdef D_PROGRESSIVE_SUPPORTED
- jinit_phuff_decoder(cinfo);
- #else
- ERREXIT(cinfo, JERR_NOT_COMPILED);
- #endif
- } else
- jinit_huff_decoder(cinfo);
- }
-
- /* Initialize principal buffer controllers. */
- use_c_buffer = cinfo->inputctl->has_multiple_scans || cinfo->buffered_image;
- jinit_d_coef_controller(cinfo, use_c_buffer);
-
- if (! cinfo->raw_data_out)
- jinit_d_main_controller(cinfo, FALSE /* never need full buffer here */);
-
- /* We can now tell the memory manager to allocate virtual arrays. */
- (*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo);
-
- /* Initialize input side of decompressor to consume first scan. */
- (*cinfo->inputctl->start_input_pass) (cinfo);
-
- #ifdef D_MULTISCAN_FILES_SUPPORTED
- /* If jpeg_start_decompress will read the whole file, initialize
- * progress monitoring appropriately. The input step is counted
- * as one pass.
- */
- if (cinfo->progress != NULL && ! cinfo->buffered_image &&
- cinfo->inputctl->has_multiple_scans) {
- int nscans;
- /* Estimate number of scans to set pass_limit. */
- if (cinfo->progressive_mode) {
- /* Arbitrarily estimate 2 interleaved DC scans + 3 AC scans/component. */
- nscans = 2 + 3 * cinfo->num_components;
- } else {
- /* For a nonprogressive multiscan file, estimate 1 scan per component. */
- nscans = cinfo->num_components;
- }
- cinfo->progress->pass_counter = 0L;
- cinfo->progress->pass_limit = (long) cinfo->total_iMCU_rows * nscans;
- cinfo->progress->completed_passes = 0;
- cinfo->progress->total_passes = (cinfo->enable_2pass_quant ? 3 : 2);
- /* Count the input pass as done */
- master->pass_number++;
- }
- #endif /* D_MULTISCAN_FILES_SUPPORTED */
- }
-
- /*
- * Per-pass setup.
- * This is called at the beginning of each output pass. We determine which
- * modules will be active during this pass and give them appropriate
- * start_pass calls. We also set is_dummy_pass to indicate whether this
- * is a "real" output pass or a dummy pass for color quantization.
- * (In the latter case, jdapistd.c will crank the pass to completion.)
- */
-
- METHODDEF(void)
- prepare_for_output_pass (j_decompress_ptr cinfo)
- {
- my_master_ptr6 master = (my_master_ptr6) cinfo->master;
-
- if (master->pub.is_dummy_pass) {
- #ifdef QUANT_2PASS_SUPPORTED
- /* Final pass of 2-pass quantization */
- master->pub.is_dummy_pass = FALSE;
- (*cinfo->cquantize->start_pass) (cinfo, FALSE);
- (*cinfo->post->start_pass) (cinfo, JBUF_CRANK_DEST);
- (*cinfo->main->start_pass) (cinfo, JBUF_CRANK_DEST);
- #else
- ERREXIT(cinfo, JERR_NOT_COMPILED);
- #endif /* QUANT_2PASS_SUPPORTED */
- } else {
- if (cinfo->quantize_colors && cinfo->colormap == NULL) {
- /* Select new quantization method */
- if (cinfo->two_pass_quantize && cinfo->enable_2pass_quant) {
- cinfo->cquantize = master->quantizer_2pass;
- master->pub.is_dummy_pass = TRUE;
- } else if (cinfo->enable_1pass_quant) {
- cinfo->cquantize = master->quantizer_1pass;
- } else {
- ERREXIT(cinfo, JERR_MODE_CHANGE);
- }
- }
- (*cinfo->idct->start_pass) (cinfo);
- (*cinfo->coef->start_output_pass) (cinfo);
- if (! cinfo->raw_data_out) {
- if (! master->using_merged_upsample)
- (*cinfo->cconvert->start_pass) (cinfo);
- (*cinfo->upsample->start_pass) (cinfo);
- if (cinfo->quantize_colors)
- (*cinfo->cquantize->start_pass) (cinfo, master->pub.is_dummy_pass);
- (*cinfo->post->start_pass) (cinfo,
- (master->pub.is_dummy_pass ? JBUF_SAVE_AND_PASS : JBUF_PASS_THRU));
- (*cinfo->main->start_pass) (cinfo, JBUF_PASS_THRU);
- }
- }
-
- /* Set up progress monitor's pass info if present */
- if (cinfo->progress != NULL) {
- cinfo->progress->completed_passes = master->pass_number;
- cinfo->progress->total_passes = master->pass_number +
- (master->pub.is_dummy_pass ? 2 : 1);
- /* In buffered-image mode, we assume one more output pass if EOI not
- * yet reached, but no more passes if EOI has been reached.
- */
- if (cinfo->buffered_image && ! cinfo->inputctl->eoi_reached) {
- cinfo->progress->total_passes += (cinfo->enable_2pass_quant ? 2 : 1);
- }
- }
- }
-
- /*
- * Finish up at end of an output pass.
- */
-
- METHODDEF(void)
- finish_output_pass (j_decompress_ptr cinfo)
- {
- my_master_ptr6 master = (my_master_ptr6) cinfo->master;
-
- if (cinfo->quantize_colors)
- (*cinfo->cquantize->finish_pass) (cinfo);
- master->pass_number++;
- }
-
- #ifdef D_MULTISCAN_FILES_SUPPORTED
-
- /*
- * Switch to a new external colormap between output passes.
- */
-
- GLOBAL(void)
- jpeg_new_colormap (j_decompress_ptr cinfo)
- {
- my_master_ptr6 master = (my_master_ptr6) cinfo->master;
-
- /* Prevent application from calling me at wrong times */
- if (cinfo->global_state != DSTATE_BUFIMAGE)
- ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
-
- if (cinfo->quantize_colors && cinfo->enable_external_quant &&
- cinfo->colormap != NULL) {
- /* Select 2-pass quantizer for external colormap use */
- cinfo->cquantize = master->quantizer_2pass;
- /* Notify quantizer of colormap change */
- (*cinfo->cquantize->new_color_map) (cinfo);
- master->pub.is_dummy_pass = FALSE; /* just in case */
- } else
- ERREXIT(cinfo, JERR_MODE_CHANGE);
- }
-
- #endif /* D_MULTISCAN_FILES_SUPPORTED */
-
- /*
- * Initialize master decompression control and select active modules.
- * This is performed at the start of jpeg_start_decompress.
- */
-
- GLOBAL(void)
- jinit_master_decompress (j_decompress_ptr cinfo)
- {
- my_master_ptr6 master;
-
- master = (my_master_ptr6)
- (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
- SIZEOF(my_decomp_master));
- cinfo->master = (struct jpeg_decomp_master *) master;
- master->pub.prepare_for_output_pass = prepare_for_output_pass;
- master->pub.finish_output_pass = finish_output_pass;
-
- master->pub.is_dummy_pass = FALSE;
-
- master_selection(cinfo);
- }
- /********* End of inlined file: jdmaster.c *********/
-
- #undef FIX
-
- /********* Start of inlined file: jdmerge.c *********/
- #define JPEG_INTERNALS
-
- #ifdef UPSAMPLE_MERGING_SUPPORTED
-
- /* Private subobject */
-
- typedef struct {
- struct jpeg_upsampler pub; /* public fields */
-
- /* Pointer to routine to do actual upsampling/conversion of one row group */
- JMETHOD(void, upmethod, (j_decompress_ptr cinfo,
- JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
- JSAMPARRAY output_buf));
-
- /* Private state for YCC->RGB conversion */
- int * Cr_r_tab; /* => table for Cr to R conversion */
- int * Cb_b_tab; /* => table for Cb to B conversion */
- INT32 * Cr_g_tab; /* => table for Cr to G conversion */
- INT32 * Cb_g_tab; /* => table for Cb to G conversion */
-
- /* For 2:1 vertical sampling, we produce two output rows at a time.
- * We need a "spare" row buffer to hold the second output row if the
- * application provides just a one-row buffer; we also use the spare
- * to discard the dummy last row if the image height is odd.
- */
- JSAMPROW spare_row;
- boolean spare_full; /* T if spare buffer is occupied */
-
- JDIMENSION out_row_width; /* samples per output row */
- JDIMENSION rows_to_go; /* counts rows remaining in image */
- } my_upsampler;
-
- typedef my_upsampler * my_upsample_ptr;
-
- #define SCALEBITS 16 /* speediest right-shift on some machines */
- #define ONE_HALF ((INT32) 1 << (SCALEBITS-1))
- #define FIX(x) ((INT32) ((x) * (1L<<SCALEBITS) + 0.5))
-
- /*
- * Initialize tables for YCC->RGB colorspace conversion.
- * This is taken directly from jdcolor.c; see that file for more info.
- */
-
- LOCAL(void)
- build_ycc_rgb_table2 (j_decompress_ptr cinfo)
- {
- my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
- int i;
- INT32 x;
- SHIFT_TEMPS
-
- upsample->Cr_r_tab = (int *)
- (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
- (MAXJSAMPLE+1) * SIZEOF(int));
- upsample->Cb_b_tab = (int *)
- (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
- (MAXJSAMPLE+1) * SIZEOF(int));
- upsample->Cr_g_tab = (INT32 *)
- (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
- (MAXJSAMPLE+1) * SIZEOF(INT32));
- upsample->Cb_g_tab = (INT32 *)
- (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
- (MAXJSAMPLE+1) * SIZEOF(INT32));
-
- for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) {
- /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
- /* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
- /* Cr=>R value is nearest int to 1.40200 * x */
- upsample->Cr_r_tab[i] = (int)
- RIGHT_SHIFT(FIX(1.40200) * x + ONE_HALF, SCALEBITS);
- /* Cb=>B value is nearest int to 1.77200 * x */
- upsample->Cb_b_tab[i] = (int)
- RIGHT_SHIFT(FIX(1.77200) * x + ONE_HALF, SCALEBITS);
- /* Cr=>G value is scaled-up -0.71414 * x */
- upsample->Cr_g_tab[i] = (- FIX(0.71414)) * x;
- /* Cb=>G value is scaled-up -0.34414 * x */
- /* We also add in ONE_HALF so that need not do it in inner loop */
- upsample->Cb_g_tab[i] = (- FIX(0.34414)) * x + ONE_HALF;
- }
- }
-
- /*
- * Initialize for an upsampling pass.
- */
-
- METHODDEF(void)
- start_pass_merged_upsample (j_decompress_ptr cinfo)
- {
- my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
-
- /* Mark the spare buffer empty */
- upsample->spare_full = FALSE;
- /* Initialize total-height counter for detecting bottom of image */
- upsample->rows_to_go = cinfo->output_height;
- }
-
- /*
- * Control routine to do upsampling (and color conversion).
- *
- * The control routine just handles the row buffering considerations.
- */
-
- METHODDEF(void)
- merged_2v_upsample (j_decompress_ptr cinfo,
- JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
- JDIMENSION in_row_groups_avail,
- JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
- JDIMENSION out_rows_avail)
- /* 2:1 vertical sampling case: may need a spare row. */
- {
- my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
- JSAMPROW work_ptrs[2];
- JDIMENSION num_rows; /* number of rows returned to caller */
-
- if (upsample->spare_full) {
- /* If we have a spare row saved from a previous cycle, just return it. */
- jcopy_sample_rows(& upsample->spare_row, 0, output_buf + *out_row_ctr, 0,
- 1, upsample->out_row_width);
- num_rows = 1;
- upsample->spare_full = FALSE;
- } else {
- /* Figure number of rows to return to caller. */
- num_rows = 2;
- /* Not more than the distance to the end of the image. */
- if (num_rows > upsample->rows_to_go)
- num_rows = upsample->rows_to_go;
- /* And not more than what the client can accept: */
- out_rows_avail -= *out_row_ctr;
- if (num_rows > out_rows_avail)
- num_rows = out_rows_avail;
- /* Create output pointer array for upsampler. */
- work_ptrs[0] = output_buf[*out_row_ctr];
- if (num_rows > 1) {
- work_ptrs[1] = output_buf[*out_row_ctr + 1];
- } else {
- work_ptrs[1] = upsample->spare_row;
- upsample->spare_full = TRUE;
- }
- /* Now do the upsampling. */
- (*upsample->upmethod) (cinfo, input_buf, *in_row_group_ctr, work_ptrs);
- }
-
- /* Adjust counts */
- *out_row_ctr += num_rows;
- upsample->rows_to_go -= num_rows;
- /* When the buffer is emptied, declare this input row group consumed */
- if (! upsample->spare_full)
- (*in_row_group_ctr)++;
- }
-
- METHODDEF(void)
- merged_1v_upsample (j_decompress_ptr cinfo,
- JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
- JDIMENSION in_row_groups_avail,
- JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
- JDIMENSION out_rows_avail)
- /* 1:1 vertical sampling case: much easier, never need a spare row. */
- {
- my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
-
- /* Just do the upsampling. */
- (*upsample->upmethod) (cinfo, input_buf, *in_row_group_ctr,
- output_buf + *out_row_ctr);
- /* Adjust counts */
- (*out_row_ctr)++;
- (*in_row_group_ctr)++;
- }
-
- /*
- * These are the routines invoked by the control routines to do
- * the actual upsampling/conversion. One row group is processed per call.
- *
- * Note: since we may be writing directly into application-supplied buffers,
- * we have to be honest about the output width; we can't assume the buffer
- * has been rounded up to an even width.
- */
-
- /*
- * Upsample and color convert for the case of 2:1 horizontal and 1:1 vertical.
- */
-
- METHODDEF(void)
- h2v1_merged_upsample (j_decompress_ptr cinfo,
- JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
- JSAMPARRAY output_buf)
- {
- my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
- register int y, cred, cgreen, cblue;
- int cb, cr;
- register JSAMPROW outptr;
- JSAMPROW inptr0, inptr1, inptr2;
- JDIMENSION col;
- /* copy these pointers into registers if possible */
- register JSAMPLE * range_limit = cinfo->sample_range_limit;
- int * Crrtab = upsample->Cr_r_tab;
- int * Cbbtab = upsample->Cb_b_tab;
- INT32 * Crgtab = upsample->Cr_g_tab;
- INT32 * Cbgtab = upsample->Cb_g_tab;
- SHIFT_TEMPS
-
- inptr0 = input_buf[0][in_row_group_ctr];
- inptr1 = input_buf[1][in_row_group_ctr];
- inptr2 = input_buf[2][in_row_group_ctr];
- outptr = output_buf[0];
- /* Loop for each pair of output pixels */
- for (col = cinfo->output_width >> 1; col > 0; col--) {
- /* Do the chroma part of the calculation */
- cb = GETJSAMPLE(*inptr1++);
- cr = GETJSAMPLE(*inptr2++);
- cred = Crrtab[cr];
- cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
- cblue = Cbbtab[cb];
- /* Fetch 2 Y values and emit 2 pixels */
- y = GETJSAMPLE(*inptr0++);
- outptr[RGB_RED] = range_limit[y + cred];
- outptr[RGB_GREEN] = range_limit[y + cgreen];
- outptr[RGB_BLUE] = range_limit[y + cblue];
- outptr += RGB_PIXELSIZE;
- y = GETJSAMPLE(*inptr0++);
- outptr[RGB_RED] = range_limit[y + cred];
- outptr[RGB_GREEN] = range_limit[y + cgreen];
- outptr[RGB_BLUE] = range_limit[y + cblue];
- outptr += RGB_PIXELSIZE;
- }
- /* If image width is odd, do the last output column separately */
- if (cinfo->output_width & 1) {
- cb = GETJSAMPLE(*inptr1);
- cr = GETJSAMPLE(*inptr2);
- cred = Crrtab[cr];
- cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
- cblue = Cbbtab[cb];
- y = GETJSAMPLE(*inptr0);
- outptr[RGB_RED] = range_limit[y + cred];
- outptr[RGB_GREEN] = range_limit[y + cgreen];
- outptr[RGB_BLUE] = range_limit[y + cblue];
- }
- }
-
- /*
- * Upsample and color convert for the case of 2:1 horizontal and 2:1 vertical.
- */
-
- METHODDEF(void)
- h2v2_merged_upsample (j_decompress_ptr cinfo,
- JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
- JSAMPARRAY output_buf)
- {
- my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
- register int y, cred, cgreen, cblue;
- int cb, cr;
- register JSAMPROW outptr0, outptr1;
- JSAMPROW inptr00, inptr01, inptr1, inptr2;
- JDIMENSION col;
- /* copy these pointers into registers if possible */
- register JSAMPLE * range_limit = cinfo->sample_range_limit;
- int * Crrtab = upsample->Cr_r_tab;
- int * Cbbtab = upsample->Cb_b_tab;
- INT32 * Crgtab = upsample->Cr_g_tab;
- INT32 * Cbgtab = upsample->Cb_g_tab;
- SHIFT_TEMPS
-
- inptr00 = input_buf[0][in_row_group_ctr*2];
- inptr01 = input_buf[0][in_row_group_ctr*2 + 1];
- inptr1 = input_buf[1][in_row_group_ctr];
- inptr2 = input_buf[2][in_row_group_ctr];
- outptr0 = output_buf[0];
- outptr1 = output_buf[1];
- /* Loop for each group of output pixels */
- for (col = cinfo->output_width >> 1; col > 0; col--) {
- /* Do the chroma part of the calculation */
- cb = GETJSAMPLE(*inptr1++);
- cr = GETJSAMPLE(*inptr2++);
- cred = Crrtab[cr];
- cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
- cblue = Cbbtab[cb];
- /* Fetch 4 Y values and emit 4 pixels */
- y = GETJSAMPLE(*inptr00++);
- outptr0[RGB_RED] = range_limit[y + cred];
- outptr0[RGB_GREEN] = range_limit[y + cgreen];
- outptr0[RGB_BLUE] = range_limit[y + cblue];
- outptr0 += RGB_PIXELSIZE;
- y = GETJSAMPLE(*inptr00++);
- outptr0[RGB_RED] = range_limit[y + cred];
- outptr0[RGB_GREEN] = range_limit[y + cgreen];
- outptr0[RGB_BLUE] = range_limit[y + cblue];
- outptr0 += RGB_PIXELSIZE;
- y = GETJSAMPLE(*inptr01++);
- outptr1[RGB_RED] = range_limit[y + cred];
- outptr1[RGB_GREEN] = range_limit[y + cgreen];
- outptr1[RGB_BLUE] = range_limit[y + cblue];
- outptr1 += RGB_PIXELSIZE;
- y = GETJSAMPLE(*inptr01++);
- outptr1[RGB_RED] = range_limit[y + cred];
- outptr1[RGB_GREEN] = range_limit[y + cgreen];
- outptr1[RGB_BLUE] = range_limit[y + cblue];
- outptr1 += RGB_PIXELSIZE;
- }
- /* If image width is odd, do the last output column separately */
- if (cinfo->output_width & 1) {
- cb = GETJSAMPLE(*inptr1);
- cr = GETJSAMPLE(*inptr2);
- cred = Crrtab[cr];
- cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
- cblue = Cbbtab[cb];
- y = GETJSAMPLE(*inptr00);
- outptr0[RGB_RED] = range_limit[y + cred];
- outptr0[RGB_GREEN] = range_limit[y + cgreen];
- outptr0[RGB_BLUE] = range_limit[y + cblue];
- y = GETJSAMPLE(*inptr01);
- outptr1[RGB_RED] = range_limit[y + cred];
- outptr1[RGB_GREEN] = range_limit[y + cgreen];
- outptr1[RGB_BLUE] = range_limit[y + cblue];
- }
- }
-
- /*
- * Module initialization routine for merged upsampling/color conversion.
- *
- * NB: this is called under the conditions determined by use_merged_upsample()
- * in jdmaster.c. That routine MUST correspond to the actual capabilities
- * of this module; no safety checks are made here.
- */
-
- GLOBAL(void)
- jinit_merged_upsampler (j_decompress_ptr cinfo)
- {
- my_upsample_ptr upsample;
-
- upsample = (my_upsample_ptr)
- (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
- SIZEOF(my_upsampler));
- cinfo->upsample = (struct jpeg_upsampler *) upsample;
- upsample->pub.start_pass = start_pass_merged_upsample;
- upsample->pub.need_context_rows = FALSE;
-
- upsample->out_row_width = cinfo->output_width * cinfo->out_color_components;
-
- if (cinfo->max_v_samp_factor == 2) {
- upsample->pub.upsample = merged_2v_upsample;
- upsample->upmethod = h2v2_merged_upsample;
- /* Allocate a spare row buffer */
- upsample->spare_row = (JSAMPROW)
- (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
- (size_t) (upsample->out_row_width * SIZEOF(JSAMPLE)));
- } else {
- upsample->pub.upsample = merged_1v_upsample;
- upsample->upmethod = h2v1_merged_upsample;
- /* No spare row needed */
- upsample->spare_row = NULL;
- }
-
- build_ycc_rgb_table2(cinfo);
- }
-
- #endif /* UPSAMPLE_MERGING_SUPPORTED */
- /********* End of inlined file: jdmerge.c *********/
-
- #undef ASSIGN_STATE
-
- /********* Start of inlined file: jdphuff.c *********/
- #define JPEG_INTERNALS
-
- #ifdef D_PROGRESSIVE_SUPPORTED
-
- /*
- * Expanded entropy decoder object for progressive Huffman decoding.
- *
- * The savable_state subrecord contains fields that change within an MCU,
- * but must not be updated permanently until we complete the MCU.
- */
-
- typedef struct {
- unsigned int EOBRUN; /* remaining EOBs in EOBRUN */
- int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */
- } savable_state3;
-
- /* This macro is to work around compilers with missing or broken
- * structure assignment. You'll need to fix this code if you have
- * such a compiler and you change MAX_COMPS_IN_SCAN.
- */
-
- #ifndef NO_STRUCT_ASSIGN
- #define ASSIGN_STATE(dest,src) ((dest) = (src))
- #else
- #if MAX_COMPS_IN_SCAN == 4
- #define ASSIGN_STATE(dest,src) \
- ((dest).EOBRUN = (src).EOBRUN, \
- (dest).last_dc_val[0] = (src).last_dc_val[0], \
- (dest).last_dc_val[1] = (src).last_dc_val[1], \
- (dest).last_dc_val[2] = (src).last_dc_val[2], \
- (dest).last_dc_val[3] = (src).last_dc_val[3])
- #endif
- #endif
-
- typedef struct {
- struct jpeg_entropy_decoder pub; /* public fields */
-
- /* These fields are loaded into local variables at start of each MCU.
- * In case of suspension, we exit WITHOUT updating them.
- */
- bitread_perm_state bitstate; /* Bit buffer at start of MCU */
- savable_state3 saved; /* Other state at start of MCU */
-
- /* These fields are NOT loaded into local working state. */
- unsigned int restarts_to_go; /* MCUs left in this restart interval */
-
- /* Pointers to derived tables (these workspaces have image lifespan) */
- d_derived_tbl * derived_tbls[NUM_HUFF_TBLS];
-
- d_derived_tbl * ac_derived_tbl; /* active table during an AC scan */
- } phuff_entropy_decoder;
-
- typedef phuff_entropy_decoder * phuff_entropy_ptr2;
-
- /* Forward declarations */
- METHODDEF(boolean) decode_mcu_DC_first JPP((j_decompress_ptr cinfo,
- JBLOCKROW *MCU_data));
- METHODDEF(boolean) decode_mcu_AC_first JPP((j_decompress_ptr cinfo,
- JBLOCKROW *MCU_data));
- METHODDEF(boolean) decode_mcu_DC_refine JPP((j_decompress_ptr cinfo,
- JBLOCKROW *MCU_data));
- METHODDEF(boolean) decode_mcu_AC_refine JPP((j_decompress_ptr cinfo,
- JBLOCKROW *MCU_data));
-
- /*
- * Initialize for a Huffman-compressed scan.
- */
-
- METHODDEF(void)
- start_pass_phuff_decoder (j_decompress_ptr cinfo)
- {
- phuff_entropy_ptr2 entropy = (phuff_entropy_ptr2) cinfo->entropy;
- boolean is_DC_band, bad;
- int ci, coefi, tbl;
- int *coef_bit_ptr;
- jpeg_component_info * compptr;
-
- is_DC_band = (cinfo->Ss == 0);
-
- /* Validate scan parameters */
- bad = FALSE;
- if (is_DC_band) {
- if (cinfo->Se != 0)
- bad = TRUE;
- } else {
- /* need not check Ss/Se < 0 since they came from unsigned bytes */
- if (cinfo->Ss > cinfo->Se || cinfo->Se >= DCTSIZE2)
- bad = TRUE;
- /* AC scans may have only one component */
- if (cinfo->comps_in_scan != 1)
- bad = TRUE;
- }
- if (cinfo->Ah != 0) {
- /* Successive approximation refinement scan: must have Al = Ah-1. */
- if (cinfo->Al != cinfo->Ah-1)
- bad = TRUE;
- }
- if (cinfo->Al > 13) /* need not check for < 0 */
- bad = TRUE;
- /* Arguably the maximum Al value should be less than 13 for 8-bit precision,
- * but the spec doesn't say so, and we try to be liberal about what we
- * accept. Note: large Al values could result in out-of-range DC
- * coefficients during early scans, leading to bizarre displays due to
- * overflows in the IDCT math. But we won't crash.
- */
- if (bad)
- ERREXIT4(cinfo, JERR_BAD_PROGRESSION,
- cinfo->Ss, cinfo->Se, cinfo->Ah, cinfo->Al);
- /* Update progression status, and verify that scan order is legal.
- * Note that inter-scan inconsistencies are treated as warnings
- * not fatal errors ... not clear if this is right way to behave.
- */
- for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
- int cindex = cinfo->cur_comp_info[ci]->component_index;
- coef_bit_ptr = & cinfo->coef_bits[cindex][0];
- if (!is_DC_band && coef_bit_ptr[0] < 0) /* AC without prior DC scan */
- WARNMS2(cinfo, JWRN_BOGUS_PROGRESSION, cindex, 0);
- for (coefi = cinfo->Ss; coefi <= cinfo->Se; coefi++) {
- int expected = (coef_bit_ptr[coefi] < 0) ? 0 : coef_bit_ptr[coefi];
- if (cinfo->Ah != expected)
- WARNMS2(cinfo, JWRN_BOGUS_PROGRESSION, cindex, coefi);
- coef_bit_ptr[coefi] = cinfo->Al;
- }
- }
-
- /* Select MCU decoding routine */
- if (cinfo->Ah == 0) {
- if (is_DC_band)
- entropy->pub.decode_mcu = decode_mcu_DC_first;
- else
- entropy->pub.decode_mcu = decode_mcu_AC_first;
- } else {
- if (is_DC_band)
- entropy->pub.decode_mcu = decode_mcu_DC_refine;
- else
- entropy->pub.decode_mcu = decode_mcu_AC_refine;
- }
-
- for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
- compptr = cinfo->cur_comp_info[ci];
- /* Make sure requested tables are present, and compute derived tables.
- * We may build same derived table more than once, but it's not expensive.
- */
- if (is_DC_band) {
- if (cinfo->Ah == 0) { /* DC refinement needs no table */
- tbl = compptr->dc_tbl_no;
- jpeg_make_d_derived_tbl(cinfo, TRUE, tbl,
- & entropy->derived_tbls[tbl]);
- }
- } else {
- tbl = compptr->ac_tbl_no;
- jpeg_make_d_derived_tbl(cinfo, FALSE, tbl,
- & entropy->derived_tbls[tbl]);
- /* remember the single active table */
- entropy->ac_derived_tbl = entropy->derived_tbls[tbl];
- }
- /* Initialize DC predictions to 0 */
- entropy->saved.last_dc_val[ci] = 0;
- }
-
- /* Initialize bitread state variables */
- entropy->bitstate.bits_left = 0;
- entropy->bitstate.get_buffer = 0; /* unnecessary, but keeps Purify quiet */
- entropy->pub.insufficient_data = FALSE;
-
- /* Initialize private state variables */
- entropy->saved.EOBRUN = 0;
-
- /* Initialize restart counter */
- entropy->restarts_to_go = cinfo->restart_interval;
- }
-
- /*
- * Check for a restart marker & resynchronize decoder.
- * Returns FALSE if must suspend.
- */
-
- LOCAL(boolean)
- process_restartp (j_decompress_ptr cinfo)
- {
- phuff_entropy_ptr2 entropy = (phuff_entropy_ptr2) cinfo->entropy;
- int ci;
-
- /* Throw away any unused bits remaining in bit buffer; */
- /* include any full bytes in next_marker's count of discarded bytes */
- cinfo->marker->discarded_bytes += entropy->bitstate.bits_left / 8;
- entropy->bitstate.bits_left = 0;
-
- /* Advance past the RSTn marker */
- if (! (*cinfo->marker->read_restart_marker) (cinfo))
- return FALSE;
-
- /* Re-initialize DC predictions to 0 */
- for (ci = 0; ci < cinfo->comps_in_scan; ci++)
- entropy->saved.last_dc_val[ci] = 0;
- /* Re-init EOB run count, too */
- entropy->saved.EOBRUN = 0;
-
- /* Reset restart counter */
- entropy->restarts_to_go = cinfo->restart_interval;
-
- /* Reset out-of-data flag, unless read_restart_marker left us smack up
- * against a marker. In that case we will end up treating the next data
- * segment as empty, and we can avoid producing bogus output pixels by
- * leaving the flag set.
- */
- if (cinfo->unread_marker == 0)
- entropy->pub.insufficient_data = FALSE;
-
- return TRUE;
- }
-
- /*
- * Huffman MCU decoding.
- * Each of these routines decodes and returns one MCU's worth of
- * Huffman-compressed coefficients.
- * The coefficients are reordered from zigzag order into natural array order,
- * but are not dequantized.
- *
- * The i'th block of the MCU is stored into the block pointed to by
- * MCU_data[i]. WE ASSUME THIS AREA IS INITIALLY ZEROED BY THE CALLER.
- *
- * We return FALSE if data source requested suspension. In that case no
- * changes have been made to permanent state. (Exception: some output
- * coefficients may already have been assigned. This is harmless for
- * spectral selection, since we'll just re-assign them on the next call.
- * Successive approximation AC refinement has to be more careful, however.)
- */
-
- /*
- * MCU decoding for DC initial scan (either spectral selection,
- * or first pass of successive approximation).
- */
-
- METHODDEF(boolean)
- decode_mcu_DC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
- {
- phuff_entropy_ptr2 entropy = (phuff_entropy_ptr2) cinfo->entropy;
- int Al = cinfo->Al;
- register int s, r;
- int blkn, ci;
- JBLOCKROW block;
- BITREAD_STATE_VARS;
- savable_state3 state;
- d_derived_tbl * tbl;
- jpeg_component_info * compptr;
-
- /* Process restart marker if needed; may have to suspend */
- if (cinfo->restart_interval) {
- if (entropy->restarts_to_go == 0)
- if (! process_restartp(cinfo))
- return FALSE;
- }
-
- /* If we've run out of data, just leave the MCU set to zeroes.
- * This way, we return uniform gray for the remainder of the segment.
- */
- if (! entropy->pub.insufficient_data) {
-
- /* Load up working state */
- BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
- ASSIGN_STATE(state, entropy->saved);
-
- /* Outer loop handles each block in the MCU */
-
- for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
- block = MCU_data[blkn];
- ci = cinfo->MCU_membership[blkn];
- compptr = cinfo->cur_comp_info[ci];
- tbl = entropy->derived_tbls[compptr->dc_tbl_no];
-
- /* Decode a single block's worth of coefficients */
-
- /* Section F.2.2.1: decode the DC coefficient difference */
- HUFF_DECODE(s, br_state, tbl, return FALSE, label1);
- if (s) {
- CHECK_BIT_BUFFER(br_state, s, return FALSE);
- r = GET_BITS(s);
- s = HUFF_EXTEND(r, s);
- }
-
- /* Convert DC difference to actual value, update last_dc_val */
- s += state.last_dc_val[ci];
- state.last_dc_val[ci] = s;
- /* Scale and output the coefficient (assumes jpeg_natural_order[0]=0) */
- (*block)[0] = (JCOEF) (s << Al);
- }
-
- /* Completed MCU, so update state */
- BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
- ASSIGN_STATE(entropy->saved, state);
- }
-
- /* Account for restart interval (no-op if not using restarts) */
- entropy->restarts_to_go--;
-
- return TRUE;
- }
-
- /*
- * MCU decoding for AC initial scan (either spectral selection,
- * or first pass of successive approximation).
- */
-
- METHODDEF(boolean)
- decode_mcu_AC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
- {
- phuff_entropy_ptr2 entropy = (phuff_entropy_ptr2) cinfo->entropy;
- int Se = cinfo->Se;
- int Al = cinfo->Al;
- register int s, k, r;
- unsigned int EOBRUN;
- JBLOCKROW block;
- BITREAD_STATE_VARS;
- d_derived_tbl * tbl;
-
- /* Process restart marker if needed; may have to suspend */
- if (cinfo->restart_interval) {
- if (entropy->restarts_to_go == 0)
- if (! process_restartp(cinfo))
- return FALSE;
- }
-
- /* If we've run out of data, just leave the MCU set to zeroes.
- * This way, we return uniform gray for the remainder of the segment.
- */
- if (! entropy->pub.insufficient_data) {
-
- /* Load up working state.
- * We can avoid loading/saving bitread state if in an EOB run.
- */
- EOBRUN = entropy->saved.EOBRUN; /* only part of saved state we need */
-
- /* There is always only one block per MCU */
-
- if (EOBRUN > 0) /* if it's a band of zeroes... */
- EOBRUN--; /* ...process it now (we do nothing) */
- else {
- BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
- block = MCU_data[0];
- tbl = entropy->ac_derived_tbl;
-
- for (k = cinfo->Ss; k <= Se; k++) {
- HUFF_DECODE(s, br_state, tbl, return FALSE, label2);
- r = s >> 4;
- s &= 15;
- if (s) {
- k += r;
- CHECK_BIT_BUFFER(br_state, s, return FALSE);
- r = GET_BITS(s);
- s = HUFF_EXTEND(r, s);
- /* Scale and output coefficient in natural (dezigzagged) order */
- (*block)[jpeg_natural_order[k]] = (JCOEF) (s << Al);
- } else {
- if (r == 15) { /* ZRL */
- k += 15; /* skip 15 zeroes in band */
- } else { /* EOBr, run length is 2^r + appended bits */
- EOBRUN = 1 << r;
- if (r) { /* EOBr, r > 0 */
- CHECK_BIT_BUFFER(br_state, r, return FALSE);
- r = GET_BITS(r);
- EOBRUN += r;
- }
- EOBRUN--; /* this band is processed at this moment */
- break; /* force end-of-band */
- }
- }
- }
-
- BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
- }
-
- /* Completed MCU, so update state */
- entropy->saved.EOBRUN = EOBRUN; /* only part of saved state we need */
- }
-
- /* Account for restart interval (no-op if not using restarts) */
- entropy->restarts_to_go--;
-
- return TRUE;
- }
-
- /*
- * MCU decoding for DC successive approximation refinement scan.
- * Note: we assume such scans can be multi-component, although the spec
- * is not very clear on the point.
- */
-
- METHODDEF(boolean)
- decode_mcu_DC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
- {
- phuff_entropy_ptr2 entropy = (phuff_entropy_ptr2) cinfo->entropy;
- int p1 = 1 << cinfo->Al; /* 1 in the bit position being coded */
- int blkn;
- JBLOCKROW block;
- BITREAD_STATE_VARS;
-
- /* Process restart marker if needed; may have to suspend */
- if (cinfo->restart_interval) {
- if (entropy->restarts_to_go == 0)
- if (! process_restartp(cinfo))
- return FALSE;
- }
-
- /* Not worth the cycles to check insufficient_data here,
- * since we will not change the data anyway if we read zeroes.
- */
-
- /* Load up working state */
- BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
-
- /* Outer loop handles each block in the MCU */
-
- for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
- block = MCU_data[blkn];
-
- /* Encoded data is simply the next bit of the two's-complement DC value */
- CHECK_BIT_BUFFER(br_state, 1, return FALSE);
- if (GET_BITS(1))
- (*block)[0] |= p1;
- /* Note: since we use |=, repeating the assignment later is safe */
- }
-
- /* Completed MCU, so update state */
- BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
-
- /* Account for restart interval (no-op if not using restarts) */
- entropy->restarts_to_go--;
-
- return TRUE;
- }
-
- /*
- * MCU decoding for AC successive approximation refinement scan.
- */
-
- METHODDEF(boolean)
- decode_mcu_AC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
- {
- phuff_entropy_ptr2 entropy = (phuff_entropy_ptr2) cinfo->entropy;
- int Se = cinfo->Se;
- int p1 = 1 << cinfo->Al; /* 1 in the bit position being coded */
- int m1 = (-1) << cinfo->Al; /* -1 in the bit position being coded */
- register int s, k, r;
- unsigned int EOBRUN;
- JBLOCKROW block;
- JCOEFPTR thiscoef;
- BITREAD_STATE_VARS;
- d_derived_tbl * tbl;
- int num_newnz;
- int newnz_pos[DCTSIZE2];
-
- /* Process restart marker if needed; may have to suspend */
- if (cinfo->restart_interval) {
- if (entropy->restarts_to_go == 0)
- if (! process_restartp(cinfo))
- return FALSE;
- }
-
- /* If we've run out of data, don't modify the MCU.
- */
- if (! entropy->pub.insufficient_data) {
-
- /* Load up working state */
- BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
- EOBRUN = entropy->saved.EOBRUN; /* only part of saved state we need */
-
- /* There is always only one block per MCU */
- block = MCU_data[0];
- tbl = entropy->ac_derived_tbl;
-
- /* If we are forced to suspend, we must undo the assignments to any newly
- * nonzero coefficients in the block, because otherwise we'd get confused
- * next time about which coefficients were already nonzero.
- * But we need not undo addition of bits to already-nonzero coefficients;
- * instead, we can test the current bit to see if we already did it.
- */
- num_newnz = 0;
-
- /* initialize coefficient loop counter to start of band */
- k = cinfo->Ss;
-
- if (EOBRUN == 0) {
- for (; k <= Se; k++) {
- HUFF_DECODE(s, br_state, tbl, goto undoit, label3);
- r = s >> 4;
- s &= 15;
- if (s) {
- if (s != 1) /* size of new coef should always be 1 */
- WARNMS(cinfo, JWRN_HUFF_BAD_CODE);
- CHECK_BIT_BUFFER(br_state, 1, goto undoit);
- if (GET_BITS(1))
- s = p1; /* newly nonzero coef is positive */
- else
- s = m1; /* newly nonzero coef is negative */
- } else {
- if (r != 15) {
- EOBRUN = 1 << r; /* EOBr, run length is 2^r + appended bits */
- if (r) {
- CHECK_BIT_BUFFER(br_state, r, goto undoit);
- r = GET_BITS(r);
- EOBRUN += r;
- }
- break; /* rest of block is handled by EOB logic */
- }
- /* note s = 0 for processing ZRL */
- }
- /* Advance over already-nonzero coefs and r still-zero coefs,
- * appending correction bits to the nonzeroes. A correction bit is 1
- * if the absolute value of the coefficient must be increased.
- */
- do {
- thiscoef = *block + jpeg_natural_order[k];
- if (*thiscoef != 0) {
- CHECK_BIT_BUFFER(br_state, 1, goto undoit);
- if (GET_BITS(1)) {
- if ((*thiscoef & p1) == 0) { /* do nothing if already set it */
- if (*thiscoef >= 0)
- *thiscoef += p1;
- else
- *thiscoef += m1;
- }
- }
- } else {
- if (--r < 0)
- break; /* reached target zero coefficient */
- }
- k++;
- } while (k <= Se);
- if (s) {
- int pos = jpeg_natural_order[k];
- /* Output newly nonzero coefficient */
- (*block)[pos] = (JCOEF) s;
- /* Remember its position in case we have to suspend */
- newnz_pos[num_newnz++] = pos;
- }
- }
- }
-
- if (EOBRUN > 0) {
- /* Scan any remaining coefficient positions after the end-of-band
- * (the last newly nonzero coefficient, if any). Append a correction
- * bit to each already-nonzero coefficient. A correction bit is 1
- * if the absolute value of the coefficient must be increased.
- */
- for (; k <= Se; k++) {
- thiscoef = *block + jpeg_natural_order[k];
- if (*thiscoef != 0) {
- CHECK_BIT_BUFFER(br_state, 1, goto undoit);
- if (GET_BITS(1)) {
- if ((*thiscoef & p1) == 0) { /* do nothing if already changed it */
- if (*thiscoef >= 0)
- *thiscoef += p1;
- else
- *thiscoef += m1;
- }
- }
- }
- }
- /* Count one block completed in EOB run */
- EOBRUN--;
- }
-
- /* Completed MCU, so update state */
- BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
- entropy->saved.EOBRUN = EOBRUN; /* only part of saved state we need */
- }
-
- /* Account for restart interval (no-op if not using restarts) */
- entropy->restarts_to_go--;
-
- return TRUE;
-
- undoit:
- /* Re-zero any output coefficients that we made newly nonzero */
- while (num_newnz > 0)
- (*block)[newnz_pos[--num_newnz]] = 0;
-
- return FALSE;
- }
-
- /*
- * Module initialization routine for progressive Huffman entropy decoding.
- */
-
- GLOBAL(void)
- jinit_phuff_decoder (j_decompress_ptr cinfo)
- {
- phuff_entropy_ptr2 entropy;
- int *coef_bit_ptr;
- int ci, i;
-
- entropy = (phuff_entropy_ptr2)
- (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
- SIZEOF(phuff_entropy_decoder));
- cinfo->entropy = (struct jpeg_entropy_decoder *) entropy;
- entropy->pub.start_pass = start_pass_phuff_decoder;
-
- /* Mark derived tables unallocated */
- for (i = 0; i < NUM_HUFF_TBLS; i++) {
- entropy->derived_tbls[i] = NULL;
- }
-
- /* Create progression status table */
- cinfo->coef_bits = (int (*)[DCTSIZE2])
- (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
- cinfo->num_components*DCTSIZE2*SIZEOF(int));
- coef_bit_ptr = & cinfo->coef_bits[0][0];
- for (ci = 0; ci < cinfo->num_components; ci++)
- for (i = 0; i < DCTSIZE2; i++)
- *coef_bit_ptr++ = -1;
- }
-
- #endif /* D_PROGRESSIVE_SUPPORTED */
- /********* End of inlined file: jdphuff.c *********/
-
- /********* Start of inlined file: jdpostct.c *********/
- #define JPEG_INTERNALS
-
- /* Private buffer controller object */
-
- typedef struct {
- struct jpeg_d_post_controller pub; /* public fields */
-
- /* Color quantization source buffer: this holds output data from
- * the upsample/color conversion step to be passed to the quantizer.
- * For two-pass color quantization, we need a full-image buffer;
- * for one-pass operation, a strip buffer is sufficient.
- */
- jvirt_sarray_ptr whole_image; /* virtual array, or NULL if one-pass */
- JSAMPARRAY buffer; /* strip buffer, or current strip of virtual */
- JDIMENSION strip_height; /* buffer size in rows */
- /* for two-pass mode only: */
- JDIMENSION starting_row; /* row # of first row in current strip */
- JDIMENSION next_row; /* index of next row to fill/empty in strip */
- } my_post_controller;
-
- typedef my_post_controller * my_post_ptr;
-
- /* Forward declarations */
- METHODDEF(void) post_process_1pass
- JPP((j_decompress_ptr cinfo,
- JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
- JDIMENSION in_row_groups_avail,
- JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
- JDIMENSION out_rows_avail));
- #ifdef QUANT_2PASS_SUPPORTED
- METHODDEF(void) post_process_prepass
- JPP((j_decompress_ptr cinfo,
- JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
- JDIMENSION in_row_groups_avail,
- JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
- JDIMENSION out_rows_avail));
- METHODDEF(void) post_process_2pass
- JPP((j_decompress_ptr cinfo,
- JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
- JDIMENSION in_row_groups_avail,
- JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
- JDIMENSION out_rows_avail));
- #endif
-
- /*
- * Initialize for a processing pass.
- */
-
- METHODDEF(void)
- start_pass_dpost (j_decompress_ptr cinfo, J_BUF_MODE pass_mode)
- {
- my_post_ptr post = (my_post_ptr) cinfo->post;
-
- switch (pass_mode) {
- case JBUF_PASS_THRU:
- if (cinfo->quantize_colors) {
- /* Single-pass processing with color quantization. */
- post->pub.post_process_data = post_process_1pass;
- /* We could be doing buffered-image output before starting a 2-pass
- * color quantization; in that case, jinit_d_post_controller did not
- * allocate a strip buffer. Use the virtual-array buffer as workspace.
- */
- if (post->buffer == NULL) {
- post->buffer = (*cinfo->mem->access_virt_sarray)
- ((j_common_ptr) cinfo, post->whole_image,
- (JDIMENSION) 0, post->strip_height, TRUE);
- }
- } else {
- /* For single-pass processing without color quantization,
- * I have no work to do; just call the upsampler directly.
- */
- post->pub.post_process_data = cinfo->upsample->upsample;
- }
- break;
- #ifdef QUANT_2PASS_SUPPORTED
- case JBUF_SAVE_AND_PASS:
- /* First pass of 2-pass quantization */
- if (post->whole_image == NULL)
- ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
- post->pub.post_process_data = post_process_prepass;
- break;
- case JBUF_CRANK_DEST:
- /* Second pass of 2-pass quantization */
- if (post->whole_image == NULL)
- ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
- post->pub.post_process_data = post_process_2pass;
- break;
- #endif /* QUANT_2PASS_SUPPORTED */
- default:
- ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
- break;
- }
- post->starting_row = post->next_row = 0;
- }
-
- /*
- * Process some data in the one-pass (strip buffer) case.
- * This is used for color precision reduction as well as one-pass quantization.
- */
-
- METHODDEF(void)
- post_process_1pass (j_decompress_ptr cinfo,
- JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
- JDIMENSION in_row_groups_avail,
- JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
- JDIMENSION out_rows_avail)
- {
- my_post_ptr post = (my_post_ptr) cinfo->post;
- JDIMENSION num_rows, max_rows;
-
- /* Fill the buffer, but not more than what we can dump out in one go. */
- /* Note we rely on the upsampler to detect bottom of image. */
- max_rows = out_rows_avail - *out_row_ctr;
- if (max_rows > post->strip_height)
- max_rows = post->strip_height;
- num_rows = 0;
- (*cinfo->upsample->upsample) (cinfo,
- input_buf, in_row_group_ctr, in_row_groups_avail,
- post->buffer, &num_rows, max_rows);
- /* Quantize and emit data. */
- (*cinfo->cquantize->color_quantize) (cinfo,
- post->buffer, output_buf + *out_row_ctr, (int) num_rows);
- *out_row_ctr += num_rows;
- }
-
- #ifdef QUANT_2PASS_SUPPORTED
-
- /*
- * Process some data in the first pass of 2-pass quantization.
- */
-
- METHODDEF(void)
- post_process_prepass (j_decompress_ptr cinfo,
- JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
- JDIMENSION in_row_groups_avail,
- JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
- JDIMENSION out_rows_avail)
- {
- my_post_ptr post = (my_post_ptr) cinfo->post;
- JDIMENSION old_next_row, num_rows;
-
- /* Reposition virtual buffer if at start of strip. */
- if (post->next_row == 0) {
- post->buffer = (*cinfo->mem->access_virt_sarray)
- ((j_common_ptr) cinfo, post->whole_image,
- post->starting_row, post->strip_height, TRUE);
- }
-
- /* Upsample some data (up to a strip height's worth). */
- old_next_row = post->next_row;
- (*cinfo->upsample->upsample) (cinfo,
- input_buf, in_row_group_ctr, in_row_groups_avail,
- post->buffer, &post->next_row, post->strip_height);
-
- /* Allow quantizer to scan new data. No data is emitted, */
- /* but we advance out_row_ctr so outer loop can tell when we're done. */
- if (post->next_row > old_next_row) {
- num_rows = post->next_row - old_next_row;
- (*cinfo->cquantize->color_quantize) (cinfo, post->buffer + old_next_row,
- (JSAMPARRAY) NULL, (int) num_rows);
- *out_row_ctr += num_rows;
- }
-
- /* Advance if we filled the strip. */
- if (post->next_row >= post->strip_height) {
- post->starting_row += post->strip_height;
- post->next_row = 0;
- }
- }
-
- /*
- * Process some data in the second pass of 2-pass quantization.
- */
-
- METHODDEF(void)
- post_process_2pass (j_decompress_ptr cinfo,
- JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
- JDIMENSION in_row_groups_avail,
- JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
- JDIMENSION out_rows_avail)
- {
- my_post_ptr post = (my_post_ptr) cinfo->post;
- JDIMENSION num_rows, max_rows;
-
- /* Reposition virtual buffer if at start of strip. */
- if (post->next_row == 0) {
- post->buffer = (*cinfo->mem->access_virt_sarray)
- ((j_common_ptr) cinfo, post->whole_image,
- post->starting_row, post->strip_height, FALSE);
- }
-
- /* Determine number of rows to emit. */
- num_rows = post->strip_height - post->next_row; /* available in strip */
- max_rows = out_rows_avail - *out_row_ctr; /* available in output area */
- if (num_rows > max_rows)
- num_rows = max_rows;
- /* We have to check bottom of image here, can't depend on upsampler. */
- max_rows = cinfo->output_height - post->starting_row;
- if (num_rows > max_rows)
- num_rows = max_rows;
-
- /* Quantize and emit data. */
- (*cinfo->cquantize->color_quantize) (cinfo,
- post->buffer + post->next_row, output_buf + *out_row_ctr,
- (int) num_rows);
- *out_row_ctr += num_rows;
-
- /* Advance if we filled the strip. */
- post->next_row += num_rows;
- if (post->next_row >= post->strip_height) {
- post->starting_row += post->strip_height;
- post->next_row = 0;
- }
- }
-
- #endif /* QUANT_2PASS_SUPPORTED */
-
- /*
- * Initialize postprocessing controller.
- */
-
- GLOBAL(void)
- jinit_d_post_controller (j_decompress_ptr cinfo, boolean need_full_buffer)
- {
- my_post_ptr post;
-
- post = (my_post_ptr)
- (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
- SIZEOF(my_post_controller));
- cinfo->post = (struct jpeg_d_post_controller *) post;
- post->pub.start_pass = start_pass_dpost;
- post->whole_image = NULL; /* flag for no virtual arrays */
- post->buffer = NULL; /* flag for no strip buffer */
-
- /* Create the quantization buffer, if needed */
- if (cinfo->quantize_colors) {
- /* The buffer strip height is max_v_samp_factor, which is typically
- * an efficient number of rows for upsampling to return.
- * (In the presence of output rescaling, we might want to be smarter?)
- */
- post->strip_height = (JDIMENSION) cinfo->max_v_samp_factor;
- if (need_full_buffer) {
- /* Two-pass color quantization: need full-image storage. */
- /* We round up the number of rows to a multiple of the strip height. */
- #ifdef QUANT_2PASS_SUPPORTED
- post->whole_image = (*cinfo->mem->request_virt_sarray)
- ((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE,
- cinfo->output_width * cinfo->out_color_components,
- (JDIMENSION) jround_up((long) cinfo->output_height,
- (long) post->strip_height),
- post->strip_height);
- #else
- ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
- #endif /* QUANT_2PASS_SUPPORTED */
- } else {
- /* One-pass color quantization: just make a strip buffer. */
- post->buffer = (*cinfo->mem->alloc_sarray)
- ((j_common_ptr) cinfo, JPOOL_IMAGE,
- cinfo->output_width * cinfo->out_color_components,
- post->strip_height);
- }
- }
- }
- /********* End of inlined file: jdpostct.c *********/
-
- #undef FIX
-
- /********* Start of inlined file: jdsample.c *********/
- #define JPEG_INTERNALS
-
- /* Pointer to routine to upsample a single component */
- typedef JMETHOD(void, upsample1_ptr,
- (j_decompress_ptr cinfo, jpeg_component_info * compptr,
- JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr));
-
- /* Private subobject */
-
- typedef struct {
- struct jpeg_upsampler pub; /* public fields */
-
- /* Color conversion buffer. When using separate upsampling and color
- * conversion steps, this buffer holds one upsampled row group until it
- * has been color converted and output.
- * Note: we do not allocate any storage for component(s) which are full-size,
- * ie do not need rescaling. The corresponding entry of color_buf[] is
- * simply set to point to the input data array, thereby avoiding copying.
- */
- JSAMPARRAY color_buf[MAX_COMPONENTS];
-
- /* Per-component upsampling method pointers */
- upsample1_ptr methods[MAX_COMPONENTS];
-
- int next_row_out; /* counts rows emitted from color_buf */
- JDIMENSION rows_to_go; /* counts rows remaining in image */
-
- /* Height of an input row group for each component. */
- int rowgroup_height[MAX_COMPONENTS];
-
- /* These arrays save pixel expansion factors so that int_expand need not
- * recompute them each time. They are unused for other upsampling methods.
- */
- UINT8 h_expand[MAX_COMPONENTS];
- UINT8 v_expand[MAX_COMPONENTS];
- } my_upsampler2;
-
- typedef my_upsampler2 * my_upsample_ptr2;
-
- /*
- * Initialize for an upsampling pass.
- */
-
- METHODDEF(void)
- start_pass_upsample (j_decompress_ptr cinfo)
- {
- my_upsample_ptr2 upsample = (my_upsample_ptr2) cinfo->upsample;
-
- /* Mark the conversion buffer empty */
- upsample->next_row_out = cinfo->max_v_samp_factor;
- /* Initialize total-height counter for detecting bottom of image */
- upsample->rows_to_go = cinfo->output_height;
- }
-
- /*
- * Control routine to do upsampling (and color conversion).
- *
- * In this version we upsample each component independently.
- * We upsample one row group into the conversion buffer, then apply
- * color conversion a row at a time.
- */
-
- METHODDEF(void)
- sep_upsample (j_decompress_ptr cinfo,
- JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
- JDIMENSION in_row_groups_avail,
- JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
- JDIMENSION out_rows_avail)
- {
- my_upsample_ptr2 upsample = (my_upsample_ptr2) cinfo->upsample;
- int ci;
- jpeg_component_info * compptr;
- JDIMENSION num_rows;
-
- /* Fill the conversion buffer, if it's empty */
- if (upsample->next_row_out >= cinfo->max_v_samp_factor) {
- for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
- ci++, compptr++) {
- /* Invoke per-component upsample method. Notice we pass a POINTER
- * to color_buf[ci], so that fullsize_upsample can change it.
- */
- (*upsample->methods[ci]) (cinfo, compptr,
- input_buf[ci] + (*in_row_group_ctr * upsample->rowgroup_height[ci]),
- upsample->color_buf + ci);
- }
- upsample->next_row_out = 0;
- }
-
- /* Color-convert and emit rows */
-
- /* How many we have in the buffer: */
- num_rows = (JDIMENSION) (cinfo->max_v_samp_factor - upsample->next_row_out);
- /* Not more than the distance to the end of the image. Need this test
- * in case the image height is not a multiple of max_v_samp_factor:
- */
- if (num_rows > upsample->rows_to_go)
- num_rows = upsample->rows_to_go;
- /* And not more than what the client can accept: */
- out_rows_avail -= *out_row_ctr;
- if (num_rows > out_rows_avail)
- num_rows = out_rows_avail;
-
- (*cinfo->cconvert->color_convert) (cinfo, upsample->color_buf,
- (JDIMENSION) upsample->next_row_out,
- output_buf + *out_row_ctr,
- (int) num_rows);
-
- /* Adjust counts */
- *out_row_ctr += num_rows;
- upsample->rows_to_go -= num_rows;
- upsample->next_row_out += num_rows;
- /* When the buffer is emptied, declare this input row group consumed */
- if (upsample->next_row_out >= cinfo->max_v_samp_factor)
- (*in_row_group_ctr)++;
- }
-
- /*
- * These are the routines invoked by sep_upsample to upsample pixel values
- * of a single component. One row group is processed per call.
- */
-
- /*
- * For full-size components, we just make color_buf[ci] point at the
- * input buffer, and thus avoid copying any data. Note that this is
- * safe only because sep_upsample doesn't declare the input row group
- * "consumed" until we are done color converting and emitting it.
- */
-
- METHODDEF(void)
- fullsize_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
- JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
- {
- *output_data_ptr = input_data;
- }
-
- /*
- * This is a no-op version used for "uninteresting" components.
- * These components will not be referenced by color conversion.
- */
-
- METHODDEF(void)
- noop_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
- JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
- {
- *output_data_ptr = NULL; /* safety check */
- }
-
- /*
- * This version handles any integral sampling ratios.
- * This is not used for typical JPEG files, so it need not be fast.
- * Nor, for that matter, is it particularly accurate: the algorithm is
- * simple replication of the input pixel onto the corresponding output
- * pixels. The hi-falutin sampling literature refers to this as a
- * "box filter". A box filter tends to introduce visible artifacts,
- * so if you are actually going to use 3:1 or 4:1 sampling ratios
- * you would be well advised to improve this code.
- */
-
- METHODDEF(void)
- int_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
- JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
- {
- my_upsample_ptr2 upsample = (my_upsample_ptr2) cinfo->upsample;
- JSAMPARRAY output_data = *output_data_ptr;
- register JSAMPROW inptr, outptr;
- register JSAMPLE invalue;
- register int h;
- JSAMPROW outend;
- int h_expand, v_expand;
- int inrow, outrow;
-
- h_expand = upsample->h_expand[compptr->component_index];
- v_expand = upsample->v_expand[compptr->component_index];
-
- inrow = outrow = 0;
- while (outrow < cinfo->max_v_samp_factor) {
- /* Generate one output row with proper horizontal expansion */
- inptr = input_data[inrow];
- outptr = output_data[outrow];
- outend = outptr + cinfo->output_width;
- while (outptr < outend) {
- invalue = *inptr++; /* don't need GETJSAMPLE() here */
- for (h = h_expand; h > 0; h--) {
- *outptr++ = invalue;
- }
- }
- /* Generate any additional output rows by duplicating the first one */
- if (v_expand > 1) {
- jcopy_sample_rows(output_data, outrow, output_data, outrow+1,
- v_expand-1, cinfo->output_width);
- }
- inrow++;
- outrow += v_expand;
- }
- }
-
- /*
- * Fast processing for the common case of 2:1 horizontal and 1:1 vertical.
- * It's still a box filter.
- */
-
- METHODDEF(void)
- h2v1_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
- JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
- {
- JSAMPARRAY output_data = *output_data_ptr;
- register JSAMPROW inptr, outptr;
- register JSAMPLE invalue;
- JSAMPROW outend;
- int inrow;
-
- for (inrow = 0; inrow < cinfo->max_v_samp_factor; inrow++) {
- inptr = input_data[inrow];
- outptr = output_data[inrow];
- outend = outptr + cinfo->output_width;
- while (outptr < outend) {
- invalue = *inptr++; /* don't need GETJSAMPLE() here */
- *outptr++ = invalue;
- *outptr++ = invalue;
- }
- }
- }
-
- /*
- * Fast processing for the common case of 2:1 horizontal and 2:1 vertical.
- * It's still a box filter.
- */
-
- METHODDEF(void)
- h2v2_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
- JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
- {
- JSAMPARRAY output_data = *output_data_ptr;
- register JSAMPROW inptr, outptr;
- register JSAMPLE invalue;
- JSAMPROW outend;
- int inrow, outrow;
-
- inrow = outrow = 0;
- while (outrow < cinfo->max_v_samp_factor) {
- inptr = input_data[inrow];
- outptr = output_data[outrow];
- outend = outptr + cinfo->output_width;
- while (outptr < outend) {
- invalue = *inptr++; /* don't need GETJSAMPLE() here */
- *outptr++ = invalue;
- *outptr++ = invalue;
- }
- jcopy_sample_rows(output_data, outrow, output_data, outrow+1,
- 1, cinfo->output_width);
- inrow++;
- outrow += 2;
- }
- }
-
- /*
- * Fancy processing for the common case of 2:1 horizontal and 1:1 vertical.
- *
- * The upsampling algorithm is linear interpolation between pixel centers,
- * also known as a "triangle filter". This is a good compromise between
- * speed and visual quality. The centers of the output pixels are 1/4 and 3/4
- * of the way between input pixel centers.
- *
- * A note about the "bias" calculations: when rounding fractional values to
- * integer, we do not want to always round 0.5 up to the next integer.
- * If we did that, we'd introduce a noticeable bias towards larger values.
- * Instead, this code is arranged so that 0.5 will be rounded up or down at
- * alternate pixel locations (a simple ordered dither pattern).
- */
-
- METHODDEF(void)
- h2v1_fancy_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
- JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
- {
- JSAMPARRAY output_data = *output_data_ptr;
- register JSAMPROW inptr, outptr;
- register int invalue;
- register JDIMENSION colctr;
- int inrow;
-
- for (inrow = 0; inrow < cinfo->max_v_samp_factor; inrow++) {
- inptr = input_data[inrow];
- outptr = output_data[inrow];
- /* Special case for first column */
- invalue = GETJSAMPLE(*inptr++);
- *outptr++ = (JSAMPLE) invalue;
- *outptr++ = (JSAMPLE) ((invalue * 3 + GETJSAMPLE(*inptr) + 2) >> 2);
-
- for (colctr = compptr->downsampled_width - 2; colctr > 0; colctr--) {
- /* General case: 3/4 * nearer pixel + 1/4 * further pixel */
- invalue = GETJSAMPLE(*inptr++) * 3;
- *outptr++ = (JSAMPLE) ((invalue + GETJSAMPLE(inptr[-2]) + 1) >> 2);
- *outptr++ = (JSAMPLE) ((invalue + GETJSAMPLE(*inptr) + 2) >> 2);
- }
-
- /* Special case for last column */
- invalue = GETJSAMPLE(*inptr);
- *outptr++ = (JSAMPLE) ((invalue * 3 + GETJSAMPLE(inptr[-1]) + 1) >> 2);
- *outptr++ = (JSAMPLE) invalue;
- }
- }
-
- /*
- * Fancy processing for the common case of 2:1 horizontal and 2:1 vertical.
- * Again a triangle filter; see comments for h2v1 case, above.
- *
- * It is OK for us to reference the adjacent input rows because we demanded
- * context from the main buffer controller (see initialization code).
- */
-
- METHODDEF(void)
- h2v2_fancy_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
- JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
- {
- JSAMPARRAY output_data = *output_data_ptr;
- register JSAMPROW inptr0, inptr1, outptr;
- #if BITS_IN_JSAMPLE == 8
- register int thiscolsum, lastcolsum, nextcolsum;
- #else
- register INT32 thiscolsum, lastcolsum, nextcolsum;
- #endif
- register JDIMENSION colctr;
- int inrow, outrow, v;
-
- inrow = outrow = 0;
- while (outrow < cinfo->max_v_samp_factor) {
- for (v = 0; v < 2; v++) {
- /* inptr0 points to nearest input row, inptr1 points to next nearest */
- inptr0 = input_data[inrow];
- if (v == 0) /* next nearest is row above */
- inptr1 = input_data[inrow-1];
- else /* next nearest is row below */
- inptr1 = input_data[inrow+1];
- outptr = output_data[outrow++];
-
- /* Special case for first column */
- thiscolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++);
- nextcolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++);
- *outptr++ = (JSAMPLE) ((thiscolsum * 4 + 8) >> 4);
- *outptr++ = (JSAMPLE) ((thiscolsum * 3 + nextcolsum + 7) >> 4);
- lastcolsum = thiscolsum; thiscolsum = nextcolsum;
-
- for (colctr = compptr->downsampled_width - 2; colctr > 0; colctr--) {
- /* General case: 3/4 * nearer pixel + 1/4 * further pixel in each */
- /* dimension, thus 9/16, 3/16, 3/16, 1/16 overall */
- nextcolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++);
- *outptr++ = (JSAMPLE) ((thiscolsum * 3 + lastcolsum + 8) >> 4);
- *outptr++ = (JSAMPLE) ((thiscolsum * 3 + nextcolsum + 7) >> 4);
- lastcolsum = thiscolsum; thiscolsum = nextcolsum;
- }
-
- /* Special case for last column */
- *outptr++ = (JSAMPLE) ((thiscolsum * 3 + lastcolsum + 8) >> 4);
- *outptr++ = (JSAMPLE) ((thiscolsum * 4 + 7) >> 4);
- }
- inrow++;
- }
- }
-
- /*
- * Module initialization routine for upsampling.
- */
-
- GLOBAL(void)
- jinit_upsampler (j_decompress_ptr cinfo)
- {
- my_upsample_ptr2 upsample;
- int ci;
- jpeg_component_info * compptr;
- boolean need_buffer, do_fancy;
- int h_in_group, v_in_group, h_out_group, v_out_group;
-
- upsample = (my_upsample_ptr2)
- (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
- SIZEOF(my_upsampler2));
- cinfo->upsample = (struct jpeg_upsampler *) upsample;
- upsample->pub.start_pass = start_pass_upsample;
- upsample->pub.upsample = sep_upsample;
- upsample->pub.need_context_rows = FALSE; /* until we find out differently */
-
- if (cinfo->CCIR601_sampling) /* this isn't supported */
- ERREXIT(cinfo, JERR_CCIR601_NOTIMPL);
-
- /* jdmainct.c doesn't support context rows when min_DCT_scaled_size = 1,
- * so don't ask for it.
- */
- do_fancy = cinfo->do_fancy_upsampling && cinfo->min_DCT_scaled_size > 1;
-
- /* Verify we can handle the sampling factors, select per-component methods,
- * and create storage as needed.
- */
- for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
- ci++, compptr++) {
- /* Compute size of an "input group" after IDCT scaling. This many samples
- * are to be converted to max_h_samp_factor * max_v_samp_factor pixels.
- */
- h_in_group = (compptr->h_samp_factor * compptr->DCT_scaled_size) /
- cinfo->min_DCT_scaled_size;
- v_in_group = (compptr->v_samp_factor * compptr->DCT_scaled_size) /
- cinfo->min_DCT_scaled_size;
- h_out_group = cinfo->max_h_samp_factor;
- v_out_group = cinfo->max_v_samp_factor;
- upsample->rowgroup_height[ci] = v_in_group; /* save for use later */
- need_buffer = TRUE;
- if (! compptr->component_needed) {
- /* Don't bother to upsample an uninteresting component. */
- upsample->methods[ci] = noop_upsample;
- need_buffer = FALSE;
- } else if (h_in_group == h_out_group && v_in_group == v_out_group) {
- /* Fullsize components can be processed without any work. */
- upsample->methods[ci] = fullsize_upsample;
- need_buffer = FALSE;
- } else if (h_in_group * 2 == h_out_group &&
- v_in_group == v_out_group) {
- /* Special cases for 2h1v upsampling */
- if (do_fancy && compptr->downsampled_width > 2)
- upsample->methods[ci] = h2v1_fancy_upsample;
- else
- upsample->methods[ci] = h2v1_upsample;
- } else if (h_in_group * 2 == h_out_group &&
- v_in_group * 2 == v_out_group) {
- /* Special cases for 2h2v upsampling */
- if (do_fancy && compptr->downsampled_width > 2) {
- upsample->methods[ci] = h2v2_fancy_upsample;
- upsample->pub.need_context_rows = TRUE;
- } else
- upsample->methods[ci] = h2v2_upsample;
- } else if ((h_out_group % h_in_group) == 0 &&
- (v_out_group % v_in_group) == 0) {
- /* Generic integral-factors upsampling method */
- upsample->methods[ci] = int_upsample;
- upsample->h_expand[ci] = (UINT8) (h_out_group / h_in_group);
- upsample->v_expand[ci] = (UINT8) (v_out_group / v_in_group);
- } else
- ERREXIT(cinfo, JERR_FRACT_SAMPLE_NOTIMPL);
- if (need_buffer) {
- upsample->color_buf[ci] = (*cinfo->mem->alloc_sarray)
- ((j_common_ptr) cinfo, JPOOL_IMAGE,
- (JDIMENSION) jround_up((long) cinfo->output_width,
- (long) cinfo->max_h_samp_factor),
- (JDIMENSION) cinfo->max_v_samp_factor);
- }
- }
- }
- /********* End of inlined file: jdsample.c *********/
-
- /********* Start of inlined file: jdtrans.c *********/
- #define JPEG_INTERNALS
-
- /* Forward declarations */
- LOCAL(void) transdecode_master_selection JPP((j_decompress_ptr cinfo));
-
- /*
- * Read the coefficient arrays from a JPEG file.
- * jpeg_read_header must be completed before calling this.
- *
- * The entire image is read into a set of virtual coefficient-block arrays,
- * one per component. The return value is a pointer to the array of
- * virtual-array descriptors. These can be manipulated directly via the
- * JPEG memory manager, or handed off to jpeg_write_coefficients().
- * To release the memory occupied by the virtual arrays, call
- * jpeg_finish_decompress() when done with the data.
- *
- * An alternative usage is to simply obtain access to the coefficient arrays
- * during a buffered-image-mode decompression operation. This is allowed
- * after any jpeg_finish_output() call. The arrays can be accessed until
- * jpeg_finish_decompress() is called. (Note that any call to the library
- * may reposition the arrays, so don't rely on access_virt_barray() results
- * to stay valid across library calls.)
- *
- * Returns NULL if suspended. This case need be checked only if
- * a suspending data source is used.
- */
-
- GLOBAL(jvirt_barray_ptr *)
- jpeg_read_coefficients (j_decompress_ptr cinfo)
- {
- if (cinfo->global_state == DSTATE_READY) {
- /* First call: initialize active modules */
- transdecode_master_selection(cinfo);
- cinfo->global_state = DSTATE_RDCOEFS;
- }
- if (cinfo->global_state == DSTATE_RDCOEFS) {
- /* Absorb whole file into the coef buffer */
- for (;;) {
- int retcode;
- /* Call progress monitor hook if present */
- if (cinfo->progress != NULL)
- (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
- /* Absorb some more input */
- retcode = (*cinfo->inputctl->consume_input) (cinfo);
- if (retcode == JPEG_SUSPENDED)
- return NULL;
- if (retcode == JPEG_REACHED_EOI)
- break;
- /* Advance progress counter if appropriate */
- if (cinfo->progress != NULL &&
- (retcode == JPEG_ROW_COMPLETED || retcode == JPEG_REACHED_SOS)) {
- if (++cinfo->progress->pass_counter >= cinfo->progress->pass_limit) {
- /* startup underestimated number of scans; ratchet up one scan */
- cinfo->progress->pass_limit += (long) cinfo->total_iMCU_rows;
- }
- }
- }
- /* Set state so that jpeg_finish_decompress does the right thing */
- cinfo->global_state = DSTATE_STOPPING;
- }
- /* At this point we should be in state DSTATE_STOPPING if being used
- * standalone, or in state DSTATE_BUFIMAGE if being invoked to get access
- * to the coefficients during a full buffered-image-mode decompression.
- */
- if ((cinfo->global_state == DSTATE_STOPPING ||
- cinfo->global_state == DSTATE_BUFIMAGE) && cinfo->buffered_image) {
- return cinfo->coef->coef_arrays;
- }
- /* Oops, improper usage */
- ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
- return NULL; /* keep compiler happy */
- }
-
- /*
- * Master selection of decompression modules for transcoding.
- * This substitutes for jdmaster.c's initialization of the full decompressor.
- */
-
- LOCAL(void)
- transdecode_master_selection (j_decompress_ptr cinfo)
- {
- /* This is effectively a buffered-image operation. */
- cinfo->buffered_image = TRUE;
-
- /* Entropy decoding: either Huffman or arithmetic coding. */
- if (cinfo->arith_code) {
- ERREXIT(cinfo, JERR_ARITH_NOTIMPL);
- } else {
- if (cinfo->progressive_mode) {
- #ifdef D_PROGRESSIVE_SUPPORTED
- jinit_phuff_decoder(cinfo);
- #else
- ERREXIT(cinfo, JERR_NOT_COMPILED);
- #endif
- } else
- jinit_huff_decoder(cinfo);
- }
-
- /* Always get a full-image coefficient buffer. */
- jinit_d_coef_controller(cinfo, TRUE);
-
- /* We can now tell the memory manager to allocate virtual arrays. */
- (*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo);
-
- /* Initialize input side of decompressor to consume first scan. */
- (*cinfo->inputctl->start_input_pass) (cinfo);
-
- /* Initialize progress monitoring. */
- if (cinfo->progress != NULL) {
- int nscans;
- /* Estimate number of scans to set pass_limit. */
- if (cinfo->progressive_mode) {
- /* Arbitrarily estimate 2 interleaved DC scans + 3 AC scans/component. */
- nscans = 2 + 3 * cinfo->num_components;
- } else if (cinfo->inputctl->has_multiple_scans) {
- /* For a nonprogressive multiscan file, estimate 1 scan per component. */
- nscans = cinfo->num_components;
- } else {
- nscans = 1;
- }
- cinfo->progress->pass_counter = 0L;
- cinfo->progress->pass_limit = (long) cinfo->total_iMCU_rows * nscans;
- cinfo->progress->completed_passes = 0;
- cinfo->progress->total_passes = 1;
- }
- }
- /********* End of inlined file: jdtrans.c *********/
-
- /********* Start of inlined file: jfdctflt.c *********/
- #define JPEG_INTERNALS
-
- #ifdef DCT_FLOAT_SUPPORTED
-
- /*
- * This module is specialized to the case DCTSIZE = 8.
- */
-
- #if DCTSIZE != 8
- Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */
- #endif
-
- /*
- * Perform the forward DCT on one block of samples.
- */
-
- GLOBAL(void)
- jpeg_fdct_float (FAST_FLOAT * data)
- {
- FAST_FLOAT tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
- FAST_FLOAT tmp10, tmp11, tmp12, tmp13;
- FAST_FLOAT z1, z2, z3, z4, z5, z11, z13;
- FAST_FLOAT *dataptr;
- int ctr;
-
- /* Pass 1: process rows. */
-
- dataptr = data;
- for (ctr = DCTSIZE-1; ctr >= 0; ctr--) {
- tmp0 = dataptr[0] + dataptr[7];
- tmp7 = dataptr[0] - dataptr[7];
- tmp1 = dataptr[1] + dataptr[6];
- tmp6 = dataptr[1] - dataptr[6];
- tmp2 = dataptr[2] + dataptr[5];
- tmp5 = dataptr[2] - dataptr[5];
- tmp3 = dataptr[3] + dataptr[4];
- tmp4 = dataptr[3] - dataptr[4];
-
- /* Even part */
-
- tmp10 = tmp0 + tmp3; /* phase 2 */
- tmp13 = tmp0 - tmp3;
- tmp11 = tmp1 + tmp2;
- tmp12 = tmp1 - tmp2;
-
- dataptr[0] = tmp10 + tmp11; /* phase 3 */
- dataptr[4] = tmp10 - tmp11;
-
- z1 = (tmp12 + tmp13) * ((FAST_FLOAT) 0.707106781); /* c4 */
- dataptr[2] = tmp13 + z1; /* phase 5 */
- dataptr[6] = tmp13 - z1;
-
- /* Odd part */
-
- tmp10 = tmp4 + tmp5; /* phase 2 */
- tmp11 = tmp5 + tmp6;
- tmp12 = tmp6 + tmp7;
-
- /* The rotator is modified from fig 4-8 to avoid extra negations. */
- z5 = (tmp10 - tmp12) * ((FAST_FLOAT) 0.382683433); /* c6 */
- z2 = ((FAST_FLOAT) 0.541196100) * tmp10 + z5; /* c2-c6 */
- z4 = ((FAST_FLOAT) 1.306562965) * tmp12 + z5; /* c2+c6 */
- z3 = tmp11 * ((FAST_FLOAT) 0.707106781); /* c4 */
-
- z11 = tmp7 + z3; /* phase 5 */
- z13 = tmp7 - z3;
-
- dataptr[5] = z13 + z2; /* phase 6 */
- dataptr[3] = z13 - z2;
- dataptr[1] = z11 + z4;
- dataptr[7] = z11 - z4;
-
- dataptr += DCTSIZE; /* advance pointer to next row */
- }
-
- /* Pass 2: process columns. */
-
- dataptr = data;
- for (ctr = DCTSIZE-1; ctr >= 0; ctr--) {
- tmp0 = dataptr[DCTSIZE*0] + dataptr[DCTSIZE*7];
- tmp7 = dataptr[DCTSIZE*0] - dataptr[DCTSIZE*7];
- tmp1 = dataptr[DCTSIZE*1] + dataptr[DCTSIZE*6];
- tmp6 = dataptr[DCTSIZE*1] - dataptr[DCTSIZE*6];
- tmp2 = dataptr[DCTSIZE*2] + dataptr[DCTSIZE*5];
- tmp5 = dataptr[DCTSIZE*2] - dataptr[DCTSIZE*5];
- tmp3 = dataptr[DCTSIZE*3] + dataptr[DCTSIZE*4];
- tmp4 = dataptr[DCTSIZE*3] - dataptr[DCTSIZE*4];
-
- /* Even part */
-
- tmp10 = tmp0 + tmp3; /* phase 2 */
- tmp13 = tmp0 - tmp3;
- tmp11 = tmp1 + tmp2;
- tmp12 = tmp1 - tmp2;
-
- dataptr[DCTSIZE*0] = tmp10 + tmp11; /* phase 3 */
- dataptr[DCTSIZE*4] = tmp10 - tmp11;
-
- z1 = (tmp12 + tmp13) * ((FAST_FLOAT) 0.707106781); /* c4 */
- dataptr[DCTSIZE*2] = tmp13 + z1; /* phase 5 */
- dataptr[DCTSIZE*6] = tmp13 - z1;
-
- /* Odd part */
-
- tmp10 = tmp4 + tmp5; /* phase 2 */
- tmp11 = tmp5 + tmp6;
- tmp12 = tmp6 + tmp7;
-
- /* The rotator is modified from fig 4-8 to avoid extra negations. */
- z5 = (tmp10 - tmp12) * ((FAST_FLOAT) 0.382683433); /* c6 */
- z2 = ((FAST_FLOAT) 0.541196100) * tmp10 + z5; /* c2-c6 */
- z4 = ((FAST_FLOAT) 1.306562965) * tmp12 + z5; /* c2+c6 */
- z3 = tmp11 * ((FAST_FLOAT) 0.707106781); /* c4 */
-
- z11 = tmp7 + z3; /* phase 5 */
- z13 = tmp7 - z3;
-
- dataptr[DCTSIZE*5] = z13 + z2; /* phase 6 */
- dataptr[DCTSIZE*3] = z13 - z2;
- dataptr[DCTSIZE*1] = z11 + z4;
- dataptr[DCTSIZE*7] = z11 - z4;
-
- dataptr++; /* advance pointer to next column */
- }
- }
-
- #endif /* DCT_FLOAT_SUPPORTED */
- /********* End of inlined file: jfdctflt.c *********/
-
- /********* Start of inlined file: jfdctint.c *********/
- #define JPEG_INTERNALS
-
- #ifdef DCT_ISLOW_SUPPORTED
-
- /*
- * This module is specialized to the case DCTSIZE = 8.
- */
-
- #if DCTSIZE != 8
- Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */
- #endif
-
- /*
- * The poop on this scaling stuff is as follows:
- *
- * Each 1-D DCT step produces outputs which are a factor of sqrt(N)
- * larger than the true DCT outputs. The final outputs are therefore
- * a factor of N larger than desired; since N=8 this can be cured by
- * a simple right shift at the end of the algorithm. The advantage of
- * this arrangement is that we save two multiplications per 1-D DCT,
- * because the y0 and y4 outputs need not be divided by sqrt(N).
- * In the IJG code, this factor of 8 is removed by the quantization step
- * (in jcdctmgr.c), NOT in this module.
- *
- * We have to do addition and subtraction of the integer inputs, which
- * is no problem, and multiplication by fractional constants, which is
- * a problem to do in integer arithmetic. We multiply all the constants
- * by CONST_SCALE and convert them to integer constants (thus retaining
- * CONST_BITS bits of precision in the constants). After doing a
- * multiplication we have to divide the product by CONST_SCALE, with proper
- * rounding, to produce the correct output. This division can be done
- * cheaply as a right shift of CONST_BITS bits. We postpone shifting
- * as long as possible so that partial sums can be added together with
- * full fractional precision.
- *
- * The outputs of the first pass are scaled up by PASS1_BITS bits so that
- * they are represented to better-than-integral precision. These outputs
- * require BITS_IN_JSAMPLE + PASS1_BITS + 3 bits; this fits in a 16-bit word
- * with the recommended scaling. (For 12-bit sample data, the intermediate
- * array is INT32 anyway.)
- *
- * To avoid overflow of the 32-bit intermediate results in pass 2, we must
- * have BITS_IN_JSAMPLE + CONST_BITS + PASS1_BITS <= 26. Error analysis
- * shows that the values given below are the most effective.
- */
-
- #if BITS_IN_JSAMPLE == 8
- #define CONST_BITS 13
- #define PASS1_BITS 2
- #else
- #define CONST_BITS 13
- #define PASS1_BITS 1 /* lose a little precision to avoid overflow */
- #endif
-
- /* Some C compilers fail to reduce "FIX(constant)" at compile time, thus
- * causing a lot of useless floating-point operations at run time.
- * To get around this we use the following pre-calculated constants.
- * If you change CONST_BITS you may want to add appropriate values.
- * (With a reasonable C compiler, you can just rely on the FIX() macro...)
- */
-
- #if CONST_BITS == 13
- #define FIX_0_298631336 ((INT32) 2446) /* FIX(0.298631336) */
- #define FIX_0_390180644 ((INT32) 3196) /* FIX(0.390180644) */
- #define FIX_0_541196100 ((INT32) 4433) /* FIX(0.541196100) */
- #define FIX_0_765366865 ((INT32) 6270) /* FIX(0.765366865) */
- #define FIX_0_899976223 ((INT32) 7373) /* FIX(0.899976223) */
- #define FIX_1_175875602 ((INT32) 9633) /* FIX(1.175875602) */
- #define FIX_1_501321110 ((INT32) 12299) /* FIX(1.501321110) */
- #define FIX_1_847759065 ((INT32) 15137) /* FIX(1.847759065) */
- #define FIX_1_961570560 ((INT32) 16069) /* FIX(1.961570560) */
- #define FIX_2_053119869 ((INT32) 16819) /* FIX(2.053119869) */
- #define FIX_2_562915447 ((INT32) 20995) /* FIX(2.562915447) */
- #define FIX_3_072711026 ((INT32) 25172) /* FIX(3.072711026) */
- #else
- #define FIX_0_298631336 FIX(0.298631336)
- #define FIX_0_390180644 FIX(0.390180644)
- #define FIX_0_541196100 FIX(0.541196100)
- #define FIX_0_765366865 FIX(0.765366865)
- #define FIX_0_899976223 FIX(0.899976223)
- #define FIX_1_175875602 FIX(1.175875602)
- #define FIX_1_501321110 FIX(1.501321110)
- #define FIX_1_847759065 FIX(1.847759065)
- #define FIX_1_961570560 FIX(1.961570560)
- #define FIX_2_053119869 FIX(2.053119869)
- #define FIX_2_562915447 FIX(2.562915447)
- #define FIX_3_072711026 FIX(3.072711026)
- #endif
-
- /* Multiply an INT32 variable by an INT32 constant to yield an INT32 result.
- * For 8-bit samples with the recommended scaling, all the variable
- * and constant values involved are no more than 16 bits wide, so a
- * 16x16->32 bit multiply can be used instead of a full 32x32 multiply.
- * For 12-bit samples, a full 32-bit multiplication will be needed.
- */
-
- #if BITS_IN_JSAMPLE == 8
- #define MULTIPLY(var,const) MULTIPLY16C16(var,const)
- #else
- #define MULTIPLY(var,const) ((var) * (const))
- #endif
-
- /*
- * Perform the forward DCT on one block of samples.
- */
-
- GLOBAL(void)
- jpeg_fdct_islow (DCTELEM * data)
- {
- INT32 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
- INT32 tmp10, tmp11, tmp12, tmp13;
- INT32 z1, z2, z3, z4, z5;
- DCTELEM *dataptr;
- int ctr;
- SHIFT_TEMPS
-
- /* Pass 1: process rows. */
- /* Note results are scaled up by sqrt(8) compared to a true DCT; */
- /* furthermore, we scale the results by 2**PASS1_BITS. */
-
- dataptr = data;
- for (ctr = DCTSIZE-1; ctr >= 0; ctr--) {
- tmp0 = dataptr[0] + dataptr[7];
- tmp7 = dataptr[0] - dataptr[7];
- tmp1 = dataptr[1] + dataptr[6];
- tmp6 = dataptr[1] - dataptr[6];
- tmp2 = dataptr[2] + dataptr[5];
- tmp5 = dataptr[2] - dataptr[5];
- tmp3 = dataptr[3] + dataptr[4];
- tmp4 = dataptr[3] - dataptr[4];
-
- /* Even part per LL&M figure 1 --- note that published figure is faulty;
- * rotator "sqrt(2)*c1" should be "sqrt(2)*c6".
- */
-
- tmp10 = tmp0 + tmp3;
- tmp13 = tmp0 - tmp3;
- tmp11 = tmp1 + tmp2;
- tmp12 = tmp1 - tmp2;
-
- dataptr[0] = (DCTELEM) ((tmp10 + tmp11) << PASS1_BITS);
- dataptr[4] = (DCTELEM) ((tmp10 - tmp11) << PASS1_BITS);
-
- z1 = MULTIPLY(tmp12 + tmp13, FIX_0_541196100);
- dataptr[2] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp13, FIX_0_765366865),
- CONST_BITS-PASS1_BITS);
- dataptr[6] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp12, - FIX_1_847759065),
- CONST_BITS-PASS1_BITS);
-
- /* Odd part per figure 8 --- note paper omits factor of sqrt(2).
- * cK represents cos(K*pi/16).
- * i0..i3 in the paper are tmp4..tmp7 here.
- */
-
- z1 = tmp4 + tmp7;
- z2 = tmp5 + tmp6;
- z3 = tmp4 + tmp6;
- z4 = tmp5 + tmp7;
- z5 = MULTIPLY(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */
-
- tmp4 = MULTIPLY(tmp4, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */
- tmp5 = MULTIPLY(tmp5, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */
- tmp6 = MULTIPLY(tmp6, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */
- tmp7 = MULTIPLY(tmp7, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */
- z1 = MULTIPLY(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */
- z2 = MULTIPLY(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
- z3 = MULTIPLY(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
- z4 = MULTIPLY(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */
-
- z3 += z5;
- z4 += z5;
-
- dataptr[7] = (DCTELEM) DESCALE(tmp4 + z1 + z3, CONST_BITS-PASS1_BITS);
- dataptr[5] = (DCTELEM) DESCALE(tmp5 + z2 + z4, CONST_BITS-PASS1_BITS);
- dataptr[3] = (DCTELEM) DESCALE(tmp6 + z2 + z3, CONST_BITS-PASS1_BITS);
- dataptr[1] = (DCTELEM) DESCALE(tmp7 + z1 + z4, CONST_BITS-PASS1_BITS);
-
- dataptr += DCTSIZE; /* advance pointer to next row */
- }
-
- /* Pass 2: process columns.
- * We remove the PASS1_BITS scaling, but leave the results scaled up
- * by an overall factor of 8.
- */
-
- dataptr = data;
- for (ctr = DCTSIZE-1; ctr >= 0; ctr--) {
- tmp0 = dataptr[DCTSIZE*0] + dataptr[DCTSIZE*7];
- tmp7 = dataptr[DCTSIZE*0] - dataptr[DCTSIZE*7];
- tmp1 = dataptr[DCTSIZE*1] + dataptr[DCTSIZE*6];
- tmp6 = dataptr[DCTSIZE*1] - dataptr[DCTSIZE*6];
- tmp2 = dataptr[DCTSIZE*2] + dataptr[DCTSIZE*5];
- tmp5 = dataptr[DCTSIZE*2] - dataptr[DCTSIZE*5];
- tmp3 = dataptr[DCTSIZE*3] + dataptr[DCTSIZE*4];
- tmp4 = dataptr[DCTSIZE*3] - dataptr[DCTSIZE*4];
-
- /* Even part per LL&M figure 1 --- note that published figure is faulty;
- * rotator "sqrt(2)*c1" should be "sqrt(2)*c6".
- */
-
- tmp10 = tmp0 + tmp3;
- tmp13 = tmp0 - tmp3;
- tmp11 = tmp1 + tmp2;
- tmp12 = tmp1 - tmp2;
-
- dataptr[DCTSIZE*0] = (DCTELEM) DESCALE(tmp10 + tmp11, PASS1_BITS);
- dataptr[DCTSIZE*4] = (DCTELEM) DESCALE(tmp10 - tmp11, PASS1_BITS);
-
- z1 = MULTIPLY(tmp12 + tmp13, FIX_0_541196100);
- dataptr[DCTSIZE*2] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp13, FIX_0_765366865),
- CONST_BITS+PASS1_BITS);
- dataptr[DCTSIZE*6] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp12, - FIX_1_847759065),
- CONST_BITS+PASS1_BITS);
-
- /* Odd part per figure 8 --- note paper omits factor of sqrt(2).
- * cK represents cos(K*pi/16).
- * i0..i3 in the paper are tmp4..tmp7 here.
- */
-
- z1 = tmp4 + tmp7;
- z2 = tmp5 + tmp6;
- z3 = tmp4 + tmp6;
- z4 = tmp5 + tmp7;
- z5 = MULTIPLY(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */
-
- tmp4 = MULTIPLY(tmp4, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */
- tmp5 = MULTIPLY(tmp5, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */
- tmp6 = MULTIPLY(tmp6, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */
- tmp7 = MULTIPLY(tmp7, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */
- z1 = MULTIPLY(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */
- z2 = MULTIPLY(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
- z3 = MULTIPLY(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
- z4 = MULTIPLY(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */
-
- z3 += z5;
- z4 += z5;
-
- dataptr[DCTSIZE*7] = (DCTELEM) DESCALE(tmp4 + z1 + z3,
- CONST_BITS+PASS1_BITS);
- dataptr[DCTSIZE*5] = (DCTELEM) DESCALE(tmp5 + z2 + z4,
- CONST_BITS+PASS1_BITS);
- dataptr[DCTSIZE*3] = (DCTELEM) DESCALE(tmp6 + z2 + z3,
- CONST_BITS+PASS1_BITS);
- dataptr[DCTSIZE*1] = (DCTELEM) DESCALE(tmp7 + z1 + z4,
- CONST_BITS+PASS1_BITS);
-
- dataptr++; /* advance pointer to next column */
- }
- }
-
- #endif /* DCT_ISLOW_SUPPORTED */
- /********* End of inlined file: jfdctint.c *********/
-
- #undef CONST_BITS
- #undef MULTIPLY
- #undef FIX_0_541196100
-
- /********* Start of inlined file: jfdctfst.c *********/
- #define JPEG_INTERNALS
-
- #ifdef DCT_IFAST_SUPPORTED
-
- /*
- * This module is specialized to the case DCTSIZE = 8.
- */
-
- #if DCTSIZE != 8
- Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */
- #endif
-
- /* Scaling decisions are generally the same as in the LL&M algorithm;
- * see jfdctint.c for more details. However, we choose to descale
- * (right shift) multiplication products as soon as they are formed,
- * rather than carrying additional fractional bits into subsequent additions.
- * This compromises accuracy slightly, but it lets us save a few shifts.
- * More importantly, 16-bit arithmetic is then adequate (for 8-bit samples)
- * everywhere except in the multiplications proper; this saves a good deal
- * of work on 16-bit-int machines.
- *
- * Again to save a few shifts, the intermediate results between pass 1 and
- * pass 2 are not upscaled, but are represented only to integral precision.
- *
- * A final compromise is to represent the multiplicative constants to only
- * 8 fractional bits, rather than 13. This saves some shifting work on some
- * machines, and may also reduce the cost of multiplication (since there
- * are fewer one-bits in the constants).
- */
-
- #define CONST_BITS 8
-
- /* Some C compilers fail to reduce "FIX(constant)" at compile time, thus
- * causing a lot of useless floating-point operations at run time.
- * To get around this we use the following pre-calculated constants.
- * If you change CONST_BITS you may want to add appropriate values.
- * (With a reasonable C compiler, you can just rely on the FIX() macro...)
- */
-
- #if CONST_BITS == 8
- #define FIX_0_382683433 ((INT32) 98) /* FIX(0.382683433) */
- #define FIX_0_541196100 ((INT32) 139) /* FIX(0.541196100) */
- #define FIX_0_707106781 ((INT32) 181) /* FIX(0.707106781) */
- #define FIX_1_306562965 ((INT32) 334) /* FIX(1.306562965) */
- #else
- #define FIX_0_382683433 FIX(0.382683433)
- #define FIX_0_541196100 FIX(0.541196100)
- #define FIX_0_707106781 FIX(0.707106781)
- #define FIX_1_306562965 FIX(1.306562965)
- #endif
-
- /* We can gain a little more speed, with a further compromise in accuracy,
- * by omitting the addition in a descaling shift. This yields an incorrectly
- * rounded result half the time...
- */
-
- #ifndef USE_ACCURATE_ROUNDING
- #undef DESCALE
- #define DESCALE(x,n) RIGHT_SHIFT(x, n)
- #endif
-
- /* Multiply a DCTELEM variable by an INT32 constant, and immediately
- * descale to yield a DCTELEM result.
- */
-
- #define MULTIPLY(var,const) ((DCTELEM) DESCALE((var) * (const), CONST_BITS))
-
- /*
- * Perform the forward DCT on one block of samples.
- */
-
- GLOBAL(void)
- jpeg_fdct_ifast (DCTELEM * data)
- {
- DCTELEM tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
- DCTELEM tmp10, tmp11, tmp12, tmp13;
- DCTELEM z1, z2, z3, z4, z5, z11, z13;
- DCTELEM *dataptr;
- int ctr;
- SHIFT_TEMPS
-
- /* Pass 1: process rows. */
-
- dataptr = data;
- for (ctr = DCTSIZE-1; ctr >= 0; ctr--) {
- tmp0 = dataptr[0] + dataptr[7];
- tmp7 = dataptr[0] - dataptr[7];
- tmp1 = dataptr[1] + dataptr[6];
- tmp6 = dataptr[1] - dataptr[6];
- tmp2 = dataptr[2] + dataptr[5];
- tmp5 = dataptr[2] - dataptr[5];
- tmp3 = dataptr[3] + dataptr[4];
- tmp4 = dataptr[3] - dataptr[4];
-
- /* Even part */
-
- tmp10 = tmp0 + tmp3; /* phase 2 */
- tmp13 = tmp0 - tmp3;
- tmp11 = tmp1 + tmp2;
- tmp12 = tmp1 - tmp2;
-
- dataptr[0] = tmp10 + tmp11; /* phase 3 */
- dataptr[4] = tmp10 - tmp11;
-
- z1 = MULTIPLY(tmp12 + tmp13, FIX_0_707106781); /* c4 */
- dataptr[2] = tmp13 + z1; /* phase 5 */
- dataptr[6] = tmp13 - z1;
-
- /* Odd part */
-
- tmp10 = tmp4 + tmp5; /* phase 2 */
- tmp11 = tmp5 + tmp6;
- tmp12 = tmp6 + tmp7;
-
- /* The rotator is modified from fig 4-8 to avoid extra negations. */
- z5 = MULTIPLY(tmp10 - tmp12, FIX_0_382683433); /* c6 */
- z2 = MULTIPLY(tmp10, FIX_0_541196100) + z5; /* c2-c6 */
- z4 = MULTIPLY(tmp12, FIX_1_306562965) + z5; /* c2+c6 */
- z3 = MULTIPLY(tmp11, FIX_0_707106781); /* c4 */
-
- z11 = tmp7 + z3; /* phase 5 */
- z13 = tmp7 - z3;
-
- dataptr[5] = z13 + z2; /* phase 6 */
- dataptr[3] = z13 - z2;
- dataptr[1] = z11 + z4;
- dataptr[7] = z11 - z4;
-
- dataptr += DCTSIZE; /* advance pointer to next row */
- }
-
- /* Pass 2: process columns. */
-
- dataptr = data;
- for (ctr = DCTSIZE-1; ctr >= 0; ctr--) {
- tmp0 = dataptr[DCTSIZE*0] + dataptr[DCTSIZE*7];
- tmp7 = dataptr[DCTSIZE*0] - dataptr[DCTSIZE*7];
- tmp1 = dataptr[DCTSIZE*1] + dataptr[DCTSIZE*6];
- tmp6 = dataptr[DCTSIZE*1] - dataptr[DCTSIZE*6];
- tmp2 = dataptr[DCTSIZE*2] + dataptr[DCTSIZE*5];
- tmp5 = dataptr[DCTSIZE*2] - dataptr[DCTSIZE*5];
- tmp3 = dataptr[DCTSIZE*3] + dataptr[DCTSIZE*4];
- tmp4 = dataptr[DCTSIZE*3] - dataptr[DCTSIZE*4];
-
- /* Even part */
-
- tmp10 = tmp0 + tmp3; /* phase 2 */
- tmp13 = tmp0 - tmp3;
- tmp11 = tmp1 + tmp2;
- tmp12 = tmp1 - tmp2;
-
- dataptr[DCTSIZE*0] = tmp10 + tmp11; /* phase 3 */
- dataptr[DCTSIZE*4] = tmp10 - tmp11;
-
- z1 = MULTIPLY(tmp12 + tmp13, FIX_0_707106781); /* c4 */
- dataptr[DCTSIZE*2] = tmp13 + z1; /* phase 5 */
- dataptr[DCTSIZE*6] = tmp13 - z1;
-
- /* Odd part */
-
- tmp10 = tmp4 + tmp5; /* phase 2 */
- tmp11 = tmp5 + tmp6;
- tmp12 = tmp6 + tmp7;
-
- /* The rotator is modified from fig 4-8 to avoid extra negations. */
- z5 = MULTIPLY(tmp10 - tmp12, FIX_0_382683433); /* c6 */
- z2 = MULTIPLY(tmp10, FIX_0_541196100) + z5; /* c2-c6 */
- z4 = MULTIPLY(tmp12, FIX_1_306562965) + z5; /* c2+c6 */
- z3 = MULTIPLY(tmp11, FIX_0_707106781); /* c4 */
-
- z11 = tmp7 + z3; /* phase 5 */
- z13 = tmp7 - z3;
-
- dataptr[DCTSIZE*5] = z13 + z2; /* phase 6 */
- dataptr[DCTSIZE*3] = z13 - z2;
- dataptr[DCTSIZE*1] = z11 + z4;
- dataptr[DCTSIZE*7] = z11 - z4;
-
- dataptr++; /* advance pointer to next column */
- }
- }
-
- #endif /* DCT_IFAST_SUPPORTED */
- /********* End of inlined file: jfdctfst.c *********/
-
- #undef FIX_0_541196100
-
- /********* Start of inlined file: jidctflt.c *********/
- #define JPEG_INTERNALS
-
- #ifdef DCT_FLOAT_SUPPORTED
-
- /*
- * This module is specialized to the case DCTSIZE = 8.
- */
-
- #if DCTSIZE != 8
- Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */
- #endif
-
- /* Dequantize a coefficient by multiplying it by the multiplier-table
- * entry; produce a float result.
- */
-
- #define DEQUANTIZE(coef,quantval) (((FAST_FLOAT) (coef)) * (quantval))
-
- /*
- * Perform dequantization and inverse DCT on one block of coefficients.
- */
-
- GLOBAL(void)
- jpeg_idct_float (j_decompress_ptr cinfo, jpeg_component_info * compptr,
- JCOEFPTR coef_block,
- JSAMPARRAY output_buf, JDIMENSION output_col)
- {
- FAST_FLOAT tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
- FAST_FLOAT tmp10, tmp11, tmp12, tmp13;
- FAST_FLOAT z5, z10, z11, z12, z13;
- JCOEFPTR inptr;
- FLOAT_MULT_TYPE * quantptr;
- FAST_FLOAT * wsptr;
- JSAMPROW outptr;
- JSAMPLE *range_limit = IDCT_range_limit(cinfo);
- int ctr;
- FAST_FLOAT workspace[DCTSIZE2]; /* buffers data between passes */
- SHIFT_TEMPS
-
- /* Pass 1: process columns from input, store into work array. */
-
- inptr = coef_block;
- quantptr = (FLOAT_MULT_TYPE *) compptr->dct_table;
- wsptr = workspace;
- for (ctr = DCTSIZE; ctr > 0; ctr--) {
- /* Due to quantization, we will usually find that many of the input
- * coefficients are zero, especially the AC terms. We can exploit this
- * by short-circuiting the IDCT calculation for any column in which all
- * the AC terms are zero. In that case each output is equal to the
- * DC coefficient (with scale factor as needed).
- * With typical images and quantization tables, half or more of the
- * column DCT calculations can be simplified this way.
- */
-
- if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 &&
- inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*4] == 0 &&
- inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*6] == 0 &&
- inptr[DCTSIZE*7] == 0) {
- /* AC terms all zero */
- FAST_FLOAT dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
-
- wsptr[DCTSIZE*0] = dcval;
- wsptr[DCTSIZE*1] = dcval;
- wsptr[DCTSIZE*2] = dcval;
- wsptr[DCTSIZE*3] = dcval;
- wsptr[DCTSIZE*4] = dcval;
- wsptr[DCTSIZE*5] = dcval;
- wsptr[DCTSIZE*6] = dcval;
- wsptr[DCTSIZE*7] = dcval;
-
- inptr++; /* advance pointers to next column */
- quantptr++;
- wsptr++;
- continue;
- }
-
- /* Even part */
-
- tmp0 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
- tmp1 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]);
- tmp2 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]);
- tmp3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]);
-
- tmp10 = tmp0 + tmp2; /* phase 3 */
- tmp11 = tmp0 - tmp2;
-
- tmp13 = tmp1 + tmp3; /* phases 5-3 */
- tmp12 = (tmp1 - tmp3) * ((FAST_FLOAT) 1.414213562) - tmp13; /* 2*c4 */
-
- tmp0 = tmp10 + tmp13; /* phase 2 */
- tmp3 = tmp10 - tmp13;
- tmp1 = tmp11 + tmp12;
- tmp2 = tmp11 - tmp12;
-
- /* Odd part */
-
- tmp4 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]);
- tmp5 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]);
- tmp6 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]);
- tmp7 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]);
-
- z13 = tmp6 + tmp5; /* phase 6 */
- z10 = tmp6 - tmp5;
- z11 = tmp4 + tmp7;
- z12 = tmp4 - tmp7;
-
- tmp7 = z11 + z13; /* phase 5 */
- tmp11 = (z11 - z13) * ((FAST_FLOAT) 1.414213562); /* 2*c4 */
-
- z5 = (z10 + z12) * ((FAST_FLOAT) 1.847759065); /* 2*c2 */
- tmp10 = ((FAST_FLOAT) 1.082392200) * z12 - z5; /* 2*(c2-c6) */
- tmp12 = ((FAST_FLOAT) -2.613125930) * z10 + z5; /* -2*(c2+c6) */
-
- tmp6 = tmp12 - tmp7; /* phase 2 */
- tmp5 = tmp11 - tmp6;
- tmp4 = tmp10 + tmp5;
-
- wsptr[DCTSIZE*0] = tmp0 + tmp7;
- wsptr[DCTSIZE*7] = tmp0 - tmp7;
- wsptr[DCTSIZE*1] = tmp1 + tmp6;
- wsptr[DCTSIZE*6] = tmp1 - tmp6;
- wsptr[DCTSIZE*2] = tmp2 + tmp5;
- wsptr[DCTSIZE*5] = tmp2 - tmp5;
- wsptr[DCTSIZE*4] = tmp3 + tmp4;
- wsptr[DCTSIZE*3] = tmp3 - tmp4;
-
- inptr++; /* advance pointers to next column */
- quantptr++;
- wsptr++;
- }
-
- /* Pass 2: process rows from work array, store into output array. */
- /* Note that we must descale the results by a factor of 8 == 2**3. */
-
- wsptr = workspace;
- for (ctr = 0; ctr < DCTSIZE; ctr++) {
- outptr = output_buf[ctr] + output_col;
- /* Rows of zeroes can be exploited in the same way as we did with columns.
- * However, the column calculation has created many nonzero AC terms, so
- * the simplification applies less often (typically 5% to 10% of the time).
- * And testing floats for zero is relatively expensive, so we don't bother.
- */
-
- /* Even part */
-
- tmp10 = wsptr[0] + wsptr[4];
- tmp11 = wsptr[0] - wsptr[4];
-
- tmp13 = wsptr[2] + wsptr[6];
- tmp12 = (wsptr[2] - wsptr[6]) * ((FAST_FLOAT) 1.414213562) - tmp13;
-
- tmp0 = tmp10 + tmp13;
- tmp3 = tmp10 - tmp13;
- tmp1 = tmp11 + tmp12;
- tmp2 = tmp11 - tmp12;
-
- /* Odd part */
-
- z13 = wsptr[5] + wsptr[3];
- z10 = wsptr[5] - wsptr[3];
- z11 = wsptr[1] + wsptr[7];
- z12 = wsptr[1] - wsptr[7];
-
- tmp7 = z11 + z13;
- tmp11 = (z11 - z13) * ((FAST_FLOAT) 1.414213562);
-
- z5 = (z10 + z12) * ((FAST_FLOAT) 1.847759065); /* 2*c2 */
- tmp10 = ((FAST_FLOAT) 1.082392200) * z12 - z5; /* 2*(c2-c6) */
- tmp12 = ((FAST_FLOAT) -2.613125930) * z10 + z5; /* -2*(c2+c6) */
-
- tmp6 = tmp12 - tmp7;
- tmp5 = tmp11 - tmp6;
- tmp4 = tmp10 + tmp5;
-
- /* Final output stage: scale down by a factor of 8 and range-limit */
-
- outptr[0] = range_limit[(int) DESCALE((INT32) (tmp0 + tmp7), 3)
- & RANGE_MASK];
- outptr[7] = range_limit[(int) DESCALE((INT32) (tmp0 - tmp7), 3)
- & RANGE_MASK];
- outptr[1] = range_limit[(int) DESCALE((INT32) (tmp1 + tmp6), 3)
- & RANGE_MASK];
- outptr[6] = range_limit[(int) DESCALE((INT32) (tmp1 - tmp6), 3)
- & RANGE_MASK];
- outptr[2] = range_limit[(int) DESCALE((INT32) (tmp2 + tmp5), 3)
- & RANGE_MASK];
- outptr[5] = range_limit[(int) DESCALE((INT32) (tmp2 - tmp5), 3)
- & RANGE_MASK];
- outptr[4] = range_limit[(int) DESCALE((INT32) (tmp3 + tmp4), 3)
- & RANGE_MASK];
- outptr[3] = range_limit[(int) DESCALE((INT32) (tmp3 - tmp4), 3)
- & RANGE_MASK];
-
- wsptr += DCTSIZE; /* advance pointer to next row */
- }
- }
-
- #endif /* DCT_FLOAT_SUPPORTED */
- /********* End of inlined file: jidctflt.c *********/
-
- #undef CONST_BITS
- #undef FIX_1_847759065
- #undef MULTIPLY
- #undef DEQUANTIZE
- #undef DESCALE
-
- /********* Start of inlined file: jidctfst.c *********/
- #define JPEG_INTERNALS
-
- #ifdef DCT_IFAST_SUPPORTED
-
- /*
- * This module is specialized to the case DCTSIZE = 8.
- */
-
- #if DCTSIZE != 8
- Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */
- #endif
-
- /* Scaling decisions are generally the same as in the LL&M algorithm;
- * see jidctint.c for more details. However, we choose to descale
- * (right shift) multiplication products as soon as they are formed,
- * rather than carrying additional fractional bits into subsequent additions.
- * This compromises accuracy slightly, but it lets us save a few shifts.
- * More importantly, 16-bit arithmetic is then adequate (for 8-bit samples)
- * everywhere except in the multiplications proper; this saves a good deal
- * of work on 16-bit-int machines.
- *
- * The dequantized coefficients are not integers because the AA&N scaling
- * factors have been incorporated. We represent them scaled up by PASS1_BITS,
- * so that the first and second IDCT rounds have the same input scaling.
- * For 8-bit JSAMPLEs, we choose IFAST_SCALE_BITS = PASS1_BITS so as to
- * avoid a descaling shift; this compromises accuracy rather drastically
- * for small quantization table entries, but it saves a lot of shifts.
- * For 12-bit JSAMPLEs, there's no hope of using 16x16 multiplies anyway,
- * so we use a much larger scaling factor to preserve accuracy.
- *
- * A final compromise is to represent the multiplicative constants to only
- * 8 fractional bits, rather than 13. This saves some shifting work on some
- * machines, and may also reduce the cost of multiplication (since there
- * are fewer one-bits in the constants).
- */
-
- #if BITS_IN_JSAMPLE == 8
- #define CONST_BITS 8
- #define PASS1_BITS 2
- #else
- #define CONST_BITS 8
- #define PASS1_BITS 1 /* lose a little precision to avoid overflow */
- #endif
-
- /* Some C compilers fail to reduce "FIX(constant)" at compile time, thus
- * causing a lot of useless floating-point operations at run time.
- * To get around this we use the following pre-calculated constants.
- * If you change CONST_BITS you may want to add appropriate values.
- * (With a reasonable C compiler, you can just rely on the FIX() macro...)
- */
-
- #if CONST_BITS == 8
- #define FIX_1_082392200 ((INT32) 277) /* FIX(1.082392200) */
- #define FIX_1_414213562 ((INT32) 362) /* FIX(1.414213562) */
- #define FIX_1_847759065 ((INT32) 473) /* FIX(1.847759065) */
- #define FIX_2_613125930 ((INT32) 669) /* FIX(2.613125930) */
- #else
- #define FIX_1_082392200 FIX(1.082392200)
- #define FIX_1_414213562 FIX(1.414213562)
- #define FIX_1_847759065 FIX(1.847759065)
- #define FIX_2_613125930 FIX(2.613125930)
- #endif
-
- /* We can gain a little more speed, with a further compromise in accuracy,
- * by omitting the addition in a descaling shift. This yields an incorrectly
- * rounded result half the time...
- */
-
- #ifndef USE_ACCURATE_ROUNDING
- #undef DESCALE
- #define DESCALE(x,n) RIGHT_SHIFT(x, n)
- #endif
-
- /* Multiply a DCTELEM variable by an INT32 constant, and immediately
- * descale to yield a DCTELEM result.
- */
-
- #define MULTIPLY(var,const) ((DCTELEM) DESCALE((var) * (const), CONST_BITS))
-
- /* Dequantize a coefficient by multiplying it by the multiplier-table
- * entry; produce a DCTELEM result. For 8-bit data a 16x16->16
- * multiplication will do. For 12-bit data, the multiplier table is
- * declared INT32, so a 32-bit multiply will be used.
- */
-
- #if BITS_IN_JSAMPLE == 8
- #define DEQUANTIZE(coef,quantval) (((IFAST_MULT_TYPE) (coef)) * (quantval))
- #else
- #define DEQUANTIZE(coef,quantval) \
- DESCALE((coef)*(quantval), IFAST_SCALE_BITS-PASS1_BITS)
- #endif
-
- /* Like DESCALE, but applies to a DCTELEM and produces an int.
- * We assume that int right shift is unsigned if INT32 right shift is.
- */
-
- #ifdef RIGHT_SHIFT_IS_UNSIGNED
- #define ISHIFT_TEMPS DCTELEM ishift_temp;
- #if BITS_IN_JSAMPLE == 8
- #define DCTELEMBITS 16 /* DCTELEM may be 16 or 32 bits */
- #else
- #define DCTELEMBITS 32 /* DCTELEM must be 32 bits */
- #endif
- #define IRIGHT_SHIFT(x,shft) \
- ((ishift_temp = (x)) < 0 ? \
- (ishift_temp >> (shft)) | ((~((DCTELEM) 0)) << (DCTELEMBITS-(shft))) : \
- (ishift_temp >> (shft)))
- #else
- #define ISHIFT_TEMPS
- #define IRIGHT_SHIFT(x,shft) ((x) >> (shft))
- #endif
-
- #ifdef USE_ACCURATE_ROUNDING
- #define IDESCALE(x,n) ((int) IRIGHT_SHIFT((x) + (1 << ((n)-1)), n))
- #else
- #define IDESCALE(x,n) ((int) IRIGHT_SHIFT(x, n))
- #endif
-
- /*
- * Perform dequantization and inverse DCT on one block of coefficients.
- */
-
- GLOBAL(void)
- jpeg_idct_ifast (j_decompress_ptr cinfo, jpeg_component_info * compptr,
- JCOEFPTR coef_block,
- JSAMPARRAY output_buf, JDIMENSION output_col)
- {
- DCTELEM tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
- DCTELEM tmp10, tmp11, tmp12, tmp13;
- DCTELEM z5, z10, z11, z12, z13;
- JCOEFPTR inptr;
- IFAST_MULT_TYPE * quantptr;
- int * wsptr;
- JSAMPROW outptr;
- JSAMPLE *range_limit = IDCT_range_limit(cinfo);
- int ctr;
- int workspace[DCTSIZE2]; /* buffers data between passes */
- SHIFT_TEMPS /* for DESCALE */
- ISHIFT_TEMPS /* for IDESCALE */
-
- /* Pass 1: process columns from input, store into work array. */
-
- inptr = coef_block;
- quantptr = (IFAST_MULT_TYPE *) compptr->dct_table;
- wsptr = workspace;
- for (ctr = DCTSIZE; ctr > 0; ctr--) {
- /* Due to quantization, we will usually find that many of the input
- * coefficients are zero, especially the AC terms. We can exploit this
- * by short-circuiting the IDCT calculation for any column in which all
- * the AC terms are zero. In that case each output is equal to the
- * DC coefficient (with scale factor as needed).
- * With typical images and quantization tables, half or more of the
- * column DCT calculations can be simplified this way.
- */
-
- if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 &&
- inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*4] == 0 &&
- inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*6] == 0 &&
- inptr[DCTSIZE*7] == 0) {
- /* AC terms all zero */
- int dcval = (int) DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
-
- wsptr[DCTSIZE*0] = dcval;
- wsptr[DCTSIZE*1] = dcval;
- wsptr[DCTSIZE*2] = dcval;
- wsptr[DCTSIZE*3] = dcval;
- wsptr[DCTSIZE*4] = dcval;
- wsptr[DCTSIZE*5] = dcval;
- wsptr[DCTSIZE*6] = dcval;
- wsptr[DCTSIZE*7] = dcval;
-
- inptr++; /* advance pointers to next column */
- quantptr++;
- wsptr++;
- continue;
- }
-
- /* Even part */
-
- tmp0 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
- tmp1 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]);
- tmp2 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]);
- tmp3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]);
-
- tmp10 = tmp0 + tmp2; /* phase 3 */
- tmp11 = tmp0 - tmp2;
-
- tmp13 = tmp1 + tmp3; /* phases 5-3 */
- tmp12 = MULTIPLY(tmp1 - tmp3, FIX_1_414213562) - tmp13; /* 2*c4 */
-
- tmp0 = tmp10 + tmp13; /* phase 2 */
- tmp3 = tmp10 - tmp13;
- tmp1 = tmp11 + tmp12;
- tmp2 = tmp11 - tmp12;
-
- /* Odd part */
-
- tmp4 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]);
- tmp5 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]);
- tmp6 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]);
- tmp7 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]);
-
- z13 = tmp6 + tmp5; /* phase 6 */
- z10 = tmp6 - tmp5;
- z11 = tmp4 + tmp7;
- z12 = tmp4 - tmp7;
-
- tmp7 = z11 + z13; /* phase 5 */
- tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); /* 2*c4 */
-
- z5 = MULTIPLY(z10 + z12, FIX_1_847759065); /* 2*c2 */
- tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5; /* 2*(c2-c6) */
- tmp12 = MULTIPLY(z10, - FIX_2_613125930) + z5; /* -2*(c2+c6) */
-
- tmp6 = tmp12 - tmp7; /* phase 2 */
- tmp5 = tmp11 - tmp6;
- tmp4 = tmp10 + tmp5;
-
- wsptr[DCTSIZE*0] = (int) (tmp0 + tmp7);
- wsptr[DCTSIZE*7] = (int) (tmp0 - tmp7);
- wsptr[DCTSIZE*1] = (int) (tmp1 + tmp6);
- wsptr[DCTSIZE*6] = (int) (tmp1 - tmp6);
- wsptr[DCTSIZE*2] = (int) (tmp2 + tmp5);
- wsptr[DCTSIZE*5] = (int) (tmp2 - tmp5);
- wsptr[DCTSIZE*4] = (int) (tmp3 + tmp4);
- wsptr[DCTSIZE*3] = (int) (tmp3 - tmp4);
-
- inptr++; /* advance pointers to next column */
- quantptr++;
- wsptr++;
- }
-
- /* Pass 2: process rows from work array, store into output array. */
- /* Note that we must descale the results by a factor of 8 == 2**3, */
- /* and also undo the PASS1_BITS scaling. */
-
- wsptr = workspace;
- for (ctr = 0; ctr < DCTSIZE; ctr++) {
- outptr = output_buf[ctr] + output_col;
- /* Rows of zeroes can be exploited in the same way as we did with columns.
- * However, the column calculation has created many nonzero AC terms, so
- * the simplification applies less often (typically 5% to 10% of the time).
- * On machines with very fast multiplication, it's possible that the
- * test takes more time than it's worth. In that case this section
- * may be commented out.
- */
-
- #ifndef NO_ZERO_ROW_TEST
- if (wsptr[1] == 0 && wsptr[2] == 0 && wsptr[3] == 0 && wsptr[4] == 0 &&
- wsptr[5] == 0 && wsptr[6] == 0 && wsptr[7] == 0) {
- /* AC terms all zero */
- JSAMPLE dcval = range_limit[IDESCALE(wsptr[0], PASS1_BITS+3)
- & RANGE_MASK];
-
- outptr[0] = dcval;
- outptr[1] = dcval;
- outptr[2] = dcval;
- outptr[3] = dcval;
- outptr[4] = dcval;
- outptr[5] = dcval;
- outptr[6] = dcval;
- outptr[7] = dcval;
-
- wsptr += DCTSIZE; /* advance pointer to next row */
- continue;
- }
- #endif
-
- /* Even part */
-
- tmp10 = ((DCTELEM) wsptr[0] + (DCTELEM) wsptr[4]);
- tmp11 = ((DCTELEM) wsptr[0] - (DCTELEM) wsptr[4]);
-
- tmp13 = ((DCTELEM) wsptr[2] + (DCTELEM) wsptr[6]);
- tmp12 = MULTIPLY((DCTELEM) wsptr[2] - (DCTELEM) wsptr[6], FIX_1_414213562)
- - tmp13;
-
- tmp0 = tmp10 + tmp13;
- tmp3 = tmp10 - tmp13;
- tmp1 = tmp11 + tmp12;
- tmp2 = tmp11 - tmp12;
-
- /* Odd part */
-
- z13 = (DCTELEM) wsptr[5] + (DCTELEM) wsptr[3];
- z10 = (DCTELEM) wsptr[5] - (DCTELEM) wsptr[3];
- z11 = (DCTELEM) wsptr[1] + (DCTELEM) wsptr[7];
- z12 = (DCTELEM) wsptr[1] - (DCTELEM) wsptr[7];
-
- tmp7 = z11 + z13; /* phase 5 */
- tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); /* 2*c4 */
-
- z5 = MULTIPLY(z10 + z12, FIX_1_847759065); /* 2*c2 */
- tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5; /* 2*(c2-c6) */
- tmp12 = MULTIPLY(z10, - FIX_2_613125930) + z5; /* -2*(c2+c6) */
-
- tmp6 = tmp12 - tmp7; /* phase 2 */
- tmp5 = tmp11 - tmp6;
- tmp4 = tmp10 + tmp5;
-
- /* Final output stage: scale down by a factor of 8 and range-limit */
-
- outptr[0] = range_limit[IDESCALE(tmp0 + tmp7, PASS1_BITS+3)
- & RANGE_MASK];
- outptr[7] = range_limit[IDESCALE(tmp0 - tmp7, PASS1_BITS+3)
- & RANGE_MASK];
- outptr[1] = range_limit[IDESCALE(tmp1 + tmp6, PASS1_BITS+3)
- & RANGE_MASK];
- outptr[6] = range_limit[IDESCALE(tmp1 - tmp6, PASS1_BITS+3)
- & RANGE_MASK];
- outptr[2] = range_limit[IDESCALE(tmp2 + tmp5, PASS1_BITS+3)
- & RANGE_MASK];
- outptr[5] = range_limit[IDESCALE(tmp2 - tmp5, PASS1_BITS+3)
- & RANGE_MASK];
- outptr[4] = range_limit[IDESCALE(tmp3 + tmp4, PASS1_BITS+3)
- & RANGE_MASK];
- outptr[3] = range_limit[IDESCALE(tmp3 - tmp4, PASS1_BITS+3)
- & RANGE_MASK];
-
- wsptr += DCTSIZE; /* advance pointer to next row */
- }
- }
-
- #endif /* DCT_IFAST_SUPPORTED */
- /********* End of inlined file: jidctfst.c *********/
-
- #undef CONST_BITS
- #undef FIX_1_847759065
- #undef MULTIPLY
- #undef DEQUANTIZE
-
- /********* Start of inlined file: jidctint.c *********/
- #define JPEG_INTERNALS
-
- #ifdef DCT_ISLOW_SUPPORTED
-
- /*
- * This module is specialized to the case DCTSIZE = 8.
- */
-
- #if DCTSIZE != 8
- Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */
- #endif
-
- /*
- * The poop on this scaling stuff is as follows:
- *
- * Each 1-D IDCT step produces outputs which are a factor of sqrt(N)
- * larger than the true IDCT outputs. The final outputs are therefore
- * a factor of N larger than desired; since N=8 this can be cured by
- * a simple right shift at the end of the algorithm. The advantage of
- * this arrangement is that we save two multiplications per 1-D IDCT,
- * because the y0 and y4 inputs need not be divided by sqrt(N).
- *
- * We have to do addition and subtraction of the integer inputs, which
- * is no problem, and multiplication by fractional constants, which is
- * a problem to do in integer arithmetic. We multiply all the constants
- * by CONST_SCALE and convert them to integer constants (thus retaining
- * CONST_BITS bits of precision in the constants). After doing a
- * multiplication we have to divide the product by CONST_SCALE, with proper
- * rounding, to produce the correct output. This division can be done
- * cheaply as a right shift of CONST_BITS bits. We postpone shifting
- * as long as possible so that partial sums can be added together with
- * full fractional precision.
- *
- * The outputs of the first pass are scaled up by PASS1_BITS bits so that
- * they are represented to better-than-integral precision. These outputs
- * require BITS_IN_JSAMPLE + PASS1_BITS + 3 bits; this fits in a 16-bit word
- * with the recommended scaling. (To scale up 12-bit sample data further, an
- * intermediate INT32 array would be needed.)
- *
- * To avoid overflow of the 32-bit intermediate results in pass 2, we must
- * have BITS_IN_JSAMPLE + CONST_BITS + PASS1_BITS <= 26. Error analysis
- * shows that the values given below are the most effective.
- */
-
- #if BITS_IN_JSAMPLE == 8
- #define CONST_BITS 13
- #define PASS1_BITS 2
- #else
- #define CONST_BITS 13
- #define PASS1_BITS 1 /* lose a little precision to avoid overflow */
- #endif
-
- /* Some C compilers fail to reduce "FIX(constant)" at compile time, thus
- * causing a lot of useless floating-point operations at run time.
- * To get around this we use the following pre-calculated constants.
- * If you change CONST_BITS you may want to add appropriate values.
- * (With a reasonable C compiler, you can just rely on the FIX() macro...)
- */
-
- #if CONST_BITS == 13
- #define FIX_0_298631336 ((INT32) 2446) /* FIX(0.298631336) */
- #define FIX_0_390180644 ((INT32) 3196) /* FIX(0.390180644) */
- #define FIX_0_541196100 ((INT32) 4433) /* FIX(0.541196100) */
- #define FIX_0_765366865 ((INT32) 6270) /* FIX(0.765366865) */
- #define FIX_0_899976223 ((INT32) 7373) /* FIX(0.899976223) */
- #define FIX_1_175875602 ((INT32) 9633) /* FIX(1.175875602) */
- #define FIX_1_501321110 ((INT32) 12299) /* FIX(1.501321110) */
- #define FIX_1_847759065 ((INT32) 15137) /* FIX(1.847759065) */
- #define FIX_1_961570560 ((INT32) 16069) /* FIX(1.961570560) */
- #define FIX_2_053119869 ((INT32) 16819) /* FIX(2.053119869) */
- #define FIX_2_562915447 ((INT32) 20995) /* FIX(2.562915447) */
- #define FIX_3_072711026 ((INT32) 25172) /* FIX(3.072711026) */
- #else
- #define FIX_0_298631336 FIX(0.298631336)
- #define FIX_0_390180644 FIX(0.390180644)
- #define FIX_0_541196100 FIX(0.541196100)
- #define FIX_0_765366865 FIX(0.765366865)
- #define FIX_0_899976223 FIX(0.899976223)
- #define FIX_1_175875602 FIX(1.175875602)
- #define FIX_1_501321110 FIX(1.501321110)
- #define FIX_1_847759065 FIX(1.847759065)
- #define FIX_1_961570560 FIX(1.961570560)
- #define FIX_2_053119869 FIX(2.053119869)
- #define FIX_2_562915447 FIX(2.562915447)
- #define FIX_3_072711026 FIX(3.072711026)
- #endif
-
- /* Multiply an INT32 variable by an INT32 constant to yield an INT32 result.
- * For 8-bit samples with the recommended scaling, all the variable
- * and constant values involved are no more than 16 bits wide, so a
- * 16x16->32 bit multiply can be used instead of a full 32x32 multiply.
- * For 12-bit samples, a full 32-bit multiplication will be needed.
- */
-
- #if BITS_IN_JSAMPLE == 8
- #define MULTIPLY(var,const) MULTIPLY16C16(var,const)
- #else
- #define MULTIPLY(var,const) ((var) * (const))
- #endif
-
- /* Dequantize a coefficient by multiplying it by the multiplier-table
- * entry; produce an int result. In this module, both inputs and result
- * are 16 bits or less, so either int or short multiply will work.
- */
-
- #define DEQUANTIZE(coef,quantval) (((ISLOW_MULT_TYPE) (coef)) * (quantval))
-
- /*
- * Perform dequantization and inverse DCT on one block of coefficients.
- */
-
- GLOBAL(void)
- jpeg_idct_islow (j_decompress_ptr cinfo, jpeg_component_info * compptr,
- JCOEFPTR coef_block,
- JSAMPARRAY output_buf, JDIMENSION output_col)
- {
- INT32 tmp0, tmp1, tmp2, tmp3;
- INT32 tmp10, tmp11, tmp12, tmp13;
- INT32 z1, z2, z3, z4, z5;
- JCOEFPTR inptr;
- ISLOW_MULT_TYPE * quantptr;
- int * wsptr;
- JSAMPROW outptr;
- JSAMPLE *range_limit = IDCT_range_limit(cinfo);
- int ctr;
- int workspace[DCTSIZE2]; /* buffers data between passes */
- SHIFT_TEMPS
-
- /* Pass 1: process columns from input, store into work array. */
- /* Note results are scaled up by sqrt(8) compared to a true IDCT; */
- /* furthermore, we scale the results by 2**PASS1_BITS. */
-
- inptr = coef_block;
- quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table;
- wsptr = workspace;
- for (ctr = DCTSIZE; ctr > 0; ctr--) {
- /* Due to quantization, we will usually find that many of the input
- * coefficients are zero, especially the AC terms. We can exploit this
- * by short-circuiting the IDCT calculation for any column in which all
- * the AC terms are zero. In that case each output is equal to the
- * DC coefficient (with scale factor as needed).
- * With typical images and quantization tables, half or more of the
- * column DCT calculations can be simplified this way.
- */
-
- if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 &&
- inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*4] == 0 &&
- inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*6] == 0 &&
- inptr[DCTSIZE*7] == 0) {
- /* AC terms all zero */
- int dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]) << PASS1_BITS;
-
- wsptr[DCTSIZE*0] = dcval;
- wsptr[DCTSIZE*1] = dcval;
- wsptr[DCTSIZE*2] = dcval;
- wsptr[DCTSIZE*3] = dcval;
- wsptr[DCTSIZE*4] = dcval;
- wsptr[DCTSIZE*5] = dcval;
- wsptr[DCTSIZE*6] = dcval;
- wsptr[DCTSIZE*7] = dcval;
-
- inptr++; /* advance pointers to next column */
- quantptr++;
- wsptr++;
- continue;
- }
-
- /* Even part: reverse the even part of the forward DCT. */
- /* The rotator is sqrt(2)*c(-6). */
-
- z2 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]);
- z3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]);
-
- z1 = MULTIPLY(z2 + z3, FIX_0_541196100);
- tmp2 = z1 + MULTIPLY(z3, - FIX_1_847759065);
- tmp3 = z1 + MULTIPLY(z2, FIX_0_765366865);
-
- z2 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
- z3 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]);
-
- tmp0 = (z2 + z3) << CONST_BITS;
- tmp1 = (z2 - z3) << CONST_BITS;
-
- tmp10 = tmp0 + tmp3;
- tmp13 = tmp0 - tmp3;
- tmp11 = tmp1 + tmp2;
- tmp12 = tmp1 - tmp2;
-
- /* Odd part per figure 8; the matrix is unitary and hence its
- * transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively.
- */
-
- tmp0 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]);
- tmp1 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]);
- tmp2 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]);
- tmp3 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]);
-
- z1 = tmp0 + tmp3;
- z2 = tmp1 + tmp2;
- z3 = tmp0 + tmp2;
- z4 = tmp1 + tmp3;
- z5 = MULTIPLY(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */
-
- tmp0 = MULTIPLY(tmp0, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */
- tmp1 = MULTIPLY(tmp1, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */
- tmp2 = MULTIPLY(tmp2, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */
- tmp3 = MULTIPLY(tmp3, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */
- z1 = MULTIPLY(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */
- z2 = MULTIPLY(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
- z3 = MULTIPLY(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
- z4 = MULTIPLY(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */
-
- z3 += z5;
- z4 += z5;
-
- tmp0 += z1 + z3;
- tmp1 += z2 + z4;
- tmp2 += z2 + z3;
- tmp3 += z1 + z4;
-
- /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */
-
- wsptr[DCTSIZE*0] = (int) DESCALE(tmp10 + tmp3, CONST_BITS-PASS1_BITS);
- wsptr[DCTSIZE*7] = (int) DESCALE(tmp10 - tmp3, CONST_BITS-PASS1_BITS);
- wsptr[DCTSIZE*1] = (int) DESCALE(tmp11 + tmp2, CONST_BITS-PASS1_BITS);
- wsptr[DCTSIZE*6] = (int) DESCALE(tmp11 - tmp2, CONST_BITS-PASS1_BITS);
- wsptr[DCTSIZE*2] = (int) DESCALE(tmp12 + tmp1, CONST_BITS-PASS1_BITS);
- wsptr[DCTSIZE*5] = (int) DESCALE(tmp12 - tmp1, CONST_BITS-PASS1_BITS);
- wsptr[DCTSIZE*3] = (int) DESCALE(tmp13 + tmp0, CONST_BITS-PASS1_BITS);
- wsptr[DCTSIZE*4] = (int) DESCALE(tmp13 - tmp0, CONST_BITS-PASS1_BITS);
-
- inptr++; /* advance pointers to next column */
- quantptr++;
- wsptr++;
- }
-
- /* Pass 2: process rows from work array, store into output array. */
- /* Note that we must descale the results by a factor of 8 == 2**3, */
- /* and also undo the PASS1_BITS scaling. */
-
- wsptr = workspace;
- for (ctr = 0; ctr < DCTSIZE; ctr++) {
- outptr = output_buf[ctr] + output_col;
- /* Rows of zeroes can be exploited in the same way as we did with columns.
- * However, the column calculation has created many nonzero AC terms, so
- * the simplification applies less often (typically 5% to 10% of the time).
- * On machines with very fast multiplication, it's possible that the
- * test takes more time than it's worth. In that case this section
- * may be commented out.
- */
-
- #ifndef NO_ZERO_ROW_TEST
- if (wsptr[1] == 0 && wsptr[2] == 0 && wsptr[3] == 0 && wsptr[4] == 0 &&
- wsptr[5] == 0 && wsptr[6] == 0 && wsptr[7] == 0) {
- /* AC terms all zero */
- JSAMPLE dcval = range_limit[(int) DESCALE((INT32) wsptr[0], PASS1_BITS+3)
- & RANGE_MASK];
-
- outptr[0] = dcval;
- outptr[1] = dcval;
- outptr[2] = dcval;
- outptr[3] = dcval;
- outptr[4] = dcval;
- outptr[5] = dcval;
- outptr[6] = dcval;
- outptr[7] = dcval;
-
- wsptr += DCTSIZE; /* advance pointer to next row */
- continue;
- }
- #endif
-
- /* Even part: reverse the even part of the forward DCT. */
- /* The rotator is sqrt(2)*c(-6). */
-
- z2 = (INT32) wsptr[2];
- z3 = (INT32) wsptr[6];
-
- z1 = MULTIPLY(z2 + z3, FIX_0_541196100);
- tmp2 = z1 + MULTIPLY(z3, - FIX_1_847759065);
- tmp3 = z1 + MULTIPLY(z2, FIX_0_765366865);
-
- tmp0 = ((INT32) wsptr[0] + (INT32) wsptr[4]) << CONST_BITS;
- tmp1 = ((INT32) wsptr[0] - (INT32) wsptr[4]) << CONST_BITS;
-
- tmp10 = tmp0 + tmp3;
- tmp13 = tmp0 - tmp3;
- tmp11 = tmp1 + tmp2;
- tmp12 = tmp1 - tmp2;
-
- /* Odd part per figure 8; the matrix is unitary and hence its
- * transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively.
- */
-
- tmp0 = (INT32) wsptr[7];
- tmp1 = (INT32) wsptr[5];
- tmp2 = (INT32) wsptr[3];
- tmp3 = (INT32) wsptr[1];
-
- z1 = tmp0 + tmp3;
- z2 = tmp1 + tmp2;
- z3 = tmp0 + tmp2;
- z4 = tmp1 + tmp3;
- z5 = MULTIPLY(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */
-
- tmp0 = MULTIPLY(tmp0, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */
- tmp1 = MULTIPLY(tmp1, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */
- tmp2 = MULTIPLY(tmp2, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */
- tmp3 = MULTIPLY(tmp3, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */
- z1 = MULTIPLY(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */
- z2 = MULTIPLY(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
- z3 = MULTIPLY(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
- z4 = MULTIPLY(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */
-
- z3 += z5;
- z4 += z5;
-
- tmp0 += z1 + z3;
- tmp1 += z2 + z4;
- tmp2 += z2 + z3;
- tmp3 += z1 + z4;
-
- /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */
-
- outptr[0] = range_limit[(int) DESCALE(tmp10 + tmp3,
- CONST_BITS+PASS1_BITS+3)
- & RANGE_MASK];
- outptr[7] = range_limit[(int) DESCALE(tmp10 - tmp3,
- CONST_BITS+PASS1_BITS+3)
- & RANGE_MASK];
- outptr[1] = range_limit[(int) DESCALE(tmp11 + tmp2,
- CONST_BITS+PASS1_BITS+3)
- & RANGE_MASK];
- outptr[6] = range_limit[(int) DESCALE(tmp11 - tmp2,
- CONST_BITS+PASS1_BITS+3)
- & RANGE_MASK];
- outptr[2] = range_limit[(int) DESCALE(tmp12 + tmp1,
- CONST_BITS+PASS1_BITS+3)
- & RANGE_MASK];
- outptr[5] = range_limit[(int) DESCALE(tmp12 - tmp1,
- CONST_BITS+PASS1_BITS+3)
- & RANGE_MASK];
- outptr[3] = range_limit[(int) DESCALE(tmp13 + tmp0,
- CONST_BITS+PASS1_BITS+3)
- & RANGE_MASK];
- outptr[4] = range_limit[(int) DESCALE(tmp13 - tmp0,
- CONST_BITS+PASS1_BITS+3)
- & RANGE_MASK];
-
- wsptr += DCTSIZE; /* advance pointer to next row */
- }
- }
-
- #endif /* DCT_ISLOW_SUPPORTED */
- /********* End of inlined file: jidctint.c *********/
-
- /********* Start of inlined file: jidctred.c *********/
- #define JPEG_INTERNALS
-
- #ifdef IDCT_SCALING_SUPPORTED
-
- /*
- * This module is specialized to the case DCTSIZE = 8.
- */
-
- #if DCTSIZE != 8
- Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */
- #endif
-
- /* Scaling is the same as in jidctint.c. */
-
- #if BITS_IN_JSAMPLE == 8
- #define CONST_BITS 13
- #define PASS1_BITS 2
- #else
- #define CONST_BITS 13
- #define PASS1_BITS 1 /* lose a little precision to avoid overflow */
- #endif
-
- /* Some C compilers fail to reduce "FIX(constant)" at compile time, thus
- * causing a lot of useless floating-point operations at run time.
- * To get around this we use the following pre-calculated constants.
- * If you change CONST_BITS you may want to add appropriate values.
- * (With a reasonable C compiler, you can just rely on the FIX() macro...)
- */
-
- #if CONST_BITS == 13
- #define FIX_0_211164243 ((INT32) 1730) /* FIX(0.211164243) */
- #define FIX_0_509795579 ((INT32) 4176) /* FIX(0.509795579) */
- #define FIX_0_601344887 ((INT32) 4926) /* FIX(0.601344887) */
- #define FIX_0_720959822 ((INT32) 5906) /* FIX(0.720959822) */
- #define FIX_0_765366865 ((INT32) 6270) /* FIX(0.765366865) */
- #define FIX_0_850430095 ((INT32) 6967) /* FIX(0.850430095) */
- #define FIX_0_899976223 ((INT32) 7373) /* FIX(0.899976223) */
- #define FIX_1_061594337 ((INT32) 8697) /* FIX(1.061594337) */
- #define FIX_1_272758580 ((INT32) 10426) /* FIX(1.272758580) */
- #define FIX_1_451774981 ((INT32) 11893) /* FIX(1.451774981) */
- #define FIX_1_847759065 ((INT32) 15137) /* FIX(1.847759065) */
- #define FIX_2_172734803 ((INT32) 17799) /* FIX(2.172734803) */
- #define FIX_2_562915447 ((INT32) 20995) /* FIX(2.562915447) */
- #define FIX_3_624509785 ((INT32) 29692) /* FIX(3.624509785) */
- #else
- #define FIX_0_211164243 FIX(0.211164243)
- #define FIX_0_509795579 FIX(0.509795579)
- #define FIX_0_601344887 FIX(0.601344887)
- #define FIX_0_720959822 FIX(0.720959822)
- #define FIX_0_765366865 FIX(0.765366865)
- #define FIX_0_850430095 FIX(0.850430095)
- #define FIX_0_899976223 FIX(0.899976223)
- #define FIX_1_061594337 FIX(1.061594337)
- #define FIX_1_272758580 FIX(1.272758580)
- #define FIX_1_451774981 FIX(1.451774981)
- #define FIX_1_847759065 FIX(1.847759065)
- #define FIX_2_172734803 FIX(2.172734803)
- #define FIX_2_562915447 FIX(2.562915447)
- #define FIX_3_624509785 FIX(3.624509785)
- #endif
-
- /* Multiply an INT32 variable by an INT32 constant to yield an INT32 result.
- * For 8-bit samples with the recommended scaling, all the variable
- * and constant values involved are no more than 16 bits wide, so a
- * 16x16->32 bit multiply can be used instead of a full 32x32 multiply.
- * For 12-bit samples, a full 32-bit multiplication will be needed.
- */
-
- #if BITS_IN_JSAMPLE == 8
- #define MULTIPLY(var,const) MULTIPLY16C16(var,const)
- #else
- #define MULTIPLY(var,const) ((var) * (const))
- #endif
-
- /* Dequantize a coefficient by multiplying it by the multiplier-table
- * entry; produce an int result. In this module, both inputs and result
- * are 16 bits or less, so either int or short multiply will work.
- */
-
- #define DEQUANTIZE(coef,quantval) (((ISLOW_MULT_TYPE) (coef)) * (quantval))
-
- /*
- * Perform dequantization and inverse DCT on one block of coefficients,
- * producing a reduced-size 4x4 output block.
- */
-
- GLOBAL(void)
- jpeg_idct_4x4 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
- JCOEFPTR coef_block,
- JSAMPARRAY output_buf, JDIMENSION output_col)
- {
- INT32 tmp0, tmp2, tmp10, tmp12;
- INT32 z1, z2, z3, z4;
- JCOEFPTR inptr;
- ISLOW_MULT_TYPE * quantptr;
- int * wsptr;
- JSAMPROW outptr;
- JSAMPLE *range_limit = IDCT_range_limit(cinfo);
- int ctr;
- int workspace[DCTSIZE*4]; /* buffers data between passes */
- SHIFT_TEMPS
-
- /* Pass 1: process columns from input, store into work array. */
-
- inptr = coef_block;
- quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table;
- wsptr = workspace;
- for (ctr = DCTSIZE; ctr > 0; inptr++, quantptr++, wsptr++, ctr--) {
- /* Don't bother to process column 4, because second pass won't use it */
- if (ctr == DCTSIZE-4)
- continue;
- if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 &&
- inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*5] == 0 &&
- inptr[DCTSIZE*6] == 0 && inptr[DCTSIZE*7] == 0) {
- /* AC terms all zero; we need not examine term 4 for 4x4 output */
- int dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]) << PASS1_BITS;
-
- wsptr[DCTSIZE*0] = dcval;
- wsptr[DCTSIZE*1] = dcval;
- wsptr[DCTSIZE*2] = dcval;
- wsptr[DCTSIZE*3] = dcval;
-
- continue;
- }
-
- /* Even part */
-
- tmp0 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
- tmp0 <<= (CONST_BITS+1);
-
- z2 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]);
- z3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]);
-
- tmp2 = MULTIPLY(z2, FIX_1_847759065) + MULTIPLY(z3, - FIX_0_765366865);
-
- tmp10 = tmp0 + tmp2;
- tmp12 = tmp0 - tmp2;
-
- /* Odd part */
-
- z1 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]);
- z2 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]);
- z3 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]);
- z4 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]);
-
- tmp0 = MULTIPLY(z1, - FIX_0_211164243) /* sqrt(2) * (c3-c1) */
- + MULTIPLY(z2, FIX_1_451774981) /* sqrt(2) * (c3+c7) */
- + MULTIPLY(z3, - FIX_2_172734803) /* sqrt(2) * (-c1-c5) */
- + MULTIPLY(z4, FIX_1_061594337); /* sqrt(2) * (c5+c7) */
-
- tmp2 = MULTIPLY(z1, - FIX_0_509795579) /* sqrt(2) * (c7-c5) */
- + MULTIPLY(z2, - FIX_0_601344887) /* sqrt(2) * (c5-c1) */
- + MULTIPLY(z3, FIX_0_899976223) /* sqrt(2) * (c3-c7) */
- + MULTIPLY(z4, FIX_2_562915447); /* sqrt(2) * (c1+c3) */
-
- /* Final output stage */
-
- wsptr[DCTSIZE*0] = (int) DESCALE(tmp10 + tmp2, CONST_BITS-PASS1_BITS+1);
- wsptr[DCTSIZE*3] = (int) DESCALE(tmp10 - tmp2, CONST_BITS-PASS1_BITS+1);
- wsptr[DCTSIZE*1] = (int) DESCALE(tmp12 + tmp0, CONST_BITS-PASS1_BITS+1);
- wsptr[DCTSIZE*2] = (int) DESCALE(tmp12 - tmp0, CONST_BITS-PASS1_BITS+1);
- }
-
- /* Pass 2: process 4 rows from work array, store into output array. */
-
- wsptr = workspace;
- for (ctr = 0; ctr < 4; ctr++) {
- outptr = output_buf[ctr] + output_col;
- /* It's not clear whether a zero row test is worthwhile here ... */
-
- #ifndef NO_ZERO_ROW_TEST
- if (wsptr[1] == 0 && wsptr[2] == 0 && wsptr[3] == 0 &&
- wsptr[5] == 0 && wsptr[6] == 0 && wsptr[7] == 0) {
- /* AC terms all zero */
- JSAMPLE dcval = range_limit[(int) DESCALE((INT32) wsptr[0], PASS1_BITS+3)
- & RANGE_MASK];
-
- outptr[0] = dcval;
- outptr[1] = dcval;
- outptr[2] = dcval;
- outptr[3] = dcval;
-
- wsptr += DCTSIZE; /* advance pointer to next row */
- continue;
- }
- #endif
-
- /* Even part */
-
- tmp0 = ((INT32) wsptr[0]) << (CONST_BITS+1);
-
- tmp2 = MULTIPLY((INT32) wsptr[2], FIX_1_847759065)
- + MULTIPLY((INT32) wsptr[6], - FIX_0_765366865);
-
- tmp10 = tmp0 + tmp2;
- tmp12 = tmp0 - tmp2;
-
- /* Odd part */
-
- z1 = (INT32) wsptr[7];
- z2 = (INT32) wsptr[5];
- z3 = (INT32) wsptr[3];
- z4 = (INT32) wsptr[1];
-
- tmp0 = MULTIPLY(z1, - FIX_0_211164243) /* sqrt(2) * (c3-c1) */
- + MULTIPLY(z2, FIX_1_451774981) /* sqrt(2) * (c3+c7) */
- + MULTIPLY(z3, - FIX_2_172734803) /* sqrt(2) * (-c1-c5) */
- + MULTIPLY(z4, FIX_1_061594337); /* sqrt(2) * (c5+c7) */
-
- tmp2 = MULTIPLY(z1, - FIX_0_509795579) /* sqrt(2) * (c7-c5) */
- + MULTIPLY(z2, - FIX_0_601344887) /* sqrt(2) * (c5-c1) */
- + MULTIPLY(z3, FIX_0_899976223) /* sqrt(2) * (c3-c7) */
- + MULTIPLY(z4, FIX_2_562915447); /* sqrt(2) * (c1+c3) */
-
- /* Final output stage */
-
- outptr[0] = range_limit[(int) DESCALE(tmp10 + tmp2,
- CONST_BITS+PASS1_BITS+3+1)
- & RANGE_MASK];
- outptr[3] = range_limit[(int) DESCALE(tmp10 - tmp2,
- CONST_BITS+PASS1_BITS+3+1)
- & RANGE_MASK];
- outptr[1] = range_limit[(int) DESCALE(tmp12 + tmp0,
- CONST_BITS+PASS1_BITS+3+1)
- & RANGE_MASK];
- outptr[2] = range_limit[(int) DESCALE(tmp12 - tmp0,
- CONST_BITS+PASS1_BITS+3+1)
- & RANGE_MASK];
-
- wsptr += DCTSIZE; /* advance pointer to next row */
- }
- }
-
- /*
- * Perform dequantization and inverse DCT on one block of coefficients,
- * producing a reduced-size 2x2 output block.
- */
-
- GLOBAL(void)
- jpeg_idct_2x2 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
- JCOEFPTR coef_block,
- JSAMPARRAY output_buf, JDIMENSION output_col)
- {
- INT32 tmp0, tmp10, z1;
- JCOEFPTR inptr;
- ISLOW_MULT_TYPE * quantptr;
- int * wsptr;
- JSAMPROW outptr;
- JSAMPLE *range_limit = IDCT_range_limit(cinfo);
- int ctr;
- int workspace[DCTSIZE*2]; /* buffers data between passes */
- SHIFT_TEMPS
-
- /* Pass 1: process columns from input, store into work array. */
-
- inptr = coef_block;
- quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table;
- wsptr = workspace;
- for (ctr = DCTSIZE; ctr > 0; inptr++, quantptr++, wsptr++, ctr--) {
- /* Don't bother to process columns 2,4,6 */
- if (ctr == DCTSIZE-2 || ctr == DCTSIZE-4 || ctr == DCTSIZE-6)
- continue;
- if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*3] == 0 &&
- inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*7] == 0) {
- /* AC terms all zero; we need not examine terms 2,4,6 for 2x2 output */
- int dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]) << PASS1_BITS;
-
- wsptr[DCTSIZE*0] = dcval;
- wsptr[DCTSIZE*1] = dcval;
-
- continue;
- }
-
- /* Even part */
-
- z1 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
- tmp10 = z1 << (CONST_BITS+2);
-
- /* Odd part */
-
- z1 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]);
- tmp0 = MULTIPLY(z1, - FIX_0_720959822); /* sqrt(2) * (c7-c5+c3-c1) */
- z1 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]);
- tmp0 += MULTIPLY(z1, FIX_0_850430095); /* sqrt(2) * (-c1+c3+c5+c7) */
- z1 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]);
- tmp0 += MULTIPLY(z1, - FIX_1_272758580); /* sqrt(2) * (-c1+c3-c5-c7) */
- z1 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]);
- tmp0 += MULTIPLY(z1, FIX_3_624509785); /* sqrt(2) * (c1+c3+c5+c7) */
-
- /* Final output stage */
-
- wsptr[DCTSIZE*0] = (int) DESCALE(tmp10 + tmp0, CONST_BITS-PASS1_BITS+2);
- wsptr[DCTSIZE*1] = (int) DESCALE(tmp10 - tmp0, CONST_BITS-PASS1_BITS+2);
- }
-
- /* Pass 2: process 2 rows from work array, store into output array. */
-
- wsptr = workspace;
- for (ctr = 0; ctr < 2; ctr++) {
- outptr = output_buf[ctr] + output_col;
- /* It's not clear whether a zero row test is worthwhile here ... */
-
- #ifndef NO_ZERO_ROW_TEST
- if (wsptr[1] == 0 && wsptr[3] == 0 && wsptr[5] == 0 && wsptr[7] == 0) {
- /* AC terms all zero */
- JSAMPLE dcval = range_limit[(int) DESCALE((INT32) wsptr[0], PASS1_BITS+3)
- & RANGE_MASK];
-
- outptr[0] = dcval;
- outptr[1] = dcval;
-
- wsptr += DCTSIZE; /* advance pointer to next row */
- continue;
- }
- #endif
-
- /* Even part */
-
- tmp10 = ((INT32) wsptr[0]) << (CONST_BITS+2);
-
- /* Odd part */
-
- tmp0 = MULTIPLY((INT32) wsptr[7], - FIX_0_720959822) /* sqrt(2) * (c7-c5+c3-c1) */
- + MULTIPLY((INT32) wsptr[5], FIX_0_850430095) /* sqrt(2) * (-c1+c3+c5+c7) */
- + MULTIPLY((INT32) wsptr[3], - FIX_1_272758580) /* sqrt(2) * (-c1+c3-c5-c7) */
- + MULTIPLY((INT32) wsptr[1], FIX_3_624509785); /* sqrt(2) * (c1+c3+c5+c7) */
-
- /* Final output stage */
-
- outptr[0] = range_limit[(int) DESCALE(tmp10 + tmp0,
- CONST_BITS+PASS1_BITS+3+2)
- & RANGE_MASK];
- outptr[1] = range_limit[(int) DESCALE(tmp10 - tmp0,
- CONST_BITS+PASS1_BITS+3+2)
- & RANGE_MASK];
-
- wsptr += DCTSIZE; /* advance pointer to next row */
- }
- }
-
- /*
- * Perform dequantization and inverse DCT on one block of coefficients,
- * producing a reduced-size 1x1 output block.
- */
-
- GLOBAL(void)
- jpeg_idct_1x1 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
- JCOEFPTR coef_block,
- JSAMPARRAY output_buf, JDIMENSION output_col)
- {
- int dcval;
- ISLOW_MULT_TYPE * quantptr;
- JSAMPLE *range_limit = IDCT_range_limit(cinfo);
- SHIFT_TEMPS
-
- /* We hardly need an inverse DCT routine for this: just take the
- * average pixel value, which is one-eighth of the DC coefficient.
- */
- quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table;
- dcval = DEQUANTIZE(coef_block[0], quantptr[0]);
- dcval = (int) DESCALE((INT32) dcval, 3);
-
- output_buf[0][output_col] = range_limit[dcval & RANGE_MASK];
- }
-
- #endif /* IDCT_SCALING_SUPPORTED */
- /********* End of inlined file: jidctred.c *********/
-
- /********* Start of inlined file: jmemmgr.c *********/
- #define JPEG_INTERNALS
- #define AM_MEMORY_MANAGER /* we define jvirt_Xarray_control structs */
-
- /********* Start of inlined file: jmemsys.h *********/
- #ifndef __jmemsys_h__
- #define __jmemsys_h__
-
- /* Short forms of external names for systems with brain-damaged linkers. */
-
- #ifdef NEED_SHORT_EXTERNAL_NAMES
- #define jpeg_get_small jGetSmall
- #define jpeg_free_small jFreeSmall
- #define jpeg_get_large jGetLarge
- #define jpeg_free_large jFreeLarge
- #define jpeg_mem_available jMemAvail
- #define jpeg_open_backing_store jOpenBackStore
- #define jpeg_mem_init jMemInit
- #define jpeg_mem_term jMemTerm
- #endif /* NEED_SHORT_EXTERNAL_NAMES */
-
- /*
- * These two functions are used to allocate and release small chunks of
- * memory. (Typically the total amount requested through jpeg_get_small is
- * no more than 20K or so; this will be requested in chunks of a few K each.)
- * Behavior should be the same as for the standard library functions malloc
- * and free; in particular, jpeg_get_small must return NULL on failure.
- * On most systems, these ARE malloc and free. jpeg_free_small is passed the
- * size of the object being freed, just in case it's needed.
- * On an 80x86 machine using small-data memory model, these manage near heap.
- */
-
- EXTERN(void *) jpeg_get_small JPP((j_common_ptr cinfo, size_t sizeofobject));
- EXTERN(void) jpeg_free_small JPP((j_common_ptr cinfo, void * object,
- size_t sizeofobject));
-
- /*
- * These two functions are used to allocate and release large chunks of
- * memory (up to the total free space designated by jpeg_mem_available).
- * The interface is the same as above, except that on an 80x86 machine,
- * far pointers are used. On most other machines these are identical to
- * the jpeg_get/free_small routines; but we keep them separate anyway,
- * in case a different allocation strategy is desirable for large chunks.
- */
-
- EXTERN(void FAR *) jpeg_get_large JPP((j_common_ptr cinfo,
- size_t sizeofobject));
- EXTERN(void) jpeg_free_large JPP((j_common_ptr cinfo, void FAR * object,
- size_t sizeofobject));
-
- /*
- * The macro MAX_ALLOC_CHUNK designates the maximum number of bytes that may
- * be requested in a single call to jpeg_get_large (and jpeg_get_small for that
- * matter, but that case should never come into play). This macro is needed
- * to model the 64Kb-segment-size limit of far addressing on 80x86 machines.
- * On those machines, we expect that jconfig.h will provide a proper value.
- * On machines with 32-bit flat address spaces, any large constant may be used.
- *
- * NB: jmemmgr.c expects that MAX_ALLOC_CHUNK will be representable as type
- * size_t and will be a multiple of sizeof(align_type).
- */
-
- #ifndef MAX_ALLOC_CHUNK /* may be overridden in jconfig.h */
- #define MAX_ALLOC_CHUNK 1000000000L
- #endif
-
- /*
- * This routine computes the total space still available for allocation by
- * jpeg_get_large. If more space than this is needed, backing store will be
- * used. NOTE: any memory already allocated must not be counted.
- *
- * There is a minimum space requirement, corresponding to the minimum
- * feasible buffer sizes; jmemmgr.c will request that much space even if
- * jpeg_mem_available returns zero. The maximum space needed, enough to hold
- * all working storage in memory, is also passed in case it is useful.
- * Finally, the total space already allocated is passed. If no better
- * method is available, cinfo->mem->max_memory_to_use - already_allocated
- * is often a suitable calculation.
- *
- * It is OK for jpeg_mem_available to underestimate the space available
- * (that'll just lead to more backing-store access than is really necessary).
- * However, an overestimate will lead to failure. Hence it's wise to subtract
- * a slop factor from the true available space. 5% should be enough.
- *
- * On machines with lots of virtual memory, any large constant may be returned.
- * Conversely, zero may be returned to always use the minimum amount of memory.
- */
-
- EXTERN(long) jpeg_mem_available JPP((j_common_ptr cinfo,
- long min_bytes_needed,
- long max_bytes_needed,
- long already_allocated));
-
- /*
- * This structure holds whatever state is needed to access a single
- * backing-store object. The read/write/close method pointers are called
- * by jmemmgr.c to manipulate the backing-store object; all other fields
- * are private to the system-dependent backing store routines.
- */
-
- #define TEMP_NAME_LENGTH 64 /* max length of a temporary file's name */
-
- #ifdef USE_MSDOS_MEMMGR /* DOS-specific junk */
-
- typedef unsigned short XMSH; /* type of extended-memory handles */
- typedef unsigned short EMSH; /* type of expanded-memory handles */
-
- typedef union {
- short file_handle; /* DOS file handle if it's a temp file */
- XMSH xms_handle; /* handle if it's a chunk of XMS */
- EMSH ems_handle; /* handle if it's a chunk of EMS */
- } handle_union;
-
- #endif /* USE_MSDOS_MEMMGR */
-
- #ifdef USE_MAC_MEMMGR /* Mac-specific junk */
- #include <Files.h>
- #endif /* USE_MAC_MEMMGR */
-
- //typedef struct backing_store_struct * backing_store_ptr;
-
- typedef struct backing_store_struct {
- /* Methods for reading/writing/closing this backing-store object */
- JMETHOD(void, read_backing_store, (j_common_ptr cinfo,
- struct backing_store_struct *info,
- void FAR * buffer_address,
- long file_offset, long byte_count));
- JMETHOD(void, write_backing_store, (j_common_ptr cinfo,
- struct backing_store_struct *info,
- void FAR * buffer_address,
- long file_offset, long byte_count));
- JMETHOD(void, close_backing_store, (j_common_ptr cinfo,
- struct backing_store_struct *info));
-
- /* Private fields for system-dependent backing-store management */
- #ifdef USE_MSDOS_MEMMGR
- /* For the MS-DOS manager (jmemdos.c), we need: */
- handle_union handle; /* reference to backing-store storage object */
- char temp_name[TEMP_NAME_LENGTH]; /* name if it's a file */
- #else
- #ifdef USE_MAC_MEMMGR
- /* For the Mac manager (jmemmac.c), we need: */
- short temp_file; /* file reference number to temp file */
- FSSpec tempSpec; /* the FSSpec for the temp file */
- char temp_name[TEMP_NAME_LENGTH]; /* name if it's a file */
- #else
- /* For a typical implementation with temp files, we need: */
- FILE * temp_file; /* stdio reference to temp file */
- char temp_name[TEMP_NAME_LENGTH]; /* name of temp file */
- #endif
- #endif
- } backing_store_info;
-
- /*
- * Initial opening of a backing-store object. This must fill in the
- * read/write/close pointers in the object. The read/write routines
- * may take an error exit if the specified maximum file size is exceeded.
- * (If jpeg_mem_available always returns a large value, this routine can
- * just take an error exit.)
- */
-
- EXTERN(void) jpeg_open_backing_store JPP((j_common_ptr cinfo,
- struct backing_store_struct *info,
- long total_bytes_needed));
-
- /*
- * These routines take care of any system-dependent initialization and
- * cleanup required. jpeg_mem_init will be called before anything is
- * allocated (and, therefore, nothing in cinfo is of use except the error
- * manager pointer). It should return a suitable default value for
- * max_memory_to_use; this may subsequently be overridden by the surrounding
- * application. (Note that max_memory_to_use is only important if
- * jpeg_mem_available chooses to consult it ... no one else will.)
- * jpeg_mem_term may assume that all requested memory has been freed and that
- * all opened backing-store objects have been closed.
- */
-
- EXTERN(long) jpeg_mem_init JPP((j_common_ptr cinfo));
- EXTERN(void) jpeg_mem_term JPP((j_common_ptr cinfo));
-
- #endif
- /********* End of inlined file: jmemsys.h *********/
-
- /* import the system-dependent declarations */
-
- #ifndef NO_GETENV
- #ifndef HAVE_STDLIB_H /* <stdlib.h> should declare getenv() */
- extern char * getenv JPP((const char * name));
- #endif
- #endif
-
- /*
- * Some important notes:
- * The allocation routines provided here must never return NULL.
- * They should exit to error_exit if unsuccessful.
- *
- * It's not a good idea to try to merge the sarray and barray routines,
- * even though they are textually almost the same, because samples are
- * usually stored as bytes while coefficients are shorts or ints. Thus,
- * in machines where byte pointers have a different representation from
- * word pointers, the resulting machine code could not be the same.
- */
-
- /*
- * Many machines require storage alignment: longs must start on 4-byte
- * boundaries, doubles on 8-byte boundaries, etc. On such machines, malloc()
- * always returns pointers that are multiples of the worst-case alignment
- * requirement, and we had better do so too.
- * There isn't any really portable way to determine the worst-case alignment
- * requirement. This module assumes that the alignment requirement is
- * multiples of sizeof(ALIGN_TYPE).
- * By default, we define ALIGN_TYPE as double. This is necessary on some
- * workstations (where doubles really do need 8-byte alignment) and will work
- * fine on nearly everything. If your machine has lesser alignment needs,
- * you can save a few bytes by making ALIGN_TYPE smaller.
- * The only place I know of where this will NOT work is certain Macintosh
- * 680x0 compilers that define double as a 10-byte IEEE extended float.
- * Doing 10-byte alignment is counterproductive because longwords won't be
- * aligned well. Put "#define ALIGN_TYPE long" in jconfig.h if you have
- * such a compiler.
- */
-
- #ifndef ALIGN_TYPE /* so can override from jconfig.h */
- #define ALIGN_TYPE double
- #endif
-
- /*
- * We allocate objects from "pools", where each pool is gotten with a single
- * request to jpeg_get_small() or jpeg_get_large(). There is no per-object
- * overhead within a pool, except for alignment padding. Each pool has a
- * header with a link to the next pool of the same class.
- * Small and large pool headers are identical except that the latter's
- * link pointer must be FAR on 80x86 machines.
- * Notice that the "real" header fields are union'ed with a dummy ALIGN_TYPE
- * field. This forces the compiler to make SIZEOF(small_pool_hdr) a multiple
- * of the alignment requirement of ALIGN_TYPE.
- */
-
- typedef union small_pool_struct * small_pool_ptr;
-
- typedef union small_pool_struct {
- struct {
- small_pool_ptr next; /* next in list of pools */
- size_t bytes_used; /* how many bytes already used within pool */
- size_t bytes_left; /* bytes still available in this pool */
- } hdr;
- ALIGN_TYPE dummy; /* included in union to ensure alignment */
- } small_pool_hdr;
-
- typedef union large_pool_struct FAR * large_pool_ptr;
-
- typedef union large_pool_struct {
- struct {
- large_pool_ptr next; /* next in list of pools */
- size_t bytes_used; /* how many bytes already used within pool */
- size_t bytes_left; /* bytes still available in this pool */
- } hdr;
- ALIGN_TYPE dummy; /* included in union to ensure alignment */
- } large_pool_hdr;
-
- /*
- * Here is the full definition of a memory manager object.
- */
-
- typedef struct {
- struct jpeg_memory_mgr pub; /* public fields */
-
- /* Each pool identifier (lifetime class) names a linked list of pools. */
- small_pool_ptr small_list[JPOOL_NUMPOOLS];
- large_pool_ptr large_list[JPOOL_NUMPOOLS];
-
- /* Since we only have one lifetime class of virtual arrays, only one
- * linked list is necessary (for each datatype). Note that the virtual
- * array control blocks being linked together are actually stored somewhere
- * in the small-pool list.
- */
- jvirt_sarray_ptr virt_sarray_list;
- jvirt_barray_ptr virt_barray_list;
-
- /* This counts total space obtained from jpeg_get_small/large */
- long total_space_allocated;
-
- /* alloc_sarray and alloc_barray set this value for use by virtual
- * array routines.
- */
- JDIMENSION last_rowsperchunk; /* from most recent alloc_sarray/barray */
- } my_memory_mgr;
-
- typedef my_memory_mgr * my_mem_ptr;
-
- /*
- * The control blocks for virtual arrays.
- * Note that these blocks are allocated in the "small" pool area.
- * System-dependent info for the associated backing store (if any) is hidden
- * inside the backing_store_info struct.
- */
-
- struct jvirt_sarray_control {
- JSAMPARRAY mem_buffer; /* => the in-memory buffer */
- JDIMENSION rows_in_array; /* total virtual array height */
- JDIMENSION samplesperrow; /* width of array (and of memory buffer) */
- JDIMENSION maxaccess; /* max rows accessed by access_virt_sarray */
- JDIMENSION rows_in_mem; /* height of memory buffer */
- JDIMENSION rowsperchunk; /* allocation chunk size in mem_buffer */
- JDIMENSION cur_start_row; /* first logical row # in the buffer */
- JDIMENSION first_undef_row; /* row # of first uninitialized row */
- boolean pre_zero; /* pre-zero mode requested? */
- boolean dirty; /* do current buffer contents need written? */
- boolean b_s_open; /* is backing-store data valid? */
- jvirt_sarray_ptr next; /* link to next virtual sarray control block */
- backing_store_info b_s_info; /* System-dependent control info */
- };
-
- struct jvirt_barray_control {
- JBLOCKARRAY mem_buffer; /* => the in-memory buffer */
- JDIMENSION rows_in_array; /* total virtual array height */
- JDIMENSION blocksperrow; /* width of array (and of memory buffer) */
- JDIMENSION maxaccess; /* max rows accessed by access_virt_barray */
- JDIMENSION rows_in_mem; /* height of memory buffer */
- JDIMENSION rowsperchunk; /* allocation chunk size in mem_buffer */
- JDIMENSION cur_start_row; /* first logical row # in the buffer */
- JDIMENSION first_undef_row; /* row # of first uninitialized row */
- boolean pre_zero; /* pre-zero mode requested? */
- boolean dirty; /* do current buffer contents need written? */
- boolean b_s_open; /* is backing-store data valid? */
- jvirt_barray_ptr next; /* link to next virtual barray control block */
- backing_store_info b_s_info; /* System-dependent control info */
- };
-
- #ifdef MEM_STATS /* optional extra stuff for statistics */
-
- LOCAL(void)
- print_mem_stats (j_common_ptr cinfo, int pool_id)
- {
- my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
- small_pool_ptr shdr_ptr;
- large_pool_ptr lhdr_ptr;
-
- /* Since this is only a debugging stub, we can cheat a little by using
- * fprintf directly rather than going through the trace message code.
- * This is helpful because message parm array can't handle longs.
- */
- fprintf(stderr, "Freeing pool %d, total space = %ld\n",
- pool_id, mem->total_space_allocated);
-
- for (lhdr_ptr = mem->large_list[pool_id]; lhdr_ptr != NULL;
- lhdr_ptr = lhdr_ptr->hdr.next) {
- fprintf(stderr, " Large chunk used %ld\n",
- (long) lhdr_ptr->hdr.bytes_used);
- }
-
- for (shdr_ptr = mem->small_list[pool_id]; shdr_ptr != NULL;
- shdr_ptr = shdr_ptr->hdr.next) {
- fprintf(stderr, " Small chunk used %ld free %ld\n",
- (long) shdr_ptr->hdr.bytes_used,
- (long) shdr_ptr->hdr.bytes_left);
- }
- }
-
- #endif /* MEM_STATS */
-
- LOCAL(void)
- out_of_memory (j_common_ptr cinfo, int which)
- /* Report an out-of-memory error and stop execution */
- /* If we compiled MEM_STATS support, report alloc requests before dying */
- {
- #ifdef MEM_STATS
- cinfo->err->trace_level = 2; /* force self_destruct to report stats */
- #endif
- ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, which);
- }
-
- /*
- * Allocation of "small" objects.
- *
- * For these, we use pooled storage. When a new pool must be created,
- * we try to get enough space for the current request plus a "slop" factor,
- * where the slop will be the amount of leftover space in the new pool.
- * The speed vs. space tradeoff is largely determined by the slop values.
- * A different slop value is provided for each pool class (lifetime),
- * and we also distinguish the first pool of a class from later ones.
- * NOTE: the values given work fairly well on both 16- and 32-bit-int
- * machines, but may be too small if longs are 64 bits or more.
- */
-
- static const size_t first_pool_slop[JPOOL_NUMPOOLS] =
- {
- 1600, /* first PERMANENT pool */
- 16000 /* first IMAGE pool */
- };
-
- static const size_t extra_pool_slop[JPOOL_NUMPOOLS] =
- {
- 0, /* additional PERMANENT pools */
- 5000 /* additional IMAGE pools */
- };
-
- #define MIN_SLOP 50 /* greater than 0 to avoid futile looping */
-
- METHODDEF(void *)
- alloc_small (j_common_ptr cinfo, int pool_id, size_t sizeofobject)
- /* Allocate a "small" object */
- {
- my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
- small_pool_ptr hdr_ptr, prev_hdr_ptr;
- char * data_ptr;
- size_t odd_bytes, min_request, slop;
-
- /* Check for unsatisfiable request (do now to ensure no overflow below) */
- if (sizeofobject > (size_t) (MAX_ALLOC_CHUNK-SIZEOF(small_pool_hdr)))
- out_of_memory(cinfo, 1); /* request exceeds malloc's ability */
-
- /* Round up the requested size to a multiple of SIZEOF(ALIGN_TYPE) */
- odd_bytes = sizeofobject % SIZEOF(ALIGN_TYPE);
- if (odd_bytes > 0)
- sizeofobject += SIZEOF(ALIGN_TYPE) - odd_bytes;
-
- /* See if space is available in any existing pool */
- if (pool_id < 0 || pool_id >= JPOOL_NUMPOOLS)
- ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */
- prev_hdr_ptr = NULL;
- hdr_ptr = mem->small_list[pool_id];
- while (hdr_ptr != NULL) {
- if (hdr_ptr->hdr.bytes_left >= sizeofobject)
- break; /* found pool with enough space */
- prev_hdr_ptr = hdr_ptr;
- hdr_ptr = hdr_ptr->hdr.next;
- }
-
- /* Time to make a new pool? */
- if (hdr_ptr == NULL) {
- /* min_request is what we need now, slop is what will be leftover */
- min_request = sizeofobject + SIZEOF(small_pool_hdr);
- if (prev_hdr_ptr == NULL) /* first pool in class? */
- slop = first_pool_slop[pool_id];
- else
- slop = extra_pool_slop[pool_id];
- /* Don't ask for more than MAX_ALLOC_CHUNK */
- if (slop > (size_t) (MAX_ALLOC_CHUNK-min_request))
- slop = (size_t) (MAX_ALLOC_CHUNK-min_request);
- /* Try to get space, if fail reduce slop and try again */
- for (;;) {
- hdr_ptr = (small_pool_ptr) jpeg_get_small(cinfo, min_request + slop);
- if (hdr_ptr != NULL)
- break;
- slop /= 2;
- if (slop < MIN_SLOP) /* give up when it gets real small */
- out_of_memory(cinfo, 2); /* jpeg_get_small failed */
- }
- mem->total_space_allocated += min_request + slop;
- /* Success, initialize the new pool header and add to end of list */
- hdr_ptr->hdr.next = NULL;
- hdr_ptr->hdr.bytes_used = 0;
- hdr_ptr->hdr.bytes_left = sizeofobject + slop;
- if (prev_hdr_ptr == NULL) /* first pool in class? */
- mem->small_list[pool_id] = hdr_ptr;
- else
- prev_hdr_ptr->hdr.next = hdr_ptr;
- }
-
- /* OK, allocate the object from the current pool */
- data_ptr = (char *) (hdr_ptr + 1); /* point to first data byte in pool */
- data_ptr += hdr_ptr->hdr.bytes_used; /* point to place for object */
- hdr_ptr->hdr.bytes_used += sizeofobject;
- hdr_ptr->hdr.bytes_left -= sizeofobject;
-
- return (void *) data_ptr;
- }
-
- /*
- * Allocation of "large" objects.
- *
- * The external semantics of these are the same as "small" objects,
- * except that FAR pointers are used on 80x86. However the pool
- * management heuristics are quite different. We assume that each
- * request is large enough that it may as well be passed directly to
- * jpeg_get_large; the pool management just links everything together
- * so that we can free it all on demand.
- * Note: the major use of "large" objects is in JSAMPARRAY and JBLOCKARRAY
- * structures. The routines that create these structures (see below)
- * deliberately bunch rows together to ensure a large request size.
- */
-
- METHODDEF(void FAR *)
- alloc_large (j_common_ptr cinfo, int pool_id, size_t sizeofobject)
- /* Allocate a "large" object */
- {
- my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
- large_pool_ptr hdr_ptr;
- size_t odd_bytes;
-
- /* Check for unsatisfiable request (do now to ensure no overflow below) */
- if (sizeofobject > (size_t) (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr)))
- out_of_memory(cinfo, 3); /* request exceeds malloc's ability */
-
- /* Round up the requested size to a multiple of SIZEOF(ALIGN_TYPE) */
- odd_bytes = sizeofobject % SIZEOF(ALIGN_TYPE);
- if (odd_bytes > 0)
- sizeofobject += SIZEOF(ALIGN_TYPE) - odd_bytes;
-
- /* Always make a new pool */
- if (pool_id < 0 || pool_id >= JPOOL_NUMPOOLS)
- ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */
-
- hdr_ptr = (large_pool_ptr) jpeg_get_large(cinfo, sizeofobject +
- SIZEOF(large_pool_hdr));
- if (hdr_ptr == NULL)
- out_of_memory(cinfo, 4); /* jpeg_get_large failed */
- mem->total_space_allocated += sizeofobject + SIZEOF(large_pool_hdr);
-
- /* Success, initialize the new pool header and add to list */
- hdr_ptr->hdr.next = mem->large_list[pool_id];
- /* We maintain space counts in each pool header for statistical purposes,
- * even though they are not needed for allocation.
- */
- hdr_ptr->hdr.bytes_used = sizeofobject;
- hdr_ptr->hdr.bytes_left = 0;
- mem->large_list[pool_id] = hdr_ptr;
-
- return (void FAR *) (hdr_ptr + 1); /* point to first data byte in pool */
- }
-
- /*
- * Creation of 2-D sample arrays.
- * The pointers are in near heap, the samples themselves in FAR heap.
- *
- * To minimize allocation overhead and to allow I/O of large contiguous
- * blocks, we allocate the sample rows in groups of as many rows as possible
- * without exceeding MAX_ALLOC_CHUNK total bytes per allocation request.
- * NB: the virtual array control routines, later in this file, know about
- * this chunking of rows. The rowsperchunk value is left in the mem manager
- * object so that it can be saved away if this sarray is the workspace for
- * a virtual array.
- */
-
- METHODDEF(JSAMPARRAY)
- alloc_sarray (j_common_ptr cinfo, int pool_id,
- JDIMENSION samplesperrow, JDIMENSION numrows)
- /* Allocate a 2-D sample array */
- {
- my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
- JSAMPARRAY result;
- JSAMPROW workspace;
- JDIMENSION rowsperchunk, currow, i;
- long ltemp;
-
- /* Calculate max # of rows allowed in one allocation chunk */
- ltemp = (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr)) /
- ((long) samplesperrow * SIZEOF(JSAMPLE));
- if (ltemp <= 0)
- ERREXIT(cinfo, JERR_WIDTH_OVERFLOW);
- if (ltemp < (long) numrows)
- rowsperchunk = (JDIMENSION) ltemp;
- else
- rowsperchunk = numrows;
- mem->last_rowsperchunk = rowsperchunk;
-
- /* Get space for row pointers (small object) */
- result = (JSAMPARRAY) alloc_small(cinfo, pool_id,
- (size_t) (numrows * SIZEOF(JSAMPROW)));
-
- /* Get the rows themselves (large objects) */
- currow = 0;
- while (currow < numrows) {
- rowsperchunk = MIN(rowsperchunk, numrows - currow);
- workspace = (JSAMPROW) alloc_large(cinfo, pool_id,
- (size_t) ((size_t) rowsperchunk * (size_t) samplesperrow
- * SIZEOF(JSAMPLE)));
- for (i = rowsperchunk; i > 0; i--) {
- result[currow++] = workspace;
- workspace += samplesperrow;
- }
- }
-
- return result;
- }
-
- /*
- * Creation of 2-D coefficient-block arrays.
- * This is essentially the same as the code for sample arrays, above.
- */
-
- METHODDEF(JBLOCKARRAY)
- alloc_barray (j_common_ptr cinfo, int pool_id,
- JDIMENSION blocksperrow, JDIMENSION numrows)
- /* Allocate a 2-D coefficient-block array */
- {
- my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
- JBLOCKARRAY result;
- JBLOCKROW workspace;
- JDIMENSION rowsperchunk, currow, i;
- long ltemp;
-
- /* Calculate max # of rows allowed in one allocation chunk */
- ltemp = (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr)) /
- ((long) blocksperrow * SIZEOF(JBLOCK));
- if (ltemp <= 0)
- ERREXIT(cinfo, JERR_WIDTH_OVERFLOW);
- if (ltemp < (long) numrows)
- rowsperchunk = (JDIMENSION) ltemp;
- else
- rowsperchunk = numrows;
- mem->last_rowsperchunk = rowsperchunk;
-
- /* Get space for row pointers (small object) */
- result = (JBLOCKARRAY) alloc_small(cinfo, pool_id,
- (size_t) (numrows * SIZEOF(JBLOCKROW)));
-
- /* Get the rows themselves (large objects) */
- currow = 0;
- while (currow < numrows) {
- rowsperchunk = MIN(rowsperchunk, numrows - currow);
- workspace = (JBLOCKROW) alloc_large(cinfo, pool_id,
- (size_t) ((size_t) rowsperchunk * (size_t) blocksperrow
- * SIZEOF(JBLOCK)));
- for (i = rowsperchunk; i > 0; i--) {
- result[currow++] = workspace;
- workspace += blocksperrow;
- }
- }
-
- return result;
- }
-
- /*
- * About virtual array management:
- *
- * The above "normal" array routines are only used to allocate strip buffers
- * (as wide as the image, but just a few rows high). Full-image-sized buffers
- * are handled as "virtual" arrays. The array is still accessed a strip at a
- * time, but the memory manager must save the whole array for repeated
- * accesses. The intended implementation is that there is a strip buffer in
- * memory (as high as is possible given the desired memory limit), plus a
- * backing file that holds the rest of the array.
- *
- * The request_virt_array routines are told the total size of the image and
- * the maximum number of rows that will be accessed at once. The in-memory
- * buffer must be at least as large as the maxaccess value.
- *
- * The request routines create control blocks but not the in-memory buffers.
- * That is postponed until realize_virt_arrays is called. At that time the
- * total amount of space needed is known (approximately, anyway), so free
- * memory can be divided up fairly.
- *
- * The access_virt_array routines are responsible for making a specific strip
- * area accessible (after reading or writing the backing file, if necessary).
- * Note that the access routines are told whether the caller intends to modify
- * the accessed strip; during a read-only pass this saves having to rewrite
- * data to disk. The access routines are also responsible for pre-zeroing
- * any newly accessed rows, if pre-zeroing was requested.
- *
- * In current usage, the access requests are usually for nonoverlapping
- * strips; that is, successive access start_row numbers differ by exactly
- * num_rows = maxaccess. This means we can get good performance with simple
- * buffer dump/reload logic, by making the in-memory buffer be a multiple
- * of the access height; then there will never be accesses across bufferload
- * boundaries. The code will still work with overlapping access requests,
- * but it doesn't handle bufferload overlaps very efficiently.
- */
-
- METHODDEF(jvirt_sarray_ptr)
- request_virt_sarray (j_common_ptr cinfo, int pool_id, boolean pre_zero,
- JDIMENSION samplesperrow, JDIMENSION numrows,
- JDIMENSION maxaccess)
- /* Request a virtual 2-D sample array */
- {
- my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
- jvirt_sarray_ptr result;
-
- /* Only IMAGE-lifetime virtual arrays are currently supported */
- if (pool_id != JPOOL_IMAGE)
- ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */
-
- /* get control block */
- result = (jvirt_sarray_ptr) alloc_small(cinfo, pool_id,
- SIZEOF(struct jvirt_sarray_control));
-
- result->mem_buffer = NULL; /* marks array not yet realized */
- result->rows_in_array = numrows;
- result->samplesperrow = samplesperrow;
- result->maxaccess = maxaccess;
- result->pre_zero = pre_zero;
- result->b_s_open = FALSE; /* no associated backing-store object */
- result->next = mem->virt_sarray_list; /* add to list of virtual arrays */
- mem->virt_sarray_list = result;
-
- return result;
- }
-
- METHODDEF(jvirt_barray_ptr)
- request_virt_barray (j_common_ptr cinfo, int pool_id, boolean pre_zero,
- JDIMENSION blocksperrow, JDIMENSION numrows,
- JDIMENSION maxaccess)
- /* Request a virtual 2-D coefficient-block array */
- {
- my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
- jvirt_barray_ptr result;
-
- /* Only IMAGE-lifetime virtual arrays are currently supported */
- if (pool_id != JPOOL_IMAGE)
- ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */
-
- /* get control block */
- result = (jvirt_barray_ptr) alloc_small(cinfo, pool_id,
- SIZEOF(struct jvirt_barray_control));
-
- result->mem_buffer = NULL; /* marks array not yet realized */
- result->rows_in_array = numrows;
- result->blocksperrow = blocksperrow;
- result->maxaccess = maxaccess;
- result->pre_zero = pre_zero;
- result->b_s_open = FALSE; /* no associated backing-store object */
- result->next = mem->virt_barray_list; /* add to list of virtual arrays */
- mem->virt_barray_list = result;
-
- return result;
- }
-
- METHODDEF(void)
- realize_virt_arrays (j_common_ptr cinfo)
- /* Allocate the in-memory buffers for any unrealized virtual arrays */
- {
- my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
- long space_per_minheight, maximum_space, avail_mem;
- long minheights, max_minheights;
- jvirt_sarray_ptr sptr;
- jvirt_barray_ptr bptr;
-
- /* Compute the minimum space needed (maxaccess rows in each buffer)
- * and the maximum space needed (full image height in each buffer).
- * These may be of use to the system-dependent jpeg_mem_available routine.
- */
- space_per_minheight = 0;
- maximum_space = 0;
- for (sptr = mem->virt_sarray_list; sptr != NULL; sptr = sptr->next) {
- if (sptr->mem_buffer == NULL) { /* if not realized yet */
- space_per_minheight += (long) sptr->maxaccess *
- (long) sptr->samplesperrow * SIZEOF(JSAMPLE);
- maximum_space += (long) sptr->rows_in_array *
- (long) sptr->samplesperrow * SIZEOF(JSAMPLE);
- }
- }
- for (bptr = mem->virt_barray_list; bptr != NULL; bptr = bptr->next) {
- if (bptr->mem_buffer == NULL) { /* if not realized yet */
- space_per_minheight += (long) bptr->maxaccess *
- (long) bptr->blocksperrow * SIZEOF(JBLOCK);
- maximum_space += (long) bptr->rows_in_array *
- (long) bptr->blocksperrow * SIZEOF(JBLOCK);
- }
- }
-
- if (space_per_minheight <= 0)
- return; /* no unrealized arrays, no work */
-
- /* Determine amount of memory to actually use; this is system-dependent. */
- avail_mem = jpeg_mem_available(cinfo, space_per_minheight, maximum_space,
- mem->total_space_allocated);
-
- /* If the maximum space needed is available, make all the buffers full
- * height; otherwise parcel it out with the same number of minheights
- * in each buffer.
- */
- if (avail_mem >= maximum_space)
- max_minheights = 1000000000L;
- else {
- max_minheights = avail_mem / space_per_minheight;
- /* If there doesn't seem to be enough space, try to get the minimum
- * anyway. This allows a "stub" implementation of jpeg_mem_available().
- */
- if (max_minheights <= 0)
- max_minheights = 1;
- }
-
- /* Allocate the in-memory buffers and initialize backing store as needed. */
-
- for (sptr = mem->virt_sarray_list; sptr != NULL; sptr = sptr->next) {
- if (sptr->mem_buffer == NULL) { /* if not realized yet */
- minheights = ((long) sptr->rows_in_array - 1L) / sptr->maxaccess + 1L;
- if (minheights <= max_minheights) {
- /* This buffer fits in memory */
- sptr->rows_in_mem = sptr->rows_in_array;
- } else {
- /* It doesn't fit in memory, create backing store. */
- sptr->rows_in_mem = (JDIMENSION) (max_minheights * sptr->maxaccess);
- jpeg_open_backing_store(cinfo, & sptr->b_s_info,
- (long) sptr->rows_in_array *
- (long) sptr->samplesperrow *
- (long) SIZEOF(JSAMPLE));
- sptr->b_s_open = TRUE;
- }
- sptr->mem_buffer = alloc_sarray(cinfo, JPOOL_IMAGE,
- sptr->samplesperrow, sptr->rows_in_mem);
- sptr->rowsperchunk = mem->last_rowsperchunk;
- sptr->cur_start_row = 0;
- sptr->first_undef_row = 0;
- sptr->dirty = FALSE;
- }
- }
-
- for (bptr = mem->virt_barray_list; bptr != NULL; bptr = bptr->next) {
- if (bptr->mem_buffer == NULL) { /* if not realized yet */
- minheights = ((long) bptr->rows_in_array - 1L) / bptr->maxaccess + 1L;
- if (minheights <= max_minheights) {
- /* This buffer fits in memory */
- bptr->rows_in_mem = bptr->rows_in_array;
- } else {
- /* It doesn't fit in memory, create backing store. */
- bptr->rows_in_mem = (JDIMENSION) (max_minheights * bptr->maxaccess);
- jpeg_open_backing_store(cinfo, & bptr->b_s_info,
- (long) bptr->rows_in_array *
- (long) bptr->blocksperrow *
- (long) SIZEOF(JBLOCK));
- bptr->b_s_open = TRUE;
- }
- bptr->mem_buffer = alloc_barray(cinfo, JPOOL_IMAGE,
- bptr->blocksperrow, bptr->rows_in_mem);
- bptr->rowsperchunk = mem->last_rowsperchunk;
- bptr->cur_start_row = 0;
- bptr->first_undef_row = 0;
- bptr->dirty = FALSE;
- }
- }
- }
-
- LOCAL(void)
- do_sarray_io (j_common_ptr cinfo, jvirt_sarray_ptr ptr, boolean writing)
- /* Do backing store read or write of a virtual sample array */
- {
- long bytesperrow, file_offset, byte_count, rows, thisrow, i;
-
- bytesperrow = (long) ptr->samplesperrow * SIZEOF(JSAMPLE);
- file_offset = ptr->cur_start_row * bytesperrow;
- /* Loop to read or write each allocation chunk in mem_buffer */
- for (i = 0; i < (long) ptr->rows_in_mem; i += ptr->rowsperchunk) {
- /* One chunk, but check for short chunk at end of buffer */
- rows = MIN((long) ptr->rowsperchunk, (long) ptr->rows_in_mem - i);
- /* Transfer no more than is currently defined */
- thisrow = (long) ptr->cur_start_row + i;
- rows = MIN(rows, (long) ptr->first_undef_row - thisrow);
- /* Transfer no more than fits in file */
- rows = MIN(rows, (long) ptr->rows_in_array - thisrow);
- if (rows <= 0) /* this chunk might be past end of file! */
- break;
- byte_count = rows * bytesperrow;
- if (writing)
- (*ptr->b_s_info.write_backing_store) (cinfo, & ptr->b_s_info,
- (void FAR *) ptr->mem_buffer[i],
- file_offset, byte_count);
- else
- (*ptr->b_s_info.read_backing_store) (cinfo, & ptr->b_s_info,
- (void FAR *) ptr->mem_buffer[i],
- file_offset, byte_count);
- file_offset += byte_count;
- }
- }
-
- LOCAL(void)
- do_barray_io (j_common_ptr cinfo, jvirt_barray_ptr ptr, boolean writing)
- /* Do backing store read or write of a virtual coefficient-block array */
- {
- long bytesperrow, file_offset, byte_count, rows, thisrow, i;
-
- bytesperrow = (long) ptr->blocksperrow * SIZEOF(JBLOCK);
- file_offset = ptr->cur_start_row * bytesperrow;
- /* Loop to read or write each allocation chunk in mem_buffer */
- for (i = 0; i < (long) ptr->rows_in_mem; i += ptr->rowsperchunk) {
- /* One chunk, but check for short chunk at end of buffer */
- rows = MIN((long) ptr->rowsperchunk, (long) ptr->rows_in_mem - i);
- /* Transfer no more than is currently defined */
- thisrow = (long) ptr->cur_start_row + i;
- rows = MIN(rows, (long) ptr->first_undef_row - thisrow);
- /* Transfer no more than fits in file */
- rows = MIN(rows, (long) ptr->rows_in_array - thisrow);
- if (rows <= 0) /* this chunk might be past end of file! */
- break;
- byte_count = rows * bytesperrow;
- if (writing)
- (*ptr->b_s_info.write_backing_store) (cinfo, & ptr->b_s_info,
- (void FAR *) ptr->mem_buffer[i],
- file_offset, byte_count);
- else
- (*ptr->b_s_info.read_backing_store) (cinfo, & ptr->b_s_info,
- (void FAR *) ptr->mem_buffer[i],
- file_offset, byte_count);
- file_offset += byte_count;
- }
- }
-
- METHODDEF(JSAMPARRAY)
- access_virt_sarray (j_common_ptr cinfo, jvirt_sarray_ptr ptr,
- JDIMENSION start_row, JDIMENSION num_rows,
- boolean writable)
- /* Access the part of a virtual sample array starting at start_row */
- /* and extending for num_rows rows. writable is true if */
- /* caller intends to modify the accessed area. */
- {
- JDIMENSION end_row = start_row + num_rows;
- JDIMENSION undef_row;
-
- /* debugging check */
- if (end_row > ptr->rows_in_array || num_rows > ptr->maxaccess ||
- ptr->mem_buffer == NULL)
- ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS);
-
- /* Make the desired part of the virtual array accessible */
- if (start_row < ptr->cur_start_row ||
- end_row > ptr->cur_start_row+ptr->rows_in_mem) {
- if (! ptr->b_s_open)
- ERREXIT(cinfo, JERR_VIRTUAL_BUG);
- /* Flush old buffer contents if necessary */
- if (ptr->dirty) {
- do_sarray_io(cinfo, ptr, TRUE);
- ptr->dirty = FALSE;
- }
- /* Decide what part of virtual array to access.
- * Algorithm: if target address > current window, assume forward scan,
- * load starting at target address. If target address < current window,
- * assume backward scan, load so that target area is top of window.
- * Note that when switching from forward write to forward read, will have
- * start_row = 0, so the limiting case applies and we load from 0 anyway.
- */
- if (start_row > ptr->cur_start_row) {
- ptr->cur_start_row = start_row;
- } else {
- /* use long arithmetic here to avoid overflow & unsigned problems */
- long ltemp;
-
- ltemp = (long) end_row - (long) ptr->rows_in_mem;
- if (ltemp < 0)
- ltemp = 0; /* don't fall off front end of file */
- ptr->cur_start_row = (JDIMENSION) ltemp;
- }
- /* Read in the selected part of the array.
- * During the initial write pass, we will do no actual read
- * because the selected part is all undefined.
- */
- do_sarray_io(cinfo, ptr, FALSE);
- }
- /* Ensure the accessed part of the array is defined; prezero if needed.
- * To improve locality of access, we only prezero the part of the array
- * that the caller is about to access, not the entire in-memory array.
- */
- if (ptr->first_undef_row < end_row) {
- if (ptr->first_undef_row < start_row) {
- if (writable) /* writer skipped over a section of array */
- ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS);
- undef_row = start_row; /* but reader is allowed to read ahead */
- } else {
- undef_row = ptr->first_undef_row;
- }
- if (writable)
- ptr->first_undef_row = end_row;
- if (ptr->pre_zero) {
- size_t bytesperrow = (size_t) ptr->samplesperrow * SIZEOF(JSAMPLE);
- undef_row -= ptr->cur_start_row; /* make indexes relative to buffer */
- end_row -= ptr->cur_start_row;
- while (undef_row < end_row) {
- jzero_far((void FAR *) ptr->mem_buffer[undef_row], bytesperrow);
- undef_row++;
- }
- } else {
- if (! writable) /* reader looking at undefined data */
- ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS);
- }
- }
- /* Flag the buffer dirty if caller will write in it */
- if (writable)
- ptr->dirty = TRUE;
- /* Return address of proper part of the buffer */
- return ptr->mem_buffer + (start_row - ptr->cur_start_row);
- }
-
- METHODDEF(JBLOCKARRAY)
- access_virt_barray (j_common_ptr cinfo, jvirt_barray_ptr ptr,
- JDIMENSION start_row, JDIMENSION num_rows,
- boolean writable)
- /* Access the part of a virtual block array starting at start_row */
- /* and extending for num_rows rows. writable is true if */
- /* caller intends to modify the accessed area. */
- {
- JDIMENSION end_row = start_row + num_rows;
- JDIMENSION undef_row;
-
- /* debugging check */
- if (end_row > ptr->rows_in_array || num_rows > ptr->maxaccess ||
- ptr->mem_buffer == NULL)
- ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS);
-
- /* Make the desired part of the virtual array accessible */
- if (start_row < ptr->cur_start_row ||
- end_row > ptr->cur_start_row+ptr->rows_in_mem) {
- if (! ptr->b_s_open)
- ERREXIT(cinfo, JERR_VIRTUAL_BUG);
- /* Flush old buffer contents if necessary */
- if (ptr->dirty) {
- do_barray_io(cinfo, ptr, TRUE);
- ptr->dirty = FALSE;
- }
- /* Decide what part of virtual array to access.
- * Algorithm: if target address > current window, assume forward scan,
- * load starting at target address. If target address < current window,
- * assume backward scan, load so that target area is top of window.
- * Note that when switching from forward write to forward read, will have
- * start_row = 0, so the limiting case applies and we load from 0 anyway.
- */
- if (start_row > ptr->cur_start_row) {
- ptr->cur_start_row = start_row;
- } else {
- /* use long arithmetic here to avoid overflow & unsigned problems */
- long ltemp;
-
- ltemp = (long) end_row - (long) ptr->rows_in_mem;
- if (ltemp < 0)
- ltemp = 0; /* don't fall off front end of file */
- ptr->cur_start_row = (JDIMENSION) ltemp;
- }
- /* Read in the selected part of the array.
- * During the initial write pass, we will do no actual read
- * because the selected part is all undefined.
- */
- do_barray_io(cinfo, ptr, FALSE);
- }
- /* Ensure the accessed part of the array is defined; prezero if needed.
- * To improve locality of access, we only prezero the part of the array
- * that the caller is about to access, not the entire in-memory array.
- */
- if (ptr->first_undef_row < end_row) {
- if (ptr->first_undef_row < start_row) {
- if (writable) /* writer skipped over a section of array */
- ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS);
- undef_row = start_row; /* but reader is allowed to read ahead */
- } else {
- undef_row = ptr->first_undef_row;
- }
- if (writable)
- ptr->first_undef_row = end_row;
- if (ptr->pre_zero) {
- size_t bytesperrow = (size_t) ptr->blocksperrow * SIZEOF(JBLOCK);
- undef_row -= ptr->cur_start_row; /* make indexes relative to buffer */
- end_row -= ptr->cur_start_row;
- while (undef_row < end_row) {
- jzero_far((void FAR *) ptr->mem_buffer[undef_row], bytesperrow);
- undef_row++;
- }
- } else {
- if (! writable) /* reader looking at undefined data */
- ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS);
- }
- }
- /* Flag the buffer dirty if caller will write in it */
- if (writable)
- ptr->dirty = TRUE;
- /* Return address of proper part of the buffer */
- return ptr->mem_buffer + (start_row - ptr->cur_start_row);
- }
-
- /*
- * Release all objects belonging to a specified pool.
- */
-
- METHODDEF(void)
- free_pool (j_common_ptr cinfo, int pool_id)
- {
- my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
- small_pool_ptr shdr_ptr;
- large_pool_ptr lhdr_ptr;
- size_t space_freed;
-
- if (pool_id < 0 || pool_id >= JPOOL_NUMPOOLS)
- ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */
-
- #ifdef MEM_STATS
- if (cinfo->err->trace_level > 1)
- print_mem_stats(cinfo, pool_id); /* print pool's memory usage statistics */
- #endif
-
- /* If freeing IMAGE pool, close any virtual arrays first */
- if (pool_id == JPOOL_IMAGE) {
- jvirt_sarray_ptr sptr;
- jvirt_barray_ptr bptr;
-
- for (sptr = mem->virt_sarray_list; sptr != NULL; sptr = sptr->next) {
- if (sptr->b_s_open) { /* there may be no backing store */
- sptr->b_s_open = FALSE; /* prevent recursive close if error */
- (*sptr->b_s_info.close_backing_store) (cinfo, & sptr->b_s_info);
- }
- }
- mem->virt_sarray_list = NULL;
- for (bptr = mem->virt_barray_list; bptr != NULL; bptr = bptr->next) {
- if (bptr->b_s_open) { /* there may be no backing store */
- bptr->b_s_open = FALSE; /* prevent recursive close if error */
- (*bptr->b_s_info.close_backing_store) (cinfo, & bptr->b_s_info);
- }
- }
- mem->virt_barray_list = NULL;
- }
-
- /* Release large objects */
- lhdr_ptr = mem->large_list[pool_id];
- mem->large_list[pool_id] = NULL;
-
- while (lhdr_ptr != NULL) {
- large_pool_ptr next_lhdr_ptr = lhdr_ptr->hdr.next;
- space_freed = lhdr_ptr->hdr.bytes_used +
- lhdr_ptr->hdr.bytes_left +
- SIZEOF(large_pool_hdr);
- jpeg_free_large(cinfo, (void FAR *) lhdr_ptr, space_freed);
- mem->total_space_allocated -= space_freed;
- lhdr_ptr = next_lhdr_ptr;
- }
-
- /* Release small objects */
- shdr_ptr = mem->small_list[pool_id];
- mem->small_list[pool_id] = NULL;
-
- while (shdr_ptr != NULL) {
- small_pool_ptr next_shdr_ptr = shdr_ptr->hdr.next;
- space_freed = shdr_ptr->hdr.bytes_used +
- shdr_ptr->hdr.bytes_left +
- SIZEOF(small_pool_hdr);
- jpeg_free_small(cinfo, (void *) shdr_ptr, space_freed);
- mem->total_space_allocated -= space_freed;
- shdr_ptr = next_shdr_ptr;
- }
- }
-
- /*
- * Close up shop entirely.
- * Note that this cannot be called unless cinfo->mem is non-NULL.
- */
-
- METHODDEF(void)
- self_destruct (j_common_ptr cinfo)
- {
- int pool;
-
- /* Close all backing store, release all memory.
- * Releasing pools in reverse order might help avoid fragmentation
- * with some (brain-damaged) malloc libraries.
- */
- for (pool = JPOOL_NUMPOOLS-1; pool >= JPOOL_PERMANENT; pool--) {
- free_pool(cinfo, pool);
- }
-
- /* Release the memory manager control block too. */
- jpeg_free_small(cinfo, (void *) cinfo->mem, SIZEOF(my_memory_mgr));
- cinfo->mem = NULL; /* ensures I will be called only once */
-
- jpeg_mem_term(cinfo); /* system-dependent cleanup */
- }
-
- /*
- * Memory manager initialization.
- * When this is called, only the error manager pointer is valid in cinfo!
- */
-
- GLOBAL(void)
- jinit_memory_mgr (j_common_ptr cinfo)
- {
- my_mem_ptr mem;
- long max_to_use;
- int pool;
- size_t test_mac;
-
- cinfo->mem = NULL; /* for safety if init fails */
-
- /* Check for configuration errors.
- * SIZEOF(ALIGN_TYPE) should be a power of 2; otherwise, it probably
- * doesn't reflect any real hardware alignment requirement.
- * The test is a little tricky: for X>0, X and X-1 have no one-bits
- * in common if and only if X is a power of 2, ie has only one one-bit.
- * Some compilers may give an "unreachable code" warning here; ignore it.
- */
- if ((SIZEOF(ALIGN_TYPE) & (SIZEOF(ALIGN_TYPE)-1)) != 0)
- ERREXIT(cinfo, JERR_BAD_ALIGN_TYPE);
- /* MAX_ALLOC_CHUNK must be representable as type size_t, and must be
- * a multiple of SIZEOF(ALIGN_TYPE).
- * Again, an "unreachable code" warning may be ignored here.
- * But a "constant too large" warning means you need to fix MAX_ALLOC_CHUNK.
- */
- test_mac = (size_t) MAX_ALLOC_CHUNK;
- if ((long) test_mac != MAX_ALLOC_CHUNK ||
- (MAX_ALLOC_CHUNK % SIZEOF(ALIGN_TYPE)) != 0)
- ERREXIT(cinfo, JERR_BAD_ALLOC_CHUNK);
-
- max_to_use = jpeg_mem_init(cinfo); /* system-dependent initialization */
-
- /* Attempt to allocate memory manager's control block */
- mem = (my_mem_ptr) jpeg_get_small(cinfo, SIZEOF(my_memory_mgr));
-
- if (mem == NULL) {
- jpeg_mem_term(cinfo); /* system-dependent cleanup */
- ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 0);
- }
-
- /* OK, fill in the method pointers */
- mem->pub.alloc_small = alloc_small;
- mem->pub.alloc_large = alloc_large;
- mem->pub.alloc_sarray = alloc_sarray;
- mem->pub.alloc_barray = alloc_barray;
- mem->pub.request_virt_sarray = request_virt_sarray;
- mem->pub.request_virt_barray = request_virt_barray;
- mem->pub.realize_virt_arrays = realize_virt_arrays;
- mem->pub.access_virt_sarray = access_virt_sarray;
- mem->pub.access_virt_barray = access_virt_barray;
- mem->pub.free_pool = free_pool;
- mem->pub.self_destruct = self_destruct;
-
- /* Make MAX_ALLOC_CHUNK accessible to other modules */
- mem->pub.max_alloc_chunk = MAX_ALLOC_CHUNK;
-
- /* Initialize working state */
- mem->pub.max_memory_to_use = max_to_use;
-
- for (pool = JPOOL_NUMPOOLS-1; pool >= JPOOL_PERMANENT; pool--) {
- mem->small_list[pool] = NULL;
- mem->large_list[pool] = NULL;
- }
- mem->virt_sarray_list = NULL;
- mem->virt_barray_list = NULL;
-
- mem->total_space_allocated = SIZEOF(my_memory_mgr);
-
- /* Declare ourselves open for business */
- cinfo->mem = & mem->pub;
-
- /* Check for an environment variable JPEGMEM; if found, override the
- * default max_memory setting from jpeg_mem_init. Note that the
- * surrounding application may again override this value.
- * If your system doesn't support getenv(), define NO_GETENV to disable
- * this feature.
- */
- #ifndef NO_GETENV
- { char * memenv;
-
- if ((memenv = getenv("JPEGMEM")) != NULL) {
- char ch = 'x';
-
- if (sscanf(memenv, "%ld%c", &max_to_use, &ch) > 0) {
- if (ch == 'm' || ch == 'M')
- max_to_use *= 1000L;
- mem->pub.max_memory_to_use = max_to_use * 1000L;
- }
- }
- }
- #endif
-
- }
- /********* End of inlined file: jmemmgr.c *********/
-
- /********* Start of inlined file: jmemnobs.c *********/
- #define JPEG_INTERNALS
-
- #ifndef HAVE_STDLIB_H /* <stdlib.h> should declare malloc(),free() */
- extern void * malloc JPP((size_t size));
- extern void free JPP((void *ptr));
- #endif
-
- /*
- * Memory allocation and freeing are controlled by the regular library
- * routines malloc() and free().
- */
-
- GLOBAL(void *)
- jpeg_get_small (j_common_ptr cinfo, size_t sizeofobject)
- {
- return (void *) malloc(sizeofobject);
- }
-
- GLOBAL(void)
- jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject)
- {
- free(object);
- }
-
- /*
- * "Large" objects are treated the same as "small" ones.
- * NB: although we include FAR keywords in the routine declarations,
- * this file won't actually work in 80x86 small/medium model; at least,
- * you probably won't be able to process useful-size images in only 64KB.
- */
-
- GLOBAL(void FAR *)
- jpeg_get_large (j_common_ptr cinfo, size_t sizeofobject)
- {
- return (void FAR *) malloc(sizeofobject);
- }
-
- GLOBAL(void)
- jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject)
- {
- free(object);
- }
-
- /*
- * This routine computes the total memory space available for allocation.
- * Here we always say, "we got all you want bud!"
- */
-
- GLOBAL(long)
- jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed,
- long max_bytes_needed, long already_allocated)
- {
- return max_bytes_needed;
- }
-
- /*
- * Backing store (temporary file) management.
- * Since jpeg_mem_available always promised the moon,
- * this should never be called and we can just error out.
- */
-
- GLOBAL(void)
- jpeg_open_backing_store (j_common_ptr cinfo, struct backing_store_struct *info,
- long total_bytes_needed)
- {
- ERREXIT(cinfo, JERR_NO_BACKING_STORE);
- }
-
- /*
- * These routines take care of any system-dependent initialization and
- * cleanup required. Here, there isn't any.
- */
-
- GLOBAL(long)
- jpeg_mem_init (j_common_ptr cinfo)
- {
- return 0; /* just set max_memory_to_use to 0 */
- }
-
- GLOBAL(void)
- jpeg_mem_term (j_common_ptr cinfo)
- {
- /* no work */
- }
- /********* End of inlined file: jmemnobs.c *********/
-
- /********* Start of inlined file: jquant1.c *********/
- #define JPEG_INTERNALS
-
- #ifdef QUANT_1PASS_SUPPORTED
-
- /*
- * The main purpose of 1-pass quantization is to provide a fast, if not very
- * high quality, colormapped output capability. A 2-pass quantizer usually
- * gives better visual quality; however, for quantized grayscale output this
- * quantizer is perfectly adequate. Dithering is highly recommended with this
- * quantizer, though you can turn it off if you really want to.
- *
- * In 1-pass quantization the colormap must be chosen in advance of seeing the
- * image. We use a map consisting of all combinations of Ncolors[i] color
- * values for the i'th component. The Ncolors[] values are chosen so that
- * their product, the total number of colors, is no more than that requested.
- * (In most cases, the product will be somewhat less.)
- *
- * Since the colormap is orthogonal, the representative value for each color
- * component can be determined without considering the other components;
- * then these indexes can be combined into a colormap index by a standard
- * N-dimensional-array-subscript calculation. Most of the arithmetic involved
- * can be precalculated and stored in the lookup table colorindex[].
- * colorindex[i][j] maps pixel value j in component i to the nearest
- * representative value (grid plane) for that component; this index is
- * multiplied by the array stride for component i, so that the
- * index of the colormap entry closest to a given pixel value is just
- * sum( colorindex[component-number][pixel-component-value] )
- * Aside from being fast, this scheme allows for variable spacing between
- * representative values with no additional lookup cost.
- *
- * If gamma correction has been applied in color conversion, it might be wise
- * to adjust the color grid spacing so that the representative colors are
- * equidistant in linear space. At this writing, gamma correction is not
- * implemented by jdcolor, so nothing is done here.
- */
-
- /* Declarations for ordered dithering.
- *
- * We use a standard 16x16 ordered dither array. The basic concept of ordered
- * dithering is described in many references, for instance Dale Schumacher's
- * chapter II.2 of Graphics Gems II (James Arvo, ed. Academic Press, 1991).
- * In place of Schumacher's comparisons against a "threshold" value, we add a
- * "dither" value to the input pixel and then round the result to the nearest
- * output value. The dither value is equivalent to (0.5 - threshold) times
- * the distance between output values. For ordered dithering, we assume that
- * the output colors are equally spaced; if not, results will probably be
- * worse, since the dither may be too much or too little at a given point.
- *
- * The normal calculation would be to form pixel value + dither, range-limit
- * this to 0..MAXJSAMPLE, and then index into the colorindex table as usual.
- * We can skip the separate range-limiting step by extending the colorindex
- * table in both directions.
- */
-
- #define ODITHER_SIZE 16 /* dimension of dither matrix */
- /* NB: if ODITHER_SIZE is not a power of 2, ODITHER_MASK uses will break */
- #define ODITHER_CELLS (ODITHER_SIZE*ODITHER_SIZE) /* # cells in matrix */
- #define ODITHER_MASK (ODITHER_SIZE-1) /* mask for wrapping around counters */
-
- typedef int ODITHER_MATRIX[ODITHER_SIZE][ODITHER_SIZE];
- typedef int (*ODITHER_MATRIX_PTR)[ODITHER_SIZE];
-
- static const UINT8 base_dither_matrix[ODITHER_SIZE][ODITHER_SIZE] = {
- /* Bayer's order-4 dither array. Generated by the code given in
- * Stephen Hawley's article "Ordered Dithering" in Graphics Gems I.
- * The values in this array must range from 0 to ODITHER_CELLS-1.
- */
- { 0,192, 48,240, 12,204, 60,252, 3,195, 51,243, 15,207, 63,255 },
- { 128, 64,176,112,140, 76,188,124,131, 67,179,115,143, 79,191,127 },
- { 32,224, 16,208, 44,236, 28,220, 35,227, 19,211, 47,239, 31,223 },
- { 160, 96,144, 80,172,108,156, 92,163, 99,147, 83,175,111,159, 95 },
- { 8,200, 56,248, 4,196, 52,244, 11,203, 59,251, 7,199, 55,247 },
- { 136, 72,184,120,132, 68,180,116,139, 75,187,123,135, 71,183,119 },
- { 40,232, 24,216, 36,228, 20,212, 43,235, 27,219, 39,231, 23,215 },
- { 168,104,152, 88,164,100,148, 84,171,107,155, 91,167,103,151, 87 },
- { 2,194, 50,242, 14,206, 62,254, 1,193, 49,241, 13,205, 61,253 },
- { 130, 66,178,114,142, 78,190,126,129, 65,177,113,141, 77,189,125 },
- { 34,226, 18,210, 46,238, 30,222, 33,225, 17,209, 45,237, 29,221 },
- { 162, 98,146, 82,174,110,158, 94,161, 97,145, 81,173,109,157, 93 },
- { 10,202, 58,250, 6,198, 54,246, 9,201, 57,249, 5,197, 53,245 },
- { 138, 74,186,122,134, 70,182,118,137, 73,185,121,133, 69,181,117 },
- { 42,234, 26,218, 38,230, 22,214, 41,233, 25,217, 37,229, 21,213 },
- { 170,106,154, 90,166,102,150, 86,169,105,153, 89,165,101,149, 85 }
- };
-
- /* Declarations for Floyd-Steinberg dithering.
- *
- * Errors are accumulated into the array fserrors[], at a resolution of
- * 1/16th of a pixel count. The error at a given pixel is propagated
- * to its not-yet-processed neighbors using the standard F-S fractions,
- * ... (here) 7/16
- * 3/16 5/16 1/16
- * We work left-to-right on even rows, right-to-left on odd rows.
- *
- * We can get away with a single array (holding one row's worth of errors)
- * by using it to store the current row's errors at pixel columns not yet
- * processed, but the next row's errors at columns already processed. We
- * need only a few extra variables to hold the errors immediately around the
- * current column. (If we are lucky, those variables are in registers, but
- * even if not, they're probably cheaper to access than array elements are.)
- *
- * The fserrors[] array is indexed [component#][position].
- * We provide (#columns + 2) entries per component; the extra entry at each
- * end saves us from special-casing the first and last pixels.
- *
- * Note: on a wide image, we might not have enough room in a PC's near data
- * segment to hold the error array; so it is allocated with alloc_large.
- */
-
- #if BITS_IN_JSAMPLE == 8
- typedef INT16 FSERROR; /* 16 bits should be enough */
- typedef int LOCFSERROR; /* use 'int' for calculation temps */
- #else
- typedef INT32 FSERROR; /* may need more than 16 bits */
- typedef INT32 LOCFSERROR; /* be sure calculation temps are big enough */
- #endif
-
- typedef FSERROR FAR *FSERRPTR; /* pointer to error array (in FAR storage!) */
-
- /* Private subobject */
-
- #define MAX_Q_COMPS 4 /* max components I can handle */
-
- typedef struct {
- struct jpeg_color_quantizer pub; /* public fields */
-
- /* Initially allocated colormap is saved here */
- JSAMPARRAY sv_colormap; /* The color map as a 2-D pixel array */
- int sv_actual; /* number of entries in use */
-
- JSAMPARRAY colorindex; /* Precomputed mapping for speed */
- /* colorindex[i][j] = index of color closest to pixel value j in component i,
- * premultiplied as described above. Since colormap indexes must fit into
- * JSAMPLEs, the entries of this array will too.
- */
- boolean is_padded; /* is the colorindex padded for odither? */
-
- int Ncolors[MAX_Q_COMPS]; /* # of values alloced to each component */
-
- /* Variables for ordered dithering */
- int row_index; /* cur row's vertical index in dither matrix */
- ODITHER_MATRIX_PTR odither[MAX_Q_COMPS]; /* one dither array per component */
-
- /* Variables for Floyd-Steinberg dithering */
- FSERRPTR fserrors[MAX_Q_COMPS]; /* accumulated errors */
- boolean on_odd_row; /* flag to remember which row we are on */
- } my_cquantizer;
-
- typedef my_cquantizer * my_cquantize_ptr;
-
- /*
- * Policy-making subroutines for create_colormap and create_colorindex.
- * These routines determine the colormap to be used. The rest of the module
- * only assumes that the colormap is orthogonal.
- *
- * * select_ncolors decides how to divvy up the available colors
- * among the components.
- * * output_value defines the set of representative values for a component.
- * * largest_input_value defines the mapping from input values to
- * representative values for a component.
- * Note that the latter two routines may impose different policies for
- * different components, though this is not currently done.
- */
-
- LOCAL(int)
- select_ncolors (j_decompress_ptr cinfo, int Ncolors[])
- /* Determine allocation of desired colors to components, */
- /* and fill in Ncolors[] array to indicate choice. */
- /* Return value is total number of colors (product of Ncolors[] values). */
- {
- int nc = cinfo->out_color_components; /* number of color components */
- int max_colors = cinfo->desired_number_of_colors;
- int total_colors, iroot, i, j;
- boolean changed;
- long temp;
- static const int RGB_order[3] = { RGB_GREEN, RGB_RED, RGB_BLUE };
-
- /* We can allocate at least the nc'th root of max_colors per component. */
- /* Compute floor(nc'th root of max_colors). */
- iroot = 1;
- do {
- iroot++;
- temp = iroot; /* set temp = iroot ** nc */
- for (i = 1; i < nc; i++)
- temp *= iroot;
- } while (temp <= (long) max_colors); /* repeat till iroot exceeds root */
- iroot--; /* now iroot = floor(root) */
-
- /* Must have at least 2 color values per component */
- if (iroot < 2)
- ERREXIT1(cinfo, JERR_QUANT_FEW_COLORS, (int) temp);
-
- /* Initialize to iroot color values for each component */
- total_colors = 1;
- for (i = 0; i < nc; i++) {
- Ncolors[i] = iroot;
- total_colors *= iroot;
- }
- /* We may be able to increment the count for one or more components without
- * exceeding max_colors, though we know not all can be incremented.
- * Sometimes, the first component can be incremented more than once!
- * (Example: for 16 colors, we start at 2*2*2, go to 3*2*2, then 4*2*2.)
- * In RGB colorspace, try to increment G first, then R, then B.
- */
- do {
- changed = FALSE;
- for (i = 0; i < nc; i++) {
- j = (cinfo->out_color_space == JCS_RGB ? RGB_order[i] : i);
- /* calculate new total_colors if Ncolors[j] is incremented */
- temp = total_colors / Ncolors[j];
- temp *= Ncolors[j]+1; /* done in long arith to avoid oflo */
- if (temp > (long) max_colors)
- break; /* won't fit, done with this pass */
- Ncolors[j]++; /* OK, apply the increment */
- total_colors = (int) temp;
- changed = TRUE;
- }
- } while (changed);
-
- return total_colors;
- }
-
- LOCAL(int)
- output_value (j_decompress_ptr cinfo, int ci, int j, int maxj)
- /* Return j'th output value, where j will range from 0 to maxj */
- /* The output values must fall in 0..MAXJSAMPLE in increasing order */
- {
- /* We always provide values 0 and MAXJSAMPLE for each component;
- * any additional values are equally spaced between these limits.
- * (Forcing the upper and lower values to the limits ensures that
- * dithering can't produce a color outside the selected gamut.)
- */
- return (int) (((INT32) j * MAXJSAMPLE + maxj/2) / maxj);
- }
-
- LOCAL(int)
- largest_input_value (j_decompress_ptr cinfo, int ci, int j, int maxj)
- /* Return largest input value that should map to j'th output value */
- /* Must have largest(j=0) >= 0, and largest(j=maxj) >= MAXJSAMPLE */
- {
- /* Breakpoints are halfway between values returned by output_value */
- return (int) (((INT32) (2*j + 1) * MAXJSAMPLE + maxj) / (2*maxj));
- }
-
- /*
- * Create the colormap.
- */
-
- LOCAL(void)
- create_colormap (j_decompress_ptr cinfo)
- {
- my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
- JSAMPARRAY colormap; /* Created colormap */
- int total_colors; /* Number of distinct output colors */
- int i,j,k, nci, blksize, blkdist, ptr, val;
-
- /* Select number of colors for each component */
- total_colors = select_ncolors(cinfo, cquantize->Ncolors);
-
- /* Report selected color counts */
- if (cinfo->out_color_components == 3)
- TRACEMS4(cinfo, 1, JTRC_QUANT_3_NCOLORS,
- total_colors, cquantize->Ncolors[0],
- cquantize->Ncolors[1], cquantize->Ncolors[2]);
- else
- TRACEMS1(cinfo, 1, JTRC_QUANT_NCOLORS, total_colors);
-
- /* Allocate and fill in the colormap. */
- /* The colors are ordered in the map in standard row-major order, */
- /* i.e. rightmost (highest-indexed) color changes most rapidly. */
-
- colormap = (*cinfo->mem->alloc_sarray)
- ((j_common_ptr) cinfo, JPOOL_IMAGE,
- (JDIMENSION) total_colors, (JDIMENSION) cinfo->out_color_components);
-
- /* blksize is number of adjacent repeated entries for a component */
- /* blkdist is distance between groups of identical entries for a component */
- blkdist = total_colors;
-
- for (i = 0; i < cinfo->out_color_components; i++) {
- /* fill in colormap entries for i'th color component */
- nci = cquantize->Ncolors[i]; /* # of distinct values for this color */
- blksize = blkdist / nci;
- for (j = 0; j < nci; j++) {
- /* Compute j'th output value (out of nci) for component */
- val = output_value(cinfo, i, j, nci-1);
- /* Fill in all colormap entries that have this value of this component */
- for (ptr = j * blksize; ptr < total_colors; ptr += blkdist) {
- /* fill in blksize entries beginning at ptr */
- for (k = 0; k < blksize; k++)
- colormap[i][ptr+k] = (JSAMPLE) val;
- }
- }
- blkdist = blksize; /* blksize of this color is blkdist of next */
- }
-
- /* Save the colormap in private storage,
- * where it will survive color quantization mode changes.
- */
- cquantize->sv_colormap = colormap;
- cquantize->sv_actual = total_colors;
- }
-
- /*
- * Create the color index table.
- */
-
- LOCAL(void)
- create_colorindex (j_decompress_ptr cinfo)
- {
- my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
- JSAMPROW indexptr;
- int i,j,k, nci, blksize, val, pad;
-
- /* For ordered dither, we pad the color index tables by MAXJSAMPLE in
- * each direction (input index values can be -MAXJSAMPLE .. 2*MAXJSAMPLE).
- * This is not necessary in the other dithering modes. However, we
- * flag whether it was done in case user changes dithering mode.
- */
- if (cinfo->dither_mode == JDITHER_ORDERED) {
- pad = MAXJSAMPLE*2;
- cquantize->is_padded = TRUE;
- } else {
- pad = 0;
- cquantize->is_padded = FALSE;
- }
-
- cquantize->colorindex = (*cinfo->mem->alloc_sarray)
- ((j_common_ptr) cinfo, JPOOL_IMAGE,
- (JDIMENSION) (MAXJSAMPLE+1 + pad),
- (JDIMENSION) cinfo->out_color_components);
-
- /* blksize is number of adjacent repeated entries for a component */
- blksize = cquantize->sv_actual;
-
- for (i = 0; i < cinfo->out_color_components; i++) {
- /* fill in colorindex entries for i'th color component */
- nci = cquantize->Ncolors[i]; /* # of distinct values for this color */
- blksize = blksize / nci;
-
- /* adjust colorindex pointers to provide padding at negative indexes. */
- if (pad)
- cquantize->colorindex[i] += MAXJSAMPLE;
-
- /* in loop, val = index of current output value, */
- /* and k = largest j that maps to current val */
- indexptr = cquantize->colorindex[i];
- val = 0;
- k = largest_input_value(cinfo, i, 0, nci-1);
- for (j = 0; j <= MAXJSAMPLE; j++) {
- while (j > k) /* advance val if past boundary */
- k = largest_input_value(cinfo, i, ++val, nci-1);
- /* premultiply so that no multiplication needed in main processing */
- indexptr[j] = (JSAMPLE) (val * blksize);
- }
- /* Pad at both ends if necessary */
- if (pad)
- for (j = 1; j <= MAXJSAMPLE; j++) {
- indexptr[-j] = indexptr[0];
- indexptr[MAXJSAMPLE+j] = indexptr[MAXJSAMPLE];
- }
- }
- }
-
- /*
- * Create an ordered-dither array for a component having ncolors
- * distinct output values.
- */
-
- LOCAL(ODITHER_MATRIX_PTR)
- make_odither_array (j_decompress_ptr cinfo, int ncolors)
- {
- ODITHER_MATRIX_PTR odither;
- int j,k;
- INT32 num,den;
-
- odither = (ODITHER_MATRIX_PTR)
- (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
- SIZEOF(ODITHER_MATRIX));
- /* The inter-value distance for this color is MAXJSAMPLE/(ncolors-1).
- * Hence the dither value for the matrix cell with fill order f
- * (f=0..N-1) should be (N-1-2*f)/(2*N) * MAXJSAMPLE/(ncolors-1).
- * On 16-bit-int machine, be careful to avoid overflow.
- */
- den = 2 * ODITHER_CELLS * ((INT32) (ncolors - 1));
- for (j = 0; j < ODITHER_SIZE; j++) {
- for (k = 0; k < ODITHER_SIZE; k++) {
- num = ((INT32) (ODITHER_CELLS-1 - 2*((int)base_dither_matrix[j][k])))
- * MAXJSAMPLE;
- /* Ensure round towards zero despite C's lack of consistency
- * about rounding negative values in integer division...
- */
- odither[j][k] = (int) (num<0 ? -((-num)/den) : num/den);
- }
- }
- return odither;
- }
-
- /*
- * Create the ordered-dither tables.
- * Components having the same number of representative colors may
- * share a dither table.
- */
-
- LOCAL(void)
- create_odither_tables (j_decompress_ptr cinfo)
- {
- my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
- ODITHER_MATRIX_PTR odither;
- int i, j, nci;
-
- for (i = 0; i < cinfo->out_color_components; i++) {
- nci = cquantize->Ncolors[i]; /* # of distinct values for this color */
- odither = NULL; /* search for matching prior component */
- for (j = 0; j < i; j++) {
- if (nci == cquantize->Ncolors[j]) {
- odither = cquantize->odither[j];
- break;
- }
- }
- if (odither == NULL) /* need a new table? */
- odither = make_odither_array(cinfo, nci);
- cquantize->odither[i] = odither;
- }
- }
-
- /*
- * Map some rows of pixels to the output colormapped representation.
- */
-
- METHODDEF(void)
- color_quantize (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
- JSAMPARRAY output_buf, int num_rows)
- /* General case, no dithering */
- {
- my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
- JSAMPARRAY colorindex = cquantize->colorindex;
- register int pixcode, ci;
- register JSAMPROW ptrin, ptrout;
- int row;
- JDIMENSION col;
- JDIMENSION width = cinfo->output_width;
- register int nc = cinfo->out_color_components;
-
- for (row = 0; row < num_rows; row++) {
- ptrin = input_buf[row];
- ptrout = output_buf[row];
- for (col = width; col > 0; col--) {
- pixcode = 0;
- for (ci = 0; ci < nc; ci++) {
- pixcode += GETJSAMPLE(colorindex[ci][GETJSAMPLE(*ptrin++)]);
- }
- *ptrout++ = (JSAMPLE) pixcode;
- }
- }
- }
-
- METHODDEF(void)
- color_quantize3 (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
- JSAMPARRAY output_buf, int num_rows)
- /* Fast path for out_color_components==3, no dithering */
- {
- my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
- register int pixcode;
- register JSAMPROW ptrin, ptrout;
- JSAMPROW colorindex0 = cquantize->colorindex[0];
- JSAMPROW colorindex1 = cquantize->colorindex[1];
- JSAMPROW colorindex2 = cquantize->colorindex[2];
- int row;
- JDIMENSION col;
- JDIMENSION width = cinfo->output_width;
-
- for (row = 0; row < num_rows; row++) {
- ptrin = input_buf[row];
- ptrout = output_buf[row];
- for (col = width; col > 0; col--) {
- pixcode = GETJSAMPLE(colorindex0[GETJSAMPLE(*ptrin++)]);
- pixcode += GETJSAMPLE(colorindex1[GETJSAMPLE(*ptrin++)]);
- pixcode += GETJSAMPLE(colorindex2[GETJSAMPLE(*ptrin++)]);
- *ptrout++ = (JSAMPLE) pixcode;
- }
- }
- }
-
- METHODDEF(void)
- quantize_ord_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
- JSAMPARRAY output_buf, int num_rows)
- /* General case, with ordered dithering */
- {
- my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
- register JSAMPROW input_ptr;
- register JSAMPROW output_ptr;
- JSAMPROW colorindex_ci;
- int * dither; /* points to active row of dither matrix */
- int row_index, col_index; /* current indexes into dither matrix */
- int nc = cinfo->out_color_components;
- int ci;
- int row;
- JDIMENSION col;
- JDIMENSION width = cinfo->output_width;
-
- for (row = 0; row < num_rows; row++) {
- /* Initialize output values to 0 so can process components separately */
- jzero_far((void FAR *) output_buf[row],
- (size_t) (width * SIZEOF(JSAMPLE)));
- row_index = cquantize->row_index;
- for (ci = 0; ci < nc; ci++) {
- input_ptr = input_buf[row] + ci;
- output_ptr = output_buf[row];
- colorindex_ci = cquantize->colorindex[ci];
- dither = cquantize->odither[ci][row_index];
- col_index = 0;
-
- for (col = width; col > 0; col--) {
- /* Form pixel value + dither, range-limit to 0..MAXJSAMPLE,
- * select output value, accumulate into output code for this pixel.
- * Range-limiting need not be done explicitly, as we have extended
- * the colorindex table to produce the right answers for out-of-range
- * inputs. The maximum dither is +- MAXJSAMPLE; this sets the
- * required amount of padding.
- */
- *output_ptr += colorindex_ci[GETJSAMPLE(*input_ptr)+dither[col_index]];
- input_ptr += nc;
- output_ptr++;
- col_index = (col_index + 1) & ODITHER_MASK;
- }
- }
- /* Advance row index for next row */
- row_index = (row_index + 1) & ODITHER_MASK;
- cquantize->row_index = row_index;
- }
- }
-
- METHODDEF(void)
- quantize3_ord_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
- JSAMPARRAY output_buf, int num_rows)
- /* Fast path for out_color_components==3, with ordered dithering */
- {
- my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
- register int pixcode;
- register JSAMPROW input_ptr;
- register JSAMPROW output_ptr;
- JSAMPROW colorindex0 = cquantize->colorindex[0];
- JSAMPROW colorindex1 = cquantize->colorindex[1];
- JSAMPROW colorindex2 = cquantize->colorindex[2];
- int * dither0; /* points to active row of dither matrix */
- int * dither1;
- int * dither2;
- int row_index, col_index; /* current indexes into dither matrix */
- int row;
- JDIMENSION col;
- JDIMENSION width = cinfo->output_width;
-
- for (row = 0; row < num_rows; row++) {
- row_index = cquantize->row_index;
- input_ptr = input_buf[row];
- output_ptr = output_buf[row];
- dither0 = cquantize->odither[0][row_index];
- dither1 = cquantize->odither[1][row_index];
- dither2 = cquantize->odither[2][row_index];
- col_index = 0;
-
- for (col = width; col > 0; col--) {
- pixcode = GETJSAMPLE(colorindex0[GETJSAMPLE(*input_ptr++) +
- dither0[col_index]]);
- pixcode += GETJSAMPLE(colorindex1[GETJSAMPLE(*input_ptr++) +
- dither1[col_index]]);
- pixcode += GETJSAMPLE(colorindex2[GETJSAMPLE(*input_ptr++) +
- dither2[col_index]]);
- *output_ptr++ = (JSAMPLE) pixcode;
- col_index = (col_index + 1) & ODITHER_MASK;
- }
- row_index = (row_index + 1) & ODITHER_MASK;
- cquantize->row_index = row_index;
- }
- }
-
- METHODDEF(void)
- quantize_fs_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
- JSAMPARRAY output_buf, int num_rows)
- /* General case, with Floyd-Steinberg dithering */
- {
- my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
- register LOCFSERROR cur; /* current error or pixel value */
- LOCFSERROR belowerr; /* error for pixel below cur */
- LOCFSERROR bpreverr; /* error for below/prev col */
- LOCFSERROR bnexterr; /* error for below/next col */
- LOCFSERROR delta;
- register FSERRPTR errorptr; /* => fserrors[] at column before current */
- register JSAMPROW input_ptr;
- register JSAMPROW output_ptr;
- JSAMPROW colorindex_ci;
- JSAMPROW colormap_ci;
- int pixcode;
- int nc = cinfo->out_color_components;
- int dir; /* 1 for left-to-right, -1 for right-to-left */
- int dirnc; /* dir * nc */
- int ci;
- int row;
- JDIMENSION col;
- JDIMENSION width = cinfo->output_width;
- JSAMPLE *range_limit = cinfo->sample_range_limit;
- SHIFT_TEMPS
-
- for (row = 0; row < num_rows; row++) {
- /* Initialize output values to 0 so can process components separately */
- jzero_far((void FAR *) output_buf[row],
- (size_t) (width * SIZEOF(JSAMPLE)));
- for (ci = 0; ci < nc; ci++) {
- input_ptr = input_buf[row] + ci;
- output_ptr = output_buf[row];
- if (cquantize->on_odd_row) {
- /* work right to left in this row */
- input_ptr += (width-1) * nc; /* so point to rightmost pixel */
- output_ptr += width-1;
- dir = -1;
- dirnc = -nc;
- errorptr = cquantize->fserrors[ci] + (width+1); /* => entry after last column */
- } else {
- /* work left to right in this row */
- dir = 1;
- dirnc = nc;
- errorptr = cquantize->fserrors[ci]; /* => entry before first column */
- }
- colorindex_ci = cquantize->colorindex[ci];
- colormap_ci = cquantize->sv_colormap[ci];
- /* Preset error values: no error propagated to first pixel from left */
- cur = 0;
- /* and no error propagated to row below yet */
- belowerr = bpreverr = 0;
-
- for (col = width; col > 0; col--) {
- /* cur holds the error propagated from the previous pixel on the
- * current line. Add the error propagated from the previous line
- * to form the complete error correction term for this pixel, and
- * round the error term (which is expressed * 16) to an integer.
- * RIGHT_SHIFT rounds towards minus infinity, so adding 8 is correct
- * for either sign of the error value.
- * Note: errorptr points to *previous* column's array entry.
- */
- cur = RIGHT_SHIFT(cur + errorptr[dir] + 8, 4);
- /* Form pixel value + error, and range-limit to 0..MAXJSAMPLE.
- * The maximum error is +- MAXJSAMPLE; this sets the required size
- * of the range_limit array.
- */
- cur += GETJSAMPLE(*input_ptr);
- cur = GETJSAMPLE(range_limit[cur]);
- /* Select output value, accumulate into output code for this pixel */
- pixcode = GETJSAMPLE(colorindex_ci[cur]);
- *output_ptr += (JSAMPLE) pixcode;
- /* Compute actual representation error at this pixel */
- /* Note: we can do this even though we don't have the final */
- /* pixel code, because the colormap is orthogonal. */
- cur -= GETJSAMPLE(colormap_ci[pixcode]);
- /* Compute error fractions to be propagated to adjacent pixels.
- * Add these into the running sums, and simultaneously shift the
- * next-line error sums left by 1 column.
- */
- bnexterr = cur;
- delta = cur * 2;
- cur += delta; /* form error * 3 */
- errorptr[0] = (FSERROR) (bpreverr + cur);
- cur += delta; /* form error * 5 */
- bpreverr = belowerr + cur;
- belowerr = bnexterr;
- cur += delta; /* form error * 7 */
- /* At this point cur contains the 7/16 error value to be propagated
- * to the next pixel on the current line, and all the errors for the
- * next line have been shifted over. We are therefore ready to move on.
- */
- input_ptr += dirnc; /* advance input ptr to next column */
- output_ptr += dir; /* advance output ptr to next column */
- errorptr += dir; /* advance errorptr to current column */
- }
- /* Post-loop cleanup: we must unload the final error value into the
- * final fserrors[] entry. Note we need not unload belowerr because
- * it is for the dummy column before or after the actual array.
- */
- errorptr[0] = (FSERROR) bpreverr; /* unload prev err into array */
- }
- cquantize->on_odd_row = (cquantize->on_odd_row ? FALSE : TRUE);
- }
- }
-
- /*
- * Allocate workspace for Floyd-Steinberg errors.
- */
-
- LOCAL(void)
- alloc_fs_workspace (j_decompress_ptr cinfo)
- {
- my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
- size_t arraysize;
- int i;
-
- arraysize = (size_t) ((cinfo->output_width + 2) * SIZEOF(FSERROR));
- for (i = 0; i < cinfo->out_color_components; i++) {
- cquantize->fserrors[i] = (FSERRPTR)
- (*cinfo->mem->alloc_large)((j_common_ptr) cinfo, JPOOL_IMAGE, arraysize);
- }
- }
-
- /*
- * Initialize for one-pass color quantization.
- */
-
- METHODDEF(void)
- start_pass_1_quant (j_decompress_ptr cinfo, boolean is_pre_scan)
- {
- my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
- size_t arraysize;
- int i;
-
- /* Install my colormap. */
- cinfo->colormap = cquantize->sv_colormap;
- cinfo->actual_number_of_colors = cquantize->sv_actual;
-
- /* Initialize for desired dithering mode. */
- switch (cinfo->dither_mode) {
- case JDITHER_NONE:
- if (cinfo->out_color_components == 3)
- cquantize->pub.color_quantize = color_quantize3;
- else
- cquantize->pub.color_quantize = color_quantize;
- break;
- case JDITHER_ORDERED:
- if (cinfo->out_color_components == 3)
- cquantize->pub.color_quantize = quantize3_ord_dither;
- else
- cquantize->pub.color_quantize = quantize_ord_dither;
- cquantize->row_index = 0; /* initialize state for ordered dither */
- /* If user changed to ordered dither from another mode,
- * we must recreate the color index table with padding.
- * This will cost extra space, but probably isn't very likely.
- */
- if (! cquantize->is_padded)
- create_colorindex(cinfo);
- /* Create ordered-dither tables if we didn't already. */
- if (cquantize->odither[0] == NULL)
- create_odither_tables(cinfo);
- break;
- case JDITHER_FS:
- cquantize->pub.color_quantize = quantize_fs_dither;
- cquantize->on_odd_row = FALSE; /* initialize state for F-S dither */
- /* Allocate Floyd-Steinberg workspace if didn't already. */
- if (cquantize->fserrors[0] == NULL)
- alloc_fs_workspace(cinfo);
- /* Initialize the propagated errors to zero. */
- arraysize = (size_t) ((cinfo->output_width + 2) * SIZEOF(FSERROR));
- for (i = 0; i < cinfo->out_color_components; i++)
- jzero_far((void FAR *) cquantize->fserrors[i], arraysize);
- break;
- default:
- ERREXIT(cinfo, JERR_NOT_COMPILED);
- break;
- }
- }
-
- /*
- * Finish up at the end of the pass.
- */
-
- METHODDEF(void)
- finish_pass_1_quant (j_decompress_ptr cinfo)
- {
- /* no work in 1-pass case */
- }
-
- /*
- * Switch to a new external colormap between output passes.
- * Shouldn't get to this module!
- */
-
- METHODDEF(void)
- new_color_map_1_quant (j_decompress_ptr cinfo)
- {
- ERREXIT(cinfo, JERR_MODE_CHANGE);
- }
-
- /*
- * Module initialization routine for 1-pass color quantization.
- */
-
- GLOBAL(void)
- jinit_1pass_quantizer (j_decompress_ptr cinfo)
- {
- my_cquantize_ptr cquantize;
-
- cquantize = (my_cquantize_ptr)
- (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
- SIZEOF(my_cquantizer));
- cinfo->cquantize = (struct jpeg_color_quantizer *) cquantize;
- cquantize->pub.start_pass = start_pass_1_quant;
- cquantize->pub.finish_pass = finish_pass_1_quant;
- cquantize->pub.new_color_map = new_color_map_1_quant;
- cquantize->fserrors[0] = NULL; /* Flag FS workspace not allocated */
- cquantize->odither[0] = NULL; /* Also flag odither arrays not allocated */
-
- /* Make sure my internal arrays won't overflow */
- if (cinfo->out_color_components > MAX_Q_COMPS)
- ERREXIT1(cinfo, JERR_QUANT_COMPONENTS, MAX_Q_COMPS);
- /* Make sure colormap indexes can be represented by JSAMPLEs */
- if (cinfo->desired_number_of_colors > (MAXJSAMPLE+1))
- ERREXIT1(cinfo, JERR_QUANT_MANY_COLORS, MAXJSAMPLE+1);
-
- /* Create the colormap and color index table. */
- create_colormap(cinfo);
- create_colorindex(cinfo);
-
- /* Allocate Floyd-Steinberg workspace now if requested.
- * We do this now since it is FAR storage and may affect the memory
- * manager's space calculations. If the user changes to FS dither
- * mode in a later pass, we will allocate the space then, and will
- * possibly overrun the max_memory_to_use setting.
- */
- if (cinfo->dither_mode == JDITHER_FS)
- alloc_fs_workspace(cinfo);
- }
-
- #endif /* QUANT_1PASS_SUPPORTED */
- /********* End of inlined file: jquant1.c *********/
-
- /********* Start of inlined file: jquant2.c *********/
- #define JPEG_INTERNALS
-
- #ifdef QUANT_2PASS_SUPPORTED
-
- /*
- * This module implements the well-known Heckbert paradigm for color
- * quantization. Most of the ideas used here can be traced back to
- * Heckbert's seminal paper
- * Heckbert, Paul. "Color Image Quantization for Frame Buffer Display",
- * Proc. SIGGRAPH '82, Computer Graphics v.16 #3 (July 1982), pp 297-304.
- *
- * In the first pass over the image, we accumulate a histogram showing the
- * usage count of each possible color. To keep the histogram to a reasonable
- * size, we reduce the precision of the input; typical practice is to retain
- * 5 or 6 bits per color, so that 8 or 4 different input values are counted
- * in the same histogram cell.
- *
- * Next, the color-selection step begins with a box representing the whole
- * color space, and repeatedly splits the "largest" remaining box until we
- * have as many boxes as desired colors. Then the mean color in each
- * remaining box becomes one of the possible output colors.
- *
- * The second pass over the image maps each input pixel to the closest output
- * color (optionally after applying a Floyd-Steinberg dithering correction).
- * This mapping is logically trivial, but making it go fast enough requires
- * considerable care.
- *
- * Heckbert-style quantizers vary a good deal in their policies for choosing
- * the "largest" box and deciding where to cut it. The particular policies
- * used here have proved out well in experimental comparisons, but better ones
- * may yet be found.
- *
- * In earlier versions of the IJG code, this module quantized in YCbCr color
- * space, processing the raw upsampled data without a color conversion step.
- * This allowed the color conversion math to be done only once per colormap
- * entry, not once per pixel. However, that optimization precluded other
- * useful optimizations (such as merging color conversion with upsampling)
- * and it also interfered with desired capabilities such as quantizing to an
- * externally-supplied colormap. We have therefore abandoned that approach.
- * The present code works in the post-conversion color space, typically RGB.
- *
- * To improve the visual quality of the results, we actually work in scaled
- * RGB space, giving G distances more weight than R, and R in turn more than
- * B. To do everything in integer math, we must use integer scale factors.
- * The 2/3/1 scale factors used here correspond loosely to the relative
- * weights of the colors in the NTSC grayscale equation.
- * If you want to use this code to quantize a non-RGB color space, you'll
- * probably need to change these scale factors.
- */
-
- #define R_SCALE 2 /* scale R distances by this much */
- #define G_SCALE 3 /* scale G distances by this much */
- #define B_SCALE 1 /* and B by this much */
-
- /* Relabel R/G/B as components 0/1/2, respecting the RGB ordering defined
- * in jmorecfg.h. As the code stands, it will do the right thing for R,G,B
- * and B,G,R orders. If you define some other weird order in jmorecfg.h,
- * you'll get compile errors until you extend this logic. In that case
- * you'll probably want to tweak the histogram sizes too.
- */
-
- #if RGB_RED == 0
- #define C0_SCALE R_SCALE
- #endif
- #if RGB_BLUE == 0
- #define C0_SCALE B_SCALE
- #endif
- #if RGB_GREEN == 1
- #define C1_SCALE G_SCALE
- #endif
- #if RGB_RED == 2
- #define C2_SCALE R_SCALE
- #endif
- #if RGB_BLUE == 2
- #define C2_SCALE B_SCALE
- #endif
-
- /*
- * First we have the histogram data structure and routines for creating it.
- *
- * The number of bits of precision can be adjusted by changing these symbols.
- * We recommend keeping 6 bits for G and 5 each for R and B.
- * If you have plenty of memory and cycles, 6 bits all around gives marginally
- * better results; if you are short of memory, 5 bits all around will save
- * some space but degrade the results.
- * To maintain a fully accurate histogram, we'd need to allocate a "long"
- * (preferably unsigned long) for each cell. In practice this is overkill;
- * we can get by with 16 bits per cell. Few of the cell counts will overflow,
- * and clamping those that do overflow to the maximum value will give close-
- * enough results. This reduces the recommended histogram size from 256Kb
- * to 128Kb, which is a useful savings on PC-class machines.
- * (In the second pass the histogram space is re-used for pixel mapping data;
- * in that capacity, each cell must be able to store zero to the number of
- * desired colors. 16 bits/cell is plenty for that too.)
- * Since the JPEG code is intended to run in small memory model on 80x86
- * machines, we can't just allocate the histogram in one chunk. Instead
- * of a true 3-D array, we use a row of pointers to 2-D arrays. Each
- * pointer corresponds to a C0 value (typically 2^5 = 32 pointers) and
- * each 2-D array has 2^6*2^5 = 2048 or 2^6*2^6 = 4096 entries. Note that
- * on 80x86 machines, the pointer row is in near memory but the actual
- * arrays are in far memory (same arrangement as we use for image arrays).
- */
-
- #define MAXNUMCOLORS (MAXJSAMPLE+1) /* maximum size of colormap */
-
- /* These will do the right thing for either R,G,B or B,G,R color order,
- * but you may not like the results for other color orders.
- */
- #define HIST_C0_BITS 5 /* bits of precision in R/B histogram */
- #define HIST_C1_BITS 6 /* bits of precision in G histogram */
- #define HIST_C2_BITS 5 /* bits of precision in B/R histogram */
-
- /* Number of elements along histogram axes. */
- #define HIST_C0_ELEMS (1<<HIST_C0_BITS)
- #define HIST_C1_ELEMS (1<<HIST_C1_BITS)
- #define HIST_C2_ELEMS (1<<HIST_C2_BITS)
-
- /* These are the amounts to shift an input value to get a histogram index. */
- #define C0_SHIFT (BITS_IN_JSAMPLE-HIST_C0_BITS)
- #define C1_SHIFT (BITS_IN_JSAMPLE-HIST_C1_BITS)
- #define C2_SHIFT (BITS_IN_JSAMPLE-HIST_C2_BITS)
-
- typedef UINT16 histcell; /* histogram cell; prefer an unsigned type */
-
- typedef histcell FAR * histptr; /* for pointers to histogram cells */
-
- typedef histcell hist1d[HIST_C2_ELEMS]; /* typedefs for the array */
- typedef hist1d FAR * hist2d; /* type for the 2nd-level pointers */
- typedef hist2d * hist3d; /* type for top-level pointer */
-
- /* Declarations for Floyd-Steinberg dithering.
- *
- * Errors are accumulated into the array fserrors[], at a resolution of
- * 1/16th of a pixel count. The error at a given pixel is propagated
- * to its not-yet-processed neighbors using the standard F-S fractions,
- * ... (here) 7/16
- * 3/16 5/16 1/16
- * We work left-to-right on even rows, right-to-left on odd rows.
- *
- * We can get away with a single array (holding one row's worth of errors)
- * by using it to store the current row's errors at pixel columns not yet
- * processed, but the next row's errors at columns already processed. We
- * need only a few extra variables to hold the errors immediately around the
- * current column. (If we are lucky, those variables are in registers, but
- * even if not, they're probably cheaper to access than array elements are.)
- *
- * The fserrors[] array has (#columns + 2) entries; the extra entry at
- * each end saves us from special-casing the first and last pixels.
- * Each entry is three values long, one value for each color component.
- *
- * Note: on a wide image, we might not have enough room in a PC's near data
- * segment to hold the error array; so it is allocated with alloc_large.
- */
-
- #if BITS_IN_JSAMPLE == 8
- typedef INT16 FSERROR; /* 16 bits should be enough */
- typedef int LOCFSERROR; /* use 'int' for calculation temps */
- #else
- typedef INT32 FSERROR; /* may need more than 16 bits */
- typedef INT32 LOCFSERROR; /* be sure calculation temps are big enough */
- #endif
-
- typedef FSERROR FAR *FSERRPTR; /* pointer to error array (in FAR storage!) */
-
- /* Private subobject */
-
- typedef struct {
- struct jpeg_color_quantizer pub; /* public fields */
-
- /* Space for the eventually created colormap is stashed here */
- JSAMPARRAY sv_colormap; /* colormap allocated at init time */
- int desired; /* desired # of colors = size of colormap */
-
- /* Variables for accumulating image statistics */
- hist3d histogram; /* pointer to the histogram */
-
- boolean needs_zeroed; /* TRUE if next pass must zero histogram */
-
- /* Variables for Floyd-Steinberg dithering */
- FSERRPTR fserrors; /* accumulated errors */
- boolean on_odd_row; /* flag to remember which row we are on */
- int * error_limiter; /* table for clamping the applied error */
- } my_cquantizer2;
-
- typedef my_cquantizer2 * my_cquantize_ptr2;
-
- /*
- * Prescan some rows of pixels.
- * In this module the prescan simply updates the histogram, which has been
- * initialized to zeroes by start_pass.
- * An output_buf parameter is required by the method signature, but no data
- * is actually output (in fact the buffer controller is probably passing a
- * NULL pointer).
- */
-
- METHODDEF(void)
- prescan_quantize (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
- JSAMPARRAY output_buf, int num_rows)
- {
- my_cquantize_ptr2 cquantize = (my_cquantize_ptr2) cinfo->cquantize;
- register JSAMPROW ptr;
- register histptr histp;
- register hist3d histogram = cquantize->histogram;
- int row;
- JDIMENSION col;
- JDIMENSION width = cinfo->output_width;
-
- for (row = 0; row < num_rows; row++) {
- ptr = input_buf[row];
- for (col = width; col > 0; col--) {
- /* get pixel value and index into the histogram */
- histp = & histogram[GETJSAMPLE(ptr[0]) >> C0_SHIFT]
- [GETJSAMPLE(ptr[1]) >> C1_SHIFT]
- [GETJSAMPLE(ptr[2]) >> C2_SHIFT];
- /* increment, check for overflow and undo increment if so. */
- if (++(*histp) <= 0)
- (*histp)--;
- ptr += 3;
- }
- }
- }
-
- /*
- * Next we have the really interesting routines: selection of a colormap
- * given the completed histogram.
- * These routines work with a list of "boxes", each representing a rectangular
- * subset of the input color space (to histogram precision).
- */
-
- typedef struct {
- /* The bounds of the box (inclusive); expressed as histogram indexes */
- int c0min, c0max;
- int c1min, c1max;
- int c2min, c2max;
- /* The volume (actually 2-norm) of the box */
- INT32 volume;
- /* The number of nonzero histogram cells within this box */
- long colorcount;
- } box;
-
- typedef box * boxptr;
-
- LOCAL(boxptr)
- find_biggest_color_pop (boxptr boxlist, int numboxes)
- /* Find the splittable box with the largest color population */
- /* Returns NULL if no splittable boxes remain */
- {
- register boxptr boxp;
- register int i;
- register long maxc = 0;
- boxptr which = NULL;
-
- for (i = 0, boxp = boxlist; i < numboxes; i++, boxp++) {
- if (boxp->colorcount > maxc && boxp->volume > 0) {
- which = boxp;
- maxc = boxp->colorcount;
- }
- }
- return which;
- }
-
- LOCAL(boxptr)
- find_biggest_volume (boxptr boxlist, int numboxes)
- /* Find the splittable box with the largest (scaled) volume */
- /* Returns NULL if no splittable boxes remain */
- {
- register boxptr boxp;
- register int i;
- register INT32 maxv = 0;
- boxptr which = NULL;
-
- for (i = 0, boxp = boxlist; i < numboxes; i++, boxp++) {
- if (boxp->volume > maxv) {
- which = boxp;
- maxv = boxp->volume;
- }
- }
- return which;
- }
-
- LOCAL(void)
- update_box (j_decompress_ptr cinfo, boxptr boxp)
- /* Shrink the min/max bounds of a box to enclose only nonzero elements, */
- /* and recompute its volume and population */
- {
- my_cquantize_ptr2 cquantize = (my_cquantize_ptr2) cinfo->cquantize;
- hist3d histogram = cquantize->histogram;
- histptr histp;
- int c0,c1,c2;
- int c0min,c0max,c1min,c1max,c2min,c2max;
- INT32 dist0,dist1,dist2;
- long ccount;
-
- c0min = boxp->c0min; c0max = boxp->c0max;
- c1min = boxp->c1min; c1max = boxp->c1max;
- c2min = boxp->c2min; c2max = boxp->c2max;
-
- if (c0max > c0min)
- for (c0 = c0min; c0 <= c0max; c0++)
- for (c1 = c1min; c1 <= c1max; c1++) {
- histp = & histogram[c0][c1][c2min];
- for (c2 = c2min; c2 <= c2max; c2++)
- if (*histp++ != 0) {
- boxp->c0min = c0min = c0;
- goto have_c0min;
- }
- }
- have_c0min:
- if (c0max > c0min)
- for (c0 = c0max; c0 >= c0min; c0--)
- for (c1 = c1min; c1 <= c1max; c1++) {
- histp = & histogram[c0][c1][c2min];
- for (c2 = c2min; c2 <= c2max; c2++)
- if (*histp++ != 0) {
- boxp->c0max = c0max = c0;
- goto have_c0max;
- }
- }
- have_c0max:
- if (c1max > c1min)
- for (c1 = c1min; c1 <= c1max; c1++)
- for (c0 = c0min; c0 <= c0max; c0++) {
- histp = & histogram[c0][c1][c2min];
- for (c2 = c2min; c2 <= c2max; c2++)
- if (*histp++ != 0) {
- boxp->c1min = c1min = c1;
- goto have_c1min;
- }
- }
- have_c1min:
- if (c1max > c1min)
- for (c1 = c1max; c1 >= c1min; c1--)
- for (c0 = c0min; c0 <= c0max; c0++) {
- histp = & histogram[c0][c1][c2min];
- for (c2 = c2min; c2 <= c2max; c2++)
- if (*histp++ != 0) {
- boxp->c1max = c1max = c1;
- goto have_c1max;
- }
- }
- have_c1max:
- if (c2max > c2min)
- for (c2 = c2min; c2 <= c2max; c2++)
- for (c0 = c0min; c0 <= c0max; c0++) {
- histp = & histogram[c0][c1min][c2];
- for (c1 = c1min; c1 <= c1max; c1++, histp += HIST_C2_ELEMS)
- if (*histp != 0) {
- boxp->c2min = c2min = c2;
- goto have_c2min;
- }
- }
- have_c2min:
- if (c2max > c2min)
- for (c2 = c2max; c2 >= c2min; c2--)
- for (c0 = c0min; c0 <= c0max; c0++) {
- histp = & histogram[c0][c1min][c2];
- for (c1 = c1min; c1 <= c1max; c1++, histp += HIST_C2_ELEMS)
- if (*histp != 0) {
- boxp->c2max = c2max = c2;
- goto have_c2max;
- }
- }
- have_c2max:
-
- /* Update box volume.
- * We use 2-norm rather than real volume here; this biases the method
- * against making long narrow boxes, and it has the side benefit that
- * a box is splittable iff norm > 0.
- * Since the differences are expressed in histogram-cell units,
- * we have to shift back to JSAMPLE units to get consistent distances;
- * after which, we scale according to the selected distance scale factors.
- */
- dist0 = ((c0max - c0min) << C0_SHIFT) * C0_SCALE;
- dist1 = ((c1max - c1min) << C1_SHIFT) * C1_SCALE;
- dist2 = ((c2max - c2min) << C2_SHIFT) * C2_SCALE;
- boxp->volume = dist0*dist0 + dist1*dist1 + dist2*dist2;
-
- /* Now scan remaining volume of box and compute population */
- ccount = 0;
- for (c0 = c0min; c0 <= c0max; c0++)
- for (c1 = c1min; c1 <= c1max; c1++) {
- histp = & histogram[c0][c1][c2min];
- for (c2 = c2min; c2 <= c2max; c2++, histp++)
- if (*histp != 0) {
- ccount++;
- }
- }
- boxp->colorcount = ccount;
- }
-
- LOCAL(int)
- median_cut (j_decompress_ptr cinfo, boxptr boxlist, int numboxes,
- int desired_colors)
- /* Repeatedly select and split the largest box until we have enough boxes */
- {
- int n,lb;
- int c0,c1,c2,cmax;
- register boxptr b1,b2;
-
- while (numboxes < desired_colors) {
- /* Select box to split.
- * Current algorithm: by population for first half, then by volume.
- */
- if (numboxes*2 <= desired_colors) {
- b1 = find_biggest_color_pop(boxlist, numboxes);
- } else {
- b1 = find_biggest_volume(boxlist, numboxes);
- }
- if (b1 == NULL) /* no splittable boxes left! */
- break;
- b2 = &boxlist[numboxes]; /* where new box will go */
- /* Copy the color bounds to the new box. */
- b2->c0max = b1->c0max; b2->c1max = b1->c1max; b2->c2max = b1->c2max;
- b2->c0min = b1->c0min; b2->c1min = b1->c1min; b2->c2min = b1->c2min;
- /* Choose which axis to split the box on.
- * Current algorithm: longest scaled axis.
- * See notes in update_box about scaling distances.
- */
- c0 = ((b1->c0max - b1->c0min) << C0_SHIFT) * C0_SCALE;
- c1 = ((b1->c1max - b1->c1min) << C1_SHIFT) * C1_SCALE;
- c2 = ((b1->c2max - b1->c2min) << C2_SHIFT) * C2_SCALE;
- /* We want to break any ties in favor of green, then red, blue last.
- * This code does the right thing for R,G,B or B,G,R color orders only.
- */
- #if RGB_RED == 0
- cmax = c1; n = 1;
- if (c0 > cmax) { cmax = c0; n = 0; }
- if (c2 > cmax) { n = 2; }
- #else
- cmax = c1; n = 1;
- if (c2 > cmax) { cmax = c2; n = 2; }
- if (c0 > cmax) { n = 0; }
- #endif
- /* Choose split point along selected axis, and update box bounds.
- * Current algorithm: split at halfway point.
- * (Since the box has been shrunk to minimum volume,
- * any split will produce two nonempty subboxes.)
- * Note that lb value is max for lower box, so must be < old max.
- */
- switch (n) {
- case 0:
- lb = (b1->c0max + b1->c0min) / 2;
- b1->c0max = lb;
- b2->c0min = lb+1;
- break;
- case 1:
- lb = (b1->c1max + b1->c1min) / 2;
- b1->c1max = lb;
- b2->c1min = lb+1;
- break;
- case 2:
- lb = (b1->c2max + b1->c2min) / 2;
- b1->c2max = lb;
- b2->c2min = lb+1;
- break;
- }
- /* Update stats for boxes */
- update_box(cinfo, b1);
- update_box(cinfo, b2);
- numboxes++;
- }
- return numboxes;
- }
-
- LOCAL(void)
- compute_color (j_decompress_ptr cinfo, boxptr boxp, int icolor)
- /* Compute representative color for a box, put it in colormap[icolor] */
- {
- /* Current algorithm: mean weighted by pixels (not colors) */
- /* Note it is important to get the rounding correct! */
- my_cquantize_ptr2 cquantize = (my_cquantize_ptr2) cinfo->cquantize;
- hist3d histogram = cquantize->histogram;
- histptr histp;
- int c0,c1,c2;
- int c0min,c0max,c1min,c1max,c2min,c2max;
- long count;
- long total = 0;
- long c0total = 0;
- long c1total = 0;
- long c2total = 0;
-
- c0min = boxp->c0min; c0max = boxp->c0max;
- c1min = boxp->c1min; c1max = boxp->c1max;
- c2min = boxp->c2min; c2max = boxp->c2max;
-
- for (c0 = c0min; c0 <= c0max; c0++)
- for (c1 = c1min; c1 <= c1max; c1++) {
- histp = & histogram[c0][c1][c2min];
- for (c2 = c2min; c2 <= c2max; c2++) {
- if ((count = *histp++) != 0) {
- total += count;
- c0total += ((c0 << C0_SHIFT) + ((1<<C0_SHIFT)>>1)) * count;
- c1total += ((c1 << C1_SHIFT) + ((1<<C1_SHIFT)>>1)) * count;
- c2total += ((c2 << C2_SHIFT) + ((1<<C2_SHIFT)>>1)) * count;
- }
- }
- }
-
- cinfo->colormap[0][icolor] = (JSAMPLE) ((c0total + (total>>1)) / total);
- cinfo->colormap[1][icolor] = (JSAMPLE) ((c1total + (total>>1)) / total);
- cinfo->colormap[2][icolor] = (JSAMPLE) ((c2total + (total>>1)) / total);
- }
-
- LOCAL(void)
- select_colors (j_decompress_ptr cinfo, int desired_colors)
- /* Master routine for color selection */
- {
- boxptr boxlist;
- int numboxes;
- int i;
-
- /* Allocate workspace for box list */
- boxlist = (boxptr) (*cinfo->mem->alloc_small)
- ((j_common_ptr) cinfo, JPOOL_IMAGE, desired_colors * SIZEOF(box));
- /* Initialize one box containing whole space */
- numboxes = 1;
- boxlist[0].c0min = 0;
- boxlist[0].c0max = MAXJSAMPLE >> C0_SHIFT;
- boxlist[0].c1min = 0;
- boxlist[0].c1max = MAXJSAMPLE >> C1_SHIFT;
- boxlist[0].c2min = 0;
- boxlist[0].c2max = MAXJSAMPLE >> C2_SHIFT;
- /* Shrink it to actually-used volume and set its statistics */
- update_box(cinfo, & boxlist[0]);
- /* Perform median-cut to produce final box list */
- numboxes = median_cut(cinfo, boxlist, numboxes, desired_colors);
- /* Compute the representative color for each box, fill colormap */
- for (i = 0; i < numboxes; i++)
- compute_color(cinfo, & boxlist[i], i);
- cinfo->actual_number_of_colors = numboxes;
- TRACEMS1(cinfo, 1, JTRC_QUANT_SELECTED, numboxes);
- }
-
- /*
- * These routines are concerned with the time-critical task of mapping input
- * colors to the nearest color in the selected colormap.
- *
- * We re-use the histogram space as an "inverse color map", essentially a
- * cache for the results of nearest-color searches. All colors within a
- * histogram cell will be mapped to the same colormap entry, namely the one
- * closest to the cell's center. This may not be quite the closest entry to
- * the actual input color, but it's almost as good. A zero in the cache
- * indicates we haven't found the nearest color for that cell yet; the array
- * is cleared to zeroes before starting the mapping pass. When we find the
- * nearest color for a cell, its colormap index plus one is recorded in the
- * cache for future use. The pass2 scanning routines call fill_inverse_cmap
- * when they need to use an unfilled entry in the cache.
- *
- * Our method of efficiently finding nearest colors is based on the "locally
- * sorted search" idea described by Heckbert and on the incremental distance
- * calculation described by Spencer W. Thomas in chapter III.1 of Graphics
- * Gems II (James Arvo, ed. Academic Press, 1991). Thomas points out that
- * the distances from a given colormap entry to each cell of the histogram can
- * be computed quickly using an incremental method: the differences between
- * distances to adjacent cells themselves differ by a constant. This allows a
- * fairly fast implementation of the "brute force" approach of computing the
- * distance from every colormap entry to every histogram cell. Unfortunately,
- * it needs a work array to hold the best-distance-so-far for each histogram
- * cell (because the inner loop has to be over cells, not colormap entries).
- * The work array elements have to be INT32s, so the work array would need
- * 256Kb at our recommended precision. This is not feasible in DOS machines.
- *
- * To get around these problems, we apply Thomas' method to compute the
- * nearest colors for only the cells within a small subbox of the histogram.
- * The work array need be only as big as the subbox, so the memory usage
- * problem is solved. Furthermore, we need not fill subboxes that are never
- * referenced in pass2; many images use only part of the color gamut, so a
- * fair amount of work is saved. An additional advantage of this
- * approach is that we can apply Heckbert's locality criterion to quickly
- * eliminate colormap entries that are far away from the subbox; typically
- * three-fourths of the colormap entries are rejected by Heckbert's criterion,
- * and we need not compute their distances to individual cells in the subbox.
- * The speed of this approach is heavily influenced by the subbox size: too
- * small means too much overhead, too big loses because Heckbert's criterion
- * can't eliminate as many colormap entries. Empirically the best subbox
- * size seems to be about 1/512th of the histogram (1/8th in each direction).
- *
- * Thomas' article also describes a refined method which is asymptotically
- * faster than the brute-force method, but it is also far more complex and
- * cannot efficiently be applied to small subboxes. It is therefore not
- * useful for programs intended to be portable to DOS machines. On machines
- * with plenty of memory, filling the whole histogram in one shot with Thomas'
- * refined method might be faster than the present code --- but then again,
- * it might not be any faster, and it's certainly more complicated.
- */
-
- /* log2(histogram cells in update box) for each axis; this can be adjusted */
- #define BOX_C0_LOG (HIST_C0_BITS-3)
- #define BOX_C1_LOG (HIST_C1_BITS-3)
- #define BOX_C2_LOG (HIST_C2_BITS-3)
-
- #define BOX_C0_ELEMS (1<<BOX_C0_LOG) /* # of hist cells in update box */
- #define BOX_C1_ELEMS (1<<BOX_C1_LOG)
- #define BOX_C2_ELEMS (1<<BOX_C2_LOG)
-
- #define BOX_C0_SHIFT (C0_SHIFT + BOX_C0_LOG)
- #define BOX_C1_SHIFT (C1_SHIFT + BOX_C1_LOG)
- #define BOX_C2_SHIFT (C2_SHIFT + BOX_C2_LOG)
-
- /*
- * The next three routines implement inverse colormap filling. They could
- * all be folded into one big routine, but splitting them up this way saves
- * some stack space (the mindist[] and bestdist[] arrays need not coexist)
- * and may allow some compilers to produce better code by registerizing more
- * inner-loop variables.
- */
-
- LOCAL(int)
- find_nearby_colors (j_decompress_ptr cinfo, int minc0, int minc1, int minc2,
- JSAMPLE colorlist[])
- /* Locate the colormap entries close enough to an update box to be candidates
- * for the nearest entry to some cell(s) in the update box. The update box
- * is specified by the center coordinates of its first cell. The number of
- * candidate colormap entries is returned, and their colormap indexes are
- * placed in colorlist[].
- * This routine uses Heckbert's "locally sorted search" criterion to select
- * the colors that need further consideration.
- */
- {
- int numcolors = cinfo->actual_number_of_colors;
- int maxc0, maxc1, maxc2;
- int centerc0, centerc1, centerc2;
- int i, x, ncolors;
- INT32 minmaxdist, min_dist, max_dist, tdist;
- INT32 mindist[MAXNUMCOLORS]; /* min distance to colormap entry i */
-
- /* Compute true coordinates of update box's upper corner and center.
- * Actually we compute the coordinates of the center of the upper-corner
- * histogram cell, which are the upper bounds of the volume we care about.
- * Note that since ">>" rounds down, the "center" values may be closer to
- * min than to max; hence comparisons to them must be "<=", not "<".
- */
- maxc0 = minc0 + ((1 << BOX_C0_SHIFT) - (1 << C0_SHIFT));
- centerc0 = (minc0 + maxc0) >> 1;
- maxc1 = minc1 + ((1 << BOX_C1_SHIFT) - (1 << C1_SHIFT));
- centerc1 = (minc1 + maxc1) >> 1;
- maxc2 = minc2 + ((1 << BOX_C2_SHIFT) - (1 << C2_SHIFT));
- centerc2 = (minc2 + maxc2) >> 1;
-
- /* For each color in colormap, find:
- * 1. its minimum squared-distance to any point in the update box
- * (zero if color is within update box);
- * 2. its maximum squared-distance to any point in the update box.
- * Both of these can be found by considering only the corners of the box.
- * We save the minimum distance for each color in mindist[];
- * only the smallest maximum distance is of interest.
- */
- minmaxdist = 0x7FFFFFFFL;
-
- for (i = 0; i < numcolors; i++) {
- /* We compute the squared-c0-distance term, then add in the other two. */
- x = GETJSAMPLE(cinfo->colormap[0][i]);
- if (x < minc0) {
- tdist = (x - minc0) * C0_SCALE;
- min_dist = tdist*tdist;
- tdist = (x - maxc0) * C0_SCALE;
- max_dist = tdist*tdist;
- } else if (x > maxc0) {
- tdist = (x - maxc0) * C0_SCALE;
- min_dist = tdist*tdist;
- tdist = (x - minc0) * C0_SCALE;
- max_dist = tdist*tdist;
- } else {
- /* within cell range so no contribution to min_dist */
- min_dist = 0;
- if (x <= centerc0) {
- tdist = (x - maxc0) * C0_SCALE;
- max_dist = tdist*tdist;
- } else {
- tdist = (x - minc0) * C0_SCALE;
- max_dist = tdist*tdist;
- }
- }
-
- x = GETJSAMPLE(cinfo->colormap[1][i]);
- if (x < minc1) {
- tdist = (x - minc1) * C1_SCALE;
- min_dist += tdist*tdist;
- tdist = (x - maxc1) * C1_SCALE;
- max_dist += tdist*tdist;
- } else if (x > maxc1) {
- tdist = (x - maxc1) * C1_SCALE;
- min_dist += tdist*tdist;
- tdist = (x - minc1) * C1_SCALE;
- max_dist += tdist*tdist;
- } else {
- /* within cell range so no contribution to min_dist */
- if (x <= centerc1) {
- tdist = (x - maxc1) * C1_SCALE;
- max_dist += tdist*tdist;
- } else {
- tdist = (x - minc1) * C1_SCALE;
- max_dist += tdist*tdist;
- }
- }
-
- x = GETJSAMPLE(cinfo->colormap[2][i]);
- if (x < minc2) {
- tdist = (x - minc2) * C2_SCALE;
- min_dist += tdist*tdist;
- tdist = (x - maxc2) * C2_SCALE;
- max_dist += tdist*tdist;
- } else if (x > maxc2) {
- tdist = (x - maxc2) * C2_SCALE;
- min_dist += tdist*tdist;
- tdist = (x - minc2) * C2_SCALE;
- max_dist += tdist*tdist;
- } else {
- /* within cell range so no contribution to min_dist */
- if (x <= centerc2) {
- tdist = (x - maxc2) * C2_SCALE;
- max_dist += tdist*tdist;
- } else {
- tdist = (x - minc2) * C2_SCALE;
- max_dist += tdist*tdist;
- }
- }
-
- mindist[i] = min_dist; /* save away the results */
- if (max_dist < minmaxdist)
- minmaxdist = max_dist;
- }
-
- /* Now we know that no cell in the update box is more than minmaxdist
- * away from some colormap entry. Therefore, only colors that are
- * within minmaxdist of some part of the box need be considered.
- */
- ncolors = 0;
- for (i = 0; i < numcolors; i++) {
- if (mindist[i] <= minmaxdist)
- colorlist[ncolors++] = (JSAMPLE) i;
- }
- return ncolors;
- }
-
- LOCAL(void)
- find_best_colors (j_decompress_ptr cinfo, int minc0, int minc1, int minc2,
- int numcolors, JSAMPLE colorlist[], JSAMPLE bestcolor[])
- /* Find the closest colormap entry for each cell in the update box,
- * given the list of candidate colors prepared by find_nearby_colors.
- * Return the indexes of the closest entries in the bestcolor[] array.
- * This routine uses Thomas' incremental distance calculation method to
- * find the distance from a colormap entry to successive cells in the box.
- */
- {
- int ic0, ic1, ic2;
- int i, icolor;
- register INT32 * bptr; /* pointer into bestdist[] array */
- JSAMPLE * cptr; /* pointer into bestcolor[] array */
- INT32 dist0, dist1; /* initial distance values */
- register INT32 dist2; /* current distance in inner loop */
- INT32 xx0, xx1; /* distance increments */
- register INT32 xx2;
- INT32 inc0, inc1, inc2; /* initial values for increments */
- /* This array holds the distance to the nearest-so-far color for each cell */
- INT32 bestdist[BOX_C0_ELEMS * BOX_C1_ELEMS * BOX_C2_ELEMS];
-
- /* Initialize best-distance for each cell of the update box */
- bptr = bestdist;
- for (i = BOX_C0_ELEMS*BOX_C1_ELEMS*BOX_C2_ELEMS-1; i >= 0; i--)
- *bptr++ = 0x7FFFFFFFL;
-
- /* For each color selected by find_nearby_colors,
- * compute its distance to the center of each cell in the box.
- * If that's less than best-so-far, update best distance and color number.
- */
-
- /* Nominal steps between cell centers ("x" in Thomas article) */
- #define STEP_C0 ((1 << C0_SHIFT) * C0_SCALE)
- #define STEP_C1 ((1 << C1_SHIFT) * C1_SCALE)
- #define STEP_C2 ((1 << C2_SHIFT) * C2_SCALE)
-
- for (i = 0; i < numcolors; i++) {
- icolor = GETJSAMPLE(colorlist[i]);
- /* Compute (square of) distance from minc0/c1/c2 to this color */
- inc0 = (minc0 - GETJSAMPLE(cinfo->colormap[0][icolor])) * C0_SCALE;
- dist0 = inc0*inc0;
- inc1 = (minc1 - GETJSAMPLE(cinfo->colormap[1][icolor])) * C1_SCALE;
- dist0 += inc1*inc1;
- inc2 = (minc2 - GETJSAMPLE(cinfo->colormap[2][icolor])) * C2_SCALE;
- dist0 += inc2*inc2;
- /* Form the initial difference increments */
- inc0 = inc0 * (2 * STEP_C0) + STEP_C0 * STEP_C0;
- inc1 = inc1 * (2 * STEP_C1) + STEP_C1 * STEP_C1;
- inc2 = inc2 * (2 * STEP_C2) + STEP_C2 * STEP_C2;
- /* Now loop over all cells in box, updating distance per Thomas method */
- bptr = bestdist;
- cptr = bestcolor;
- xx0 = inc0;
- for (ic0 = BOX_C0_ELEMS-1; ic0 >= 0; ic0--) {
- dist1 = dist0;
- xx1 = inc1;
- for (ic1 = BOX_C1_ELEMS-1; ic1 >= 0; ic1--) {
- dist2 = dist1;
- xx2 = inc2;
- for (ic2 = BOX_C2_ELEMS-1; ic2 >= 0; ic2--) {
- if (dist2 < *bptr) {
- *bptr = dist2;
- *cptr = (JSAMPLE) icolor;
- }
- dist2 += xx2;
- xx2 += 2 * STEP_C2 * STEP_C2;
- bptr++;
- cptr++;
- }
- dist1 += xx1;
- xx1 += 2 * STEP_C1 * STEP_C1;
- }
- dist0 += xx0;
- xx0 += 2 * STEP_C0 * STEP_C0;
- }
- }
- }
-
- LOCAL(void)
- fill_inverse_cmap (j_decompress_ptr cinfo, int c0, int c1, int c2)
- /* Fill the inverse-colormap entries in the update box that contains */
- /* histogram cell c0/c1/c2. (Only that one cell MUST be filled, but */
- /* we can fill as many others as we wish.) */
- {
- my_cquantize_ptr2 cquantize = (my_cquantize_ptr2) cinfo->cquantize;
- hist3d histogram = cquantize->histogram;
- int minc0, minc1, minc2; /* lower left corner of update box */
- int ic0, ic1, ic2;
- register JSAMPLE * cptr; /* pointer into bestcolor[] array */
- register histptr cachep; /* pointer into main cache array */
- /* This array lists the candidate colormap indexes. */
- JSAMPLE colorlist[MAXNUMCOLORS];
- int numcolors; /* number of candidate colors */
- /* This array holds the actually closest colormap index for each cell. */
- JSAMPLE bestcolor[BOX_C0_ELEMS * BOX_C1_ELEMS * BOX_C2_ELEMS];
-
- /* Convert cell coordinates to update box ID */
- c0 >>= BOX_C0_LOG;
- c1 >>= BOX_C1_LOG;
- c2 >>= BOX_C2_LOG;
-
- /* Compute true coordinates of update box's origin corner.
- * Actually we compute the coordinates of the center of the corner
- * histogram cell, which are the lower bounds of the volume we care about.
- */
- minc0 = (c0 << BOX_C0_SHIFT) + ((1 << C0_SHIFT) >> 1);
- minc1 = (c1 << BOX_C1_SHIFT) + ((1 << C1_SHIFT) >> 1);
- minc2 = (c2 << BOX_C2_SHIFT) + ((1 << C2_SHIFT) >> 1);
-
- /* Determine which colormap entries are close enough to be candidates
- * for the nearest entry to some cell in the update box.
- */
- numcolors = find_nearby_colors(cinfo, minc0, minc1, minc2, colorlist);
-
- /* Determine the actually nearest colors. */
- find_best_colors(cinfo, minc0, minc1, minc2, numcolors, colorlist,
- bestcolor);
-
- /* Save the best color numbers (plus 1) in the main cache array */
- c0 <<= BOX_C0_LOG; /* convert ID back to base cell indexes */
- c1 <<= BOX_C1_LOG;
- c2 <<= BOX_C2_LOG;
- cptr = bestcolor;
- for (ic0 = 0; ic0 < BOX_C0_ELEMS; ic0++) {
- for (ic1 = 0; ic1 < BOX_C1_ELEMS; ic1++) {
- cachep = & histogram[c0+ic0][c1+ic1][c2];
- for (ic2 = 0; ic2 < BOX_C2_ELEMS; ic2++) {
- *cachep++ = (histcell) (GETJSAMPLE(*cptr++) + 1);
- }
- }
- }
- }
-
- /*
- * Map some rows of pixels to the output colormapped representation.
- */
-
- METHODDEF(void)
- pass2_no_dither (j_decompress_ptr cinfo,
- JSAMPARRAY input_buf, JSAMPARRAY output_buf, int num_rows)
- /* This version performs no dithering */
- {
- my_cquantize_ptr2 cquantize = (my_cquantize_ptr2) cinfo->cquantize;
- hist3d histogram = cquantize->histogram;
- register JSAMPROW inptr, outptr;
- register histptr cachep;
- register int c0, c1, c2;
- int row;
- JDIMENSION col;
- JDIMENSION width = cinfo->output_width;
-
- for (row = 0; row < num_rows; row++) {
- inptr = input_buf[row];
- outptr = output_buf[row];
- for (col = width; col > 0; col--) {
- /* get pixel value and index into the cache */
- c0 = GETJSAMPLE(*inptr++) >> C0_SHIFT;
- c1 = GETJSAMPLE(*inptr++) >> C1_SHIFT;
- c2 = GETJSAMPLE(*inptr++) >> C2_SHIFT;
- cachep = & histogram[c0][c1][c2];
- /* If we have not seen this color before, find nearest colormap entry */
- /* and update the cache */
- if (*cachep == 0)
- fill_inverse_cmap(cinfo, c0,c1,c2);
- /* Now emit the colormap index for this cell */
- *outptr++ = (JSAMPLE) (*cachep - 1);
- }
- }
- }
-
- METHODDEF(void)
- pass2_fs_dither (j_decompress_ptr cinfo,
- JSAMPARRAY input_buf, JSAMPARRAY output_buf, int num_rows)
- /* This version performs Floyd-Steinberg dithering */
- {
- my_cquantize_ptr2 cquantize = (my_cquantize_ptr2) cinfo->cquantize;
- hist3d histogram = cquantize->histogram;
- register LOCFSERROR cur0, cur1, cur2; /* current error or pixel value */
- LOCFSERROR belowerr0, belowerr1, belowerr2; /* error for pixel below cur */
- LOCFSERROR bpreverr0, bpreverr1, bpreverr2; /* error for below/prev col */
- register FSERRPTR errorptr; /* => fserrors[] at column before current */
- JSAMPROW inptr; /* => current input pixel */
- JSAMPROW outptr; /* => current output pixel */
- histptr cachep;
- int dir; /* +1 or -1 depending on direction */
- int dir3; /* 3*dir, for advancing inptr & errorptr */
- int row;
- JDIMENSION col;
- JDIMENSION width = cinfo->output_width;
- JSAMPLE *range_limit = cinfo->sample_range_limit;
- int *error_limit = cquantize->error_limiter;
- JSAMPROW colormap0 = cinfo->colormap[0];
- JSAMPROW colormap1 = cinfo->colormap[1];
- JSAMPROW colormap2 = cinfo->colormap[2];
- SHIFT_TEMPS
-
- for (row = 0; row < num_rows; row++) {
- inptr = input_buf[row];
- outptr = output_buf[row];
- if (cquantize->on_odd_row) {
- /* work right to left in this row */
- inptr += (width-1) * 3; /* so point to rightmost pixel */
- outptr += width-1;
- dir = -1;
- dir3 = -3;
- errorptr = cquantize->fserrors + (width+1)*3; /* => entry after last column */
- cquantize->on_odd_row = FALSE; /* flip for next time */
- } else {
- /* work left to right in this row */
- dir = 1;
- dir3 = 3;
- errorptr = cquantize->fserrors; /* => entry before first real column */
- cquantize->on_odd_row = TRUE; /* flip for next time */
- }
- /* Preset error values: no error propagated to first pixel from left */
- cur0 = cur1 = cur2 = 0;
- /* and no error propagated to row below yet */
- belowerr0 = belowerr1 = belowerr2 = 0;
- bpreverr0 = bpreverr1 = bpreverr2 = 0;
-
- for (col = width; col > 0; col--) {
- /* curN holds the error propagated from the previous pixel on the
- * current line. Add the error propagated from the previous line
- * to form the complete error correction term for this pixel, and
- * round the error term (which is expressed * 16) to an integer.
- * RIGHT_SHIFT rounds towards minus infinity, so adding 8 is correct
- * for either sign of the error value.
- * Note: errorptr points to *previous* column's array entry.
- */
- cur0 = RIGHT_SHIFT(cur0 + errorptr[dir3+0] + 8, 4);
- cur1 = RIGHT_SHIFT(cur1 + errorptr[dir3+1] + 8, 4);
- cur2 = RIGHT_SHIFT(cur2 + errorptr[dir3+2] + 8, 4);
- /* Limit the error using transfer function set by init_error_limit.
- * See comments with init_error_limit for rationale.
- */
- cur0 = error_limit[cur0];
- cur1 = error_limit[cur1];
- cur2 = error_limit[cur2];
- /* Form pixel value + error, and range-limit to 0..MAXJSAMPLE.
- * The maximum error is +- MAXJSAMPLE (or less with error limiting);
- * this sets the required size of the range_limit array.
- */
- cur0 += GETJSAMPLE(inptr[0]);
- cur1 += GETJSAMPLE(inptr[1]);
- cur2 += GETJSAMPLE(inptr[2]);
- cur0 = GETJSAMPLE(range_limit[cur0]);
- cur1 = GETJSAMPLE(range_limit[cur1]);
- cur2 = GETJSAMPLE(range_limit[cur2]);
- /* Index into the cache with adjusted pixel value */
- cachep = & histogram[cur0>>C0_SHIFT][cur1>>C1_SHIFT][cur2>>C2_SHIFT];
- /* If we have not seen this color before, find nearest colormap */
- /* entry and update the cache */
- if (*cachep == 0)
- fill_inverse_cmap(cinfo, cur0>>C0_SHIFT,cur1>>C1_SHIFT,cur2>>C2_SHIFT);
- /* Now emit the colormap index for this cell */
- { register int pixcode = *cachep - 1;
- *outptr = (JSAMPLE) pixcode;
- /* Compute representation error for this pixel */
- cur0 -= GETJSAMPLE(colormap0[pixcode]);
- cur1 -= GETJSAMPLE(colormap1[pixcode]);
- cur2 -= GETJSAMPLE(colormap2[pixcode]);
- }
- /* Compute error fractions to be propagated to adjacent pixels.
- * Add these into the running sums, and simultaneously shift the
- * next-line error sums left by 1 column.
- */
- { register LOCFSERROR bnexterr, delta;
-
- bnexterr = cur0; /* Process component 0 */
- delta = cur0 * 2;
- cur0 += delta; /* form error * 3 */
- errorptr[0] = (FSERROR) (bpreverr0 + cur0);
- cur0 += delta; /* form error * 5 */
- bpreverr0 = belowerr0 + cur0;
- belowerr0 = bnexterr;
- cur0 += delta; /* form error * 7 */
- bnexterr = cur1; /* Process component 1 */
- delta = cur1 * 2;
- cur1 += delta; /* form error * 3 */
- errorptr[1] = (FSERROR) (bpreverr1 + cur1);
- cur1 += delta; /* form error * 5 */
- bpreverr1 = belowerr1 + cur1;
- belowerr1 = bnexterr;
- cur1 += delta; /* form error * 7 */
- bnexterr = cur2; /* Process component 2 */
- delta = cur2 * 2;
- cur2 += delta; /* form error * 3 */
- errorptr[2] = (FSERROR) (bpreverr2 + cur2);
- cur2 += delta; /* form error * 5 */
- bpreverr2 = belowerr2 + cur2;
- belowerr2 = bnexterr;
- cur2 += delta; /* form error * 7 */
- }
- /* At this point curN contains the 7/16 error value to be propagated
- * to the next pixel on the current line, and all the errors for the
- * next line have been shifted over. We are therefore ready to move on.
- */
- inptr += dir3; /* Advance pixel pointers to next column */
- outptr += dir;
- errorptr += dir3; /* advance errorptr to current column */
- }
- /* Post-loop cleanup: we must unload the final error values into the
- * final fserrors[] entry. Note we need not unload belowerrN because
- * it is for the dummy column before or after the actual array.
- */
- errorptr[0] = (FSERROR) bpreverr0; /* unload prev errs into array */
- errorptr[1] = (FSERROR) bpreverr1;
- errorptr[2] = (FSERROR) bpreverr2;
- }
- }
-
- /*
- * Initialize the error-limiting transfer function (lookup table).
- * The raw F-S error computation can potentially compute error values of up to
- * +- MAXJSAMPLE. But we want the maximum correction applied to a pixel to be
- * much less, otherwise obviously wrong pixels will be created. (Typical
- * effects include weird fringes at color-area boundaries, isolated bright
- * pixels in a dark area, etc.) The standard advice for avoiding this problem
- * is to ensure that the "corners" of the color cube are allocated as output
- * colors; then repeated errors in the same direction cannot cause cascading
- * error buildup. However, that only prevents the error from getting
- * completely out of hand; Aaron Giles reports that error limiting improves
- * the results even with corner colors allocated.
- * A simple clamping of the error values to about +- MAXJSAMPLE/8 works pretty
- * well, but the smoother transfer function used below is even better. Thanks
- * to Aaron Giles for this idea.
- */
-
- LOCAL(void)
- init_error_limit (j_decompress_ptr cinfo)
- /* Allocate and fill in the error_limiter table */
- {
- my_cquantize_ptr2 cquantize = (my_cquantize_ptr2) cinfo->cquantize;
- int * table;
- int in, out;
-
- table = (int *) (*cinfo->mem->alloc_small)
- ((j_common_ptr) cinfo, JPOOL_IMAGE, (MAXJSAMPLE*2+1) * SIZEOF(int));
- table += MAXJSAMPLE; /* so can index -MAXJSAMPLE .. +MAXJSAMPLE */
- cquantize->error_limiter = table;
-
- #define STEPSIZE ((MAXJSAMPLE+1)/16)
- /* Map errors 1:1 up to +- MAXJSAMPLE/16 */
- out = 0;
- for (in = 0; in < STEPSIZE; in++, out++) {
- table[in] = out; table[-in] = -out;
- }
- /* Map errors 1:2 up to +- 3*MAXJSAMPLE/16 */
- for (; in < STEPSIZE*3; in++, out += (in&1) ? 0 : 1) {
- table[in] = out; table[-in] = -out;
- }
- /* Clamp the rest to final out value (which is (MAXJSAMPLE+1)/8) */
- for (; in <= MAXJSAMPLE; in++) {
- table[in] = out; table[-in] = -out;
- }
- #undef STEPSIZE
- }
-
- /*
- * Finish up at the end of each pass.
- */
-
- METHODDEF(void)
- finish_pass1 (j_decompress_ptr cinfo)
- {
- my_cquantize_ptr2 cquantize = (my_cquantize_ptr2) cinfo->cquantize;
-
- /* Select the representative colors and fill in cinfo->colormap */
- cinfo->colormap = cquantize->sv_colormap;
- select_colors(cinfo, cquantize->desired);
- /* Force next pass to zero the color index table */
- cquantize->needs_zeroed = TRUE;
- }
-
- METHODDEF(void)
- finish_pass2 (j_decompress_ptr cinfo)
- {
- /* no work */
- }
-
- /*
- * Initialize for each processing pass.
- */
-
- METHODDEF(void)
- start_pass_2_quant (j_decompress_ptr cinfo, boolean is_pre_scan)
- {
- my_cquantize_ptr2 cquantize = (my_cquantize_ptr2) cinfo->cquantize;
- hist3d histogram = cquantize->histogram;
- int i;
-
- /* Only F-S dithering or no dithering is supported. */
- /* If user asks for ordered dither, give him F-S. */
- if (cinfo->dither_mode != JDITHER_NONE)
- cinfo->dither_mode = JDITHER_FS;
-
- if (is_pre_scan) {
- /* Set up method pointers */
- cquantize->pub.color_quantize = prescan_quantize;
- cquantize->pub.finish_pass = finish_pass1;
- cquantize->needs_zeroed = TRUE; /* Always zero histogram */
- } else {
- /* Set up method pointers */
- if (cinfo->dither_mode == JDITHER_FS)
- cquantize->pub.color_quantize = pass2_fs_dither;
- else
- cquantize->pub.color_quantize = pass2_no_dither;
- cquantize->pub.finish_pass = finish_pass2;
-
- /* Make sure color count is acceptable */
- i = cinfo->actual_number_of_colors;
- if (i < 1)
- ERREXIT1(cinfo, JERR_QUANT_FEW_COLORS, 1);
- if (i > MAXNUMCOLORS)
- ERREXIT1(cinfo, JERR_QUANT_MANY_COLORS, MAXNUMCOLORS);
-
- if (cinfo->dither_mode == JDITHER_FS) {
- size_t arraysize = (size_t) ((cinfo->output_width + 2) *
- (3 * SIZEOF(FSERROR)));
- /* Allocate Floyd-Steinberg workspace if we didn't already. */
- if (cquantize->fserrors == NULL)
- cquantize->fserrors = (FSERRPTR) (*cinfo->mem->alloc_large)
- ((j_common_ptr) cinfo, JPOOL_IMAGE, arraysize);
- /* Initialize the propagated errors to zero. */
- jzero_far((void FAR *) cquantize->fserrors, arraysize);
- /* Make the error-limit table if we didn't already. */
- if (cquantize->error_limiter == NULL)
- init_error_limit(cinfo);
- cquantize->on_odd_row = FALSE;
- }
-
- }
- /* Zero the histogram or inverse color map, if necessary */
- if (cquantize->needs_zeroed) {
- for (i = 0; i < HIST_C0_ELEMS; i++) {
- jzero_far((void FAR *) histogram[i],
- HIST_C1_ELEMS*HIST_C2_ELEMS * SIZEOF(histcell));
- }
- cquantize->needs_zeroed = FALSE;
- }
- }
-
- /*
- * Switch to a new external colormap between output passes.
- */
-
- METHODDEF(void)
- new_color_map_2_quant (j_decompress_ptr cinfo)
- {
- my_cquantize_ptr2 cquantize = (my_cquantize_ptr2) cinfo->cquantize;
-
- /* Reset the inverse color map */
- cquantize->needs_zeroed = TRUE;
- }
-
- /*
- * Module initialization routine for 2-pass color quantization.
- */
-
- GLOBAL(void)
- jinit_2pass_quantizer (j_decompress_ptr cinfo)
- {
- my_cquantize_ptr2 cquantize;
- int i;
-
- cquantize = (my_cquantize_ptr2)
- (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
- SIZEOF(my_cquantizer2));
- cinfo->cquantize = (struct jpeg_color_quantizer *) cquantize;
- cquantize->pub.start_pass = start_pass_2_quant;
- cquantize->pub.new_color_map = new_color_map_2_quant;
- cquantize->fserrors = NULL; /* flag optional arrays not allocated */
- cquantize->error_limiter = NULL;
-
- /* Make sure jdmaster didn't give me a case I can't handle */
- if (cinfo->out_color_components != 3)
- ERREXIT(cinfo, JERR_NOTIMPL);
-
- /* Allocate the histogram/inverse colormap storage */
- cquantize->histogram = (hist3d) (*cinfo->mem->alloc_small)
- ((j_common_ptr) cinfo, JPOOL_IMAGE, HIST_C0_ELEMS * SIZEOF(hist2d));
- for (i = 0; i < HIST_C0_ELEMS; i++) {
- cquantize->histogram[i] = (hist2d) (*cinfo->mem->alloc_large)
- ((j_common_ptr) cinfo, JPOOL_IMAGE,
- HIST_C1_ELEMS*HIST_C2_ELEMS * SIZEOF(histcell));
- }
- cquantize->needs_zeroed = TRUE; /* histogram is garbage now */
-
- /* Allocate storage for the completed colormap, if required.
- * We do this now since it is FAR storage and may affect
- * the memory manager's space calculations.
- */
- if (cinfo->enable_2pass_quant) {
- /* Make sure color count is acceptable */
- int desired = cinfo->desired_number_of_colors;
- /* Lower bound on # of colors ... somewhat arbitrary as long as > 0 */
- if (desired < 8)
- ERREXIT1(cinfo, JERR_QUANT_FEW_COLORS, 8);
- /* Make sure colormap indexes can be represented by JSAMPLEs */
- if (desired > MAXNUMCOLORS)
- ERREXIT1(cinfo, JERR_QUANT_MANY_COLORS, MAXNUMCOLORS);
- cquantize->sv_colormap = (*cinfo->mem->alloc_sarray)
- ((j_common_ptr) cinfo,JPOOL_IMAGE, (JDIMENSION) desired, (JDIMENSION) 3);
- cquantize->desired = desired;
- } else
- cquantize->sv_colormap = NULL;
-
- /* Only F-S dithering or no dithering is supported. */
- /* If user asks for ordered dither, give him F-S. */
- if (cinfo->dither_mode != JDITHER_NONE)
- cinfo->dither_mode = JDITHER_FS;
-
- /* Allocate Floyd-Steinberg workspace if necessary.
- * This isn't really needed until pass 2, but again it is FAR storage.
- * Although we will cope with a later change in dither_mode,
- * we do not promise to honor max_memory_to_use if dither_mode changes.
- */
- if (cinfo->dither_mode == JDITHER_FS) {
- cquantize->fserrors = (FSERRPTR) (*cinfo->mem->alloc_large)
- ((j_common_ptr) cinfo, JPOOL_IMAGE,
- (size_t) ((cinfo->output_width + 2) * (3 * SIZEOF(FSERROR))));
- /* Might as well create the error-limiting table too. */
- init_error_limit(cinfo);
- }
- }
-
- #endif /* QUANT_2PASS_SUPPORTED */
- /********* End of inlined file: jquant2.c *********/
-
- /********* Start of inlined file: jutils.c *********/
- #define JPEG_INTERNALS
-
- /*
- * jpeg_zigzag_order[i] is the zigzag-order position of the i'th element
- * of a DCT block read in natural order (left to right, top to bottom).
- */
-
- #if 0 /* This table is not actually needed in v6a */
-
- const int jpeg_zigzag_order[DCTSIZE2] = {
- 0, 1, 5, 6, 14, 15, 27, 28,
- 2, 4, 7, 13, 16, 26, 29, 42,
- 3, 8, 12, 17, 25, 30, 41, 43,
- 9, 11, 18, 24, 31, 40, 44, 53,
- 10, 19, 23, 32, 39, 45, 52, 54,
- 20, 22, 33, 38, 46, 51, 55, 60,
- 21, 34, 37, 47, 50, 56, 59, 61,
- 35, 36, 48, 49, 57, 58, 62, 63
- };
-
- #endif
-
- /*
- * jpeg_natural_order[i] is the natural-order position of the i'th element
- * of zigzag order.
- *
- * When reading corrupted data, the Huffman decoders could attempt
- * to reference an entry beyond the end of this array (if the decoded
- * zero run length reaches past the end of the block). To prevent
- * wild stores without adding an inner-loop test, we put some extra
- * "63"s after the real entries. This will cause the extra coefficient
- * to be stored in location 63 of the block, not somewhere random.
- * The worst case would be a run-length of 15, which means we need 16
- * fake entries.
- */
-
- const int jpeg_natural_order[DCTSIZE2+16] = {
- 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,
- 63, 63, 63, 63, 63, 63, 63, 63, /* extra entries for safety in decoder */
- 63, 63, 63, 63, 63, 63, 63, 63
- };
-
- /*
- * Arithmetic utilities
- */
-
- GLOBAL(long)
- jdiv_round_up (long a, long b)
- /* Compute a/b rounded up to next integer, ie, ceil(a/b) */
- /* Assumes a >= 0, b > 0 */
- {
- return (a + b - 1L) / b;
- }
-
- GLOBAL(long)
- jround_up (long a, long b)
- /* Compute a rounded up to next multiple of b, ie, ceil(a/b)*b */
- /* Assumes a >= 0, b > 0 */
- {
- a += b - 1L;
- return a - (a % b);
- }
-
- /* On normal machines we can apply MEMCOPY() and MEMZERO() to sample arrays
- * and coefficient-block arrays. This won't work on 80x86 because the arrays
- * are FAR and we're assuming a small-pointer memory model. However, some
- * DOS compilers provide far-pointer versions of memcpy() and memset() even
- * in the small-model libraries. These will be used if USE_FMEM is defined.
- * Otherwise, the routines below do it the hard way. (The performance cost
- * is not all that great, because these routines aren't very heavily used.)
- */
-
- #ifndef NEED_FAR_POINTERS /* normal case, same as regular macros */
- #define FMEMCOPY(dest,src,size) MEMCOPY(dest,src,size)
- #define FMEMZERO(target,size) MEMZERO(target,size)
- #else /* 80x86 case, define if we can */
- #ifdef USE_FMEM
- #define FMEMCOPY(dest,src,size) _fmemcpy((void FAR *)(dest), (const void FAR *)(src), (size_t)(size))
- #define FMEMZERO(target,size) _fmemset((void FAR *)(target), 0, (size_t)(size))
- #endif
- #endif
-
- GLOBAL(void)
- jcopy_sample_rows (JSAMPARRAY input_array, int source_row,
- JSAMPARRAY output_array, int dest_row,
- int num_rows, JDIMENSION num_cols)
- /* Copy some rows of samples from one place to another.
- * num_rows rows are copied from input_array[source_row++]
- * to output_array[dest_row++]; these areas may overlap for duplication.
- * The source and destination arrays must be at least as wide as num_cols.
- */
- {
- register JSAMPROW inptr, outptr;
- #ifdef FMEMCOPY
- register size_t count = (size_t) (num_cols * SIZEOF(JSAMPLE));
- #else
- register JDIMENSION count;
- #endif
- register int row;
-
- input_array += source_row;
- output_array += dest_row;
-
- for (row = num_rows; row > 0; row--) {
- inptr = *input_array++;
- outptr = *output_array++;
- #ifdef FMEMCOPY
- FMEMCOPY(outptr, inptr, count);
- #else
- for (count = num_cols; count > 0; count--)
- *outptr++ = *inptr++; /* needn't bother with GETJSAMPLE() here */
- #endif
- }
- }
-
- GLOBAL(void)
- jcopy_block_row (JBLOCKROW input_row, JBLOCKROW output_row,
- JDIMENSION num_blocks)
- /* Copy a row of coefficient blocks from one place to another. */
- {
- #ifdef FMEMCOPY
- FMEMCOPY(output_row, input_row, num_blocks * (DCTSIZE2 * SIZEOF(JCOEF)));
- #else
- register JCOEFPTR inptr, outptr;
- register long count;
-
- inptr = (JCOEFPTR) input_row;
- outptr = (JCOEFPTR) output_row;
- for (count = (long) num_blocks * DCTSIZE2; count > 0; count--) {
- *outptr++ = *inptr++;
- }
- #endif
- }
-
- GLOBAL(void)
- jzero_far (void FAR * target, size_t bytestozero)
- /* Zero out a chunk of FAR memory. */
- /* This might be sample-array data, block-array data, or alloc_large data. */
- {
- #ifdef FMEMZERO
- FMEMZERO(target, bytestozero);
- #else
- register char FAR * ptr = (char FAR *) target;
- register size_t count;
-
- for (count = bytestozero; count > 0; count--) {
- *ptr++ = 0;
- }
- #endif
- }
- /********* End of inlined file: jutils.c *********/
-
- /********* Start of inlined file: transupp.c *********/
- /* Although this file really shouldn't have access to the library internals,
- * it's helpful to let it call jround_up() and jcopy_block_row().
- */
- #define JPEG_INTERNALS
-
- /********* Start of inlined file: transupp.h *********/
- /* If you happen not to want the image transform support, disable it here */
- #ifndef TRANSFORMS_SUPPORTED
- #define TRANSFORMS_SUPPORTED 1 /* 0 disables transform code */
- #endif
-
- /* Short forms of external names for systems with brain-damaged linkers. */
-
- #ifdef NEED_SHORT_EXTERNAL_NAMES
- #define jtransform_request_workspace jTrRequest
- #define jtransform_adjust_parameters jTrAdjust
- #define jtransform_execute_transformation jTrExec
- #define jcopy_markers_setup jCMrkSetup
- #define jcopy_markers_execute jCMrkExec
- #endif /* NEED_SHORT_EXTERNAL_NAMES */
-
- /*
- * Codes for supported types of image transformations.
- */
-
- typedef enum {
- JXFORM_NONE, /* no transformation */
- JXFORM_FLIP_H, /* horizontal flip */
- JXFORM_FLIP_V, /* vertical flip */
- JXFORM_TRANSPOSE, /* transpose across UL-to-LR axis */
- JXFORM_TRANSVERSE, /* transpose across UR-to-LL axis */
- JXFORM_ROT_90, /* 90-degree clockwise rotation */
- JXFORM_ROT_180, /* 180-degree rotation */
- JXFORM_ROT_270 /* 270-degree clockwise (or 90 ccw) */
- } JXFORM_CODE;
-
- /*
- * Although rotating and flipping data expressed as DCT coefficients is not
- * hard, there is an asymmetry in the JPEG format specification for images
- * whose dimensions aren't multiples of the iMCU size. The right and bottom
- * image edges are padded out to the next iMCU boundary with junk data; but
- * no padding is possible at the top and left edges. If we were to flip
- * the whole image including the pad data, then pad garbage would become
- * visible at the top and/or left, and real pixels would disappear into the
- * pad margins --- perhaps permanently, since encoders & decoders may not
- * bother to preserve DCT blocks that appear to be completely outside the
- * nominal image area. So, we have to exclude any partial iMCUs from the
- * basic transformation.
- *
- * Transpose is the only transformation that can handle partial iMCUs at the
- * right and bottom edges completely cleanly. flip_h can flip partial iMCUs
- * at the bottom, but leaves any partial iMCUs at the right edge untouched.
- * Similarly flip_v leaves any partial iMCUs at the bottom edge untouched.
- * The other transforms are defined as combinations of these basic transforms
- * and process edge blocks in a way that preserves the equivalence.
- *
- * The "trim" option causes untransformable partial iMCUs to be dropped;
- * this is not strictly lossless, but it usually gives the best-looking
- * result for odd-size images. Note that when this option is active,
- * the expected mathematical equivalences between the transforms may not hold.
- * (For example, -rot 270 -trim trims only the bottom edge, but -rot 90 -trim
- * followed by -rot 180 -trim trims both edges.)
- *
- * We also offer a "force to grayscale" option, which simply discards the
- * chrominance channels of a YCbCr image. This is lossless in the sense that
- * the luminance channel is preserved exactly. It's not the same kind of
- * thing as the rotate/flip transformations, but it's convenient to handle it
- * as part of this package, mainly because the transformation routines have to
- * be aware of the option to know how many components to work on.
- */
-
- typedef struct {
- /* Options: set by caller */
- JXFORM_CODE transform; /* image transform operator */
- boolean trim; /* if TRUE, trim partial MCUs as needed */
- boolean force_grayscale; /* if TRUE, convert color image to grayscale */
-
- /* Internal workspace: caller should not touch these */
- int num_components; /* # of components in workspace */
- jvirt_barray_ptr * workspace_coef_arrays; /* workspace for transformations */
- } jpeg_transform_info;
-
- #if TRANSFORMS_SUPPORTED
-
- /* Request any required workspace */
- EXTERN(void) jtransform_request_workspace
- JPP((j_decompress_ptr srcinfo, jpeg_transform_info *info));
- /* Adjust output image parameters */
- EXTERN(jvirt_barray_ptr *) jtransform_adjust_parameters
- JPP((j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
- jvirt_barray_ptr *src_coef_arrays,
- jpeg_transform_info *info));
- /* Execute the actual transformation, if any */
- EXTERN(void) jtransform_execute_transformation
- JPP((j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
- jvirt_barray_ptr *src_coef_arrays,
- jpeg_transform_info *info));
-
- #endif /* TRANSFORMS_SUPPORTED */
-
- /*
- * Support for copying optional markers from source to destination file.
- */
-
- typedef enum {
- JCOPYOPT_NONE, /* copy no optional markers */
- JCOPYOPT_COMMENTS, /* copy only comment (COM) markers */
- JCOPYOPT_ALL /* copy all optional markers */
- } JCOPY_OPTION;
-
- #define JCOPYOPT_DEFAULT JCOPYOPT_COMMENTS /* recommended default */
-
- /* Setup decompression object to save desired markers in memory */
- EXTERN(void) jcopy_markers_setup
- JPP((j_decompress_ptr srcinfo, JCOPY_OPTION option));
- /* Copy markers saved in the given source object to the destination object */
- EXTERN(void) jcopy_markers_execute
- JPP((j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
- JCOPY_OPTION option));
- /********* End of inlined file: transupp.h *********/
-
- /* My own external interface */
-
- #if TRANSFORMS_SUPPORTED
-
- /*
- * Lossless image transformation routines. These routines work on DCT
- * coefficient arrays and thus do not require any lossy decompression
- * or recompression of the image.
- * Thanks to Guido Vollbeding for the initial design and code of this feature.
- *
- * Horizontal flipping is done in-place, using a single top-to-bottom
- * pass through the virtual source array. It will thus be much the
- * fastest option for images larger than main memory.
- *
- * The other routines require a set of destination virtual arrays, so they
- * need twice as much memory as jpegtran normally does. The destination
- * arrays are always written in normal scan order (top to bottom) because
- * the virtual array manager expects this. The source arrays will be scanned
- * in the corresponding order, which means multiple passes through the source
- * arrays for most of the transforms. That could result in much thrashing
- * if the image is larger than main memory.
- *
- * Some notes about the operating environment of the individual transform
- * routines:
- * 1. Both the source and destination virtual arrays are allocated from the
- * source JPEG object, and therefore should be manipulated by calling the
- * source's memory manager.
- * 2. The destination's component count should be used. It may be smaller
- * than the source's when forcing to grayscale.
- * 3. Likewise the destination's sampling factors should be used. When
- * forcing to grayscale the destination's sampling factors will be all 1,
- * and we may as well take that as the effective iMCU size.
- * 4. When "trim" is in effect, the destination's dimensions will be the
- * trimmed values but the source's will be untrimmed.
- * 5. All the routines assume that the source and destination buffers are
- * padded out to a full iMCU boundary. This is true, although for the
- * source buffer it is an undocumented property of jdcoefct.c.
- * Notes 2,3,4 boil down to this: generally we should use the destination's
- * dimensions and ignore the source's.
- */
-
- LOCAL(void)
- do_flip_h (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
- jvirt_barray_ptr *src_coef_arrays)
- /* Horizontal flip; done in-place, so no separate dest array is required */
- {
- JDIMENSION MCU_cols, comp_width, blk_x, blk_y;
- int ci, k, offset_y;
- JBLOCKARRAY buffer;
- JCOEFPTR ptr1, ptr2;
- JCOEF temp1, temp2;
- jpeg_component_info *compptr;
-
- /* Horizontal mirroring of DCT blocks is accomplished by swapping
- * pairs of blocks in-place. Within a DCT block, we perform horizontal
- * mirroring by changing the signs of odd-numbered columns.
- * Partial iMCUs at the right edge are left untouched.
- */
- MCU_cols = dstinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE);
-
- for (ci = 0; ci < dstinfo->num_components; ci++) {
- compptr = dstinfo->comp_info + ci;
- comp_width = MCU_cols * compptr->h_samp_factor;
- for (blk_y = 0; blk_y < compptr->height_in_blocks;
- blk_y += compptr->v_samp_factor) {
- buffer = (*srcinfo->mem->access_virt_barray)
- ((j_common_ptr) srcinfo, src_coef_arrays[ci], blk_y,
- (JDIMENSION) compptr->v_samp_factor, TRUE);
- for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
- for (blk_x = 0; blk_x * 2 < comp_width; blk_x++) {
- ptr1 = buffer[offset_y][blk_x];
- ptr2 = buffer[offset_y][comp_width - blk_x - 1];
- /* this unrolled loop doesn't need to know which row it's on... */
- for (k = 0; k < DCTSIZE2; k += 2) {
- temp1 = *ptr1; /* swap even column */
- temp2 = *ptr2;
- *ptr1++ = temp2;
- *ptr2++ = temp1;
- temp1 = *ptr1; /* swap odd column with sign change */
- temp2 = *ptr2;
- *ptr1++ = -temp2;
- *ptr2++ = -temp1;
- }
- }
- }
- }
- }
- }
-
- LOCAL(void)
- do_flip_v (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
- jvirt_barray_ptr *src_coef_arrays,
- jvirt_barray_ptr *dst_coef_arrays)
- /* Vertical flip */
- {
- JDIMENSION MCU_rows, comp_height, dst_blk_x, dst_blk_y;
- int ci, i, j, offset_y;
- JBLOCKARRAY src_buffer, dst_buffer;
- JBLOCKROW src_row_ptr, dst_row_ptr;
- JCOEFPTR src_ptr, dst_ptr;
- jpeg_component_info *compptr;
-
- /* We output into a separate array because we can't touch different
- * rows of the source virtual array simultaneously. Otherwise, this
- * is a pretty straightforward analog of horizontal flip.
- * Within a DCT block, vertical mirroring is done by changing the signs
- * of odd-numbered rows.
- * Partial iMCUs at the bottom edge are copied verbatim.
- */
- MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE);
-
- for (ci = 0; ci < dstinfo->num_components; ci++) {
- compptr = dstinfo->comp_info + ci;
- comp_height = MCU_rows * compptr->v_samp_factor;
- for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
- dst_blk_y += compptr->v_samp_factor) {
- dst_buffer = (*srcinfo->mem->access_virt_barray)
- ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
- (JDIMENSION) compptr->v_samp_factor, TRUE);
- if (dst_blk_y < comp_height) {
- /* Row is within the mirrorable area. */
- src_buffer = (*srcinfo->mem->access_virt_barray)
- ((j_common_ptr) srcinfo, src_coef_arrays[ci],
- comp_height - dst_blk_y - (JDIMENSION) compptr->v_samp_factor,
- (JDIMENSION) compptr->v_samp_factor, FALSE);
- } else {
- /* Bottom-edge blocks will be copied verbatim. */
- src_buffer = (*srcinfo->mem->access_virt_barray)
- ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_y,
- (JDIMENSION) compptr->v_samp_factor, FALSE);
- }
- for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
- if (dst_blk_y < comp_height) {
- /* Row is within the mirrorable area. */
- dst_row_ptr = dst_buffer[offset_y];
- src_row_ptr = src_buffer[compptr->v_samp_factor - offset_y - 1];
- for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
- dst_blk_x++) {
- dst_ptr = dst_row_ptr[dst_blk_x];
- src_ptr = src_row_ptr[dst_blk_x];
- for (i = 0; i < DCTSIZE; i += 2) {
- /* copy even row */
- for (j = 0; j < DCTSIZE; j++)
- *dst_ptr++ = *src_ptr++;
- /* copy odd row with sign change */
- for (j = 0; j < DCTSIZE; j++)
- *dst_ptr++ = - *src_ptr++;
- }
- }
- } else {
- /* Just copy row verbatim. */
- jcopy_block_row(src_buffer[offset_y], dst_buffer[offset_y],
- compptr->width_in_blocks);
- }
- }
- }
- }
- }
-
- LOCAL(void)
- do_transpose (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
- jvirt_barray_ptr *src_coef_arrays,
- jvirt_barray_ptr *dst_coef_arrays)
- /* Transpose source into destination */
- {
- JDIMENSION dst_blk_x, dst_blk_y;
- int ci, i, j, offset_x, offset_y;
- JBLOCKARRAY src_buffer, dst_buffer;
- JCOEFPTR src_ptr, dst_ptr;
- jpeg_component_info *compptr;
-
- /* Transposing pixels within a block just requires transposing the
- * DCT coefficients.
- * Partial iMCUs at the edges require no special treatment; we simply
- * process all the available DCT blocks for every component.
- */
- for (ci = 0; ci < dstinfo->num_components; ci++) {
- compptr = dstinfo->comp_info + ci;
- for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
- dst_blk_y += compptr->v_samp_factor) {
- dst_buffer = (*srcinfo->mem->access_virt_barray)
- ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
- (JDIMENSION) compptr->v_samp_factor, TRUE);
- for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
- for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
- dst_blk_x += compptr->h_samp_factor) {
- src_buffer = (*srcinfo->mem->access_virt_barray)
- ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_x,
- (JDIMENSION) compptr->h_samp_factor, FALSE);
- for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) {
- src_ptr = src_buffer[offset_x][dst_blk_y + offset_y];
- dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x];
- for (i = 0; i < DCTSIZE; i++)
- for (j = 0; j < DCTSIZE; j++)
- dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
- }
- }
- }
- }
- }
- }
-
- LOCAL(void)
- do_rot_90 (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
- jvirt_barray_ptr *src_coef_arrays,
- jvirt_barray_ptr *dst_coef_arrays)
- /* 90 degree rotation is equivalent to
- * 1. Transposing the image;
- * 2. Horizontal mirroring.
- * These two steps are merged into a single processing routine.
- */
- {
- JDIMENSION MCU_cols, comp_width, dst_blk_x, dst_blk_y;
- int ci, i, j, offset_x, offset_y;
- JBLOCKARRAY src_buffer, dst_buffer;
- JCOEFPTR src_ptr, dst_ptr;
- jpeg_component_info *compptr;
-
- /* Because of the horizontal mirror step, we can't process partial iMCUs
- * at the (output) right edge properly. They just get transposed and
- * not mirrored.
- */
- MCU_cols = dstinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE);
-
- for (ci = 0; ci < dstinfo->num_components; ci++) {
- compptr = dstinfo->comp_info + ci;
- comp_width = MCU_cols * compptr->h_samp_factor;
- for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
- dst_blk_y += compptr->v_samp_factor) {
- dst_buffer = (*srcinfo->mem->access_virt_barray)
- ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
- (JDIMENSION) compptr->v_samp_factor, TRUE);
- for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
- for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
- dst_blk_x += compptr->h_samp_factor) {
- src_buffer = (*srcinfo->mem->access_virt_barray)
- ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_x,
- (JDIMENSION) compptr->h_samp_factor, FALSE);
- for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) {
- src_ptr = src_buffer[offset_x][dst_blk_y + offset_y];
- if (dst_blk_x < comp_width) {
- /* Block is within the mirrorable area. */
- dst_ptr = dst_buffer[offset_y]
- [comp_width - dst_blk_x - offset_x - 1];
- for (i = 0; i < DCTSIZE; i++) {
- for (j = 0; j < DCTSIZE; j++)
- dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
- i++;
- for (j = 0; j < DCTSIZE; j++)
- dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j];
- }
- } else {
- /* Edge blocks are transposed but not mirrored. */
- dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x];
- for (i = 0; i < DCTSIZE; i++)
- for (j = 0; j < DCTSIZE; j++)
- dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
- }
- }
- }
- }
- }
- }
- }
-
- LOCAL(void)
- do_rot_270 (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
- jvirt_barray_ptr *src_coef_arrays,
- jvirt_barray_ptr *dst_coef_arrays)
- /* 270 degree rotation is equivalent to
- * 1. Horizontal mirroring;
- * 2. Transposing the image.
- * These two steps are merged into a single processing routine.
- */
- {
- JDIMENSION MCU_rows, comp_height, dst_blk_x, dst_blk_y;
- int ci, i, j, offset_x, offset_y;
- JBLOCKARRAY src_buffer, dst_buffer;
- JCOEFPTR src_ptr, dst_ptr;
- jpeg_component_info *compptr;
-
- /* Because of the horizontal mirror step, we can't process partial iMCUs
- * at the (output) bottom edge properly. They just get transposed and
- * not mirrored.
- */
- MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE);
-
- for (ci = 0; ci < dstinfo->num_components; ci++) {
- compptr = dstinfo->comp_info + ci;
- comp_height = MCU_rows * compptr->v_samp_factor;
- for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
- dst_blk_y += compptr->v_samp_factor) {
- dst_buffer = (*srcinfo->mem->access_virt_barray)
- ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
- (JDIMENSION) compptr->v_samp_factor, TRUE);
- for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
- for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
- dst_blk_x += compptr->h_samp_factor) {
- src_buffer = (*srcinfo->mem->access_virt_barray)
- ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_x,
- (JDIMENSION) compptr->h_samp_factor, FALSE);
- for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) {
- dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x];
- if (dst_blk_y < comp_height) {
- /* Block is within the mirrorable area. */
- src_ptr = src_buffer[offset_x]
- [comp_height - dst_blk_y - offset_y - 1];
- for (i = 0; i < DCTSIZE; i++) {
- for (j = 0; j < DCTSIZE; j++) {
- dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
- j++;
- dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j];
- }
- }
- } else {
- /* Edge blocks are transposed but not mirrored. */
- src_ptr = src_buffer[offset_x][dst_blk_y + offset_y];
- for (i = 0; i < DCTSIZE; i++)
- for (j = 0; j < DCTSIZE; j++)
- dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
- }
- }
- }
- }
- }
- }
- }
-
- LOCAL(void)
- do_rot_180 (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
- jvirt_barray_ptr *src_coef_arrays,
- jvirt_barray_ptr *dst_coef_arrays)
- /* 180 degree rotation is equivalent to
- * 1. Vertical mirroring;
- * 2. Horizontal mirroring.
- * These two steps are merged into a single processing routine.
- */
- {
- JDIMENSION MCU_cols, MCU_rows, comp_width, comp_height, dst_blk_x, dst_blk_y;
- int ci, i, j, offset_y;
- JBLOCKARRAY src_buffer, dst_buffer;
- JBLOCKROW src_row_ptr, dst_row_ptr;
- JCOEFPTR src_ptr, dst_ptr;
- jpeg_component_info *compptr;
-
- MCU_cols = dstinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE);
- MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE);
-
- for (ci = 0; ci < dstinfo->num_components; ci++) {
- compptr = dstinfo->comp_info + ci;
- comp_width = MCU_cols * compptr->h_samp_factor;
- comp_height = MCU_rows * compptr->v_samp_factor;
- for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
- dst_blk_y += compptr->v_samp_factor) {
- dst_buffer = (*srcinfo->mem->access_virt_barray)
- ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
- (JDIMENSION) compptr->v_samp_factor, TRUE);
- if (dst_blk_y < comp_height) {
- /* Row is within the vertically mirrorable area. */
- src_buffer = (*srcinfo->mem->access_virt_barray)
- ((j_common_ptr) srcinfo, src_coef_arrays[ci],
- comp_height - dst_blk_y - (JDIMENSION) compptr->v_samp_factor,
- (JDIMENSION) compptr->v_samp_factor, FALSE);
- } else {
- /* Bottom-edge rows are only mirrored horizontally. */
- src_buffer = (*srcinfo->mem->access_virt_barray)
- ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_y,
- (JDIMENSION) compptr->v_samp_factor, FALSE);
- }
- for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
- if (dst_blk_y < comp_height) {
- /* Row is within the mirrorable area. */
- dst_row_ptr = dst_buffer[offset_y];
- src_row_ptr = src_buffer[compptr->v_samp_factor - offset_y - 1];
- /* Process the blocks that can be mirrored both ways. */
- for (dst_blk_x = 0; dst_blk_x < comp_width; dst_blk_x++) {
- dst_ptr = dst_row_ptr[dst_blk_x];
- src_ptr = src_row_ptr[comp_width - dst_blk_x - 1];
- for (i = 0; i < DCTSIZE; i += 2) {
- /* For even row, negate every odd column. */
- for (j = 0; j < DCTSIZE; j += 2) {
- *dst_ptr++ = *src_ptr++;
- *dst_ptr++ = - *src_ptr++;
- }
- /* For odd row, negate every even column. */
- for (j = 0; j < DCTSIZE; j += 2) {
- *dst_ptr++ = - *src_ptr++;
- *dst_ptr++ = *src_ptr++;
- }
- }
- }
- /* Any remaining right-edge blocks are only mirrored vertically. */
- for (; dst_blk_x < compptr->width_in_blocks; dst_blk_x++) {
- dst_ptr = dst_row_ptr[dst_blk_x];
- src_ptr = src_row_ptr[dst_blk_x];
- for (i = 0; i < DCTSIZE; i += 2) {
- for (j = 0; j < DCTSIZE; j++)
- *dst_ptr++ = *src_ptr++;
- for (j = 0; j < DCTSIZE; j++)
- *dst_ptr++ = - *src_ptr++;
- }
- }
- } else {
- /* Remaining rows are just mirrored horizontally. */
- dst_row_ptr = dst_buffer[offset_y];
- src_row_ptr = src_buffer[offset_y];
- /* Process the blocks that can be mirrored. */
- for (dst_blk_x = 0; dst_blk_x < comp_width; dst_blk_x++) {
- dst_ptr = dst_row_ptr[dst_blk_x];
- src_ptr = src_row_ptr[comp_width - dst_blk_x - 1];
- for (i = 0; i < DCTSIZE2; i += 2) {
- *dst_ptr++ = *src_ptr++;
- *dst_ptr++ = - *src_ptr++;
- }
- }
- /* Any remaining right-edge blocks are only copied. */
- for (; dst_blk_x < compptr->width_in_blocks; dst_blk_x++) {
- dst_ptr = dst_row_ptr[dst_blk_x];
- src_ptr = src_row_ptr[dst_blk_x];
- for (i = 0; i < DCTSIZE2; i++)
- *dst_ptr++ = *src_ptr++;
- }
- }
- }
- }
- }
- }
-
- LOCAL(void)
- do_transverse (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
- jvirt_barray_ptr *src_coef_arrays,
- jvirt_barray_ptr *dst_coef_arrays)
- /* Transverse transpose is equivalent to
- * 1. 180 degree rotation;
- * 2. Transposition;
- * or
- * 1. Horizontal mirroring;
- * 2. Transposition;
- * 3. Horizontal mirroring.
- * These steps are merged into a single processing routine.
- */
- {
- JDIMENSION MCU_cols, MCU_rows, comp_width, comp_height, dst_blk_x, dst_blk_y;
- int ci, i, j, offset_x, offset_y;
- JBLOCKARRAY src_buffer, dst_buffer;
- JCOEFPTR src_ptr, dst_ptr;
- jpeg_component_info *compptr;
-
- MCU_cols = dstinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE);
- MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE);
-
- for (ci = 0; ci < dstinfo->num_components; ci++) {
- compptr = dstinfo->comp_info + ci;
- comp_width = MCU_cols * compptr->h_samp_factor;
- comp_height = MCU_rows * compptr->v_samp_factor;
- for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
- dst_blk_y += compptr->v_samp_factor) {
- dst_buffer = (*srcinfo->mem->access_virt_barray)
- ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
- (JDIMENSION) compptr->v_samp_factor, TRUE);
- for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
- for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
- dst_blk_x += compptr->h_samp_factor) {
- src_buffer = (*srcinfo->mem->access_virt_barray)
- ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_x,
- (JDIMENSION) compptr->h_samp_factor, FALSE);
- for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) {
- if (dst_blk_y < comp_height) {
- src_ptr = src_buffer[offset_x]
- [comp_height - dst_blk_y - offset_y - 1];
- if (dst_blk_x < comp_width) {
- /* Block is within the mirrorable area. */
- dst_ptr = dst_buffer[offset_y]
- [comp_width - dst_blk_x - offset_x - 1];
- for (i = 0; i < DCTSIZE; i++) {
- for (j = 0; j < DCTSIZE; j++) {
- dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
- j++;
- dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j];
- }
- i++;
- for (j = 0; j < DCTSIZE; j++) {
- dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j];
- j++;
- dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
- }
- }
- } else {
- /* Right-edge blocks are mirrored in y only */
- dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x];
- for (i = 0; i < DCTSIZE; i++) {
- for (j = 0; j < DCTSIZE; j++) {
- dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
- j++;
- dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j];
- }
- }
- }
- } else {
- src_ptr = src_buffer[offset_x][dst_blk_y + offset_y];
- if (dst_blk_x < comp_width) {
- /* Bottom-edge blocks are mirrored in x only */
- dst_ptr = dst_buffer[offset_y]
- [comp_width - dst_blk_x - offset_x - 1];
- for (i = 0; i < DCTSIZE; i++) {
- for (j = 0; j < DCTSIZE; j++)
- dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
- i++;
- for (j = 0; j < DCTSIZE; j++)
- dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j];
- }
- } else {
- /* At lower right corner, just transpose, no mirroring */
- dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x];
- for (i = 0; i < DCTSIZE; i++)
- for (j = 0; j < DCTSIZE; j++)
- dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
- }
- }
- }
- }
- }
- }
- }
- }
-
- /* Request any required workspace.
- *
- * We allocate the workspace virtual arrays from the source decompression
- * object, so that all the arrays (both the original data and the workspace)
- * will be taken into account while making memory management decisions.
- * Hence, this routine must be called after jpeg_read_header (which reads
- * the image dimensions) and before jpeg_read_coefficients (which realizes
- * the source's virtual arrays).
- */
-
- GLOBAL(void)
- jtransform_request_workspace (j_decompress_ptr srcinfo,
- jpeg_transform_info *info)
- {
- jvirt_barray_ptr *coef_arrays = NULL;
- jpeg_component_info *compptr;
- int ci;
-
- if (info->force_grayscale &&
- srcinfo->jpeg_color_space == JCS_YCbCr &&
- srcinfo->num_components == 3) {
- /* We'll only process the first component */
- info->num_components = 1;
- } else {
- /* Process all the components */
- info->num_components = srcinfo->num_components;
- }
-
- switch (info->transform) {
- case JXFORM_NONE:
- case JXFORM_FLIP_H:
- /* Don't need a workspace array */
- break;
- case JXFORM_FLIP_V:
- case JXFORM_ROT_180:
- /* Need workspace arrays having same dimensions as source image.
- * Note that we allocate arrays padded out to the next iMCU boundary,
- * so that transform routines need not worry about missing edge blocks.
- */
- coef_arrays = (jvirt_barray_ptr *)
- (*srcinfo->mem->alloc_small) ((j_common_ptr) srcinfo, JPOOL_IMAGE,
- SIZEOF(jvirt_barray_ptr) * info->num_components);
- for (ci = 0; ci < info->num_components; ci++) {
- compptr = srcinfo->comp_info + ci;
- coef_arrays[ci] = (*srcinfo->mem->request_virt_barray)
- ((j_common_ptr) srcinfo, JPOOL_IMAGE, FALSE,
- (JDIMENSION) jround_up((long) compptr->width_in_blocks,
- (long) compptr->h_samp_factor),
- (JDIMENSION) jround_up((long) compptr->height_in_blocks,
- (long) compptr->v_samp_factor),
- (JDIMENSION) compptr->v_samp_factor);
- }
- break;
- case JXFORM_TRANSPOSE:
- case JXFORM_TRANSVERSE:
- case JXFORM_ROT_90:
- case JXFORM_ROT_270:
- /* Need workspace arrays having transposed dimensions.
- * Note that we allocate arrays padded out to the next iMCU boundary,
- * so that transform routines need not worry about missing edge blocks.
- */
- coef_arrays = (jvirt_barray_ptr *)
- (*srcinfo->mem->alloc_small) ((j_common_ptr) srcinfo, JPOOL_IMAGE,
- SIZEOF(jvirt_barray_ptr) * info->num_components);
- for (ci = 0; ci < info->num_components; ci++) {
- compptr = srcinfo->comp_info + ci;
- coef_arrays[ci] = (*srcinfo->mem->request_virt_barray)
- ((j_common_ptr) srcinfo, JPOOL_IMAGE, FALSE,
- (JDIMENSION) jround_up((long) compptr->height_in_blocks,
- (long) compptr->v_samp_factor),
- (JDIMENSION) jround_up((long) compptr->width_in_blocks,
- (long) compptr->h_samp_factor),
- (JDIMENSION) compptr->h_samp_factor);
- }
- break;
- }
- info->workspace_coef_arrays = coef_arrays;
- }
-
- /* Transpose destination image parameters */
-
- LOCAL(void)
- transpose_critical_parameters (j_compress_ptr dstinfo)
- {
- int tblno, i, j, ci, itemp;
- jpeg_component_info *compptr;
- JQUANT_TBL *qtblptr;
- JDIMENSION dtemp;
- UINT16 qtemp;
-
- /* Transpose basic image dimensions */
- dtemp = dstinfo->image_width;
- dstinfo->image_width = dstinfo->image_height;
- dstinfo->image_height = dtemp;
-
- /* Transpose sampling factors */
- for (ci = 0; ci < dstinfo->num_components; ci++) {
- compptr = dstinfo->comp_info + ci;
- itemp = compptr->h_samp_factor;
- compptr->h_samp_factor = compptr->v_samp_factor;
- compptr->v_samp_factor = itemp;
- }
-
- /* Transpose quantization tables */
- for (tblno = 0; tblno < NUM_QUANT_TBLS; tblno++) {
- qtblptr = dstinfo->quant_tbl_ptrs[tblno];
- if (qtblptr != NULL) {
- for (i = 0; i < DCTSIZE; i++) {
- for (j = 0; j < i; j++) {
- qtemp = qtblptr->quantval[i*DCTSIZE+j];
- qtblptr->quantval[i*DCTSIZE+j] = qtblptr->quantval[j*DCTSIZE+i];
- qtblptr->quantval[j*DCTSIZE+i] = qtemp;
- }
- }
- }
- }
- }
-
- /* Trim off any partial iMCUs on the indicated destination edge */
-
- LOCAL(void)
- trim_right_edge (j_compress_ptr dstinfo)
- {
- int ci, max_h_samp_factor;
- JDIMENSION MCU_cols;
-
- /* We have to compute max_h_samp_factor ourselves,
- * because it hasn't been set yet in the destination
- * (and we don't want to use the source's value).
- */
- max_h_samp_factor = 1;
- for (ci = 0; ci < dstinfo->num_components; ci++) {
- int h_samp_factor = dstinfo->comp_info[ci].h_samp_factor;
- max_h_samp_factor = MAX(max_h_samp_factor, h_samp_factor);
- }
- MCU_cols = dstinfo->image_width / (max_h_samp_factor * DCTSIZE);
- if (MCU_cols > 0) /* can't trim to 0 pixels */
- dstinfo->image_width = MCU_cols * (max_h_samp_factor * DCTSIZE);
- }
-
- LOCAL(void)
- trim_bottom_edge (j_compress_ptr dstinfo)
- {
- int ci, max_v_samp_factor;
- JDIMENSION MCU_rows;
-
- /* We have to compute max_v_samp_factor ourselves,
- * because it hasn't been set yet in the destination
- * (and we don't want to use the source's value).
- */
- max_v_samp_factor = 1;
- for (ci = 0; ci < dstinfo->num_components; ci++) {
- int v_samp_factor = dstinfo->comp_info[ci].v_samp_factor;
- max_v_samp_factor = MAX(max_v_samp_factor, v_samp_factor);
- }
- MCU_rows = dstinfo->image_height / (max_v_samp_factor * DCTSIZE);
- if (MCU_rows > 0) /* can't trim to 0 pixels */
- dstinfo->image_height = MCU_rows * (max_v_samp_factor * DCTSIZE);
- }
-
- /* Adjust output image parameters as needed.
- *
- * This must be called after jpeg_copy_critical_parameters()
- * and before jpeg_write_coefficients().
- *
- * The return value is the set of virtual coefficient arrays to be written
- * (either the ones allocated by jtransform_request_workspace, or the
- * original source data arrays). The caller will need to pass this value
- * to jpeg_write_coefficients().
- */
-
- GLOBAL(jvirt_barray_ptr *)
- jtransform_adjust_parameters (j_decompress_ptr srcinfo,
- j_compress_ptr dstinfo,
- jvirt_barray_ptr *src_coef_arrays,
- jpeg_transform_info *info)
- {
- /* If force-to-grayscale is requested, adjust destination parameters */
- if (info->force_grayscale) {
- /* We use jpeg_set_colorspace to make sure subsidiary settings get fixed
- * properly. Among other things, the target h_samp_factor & v_samp_factor
- * will get set to 1, which typically won't match the source.
- * In fact we do this even if the source is already grayscale; that
- * provides an easy way of coercing a grayscale JPEG with funny sampling
- * factors to the customary 1,1. (Some decoders fail on other factors.)
- */
- if ((dstinfo->jpeg_color_space == JCS_YCbCr &&
- dstinfo->num_components == 3) ||
- (dstinfo->jpeg_color_space == JCS_GRAYSCALE &&
- dstinfo->num_components == 1)) {
- /* We have to preserve the source's quantization table number. */
- int sv_quant_tbl_no = dstinfo->comp_info[0].quant_tbl_no;
- jpeg_set_colorspace(dstinfo, JCS_GRAYSCALE);
- dstinfo->comp_info[0].quant_tbl_no = sv_quant_tbl_no;
- } else {
- /* Sorry, can't do it */
- ERREXIT(dstinfo, JERR_CONVERSION_NOTIMPL);
- }
- }
-
- /* Correct the destination's image dimensions etc if necessary */
- switch (info->transform) {
- case JXFORM_NONE:
- /* Nothing to do */
- break;
- case JXFORM_FLIP_H:
- if (info->trim)
- trim_right_edge(dstinfo);
- break;
- case JXFORM_FLIP_V:
- if (info->trim)
- trim_bottom_edge(dstinfo);
- break;
- case JXFORM_TRANSPOSE:
- transpose_critical_parameters(dstinfo);
- /* transpose does NOT have to trim anything */
- break;
- case JXFORM_TRANSVERSE:
- transpose_critical_parameters(dstinfo);
- if (info->trim) {
- trim_right_edge(dstinfo);
- trim_bottom_edge(dstinfo);
- }
- break;
- case JXFORM_ROT_90:
- transpose_critical_parameters(dstinfo);
- if (info->trim)
- trim_right_edge(dstinfo);
- break;
- case JXFORM_ROT_180:
- if (info->trim) {
- trim_right_edge(dstinfo);
- trim_bottom_edge(dstinfo);
- }
- break;
- case JXFORM_ROT_270:
- transpose_critical_parameters(dstinfo);
- if (info->trim)
- trim_bottom_edge(dstinfo);
- break;
- }
-
- /* Return the appropriate output data set */
- if (info->workspace_coef_arrays != NULL)
- return info->workspace_coef_arrays;
- return src_coef_arrays;
- }
-
- /* Execute the actual transformation, if any.
- *
- * This must be called *after* jpeg_write_coefficients, because it depends
- * on jpeg_write_coefficients to have computed subsidiary values such as
- * the per-component width and height fields in the destination object.
- *
- * Note that some transformations will modify the source data arrays!
- */
-
- GLOBAL(void)
- jtransform_execute_transformation (j_decompress_ptr srcinfo,
- j_compress_ptr dstinfo,
- jvirt_barray_ptr *src_coef_arrays,
- jpeg_transform_info *info)
- {
- jvirt_barray_ptr *dst_coef_arrays = info->workspace_coef_arrays;
-
- switch (info->transform) {
- case JXFORM_NONE:
- break;
- case JXFORM_FLIP_H:
- do_flip_h(srcinfo, dstinfo, src_coef_arrays);
- break;
- case JXFORM_FLIP_V:
- do_flip_v(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays);
- break;
- case JXFORM_TRANSPOSE:
- do_transpose(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays);
- break;
- case JXFORM_TRANSVERSE:
- do_transverse(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays);
- break;
- case JXFORM_ROT_90:
- do_rot_90(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays);
- break;
- case JXFORM_ROT_180:
- do_rot_180(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays);
- break;
- case JXFORM_ROT_270:
- do_rot_270(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays);
- break;
- }
- }
-
- #endif /* TRANSFORMS_SUPPORTED */
-
- /* Setup decompression object to save desired markers in memory.
- * This must be called before jpeg_read_header() to have the desired effect.
- */
-
- GLOBAL(void)
- jcopy_markers_setup (j_decompress_ptr srcinfo, JCOPY_OPTION option)
- {
- #ifdef SAVE_MARKERS_SUPPORTED
- int m;
-
- /* Save comments except under NONE option */
- if (option != JCOPYOPT_NONE) {
- jpeg_save_markers(srcinfo, JPEG_COM, 0xFFFF);
- }
- /* Save all types of APPn markers iff ALL option */
- if (option == JCOPYOPT_ALL) {
- for (m = 0; m < 16; m++)
- jpeg_save_markers(srcinfo, JPEG_APP0 + m, 0xFFFF);
- }
- #endif /* SAVE_MARKERS_SUPPORTED */
- }
-
- /* Copy markers saved in the given source object to the destination object.
- * This should be called just after jpeg_start_compress() or
- * jpeg_write_coefficients().
- * Note that those routines will have written the SOI, and also the
- * JFIF APP0 or Adobe APP14 markers if selected.
- */
-
- GLOBAL(void)
- jcopy_markers_execute (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
- JCOPY_OPTION option)
- {
- jpeg_saved_marker_ptr marker;
-
- /* In the current implementation, we don't actually need to examine the
- * option flag here; we just copy everything that got saved.
- * But to avoid confusion, we do not output JFIF and Adobe APP14 markers
- * if the encoder library already wrote one.
- */
- for (marker = srcinfo->marker_list; marker != NULL; marker = marker->next) {
- if (dstinfo->write_JFIF_header &&
- marker->marker == JPEG_APP0 &&
- marker->data_length >= 5 &&
- GETJOCTET(marker->data[0]) == 0x4A &&
- GETJOCTET(marker->data[1]) == 0x46 &&
- GETJOCTET(marker->data[2]) == 0x49 &&
- GETJOCTET(marker->data[3]) == 0x46 &&
- GETJOCTET(marker->data[4]) == 0)
- continue; /* reject duplicate JFIF */
- if (dstinfo->write_Adobe_marker &&
- marker->marker == JPEG_APP0+14 &&
- marker->data_length >= 5 &&
- GETJOCTET(marker->data[0]) == 0x41 &&
- GETJOCTET(marker->data[1]) == 0x64 &&
- GETJOCTET(marker->data[2]) == 0x6F &&
- GETJOCTET(marker->data[3]) == 0x62 &&
- GETJOCTET(marker->data[4]) == 0x65)
- continue; /* reject duplicate Adobe */
- #ifdef NEED_FAR_POINTERS
- /* We could use jpeg_write_marker if the data weren't FAR... */
- {
- unsigned int i;
- jpeg_write_m_header(dstinfo, marker->marker, marker->data_length);
- for (i = 0; i < marker->data_length; i++)
- jpeg_write_m_byte(dstinfo, marker->data[i]);
- }
- #else
- jpeg_write_marker(dstinfo, marker->marker,
- marker->data, marker->data_length);
- #endif
- }
- }
- /********* End of inlined file: transupp.c *********/
-
- }
- }
-
- #if JUCE_MSVC
- #pragma warning (pop)
- #endif
-
- BEGIN_JUCE_NAMESPACE
-
- using namespace jpeglibNamespace;
-
- struct JPEGDecodingFailure {};
-
- static void fatalErrorHandler (j_common_ptr)
- {
- throw JPEGDecodingFailure();
- }
-
- static void silentErrorCallback1 (j_common_ptr) {}
- static void silentErrorCallback2 (j_common_ptr, int) {}
- static void silentErrorCallback3 (j_common_ptr, char*) {}
-
- static void setupSilentErrorHandler (struct jpeg_error_mgr& err)
- {
- zerostruct (err);
-
- err.error_exit = fatalErrorHandler;
- err.emit_message = silentErrorCallback2;
- err.output_message = silentErrorCallback1;
- err.format_message = silentErrorCallback3;
- err.reset_error_mgr = silentErrorCallback1;
- }
-
- static void dummyCallback1 (j_decompress_ptr) throw()
- {
- }
-
- static void jpegSkip (j_decompress_ptr decompStruct, long num) throw()
- {
- decompStruct->src->next_input_byte += num;
-
- num = jmin (num, (int) decompStruct->src->bytes_in_buffer);
- decompStruct->src->bytes_in_buffer -= num;
- }
-
- static boolean jpegFill (j_decompress_ptr) throw()
- {
- return 0;
- }
-
- Image* juce_loadJPEGImageFromStream (InputStream& in) throw()
- {
- MemoryBlock mb;
- in.readIntoMemoryBlock (mb);
-
- Image* image = 0;
-
- if (mb.getSize() > 16)
- {
- struct jpeg_decompress_struct jpegDecompStruct;
-
- struct jpeg_error_mgr jerr;
- setupSilentErrorHandler (jerr);
- jpegDecompStruct.err = &jerr;
-
- jpeg_create_decompress (&jpegDecompStruct);
-
- jpegDecompStruct.src = (jpeg_source_mgr*)(jpegDecompStruct.mem->alloc_small)
- ((j_common_ptr)(&jpegDecompStruct), JPOOL_PERMANENT, sizeof (jpeg_source_mgr));
-
- jpegDecompStruct.src->init_source = dummyCallback1;
- jpegDecompStruct.src->fill_input_buffer = jpegFill;
- jpegDecompStruct.src->skip_input_data = jpegSkip;
- jpegDecompStruct.src->resync_to_restart = jpeg_resync_to_restart;
- jpegDecompStruct.src->term_source = dummyCallback1;
-
- jpegDecompStruct.src->next_input_byte = (const unsigned char*) mb.getData();
- jpegDecompStruct.src->bytes_in_buffer = mb.getSize();
-
- try
- {
- jpeg_read_header (&jpegDecompStruct, TRUE);
-
- jpeg_calc_output_dimensions (&jpegDecompStruct);
-
- const int width = jpegDecompStruct.output_width;
- const int height = jpegDecompStruct.output_height;
-
- jpegDecompStruct.out_color_space = JCS_RGB;
-
- JSAMPARRAY buffer
- = (*jpegDecompStruct.mem->alloc_sarray) ((j_common_ptr) &jpegDecompStruct,
- JPOOL_IMAGE,
- width * 3, 1);
-
- if (jpeg_start_decompress (&jpegDecompStruct))
- {
- image = new Image (Image::RGB, width, height, false);
-
- for (int y = 0; y < height; ++y)
- {
- jpeg_read_scanlines (&jpegDecompStruct, buffer, 1);
-
- int stride, pixelStride;
- uint8* pixels = image->lockPixelDataReadWrite (0, y, width, 1, stride, pixelStride);
- const uint8* src = *buffer;
- uint8* dest = pixels;
-
- for (int i = width; --i >= 0;)
- {
- ((PixelRGB*) dest)->setARGB (0, src[0], src[1], src[2]);
- dest += pixelStride;
- src += 3;
- }
-
- image->releasePixelDataReadWrite (pixels);
- }
-
- jpeg_finish_decompress (&jpegDecompStruct);
- }
-
- jpeg_destroy_decompress (&jpegDecompStruct);
- }
- catch (...)
- {}
- }
-
- return image;
- }
-
- static const int bufferSize = 512;
-
- struct JuceJpegDest : public jpeg_destination_mgr
- {
- OutputStream* output;
- char* buffer;
- };
-
- static void jpegWriteInit (j_compress_ptr) throw()
- {
- }
-
- static void jpegWriteTerminate (j_compress_ptr cinfo) throw()
- {
- JuceJpegDest* const dest = (JuceJpegDest*) cinfo->dest;
-
- const int numToWrite = bufferSize - dest->free_in_buffer;
- dest->output->write (dest->buffer, numToWrite);
- }
-
- static boolean jpegWriteFlush (j_compress_ptr cinfo) throw()
- {
- JuceJpegDest* const dest = (JuceJpegDest*) cinfo->dest;
-
- const int numToWrite = bufferSize;
-
- dest->next_output_byte = (JOCTET*) dest->buffer;
- dest->free_in_buffer = bufferSize;
-
- return dest->output->write (dest->buffer, numToWrite);
- }
-
- bool juce_writeJPEGImageToStream (const Image& image,
- OutputStream& out,
- float quality) throw()
- {
- if (image.hasAlphaChannel())
- {
- // this method could fill the background in white and still save the image..
- jassertfalse
- return true;
- }
-
- struct jpeg_compress_struct jpegCompStruct;
-
- struct jpeg_error_mgr jerr;
- setupSilentErrorHandler (jerr);
- jpegCompStruct.err = &jerr;
-
- jpeg_create_compress (&jpegCompStruct);
-
- JuceJpegDest dest;
- jpegCompStruct.dest = &dest;
-
- dest.output = &out;
- dest.buffer = (char*) juce_malloc (bufferSize);
- dest.next_output_byte = (JOCTET*) dest.buffer;
- dest.free_in_buffer = bufferSize;
- dest.init_destination = jpegWriteInit;
- dest.empty_output_buffer = jpegWriteFlush;
- dest.term_destination = jpegWriteTerminate;
-
- jpegCompStruct.image_width = image.getWidth();
- jpegCompStruct.image_height = image.getHeight();
- jpegCompStruct.input_components = 3;
- jpegCompStruct.in_color_space = JCS_RGB;
- jpegCompStruct.write_JFIF_header = 1;
-
- jpegCompStruct.X_density = 72;
- jpegCompStruct.Y_density = 72;
-
- jpeg_set_defaults (&jpegCompStruct);
-
- jpegCompStruct.dct_method = JDCT_FLOAT;
- jpegCompStruct.optimize_coding = 1;
- // jpegCompStruct.smoothing_factor = 10;
-
- if (quality < 0.0f)
- quality = 6.0f;
-
- jpeg_set_quality (&jpegCompStruct, jlimit (0, 100, roundFloatToInt (quality * 100.0f)), TRUE);
-
- jpeg_start_compress (&jpegCompStruct, TRUE);
-
- const int strideBytes = jpegCompStruct.image_width * jpegCompStruct.input_components;
-
- JSAMPARRAY buffer = (*jpegCompStruct.mem->alloc_sarray) ((j_common_ptr) &jpegCompStruct,
- JPOOL_IMAGE,
- strideBytes, 1);
-
- while (jpegCompStruct.next_scanline < jpegCompStruct.image_height)
- {
- int stride, pixelStride;
- const uint8* pixels = image.lockPixelDataReadOnly (0, jpegCompStruct.next_scanline, jpegCompStruct.image_width, 1, stride, pixelStride);
- const uint8* src = pixels;
- uint8* dst = *buffer;
-
- for (int i = jpegCompStruct.image_width; --i >= 0;)
- {
- *dst++ = ((const PixelRGB*) src)->getRed();
- *dst++ = ((const PixelRGB*) src)->getGreen();
- *dst++ = ((const PixelRGB*) src)->getBlue();
- src += pixelStride;
- }
-
- jpeg_write_scanlines (&jpegCompStruct, buffer, 1);
- image.releasePixelDataReadOnly (pixels);
- }
-
- jpeg_finish_compress (&jpegCompStruct);
- jpeg_destroy_compress (&jpegCompStruct);
-
- juce_free (dest.buffer);
-
- out.flush();
-
- return true;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_JPEGLoader.cpp *********/
-
- /********* Start of inlined file: juce_PNGLoader.cpp *********/
-
- #ifdef _MSC_VER
- #pragma warning (push)
- #pragma warning (disable: 4390 4611)
- #endif
-
- namespace zlibNamespace
- {
- #undef OS_CODE
- #undef fdopen
-
- #undef OS_CODE
- }
-
- namespace pnglibNamespace
- {
- using namespace zlibNamespace;
- using ::malloc;
- using ::free;
-
- extern "C"
- {
- using ::abs;
- #define PNG_INTERNAL
- #define NO_DUMMY_DECL
- #define PNG_SETJMP_NOT_SUPPORTED
-
- /********* Start of inlined file: png.h *********/
- /* png.h - header file for PNG reference library
- *
- * libpng version 1.2.21 - October 4, 2007
- * Copyright (c) 1998-2007 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
- *
- * Authors and maintainers:
- * libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat
- * libpng versions 0.89c, June 1996, through 0.96, May 1997: Andreas Dilger
- * libpng versions 0.97, January 1998, through 1.2.21 - October 4, 2007: Glenn
- * See also "Contributing Authors", below.
- *
- * Note about libpng version numbers:
- *
- * Due to various miscommunications, unforeseen code incompatibilities
- * and occasional factors outside the authors' control, version numbering
- * on the library has not always been consistent and straightforward.
- * The following table summarizes matters since version 0.89c, which was
- * the first widely used release:
- *
- * source png.h png.h shared-lib
- * version string int version
- * ------- ------ ----- ----------
- * 0.89c "1.0 beta 3" 0.89 89 1.0.89
- * 0.90 "1.0 beta 4" 0.90 90 0.90 [should have been 2.0.90]
- * 0.95 "1.0 beta 5" 0.95 95 0.95 [should have been 2.0.95]
- * 0.96 "1.0 beta 6" 0.96 96 0.96 [should have been 2.0.96]
- * 0.97b "1.00.97 beta 7" 1.00.97 97 1.0.1 [should have been 2.0.97]
- * 0.97c 0.97 97 2.0.97
- * 0.98 0.98 98 2.0.98
- * 0.99 0.99 98 2.0.99
- * 0.99a-m 0.99 99 2.0.99
- * 1.00 1.00 100 2.1.0 [100 should be 10000]
- * 1.0.0 (from here on, the 100 2.1.0 [100 should be 10000]
- * 1.0.1 png.h string is 10001 2.1.0
- * 1.0.1a-e identical to the 10002 from here on, the shared library
- * 1.0.2 source version) 10002 is 2.V where V is the source code
- * 1.0.2a-b 10003 version, except as noted.
- * 1.0.3 10003
- * 1.0.3a-d 10004
- * 1.0.4 10004
- * 1.0.4a-f 10005
- * 1.0.5 (+ 2 patches) 10005
- * 1.0.5a-d 10006
- * 1.0.5e-r 10100 (not source compatible)
- * 1.0.5s-v 10006 (not binary compatible)
- * 1.0.6 (+ 3 patches) 10006 (still binary incompatible)
- * 1.0.6d-f 10007 (still binary incompatible)
- * 1.0.6g 10007
- * 1.0.6h 10007 10.6h (testing xy.z so-numbering)
- * 1.0.6i 10007 10.6i
- * 1.0.6j 10007 2.1.0.6j (incompatible with 1.0.0)
- * 1.0.7beta11-14 DLLNUM 10007 2.1.0.7beta11-14 (binary compatible)
- * 1.0.7beta15-18 1 10007 2.1.0.7beta15-18 (binary compatible)
- * 1.0.7rc1-2 1 10007 2.1.0.7rc1-2 (binary compatible)
- * 1.0.7 1 10007 (still compatible)
- * 1.0.8beta1-4 1 10008 2.1.0.8beta1-4
- * 1.0.8rc1 1 10008 2.1.0.8rc1
- * 1.0.8 1 10008 2.1.0.8
- * 1.0.9beta1-6 1 10009 2.1.0.9beta1-6
- * 1.0.9rc1 1 10009 2.1.0.9rc1
- * 1.0.9beta7-10 1 10009 2.1.0.9beta7-10
- * 1.0.9rc2 1 10009 2.1.0.9rc2
- * 1.0.9 1 10009 2.1.0.9
- * 1.0.10beta1 1 10010 2.1.0.10beta1
- * 1.0.10rc1 1 10010 2.1.0.10rc1
- * 1.0.10 1 10010 2.1.0.10
- * 1.0.11beta1-3 1 10011 2.1.0.11beta1-3
- * 1.0.11rc1 1 10011 2.1.0.11rc1
- * 1.0.11 1 10011 2.1.0.11
- * 1.0.12beta1-2 2 10012 2.1.0.12beta1-2
- * 1.0.12rc1 2 10012 2.1.0.12rc1
- * 1.0.12 2 10012 2.1.0.12
- * 1.1.0a-f - 10100 2.1.1.0a-f (branch abandoned)
- * 1.2.0beta1-2 2 10200 2.1.2.0beta1-2
- * 1.2.0beta3-5 3 10200 3.1.2.0beta3-5
- * 1.2.0rc1 3 10200 3.1.2.0rc1
- * 1.2.0 3 10200 3.1.2.0
- * 1.2.1beta1-4 3 10201 3.1.2.1beta1-4
- * 1.2.1rc1-2 3 10201 3.1.2.1rc1-2
- * 1.2.1 3 10201 3.1.2.1
- * 1.2.2beta1-6 12 10202 12.so.0.1.2.2beta1-6
- * 1.0.13beta1 10 10013 10.so.0.1.0.13beta1
- * 1.0.13rc1 10 10013 10.so.0.1.0.13rc1
- * 1.2.2rc1 12 10202 12.so.0.1.2.2rc1
- * 1.0.13 10 10013 10.so.0.1.0.13
- * 1.2.2 12 10202 12.so.0.1.2.2
- * 1.2.3rc1-6 12 10203 12.so.0.1.2.3rc1-6
- * 1.2.3 12 10203 12.so.0.1.2.3
- * 1.2.4beta1-3 13 10204 12.so.0.1.2.4beta1-3
- * 1.0.14rc1 13 10014 10.so.0.1.0.14rc1
- * 1.2.4rc1 13 10204 12.so.0.1.2.4rc1
- * 1.0.14 10 10014 10.so.0.1.0.14
- * 1.2.4 13 10204 12.so.0.1.2.4
- * 1.2.5beta1-2 13 10205 12.so.0.1.2.5beta1-2
- * 1.0.15rc1-3 10 10015 10.so.0.1.0.15rc1-3
- * 1.2.5rc1-3 13 10205 12.so.0.1.2.5rc1-3
- * 1.0.15 10 10015 10.so.0.1.0.15
- * 1.2.5 13 10205 12.so.0.1.2.5
- * 1.2.6beta1-4 13 10206 12.so.0.1.2.6beta1-4
- * 1.0.16 10 10016 10.so.0.1.0.16
- * 1.2.6 13 10206 12.so.0.1.2.6
- * 1.2.7beta1-2 13 10207 12.so.0.1.2.7beta1-2
- * 1.0.17rc1 10 10017 10.so.0.1.0.17rc1
- * 1.2.7rc1 13 10207 12.so.0.1.2.7rc1
- * 1.0.17 10 10017 10.so.0.1.0.17
- * 1.2.7 13 10207 12.so.0.1.2.7
- * 1.2.8beta1-5 13 10208 12.so.0.1.2.8beta1-5
- * 1.0.18rc1-5 10 10018 10.so.0.1.0.18rc1-5
- * 1.2.8rc1-5 13 10208 12.so.0.1.2.8rc1-5
- * 1.0.18 10 10018 10.so.0.1.0.18
- * 1.2.8 13 10208 12.so.0.1.2.8
- * 1.2.9beta1-3 13 10209 12.so.0.1.2.9beta1-3
- * 1.2.9beta4-11 13 10209 12.so.0.9[.0]
- * 1.2.9rc1 13 10209 12.so.0.9[.0]
- * 1.2.9 13 10209 12.so.0.9[.0]
- * 1.2.10beta1-8 13 10210 12.so.0.10[.0]
- * 1.2.10rc1-3 13 10210 12.so.0.10[.0]
- * 1.2.10 13 10210 12.so.0.10[.0]
- * 1.2.11beta1-4 13 10211 12.so.0.11[.0]
- * 1.0.19rc1-5 10 10019 10.so.0.19[.0]
- * 1.2.11rc1-5 13 10211 12.so.0.11[.0]
- * 1.0.19 10 10019 10.so.0.19[.0]
- * 1.2.11 13 10211 12.so.0.11[.0]
- * 1.0.20 10 10020 10.so.0.20[.0]
- * 1.2.12 13 10212 12.so.0.12[.0]
- * 1.2.13beta1 13 10213 12.so.0.13[.0]
- * 1.0.21 10 10021 10.so.0.21[.0]
- * 1.2.13 13 10213 12.so.0.13[.0]
- * 1.2.14beta1-2 13 10214 12.so.0.14[.0]
- * 1.0.22rc1 10 10022 10.so.0.22[.0]
- * 1.2.14rc1 13 10214 12.so.0.14[.0]
- * 1.0.22 10 10022 10.so.0.22[.0]
- * 1.2.14 13 10214 12.so.0.14[.0]
- * 1.2.15beta1-6 13 10215 12.so.0.15[.0]
- * 1.0.23rc1-5 10 10023 10.so.0.23[.0]
- * 1.2.15rc1-5 13 10215 12.so.0.15[.0]
- * 1.0.23 10 10023 10.so.0.23[.0]
- * 1.2.15 13 10215 12.so.0.15[.0]
- * 1.2.16beta1-2 13 10216 12.so.0.16[.0]
- * 1.2.16rc1 13 10216 12.so.0.16[.0]
- * 1.0.24 10 10024 10.so.0.24[.0]
- * 1.2.16 13 10216 12.so.0.16[.0]
- * 1.2.17beta1-2 13 10217 12.so.0.17[.0]
- * 1.0.25rc1 10 10025 10.so.0.25[.0]
- * 1.2.17rc1-3 13 10217 12.so.0.17[.0]
- * 1.0.25 10 10025 10.so.0.25[.0]
- * 1.2.17 13 10217 12.so.0.17[.0]
- * 1.0.26 10 10026 10.so.0.26[.0]
- * 1.2.18 13 10218 12.so.0.18[.0]
- * 1.2.19beta1-31 13 10219 12.so.0.19[.0]
- * 1.0.27rc1-6 10 10027 10.so.0.27[.0]
- * 1.2.19rc1-6 13 10219 12.so.0.19[.0]
- * 1.0.27 10 10027 10.so.0.27[.0]
- * 1.2.19 13 10219 12.so.0.19[.0]
- * 1.2.20beta01-04 13 10220 12.so.0.20[.0]
- * 1.0.28rc1-6 10 10028 10.so.0.28[.0]
- * 1.2.20rc1-6 13 10220 12.so.0.20[.0]
- * 1.0.28 10 10028 10.so.0.28[.0]
- * 1.2.20 13 10220 12.so.0.20[.0]
- * 1.2.21beta1-2 13 10221 12.so.0.21[.0]
- * 1.2.21rc1-3 13 10221 12.so.0.21[.0]
- * 1.0.29 10 10029 10.so.0.29[.0]
- * 1.2.21 13 10221 12.so.0.21[.0]
- *
- * Henceforth the source version will match the shared-library major
- * and minor numbers; the shared-library major version number will be
- * used for changes in backward compatibility, as it is intended. The
- * PNG_LIBPNG_VER macro, which is not used within libpng but is available
- * for applications, is an unsigned integer of the form xyyzz corresponding
- * to the source version x.y.z (leading zeros in y and z). Beta versions
- * were given the previous public release number plus a letter, until
- * version 1.0.6j; from then on they were given the upcoming public
- * release number plus "betaNN" or "rcN".
- *
- * Binary incompatibility exists only when applications make direct access
- * to the info_ptr or png_ptr members through png.h, and the compiled
- * application is loaded with a different version of the library.
- *
- * DLLNUM will change each time there are forward or backward changes
- * in binary compatibility (e.g., when a new feature is added).
- *
- * See libpng.txt or libpng.3 for more information. The PNG specification
- * is available as a W3C Recommendation and as an ISO Specification,
- * <http://www.w3.org/TR/2003/REC-PNG-20031110/
- */
-
- /*
- * COPYRIGHT NOTICE, DISCLAIMER, and LICENSE:
- *
- * If you modify libpng you may insert additional notices immediately following
- * this sentence.
- *
- * libpng versions 1.2.6, August 15, 2004, through 1.2.21, October 4, 2007, are
- * Copyright (c) 2004, 2006-2007 Glenn Randers-Pehrson, and are
- * distributed according to the same disclaimer and license as libpng-1.2.5
- * with the following individual added to the list of Contributing Authors:
- *
- * Cosmin Truta
- *
- * libpng versions 1.0.7, July 1, 2000, through 1.2.5, October 3, 2002, are
- * Copyright (c) 2000-2002 Glenn Randers-Pehrson, and are
- * distributed according to the same disclaimer and license as libpng-1.0.6
- * with the following individuals added to the list of Contributing Authors:
- *
- * Simon-Pierre Cadieux
- * Eric S. Raymond
- * Gilles Vollant
- *
- * and with the following additions to the disclaimer:
- *
- * There is no warranty against interference with your enjoyment of the
- * library or against infringement. There is no warranty that our
- * efforts or the library will fulfill any of your particular purposes
- * or needs. This library is provided with all faults, and the entire
- * risk of satisfactory quality, performance, accuracy, and effort is with
- * the user.
- *
- * libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are
- * Copyright (c) 1998, 1999, 2000 Glenn Randers-Pehrson, and are
- * distributed according to the same disclaimer and license as libpng-0.96,
- * with the following individuals added to the list of Contributing Authors:
- *
- * Tom Lane
- * Glenn Randers-Pehrson
- * Willem van Schaik
- *
- * libpng versions 0.89, June 1996, through 0.96, May 1997, are
- * Copyright (c) 1996, 1997 Andreas Dilger
- * Distributed according to the same disclaimer and license as libpng-0.88,
- * with the following individuals added to the list of Contributing Authors:
- *
- * John Bowler
- * Kevin Bracey
- * Sam Bushell
- * Magnus Holmgren
- * Greg Roelofs
- * Tom Tanner
- *
- * libpng versions 0.5, May 1995, through 0.88, January 1996, are
- * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
- *
- * For the purposes of this copyright and license, "Contributing Authors"
- * is defined as the following set of individuals:
- *
- * Andreas Dilger
- * Dave Martindale
- * Guy Eric Schalnat
- * Paul Schmidt
- * Tim Wegner
- *
- * The PNG Reference Library is supplied "AS IS". The Contributing Authors
- * and Group 42, Inc. disclaim all warranties, expressed or implied,
- * including, without limitation, the warranties of merchantability and of
- * fitness for any purpose. The Contributing Authors and Group 42, Inc.
- * assume no liability for direct, indirect, incidental, special, exemplary,
- * or consequential damages, which may result from the use of the PNG
- * Reference Library, even if advised of the possibility of such damage.
- *
- * Permission is hereby granted to use, copy, modify, and distribute this
- * source code, or portions hereof, for any purpose, without fee, subject
- * to the following restrictions:
- *
- * 1. The origin of this source code must not be misrepresented.
- *
- * 2. Altered versions must be plainly marked as such and
- * must not be misrepresented as being the original source.
- *
- * 3. This Copyright notice may not be removed or altered from
- * any source or altered source distribution.
- *
- * The Contributing Authors and Group 42, Inc. specifically permit, without
- * fee, and encourage the use of this source code as a component to
- * supporting the PNG file format in commercial products. If you use this
- * source code in a product, acknowledgment is not required but would be
- * appreciated.
- */
-
- /*
- * A "png_get_copyright" function is available, for convenient use in "about"
- * boxes and the like:
- *
- * printf("%s",png_get_copyright(NULL));
- *
- * Also, the PNG logo (in PNG format, of course) is supplied in the
- * files "pngbar.png" and "pngbar.jpg (88x31) and "pngnow.png" (98x31).
- */
-
- /*
- * Libpng is OSI Certified Open Source Software. OSI Certified is a
- * certification mark of the Open Source Initiative.
- */
-
- /*
- * The contributing authors would like to thank all those who helped
- * with testing, bug fixes, and patience. This wouldn't have been
- * possible without all of you.
- *
- * Thanks to Frank J. T. Wojcik for helping with the documentation.
- */
-
- /*
- * Y2K compliance in libpng:
- * =========================
- *
- * October 4, 2007
- *
- * Since the PNG Development group is an ad-hoc body, we can't make
- * an official declaration.
- *
- * This is your unofficial assurance that libpng from version 0.71 and
- * upward through 1.2.21 are Y2K compliant. It is my belief that earlier
- * versions were also Y2K compliant.
- *
- * Libpng only has three year fields. One is a 2-byte unsigned integer
- * that will hold years up to 65535. The other two hold the date in text
- * format, and will hold years up to 9999.
- *
- * The integer is
- * "png_uint_16 year" in png_time_struct.
- *
- * The strings are
- * "png_charp time_buffer" in png_struct and
- * "near_time_buffer", which is a local character string in png.c.
- *
- * There are seven time-related functions:
- * png.c: png_convert_to_rfc_1123() in png.c
- * (formerly png_convert_to_rfc_1152() in error)
- * png_convert_from_struct_tm() in pngwrite.c, called in pngwrite.c
- * png_convert_from_time_t() in pngwrite.c
- * png_get_tIME() in pngget.c
- * png_handle_tIME() in pngrutil.c, called in pngread.c
- * png_set_tIME() in pngset.c
- * png_write_tIME() in pngwutil.c, called in pngwrite.c
- *
- * All handle dates properly in a Y2K environment. The
- * png_convert_from_time_t() function calls gmtime() to convert from system
- * clock time, which returns (year - 1900), which we properly convert to
- * the full 4-digit year. There is a possibility that applications using
- * libpng are not passing 4-digit years into the png_convert_to_rfc_1123()
- * function, or that they are incorrectly passing only a 2-digit year
- * instead of "year - 1900" into the png_convert_from_struct_tm() function,
- * but this is not under our control. The libpng documentation has always
- * stated that it works with 4-digit years, and the APIs have been
- * documented as such.
- *
- * The tIME chunk itself is also Y2K compliant. It uses a 2-byte unsigned
- * integer to hold the year, and can hold years as large as 65535.
- *
- * zlib, upon which libpng depends, is also Y2K compliant. It contains
- * no date-related code.
- *
- * Glenn Randers-Pehrson
- * libpng maintainer
- * PNG Development Group
- */
-
- #ifndef PNG_H
- #define PNG_H
-
- /* This is not the place to learn how to use libpng. The file libpng.txt
- * describes how to use libpng, and the file example.c summarizes it
- * with some code on which to build. This file is useful for looking
- * at the actual function definitions and structure components.
- */
-
- /* Version information for png.h - this should match the version in png.c */
- #define PNG_LIBPNG_VER_STRING "1.2.21"
- #define PNG_HEADER_VERSION_STRING \
- " libpng version 1.2.21 - October 4, 2007\n"
-
- #define PNG_LIBPNG_VER_SONUM 0
- #define PNG_LIBPNG_VER_DLLNUM 13
-
- /* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */
- #define PNG_LIBPNG_VER_MAJOR 1
- #define PNG_LIBPNG_VER_MINOR 2
- #define PNG_LIBPNG_VER_RELEASE 21
- /* This should match the numeric part of the final component of
- * PNG_LIBPNG_VER_STRING, omitting any leading zero: */
-
- #define PNG_LIBPNG_VER_BUILD 0
-
- /* Release Status */
- #define PNG_LIBPNG_BUILD_ALPHA 1
- #define PNG_LIBPNG_BUILD_BETA 2
- #define PNG_LIBPNG_BUILD_RC 3
- #define PNG_LIBPNG_BUILD_STABLE 4
- #define PNG_LIBPNG_BUILD_RELEASE_STATUS_MASK 7
-
- /* Release-Specific Flags */
- #define PNG_LIBPNG_BUILD_PATCH 8 /* Can be OR'ed with
- PNG_LIBPNG_BUILD_STABLE only */
- #define PNG_LIBPNG_BUILD_PRIVATE 16 /* Cannot be OR'ed with
- PNG_LIBPNG_BUILD_SPECIAL */
- #define PNG_LIBPNG_BUILD_SPECIAL 32 /* Cannot be OR'ed with
- PNG_LIBPNG_BUILD_PRIVATE */
-
- #define PNG_LIBPNG_BUILD_BASE_TYPE PNG_LIBPNG_BUILD_STABLE
-
- /* Careful here. At one time, Guy wanted to use 082, but that would be octal.
- * We must not include leading zeros.
- * Versions 0.7 through 1.0.0 were in the range 0 to 100 here (only
- * version 1.0.0 was mis-numbered 100 instead of 10000). From
- * version 1.0.1 it's xxyyzz, where x=major, y=minor, z=release */
- #define PNG_LIBPNG_VER 10221 /* 1.2.21 */
-
- #ifndef PNG_VERSION_INFO_ONLY
- /* include the compression library's header */
-
- #endif
-
- /* include all user configurable info, including optional assembler routines */
-
- /********* Start of inlined file: pngconf.h *********/
- /* pngconf.h - machine configurable file for libpng
- *
- * libpng version 1.2.21 - October 4, 2007
- * For conditions of distribution and use, see copyright notice in png.h
- * Copyright (c) 1998-2007 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
- */
-
- /* Any machine specific code is near the front of this file, so if you
- * are configuring libpng for a machine, you may want to read the section
- * starting here down to where it starts to typedef png_color, png_text,
- * and png_info.
- */
-
- #ifndef PNGCONF_H
- #define PNGCONF_H
-
- #define PNG_1_2_X
-
- // These are some Juce config settings that should remove any unnecessary code bloat..
-
- #define PNG_NO_STDIO 1
- #define PNG_DEBUG 0
- #define PNG_NO_WARNINGS 1
- #define PNG_NO_ERROR_TEXT 1
- #define PNG_NO_ERROR_NUMBERS 1
- #define PNG_NO_USER_MEM 1
- #define PNG_NO_READ_iCCP 1
- #define PNG_NO_READ_UNKNOWN_CHUNKS 1
- #define PNG_NO_READ_USER_CHUNKS 1
- #define PNG_NO_READ_iTXt 1
- #define PNG_NO_READ_sCAL 1
- #define PNG_NO_READ_sPLT 1
-
- #define png_error(a, b) png_err(a)
- #define png_warning(a, b)
- #define png_chunk_error(a, b) png_err(a)
- #define png_chunk_warning(a, b)
-
- /*
- * PNG_USER_CONFIG has to be defined on the compiler command line. This
- * includes the resource compiler for Windows DLL configurations.
- */
- #ifdef PNG_USER_CONFIG
- # ifndef PNG_USER_PRIVATEBUILD
- # define PNG_USER_PRIVATEBUILD
- # endif
- #include "pngusr.h"
- #endif
-
- /* PNG_CONFIGURE_LIBPNG is set by the "configure" script. */
- #ifdef PNG_CONFIGURE_LIBPNG
- #ifdef HAVE_CONFIG_H
- #include "config.h"
- #endif
- #endif
-
- /*
- * Added at libpng-1.2.8
- *
- * If you create a private DLL you need to define in "pngusr.h" the followings:
- * #define PNG_USER_PRIVATEBUILD <Describes by whom and why this version of
- * the DLL was built>
- * e.g. #define PNG_USER_PRIVATEBUILD "Build by MyCompany for xyz reasons."
- * #define PNG_USER_DLLFNAME_POSTFIX <two-letter postfix that serve to
- * distinguish your DLL from those of the official release. These
- * correspond to the trailing letters that come after the version
- * number and must match your private DLL name>
- * e.g. // private DLL "libpng13gx.dll"
- * #define PNG_USER_DLLFNAME_POSTFIX "gx"
- *
- * The following macros are also at your disposal if you want to complete the
- * DLL VERSIONINFO structure.
- * - PNG_USER_VERSIONINFO_COMMENTS
- * - PNG_USER_VERSIONINFO_COMPANYNAME
- * - PNG_USER_VERSIONINFO_LEGALTRADEMARKS
- */
-
- #ifdef __STDC__
- #ifdef SPECIALBUILD
- # pragma message("PNG_LIBPNG_SPECIALBUILD (and deprecated SPECIALBUILD)\
- are now LIBPNG reserved macros. Use PNG_USER_PRIVATEBUILD instead.")
- #endif
-
- #ifdef PRIVATEBUILD
- # pragma message("PRIVATEBUILD is deprecated.\
- Use PNG_USER_PRIVATEBUILD instead.")
- # define PNG_USER_PRIVATEBUILD PRIVATEBUILD
- #endif
- #endif /* __STDC__ */
-
- #ifndef PNG_VERSION_INFO_ONLY
-
- /* End of material added to libpng-1.2.8 */
-
- /* Added at libpng-1.2.19, removed at libpng-1.2.20 because it caused trouble
- Restored at libpng-1.2.21 */
- # define PNG_WARN_UNINITIALIZED_ROW 1
- /* End of material added at libpng-1.2.19/1.2.21 */
-
- /* This is the size of the compression buffer, and thus the size of
- * an IDAT chunk. Make this whatever size you feel is best for your
- * machine. One of these will be allocated per png_struct. When this
- * is full, it writes the data to the disk, and does some other
- * calculations. Making this an extremely small size will slow
- * the library down, but you may want to experiment to determine
- * where it becomes significant, if you are concerned with memory
- * usage. Note that zlib allocates at least 32Kb also. For readers,
- * this describes the size of the buffer available to read the data in.
- * Unless this gets smaller than the size of a row (compressed),
- * it should not make much difference how big this is.
- */
-
- #ifndef PNG_ZBUF_SIZE
- # define PNG_ZBUF_SIZE 8192
- #endif
-
- /* Enable if you want a write-only libpng */
-
- #ifndef PNG_NO_READ_SUPPORTED
- # define PNG_READ_SUPPORTED
- #endif
-
- /* Enable if you want a read-only libpng */
-
- #ifndef PNG_NO_WRITE_SUPPORTED
- # define PNG_WRITE_SUPPORTED
- #endif
-
- /* Enabled by default in 1.2.0. You can disable this if you don't need to
- support PNGs that are embedded in MNG datastreams */
- #if !defined(PNG_1_0_X) && !defined(PNG_NO_MNG_FEATURES)
- # ifndef PNG_MNG_FEATURES_SUPPORTED
- # define PNG_MNG_FEATURES_SUPPORTED
- # endif
- #endif
-
- #ifndef PNG_NO_FLOATING_POINT_SUPPORTED
- # ifndef PNG_FLOATING_POINT_SUPPORTED
- # define PNG_FLOATING_POINT_SUPPORTED
- # endif
- #endif
-
- /* If you are running on a machine where you cannot allocate more
- * than 64K of memory at once, uncomment this. While libpng will not
- * normally need that much memory in a chunk (unless you load up a very
- * large file), zlib needs to know how big of a chunk it can use, and
- * libpng thus makes sure to check any memory allocation to verify it
- * will fit into memory.
- #define PNG_MAX_MALLOC_64K
- */
- #if defined(MAXSEG_64K) && !defined(PNG_MAX_MALLOC_64K)
- # define PNG_MAX_MALLOC_64K
- #endif
-
- /* Special munging to support doing things the 'cygwin' way:
- * 'Normal' png-on-win32 defines/defaults:
- * PNG_BUILD_DLL -- building dll
- * PNG_USE_DLL -- building an application, linking to dll
- * (no define) -- building static library, or building an
- * application and linking to the static lib
- * 'Cygwin' defines/defaults:
- * PNG_BUILD_DLL -- (ignored) building the dll
- * (no define) -- (ignored) building an application, linking to the dll
- * PNG_STATIC -- (ignored) building the static lib, or building an
- * application that links to the static lib.
- * ALL_STATIC -- (ignored) building various static libs, or building an
- * application that links to the static libs.
- * Thus,
- * a cygwin user should define either PNG_BUILD_DLL or PNG_STATIC, and
- * this bit of #ifdefs will define the 'correct' config variables based on
- * that. If a cygwin user *wants* to define 'PNG_USE_DLL' that's okay, but
- * unnecessary.
- *
- * Also, the precedence order is:
- * ALL_STATIC (since we can't #undef something outside our namespace)
- * PNG_BUILD_DLL
- * PNG_STATIC
- * (nothing) == PNG_USE_DLL
- *
- * CYGWIN (2002-01-20): The preceding is now obsolete. With the advent
- * of auto-import in binutils, we no longer need to worry about
- * __declspec(dllexport) / __declspec(dllimport) and friends. Therefore,
- * we don't need to worry about PNG_STATIC or ALL_STATIC when it comes
- * to __declspec() stuff. However, we DO need to worry about
- * PNG_BUILD_DLL and PNG_STATIC because those change some defaults
- * such as CONSOLE_IO and whether GLOBAL_ARRAYS are allowed.
- */
- #if defined(__CYGWIN__)
- # if defined(ALL_STATIC)
- # if defined(PNG_BUILD_DLL)
- # undef PNG_BUILD_DLL
- # endif
- # if defined(PNG_USE_DLL)
- # undef PNG_USE_DLL
- # endif
- # if defined(PNG_DLL)
- # undef PNG_DLL
- # endif
- # if !defined(PNG_STATIC)
- # define PNG_STATIC
- # endif
- # else
- # if defined (PNG_BUILD_DLL)
- # if defined(PNG_STATIC)
- # undef PNG_STATIC
- # endif
- # if defined(PNG_USE_DLL)
- # undef PNG_USE_DLL
- # endif
- # if !defined(PNG_DLL)
- # define PNG_DLL
- # endif
- # else
- # if defined(PNG_STATIC)
- # if defined(PNG_USE_DLL)
- # undef PNG_USE_DLL
- # endif
- # if defined(PNG_DLL)
- # undef PNG_DLL
- # endif
- # else
- # if !defined(PNG_USE_DLL)
- # define PNG_USE_DLL
- # endif
- # if !defined(PNG_DLL)
- # define PNG_DLL
- # endif
- # endif
- # endif
- # endif
- #endif
-
- /* This protects us against compilers that run on a windowing system
- * and thus don't have or would rather us not use the stdio types:
- * stdin, stdout, and stderr. The only one currently used is stderr
- * in png_error() and png_warning(). #defining PNG_NO_CONSOLE_IO will
- * prevent these from being compiled and used. #defining PNG_NO_STDIO
- * will also prevent these, plus will prevent the entire set of stdio
- * macros and functions (FILE *, printf, etc.) from being compiled and used,
- * unless (PNG_DEBUG > 0) has been #defined.
- *
- * #define PNG_NO_CONSOLE_IO
- * #define PNG_NO_STDIO
- */
-
- #if defined(_WIN32_WCE)
- # include <windows.h>
- /* Console I/O functions are not supported on WindowsCE */
- # define PNG_NO_CONSOLE_IO
- # ifdef PNG_DEBUG
- # undef PNG_DEBUG
- # endif
- #endif
-
- #ifdef PNG_BUILD_DLL
- # ifndef PNG_CONSOLE_IO_SUPPORTED
- # ifndef PNG_NO_CONSOLE_IO
- # define PNG_NO_CONSOLE_IO
- # endif
- # endif
- #endif
-
- # ifdef PNG_NO_STDIO
- # ifndef PNG_NO_CONSOLE_IO
- # define PNG_NO_CONSOLE_IO
- # endif
- # ifdef PNG_DEBUG
- # if (PNG_DEBUG > 0)
- # include <stdio.h>
- # endif
- # endif
- # else
- # if !defined(_WIN32_WCE)
- /* "stdio.h" functions are not supported on WindowsCE */
- # include <stdio.h>
- # endif
- # endif
-
- /* This macro protects us against machines that don't have function
- * prototypes (ie K&R style headers). If your compiler does not handle
- * function prototypes, define this macro and use the included ansi2knr.
- * I've always been able to use _NO_PROTO as the indicator, but you may
- * need to drag the empty declaration out in front of here, or change the
- * ifdef to suit your own needs.
- */
- #ifndef PNGARG
-
- #ifdef OF /* zlib prototype munger */
- # define PNGARG(arglist) OF(arglist)
- #else
-
- #ifdef _NO_PROTO
- # define PNGARG(arglist) ()
- # ifndef PNG_TYPECAST_NULL
- # define PNG_TYPECAST_NULL
- # endif
- #else
- # define PNGARG(arglist) arglist
- #endif /* _NO_PROTO */
-
- #endif /* OF */
-
- #endif /* PNGARG */
-
- /* Try to determine if we are compiling on a Mac. Note that testing for
- * just __MWERKS__ is not good enough, because the Codewarrior is now used
- * on non-Mac platforms.
- */
- #ifndef MACOS
- # if (defined(__MWERKS__) && defined(macintosh)) || defined(applec) || \
- defined(THINK_C) || defined(__SC__) || defined(TARGET_OS_MAC)
- # define MACOS
- # endif
- #endif
-
- /* enough people need this for various reasons to include it here */
- #if !defined(MACOS) && !defined(RISCOS) && !defined(_WIN32_WCE)
- # include <sys/types.h>
- #endif
-
- #if !defined(PNG_SETJMP_NOT_SUPPORTED) && !defined(PNG_NO_SETJMP_SUPPORTED)
- # define PNG_SETJMP_SUPPORTED
- #endif
-
- #ifdef PNG_SETJMP_SUPPORTED
- /* This is an attempt to force a single setjmp behaviour on Linux. If
- * the X config stuff didn't define _BSD_SOURCE we wouldn't need this.
- */
-
- # ifdef __linux__
- # ifdef _BSD_SOURCE
- # define PNG_SAVE_BSD_SOURCE
- # undef _BSD_SOURCE
- # endif
- # ifdef _SETJMP_H
- /* If you encounter a compiler error here, see the explanation
- * near the end of INSTALL.
- */
- __png.h__ already includes setjmp.h;
- __dont__ include it again.;
- # endif
- # endif /* __linux__ */
-
- /* include setjmp.h for error handling */
- # include <setjmp.h>
-
- # ifdef __linux__
- # ifdef PNG_SAVE_BSD_SOURCE
- # define _BSD_SOURCE
- # undef PNG_SAVE_BSD_SOURCE
- # endif
- # endif /* __linux__ */
- #endif /* PNG_SETJMP_SUPPORTED */
-
- #ifdef BSD
- # include <strings.h>
- #else
- # include <string.h>
- #endif
-
- /* Other defines for things like memory and the like can go here. */
- #ifdef PNG_INTERNAL
-
- #include <stdlib.h>
-
- /* The functions exported by PNG_EXTERN are PNG_INTERNAL functions, which
- * aren't usually used outside the library (as far as I know), so it is
- * debatable if they should be exported at all. In the future, when it is
- * possible to have run-time registry of chunk-handling functions, some of
- * these will be made available again.
- #define PNG_EXTERN extern
- */
- #define PNG_EXTERN
-
- /* Other defines specific to compilers can go here. Try to keep
- * them inside an appropriate ifdef/endif pair for portability.
- */
-
- #if defined(PNG_FLOATING_POINT_SUPPORTED)
- # if defined(MACOS)
- /* We need to check that <math.h> hasn't already been included earlier
- * as it seems it doesn't agree with <fp.h>, yet we should really use
- * <fp.h> if possible.
- */
- # if !defined(__MATH_H__) && !defined(__MATH_H) && !defined(__cmath__)
- # include <fp.h>
- # endif
- # else
- # include <math.h>
- # endif
- # if defined(_AMIGA) && defined(__SASC) && defined(_M68881)
- /* Amiga SAS/C: We must include builtin FPU functions when compiling using
- * MATH=68881
- */
- # include <m68881.h>
- # endif
- #endif
-
- /* Codewarrior on NT has linking problems without this. */
- #if (defined(__MWERKS__) && defined(WIN32)) || defined(__STDC__)
- # define PNG_ALWAYS_EXTERN
- #endif
-
- /* This provides the non-ANSI (far) memory allocation routines. */
- #if defined(__TURBOC__) && defined(__MSDOS__)
- # include <mem.h>
- # include <alloc.h>
- #endif
-
- /* I have no idea why is this necessary... */
- #if defined(_MSC_VER) && (defined(WIN32) || defined(_Windows) || \
- defined(_WINDOWS) || defined(_WIN32) || defined(__WIN32__))
- # include <malloc.h>
- #endif
-
- /* This controls how fine the dithering gets. As this allocates
- * a largish chunk of memory (32K), those who are not as concerned
- * with dithering quality can decrease some or all of these.
- */
- #ifndef PNG_DITHER_RED_BITS
- # define PNG_DITHER_RED_BITS 5
- #endif
- #ifndef PNG_DITHER_GREEN_BITS
- # define PNG_DITHER_GREEN_BITS 5
- #endif
- #ifndef PNG_DITHER_BLUE_BITS
- # define PNG_DITHER_BLUE_BITS 5
- #endif
-
- /* This controls how fine the gamma correction becomes when you
- * are only interested in 8 bits anyway. Increasing this value
- * results in more memory being used, and more pow() functions
- * being called to fill in the gamma tables. Don't set this value
- * less then 8, and even that may not work (I haven't tested it).
- */
-
- #ifndef PNG_MAX_GAMMA_8
- # define PNG_MAX_GAMMA_8 11
- #endif
-
- /* This controls how much a difference in gamma we can tolerate before
- * we actually start doing gamma conversion.
- */
- #ifndef PNG_GAMMA_THRESHOLD
- # define PNG_GAMMA_THRESHOLD 0.05
- #endif
-
- #endif /* PNG_INTERNAL */
-
- /* The following uses const char * instead of char * for error
- * and warning message functions, so some compilers won't complain.
- * If you do not want to use const, define PNG_NO_CONST here.
- */
-
- #ifndef PNG_NO_CONST
- # define PNG_CONST const
- #else
- # define PNG_CONST
- #endif
-
- /* The following defines give you the ability to remove code from the
- * library that you will not be using. I wish I could figure out how to
- * automate this, but I can't do that without making it seriously hard
- * on the users. So if you are not using an ability, change the #define
- * to and #undef, and that part of the library will not be compiled. If
- * your linker can't find a function, you may want to make sure the
- * ability is defined here. Some of these depend upon some others being
- * defined. I haven't figured out all the interactions here, so you may
- * have to experiment awhile to get everything to compile. If you are
- * creating or using a shared library, you probably shouldn't touch this,
- * as it will affect the size of the structures, and this will cause bad
- * things to happen if the library and/or application ever change.
- */
-
- /* Any features you will not be using can be undef'ed here */
-
- /* GR-P, 0.96a: Set "*TRANSFORMS_SUPPORTED as default but allow user
- * to turn it off with "*TRANSFORMS_NOT_SUPPORTED" or *PNG_NO_*_TRANSFORMS
- * on the compile line, then pick and choose which ones to define without
- * having to edit this file. It is safe to use the *TRANSFORMS_NOT_SUPPORTED
- * if you only want to have a png-compliant reader/writer but don't need
- * any of the extra transformations. This saves about 80 kbytes in a
- * typical installation of the library. (PNG_NO_* form added in version
- * 1.0.1c, for consistency)
- */
-
- /* The size of the png_text structure changed in libpng-1.0.6 when
- * iTXt support was added. iTXt support was turned off by default through
- * libpng-1.2.x, to support old apps that malloc the png_text structure
- * instead of calling png_set_text() and letting libpng malloc it. It
- * was turned on by default in libpng-1.3.0.
- */
-
- #if defined(PNG_1_0_X) || defined (PNG_1_2_X)
- # ifndef PNG_NO_iTXt_SUPPORTED
- # define PNG_NO_iTXt_SUPPORTED
- # endif
- # ifndef PNG_NO_READ_iTXt
- # define PNG_NO_READ_iTXt
- # endif
- # ifndef PNG_NO_WRITE_iTXt
- # define PNG_NO_WRITE_iTXt
- # endif
- #endif
-
- #if !defined(PNG_NO_iTXt_SUPPORTED)
- # if !defined(PNG_READ_iTXt_SUPPORTED) && !defined(PNG_NO_READ_iTXt)
- # define PNG_READ_iTXt
- # endif
- # if !defined(PNG_WRITE_iTXt_SUPPORTED) && !defined(PNG_NO_WRITE_iTXt)
- # define PNG_WRITE_iTXt
- # endif
- #endif
-
- /* The following support, added after version 1.0.0, can be turned off here en
- * masse by defining PNG_LEGACY_SUPPORTED in case you need binary compatibility
- * with old applications that require the length of png_struct and png_info
- * to remain unchanged.
- */
-
- #ifdef PNG_LEGACY_SUPPORTED
- # define PNG_NO_FREE_ME
- # define PNG_NO_READ_UNKNOWN_CHUNKS
- # define PNG_NO_WRITE_UNKNOWN_CHUNKS
- # define PNG_NO_READ_USER_CHUNKS
- # define PNG_NO_READ_iCCP
- # define PNG_NO_WRITE_iCCP
- # define PNG_NO_READ_iTXt
- # define PNG_NO_WRITE_iTXt
- # define PNG_NO_READ_sCAL
- # define PNG_NO_WRITE_sCAL
- # define PNG_NO_READ_sPLT
- # define PNG_NO_WRITE_sPLT
- # define PNG_NO_INFO_IMAGE
- # define PNG_NO_READ_RGB_TO_GRAY
- # define PNG_NO_READ_USER_TRANSFORM
- # define PNG_NO_WRITE_USER_TRANSFORM
- # define PNG_NO_USER_MEM
- # define PNG_NO_READ_EMPTY_PLTE
- # define PNG_NO_MNG_FEATURES
- # define PNG_NO_FIXED_POINT_SUPPORTED
- #endif
-
- /* Ignore attempt to turn off both floating and fixed point support */
- #if !defined(PNG_FLOATING_POINT_SUPPORTED) || \
- !defined(PNG_NO_FIXED_POINT_SUPPORTED)
- # define PNG_FIXED_POINT_SUPPORTED
- #endif
-
- #ifndef PNG_NO_FREE_ME
- # define PNG_FREE_ME_SUPPORTED
- #endif
-
- #if defined(PNG_READ_SUPPORTED)
-
- #if !defined(PNG_READ_TRANSFORMS_NOT_SUPPORTED) && \
- !defined(PNG_NO_READ_TRANSFORMS)
- # define PNG_READ_TRANSFORMS_SUPPORTED
- #endif
-
- #ifdef PNG_READ_TRANSFORMS_SUPPORTED
- # ifndef PNG_NO_READ_EXPAND
- # define PNG_READ_EXPAND_SUPPORTED
- # endif
- # ifndef PNG_NO_READ_SHIFT
- # define PNG_READ_SHIFT_SUPPORTED
- # endif
- # ifndef PNG_NO_READ_PACK
- # define PNG_READ_PACK_SUPPORTED
- # endif
- # ifndef PNG_NO_READ_BGR
- # define PNG_READ_BGR_SUPPORTED
- # endif
- # ifndef PNG_NO_READ_SWAP
- # define PNG_READ_SWAP_SUPPORTED
- # endif
- # ifndef PNG_NO_READ_PACKSWAP
- # define PNG_READ_PACKSWAP_SUPPORTED
- # endif
- # ifndef PNG_NO_READ_INVERT
- # define PNG_READ_INVERT_SUPPORTED
- # endif
- # ifndef PNG_NO_READ_DITHER
- # define PNG_READ_DITHER_SUPPORTED
- # endif
- # ifndef PNG_NO_READ_BACKGROUND
- # define PNG_READ_BACKGROUND_SUPPORTED
- # endif
- # ifndef PNG_NO_READ_16_TO_8
- # define PNG_READ_16_TO_8_SUPPORTED
- # endif
- # ifndef PNG_NO_READ_FILLER
- # define PNG_READ_FILLER_SUPPORTED
- # endif
- # ifndef PNG_NO_READ_GAMMA
- # define PNG_READ_GAMMA_SUPPORTED
- # endif
- # ifndef PNG_NO_READ_GRAY_TO_RGB
- # define PNG_READ_GRAY_TO_RGB_SUPPORTED
- # endif
- # ifndef PNG_NO_READ_SWAP_ALPHA
- # define PNG_READ_SWAP_ALPHA_SUPPORTED
- # endif
- # ifndef PNG_NO_READ_INVERT_ALPHA
- # define PNG_READ_INVERT_ALPHA_SUPPORTED
- # endif
- # ifndef PNG_NO_READ_STRIP_ALPHA
- # define PNG_READ_STRIP_ALPHA_SUPPORTED
- # endif
- # ifndef PNG_NO_READ_USER_TRANSFORM
- # define PNG_READ_USER_TRANSFORM_SUPPORTED
- # endif
- # ifndef PNG_NO_READ_RGB_TO_GRAY
- # define PNG_READ_RGB_TO_GRAY_SUPPORTED
- # endif
- #endif /* PNG_READ_TRANSFORMS_SUPPORTED */
-
- #if !defined(PNG_NO_PROGRESSIVE_READ) && \
- !defined(PNG_PROGRESSIVE_READ_SUPPORTED) /* if you don't do progressive */
- # define PNG_PROGRESSIVE_READ_SUPPORTED /* reading. This is not talking */
- #endif /* about interlacing capability! You'll */
- /* still have interlacing unless you change the following line: */
-
- #define PNG_READ_INTERLACING_SUPPORTED /* required in PNG-compliant decoders */
-
- #ifndef PNG_NO_READ_COMPOSITE_NODIV
- # ifndef PNG_NO_READ_COMPOSITED_NODIV /* libpng-1.0.x misspelling */
- # define PNG_READ_COMPOSITE_NODIV_SUPPORTED /* well tested on Intel, SGI */
- # endif
- #endif
-
- #if defined(PNG_1_0_X) || defined (PNG_1_2_X)
- /* Deprecated, will be removed from version 2.0.0.
- Use PNG_MNG_FEATURES_SUPPORTED instead. */
- #ifndef PNG_NO_READ_EMPTY_PLTE
- # define PNG_READ_EMPTY_PLTE_SUPPORTED
- #endif
- #endif
-
- #endif /* PNG_READ_SUPPORTED */
-
- #if defined(PNG_WRITE_SUPPORTED)
-
- # if !defined(PNG_WRITE_TRANSFORMS_NOT_SUPPORTED) && \
- !defined(PNG_NO_WRITE_TRANSFORMS)
- # define PNG_WRITE_TRANSFORMS_SUPPORTED
- #endif
-
- #ifdef PNG_WRITE_TRANSFORMS_SUPPORTED
- # ifndef PNG_NO_WRITE_SHIFT
- # define PNG_WRITE_SHIFT_SUPPORTED
- # endif
- # ifndef PNG_NO_WRITE_PACK
- # define PNG_WRITE_PACK_SUPPORTED
- # endif
- # ifndef PNG_NO_WRITE_BGR
- # define PNG_WRITE_BGR_SUPPORTED
- # endif
- # ifndef PNG_NO_WRITE_SWAP
- # define PNG_WRITE_SWAP_SUPPORTED
- # endif
- # ifndef PNG_NO_WRITE_PACKSWAP
- # define PNG_WRITE_PACKSWAP_SUPPORTED
- # endif
- # ifndef PNG_NO_WRITE_INVERT
- # define PNG_WRITE_INVERT_SUPPORTED
- # endif
- # ifndef PNG_NO_WRITE_FILLER
- # define PNG_WRITE_FILLER_SUPPORTED /* same as WRITE_STRIP_ALPHA */
- # endif
- # ifndef PNG_NO_WRITE_SWAP_ALPHA
- # define PNG_WRITE_SWAP_ALPHA_SUPPORTED
- # endif
- # ifndef PNG_NO_WRITE_INVERT_ALPHA
- # define PNG_WRITE_INVERT_ALPHA_SUPPORTED
- # endif
- # ifndef PNG_NO_WRITE_USER_TRANSFORM
- # define PNG_WRITE_USER_TRANSFORM_SUPPORTED
- # endif
- #endif /* PNG_WRITE_TRANSFORMS_SUPPORTED */
-
- #if !defined(PNG_NO_WRITE_INTERLACING_SUPPORTED) && \
- !defined(PNG_WRITE_INTERLACING_SUPPORTED)
- #define PNG_WRITE_INTERLACING_SUPPORTED /* not required for PNG-compliant
- encoders, but can cause trouble
- if left undefined */
- #endif
-
- #if !defined(PNG_NO_WRITE_WEIGHTED_FILTER) && \
- !defined(PNG_WRITE_WEIGHTED_FILTER) && \
- defined(PNG_FLOATING_POINT_SUPPORTED)
- # define PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
- #endif
-
- #ifndef PNG_NO_WRITE_FLUSH
- # define PNG_WRITE_FLUSH_SUPPORTED
- #endif
-
- #if defined(PNG_1_0_X) || defined (PNG_1_2_X)
- /* Deprecated, see PNG_MNG_FEATURES_SUPPORTED, above */
- #ifndef PNG_NO_WRITE_EMPTY_PLTE
- # define PNG_WRITE_EMPTY_PLTE_SUPPORTED
- #endif
- #endif
-
- #endif /* PNG_WRITE_SUPPORTED */
-
- #ifndef PNG_1_0_X
- # ifndef PNG_NO_ERROR_NUMBERS
- # define PNG_ERROR_NUMBERS_SUPPORTED
- # endif
- #endif /* PNG_1_0_X */
-
- #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
- defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
- # ifndef PNG_NO_USER_TRANSFORM_PTR
- # define PNG_USER_TRANSFORM_PTR_SUPPORTED
- # endif
- #endif
-
- #ifndef PNG_NO_STDIO
- # define PNG_TIME_RFC1123_SUPPORTED
- #endif
-
- /* This adds extra functions in pngget.c for accessing data from the
- * info pointer (added in version 0.99)
- * png_get_image_width()
- * png_get_image_height()
- * png_get_bit_depth()
- * png_get_color_type()
- * png_get_compression_type()
- * png_get_filter_type()
- * png_get_interlace_type()
- * png_get_pixel_aspect_ratio()
- * png_get_pixels_per_meter()
- * png_get_x_offset_pixels()
- * png_get_y_offset_pixels()
- * png_get_x_offset_microns()
- * png_get_y_offset_microns()
- */
- #if !defined(PNG_NO_EASY_ACCESS) && !defined(PNG_EASY_ACCESS_SUPPORTED)
- # define PNG_EASY_ACCESS_SUPPORTED
- #endif
-
- /* PNG_ASSEMBLER_CODE was enabled by default in version 1.2.0
- * and removed from version 1.2.20. The following will be removed
- * from libpng-1.4.0
- */
-
- #if defined(PNG_READ_SUPPORTED) && !defined(PNG_NO_OPTIMIZED_CODE)
- # ifndef PNG_OPTIMIZED_CODE_SUPPORTED
- # define PNG_OPTIMIZED_CODE_SUPPORTED
- # endif
- #endif
-
- #if defined(PNG_READ_SUPPORTED) && !defined(PNG_NO_ASSEMBLER_CODE)
- # ifndef PNG_ASSEMBLER_CODE_SUPPORTED
- # define PNG_ASSEMBLER_CODE_SUPPORTED
- # endif
-
- # if defined(__GNUC__) && defined(__x86_64__) && (__GNUC__ < 4)
- /* work around 64-bit gcc compiler bugs in gcc-3.x */
- # if !defined(PNG_MMX_CODE_SUPPORTED) && !defined(PNG_NO_MMX_CODE)
- # define PNG_NO_MMX_CODE
- # endif
- # endif
-
- # if defined(__APPLE__)
- # if !defined(PNG_MMX_CODE_SUPPORTED) && !defined(PNG_NO_MMX_CODE)
- # define PNG_NO_MMX_CODE
- # endif
- # endif
-
- # if (defined(__MWERKS__) && ((__MWERKS__ < 0x0900) || macintosh))
- # if !defined(PNG_MMX_CODE_SUPPORTED) && !defined(PNG_NO_MMX_CODE)
- # define PNG_NO_MMX_CODE
- # endif
- # endif
-
- # if !defined(PNG_MMX_CODE_SUPPORTED) && !defined(PNG_NO_MMX_CODE)
- # define PNG_MMX_CODE_SUPPORTED
- # endif
-
- #endif
- /* end of obsolete code to be removed from libpng-1.4.0 */
-
- #if !defined(PNG_1_0_X)
- #if !defined(PNG_NO_USER_MEM) && !defined(PNG_USER_MEM_SUPPORTED)
- # define PNG_USER_MEM_SUPPORTED
- #endif
- #endif /* PNG_1_0_X */
-
- /* Added at libpng-1.2.6 */
- #if !defined(PNG_1_0_X)
- #ifndef PNG_SET_USER_LIMITS_SUPPORTED
- #if !defined(PNG_NO_SET_USER_LIMITS) && !defined(PNG_SET_USER_LIMITS_SUPPORTED)
- # define PNG_SET_USER_LIMITS_SUPPORTED
- #endif
- #endif
- #endif /* PNG_1_0_X */
-
- /* Added at libpng-1.0.16 and 1.2.6. To accept all valid PNGS no matter
- * how large, set these limits to 0x7fffffffL
- */
- #ifndef PNG_USER_WIDTH_MAX
- # define PNG_USER_WIDTH_MAX 1000000L
- #endif
- #ifndef PNG_USER_HEIGHT_MAX
- # define PNG_USER_HEIGHT_MAX 1000000L
- #endif
-
- /* These are currently experimental features, define them if you want */
-
- /* very little testing */
- /*
- #ifdef PNG_READ_SUPPORTED
- # ifndef PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED
- # define PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED
- # endif
- #endif
- */
-
- /* This is only for PowerPC big-endian and 680x0 systems */
- /* some testing */
- /*
- #ifndef PNG_READ_BIG_ENDIAN_SUPPORTED
- # define PNG_READ_BIG_ENDIAN_SUPPORTED
- #endif
- */
-
- /* Buggy compilers (e.g., gcc 2.7.2.2) need this */
- /*
- #define PNG_NO_POINTER_INDEXING
- */
-
- /* These functions are turned off by default, as they will be phased out. */
- /*
- #define PNG_USELESS_TESTS_SUPPORTED
- #define PNG_CORRECT_PALETTE_SUPPORTED
- */
-
- /* Any chunks you are not interested in, you can undef here. The
- * ones that allocate memory may be expecially important (hIST,
- * tEXt, zTXt, tRNS, pCAL). Others will just save time and make png_info
- * a bit smaller.
- */
-
- #if defined(PNG_READ_SUPPORTED) && \
- !defined(PNG_READ_ANCILLARY_CHUNKS_NOT_SUPPORTED) && \
- !defined(PNG_NO_READ_ANCILLARY_CHUNKS)
- # define PNG_READ_ANCILLARY_CHUNKS_SUPPORTED
- #endif
-
- #if defined(PNG_WRITE_SUPPORTED) && \
- !defined(PNG_WRITE_ANCILLARY_CHUNKS_NOT_SUPPORTED) && \
- !defined(PNG_NO_WRITE_ANCILLARY_CHUNKS)
- # define PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED
- #endif
-
- #ifdef PNG_READ_ANCILLARY_CHUNKS_SUPPORTED
-
- #ifdef PNG_NO_READ_TEXT
- # define PNG_NO_READ_iTXt
- # define PNG_NO_READ_tEXt
- # define PNG_NO_READ_zTXt
- #endif
- #ifndef PNG_NO_READ_bKGD
- # define PNG_READ_bKGD_SUPPORTED
- # define PNG_bKGD_SUPPORTED
- #endif
- #ifndef PNG_NO_READ_cHRM
- # define PNG_READ_cHRM_SUPPORTED
- # define PNG_cHRM_SUPPORTED
- #endif
- #ifndef PNG_NO_READ_gAMA
- # define PNG_READ_gAMA_SUPPORTED
- # define PNG_gAMA_SUPPORTED
- #endif
- #ifndef PNG_NO_READ_hIST
- # define PNG_READ_hIST_SUPPORTED
- # define PNG_hIST_SUPPORTED
- #endif
- #ifndef PNG_NO_READ_iCCP
- # define PNG_READ_iCCP_SUPPORTED
- # define PNG_iCCP_SUPPORTED
- #endif
- #ifndef PNG_NO_READ_iTXt
- # ifndef PNG_READ_iTXt_SUPPORTED
- # define PNG_READ_iTXt_SUPPORTED
- # endif
- # ifndef PNG_iTXt_SUPPORTED
- # define PNG_iTXt_SUPPORTED
- # endif
- #endif
- #ifndef PNG_NO_READ_oFFs
- # define PNG_READ_oFFs_SUPPORTED
- # define PNG_oFFs_SUPPORTED
- #endif
- #ifndef PNG_NO_READ_pCAL
- # define PNG_READ_pCAL_SUPPORTED
- # define PNG_pCAL_SUPPORTED
- #endif
- #ifndef PNG_NO_READ_sCAL
- # define PNG_READ_sCAL_SUPPORTED
- # define PNG_sCAL_SUPPORTED
- #endif
- #ifndef PNG_NO_READ_pHYs
- # define PNG_READ_pHYs_SUPPORTED
- # define PNG_pHYs_SUPPORTED
- #endif
- #ifndef PNG_NO_READ_sBIT
- # define PNG_READ_sBIT_SUPPORTED
- # define PNG_sBIT_SUPPORTED
- #endif
- #ifndef PNG_NO_READ_sPLT
- # define PNG_READ_sPLT_SUPPORTED
- # define PNG_sPLT_SUPPORTED
- #endif
- #ifndef PNG_NO_READ_sRGB
- # define PNG_READ_sRGB_SUPPORTED
- # define PNG_sRGB_SUPPORTED
- #endif
- #ifndef PNG_NO_READ_tEXt
- # define PNG_READ_tEXt_SUPPORTED
- # define PNG_tEXt_SUPPORTED
- #endif
- #ifndef PNG_NO_READ_tIME
- # define PNG_READ_tIME_SUPPORTED
- # define PNG_tIME_SUPPORTED
- #endif
- #ifndef PNG_NO_READ_tRNS
- # define PNG_READ_tRNS_SUPPORTED
- # define PNG_tRNS_SUPPORTED
- #endif
- #ifndef PNG_NO_READ_zTXt
- # define PNG_READ_zTXt_SUPPORTED
- # define PNG_zTXt_SUPPORTED
- #endif
- #ifndef PNG_NO_READ_UNKNOWN_CHUNKS
- # define PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
- # ifndef PNG_UNKNOWN_CHUNKS_SUPPORTED
- # define PNG_UNKNOWN_CHUNKS_SUPPORTED
- # endif
- # ifndef PNG_NO_HANDLE_AS_UNKNOWN
- # define PNG_HANDLE_AS_UNKNOWN_SUPPORTED
- # endif
- #endif
- #if !defined(PNG_NO_READ_USER_CHUNKS) && \
- defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
- # define PNG_READ_USER_CHUNKS_SUPPORTED
- # define PNG_USER_CHUNKS_SUPPORTED
- # ifdef PNG_NO_READ_UNKNOWN_CHUNKS
- # undef PNG_NO_READ_UNKNOWN_CHUNKS
- # endif
- # ifdef PNG_NO_HANDLE_AS_UNKNOWN
- # undef PNG_NO_HANDLE_AS_UNKNOWN
- # endif
- #endif
- #ifndef PNG_NO_READ_OPT_PLTE
- # define PNG_READ_OPT_PLTE_SUPPORTED /* only affects support of the */
- #endif /* optional PLTE chunk in RGB and RGBA images */
- #if defined(PNG_READ_iTXt_SUPPORTED) || defined(PNG_READ_tEXt_SUPPORTED) || \
- defined(PNG_READ_zTXt_SUPPORTED)
- # define PNG_READ_TEXT_SUPPORTED
- # define PNG_TEXT_SUPPORTED
- #endif
-
- #endif /* PNG_READ_ANCILLARY_CHUNKS_SUPPORTED */
-
- #ifdef PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED
-
- #ifdef PNG_NO_WRITE_TEXT
- # define PNG_NO_WRITE_iTXt
- # define PNG_NO_WRITE_tEXt
- # define PNG_NO_WRITE_zTXt
- #endif
- #ifndef PNG_NO_WRITE_bKGD
- # define PNG_WRITE_bKGD_SUPPORTED
- # ifndef PNG_bKGD_SUPPORTED
- # define PNG_bKGD_SUPPORTED
- # endif
- #endif
- #ifndef PNG_NO_WRITE_cHRM
- # define PNG_WRITE_cHRM_SUPPORTED
- # ifndef PNG_cHRM_SUPPORTED
- # define PNG_cHRM_SUPPORTED
- # endif
- #endif
- #ifndef PNG_NO_WRITE_gAMA
- # define PNG_WRITE_gAMA_SUPPORTED
- # ifndef PNG_gAMA_SUPPORTED
- # define PNG_gAMA_SUPPORTED
- # endif
- #endif
- #ifndef PNG_NO_WRITE_hIST
- # define PNG_WRITE_hIST_SUPPORTED
- # ifndef PNG_hIST_SUPPORTED
- # define PNG_hIST_SUPPORTED
- # endif
- #endif
- #ifndef PNG_NO_WRITE_iCCP
- # define PNG_WRITE_iCCP_SUPPORTED
- # ifndef PNG_iCCP_SUPPORTED
- # define PNG_iCCP_SUPPORTED
- # endif
- #endif
- #ifndef PNG_NO_WRITE_iTXt
- # ifndef PNG_WRITE_iTXt_SUPPORTED
- # define PNG_WRITE_iTXt_SUPPORTED
- # endif
- # ifndef PNG_iTXt_SUPPORTED
- # define PNG_iTXt_SUPPORTED
- # endif
- #endif
- #ifndef PNG_NO_WRITE_oFFs
- # define PNG_WRITE_oFFs_SUPPORTED
- # ifndef PNG_oFFs_SUPPORTED
- # define PNG_oFFs_SUPPORTED
- # endif
- #endif
- #ifndef PNG_NO_WRITE_pCAL
- # define PNG_WRITE_pCAL_SUPPORTED
- # ifndef PNG_pCAL_SUPPORTED
- # define PNG_pCAL_SUPPORTED
- # endif
- #endif
- #ifndef PNG_NO_WRITE_sCAL
- # define PNG_WRITE_sCAL_SUPPORTED
- # ifndef PNG_sCAL_SUPPORTED
- # define PNG_sCAL_SUPPORTED
- # endif
- #endif
- #ifndef PNG_NO_WRITE_pHYs
- # define PNG_WRITE_pHYs_SUPPORTED
- # ifndef PNG_pHYs_SUPPORTED
- # define PNG_pHYs_SUPPORTED
- # endif
- #endif
- #ifndef PNG_NO_WRITE_sBIT
- # define PNG_WRITE_sBIT_SUPPORTED
- # ifndef PNG_sBIT_SUPPORTED
- # define PNG_sBIT_SUPPORTED
- # endif
- #endif
- #ifndef PNG_NO_WRITE_sPLT
- # define PNG_WRITE_sPLT_SUPPORTED
- # ifndef PNG_sPLT_SUPPORTED
- # define PNG_sPLT_SUPPORTED
- # endif
- #endif
- #ifndef PNG_NO_WRITE_sRGB
- # define PNG_WRITE_sRGB_SUPPORTED
- # ifndef PNG_sRGB_SUPPORTED
- # define PNG_sRGB_SUPPORTED
- # endif
- #endif
- #ifndef PNG_NO_WRITE_tEXt
- # define PNG_WRITE_tEXt_SUPPORTED
- # ifndef PNG_tEXt_SUPPORTED
- # define PNG_tEXt_SUPPORTED
- # endif
- #endif
- #ifndef PNG_NO_WRITE_tIME
- # define PNG_WRITE_tIME_SUPPORTED
- # ifndef PNG_tIME_SUPPORTED
- # define PNG_tIME_SUPPORTED
- # endif
- #endif
- #ifndef PNG_NO_WRITE_tRNS
- # define PNG_WRITE_tRNS_SUPPORTED
- # ifndef PNG_tRNS_SUPPORTED
- # define PNG_tRNS_SUPPORTED
- # endif
- #endif
- #ifndef PNG_NO_WRITE_zTXt
- # define PNG_WRITE_zTXt_SUPPORTED
- # ifndef PNG_zTXt_SUPPORTED
- # define PNG_zTXt_SUPPORTED
- # endif
- #endif
- #ifndef PNG_NO_WRITE_UNKNOWN_CHUNKS
- # define PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
- # ifndef PNG_UNKNOWN_CHUNKS_SUPPORTED
- # define PNG_UNKNOWN_CHUNKS_SUPPORTED
- # endif
- # ifndef PNG_NO_HANDLE_AS_UNKNOWN
- # ifndef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
- # define PNG_HANDLE_AS_UNKNOWN_SUPPORTED
- # endif
- # endif
- #endif
- #if defined(PNG_WRITE_iTXt_SUPPORTED) || defined(PNG_WRITE_tEXt_SUPPORTED) || \
- defined(PNG_WRITE_zTXt_SUPPORTED)
- # define PNG_WRITE_TEXT_SUPPORTED
- # ifndef PNG_TEXT_SUPPORTED
- # define PNG_TEXT_SUPPORTED
- # endif
- #endif
-
- #endif /* PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED */
-
- /* Turn this off to disable png_read_png() and
- * png_write_png() and leave the row_pointers member
- * out of the info structure.
- */
- #ifndef PNG_NO_INFO_IMAGE
- # define PNG_INFO_IMAGE_SUPPORTED
- #endif
-
- /* need the time information for reading tIME chunks */
- #if defined(PNG_tIME_SUPPORTED)
- # if !defined(_WIN32_WCE)
- /* "time.h" functions are not supported on WindowsCE */
- # include <time.h>
- # endif
- #endif
-
- /* Some typedefs to get us started. These should be safe on most of the
- * common platforms. The typedefs should be at least as large as the
- * numbers suggest (a png_uint_32 must be at least 32 bits long), but they
- * don't have to be exactly that size. Some compilers dislike passing
- * unsigned shorts as function parameters, so you may be better off using
- * unsigned int for png_uint_16. Likewise, for 64-bit systems, you may
- * want to have unsigned int for png_uint_32 instead of unsigned long.
- */
-
- typedef unsigned long png_uint_32;
- typedef long png_int_32;
- typedef unsigned short png_uint_16;
- typedef short png_int_16;
- typedef unsigned char png_byte;
-
- /* This is usually size_t. It is typedef'ed just in case you need it to
- change (I'm not sure if you will or not, so I thought I'd be safe) */
- #ifdef PNG_SIZE_T
- typedef PNG_SIZE_T png_size_t;
- # define png_sizeof(x) png_convert_size(sizeof (x))
- #else
- typedef size_t png_size_t;
- # define png_sizeof(x) sizeof (x)
- #endif
-
- /* The following is needed for medium model support. It cannot be in the
- * PNG_INTERNAL section. Needs modification for other compilers besides
- * MSC. Model independent support declares all arrays and pointers to be
- * large using the far keyword. The zlib version used must also support
- * model independent data. As of version zlib 1.0.4, the necessary changes
- * have been made in zlib. The USE_FAR_KEYWORD define triggers other
- * changes that are needed. (Tim Wegner)
- */
-
- /* Separate compiler dependencies (problem here is that zlib.h always
- defines FAR. (SJT) */
- #ifdef __BORLANDC__
- # if defined(__LARGE__) || defined(__HUGE__) || defined(__COMPACT__)
- # define LDATA 1
- # else
- # define LDATA 0
- # endif
- /* GRR: why is Cygwin in here? Cygwin is not Borland C... */
- # if !defined(__WIN32__) && !defined(__FLAT__) && !defined(__CYGWIN__)
- # define PNG_MAX_MALLOC_64K
- # if (LDATA != 1)
- # ifndef FAR
- # define FAR __far
- # endif
- # define USE_FAR_KEYWORD
- # endif /* LDATA != 1 */
- /* Possibly useful for moving data out of default segment.
- * Uncomment it if you want. Could also define FARDATA as
- * const if your compiler supports it. (SJT)
- # define FARDATA FAR
- */
- # endif /* __WIN32__, __FLAT__, __CYGWIN__ */
- #endif /* __BORLANDC__ */
-
- /* Suggest testing for specific compiler first before testing for
- * FAR. The Watcom compiler defines both __MEDIUM__ and M_I86MM,
- * making reliance oncertain keywords suspect. (SJT)
- */
-
- /* MSC Medium model */
- #if defined(FAR)
- # if defined(M_I86MM)
- # define USE_FAR_KEYWORD
- # define FARDATA FAR
- # include <dos.h>
- # endif
- #endif
-
- /* SJT: default case */
- #ifndef FAR
- # define FAR
- #endif
-
- /* At this point FAR is always defined */
- #ifndef FARDATA
- # define FARDATA
- #endif
-
- /* Typedef for floating-point numbers that are converted
- to fixed-point with a multiple of 100,000, e.g., int_gamma */
- typedef png_int_32 png_fixed_point;
-
- /* Add typedefs for pointers */
- typedef void FAR * png_voidp;
- typedef png_byte FAR * png_bytep;
- typedef png_uint_32 FAR * png_uint_32p;
- typedef png_int_32 FAR * png_int_32p;
- typedef png_uint_16 FAR * png_uint_16p;
- typedef png_int_16 FAR * png_int_16p;
- typedef PNG_CONST char FAR * png_const_charp;
- typedef char FAR * png_charp;
- typedef png_fixed_point FAR * png_fixed_point_p;
-
- #ifndef PNG_NO_STDIO
- #if defined(_WIN32_WCE)
- typedef HANDLE png_FILE_p;
- #else
- typedef FILE * png_FILE_p;
- #endif
- #endif
-
- #ifdef PNG_FLOATING_POINT_SUPPORTED
- typedef double FAR * png_doublep;
- #endif
-
- /* Pointers to pointers; i.e. arrays */
- typedef png_byte FAR * FAR * png_bytepp;
- typedef png_uint_32 FAR * FAR * png_uint_32pp;
- typedef png_int_32 FAR * FAR * png_int_32pp;
- typedef png_uint_16 FAR * FAR * png_uint_16pp;
- typedef png_int_16 FAR * FAR * png_int_16pp;
- typedef PNG_CONST char FAR * FAR * png_const_charpp;
- typedef char FAR * FAR * png_charpp;
- typedef png_fixed_point FAR * FAR * png_fixed_point_pp;
- #ifdef PNG_FLOATING_POINT_SUPPORTED
- typedef double FAR * FAR * png_doublepp;
- #endif
-
- /* Pointers to pointers to pointers; i.e., pointer to array */
- typedef char FAR * FAR * FAR * png_charppp;
-
- #if 0
- /* SPC - Is this stuff deprecated? */
- /* It'll be removed as of libpng-1.3.0 - GR-P */
- /* libpng typedefs for types in zlib. If zlib changes
- * or another compression library is used, then change these.
- * Eliminates need to change all the source files.
- */
- typedef charf * png_zcharp;
- typedef charf * FAR * png_zcharpp;
- typedef z_stream FAR * png_zstreamp;
- #endif /* (PNG_1_0_X) || defined(PNG_1_2_X) */
-
- /*
- * Define PNG_BUILD_DLL if the module being built is a Windows
- * LIBPNG DLL.
- *
- * Define PNG_USE_DLL if you want to *link* to the Windows LIBPNG DLL.
- * It is equivalent to Microsoft predefined macro _DLL that is
- * automatically defined when you compile using the share
- * version of the CRT (C Run-Time library)
- *
- * The cygwin mods make this behavior a little different:
- * Define PNG_BUILD_DLL if you are building a dll for use with cygwin
- * Define PNG_STATIC if you are building a static library for use with cygwin,
- * -or- if you are building an application that you want to link to the
- * static library.
- * PNG_USE_DLL is defined by default (no user action needed) unless one of
- * the other flags is defined.
- */
-
- #if !defined(PNG_DLL) && (defined(PNG_BUILD_DLL) || defined(PNG_USE_DLL))
- # define PNG_DLL
- #endif
- /* If CYGWIN, then disallow GLOBAL ARRAYS unless building a static lib.
- * When building a static lib, default to no GLOBAL ARRAYS, but allow
- * command-line override
- */
- #if defined(__CYGWIN__)
- # if !defined(PNG_STATIC)
- # if defined(PNG_USE_GLOBAL_ARRAYS)
- # undef PNG_USE_GLOBAL_ARRAYS
- # endif
- # if !defined(PNG_USE_LOCAL_ARRAYS)
- # define PNG_USE_LOCAL_ARRAYS
- # endif
- # else
- # if defined(PNG_USE_LOCAL_ARRAYS) || defined(PNG_NO_GLOBAL_ARRAYS)
- # if defined(PNG_USE_GLOBAL_ARRAYS)
- # undef PNG_USE_GLOBAL_ARRAYS
- # endif
- # endif
- # endif
- # if !defined(PNG_USE_LOCAL_ARRAYS) && !defined(PNG_USE_GLOBAL_ARRAYS)
- # define PNG_USE_LOCAL_ARRAYS
- # endif
- #endif
-
- /* Do not use global arrays (helps with building DLL's)
- * They are no longer used in libpng itself, since version 1.0.5c,
- * but might be required for some pre-1.0.5c applications.
- */
- #if !defined(PNG_USE_LOCAL_ARRAYS) && !defined(PNG_USE_GLOBAL_ARRAYS)
- # if defined(PNG_NO_GLOBAL_ARRAYS) || \
- (defined(__GNUC__) && defined(PNG_DLL)) || defined(_MSC_VER)
- # define PNG_USE_LOCAL_ARRAYS
- # else
- # define PNG_USE_GLOBAL_ARRAYS
- # endif
- #endif
-
- #if defined(__CYGWIN__)
- # undef PNGAPI
- # define PNGAPI __cdecl
- # undef PNG_IMPEXP
- # define PNG_IMPEXP
- #endif
-
- /* If you define PNGAPI, e.g., with compiler option "-DPNGAPI=__stdcall",
- * you may get warnings regarding the linkage of png_zalloc and png_zfree.
- * Don't ignore those warnings; you must also reset the default calling
- * convention in your compiler to match your PNGAPI, and you must build
- * zlib and your applications the same way you build libpng.
- */
-
- #if defined(__MINGW32__) && !defined(PNG_MODULEDEF)
- # ifndef PNG_NO_MODULEDEF
- # define PNG_NO_MODULEDEF
- # endif
- #endif
-
- #if !defined(PNG_IMPEXP) && defined(PNG_BUILD_DLL) && !defined(PNG_NO_MODULEDEF)
- # define PNG_IMPEXP
- #endif
-
- #if defined(PNG_DLL) || defined(_DLL) || defined(__DLL__ ) || \
- (( defined(_Windows) || defined(_WINDOWS) || \
- defined(WIN32) || defined(_WIN32) || defined(__WIN32__) ))
-
- # ifndef PNGAPI
- # if defined(__GNUC__) || (defined (_MSC_VER) && (_MSC_VER >= 800))
- # define PNGAPI __cdecl
- # else
- # define PNGAPI _cdecl
- # endif
- # endif
-
- # if !defined(PNG_IMPEXP) && (!defined(PNG_DLL) || \
- 0 /* WINCOMPILER_WITH_NO_SUPPORT_FOR_DECLIMPEXP */)
- # define PNG_IMPEXP
- # endif
-
- # if !defined(PNG_IMPEXP)
-
- # define PNG_EXPORT_TYPE1(type,symbol) PNG_IMPEXP type PNGAPI symbol
- # define PNG_EXPORT_TYPE2(type,symbol) type PNG_IMPEXP PNGAPI symbol
-
- /* Borland/Microsoft */
- # if defined(_MSC_VER) || defined(__BORLANDC__)
- # if (_MSC_VER >= 800) || (__BORLANDC__ >= 0x500)
- # define PNG_EXPORT PNG_EXPORT_TYPE1
- # else
- # define PNG_EXPORT PNG_EXPORT_TYPE2
- # if defined(PNG_BUILD_DLL)
- # define PNG_IMPEXP __export
- # else
- # define PNG_IMPEXP /*__import */ /* doesn't exist AFAIK in
- VC++ */
- # endif /* Exists in Borland C++ for
- C++ classes (== huge) */
- # endif
- # endif
-
- # if !defined(PNG_IMPEXP)
- # if defined(PNG_BUILD_DLL)
- # define PNG_IMPEXP __declspec(dllexport)
- # else
- # define PNG_IMPEXP __declspec(dllimport)
- # endif
- # endif
- # endif /* PNG_IMPEXP */
- #else /* !(DLL || non-cygwin WINDOWS) */
- # if (defined(__IBMC__) || defined(__IBMCPP__)) && defined(__OS2__)
- # ifndef PNGAPI
- # define PNGAPI _System
- # endif
- # else
- # if 0 /* ... other platforms, with other meanings */
- # endif
- # endif
- #endif
-
- #ifndef PNGAPI
- # define PNGAPI
- #endif
- #ifndef PNG_IMPEXP
- # define PNG_IMPEXP
- #endif
-
- #ifdef PNG_BUILDSYMS
- # ifndef PNG_EXPORT
- # define PNG_EXPORT(type,symbol) PNG_FUNCTION_EXPORT symbol END
- # endif
- # ifdef PNG_USE_GLOBAL_ARRAYS
- # ifndef PNG_EXPORT_VAR
- # define PNG_EXPORT_VAR(type) PNG_DATA_EXPORT
- # endif
- # endif
- #endif
-
- #ifndef PNG_EXPORT
- # define PNG_EXPORT(type,symbol) PNG_IMPEXP type PNGAPI symbol
- #endif
-
- #ifdef PNG_USE_GLOBAL_ARRAYS
- # ifndef PNG_EXPORT_VAR
- # define PNG_EXPORT_VAR(type) extern PNG_IMPEXP type
- # endif
- #endif
-
- /* User may want to use these so they are not in PNG_INTERNAL. Any library
- * functions that are passed far data must be model independent.
- */
-
- #ifndef PNG_ABORT
- # define PNG_ABORT() abort()
- #endif
-
- #ifdef PNG_SETJMP_SUPPORTED
- # define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf)
- #else
- # define png_jmpbuf(png_ptr) \
- (LIBPNG_WAS_COMPILED_WITH__PNG_SETJMP_NOT_SUPPORTED)
- #endif
-
- #if defined(USE_FAR_KEYWORD) /* memory model independent fns */
- /* use this to make far-to-near assignments */
- # define CHECK 1
- # define NOCHECK 0
- # define CVT_PTR(ptr) (png_far_to_near(png_ptr,ptr,CHECK))
- # define CVT_PTR_NOCHECK(ptr) (png_far_to_near(png_ptr,ptr,NOCHECK))
- # define png_snprintf _fsnprintf /* Added to v 1.2.19 */
- # define png_strcpy _fstrcpy
- # define png_strncpy _fstrncpy /* Added to v 1.2.6 */
- # define png_strlen _fstrlen
- # define png_memcmp _fmemcmp /* SJT: added */
- # define png_memcpy _fmemcpy
- # define png_memset _fmemset
- #else /* use the usual functions */
- # define CVT_PTR(ptr) (ptr)
- # define CVT_PTR_NOCHECK(ptr) (ptr)
- # ifndef PNG_NO_SNPRINTF
- # ifdef _MSC_VER
- # define png_snprintf _snprintf /* Added to v 1.2.19 */
- # define png_snprintf2 _snprintf
- # define png_snprintf6 _snprintf
- # else
- # define png_snprintf snprintf /* Added to v 1.2.19 */
- # define png_snprintf2 snprintf
- # define png_snprintf6 snprintf
- # endif
- # else
- /* You don't have or don't want to use snprintf(). Caution: Using
- * sprintf instead of snprintf exposes your application to accidental
- * or malevolent buffer overflows. If you don't have snprintf()
- * as a general rule you should provide one (you can get one from
- * Portable OpenSSH). */
- # define png_snprintf(s1,n,fmt,x1) sprintf(s1,fmt,x1)
- # define png_snprintf2(s1,n,fmt,x1,x2) sprintf(s1,fmt,x1,x2)
- # define png_snprintf6(s1,n,fmt,x1,x2,x3,x4,x5,x6) \
- sprintf(s1,fmt,x1,x2,x3,x4,x5,x6)
- # endif
- # define png_strcpy strcpy
- # define png_strncpy strncpy /* Added to v 1.2.6 */
- # define png_strlen strlen
- # define png_memcmp memcmp /* SJT: added */
- # define png_memcpy memcpy
- # define png_memset memset
- #endif
- /* End of memory model independent support */
-
- /* Just a little check that someone hasn't tried to define something
- * contradictory.
- */
- #if (PNG_ZBUF_SIZE > 65536L) && defined(PNG_MAX_MALLOC_64K)
- # undef PNG_ZBUF_SIZE
- # define PNG_ZBUF_SIZE 65536L
- #endif
-
- /* Added at libpng-1.2.8 */
- #endif /* PNG_VERSION_INFO_ONLY */
-
- #endif /* PNGCONF_H */
- /********* End of inlined file: pngconf.h *********/
-
- #ifdef _MSC_VER
- #pragma warning (disable: 4996 4100)
- #endif
-
- /*
- * Added at libpng-1.2.8 */
- /* Ref MSDN: Private as priority over Special
- * VS_FF_PRIVATEBUILD File *was not* built using standard release
- * procedures. If this value is given, the StringFileInfo block must
- * contain a PrivateBuild string.
- *
- * VS_FF_SPECIALBUILD File *was* built by the original company using
- * standard release procedures but is a variation of the standard
- * file of the same version number. If this value is given, the
- * StringFileInfo block must contain a SpecialBuild string.
- */
-
- #if defined(PNG_USER_PRIVATEBUILD)
- # define PNG_LIBPNG_BUILD_TYPE \
- (PNG_LIBPNG_BUILD_BASE_TYPE | PNG_LIBPNG_BUILD_PRIVATE)
- #else
- # if defined(PNG_LIBPNG_SPECIALBUILD)
- # define PNG_LIBPNG_BUILD_TYPE \
- (PNG_LIBPNG_BUILD_BASE_TYPE | PNG_LIBPNG_BUILD_SPECIAL)
- # else
- # define PNG_LIBPNG_BUILD_TYPE (PNG_LIBPNG_BUILD_BASE_TYPE)
- # endif
- #endif
-
- #ifndef PNG_VERSION_INFO_ONLY
-
- /* Inhibit C++ name-mangling for libpng functions but not for system calls. */
- #ifdef __cplusplus
- extern "C" {
- #endif /* __cplusplus */
-
- /* This file is arranged in several sections. The first section contains
- * structure and type definitions. The second section contains the external
- * library functions, while the third has the internal library functions,
- * which applications aren't expected to use directly.
- */
-
- #ifndef PNG_NO_TYPECAST_NULL
- #define int_p_NULL (int *)NULL
- #define png_bytep_NULL (png_bytep)NULL
- #define png_bytepp_NULL (png_bytepp)NULL
- #define png_doublep_NULL (png_doublep)NULL
- #define png_error_ptr_NULL (png_error_ptr)NULL
- #define png_flush_ptr_NULL (png_flush_ptr)NULL
- #define png_free_ptr_NULL (png_free_ptr)NULL
- #define png_infopp_NULL (png_infopp)NULL
- #define png_malloc_ptr_NULL (png_malloc_ptr)NULL
- #define png_read_status_ptr_NULL (png_read_status_ptr)NULL
- #define png_rw_ptr_NULL (png_rw_ptr)NULL
- #define png_structp_NULL (png_structp)NULL
- #define png_uint_16p_NULL (png_uint_16p)NULL
- #define png_voidp_NULL (png_voidp)NULL
- #define png_write_status_ptr_NULL (png_write_status_ptr)NULL
- #else
- #define int_p_NULL NULL
- #define png_bytep_NULL NULL
- #define png_bytepp_NULL NULL
- #define png_doublep_NULL NULL
- #define png_error_ptr_NULL NULL
- #define png_flush_ptr_NULL NULL
- #define png_free_ptr_NULL NULL
- #define png_infopp_NULL NULL
- #define png_malloc_ptr_NULL NULL
- #define png_read_status_ptr_NULL NULL
- #define png_rw_ptr_NULL NULL
- #define png_structp_NULL NULL
- #define png_uint_16p_NULL NULL
- #define png_voidp_NULL NULL
- #define png_write_status_ptr_NULL NULL
- #endif
-
- /* variables declared in png.c - only it needs to define PNG_NO_EXTERN */
- #if !defined(PNG_NO_EXTERN) || defined(PNG_ALWAYS_EXTERN)
- /* Version information for C files, stored in png.c. This had better match
- * the version above.
- */
- #ifdef PNG_USE_GLOBAL_ARRAYS
- PNG_EXPORT_VAR (PNG_CONST char) png_libpng_ver[18];
- /* need room for 99.99.99beta99z */
- #else
- #define png_libpng_ver png_get_header_ver(NULL)
- #endif
-
- #ifdef PNG_USE_GLOBAL_ARRAYS
- /* This was removed in version 1.0.5c */
- /* Structures to facilitate easy interlacing. See png.c for more details */
- PNG_EXPORT_VAR (PNG_CONST int FARDATA) png_pass_start[7];
- PNG_EXPORT_VAR (PNG_CONST int FARDATA) png_pass_inc[7];
- PNG_EXPORT_VAR (PNG_CONST int FARDATA) png_pass_ystart[7];
- PNG_EXPORT_VAR (PNG_CONST int FARDATA) png_pass_yinc[7];
- PNG_EXPORT_VAR (PNG_CONST int FARDATA) png_pass_mask[7];
- PNG_EXPORT_VAR (PNG_CONST int FARDATA) png_pass_dsp_mask[7];
- /* This isn't currently used. If you need it, see png.c for more details.
- PNG_EXPORT_VAR (PNG_CONST int FARDATA) png_pass_height[7];
- */
- #endif
-
- #endif /* PNG_NO_EXTERN */
-
- /* Three color definitions. The order of the red, green, and blue, (and the
- * exact size) is not important, although the size of the fields need to
- * be png_byte or png_uint_16 (as defined below).
- */
- typedef struct png_color_struct
- {
- png_byte red;
- png_byte green;
- png_byte blue;
- } png_color;
- typedef png_color FAR * png_colorp;
- typedef png_color FAR * FAR * png_colorpp;
-
- typedef struct png_color_16_struct
- {
- png_byte index; /* used for palette files */
- png_uint_16 red; /* for use in red green blue files */
- png_uint_16 green;
- png_uint_16 blue;
- png_uint_16 gray; /* for use in grayscale files */
- } png_color_16;
- typedef png_color_16 FAR * png_color_16p;
- typedef png_color_16 FAR * FAR * png_color_16pp;
-
- typedef struct png_color_8_struct
- {
- png_byte red; /* for use in red green blue files */
- png_byte green;
- png_byte blue;
- png_byte gray; /* for use in grayscale files */
- png_byte alpha; /* for alpha channel files */
- } png_color_8;
- typedef png_color_8 FAR * png_color_8p;
- typedef png_color_8 FAR * FAR * png_color_8pp;
-
- /*
- * The following two structures are used for the in-core representation
- * of sPLT chunks.
- */
- typedef struct png_sPLT_entry_struct
- {
- png_uint_16 red;
- png_uint_16 green;
- png_uint_16 blue;
- png_uint_16 alpha;
- png_uint_16 frequency;
- } png_sPLT_entry;
- typedef png_sPLT_entry FAR * png_sPLT_entryp;
- typedef png_sPLT_entry FAR * FAR * png_sPLT_entrypp;
-
- /* When the depth of the sPLT palette is 8 bits, the color and alpha samples
- * occupy the LSB of their respective members, and the MSB of each member
- * is zero-filled. The frequency member always occupies the full 16 bits.
- */
-
- typedef struct png_sPLT_struct
- {
- png_charp name; /* palette name */
- png_byte depth; /* depth of palette samples */
- png_sPLT_entryp entries; /* palette entries */
- png_int_32 nentries; /* number of palette entries */
- } png_sPLT_t;
- typedef png_sPLT_t FAR * png_sPLT_tp;
- typedef png_sPLT_t FAR * FAR * png_sPLT_tpp;
-
- #ifdef PNG_TEXT_SUPPORTED
- /* png_text holds the contents of a text/ztxt/itxt chunk in a PNG file,
- * and whether that contents is compressed or not. The "key" field
- * points to a regular zero-terminated C string. The "text", "lang", and
- * "lang_key" fields can be regular C strings, empty strings, or NULL pointers.
- * However, the * structure returned by png_get_text() will always contain
- * regular zero-terminated C strings (possibly empty), never NULL pointers,
- * so they can be safely used in printf() and other string-handling functions.
- */
- typedef struct png_text_struct
- {
- int compression; /* compression value:
- -1: tEXt, none
- 0: zTXt, deflate
- 1: iTXt, none
- 2: iTXt, deflate */
- png_charp key; /* keyword, 1-79 character description of "text" */
- png_charp text; /* comment, may be an empty string (ie "")
- or a NULL pointer */
- png_size_t text_length; /* length of the text string */
- #ifdef PNG_iTXt_SUPPORTED
- png_size_t itxt_length; /* length of the itxt string */
- png_charp lang; /* language code, 0-79 characters
- or a NULL pointer */
- png_charp lang_key; /* keyword translated UTF-8 string, 0 or more
- chars or a NULL pointer */
- #endif
- } png_text;
- typedef png_text FAR * png_textp;
- typedef png_text FAR * FAR * png_textpp;
- #endif
-
- /* Supported compression types for text in PNG files (tEXt, and zTXt).
- * The values of the PNG_TEXT_COMPRESSION_ defines should NOT be changed. */
- #define PNG_TEXT_COMPRESSION_NONE_WR -3
- #define PNG_TEXT_COMPRESSION_zTXt_WR -2
- #define PNG_TEXT_COMPRESSION_NONE -1
- #define PNG_TEXT_COMPRESSION_zTXt 0
- #define PNG_ITXT_COMPRESSION_NONE 1
- #define PNG_ITXT_COMPRESSION_zTXt 2
- #define PNG_TEXT_COMPRESSION_LAST 3 /* Not a valid value */
-
- /* png_time is a way to hold the time in an machine independent way.
- * Two conversions are provided, both from time_t and struct tm. There
- * is no portable way to convert to either of these structures, as far
- * as I know. If you know of a portable way, send it to me. As a side
- * note - PNG has always been Year 2000 compliant!
- */
- typedef struct png_time_struct
- {
- png_uint_16 year; /* full year, as in, 1995 */
- png_byte month; /* month of year, 1 - 12 */
- png_byte day; /* day of month, 1 - 31 */
- png_byte hour; /* hour of day, 0 - 23 */
- png_byte minute; /* minute of hour, 0 - 59 */
- png_byte second; /* second of minute, 0 - 60 (for leap seconds) */
- } png_time;
- typedef png_time FAR * png_timep;
- typedef png_time FAR * FAR * png_timepp;
-
- #if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
- /* png_unknown_chunk is a structure to hold queued chunks for which there is
- * no specific support. The idea is that we can use this to queue
- * up private chunks for output even though the library doesn't actually
- * know about their semantics.
- */
- typedef struct png_unknown_chunk_t
- {
- png_byte name[5];
- png_byte *data;
- png_size_t size;
-
- /* libpng-using applications should NOT directly modify this byte. */
- png_byte location; /* mode of operation at read time */
- }
- png_unknown_chunk;
- typedef png_unknown_chunk FAR * png_unknown_chunkp;
- typedef png_unknown_chunk FAR * FAR * png_unknown_chunkpp;
- #endif
-
- /* png_info is a structure that holds the information in a PNG file so
- * that the application can find out the characteristics of the image.
- * If you are reading the file, this structure will tell you what is
- * in the PNG file. If you are writing the file, fill in the information
- * you want to put into the PNG file, then call png_write_info().
- * The names chosen should be very close to the PNG specification, so
- * consult that document for information about the meaning of each field.
- *
- * With libpng < 0.95, it was only possible to directly set and read the
- * the values in the png_info_struct, which meant that the contents and
- * order of the values had to remain fixed. With libpng 0.95 and later,
- * however, there are now functions that abstract the contents of
- * png_info_struct from the application, so this makes it easier to use
- * libpng with dynamic libraries, and even makes it possible to use
- * libraries that don't have all of the libpng ancillary chunk-handing
- * functionality.
- *
- * In any case, the order of the parameters in png_info_struct should NOT
- * be changed for as long as possible to keep compatibility with applications
- * that use the old direct-access method with png_info_struct.
- *
- * The following members may have allocated storage attached that should be
- * cleaned up before the structure is discarded: palette, trans, text,
- * pcal_purpose, pcal_units, pcal_params, hist, iccp_name, iccp_profile,
- * splt_palettes, scal_unit, row_pointers, and unknowns. By default, these
- * are automatically freed when the info structure is deallocated, if they were
- * allocated internally by libpng. This behavior can be changed by means
- * of the png_data_freer() function.
- *
- * More allocation details: all the chunk-reading functions that
- * change these members go through the corresponding png_set_*
- * functions. A function to clear these members is available: see
- * png_free_data(). The png_set_* functions do not depend on being
- * able to point info structure members to any of the storage they are
- * passed (they make their own copies), EXCEPT that the png_set_text
- * functions use the same storage passed to them in the text_ptr or
- * itxt_ptr structure argument, and the png_set_rows and png_set_unknowns
- * functions do not make their own copies.
- */
- typedef struct png_info_struct
- {
- /* the following are necessary for every PNG file */
- png_uint_32 width; /* width of image in pixels (from IHDR) */
- png_uint_32 height; /* height of image in pixels (from IHDR) */
- png_uint_32 valid; /* valid chunk data (see PNG_INFO_ below) */
- png_uint_32 rowbytes; /* bytes needed to hold an untransformed row */
- png_colorp palette; /* array of color values (valid & PNG_INFO_PLTE) */
- png_uint_16 num_palette; /* number of color entries in "palette" (PLTE) */
- png_uint_16 num_trans; /* number of transparent palette color (tRNS) */
- png_byte bit_depth; /* 1, 2, 4, 8, or 16 bits/channel (from IHDR) */
- png_byte color_type; /* see PNG_COLOR_TYPE_ below (from IHDR) */
- /* The following three should have been named *_method not *_type */
- png_byte compression_type; /* must be PNG_COMPRESSION_TYPE_BASE (IHDR) */
- png_byte filter_type; /* must be PNG_FILTER_TYPE_BASE (from IHDR) */
- png_byte interlace_type; /* One of PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */
-
- /* The following is informational only on read, and not used on writes. */
- png_byte channels; /* number of data channels per pixel (1, 2, 3, 4) */
- png_byte pixel_depth; /* number of bits per pixel */
- png_byte spare_byte; /* to align the data, and for future use */
- png_byte signature[8]; /* magic bytes read by libpng from start of file */
-
- /* The rest of the data is optional. If you are reading, check the
- * valid field to see if the information in these are valid. If you
- * are writing, set the valid field to those chunks you want written,
- * and initialize the appropriate fields below.
- */
-
- #if defined(PNG_gAMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
- /* The gAMA chunk describes the gamma characteristics of the system
- * on which the image was created, normally in the range [1.0, 2.5].
- * Data is valid if (valid & PNG_INFO_gAMA) is non-zero.
- */
- float gamma; /* gamma value of image, if (valid & PNG_INFO_gAMA) */
- #endif
-
- #if defined(PNG_sRGB_SUPPORTED)
- /* GR-P, 0.96a */
- /* Data valid if (valid & PNG_INFO_sRGB) non-zero. */
- png_byte srgb_intent; /* sRGB rendering intent [0, 1, 2, or 3] */
- #endif
-
- #if defined(PNG_TEXT_SUPPORTED)
- /* The tEXt, and zTXt chunks contain human-readable textual data in
- * uncompressed, compressed, and optionally compressed forms, respectively.
- * The data in "text" is an array of pointers to uncompressed,
- * null-terminated C strings. Each chunk has a keyword that describes the
- * textual data contained in that chunk. Keywords are not required to be
- * unique, and the text string may be empty. Any number of text chunks may
- * be in an image.
- */
- int num_text; /* number of comments read/to write */
- int max_text; /* current size of text array */
- png_textp text; /* array of comments read/to write */
- #endif /* PNG_TEXT_SUPPORTED */
-
- #if defined(PNG_tIME_SUPPORTED)
- /* The tIME chunk holds the last time the displayed image data was
- * modified. See the png_time struct for the contents of this struct.
- */
- png_time mod_time;
- #endif
-
- #if defined(PNG_sBIT_SUPPORTED)
- /* The sBIT chunk specifies the number of significant high-order bits
- * in the pixel data. Values are in the range [1, bit_depth], and are
- * only specified for the channels in the pixel data. The contents of
- * the low-order bits is not specified. Data is valid if
- * (valid & PNG_INFO_sBIT) is non-zero.
- */
- png_color_8 sig_bit; /* significant bits in color channels */
- #endif
-
- #if defined(PNG_tRNS_SUPPORTED) || defined(PNG_READ_EXPAND_SUPPORTED) || \
- defined(PNG_READ_BACKGROUND_SUPPORTED)
- /* The tRNS chunk supplies transparency data for paletted images and
- * other image types that don't need a full alpha channel. There are
- * "num_trans" transparency values for a paletted image, stored in the
- * same order as the palette colors, starting from index 0. Values
- * for the data are in the range [0, 255], ranging from fully transparent
- * to fully opaque, respectively. For non-paletted images, there is a
- * single color specified that should be treated as fully transparent.
- * Data is valid if (valid & PNG_INFO_tRNS) is non-zero.
- */
- png_bytep trans; /* transparent values for paletted image */
- png_color_16 trans_values; /* transparent color for non-palette image */
- #endif
-
- #if defined(PNG_bKGD_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
- /* The bKGD chunk gives the suggested image background color if the
- * display program does not have its own background color and the image
- * is needs to composited onto a background before display. The colors
- * in "background" are normally in the same color space/depth as the
- * pixel data. Data is valid if (valid & PNG_INFO_bKGD) is non-zero.
- */
- png_color_16 background;
- #endif
-
- #if defined(PNG_oFFs_SUPPORTED)
- /* The oFFs chunk gives the offset in "offset_unit_type" units rightwards
- * and downwards from the top-left corner of the display, page, or other
- * application-specific co-ordinate space. See the PNG_OFFSET_ defines
- * below for the unit types. Valid if (valid & PNG_INFO_oFFs) non-zero.
- */
- png_int_32 x_offset; /* x offset on page */
- png_int_32 y_offset; /* y offset on page */
- png_byte offset_unit_type; /* offset units type */
- #endif
-
- #if defined(PNG_pHYs_SUPPORTED)
- /* The pHYs chunk gives the physical pixel density of the image for
- * display or printing in "phys_unit_type" units (see PNG_RESOLUTION_
- * defines below). Data is valid if (valid & PNG_INFO_pHYs) is non-zero.
- */
- png_uint_32 x_pixels_per_unit; /* horizontal pixel density */
- png_uint_32 y_pixels_per_unit; /* vertical pixel density */
- png_byte phys_unit_type; /* resolution type (see PNG_RESOLUTION_ below) */
- #endif
-
- #if defined(PNG_hIST_SUPPORTED)
- /* The hIST chunk contains the relative frequency or importance of the
- * various palette entries, so that a viewer can intelligently select a
- * reduced-color palette, if required. Data is an array of "num_palette"
- * values in the range [0,65535]. Data valid if (valid & PNG_INFO_hIST)
- * is non-zero.
- */
- png_uint_16p hist;
- #endif
-
- #ifdef PNG_cHRM_SUPPORTED
- /* The cHRM chunk describes the CIE color characteristics of the monitor
- * on which the PNG was created. This data allows the viewer to do gamut
- * mapping of the input image to ensure that the viewer sees the same
- * colors in the image as the creator. Values are in the range
- * [0.0, 0.8]. Data valid if (valid & PNG_INFO_cHRM) non-zero.
- */
- #ifdef PNG_FLOATING_POINT_SUPPORTED
- float x_white;
- float y_white;
- float x_red;
- float y_red;
- float x_green;
- float y_green;
- float x_blue;
- float y_blue;
- #endif
- #endif
-
- #if defined(PNG_pCAL_SUPPORTED)
- /* The pCAL chunk describes a transformation between the stored pixel
- * values and original physical data values used to create the image.
- * The integer range [0, 2^bit_depth - 1] maps to the floating-point
- * range given by [pcal_X0, pcal_X1], and are further transformed by a
- * (possibly non-linear) transformation function given by "pcal_type"
- * and "pcal_params" into "pcal_units". Please see the PNG_EQUATION_
- * defines below, and the PNG-Group's PNG extensions document for a
- * complete description of the transformations and how they should be
- * implemented, and for a description of the ASCII parameter strings.
- * Data values are valid if (valid & PNG_INFO_pCAL) non-zero.
- */
- png_charp pcal_purpose; /* pCAL chunk description string */
- png_int_32 pcal_X0; /* minimum value */
- png_int_32 pcal_X1; /* maximum value */
- png_charp pcal_units; /* Latin-1 string giving physical units */
- png_charpp pcal_params; /* ASCII strings containing parameter values */
- png_byte pcal_type; /* equation type (see PNG_EQUATION_ below) */
- png_byte pcal_nparams; /* number of parameters given in pcal_params */
- #endif
-
- /* New members added in libpng-1.0.6 */
- #ifdef PNG_FREE_ME_SUPPORTED
- png_uint_32 free_me; /* flags items libpng is responsible for freeing */
- #endif
-
- #if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
- /* storage for unknown chunks that the library doesn't recognize. */
- png_unknown_chunkp unknown_chunks;
- png_size_t unknown_chunks_num;
- #endif
-
- #if defined(PNG_iCCP_SUPPORTED)
- /* iCCP chunk data. */
- png_charp iccp_name; /* profile name */
- png_charp iccp_profile; /* International Color Consortium profile data */
- /* Note to maintainer: should be png_bytep */
- png_uint_32 iccp_proflen; /* ICC profile data length */
- png_byte iccp_compression; /* Always zero */
- #endif
-
- #if defined(PNG_sPLT_SUPPORTED)
- /* data on sPLT chunks (there may be more than one). */
- png_sPLT_tp splt_palettes;
- png_uint_32 splt_palettes_num;
- #endif
-
- #if defined(PNG_sCAL_SUPPORTED)
- /* The sCAL chunk describes the actual physical dimensions of the
- * subject matter of the graphic. The chunk contains a unit specification
- * a byte value, and two ASCII strings representing floating-point
- * values. The values are width and height corresponsing to one pixel
- * in the image. This external representation is converted to double
- * here. Data values are valid if (valid & PNG_INFO_sCAL) is non-zero.
- */
- png_byte scal_unit; /* unit of physical scale */
- #ifdef PNG_FLOATING_POINT_SUPPORTED
- double scal_pixel_width; /* width of one pixel */
- double scal_pixel_height; /* height of one pixel */
- #endif
- #ifdef PNG_FIXED_POINT_SUPPORTED
- png_charp scal_s_width; /* string containing height */
- png_charp scal_s_height; /* string containing width */
- #endif
- #endif
-
- #if defined(PNG_INFO_IMAGE_SUPPORTED)
- /* Memory has been allocated if (valid & PNG_ALLOCATED_INFO_ROWS) non-zero */
- /* Data valid if (valid & PNG_INFO_IDAT) non-zero */
- png_bytepp row_pointers; /* the image bits */
- #endif
-
- #if defined(PNG_FIXED_POINT_SUPPORTED) && defined(PNG_gAMA_SUPPORTED)
- png_fixed_point int_gamma; /* gamma of image, if (valid & PNG_INFO_gAMA) */
- #endif
-
- #if defined(PNG_cHRM_SUPPORTED) && defined(PNG_FIXED_POINT_SUPPORTED)
- png_fixed_point int_x_white;
- png_fixed_point int_y_white;
- png_fixed_point int_x_red;
- png_fixed_point int_y_red;
- png_fixed_point int_x_green;
- png_fixed_point int_y_green;
- png_fixed_point int_x_blue;
- png_fixed_point int_y_blue;
- #endif
-
- } png_info;
-
- typedef png_info FAR * png_infop;
- typedef png_info FAR * FAR * png_infopp;
-
- /* Maximum positive integer used in PNG is (2^31)-1 */
- #define PNG_UINT_31_MAX ((png_uint_32)0x7fffffffL)
- #define PNG_UINT_32_MAX ((png_uint_32)(-1))
- #define PNG_SIZE_MAX ((png_size_t)(-1))
- #if defined(PNG_1_0_X) || defined (PNG_1_2_X)
- /* PNG_MAX_UINT is deprecated; use PNG_UINT_31_MAX instead. */
- #define PNG_MAX_UINT PNG_UINT_31_MAX
- #endif
-
- /* These describe the color_type field in png_info. */
- /* color type masks */
- #define PNG_COLOR_MASK_PALETTE 1
- #define PNG_COLOR_MASK_COLOR 2
- #define PNG_COLOR_MASK_ALPHA 4
-
- /* color types. Note that not all combinations are legal */
- #define PNG_COLOR_TYPE_GRAY 0
- #define PNG_COLOR_TYPE_PALETTE (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_PALETTE)
- #define PNG_COLOR_TYPE_RGB (PNG_COLOR_MASK_COLOR)
- #define PNG_COLOR_TYPE_RGB_ALPHA (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_ALPHA)
- #define PNG_COLOR_TYPE_GRAY_ALPHA (PNG_COLOR_MASK_ALPHA)
- /* aliases */
- #define PNG_COLOR_TYPE_RGBA PNG_COLOR_TYPE_RGB_ALPHA
- #define PNG_COLOR_TYPE_GA PNG_COLOR_TYPE_GRAY_ALPHA
-
- /* This is for compression type. PNG 1.0-1.2 only define the single type. */
- #define PNG_COMPRESSION_TYPE_BASE 0 /* Deflate method 8, 32K window */
- #define PNG_COMPRESSION_TYPE_DEFAULT PNG_COMPRESSION_TYPE_BASE
-
- /* This is for filter type. PNG 1.0-1.2 only define the single type. */
- #define PNG_FILTER_TYPE_BASE 0 /* Single row per-byte filtering */
- #define PNG_INTRAPIXEL_DIFFERENCING 64 /* Used only in MNG datastreams */
- #define PNG_FILTER_TYPE_DEFAULT PNG_FILTER_TYPE_BASE
-
- /* These are for the interlacing type. These values should NOT be changed. */
- #define PNG_INTERLACE_NONE 0 /* Non-interlaced image */
- #define PNG_INTERLACE_ADAM7 1 /* Adam7 interlacing */
- #define PNG_INTERLACE_LAST 2 /* Not a valid value */
-
- /* These are for the oFFs chunk. These values should NOT be changed. */
- #define PNG_OFFSET_PIXEL 0 /* Offset in pixels */
- #define PNG_OFFSET_MICROMETER 1 /* Offset in micrometers (1/10^6 meter) */
- #define PNG_OFFSET_LAST 2 /* Not a valid value */
-
- /* These are for the pCAL chunk. These values should NOT be changed. */
- #define PNG_EQUATION_LINEAR 0 /* Linear transformation */
- #define PNG_EQUATION_BASE_E 1 /* Exponential base e transform */
- #define PNG_EQUATION_ARBITRARY 2 /* Arbitrary base exponential transform */
- #define PNG_EQUATION_HYPERBOLIC 3 /* Hyperbolic sine transformation */
- #define PNG_EQUATION_LAST 4 /* Not a valid value */
-
- /* These are for the sCAL chunk. These values should NOT be changed. */
- #define PNG_SCALE_UNKNOWN 0 /* unknown unit (image scale) */
- #define PNG_SCALE_METER 1 /* meters per pixel */
- #define PNG_SCALE_RADIAN 2 /* radians per pixel */
- #define PNG_SCALE_LAST 3 /* Not a valid value */
-
- /* These are for the pHYs chunk. These values should NOT be changed. */
- #define PNG_RESOLUTION_UNKNOWN 0 /* pixels/unknown unit (aspect ratio) */
- #define PNG_RESOLUTION_METER 1 /* pixels/meter */
- #define PNG_RESOLUTION_LAST 2 /* Not a valid value */
-
- /* These are for the sRGB chunk. These values should NOT be changed. */
- #define PNG_sRGB_INTENT_PERCEPTUAL 0
- #define PNG_sRGB_INTENT_RELATIVE 1
- #define PNG_sRGB_INTENT_SATURATION 2
- #define PNG_sRGB_INTENT_ABSOLUTE 3
- #define PNG_sRGB_INTENT_LAST 4 /* Not a valid value */
-
- /* This is for text chunks */
- #define PNG_KEYWORD_MAX_LENGTH 79
-
- /* Maximum number of entries in PLTE/sPLT/tRNS arrays */
- #define PNG_MAX_PALETTE_LENGTH 256
-
- /* These determine if an ancillary chunk's data has been successfully read
- * from the PNG header, or if the application has filled in the corresponding
- * data in the info_struct to be written into the output file. The values
- * of the PNG_INFO_<chunk> defines should NOT be changed.
- */
- #define PNG_INFO_gAMA 0x0001
- #define PNG_INFO_sBIT 0x0002
- #define PNG_INFO_cHRM 0x0004
- #define PNG_INFO_PLTE 0x0008
- #define PNG_INFO_tRNS 0x0010
- #define PNG_INFO_bKGD 0x0020
- #define PNG_INFO_hIST 0x0040
- #define PNG_INFO_pHYs 0x0080
- #define PNG_INFO_oFFs 0x0100
- #define PNG_INFO_tIME 0x0200
- #define PNG_INFO_pCAL 0x0400
- #define PNG_INFO_sRGB 0x0800 /* GR-P, 0.96a */
- #define PNG_INFO_iCCP 0x1000 /* ESR, 1.0.6 */
- #define PNG_INFO_sPLT 0x2000 /* ESR, 1.0.6 */
- #define PNG_INFO_sCAL 0x4000 /* ESR, 1.0.6 */
- #define PNG_INFO_IDAT 0x8000L /* ESR, 1.0.6 */
-
- /* This is used for the transformation routines, as some of them
- * change these values for the row. It also should enable using
- * the routines for other purposes.
- */
- typedef struct png_row_info_struct
- {
- png_uint_32 width; /* width of row */
- png_uint_32 rowbytes; /* number of bytes in row */
- png_byte color_type; /* color type of row */
- png_byte bit_depth; /* bit depth of row */
- png_byte channels; /* number of channels (1, 2, 3, or 4) */
- png_byte pixel_depth; /* bits per pixel (depth * channels) */
- } png_row_info;
-
- typedef png_row_info FAR * png_row_infop;
- typedef png_row_info FAR * FAR * png_row_infopp;
-
- /* These are the function types for the I/O functions and for the functions
- * that allow the user to override the default I/O functions with his or her
- * own. The png_error_ptr type should match that of user-supplied warning
- * and error functions, while the png_rw_ptr type should match that of the
- * user read/write data functions.
- */
- typedef struct png_struct_def png_struct;
- typedef png_struct FAR * png_structp;
-
- typedef void (PNGAPI *png_error_ptr) PNGARG((png_structp, png_const_charp));
- typedef void (PNGAPI *png_rw_ptr) PNGARG((png_structp, png_bytep, png_size_t));
- typedef void (PNGAPI *png_flush_ptr) PNGARG((png_structp));
- typedef void (PNGAPI *png_read_status_ptr) PNGARG((png_structp, png_uint_32,
- int));
- typedef void (PNGAPI *png_write_status_ptr) PNGARG((png_structp, png_uint_32,
- int));
-
- #ifdef PNG_PROGRESSIVE_READ_SUPPORTED
- typedef void (PNGAPI *png_progressive_info_ptr) PNGARG((png_structp, png_infop));
- typedef void (PNGAPI *png_progressive_end_ptr) PNGARG((png_structp, png_infop));
- typedef void (PNGAPI *png_progressive_row_ptr) PNGARG((png_structp, png_bytep,
- png_uint_32, int));
- #endif
-
- #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
- defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \
- defined(PNG_LEGACY_SUPPORTED)
- typedef void (PNGAPI *png_user_transform_ptr) PNGARG((png_structp,
- png_row_infop, png_bytep));
- #endif
-
- #if defined(PNG_USER_CHUNKS_SUPPORTED)
- typedef int (PNGAPI *png_user_chunk_ptr) PNGARG((png_structp, png_unknown_chunkp));
- #endif
- #if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
- typedef void (PNGAPI *png_unknown_chunk_ptr) PNGARG((png_structp));
- #endif
-
- /* Transform masks for the high-level interface */
- #define PNG_TRANSFORM_IDENTITY 0x0000 /* read and write */
- #define PNG_TRANSFORM_STRIP_16 0x0001 /* read only */
- #define PNG_TRANSFORM_STRIP_ALPHA 0x0002 /* read only */
- #define PNG_TRANSFORM_PACKING 0x0004 /* read and write */
- #define PNG_TRANSFORM_PACKSWAP 0x0008 /* read and write */
- #define PNG_TRANSFORM_EXPAND 0x0010 /* read only */
- #define PNG_TRANSFORM_INVERT_MONO 0x0020 /* read and write */
- #define PNG_TRANSFORM_SHIFT 0x0040 /* read and write */
- #define PNG_TRANSFORM_BGR 0x0080 /* read and write */
- #define PNG_TRANSFORM_SWAP_ALPHA 0x0100 /* read and write */
- #define PNG_TRANSFORM_SWAP_ENDIAN 0x0200 /* read and write */
- #define PNG_TRANSFORM_INVERT_ALPHA 0x0400 /* read and write */
- #define PNG_TRANSFORM_STRIP_FILLER 0x0800 /* WRITE only */
-
- /* Flags for MNG supported features */
- #define PNG_FLAG_MNG_EMPTY_PLTE 0x01
- #define PNG_FLAG_MNG_FILTER_64 0x04
- #define PNG_ALL_MNG_FEATURES 0x05
-
- typedef png_voidp (*png_malloc_ptr) PNGARG((png_structp, png_size_t));
- typedef void (*png_free_ptr) PNGARG((png_structp, png_voidp));
-
- /* The structure that holds the information to read and write PNG files.
- * The only people who need to care about what is inside of this are the
- * people who will be modifying the library for their own special needs.
- * It should NOT be accessed directly by an application, except to store
- * the jmp_buf.
- */
-
- struct png_struct_def
- {
- #ifdef PNG_SETJMP_SUPPORTED
- jmp_buf jmpbuf; /* used in png_error */
- #endif
- png_error_ptr error_fn; /* function for printing errors and aborting */
- png_error_ptr warning_fn; /* function for printing warnings */
- png_voidp error_ptr; /* user supplied struct for error functions */
- png_rw_ptr write_data_fn; /* function for writing output data */
- png_rw_ptr read_data_fn; /* function for reading input data */
- png_voidp io_ptr; /* ptr to application struct for I/O functions */
-
- #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
- png_user_transform_ptr read_user_transform_fn; /* user read transform */
- #endif
-
- #if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
- png_user_transform_ptr write_user_transform_fn; /* user write transform */
- #endif
-
- /* These were added in libpng-1.0.2 */
- #if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
- #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
- defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
- png_voidp user_transform_ptr; /* user supplied struct for user transform */
- png_byte user_transform_depth; /* bit depth of user transformed pixels */
- png_byte user_transform_channels; /* channels in user transformed pixels */
- #endif
- #endif
-
- png_uint_32 mode; /* tells us where we are in the PNG file */
- png_uint_32 flags; /* flags indicating various things to libpng */
- png_uint_32 transformations; /* which transformations to perform */
-
- z_stream zstream; /* pointer to decompression structure (below) */
- png_bytep zbuf; /* buffer for zlib */
- png_size_t zbuf_size; /* size of zbuf */
- int zlib_level; /* holds zlib compression level */
- int zlib_method; /* holds zlib compression method */
- int zlib_window_bits; /* holds zlib compression window bits */
- int zlib_mem_level; /* holds zlib compression memory level */
- int zlib_strategy; /* holds zlib compression strategy */
-
- png_uint_32 width; /* width of image in pixels */
- png_uint_32 height; /* height of image in pixels */
- png_uint_32 num_rows; /* number of rows in current pass */
- png_uint_32 usr_width; /* width of row at start of write */
- png_uint_32 rowbytes; /* size of row in bytes */
- png_uint_32 irowbytes; /* size of current interlaced row in bytes */
- png_uint_32 iwidth; /* width of current interlaced row in pixels */
- png_uint_32 row_number; /* current row in interlace pass */
- png_bytep prev_row; /* buffer to save previous (unfiltered) row */
- png_bytep row_buf; /* buffer to save current (unfiltered) row */
- png_bytep sub_row; /* buffer to save "sub" row when filtering */
- png_bytep up_row; /* buffer to save "up" row when filtering */
- png_bytep avg_row; /* buffer to save "avg" row when filtering */
- png_bytep paeth_row; /* buffer to save "Paeth" row when filtering */
- png_row_info row_info; /* used for transformation routines */
-
- png_uint_32 idat_size; /* current IDAT size for read */
- png_uint_32 crc; /* current chunk CRC value */
- png_colorp palette; /* palette from the input file */
- png_uint_16 num_palette; /* number of color entries in palette */
- png_uint_16 num_trans; /* number of transparency values */
- png_byte chunk_name[5]; /* null-terminated name of current chunk */
- png_byte compression; /* file compression type (always 0) */
- png_byte filter; /* file filter type (always 0) */
- png_byte interlaced; /* PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */
- png_byte pass; /* current interlace pass (0 - 6) */
- png_byte do_filter; /* row filter flags (see PNG_FILTER_ below ) */
- png_byte color_type; /* color type of file */
- png_byte bit_depth; /* bit depth of file */
- png_byte usr_bit_depth; /* bit depth of users row */
- png_byte pixel_depth; /* number of bits per pixel */
- png_byte channels; /* number of channels in file */
- png_byte usr_channels; /* channels at start of write */
- png_byte sig_bytes; /* magic bytes read/written from start of file */
-
- #if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
- #ifdef PNG_LEGACY_SUPPORTED
- png_byte filler; /* filler byte for pixel expansion */
- #else
- png_uint_16 filler; /* filler bytes for pixel expansion */
- #endif
- #endif
-
- #if defined(PNG_bKGD_SUPPORTED)
- png_byte background_gamma_type;
- # ifdef PNG_FLOATING_POINT_SUPPORTED
- float background_gamma;
- # endif
- png_color_16 background; /* background color in screen gamma space */
- #if defined(PNG_READ_GAMMA_SUPPORTED)
- png_color_16 background_1; /* background normalized to gamma 1.0 */
- #endif
- #endif /* PNG_bKGD_SUPPORTED */
-
- #if defined(PNG_WRITE_FLUSH_SUPPORTED)
- png_flush_ptr output_flush_fn;/* Function for flushing output */
- png_uint_32 flush_dist; /* how many rows apart to flush, 0 - no flush */
- png_uint_32 flush_rows; /* number of rows written since last flush */
- #endif
-
- #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
- int gamma_shift; /* number of "insignificant" bits 16-bit gamma */
- #ifdef PNG_FLOATING_POINT_SUPPORTED
- float gamma; /* file gamma value */
- float screen_gamma; /* screen gamma value (display_exponent) */
- #endif
- #endif
-
- #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
- png_bytep gamma_table; /* gamma table for 8-bit depth files */
- png_bytep gamma_from_1; /* converts from 1.0 to screen */
- png_bytep gamma_to_1; /* converts from file to 1.0 */
- png_uint_16pp gamma_16_table; /* gamma table for 16-bit depth files */
- png_uint_16pp gamma_16_from_1; /* converts from 1.0 to screen */
- png_uint_16pp gamma_16_to_1; /* converts from file to 1.0 */
- #endif
-
- #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_sBIT_SUPPORTED)
- png_color_8 sig_bit; /* significant bits in each available channel */
- #endif
-
- #if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
- png_color_8 shift; /* shift for significant bit tranformation */
- #endif
-
- #if defined(PNG_tRNS_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) \
- || defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
- png_bytep trans; /* transparency values for paletted files */
- png_color_16 trans_values; /* transparency values for non-paletted files */
- #endif
-
- png_read_status_ptr read_row_fn; /* called after each row is decoded */
- png_write_status_ptr write_row_fn; /* called after each row is encoded */
- #ifdef PNG_PROGRESSIVE_READ_SUPPORTED
- png_progressive_info_ptr info_fn; /* called after header data fully read */
- png_progressive_row_ptr row_fn; /* called after each prog. row is decoded */
- png_progressive_end_ptr end_fn; /* called after image is complete */
- png_bytep save_buffer_ptr; /* current location in save_buffer */
- png_bytep save_buffer; /* buffer for previously read data */
- png_bytep current_buffer_ptr; /* current location in current_buffer */
- png_bytep current_buffer; /* buffer for recently used data */
- png_uint_32 push_length; /* size of current input chunk */
- png_uint_32 skip_length; /* bytes to skip in input data */
- png_size_t save_buffer_size; /* amount of data now in save_buffer */
- png_size_t save_buffer_max; /* total size of save_buffer */
- png_size_t buffer_size; /* total amount of available input data */
- png_size_t current_buffer_size; /* amount of data now in current_buffer */
- int process_mode; /* what push library is currently doing */
- int cur_palette; /* current push library palette index */
-
- # if defined(PNG_TEXT_SUPPORTED)
- png_size_t current_text_size; /* current size of text input data */
- png_size_t current_text_left; /* how much text left to read in input */
- png_charp current_text; /* current text chunk buffer */
- png_charp current_text_ptr; /* current location in current_text */
- # endif /* PNG_TEXT_SUPPORTED */
- #endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
-
- #if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__)
- /* for the Borland special 64K segment handler */
- png_bytepp offset_table_ptr;
- png_bytep offset_table;
- png_uint_16 offset_table_number;
- png_uint_16 offset_table_count;
- png_uint_16 offset_table_count_free;
- #endif
-
- #if defined(PNG_READ_DITHER_SUPPORTED)
- png_bytep palette_lookup; /* lookup table for dithering */
- png_bytep dither_index; /* index translation for palette files */
- #endif
-
- #if defined(PNG_READ_DITHER_SUPPORTED) || defined(PNG_hIST_SUPPORTED)
- png_uint_16p hist; /* histogram */
- #endif
-
- #if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
- png_byte heuristic_method; /* heuristic for row filter selection */
- png_byte num_prev_filters; /* number of weights for previous rows */
- png_bytep prev_filters; /* filter type(s) of previous row(s) */
- png_uint_16p filter_weights; /* weight(s) for previous line(s) */
- png_uint_16p inv_filter_weights; /* 1/weight(s) for previous line(s) */
- png_uint_16p filter_costs; /* relative filter calculation cost */
- png_uint_16p inv_filter_costs; /* 1/relative filter calculation cost */
- #endif
-
- #if defined(PNG_TIME_RFC1123_SUPPORTED)
- png_charp time_buffer; /* String to hold RFC 1123 time text */
- #endif
-
- /* New members added in libpng-1.0.6 */
-
- #ifdef PNG_FREE_ME_SUPPORTED
- png_uint_32 free_me; /* flags items libpng is responsible for freeing */
- #endif
-
- #if defined(PNG_USER_CHUNKS_SUPPORTED)
- png_voidp user_chunk_ptr;
- png_user_chunk_ptr read_user_chunk_fn; /* user read chunk handler */
- #endif
-
- #if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
- int num_chunk_list;
- png_bytep chunk_list;
- #endif
-
- /* New members added in libpng-1.0.3 */
- #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
- png_byte rgb_to_gray_status;
- /* These were changed from png_byte in libpng-1.0.6 */
- png_uint_16 rgb_to_gray_red_coeff;
- png_uint_16 rgb_to_gray_green_coeff;
- png_uint_16 rgb_to_gray_blue_coeff;
- #endif
-
- /* New member added in libpng-1.0.4 (renamed in 1.0.9) */
- #if defined(PNG_MNG_FEATURES_SUPPORTED) || \
- defined(PNG_READ_EMPTY_PLTE_SUPPORTED) || \
- defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED)
- /* changed from png_byte to png_uint_32 at version 1.2.0 */
- #ifdef PNG_1_0_X
- png_byte mng_features_permitted;
- #else
- png_uint_32 mng_features_permitted;
- #endif /* PNG_1_0_X */
- #endif
-
- /* New member added in libpng-1.0.7 */
- #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
- png_fixed_point int_gamma;
- #endif
-
- /* New member added in libpng-1.0.9, ifdef'ed out in 1.0.12, enabled in 1.2.0 */
- #if defined(PNG_MNG_FEATURES_SUPPORTED)
- png_byte filter_type;
- #endif
-
- #if defined(PNG_1_0_X)
- /* New member added in libpng-1.0.10, ifdef'ed out in 1.2.0 */
- png_uint_32 row_buf_size;
- #endif
-
- /* New members added in libpng-1.2.0 */
- #if defined(PNG_ASSEMBLER_CODE_SUPPORTED)
- # if !defined(PNG_1_0_X)
- # if defined(PNG_MMX_CODE_SUPPORTED)
- png_byte mmx_bitdepth_threshold;
- png_uint_32 mmx_rowbytes_threshold;
- # endif
- png_uint_32 asm_flags;
- # endif
- #endif
-
- /* New members added in libpng-1.0.2 but first enabled by default in 1.2.0 */
- #ifdef PNG_USER_MEM_SUPPORTED
- png_voidp mem_ptr; /* user supplied struct for mem functions */
- png_malloc_ptr malloc_fn; /* function for allocating memory */
- png_free_ptr free_fn; /* function for freeing memory */
- #endif
-
- /* New member added in libpng-1.0.13 and 1.2.0 */
- png_bytep big_row_buf; /* buffer to save current (unfiltered) row */
-
- #if defined(PNG_READ_DITHER_SUPPORTED)
- /* The following three members were added at version 1.0.14 and 1.2.4 */
- png_bytep dither_sort; /* working sort array */
- png_bytep index_to_palette; /* where the original index currently is */
- /* in the palette */
- png_bytep palette_to_index; /* which original index points to this */
- /* palette color */
- #endif
-
- /* New members added in libpng-1.0.16 and 1.2.6 */
- png_byte compression_type;
-
- #ifdef PNG_SET_USER_LIMITS_SUPPORTED
- png_uint_32 user_width_max;
- png_uint_32 user_height_max;
- #endif
-
- /* New member added in libpng-1.0.25 and 1.2.17 */
- #if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
- /* storage for unknown chunk that the library doesn't recognize. */
- png_unknown_chunk unknown_chunk;
- #endif
- };
-
- /* This triggers a compiler error in png.c, if png.c and png.h
- * do not agree upon the version number.
- */
- typedef png_structp version_1_2_21;
-
- typedef png_struct FAR * FAR * png_structpp;
-
- /* Here are the function definitions most commonly used. This is not
- * the place to find out how to use libpng. See libpng.txt for the
- * full explanation, see example.c for the summary. This just provides
- * a simple one line description of the use of each function.
- */
-
- /* Returns the version number of the library */
- extern PNG_EXPORT(png_uint_32,png_access_version_number) PNGARG((void));
-
- /* Tell lib we have already handled the first <num_bytes> magic bytes.
- * Handling more than 8 bytes from the beginning of the file is an error.
- */
- extern PNG_EXPORT(void,png_set_sig_bytes) PNGARG((png_structp png_ptr,
- int num_bytes));
-
- /* Check sig[start] through sig[start + num_to_check - 1] to see if it's a
- * PNG file. Returns zero if the supplied bytes match the 8-byte PNG
- * signature, and non-zero otherwise. Having num_to_check == 0 or
- * start > 7 will always fail (ie return non-zero).
- */
- extern PNG_EXPORT(int,png_sig_cmp) PNGARG((png_bytep sig, png_size_t start,
- png_size_t num_to_check));
-
- /* Simple signature checking function. This is the same as calling
- * png_check_sig(sig, n) := !png_sig_cmp(sig, 0, n).
- */
- extern PNG_EXPORT(int,png_check_sig) PNGARG((png_bytep sig, int num));
-
- /* Allocate and initialize png_ptr struct for reading, and any other memory. */
- extern PNG_EXPORT(png_structp,png_create_read_struct)
- PNGARG((png_const_charp user_png_ver, png_voidp error_ptr,
- png_error_ptr error_fn, png_error_ptr warn_fn));
-
- /* Allocate and initialize png_ptr struct for writing, and any other memory */
- extern PNG_EXPORT(png_structp,png_create_write_struct)
- PNGARG((png_const_charp user_png_ver, png_voidp error_ptr,
- png_error_ptr error_fn, png_error_ptr warn_fn));
-
- #ifdef PNG_WRITE_SUPPORTED
- extern PNG_EXPORT(png_uint_32,png_get_compression_buffer_size)
- PNGARG((png_structp png_ptr));
- #endif
-
- #ifdef PNG_WRITE_SUPPORTED
- extern PNG_EXPORT(void,png_set_compression_buffer_size)
- PNGARG((png_structp png_ptr, png_uint_32 size));
- #endif
-
- /* Reset the compression stream */
- extern PNG_EXPORT(int,png_reset_zstream) PNGARG((png_structp png_ptr));
-
- /* New functions added in libpng-1.0.2 (not enabled by default until 1.2.0) */
- #ifdef PNG_USER_MEM_SUPPORTED
- extern PNG_EXPORT(png_structp,png_create_read_struct_2)
- PNGARG((png_const_charp user_png_ver, png_voidp error_ptr,
- png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
- png_malloc_ptr malloc_fn, png_free_ptr free_fn));
- extern PNG_EXPORT(png_structp,png_create_write_struct_2)
- PNGARG((png_const_charp user_png_ver, png_voidp error_ptr,
- png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
- png_malloc_ptr malloc_fn, png_free_ptr free_fn));
- #endif
-
- /* Write a PNG chunk - size, type, (optional) data, CRC. */
- extern PNG_EXPORT(void,png_write_chunk) PNGARG((png_structp png_ptr,
- png_bytep chunk_name, png_bytep data, png_size_t length));
-
- /* Write the start of a PNG chunk - length and chunk name. */
- extern PNG_EXPORT(void,png_write_chunk_start) PNGARG((png_structp png_ptr,
- png_bytep chunk_name, png_uint_32 length));
-
- /* Write the data of a PNG chunk started with png_write_chunk_start(). */
- extern PNG_EXPORT(void,png_write_chunk_data) PNGARG((png_structp png_ptr,
- png_bytep data, png_size_t length));
-
- /* Finish a chunk started with png_write_chunk_start() (includes CRC). */
- extern PNG_EXPORT(void,png_write_chunk_end) PNGARG((png_structp png_ptr));
-
- /* Allocate and initialize the info structure */
- extern PNG_EXPORT(png_infop,png_create_info_struct)
- PNGARG((png_structp png_ptr));
-
- #if defined(PNG_1_0_X) || defined (PNG_1_2_X)
- /* Initialize the info structure (old interface - DEPRECATED) */
- extern PNG_EXPORT(void,png_info_init) PNGARG((png_infop info_ptr));
- #undef png_info_init
- #define png_info_init(info_ptr) png_info_init_3(&info_ptr,\
- png_sizeof(png_info));
- #endif
-
- extern PNG_EXPORT(void,png_info_init_3) PNGARG((png_infopp info_ptr,
- png_size_t png_info_struct_size));
-
- /* Writes all the PNG information before the image. */
- extern PNG_EXPORT(void,png_write_info_before_PLTE) PNGARG((png_structp png_ptr,
- png_infop info_ptr));
- extern PNG_EXPORT(void,png_write_info) PNGARG((png_structp png_ptr,
- png_infop info_ptr));
-
- #ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
- /* read the information before the actual image data. */
- extern PNG_EXPORT(void,png_read_info) PNGARG((png_structp png_ptr,
- png_infop info_ptr));
- #endif
-
- #if defined(PNG_TIME_RFC1123_SUPPORTED)
- extern PNG_EXPORT(png_charp,png_convert_to_rfc1123)
- PNGARG((png_structp png_ptr, png_timep ptime));
- #endif
-
- #if !defined(_WIN32_WCE)
- /* "time.h" functions are not supported on WindowsCE */
- #if defined(PNG_WRITE_tIME_SUPPORTED)
- /* convert from a struct tm to png_time */
- extern PNG_EXPORT(void,png_convert_from_struct_tm) PNGARG((png_timep ptime,
- struct tm FAR * ttime));
-
- /* convert from time_t to png_time. Uses gmtime() */
- extern PNG_EXPORT(void,png_convert_from_time_t) PNGARG((png_timep ptime,
- time_t ttime));
- #endif /* PNG_WRITE_tIME_SUPPORTED */
- #endif /* _WIN32_WCE */
-
- #if defined(PNG_READ_EXPAND_SUPPORTED)
- /* Expand data to 24-bit RGB, or 8-bit grayscale, with alpha if available. */
- extern PNG_EXPORT(void,png_set_expand) PNGARG((png_structp png_ptr));
- #if !defined(PNG_1_0_X)
- extern PNG_EXPORT(void,png_set_expand_gray_1_2_4_to_8) PNGARG((png_structp
- png_ptr));
- #endif
- extern PNG_EXPORT(void,png_set_palette_to_rgb) PNGARG((png_structp png_ptr));
- extern PNG_EXPORT(void,png_set_tRNS_to_alpha) PNGARG((png_structp png_ptr));
- #if defined(PNG_1_0_X) || defined (PNG_1_2_X)
- /* Deprecated */
- extern PNG_EXPORT(void,png_set_gray_1_2_4_to_8) PNGARG((png_structp png_ptr));
- #endif
- #endif
-
- #if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
- /* Use blue, green, red order for pixels. */
- extern PNG_EXPORT(void,png_set_bgr) PNGARG((png_structp png_ptr));
- #endif
-
- #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
- /* Expand the grayscale to 24-bit RGB if necessary. */
- extern PNG_EXPORT(void,png_set_gray_to_rgb) PNGARG((png_structp png_ptr));
- #endif
-
- #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
- /* Reduce RGB to grayscale. */
- #ifdef PNG_FLOATING_POINT_SUPPORTED
- extern PNG_EXPORT(void,png_set_rgb_to_gray) PNGARG((png_structp png_ptr,
- int error_action, double red, double green ));
- #endif
- extern PNG_EXPORT(void,png_set_rgb_to_gray_fixed) PNGARG((png_structp png_ptr,
- int error_action, png_fixed_point red, png_fixed_point green ));
- extern PNG_EXPORT(png_byte,png_get_rgb_to_gray_status) PNGARG((png_structp
- png_ptr));
- #endif
-
- extern PNG_EXPORT(void,png_build_grayscale_palette) PNGARG((int bit_depth,
- png_colorp palette));
-
- #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
- extern PNG_EXPORT(void,png_set_strip_alpha) PNGARG((png_structp png_ptr));
- #endif
-
- #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \
- defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
- extern PNG_EXPORT(void,png_set_swap_alpha) PNGARG((png_structp png_ptr));
- #endif
-
- #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \
- defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
- extern PNG_EXPORT(void,png_set_invert_alpha) PNGARG((png_structp png_ptr));
- #endif
-
- #if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
- /* Add a filler byte to 8-bit Gray or 24-bit RGB images. */
- extern PNG_EXPORT(void,png_set_filler) PNGARG((png_structp png_ptr,
- png_uint_32 filler, int flags));
- /* The values of the PNG_FILLER_ defines should NOT be changed */
- #define PNG_FILLER_BEFORE 0
- #define PNG_FILLER_AFTER 1
- /* Add an alpha byte to 8-bit Gray or 24-bit RGB images. */
- #if !defined(PNG_1_0_X)
- extern PNG_EXPORT(void,png_set_add_alpha) PNGARG((png_structp png_ptr,
- png_uint_32 filler, int flags));
- #endif
- #endif /* PNG_READ_FILLER_SUPPORTED || PNG_WRITE_FILLER_SUPPORTED */
-
- #if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
- /* Swap bytes in 16-bit depth files. */
- extern PNG_EXPORT(void,png_set_swap) PNGARG((png_structp png_ptr));
- #endif
-
- #if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
- /* Use 1 byte per pixel in 1, 2, or 4-bit depth files. */
- extern PNG_EXPORT(void,png_set_packing) PNGARG((png_structp png_ptr));
- #endif
-
- #if defined(PNG_READ_PACKSWAP_SUPPORTED) || defined(PNG_WRITE_PACKSWAP_SUPPORTED)
- /* Swap packing order of pixels in bytes. */
- extern PNG_EXPORT(void,png_set_packswap) PNGARG((png_structp png_ptr));
- #endif
-
- #if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
- /* Converts files to legal bit depths. */
- extern PNG_EXPORT(void,png_set_shift) PNGARG((png_structp png_ptr,
- png_color_8p true_bits));
- #endif
-
- #if defined(PNG_READ_INTERLACING_SUPPORTED) || \
- defined(PNG_WRITE_INTERLACING_SUPPORTED)
- /* Have the code handle the interlacing. Returns the number of passes. */
- extern PNG_EXPORT(int,png_set_interlace_handling) PNGARG((png_structp png_ptr));
- #endif
-
- #if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
- /* Invert monochrome files */
- extern PNG_EXPORT(void,png_set_invert_mono) PNGARG((png_structp png_ptr));
- #endif
-
- #if defined(PNG_READ_BACKGROUND_SUPPORTED)
- /* Handle alpha and tRNS by replacing with a background color. */
- #ifdef PNG_FLOATING_POINT_SUPPORTED
- extern PNG_EXPORT(void,png_set_background) PNGARG((png_structp png_ptr,
- png_color_16p background_color, int background_gamma_code,
- int need_expand, double background_gamma));
- #endif
- #define PNG_BACKGROUND_GAMMA_UNKNOWN 0
- #define PNG_BACKGROUND_GAMMA_SCREEN 1
- #define PNG_BACKGROUND_GAMMA_FILE 2
- #define PNG_BACKGROUND_GAMMA_UNIQUE 3
- #endif
-
- #if defined(PNG_READ_16_TO_8_SUPPORTED)
- /* strip the second byte of information from a 16-bit depth file. */
- extern PNG_EXPORT(void,png_set_strip_16) PNGARG((png_structp png_ptr));
- #endif
-
- #if defined(PNG_READ_DITHER_SUPPORTED)
- /* Turn on dithering, and reduce the palette to the number of colors available. */
- extern PNG_EXPORT(void,png_set_dither) PNGARG((png_structp png_ptr,
- png_colorp palette, int num_palette, int maximum_colors,
- png_uint_16p histogram, int full_dither));
- #endif
-
- #if defined(PNG_READ_GAMMA_SUPPORTED)
- /* Handle gamma correction. Screen_gamma=(display_exponent) */
- #ifdef PNG_FLOATING_POINT_SUPPORTED
- extern PNG_EXPORT(void,png_set_gamma) PNGARG((png_structp png_ptr,
- double screen_gamma, double default_file_gamma));
- #endif
- #endif
-
- #if defined(PNG_1_0_X) || defined (PNG_1_2_X)
- #if defined(PNG_READ_EMPTY_PLTE_SUPPORTED) || \
- defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED)
- /* Permit or disallow empty PLTE (0: not permitted, 1: permitted) */
- /* Deprecated and will be removed. Use png_permit_mng_features() instead. */
- extern PNG_EXPORT(void,png_permit_empty_plte) PNGARG((png_structp png_ptr,
- int empty_plte_permitted));
- #endif
- #endif
-
- #if defined(PNG_WRITE_FLUSH_SUPPORTED)
- /* Set how many lines between output flushes - 0 for no flushing */
- extern PNG_EXPORT(void,png_set_flush) PNGARG((png_structp png_ptr, int nrows));
- /* Flush the current PNG output buffer */
- extern PNG_EXPORT(void,png_write_flush) PNGARG((png_structp png_ptr));
- #endif
-
- /* optional update palette with requested transformations */
- extern PNG_EXPORT(void,png_start_read_image) PNGARG((png_structp png_ptr));
-
- /* optional call to update the users info structure */
- extern PNG_EXPORT(void,png_read_update_info) PNGARG((png_structp png_ptr,
- png_infop info_ptr));
-
- #ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
- /* read one or more rows of image data. */
- extern PNG_EXPORT(void,png_read_rows) PNGARG((png_structp png_ptr,
- png_bytepp row, png_bytepp display_row, png_uint_32 num_rows));
- #endif
-
- #ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
- /* read a row of data. */
- extern PNG_EXPORT(void,png_read_row) PNGARG((png_structp png_ptr,
- png_bytep row,
- png_bytep display_row));
- #endif
-
- #ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
- /* read the whole image into memory at once. */
- extern PNG_EXPORT(void,png_read_image) PNGARG((png_structp png_ptr,
- png_bytepp image));
- #endif
-
- /* write a row of image data */
- extern PNG_EXPORT(void,png_write_row) PNGARG((png_structp png_ptr,
- png_bytep row));
-
- /* write a few rows of image data */
- extern PNG_EXPORT(void,png_write_rows) PNGARG((png_structp png_ptr,
- png_bytepp row, png_uint_32 num_rows));
-
- /* write the image data */
- extern PNG_EXPORT(void,png_write_image) PNGARG((png_structp png_ptr,
- png_bytepp image));
-
- /* writes the end of the PNG file. */
- extern PNG_EXPORT(void,png_write_end) PNGARG((png_structp png_ptr,
- png_infop info_ptr));
-
- #ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
- /* read the end of the PNG file. */
- extern PNG_EXPORT(void,png_read_end) PNGARG((png_structp png_ptr,
- png_infop info_ptr));
- #endif
-
- /* free any memory associated with the png_info_struct */
- extern PNG_EXPORT(void,png_destroy_info_struct) PNGARG((png_structp png_ptr,
- png_infopp info_ptr_ptr));
-
- /* free any memory associated with the png_struct and the png_info_structs */
- extern PNG_EXPORT(void,png_destroy_read_struct) PNGARG((png_structpp
- png_ptr_ptr, png_infopp info_ptr_ptr, png_infopp end_info_ptr_ptr));
-
- /* free all memory used by the read (old method - NOT DLL EXPORTED) */
- extern void png_read_destroy PNGARG((png_structp png_ptr, png_infop info_ptr,
- png_infop end_info_ptr));
-
- /* free any memory associated with the png_struct and the png_info_structs */
- extern PNG_EXPORT(void,png_destroy_write_struct)
- PNGARG((png_structpp png_ptr_ptr, png_infopp info_ptr_ptr));
-
- /* free any memory used in png_ptr struct (old method - NOT DLL EXPORTED) */
- extern void png_write_destroy PNGARG((png_structp png_ptr));
-
- /* set the libpng method of handling chunk CRC errors */
- extern PNG_EXPORT(void,png_set_crc_action) PNGARG((png_structp png_ptr,
- int crit_action, int ancil_action));
-
- /* Values for png_set_crc_action() to say how to handle CRC errors in
- * ancillary and critical chunks, and whether to use the data contained
- * therein. Note that it is impossible to "discard" data in a critical
- * chunk. For versions prior to 0.90, the action was always error/quit,
- * whereas in version 0.90 and later, the action for CRC errors in ancillary
- * chunks is warn/discard. These values should NOT be changed.
- *
- * value action:critical action:ancillary
- */
- #define PNG_CRC_DEFAULT 0 /* error/quit warn/discard data */
- #define PNG_CRC_ERROR_QUIT 1 /* error/quit error/quit */
- #define PNG_CRC_WARN_DISCARD 2 /* (INVALID) warn/discard data */
- #define PNG_CRC_WARN_USE 3 /* warn/use data warn/use data */
- #define PNG_CRC_QUIET_USE 4 /* quiet/use data quiet/use data */
- #define PNG_CRC_NO_CHANGE 5 /* use current value use current value */
-
- /* These functions give the user control over the scan-line filtering in
- * libpng and the compression methods used by zlib. These functions are
- * mainly useful for testing, as the defaults should work with most users.
- * Those users who are tight on memory or want faster performance at the
- * expense of compression can modify them. See the compression library
- * header file (zlib.h) for an explination of the compression functions.
- */
-
- /* set the filtering method(s) used by libpng. Currently, the only valid
- * value for "method" is 0.
- */
- extern PNG_EXPORT(void,png_set_filter) PNGARG((png_structp png_ptr, int method,
- int filters));
-
- /* Flags for png_set_filter() to say which filters to use. The flags
- * are chosen so that they don't conflict with real filter types
- * below, in case they are supplied instead of the #defined constants.
- * These values should NOT be changed.
- */
- #define PNG_NO_FILTERS 0x00
- #define PNG_FILTER_NONE 0x08
- #define PNG_FILTER_SUB 0x10
- #define PNG_FILTER_UP 0x20
- #define PNG_FILTER_AVG 0x40
- #define PNG_FILTER_PAETH 0x80
- #define PNG_ALL_FILTERS (PNG_FILTER_NONE | PNG_FILTER_SUB | PNG_FILTER_UP | \
- PNG_FILTER_AVG | PNG_FILTER_PAETH)
-
- /* Filter values (not flags) - used in pngwrite.c, pngwutil.c for now.
- * These defines should NOT be changed.
- */
- #define PNG_FILTER_VALUE_NONE 0
- #define PNG_FILTER_VALUE_SUB 1
- #define PNG_FILTER_VALUE_UP 2
- #define PNG_FILTER_VALUE_AVG 3
- #define PNG_FILTER_VALUE_PAETH 4
- #define PNG_FILTER_VALUE_LAST 5
-
- #if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) /* EXPERIMENTAL */
- /* The "heuristic_method" is given by one of the PNG_FILTER_HEURISTIC_
- * defines, either the default (minimum-sum-of-absolute-differences), or
- * the experimental method (weighted-minimum-sum-of-absolute-differences).
- *
- * Weights are factors >= 1.0, indicating how important it is to keep the
- * filter type consistent between rows. Larger numbers mean the current
- * filter is that many times as likely to be the same as the "num_weights"
- * previous filters. This is cumulative for each previous row with a weight.
- * There needs to be "num_weights" values in "filter_weights", or it can be
- * NULL if the weights aren't being specified. Weights have no influence on
- * the selection of the first row filter. Well chosen weights can (in theory)
- * improve the compression for a given image.
- *
- * Costs are factors >= 1.0 indicating the relative decoding costs of a
- * filter type. Higher costs indicate more decoding expense, and are
- * therefore less likely to be selected over a filter with lower computational
- * costs. There needs to be a value in "filter_costs" for each valid filter
- * type (given by PNG_FILTER_VALUE_LAST), or it can be NULL if you aren't
- * setting the costs. Costs try to improve the speed of decompression without
- * unduly increasing the compressed image size.
- *
- * A negative weight or cost indicates the default value is to be used, and
- * values in the range [0.0, 1.0) indicate the value is to remain unchanged.
- * The default values for both weights and costs are currently 1.0, but may
- * change if good general weighting/cost heuristics can be found. If both
- * the weights and costs are set to 1.0, this degenerates the WEIGHTED method
- * to the UNWEIGHTED method, but with added encoding time/computation.
- */
- #ifdef PNG_FLOATING_POINT_SUPPORTED
- extern PNG_EXPORT(void,png_set_filter_heuristics) PNGARG((png_structp png_ptr,
- int heuristic_method, int num_weights, png_doublep filter_weights,
- png_doublep filter_costs));
- #endif
- #endif /* PNG_WRITE_WEIGHTED_FILTER_SUPPORTED */
-
- /* Heuristic used for row filter selection. These defines should NOT be
- * changed.
- */
- #define PNG_FILTER_HEURISTIC_DEFAULT 0 /* Currently "UNWEIGHTED" */
- #define PNG_FILTER_HEURISTIC_UNWEIGHTED 1 /* Used by libpng < 0.95 */
- #define PNG_FILTER_HEURISTIC_WEIGHTED 2 /* Experimental feature */
- #define PNG_FILTER_HEURISTIC_LAST 3 /* Not a valid value */
-
- /* Set the library compression level. Currently, valid values range from
- * 0 - 9, corresponding directly to the zlib compression levels 0 - 9
- * (0 - no compression, 9 - "maximal" compression). Note that tests have
- * shown that zlib compression levels 3-6 usually perform as well as level 9
- * for PNG images, and do considerably fewer caclulations. In the future,
- * these values may not correspond directly to the zlib compression levels.
- */
- extern PNG_EXPORT(void,png_set_compression_level) PNGARG((png_structp png_ptr,
- int level));
-
- extern PNG_EXPORT(void,png_set_compression_mem_level)
- PNGARG((png_structp png_ptr, int mem_level));
-
- extern PNG_EXPORT(void,png_set_compression_strategy)
- PNGARG((png_structp png_ptr, int strategy));
-
- extern PNG_EXPORT(void,png_set_compression_window_bits)
- PNGARG((png_structp png_ptr, int window_bits));
-
- extern PNG_EXPORT(void,png_set_compression_method) PNGARG((png_structp png_ptr,
- int method));
-
- /* These next functions are called for input/output, memory, and error
- * handling. They are in the file pngrio.c, pngwio.c, and pngerror.c,
- * and call standard C I/O routines such as fread(), fwrite(), and
- * fprintf(). These functions can be made to use other I/O routines
- * at run time for those applications that need to handle I/O in a
- * different manner by calling png_set_???_fn(). See libpng.txt for
- * more information.
- */
-
- #if !defined(PNG_NO_STDIO)
- /* Initialize the input/output for the PNG file to the default functions. */
- extern PNG_EXPORT(void,png_init_io) PNGARG((png_structp png_ptr, png_FILE_p fp));
- #endif
-
- /* Replace the (error and abort), and warning functions with user
- * supplied functions. If no messages are to be printed you must still
- * write and use replacement functions. The replacement error_fn should
- * still do a longjmp to the last setjmp location if you are using this
- * method of error handling. If error_fn or warning_fn is NULL, the
- * default function will be used.
- */
-
- extern PNG_EXPORT(void,png_set_error_fn) PNGARG((png_structp png_ptr,
- png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr warning_fn));
-
- /* Return the user pointer associated with the error functions */
- extern PNG_EXPORT(png_voidp,png_get_error_ptr) PNGARG((png_structp png_ptr));
-
- /* Replace the default data output functions with a user supplied one(s).
- * If buffered output is not used, then output_flush_fn can be set to NULL.
- * If PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng compile time
- * output_flush_fn will be ignored (and thus can be NULL).
- */
- extern PNG_EXPORT(void,png_set_write_fn) PNGARG((png_structp png_ptr,
- png_voidp io_ptr, png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn));
-
- /* Replace the default data input function with a user supplied one. */
- extern PNG_EXPORT(void,png_set_read_fn) PNGARG((png_structp png_ptr,
- png_voidp io_ptr, png_rw_ptr read_data_fn));
-
- /* Return the user pointer associated with the I/O functions */
- extern PNG_EXPORT(png_voidp,png_get_io_ptr) PNGARG((png_structp png_ptr));
-
- extern PNG_EXPORT(void,png_set_read_status_fn) PNGARG((png_structp png_ptr,
- png_read_status_ptr read_row_fn));
-
- extern PNG_EXPORT(void,png_set_write_status_fn) PNGARG((png_structp png_ptr,
- png_write_status_ptr write_row_fn));
-
- #ifdef PNG_USER_MEM_SUPPORTED
- /* Replace the default memory allocation functions with user supplied one(s). */
- extern PNG_EXPORT(void,png_set_mem_fn) PNGARG((png_structp png_ptr,
- png_voidp mem_ptr, png_malloc_ptr malloc_fn, png_free_ptr free_fn));
- /* Return the user pointer associated with the memory functions */
- extern PNG_EXPORT(png_voidp,png_get_mem_ptr) PNGARG((png_structp png_ptr));
- #endif
-
- #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
- defined(PNG_LEGACY_SUPPORTED)
- extern PNG_EXPORT(void,png_set_read_user_transform_fn) PNGARG((png_structp
- png_ptr, png_user_transform_ptr read_user_transform_fn));
- #endif
-
- #if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \
- defined(PNG_LEGACY_SUPPORTED)
- extern PNG_EXPORT(void,png_set_write_user_transform_fn) PNGARG((png_structp
- png_ptr, png_user_transform_ptr write_user_transform_fn));
- #endif
-
- #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
- defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \
- defined(PNG_LEGACY_SUPPORTED)
- extern PNG_EXPORT(void,png_set_user_transform_info) PNGARG((png_structp
- png_ptr, png_voidp user_transform_ptr, int user_transform_depth,
- int user_transform_channels));
- /* Return the user pointer associated with the user transform functions */
- extern PNG_EXPORT(png_voidp,png_get_user_transform_ptr)
- PNGARG((png_structp png_ptr));
- #endif
-
- #ifdef PNG_USER_CHUNKS_SUPPORTED
- extern PNG_EXPORT(void,png_set_read_user_chunk_fn) PNGARG((png_structp png_ptr,
- png_voidp user_chunk_ptr, png_user_chunk_ptr read_user_chunk_fn));
- extern PNG_EXPORT(png_voidp,png_get_user_chunk_ptr) PNGARG((png_structp
- png_ptr));
- #endif
-
- #ifdef PNG_PROGRESSIVE_READ_SUPPORTED
- /* Sets the function callbacks for the push reader, and a pointer to a
- * user-defined structure available to the callback functions.
- */
- extern PNG_EXPORT(void,png_set_progressive_read_fn) PNGARG((png_structp png_ptr,
- png_voidp progressive_ptr,
- png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn,
- png_progressive_end_ptr end_fn));
-
- /* returns the user pointer associated with the push read functions */
- extern PNG_EXPORT(png_voidp,png_get_progressive_ptr)
- PNGARG((png_structp png_ptr));
-
- /* function to be called when data becomes available */
- extern PNG_EXPORT(void,png_process_data) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_bytep buffer, png_size_t buffer_size));
-
- /* function that combines rows. Not very much different than the
- * png_combine_row() call. Is this even used?????
- */
- extern PNG_EXPORT(void,png_progressive_combine_row) PNGARG((png_structp png_ptr,
- png_bytep old_row, png_bytep new_row));
- #endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
-
- extern PNG_EXPORT(png_voidp,png_malloc) PNGARG((png_structp png_ptr,
- png_uint_32 size));
-
- #if defined(PNG_1_0_X)
- # define png_malloc_warn png_malloc
- #else
- /* Added at libpng version 1.2.4 */
- extern PNG_EXPORT(png_voidp,png_malloc_warn) PNGARG((png_structp png_ptr,
- png_uint_32 size));
- #endif
-
- /* frees a pointer allocated by png_malloc() */
- extern PNG_EXPORT(void,png_free) PNGARG((png_structp png_ptr, png_voidp ptr));
-
- #if defined(PNG_1_0_X)
- /* Function to allocate memory for zlib. */
- extern PNG_EXPORT(voidpf,png_zalloc) PNGARG((voidpf png_ptr, uInt items,
- uInt size));
-
- /* Function to free memory for zlib */
- extern PNG_EXPORT(void,png_zfree) PNGARG((voidpf png_ptr, voidpf ptr));
- #endif
-
- /* Free data that was allocated internally */
- extern PNG_EXPORT(void,png_free_data) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_uint_32 free_me, int num));
- #ifdef PNG_FREE_ME_SUPPORTED
- /* Reassign responsibility for freeing existing data, whether allocated
- * by libpng or by the application */
- extern PNG_EXPORT(void,png_data_freer) PNGARG((png_structp png_ptr,
- png_infop info_ptr, int freer, png_uint_32 mask));
- #endif
- /* assignments for png_data_freer */
- #define PNG_DESTROY_WILL_FREE_DATA 1
- #define PNG_SET_WILL_FREE_DATA 1
- #define PNG_USER_WILL_FREE_DATA 2
- /* Flags for png_ptr->free_me and info_ptr->free_me */
- #define PNG_FREE_HIST 0x0008
- #define PNG_FREE_ICCP 0x0010
- #define PNG_FREE_SPLT 0x0020
- #define PNG_FREE_ROWS 0x0040
- #define PNG_FREE_PCAL 0x0080
- #define PNG_FREE_SCAL 0x0100
- #define PNG_FREE_UNKN 0x0200
- #define PNG_FREE_LIST 0x0400
- #define PNG_FREE_PLTE 0x1000
- #define PNG_FREE_TRNS 0x2000
- #define PNG_FREE_TEXT 0x4000
- #define PNG_FREE_ALL 0x7fff
- #define PNG_FREE_MUL 0x4220 /* PNG_FREE_SPLT|PNG_FREE_TEXT|PNG_FREE_UNKN */
-
- #ifdef PNG_USER_MEM_SUPPORTED
- extern PNG_EXPORT(png_voidp,png_malloc_default) PNGARG((png_structp png_ptr,
- png_uint_32 size));
- extern PNG_EXPORT(void,png_free_default) PNGARG((png_structp png_ptr,
- png_voidp ptr));
- #endif
-
- extern PNG_EXPORT(png_voidp,png_memcpy_check) PNGARG((png_structp png_ptr,
- png_voidp s1, png_voidp s2, png_uint_32 size));
-
- extern PNG_EXPORT(png_voidp,png_memset_check) PNGARG((png_structp png_ptr,
- png_voidp s1, int value, png_uint_32 size));
-
- #if defined(USE_FAR_KEYWORD) /* memory model conversion function */
- extern void *png_far_to_near PNGARG((png_structp png_ptr,png_voidp ptr,
- int check));
- #endif /* USE_FAR_KEYWORD */
-
- #ifndef PNG_NO_ERROR_TEXT
- /* Fatal error in PNG image of libpng - can't continue */
- extern PNG_EXPORT(void,png_error) PNGARG((png_structp png_ptr,
- png_const_charp error_message));
-
- /* The same, but the chunk name is prepended to the error string. */
- extern PNG_EXPORT(void,png_chunk_error) PNGARG((png_structp png_ptr,
- png_const_charp error_message));
- #else
- /* Fatal error in PNG image of libpng - can't continue */
- extern PNG_EXPORT(void,png_err) PNGARG((png_structp png_ptr));
- #endif
-
- #ifndef PNG_NO_WARNINGS
- /* Non-fatal error in libpng. Can continue, but may have a problem. */
- extern PNG_EXPORT(void,png_warning) PNGARG((png_structp png_ptr,
- png_const_charp warning_message));
-
- #ifdef PNG_READ_SUPPORTED
- /* Non-fatal error in libpng, chunk name is prepended to message. */
- extern PNG_EXPORT(void,png_chunk_warning) PNGARG((png_structp png_ptr,
- png_const_charp warning_message));
- #endif /* PNG_READ_SUPPORTED */
- #endif /* PNG_NO_WARNINGS */
-
- /* The png_set_<chunk> functions are for storing values in the png_info_struct.
- * Similarly, the png_get_<chunk> calls are used to read values from the
- * png_info_struct, either storing the parameters in the passed variables, or
- * setting pointers into the png_info_struct where the data is stored. The
- * png_get_<chunk> functions return a non-zero value if the data was available
- * in info_ptr, or return zero and do not change any of the parameters if the
- * data was not available.
- *
- * These functions should be used instead of directly accessing png_info
- * to avoid problems with future changes in the size and internal layout of
- * png_info_struct.
- */
- /* Returns "flag" if chunk data is valid in info_ptr. */
- extern PNG_EXPORT(png_uint_32,png_get_valid) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_uint_32 flag));
-
- /* Returns number of bytes needed to hold a transformed row. */
- extern PNG_EXPORT(png_uint_32,png_get_rowbytes) PNGARG((png_structp png_ptr,
- png_infop info_ptr));
-
- #if defined(PNG_INFO_IMAGE_SUPPORTED)
- /* Returns row_pointers, which is an array of pointers to scanlines that was
- returned from png_read_png(). */
- extern PNG_EXPORT(png_bytepp,png_get_rows) PNGARG((png_structp png_ptr,
- png_infop info_ptr));
- /* Set row_pointers, which is an array of pointers to scanlines for use
- by png_write_png(). */
- extern PNG_EXPORT(void,png_set_rows) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_bytepp row_pointers));
- #endif
-
- /* Returns number of color channels in image. */
- extern PNG_EXPORT(png_byte,png_get_channels) PNGARG((png_structp png_ptr,
- png_infop info_ptr));
-
- #ifdef PNG_EASY_ACCESS_SUPPORTED
- /* Returns image width in pixels. */
- extern PNG_EXPORT(png_uint_32, png_get_image_width) PNGARG((png_structp
- png_ptr, png_infop info_ptr));
-
- /* Returns image height in pixels. */
- extern PNG_EXPORT(png_uint_32, png_get_image_height) PNGARG((png_structp
- png_ptr, png_infop info_ptr));
-
- /* Returns image bit_depth. */
- extern PNG_EXPORT(png_byte, png_get_bit_depth) PNGARG((png_structp
- png_ptr, png_infop info_ptr));
-
- /* Returns image color_type. */
- extern PNG_EXPORT(png_byte, png_get_color_type) PNGARG((png_structp
- png_ptr, png_infop info_ptr));
-
- /* Returns image filter_type. */
- extern PNG_EXPORT(png_byte, png_get_filter_type) PNGARG((png_structp
- png_ptr, png_infop info_ptr));
-
- /* Returns image interlace_type. */
- extern PNG_EXPORT(png_byte, png_get_interlace_type) PNGARG((png_structp
- png_ptr, png_infop info_ptr));
-
- /* Returns image compression_type. */
- extern PNG_EXPORT(png_byte, png_get_compression_type) PNGARG((png_structp
- png_ptr, png_infop info_ptr));
-
- /* Returns image resolution in pixels per meter, from pHYs chunk data. */
- extern PNG_EXPORT(png_uint_32, png_get_pixels_per_meter) PNGARG((png_structp
- png_ptr, png_infop info_ptr));
- extern PNG_EXPORT(png_uint_32, png_get_x_pixels_per_meter) PNGARG((png_structp
- png_ptr, png_infop info_ptr));
- extern PNG_EXPORT(png_uint_32, png_get_y_pixels_per_meter) PNGARG((png_structp
- png_ptr, png_infop info_ptr));
-
- /* Returns pixel aspect ratio, computed from pHYs chunk data. */
- #ifdef PNG_FLOATING_POINT_SUPPORTED
- extern PNG_EXPORT(float, png_get_pixel_aspect_ratio) PNGARG((png_structp
- png_ptr, png_infop info_ptr));
- #endif
-
- /* Returns image x, y offset in pixels or microns, from oFFs chunk data. */
- extern PNG_EXPORT(png_int_32, png_get_x_offset_pixels) PNGARG((png_structp
- png_ptr, png_infop info_ptr));
- extern PNG_EXPORT(png_int_32, png_get_y_offset_pixels) PNGARG((png_structp
- png_ptr, png_infop info_ptr));
- extern PNG_EXPORT(png_int_32, png_get_x_offset_microns) PNGARG((png_structp
- png_ptr, png_infop info_ptr));
- extern PNG_EXPORT(png_int_32, png_get_y_offset_microns) PNGARG((png_structp
- png_ptr, png_infop info_ptr));
-
- #endif /* PNG_EASY_ACCESS_SUPPORTED */
-
- /* Returns pointer to signature string read from PNG header */
- extern PNG_EXPORT(png_bytep,png_get_signature) PNGARG((png_structp png_ptr,
- png_infop info_ptr));
-
- #if defined(PNG_bKGD_SUPPORTED)
- extern PNG_EXPORT(png_uint_32,png_get_bKGD) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_color_16p *background));
- #endif
-
- #if defined(PNG_bKGD_SUPPORTED)
- extern PNG_EXPORT(void,png_set_bKGD) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_color_16p background));
- #endif
-
- #if defined(PNG_cHRM_SUPPORTED)
- #ifdef PNG_FLOATING_POINT_SUPPORTED
- extern PNG_EXPORT(png_uint_32,png_get_cHRM) PNGARG((png_structp png_ptr,
- png_infop info_ptr, double *white_x, double *white_y, double *red_x,
- double *red_y, double *green_x, double *green_y, double *blue_x,
- double *blue_y));
- #endif
- #ifdef PNG_FIXED_POINT_SUPPORTED
- extern PNG_EXPORT(png_uint_32,png_get_cHRM_fixed) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_fixed_point *int_white_x, png_fixed_point
- *int_white_y, png_fixed_point *int_red_x, png_fixed_point *int_red_y,
- png_fixed_point *int_green_x, png_fixed_point *int_green_y, png_fixed_point
- *int_blue_x, png_fixed_point *int_blue_y));
- #endif
- #endif
-
- #if defined(PNG_cHRM_SUPPORTED)
- #ifdef PNG_FLOATING_POINT_SUPPORTED
- extern PNG_EXPORT(void,png_set_cHRM) PNGARG((png_structp png_ptr,
- png_infop info_ptr, double white_x, double white_y, double red_x,
- double red_y, double green_x, double green_y, double blue_x, double blue_y));
- #endif
- #ifdef PNG_FIXED_POINT_SUPPORTED
- extern PNG_EXPORT(void,png_set_cHRM_fixed) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_fixed_point int_white_x, png_fixed_point int_white_y,
- png_fixed_point int_red_x, png_fixed_point int_red_y, png_fixed_point
- int_green_x, png_fixed_point int_green_y, png_fixed_point int_blue_x,
- png_fixed_point int_blue_y));
- #endif
- #endif
-
- #if defined(PNG_gAMA_SUPPORTED)
- #ifdef PNG_FLOATING_POINT_SUPPORTED
- extern PNG_EXPORT(png_uint_32,png_get_gAMA) PNGARG((png_structp png_ptr,
- png_infop info_ptr, double *file_gamma));
- #endif
- extern PNG_EXPORT(png_uint_32,png_get_gAMA_fixed) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_fixed_point *int_file_gamma));
- #endif
-
- #if defined(PNG_gAMA_SUPPORTED)
- #ifdef PNG_FLOATING_POINT_SUPPORTED
- extern PNG_EXPORT(void,png_set_gAMA) PNGARG((png_structp png_ptr,
- png_infop info_ptr, double file_gamma));
- #endif
- extern PNG_EXPORT(void,png_set_gAMA_fixed) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_fixed_point int_file_gamma));
- #endif
-
- #if defined(PNG_hIST_SUPPORTED)
- extern PNG_EXPORT(png_uint_32,png_get_hIST) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_uint_16p *hist));
- #endif
-
- #if defined(PNG_hIST_SUPPORTED)
- extern PNG_EXPORT(void,png_set_hIST) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_uint_16p hist));
- #endif
-
- extern PNG_EXPORT(png_uint_32,png_get_IHDR) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_uint_32 *width, png_uint_32 *height,
- int *bit_depth, int *color_type, int *interlace_method,
- int *compression_method, int *filter_method));
-
- extern PNG_EXPORT(void,png_set_IHDR) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_uint_32 width, png_uint_32 height, int bit_depth,
- int color_type, int interlace_method, int compression_method,
- int filter_method));
-
- #if defined(PNG_oFFs_SUPPORTED)
- extern PNG_EXPORT(png_uint_32,png_get_oFFs) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_int_32 *offset_x, png_int_32 *offset_y,
- int *unit_type));
- #endif
-
- #if defined(PNG_oFFs_SUPPORTED)
- extern PNG_EXPORT(void,png_set_oFFs) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_int_32 offset_x, png_int_32 offset_y,
- int unit_type));
- #endif
-
- #if defined(PNG_pCAL_SUPPORTED)
- extern PNG_EXPORT(png_uint_32,png_get_pCAL) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_charp *purpose, png_int_32 *X0, png_int_32 *X1,
- int *type, int *nparams, png_charp *units, png_charpp *params));
- #endif
-
- #if defined(PNG_pCAL_SUPPORTED)
- extern PNG_EXPORT(void,png_set_pCAL) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_charp purpose, png_int_32 X0, png_int_32 X1,
- int type, int nparams, png_charp units, png_charpp params));
- #endif
-
- #if defined(PNG_pHYs_SUPPORTED)
- extern PNG_EXPORT(png_uint_32,png_get_pHYs) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type));
- #endif
-
- #if defined(PNG_pHYs_SUPPORTED)
- extern PNG_EXPORT(void,png_set_pHYs) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_uint_32 res_x, png_uint_32 res_y, int unit_type));
- #endif
-
- extern PNG_EXPORT(png_uint_32,png_get_PLTE) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_colorp *palette, int *num_palette));
-
- extern PNG_EXPORT(void,png_set_PLTE) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_colorp palette, int num_palette));
-
- #if defined(PNG_sBIT_SUPPORTED)
- extern PNG_EXPORT(png_uint_32,png_get_sBIT) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_color_8p *sig_bit));
- #endif
-
- #if defined(PNG_sBIT_SUPPORTED)
- extern PNG_EXPORT(void,png_set_sBIT) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_color_8p sig_bit));
- #endif
-
- #if defined(PNG_sRGB_SUPPORTED)
- extern PNG_EXPORT(png_uint_32,png_get_sRGB) PNGARG((png_structp png_ptr,
- png_infop info_ptr, int *intent));
- #endif
-
- #if defined(PNG_sRGB_SUPPORTED)
- extern PNG_EXPORT(void,png_set_sRGB) PNGARG((png_structp png_ptr,
- png_infop info_ptr, int intent));
- extern PNG_EXPORT(void,png_set_sRGB_gAMA_and_cHRM) PNGARG((png_structp png_ptr,
- png_infop info_ptr, int intent));
- #endif
-
- #if defined(PNG_iCCP_SUPPORTED)
- extern PNG_EXPORT(png_uint_32,png_get_iCCP) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_charpp name, int *compression_type,
- png_charpp profile, png_uint_32 *proflen));
- /* Note to maintainer: profile should be png_bytepp */
- #endif
-
- #if defined(PNG_iCCP_SUPPORTED)
- extern PNG_EXPORT(void,png_set_iCCP) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_charp name, int compression_type,
- png_charp profile, png_uint_32 proflen));
- /* Note to maintainer: profile should be png_bytep */
- #endif
-
- #if defined(PNG_sPLT_SUPPORTED)
- extern PNG_EXPORT(png_uint_32,png_get_sPLT) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_sPLT_tpp entries));
- #endif
-
- #if defined(PNG_sPLT_SUPPORTED)
- extern PNG_EXPORT(void,png_set_sPLT) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_sPLT_tp entries, int nentries));
- #endif
-
- #if defined(PNG_TEXT_SUPPORTED)
- /* png_get_text also returns the number of text chunks in *num_text */
- extern PNG_EXPORT(png_uint_32,png_get_text) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_textp *text_ptr, int *num_text));
- #endif
-
- /*
- * Note while png_set_text() will accept a structure whose text,
- * language, and translated keywords are NULL pointers, the structure
- * returned by png_get_text will always contain regular
- * zero-terminated C strings. They might be empty strings but
- * they will never be NULL pointers.
- */
-
- #if defined(PNG_TEXT_SUPPORTED)
- extern PNG_EXPORT(void,png_set_text) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_textp text_ptr, int num_text));
- #endif
-
- #if defined(PNG_tIME_SUPPORTED)
- extern PNG_EXPORT(png_uint_32,png_get_tIME) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_timep *mod_time));
- #endif
-
- #if defined(PNG_tIME_SUPPORTED)
- extern PNG_EXPORT(void,png_set_tIME) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_timep mod_time));
- #endif
-
- #if defined(PNG_tRNS_SUPPORTED)
- extern PNG_EXPORT(png_uint_32,png_get_tRNS) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_bytep *trans, int *num_trans,
- png_color_16p *trans_values));
- #endif
-
- #if defined(PNG_tRNS_SUPPORTED)
- extern PNG_EXPORT(void,png_set_tRNS) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_bytep trans, int num_trans,
- png_color_16p trans_values));
- #endif
-
- #if defined(PNG_tRNS_SUPPORTED)
- #endif
-
- #if defined(PNG_sCAL_SUPPORTED)
- #ifdef PNG_FLOATING_POINT_SUPPORTED
- extern PNG_EXPORT(png_uint_32,png_get_sCAL) PNGARG((png_structp png_ptr,
- png_infop info_ptr, int *unit, double *width, double *height));
- #else
- #ifdef PNG_FIXED_POINT_SUPPORTED
- extern PNG_EXPORT(png_uint_32,png_get_sCAL_s) PNGARG((png_structp png_ptr,
- png_infop info_ptr, int *unit, png_charpp swidth, png_charpp sheight));
- #endif
- #endif
- #endif /* PNG_sCAL_SUPPORTED */
-
- #if defined(PNG_sCAL_SUPPORTED)
- #ifdef PNG_FLOATING_POINT_SUPPORTED
- extern PNG_EXPORT(void,png_set_sCAL) PNGARG((png_structp png_ptr,
- png_infop info_ptr, int unit, double width, double height));
- #else
- #ifdef PNG_FIXED_POINT_SUPPORTED
- extern PNG_EXPORT(void,png_set_sCAL_s) PNGARG((png_structp png_ptr,
- png_infop info_ptr, int unit, png_charp swidth, png_charp sheight));
- #endif
- #endif
- #endif /* PNG_sCAL_SUPPORTED || PNG_WRITE_sCAL_SUPPORTED */
-
- #if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
- /* provide a list of chunks and how they are to be handled, if the built-in
- handling or default unknown chunk handling is not desired. Any chunks not
- listed will be handled in the default manner. The IHDR and IEND chunks
- must not be listed.
- keep = 0: follow default behaviour
- = 1: do not keep
- = 2: keep only if safe-to-copy
- = 3: keep even if unsafe-to-copy
- */
- extern PNG_EXPORT(void, png_set_keep_unknown_chunks) PNGARG((png_structp
- png_ptr, int keep, png_bytep chunk_list, int num_chunks));
- extern PNG_EXPORT(void, png_set_unknown_chunks) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_unknown_chunkp unknowns, int num_unknowns));
- extern PNG_EXPORT(void, png_set_unknown_chunk_location)
- PNGARG((png_structp png_ptr, png_infop info_ptr, int chunk, int location));
- extern PNG_EXPORT(png_uint_32,png_get_unknown_chunks) PNGARG((png_structp
- png_ptr, png_infop info_ptr, png_unknown_chunkpp entries));
- #endif
- #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
- PNG_EXPORT(int,png_handle_as_unknown) PNGARG((png_structp png_ptr, png_bytep
- chunk_name));
- #endif
-
- /* Png_free_data() will turn off the "valid" flag for anything it frees.
- If you need to turn it off for a chunk that your application has freed,
- you can use png_set_invalid(png_ptr, info_ptr, PNG_INFO_CHNK); */
- extern PNG_EXPORT(void, png_set_invalid) PNGARG((png_structp png_ptr,
- png_infop info_ptr, int mask));
-
- #if defined(PNG_INFO_IMAGE_SUPPORTED)
- /* The "params" pointer is currently not used and is for future expansion. */
- extern PNG_EXPORT(void, png_read_png) PNGARG((png_structp png_ptr,
- png_infop info_ptr,
- int transforms,
- png_voidp params));
- extern PNG_EXPORT(void, png_write_png) PNGARG((png_structp png_ptr,
- png_infop info_ptr,
- int transforms,
- png_voidp params));
- #endif
-
- /* Define PNG_DEBUG at compile time for debugging information. Higher
- * numbers for PNG_DEBUG mean more debugging information. This has
- * only been added since version 0.95 so it is not implemented throughout
- * libpng yet, but more support will be added as needed.
- */
- #ifdef PNG_DEBUG
- #if (PNG_DEBUG > 0)
- #if !defined(PNG_DEBUG_FILE) && defined(_MSC_VER)
- #include <crtdbg.h>
- #if (PNG_DEBUG > 1)
- #define png_debug(l,m) _RPT0(_CRT_WARN,m)
- #define png_debug1(l,m,p1) _RPT1(_CRT_WARN,m,p1)
- #define png_debug2(l,m,p1,p2) _RPT2(_CRT_WARN,m,p1,p2)
- #endif
- #else /* PNG_DEBUG_FILE || !_MSC_VER */
- #ifndef PNG_DEBUG_FILE
- #define PNG_DEBUG_FILE stderr
- #endif /* PNG_DEBUG_FILE */
- #if (PNG_DEBUG > 1)
- #define png_debug(l,m) \
- { \
- int num_tabs=l; \
- fprintf(PNG_DEBUG_FILE,"%s"m,(num_tabs==1 ? "\t" : \
- (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":"")))); \
- }
- #define png_debug1(l,m,p1) \
- { \
- int num_tabs=l; \
- fprintf(PNG_DEBUG_FILE,"%s"m,(num_tabs==1 ? "\t" : \
- (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))),p1); \
- }
- #define png_debug2(l,m,p1,p2) \
- { \
- int num_tabs=l; \
- fprintf(PNG_DEBUG_FILE,"%s"m,(num_tabs==1 ? "\t" : \
- (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))),p1,p2); \
- }
- #endif /* (PNG_DEBUG > 1) */
- #endif /* _MSC_VER */
- #endif /* (PNG_DEBUG > 0) */
- #endif /* PNG_DEBUG */
- #ifndef png_debug
- #define png_debug(l, m)
- #endif
- #ifndef png_debug1
- #define png_debug1(l, m, p1)
- #endif
- #ifndef png_debug2
- #define png_debug2(l, m, p1, p2)
- #endif
-
- extern PNG_EXPORT(png_charp,png_get_copyright) PNGARG((png_structp png_ptr));
- extern PNG_EXPORT(png_charp,png_get_header_ver) PNGARG((png_structp png_ptr));
- extern PNG_EXPORT(png_charp,png_get_header_version) PNGARG((png_structp png_ptr));
- extern PNG_EXPORT(png_charp,png_get_libpng_ver) PNGARG((png_structp png_ptr));
-
- #ifdef PNG_MNG_FEATURES_SUPPORTED
- extern PNG_EXPORT(png_uint_32,png_permit_mng_features) PNGARG((png_structp
- png_ptr, png_uint_32 mng_features_permitted));
- #endif
-
- /* For use in png_set_keep_unknown, added to version 1.2.6 */
- #define PNG_HANDLE_CHUNK_AS_DEFAULT 0
- #define PNG_HANDLE_CHUNK_NEVER 1
- #define PNG_HANDLE_CHUNK_IF_SAFE 2
- #define PNG_HANDLE_CHUNK_ALWAYS 3
-
- /* Added to version 1.2.0 */
- #if defined(PNG_ASSEMBLER_CODE_SUPPORTED)
- #if defined(PNG_MMX_CODE_SUPPORTED)
- #define PNG_ASM_FLAG_MMX_SUPPORT_COMPILED 0x01 /* not user-settable */
- #define PNG_ASM_FLAG_MMX_SUPPORT_IN_CPU 0x02 /* not user-settable */
- #define PNG_ASM_FLAG_MMX_READ_COMBINE_ROW 0x04
- #define PNG_ASM_FLAG_MMX_READ_INTERLACE 0x08
- #define PNG_ASM_FLAG_MMX_READ_FILTER_SUB 0x10
- #define PNG_ASM_FLAG_MMX_READ_FILTER_UP 0x20
- #define PNG_ASM_FLAG_MMX_READ_FILTER_AVG 0x40
- #define PNG_ASM_FLAG_MMX_READ_FILTER_PAETH 0x80
- #define PNG_ASM_FLAGS_INITIALIZED 0x80000000 /* not user-settable */
-
- #define PNG_MMX_READ_FLAGS ( PNG_ASM_FLAG_MMX_READ_COMBINE_ROW \
- | PNG_ASM_FLAG_MMX_READ_INTERLACE \
- | PNG_ASM_FLAG_MMX_READ_FILTER_SUB \
- | PNG_ASM_FLAG_MMX_READ_FILTER_UP \
- | PNG_ASM_FLAG_MMX_READ_FILTER_AVG \
- | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH )
- #define PNG_MMX_WRITE_FLAGS ( 0 )
-
- #define PNG_MMX_FLAGS ( PNG_ASM_FLAG_MMX_SUPPORT_COMPILED \
- | PNG_ASM_FLAG_MMX_SUPPORT_IN_CPU \
- | PNG_MMX_READ_FLAGS \
- | PNG_MMX_WRITE_FLAGS )
-
- #define PNG_SELECT_READ 1
- #define PNG_SELECT_WRITE 2
- #endif /* PNG_MMX_CODE_SUPPORTED */
-
- #if !defined(PNG_1_0_X)
- /* pngget.c */
- extern PNG_EXPORT(png_uint_32,png_get_mmx_flagmask)
- PNGARG((int flag_select, int *compilerID));
-
- /* pngget.c */
- extern PNG_EXPORT(png_uint_32,png_get_asm_flagmask)
- PNGARG((int flag_select));
-
- /* pngget.c */
- extern PNG_EXPORT(png_uint_32,png_get_asm_flags)
- PNGARG((png_structp png_ptr));
-
- /* pngget.c */
- extern PNG_EXPORT(png_byte,png_get_mmx_bitdepth_threshold)
- PNGARG((png_structp png_ptr));
-
- /* pngget.c */
- extern PNG_EXPORT(png_uint_32,png_get_mmx_rowbytes_threshold)
- PNGARG((png_structp png_ptr));
-
- /* pngset.c */
- extern PNG_EXPORT(void,png_set_asm_flags)
- PNGARG((png_structp png_ptr, png_uint_32 asm_flags));
-
- /* pngset.c */
- extern PNG_EXPORT(void,png_set_mmx_thresholds)
- PNGARG((png_structp png_ptr, png_byte mmx_bitdepth_threshold,
- png_uint_32 mmx_rowbytes_threshold));
-
- #endif /* PNG_1_0_X */
-
- #if !defined(PNG_1_0_X)
- /* png.c, pnggccrd.c, or pngvcrd.c */
- extern PNG_EXPORT(int,png_mmx_support) PNGARG((void));
- #endif /* PNG_ASSEMBLER_CODE_SUPPORTED */
-
- /* Strip the prepended error numbers ("#nnn ") from error and warning
- * messages before passing them to the error or warning handler. */
- #ifdef PNG_ERROR_NUMBERS_SUPPORTED
- extern PNG_EXPORT(void,png_set_strip_error_numbers) PNGARG((png_structp
- png_ptr, png_uint_32 strip_mode));
- #endif
-
- #endif /* PNG_1_0_X */
-
- /* Added at libpng-1.2.6 */
- #ifdef PNG_SET_USER_LIMITS_SUPPORTED
- extern PNG_EXPORT(void,png_set_user_limits) PNGARG((png_structp
- png_ptr, png_uint_32 user_width_max, png_uint_32 user_height_max));
- extern PNG_EXPORT(png_uint_32,png_get_user_width_max) PNGARG((png_structp
- png_ptr));
- extern PNG_EXPORT(png_uint_32,png_get_user_height_max) PNGARG((png_structp
- png_ptr));
- #endif
-
- /* Maintainer: Put new public prototypes here ^, in libpng.3, and project defs */
-
- #ifdef PNG_READ_COMPOSITE_NODIV_SUPPORTED
- /* With these routines we avoid an integer divide, which will be slower on
- * most machines. However, it does take more operations than the corresponding
- * divide method, so it may be slower on a few RISC systems. There are two
- * shifts (by 8 or 16 bits) and an addition, versus a single integer divide.
- *
- * Note that the rounding factors are NOT supposed to be the same! 128 and
- * 32768 are correct for the NODIV code; 127 and 32767 are correct for the
- * standard method.
- *
- * [Optimized code by Greg Roelofs and Mark Adler...blame us for bugs. :-) ]
- */
-
- /* fg and bg should be in `gamma 1.0' space; alpha is the opacity */
-
- # define png_composite(composite, fg, alpha, bg) \
- { png_uint_16 temp = (png_uint_16)((png_uint_16)(fg) * (png_uint_16)(alpha) \
- + (png_uint_16)(bg)*(png_uint_16)(255 - \
- (png_uint_16)(alpha)) + (png_uint_16)128); \
- (composite) = (png_byte)((temp + (temp >> 8)) >> 8); }
-
- # define png_composite_16(composite, fg, alpha, bg) \
- { png_uint_32 temp = (png_uint_32)((png_uint_32)(fg) * (png_uint_32)(alpha) \
- + (png_uint_32)(bg)*(png_uint_32)(65535L - \
- (png_uint_32)(alpha)) + (png_uint_32)32768L); \
- (composite) = (png_uint_16)((temp + (temp >> 16)) >> 16); }
-
- #else /* standard method using integer division */
-
- # define png_composite(composite, fg, alpha, bg) \
- (composite) = (png_byte)(((png_uint_16)(fg) * (png_uint_16)(alpha) + \
- (png_uint_16)(bg) * (png_uint_16)(255 - (png_uint_16)(alpha)) + \
- (png_uint_16)127) / 255)
-
- # define png_composite_16(composite, fg, alpha, bg) \
- (composite) = (png_uint_16)(((png_uint_32)(fg) * (png_uint_32)(alpha) + \
- (png_uint_32)(bg)*(png_uint_32)(65535L - (png_uint_32)(alpha)) + \
- (png_uint_32)32767) / (png_uint_32)65535L)
-
- #endif /* PNG_READ_COMPOSITE_NODIV_SUPPORTED */
-
- /* Inline macros to do direct reads of bytes from the input buffer. These
- * require that you are using an architecture that uses PNG byte ordering
- * (MSB first) and supports unaligned data storage. I think that PowerPC
- * in big-endian mode and 680x0 are the only ones that will support this.
- * The x86 line of processors definitely do not. The png_get_int_32()
- * routine also assumes we are using two's complement format for negative
- * values, which is almost certainly true.
- */
- #if defined(PNG_READ_BIG_ENDIAN_SUPPORTED)
- # define png_get_uint_32(buf) ( *((png_uint_32p) (buf)))
- # define png_get_uint_16(buf) ( *((png_uint_16p) (buf)))
- # define png_get_int_32(buf) ( *((png_int_32p) (buf)))
- #else
- extern PNG_EXPORT(png_uint_32,png_get_uint_32) PNGARG((png_bytep buf));
- extern PNG_EXPORT(png_uint_16,png_get_uint_16) PNGARG((png_bytep buf));
- extern PNG_EXPORT(png_int_32,png_get_int_32) PNGARG((png_bytep buf));
- #endif /* !PNG_READ_BIG_ENDIAN_SUPPORTED */
- extern PNG_EXPORT(png_uint_32,png_get_uint_31)
- PNGARG((png_structp png_ptr, png_bytep buf));
- /* No png_get_int_16 -- may be added if there's a real need for it. */
-
- /* Place a 32-bit number into a buffer in PNG byte order (big-endian).
- */
- extern PNG_EXPORT(void,png_save_uint_32)
- PNGARG((png_bytep buf, png_uint_32 i));
- extern PNG_EXPORT(void,png_save_int_32)
- PNGARG((png_bytep buf, png_int_32 i));
-
- /* Place a 16-bit number into a buffer in PNG byte order.
- * The parameter is declared unsigned int, not png_uint_16,
- * just to avoid potential problems on pre-ANSI C compilers.
- */
- extern PNG_EXPORT(void,png_save_uint_16)
- PNGARG((png_bytep buf, unsigned int i));
- /* No png_save_int_16 -- may be added if there's a real need for it. */
-
- /* ************************************************************************* */
-
- /* These next functions are used internally in the code. They generally
- * shouldn't be used unless you are writing code to add or replace some
- * functionality in libpng. More information about most functions can
- * be found in the files where the functions are located.
- */
-
- /* Various modes of operation, that are visible to applications because
- * they are used for unknown chunk location.
- */
- #define PNG_HAVE_IHDR 0x01
- #define PNG_HAVE_PLTE 0x02
- #define PNG_HAVE_IDAT 0x04
- #define PNG_AFTER_IDAT 0x08 /* Have complete zlib datastream */
- #define PNG_HAVE_IEND 0x10
-
- #if defined(PNG_INTERNAL)
-
- /* More modes of operation. Note that after an init, mode is set to
- * zero automatically when the structure is created.
- */
- #define PNG_HAVE_gAMA 0x20
- #define PNG_HAVE_cHRM 0x40
- #define PNG_HAVE_sRGB 0x80
- #define PNG_HAVE_CHUNK_HEADER 0x100
- #define PNG_WROTE_tIME 0x200
- #define PNG_WROTE_INFO_BEFORE_PLTE 0x400
- #define PNG_BACKGROUND_IS_GRAY 0x800
- #define PNG_HAVE_PNG_SIGNATURE 0x1000
- #define PNG_HAVE_CHUNK_AFTER_IDAT 0x2000 /* Have another chunk after IDAT */
-
- /* flags for the transformations the PNG library does on the image data */
- #define PNG_BGR 0x0001
- #define PNG_INTERLACE 0x0002
- #define PNG_PACK 0x0004
- #define PNG_SHIFT 0x0008
- #define PNG_SWAP_BYTES 0x0010
- #define PNG_INVERT_MONO 0x0020
- #define PNG_DITHER 0x0040
- #define PNG_BACKGROUND 0x0080
- #define PNG_BACKGROUND_EXPAND 0x0100
- /* 0x0200 unused */
- #define PNG_16_TO_8 0x0400
- #define PNG_RGBA 0x0800
- #define PNG_EXPAND 0x1000
- #define PNG_GAMMA 0x2000
- #define PNG_GRAY_TO_RGB 0x4000
- #define PNG_FILLER 0x8000L
- #define PNG_PACKSWAP 0x10000L
- #define PNG_SWAP_ALPHA 0x20000L
- #define PNG_STRIP_ALPHA 0x40000L
- #define PNG_INVERT_ALPHA 0x80000L
- #define PNG_USER_TRANSFORM 0x100000L
- #define PNG_RGB_TO_GRAY_ERR 0x200000L
- #define PNG_RGB_TO_GRAY_WARN 0x400000L
- #define PNG_RGB_TO_GRAY 0x600000L /* two bits, RGB_TO_GRAY_ERR|WARN */
- /* 0x800000L Unused */
- #define PNG_ADD_ALPHA 0x1000000L /* Added to libpng-1.2.7 */
- #define PNG_EXPAND_tRNS 0x2000000L /* Added to libpng-1.2.9 */
- /* 0x4000000L unused */
- /* 0x8000000L unused */
- /* 0x10000000L unused */
- /* 0x20000000L unused */
- /* 0x40000000L unused */
-
- /* flags for png_create_struct */
- #define PNG_STRUCT_PNG 0x0001
- #define PNG_STRUCT_INFO 0x0002
-
- /* Scaling factor for filter heuristic weighting calculations */
- #define PNG_WEIGHT_SHIFT 8
- #define PNG_WEIGHT_FACTOR (1<<(PNG_WEIGHT_SHIFT))
- #define PNG_COST_SHIFT 3
- #define PNG_COST_FACTOR (1<<(PNG_COST_SHIFT))
-
- /* flags for the png_ptr->flags rather than declaring a byte for each one */
- #define PNG_FLAG_ZLIB_CUSTOM_STRATEGY 0x0001
- #define PNG_FLAG_ZLIB_CUSTOM_LEVEL 0x0002
- #define PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL 0x0004
- #define PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS 0x0008
- #define PNG_FLAG_ZLIB_CUSTOM_METHOD 0x0010
- #define PNG_FLAG_ZLIB_FINISHED 0x0020
- #define PNG_FLAG_ROW_INIT 0x0040
- #define PNG_FLAG_FILLER_AFTER 0x0080
- #define PNG_FLAG_CRC_ANCILLARY_USE 0x0100
- #define PNG_FLAG_CRC_ANCILLARY_NOWARN 0x0200
- #define PNG_FLAG_CRC_CRITICAL_USE 0x0400
- #define PNG_FLAG_CRC_CRITICAL_IGNORE 0x0800
- #define PNG_FLAG_FREE_PLTE 0x1000
- #define PNG_FLAG_FREE_TRNS 0x2000
- #define PNG_FLAG_FREE_HIST 0x4000
- #define PNG_FLAG_KEEP_UNKNOWN_CHUNKS 0x8000L
- #define PNG_FLAG_KEEP_UNSAFE_CHUNKS 0x10000L
- #define PNG_FLAG_LIBRARY_MISMATCH 0x20000L
- #define PNG_FLAG_STRIP_ERROR_NUMBERS 0x40000L
- #define PNG_FLAG_STRIP_ERROR_TEXT 0x80000L
- #define PNG_FLAG_MALLOC_NULL_MEM_OK 0x100000L
- #define PNG_FLAG_ADD_ALPHA 0x200000L /* Added to libpng-1.2.8 */
- #define PNG_FLAG_STRIP_ALPHA 0x400000L /* Added to libpng-1.2.8 */
- /* 0x800000L unused */
- /* 0x1000000L unused */
- /* 0x2000000L unused */
- /* 0x4000000L unused */
- /* 0x8000000L unused */
- /* 0x10000000L unused */
- /* 0x20000000L unused */
- /* 0x40000000L unused */
-
- #define PNG_FLAG_CRC_ANCILLARY_MASK (PNG_FLAG_CRC_ANCILLARY_USE | \
- PNG_FLAG_CRC_ANCILLARY_NOWARN)
-
- #define PNG_FLAG_CRC_CRITICAL_MASK (PNG_FLAG_CRC_CRITICAL_USE | \
- PNG_FLAG_CRC_CRITICAL_IGNORE)
-
- #define PNG_FLAG_CRC_MASK (PNG_FLAG_CRC_ANCILLARY_MASK | \
- PNG_FLAG_CRC_CRITICAL_MASK)
-
- /* save typing and make code easier to understand */
-
- #define PNG_COLOR_DIST(c1, c2) (abs((int)((c1).red) - (int)((c2).red)) + \
- abs((int)((c1).green) - (int)((c2).green)) + \
- abs((int)((c1).blue) - (int)((c2).blue)))
-
- /* Added to libpng-1.2.6 JB */
- #define PNG_ROWBYTES(pixel_bits, width) \
- ((pixel_bits) >= 8 ? \
- ((width) * (((png_uint_32)(pixel_bits)) >> 3)) : \
- (( ((width) * ((png_uint_32)(pixel_bits))) + 7) >> 3) )
-
- /* PNG_OUT_OF_RANGE returns true if value is outside the range
- ideal-delta..ideal+delta. Each argument is evaluated twice.
- "ideal" and "delta" should be constants, normally simple
- integers, "value" a variable. Added to libpng-1.2.6 JB */
- #define PNG_OUT_OF_RANGE(value, ideal, delta) \
- ( (value) < (ideal)-(delta) || (value) > (ideal)+(delta) )
-
- /* variables declared in png.c - only it needs to define PNG_NO_EXTERN */
- #if !defined(PNG_NO_EXTERN) || defined(PNG_ALWAYS_EXTERN)
- /* place to hold the signature string for a PNG file. */
- #ifdef PNG_USE_GLOBAL_ARRAYS
- PNG_EXPORT_VAR (PNG_CONST png_byte FARDATA) png_sig[8];
- #else
- #endif
- #endif /* PNG_NO_EXTERN */
-
- /* Constant strings for known chunk types. If you need to add a chunk,
- * define the name here, and add an invocation of the macro in png.c and
- * wherever it's needed.
- */
- #define PNG_IHDR png_byte png_IHDR[5] = { 73, 72, 68, 82, '\0'}
- #define PNG_IDAT png_byte png_IDAT[5] = { 73, 68, 65, 84, '\0'}
- #define PNG_IEND png_byte png_IEND[5] = { 73, 69, 78, 68, '\0'}
- #define PNG_PLTE png_byte png_PLTE[5] = { 80, 76, 84, 69, '\0'}
- #define PNG_bKGD png_byte png_bKGD[5] = { 98, 75, 71, 68, '\0'}
- #define PNG_cHRM png_byte png_cHRM[5] = { 99, 72, 82, 77, '\0'}
- #define PNG_gAMA png_byte png_gAMA[5] = {103, 65, 77, 65, '\0'}
- #define PNG_hIST png_byte png_hIST[5] = {104, 73, 83, 84, '\0'}
- #define PNG_iCCP png_byte png_iCCP[5] = {105, 67, 67, 80, '\0'}
- #define PNG_iTXt png_byte png_iTXt[5] = {105, 84, 88, 116, '\0'}
- #define PNG_oFFs png_byte png_oFFs[5] = {111, 70, 70, 115, '\0'}
- #define PNG_pCAL png_byte png_pCAL[5] = {112, 67, 65, 76, '\0'}
- #define PNG_sCAL png_byte png_sCAL[5] = {115, 67, 65, 76, '\0'}
- #define PNG_pHYs png_byte png_pHYs[5] = {112, 72, 89, 115, '\0'}
- #define PNG_sBIT png_byte png_sBIT[5] = {115, 66, 73, 84, '\0'}
- #define PNG_sPLT png_byte png_sPLT[5] = {115, 80, 76, 84, '\0'}
- #define PNG_sRGB png_byte png_sRGB[5] = {115, 82, 71, 66, '\0'}
- #define PNG_tEXt png_byte png_tEXt[5] = {116, 69, 88, 116, '\0'}
- #define PNG_tIME png_byte png_tIME[5] = {116, 73, 77, 69, '\0'}
- #define PNG_tRNS png_byte png_tRNS[5] = {116, 82, 78, 83, '\0'}
- #define PNG_zTXt png_byte png_zTXt[5] = {122, 84, 88, 116, '\0'}
-
- #ifdef PNG_USE_GLOBAL_ARRAYS
- PNG_EXPORT_VAR (png_byte FARDATA) png_IHDR[5];
- PNG_EXPORT_VAR (png_byte FARDATA) png_IDAT[5];
- PNG_EXPORT_VAR (png_byte FARDATA) png_IEND[5];
- PNG_EXPORT_VAR (png_byte FARDATA) png_PLTE[5];
- PNG_EXPORT_VAR (png_byte FARDATA) png_bKGD[5];
- PNG_EXPORT_VAR (png_byte FARDATA) png_cHRM[5];
- PNG_EXPORT_VAR (png_byte FARDATA) png_gAMA[5];
- PNG_EXPORT_VAR (png_byte FARDATA) png_hIST[5];
- PNG_EXPORT_VAR (png_byte FARDATA) png_iCCP[5];
- PNG_EXPORT_VAR (png_byte FARDATA) png_iTXt[5];
- PNG_EXPORT_VAR (png_byte FARDATA) png_oFFs[5];
- PNG_EXPORT_VAR (png_byte FARDATA) png_pCAL[5];
- PNG_EXPORT_VAR (png_byte FARDATA) png_sCAL[5];
- PNG_EXPORT_VAR (png_byte FARDATA) png_pHYs[5];
- PNG_EXPORT_VAR (png_byte FARDATA) png_sBIT[5];
- PNG_EXPORT_VAR (png_byte FARDATA) png_sPLT[5];
- PNG_EXPORT_VAR (png_byte FARDATA) png_sRGB[5];
- PNG_EXPORT_VAR (png_byte FARDATA) png_tEXt[5];
- PNG_EXPORT_VAR (png_byte FARDATA) png_tIME[5];
- PNG_EXPORT_VAR (png_byte FARDATA) png_tRNS[5];
- PNG_EXPORT_VAR (png_byte FARDATA) png_zTXt[5];
- #endif /* PNG_USE_GLOBAL_ARRAYS */
-
- #if defined(PNG_1_0_X) || defined (PNG_1_2_X)
- /* Initialize png_ptr struct for reading, and allocate any other memory.
- * (old interface - DEPRECATED - use png_create_read_struct instead).
- */
- extern PNG_EXPORT(void,png_read_init) PNGARG((png_structp png_ptr));
- #undef png_read_init
- #define png_read_init(png_ptr) png_read_init_3(&png_ptr, \
- PNG_LIBPNG_VER_STRING, png_sizeof(png_struct));
- #endif
-
- extern PNG_EXPORT(void,png_read_init_3) PNGARG((png_structpp ptr_ptr,
- png_const_charp user_png_ver, png_size_t png_struct_size));
- #if defined(PNG_1_0_X) || defined (PNG_1_2_X)
- extern PNG_EXPORT(void,png_read_init_2) PNGARG((png_structp png_ptr,
- png_const_charp user_png_ver, png_size_t png_struct_size, png_size_t
- png_info_size));
- #endif
-
- #if defined(PNG_1_0_X) || defined (PNG_1_2_X)
- /* Initialize png_ptr struct for writing, and allocate any other memory.
- * (old interface - DEPRECATED - use png_create_write_struct instead).
- */
- extern PNG_EXPORT(void,png_write_init) PNGARG((png_structp png_ptr));
- #undef png_write_init
- #define png_write_init(png_ptr) png_write_init_3(&png_ptr, \
- PNG_LIBPNG_VER_STRING, png_sizeof(png_struct));
- #endif
-
- extern PNG_EXPORT(void,png_write_init_3) PNGARG((png_structpp ptr_ptr,
- png_const_charp user_png_ver, png_size_t png_struct_size));
- extern PNG_EXPORT(void,png_write_init_2) PNGARG((png_structp png_ptr,
- png_const_charp user_png_ver, png_size_t png_struct_size, png_size_t
- png_info_size));
-
- /* Allocate memory for an internal libpng struct */
- PNG_EXTERN png_voidp png_create_struct PNGARG((int type));
-
- /* Free memory from internal libpng struct */
- PNG_EXTERN void png_destroy_struct PNGARG((png_voidp struct_ptr));
-
- PNG_EXTERN png_voidp png_create_struct_2 PNGARG((int type, png_malloc_ptr
- malloc_fn, png_voidp mem_ptr));
- PNG_EXTERN void png_destroy_struct_2 PNGARG((png_voidp struct_ptr,
- png_free_ptr free_fn, png_voidp mem_ptr));
-
- /* Free any memory that info_ptr points to and reset struct. */
- PNG_EXTERN void png_info_destroy PNGARG((png_structp png_ptr,
- png_infop info_ptr));
-
- #ifndef PNG_1_0_X
- /* Function to allocate memory for zlib. */
- PNG_EXTERN voidpf png_zalloc PNGARG((voidpf png_ptr, uInt items, uInt size));
-
- /* Function to free memory for zlib */
- PNG_EXTERN void png_zfree PNGARG((voidpf png_ptr, voidpf ptr));
-
- #ifdef PNG_SIZE_T
- /* Function to convert a sizeof an item to png_sizeof item */
- PNG_EXTERN png_size_t PNGAPI png_convert_size PNGARG((size_t size));
- #endif
-
- /* Next four functions are used internally as callbacks. PNGAPI is required
- * but not PNG_EXPORT. PNGAPI added at libpng version 1.2.3. */
-
- PNG_EXTERN void PNGAPI png_default_read_data PNGARG((png_structp png_ptr,
- png_bytep data, png_size_t length));
-
- #ifdef PNG_PROGRESSIVE_READ_SUPPORTED
- PNG_EXTERN void PNGAPI png_push_fill_buffer PNGARG((png_structp png_ptr,
- png_bytep buffer, png_size_t length));
- #endif
-
- PNG_EXTERN void PNGAPI png_default_write_data PNGARG((png_structp png_ptr,
- png_bytep data, png_size_t length));
-
- #if defined(PNG_WRITE_FLUSH_SUPPORTED)
- #if !defined(PNG_NO_STDIO)
- PNG_EXTERN void PNGAPI png_default_flush PNGARG((png_structp png_ptr));
- #endif
- #endif
- #else /* PNG_1_0_X */
- #ifdef PNG_PROGRESSIVE_READ_SUPPORTED
- PNG_EXTERN void png_push_fill_buffer PNGARG((png_structp png_ptr,
- png_bytep buffer, png_size_t length));
- #endif
- #endif /* PNG_1_0_X */
-
- /* Reset the CRC variable */
- PNG_EXTERN void png_reset_crc PNGARG((png_structp png_ptr));
-
- /* Write the "data" buffer to whatever output you are using. */
- PNG_EXTERN void png_write_data PNGARG((png_structp png_ptr, png_bytep data,
- png_size_t length));
-
- /* Read data from whatever input you are using into the "data" buffer */
- PNG_EXTERN void png_read_data PNGARG((png_structp png_ptr, png_bytep data,
- png_size_t length));
-
- /* Read bytes into buf, and update png_ptr->crc */
- PNG_EXTERN void png_crc_read PNGARG((png_structp png_ptr, png_bytep buf,
- png_size_t length));
-
- /* Decompress data in a chunk that uses compression */
- #if defined(PNG_zTXt_SUPPORTED) || defined(PNG_iTXt_SUPPORTED) || \
- defined(PNG_iCCP_SUPPORTED) || defined(PNG_sPLT_SUPPORTED)
- PNG_EXTERN png_charp png_decompress_chunk PNGARG((png_structp png_ptr,
- int comp_type, png_charp chunkdata, png_size_t chunklength,
- png_size_t prefix_length, png_size_t *data_length));
- #endif
-
- /* Read "skip" bytes, read the file crc, and (optionally) verify png_ptr->crc */
- PNG_EXTERN int png_crc_finish PNGARG((png_structp png_ptr, png_uint_32 skip));
-
- /* Read the CRC from the file and compare it to the libpng calculated CRC */
- PNG_EXTERN int png_crc_error PNGARG((png_structp png_ptr));
-
- /* Calculate the CRC over a section of data. Note that we are only
- * passing a maximum of 64K on systems that have this as a memory limit,
- * since this is the maximum buffer size we can specify.
- */
- PNG_EXTERN void png_calculate_crc PNGARG((png_structp png_ptr, png_bytep ptr,
- png_size_t length));
-
- #if defined(PNG_WRITE_FLUSH_SUPPORTED)
- PNG_EXTERN void png_flush PNGARG((png_structp png_ptr));
- #endif
-
- /* simple function to write the signature */
- PNG_EXTERN void png_write_sig PNGARG((png_structp png_ptr));
-
- /* write various chunks */
-
- /* Write the IHDR chunk, and update the png_struct with the necessary
- * information.
- */
- PNG_EXTERN void png_write_IHDR PNGARG((png_structp png_ptr, png_uint_32 width,
- png_uint_32 height,
- int bit_depth, int color_type, int compression_method, int filter_method,
- int interlace_method));
-
- PNG_EXTERN void png_write_PLTE PNGARG((png_structp png_ptr, png_colorp palette,
- png_uint_32 num_pal));
-
- PNG_EXTERN void png_write_IDAT PNGARG((png_structp png_ptr, png_bytep data,
- png_size_t length));
-
- PNG_EXTERN void png_write_IEND PNGARG((png_structp png_ptr));
-
- #if defined(PNG_WRITE_gAMA_SUPPORTED)
- #ifdef PNG_FLOATING_POINT_SUPPORTED
- PNG_EXTERN void png_write_gAMA PNGARG((png_structp png_ptr, double file_gamma));
- #endif
- #ifdef PNG_FIXED_POINT_SUPPORTED
- PNG_EXTERN void png_write_gAMA_fixed PNGARG((png_structp png_ptr, png_fixed_point
- file_gamma));
- #endif
- #endif
-
- #if defined(PNG_WRITE_sBIT_SUPPORTED)
- PNG_EXTERN void png_write_sBIT PNGARG((png_structp png_ptr, png_color_8p sbit,
- int color_type));
- #endif
-
- #if defined(PNG_WRITE_cHRM_SUPPORTED)
- #ifdef PNG_FLOATING_POINT_SUPPORTED
- PNG_EXTERN void png_write_cHRM PNGARG((png_structp png_ptr,
- double white_x, double white_y,
- double red_x, double red_y, double green_x, double green_y,
- double blue_x, double blue_y));
- #endif
- #ifdef PNG_FIXED_POINT_SUPPORTED
- PNG_EXTERN void png_write_cHRM_fixed PNGARG((png_structp png_ptr,
- png_fixed_point int_white_x, png_fixed_point int_white_y,
- png_fixed_point int_red_x, png_fixed_point int_red_y, png_fixed_point
- int_green_x, png_fixed_point int_green_y, png_fixed_point int_blue_x,
- png_fixed_point int_blue_y));
- #endif
- #endif
-
- #if defined(PNG_WRITE_sRGB_SUPPORTED)
- PNG_EXTERN void png_write_sRGB PNGARG((png_structp png_ptr,
- int intent));
- #endif
-
- #if defined(PNG_WRITE_iCCP_SUPPORTED)
- PNG_EXTERN void png_write_iCCP PNGARG((png_structp png_ptr,
- png_charp name, int compression_type,
- png_charp profile, int proflen));
- /* Note to maintainer: profile should be png_bytep */
- #endif
-
- #if defined(PNG_WRITE_sPLT_SUPPORTED)
- PNG_EXTERN void png_write_sPLT PNGARG((png_structp png_ptr,
- png_sPLT_tp palette));
- #endif
-
- #if defined(PNG_WRITE_tRNS_SUPPORTED)
- PNG_EXTERN void png_write_tRNS PNGARG((png_structp png_ptr, png_bytep trans,
- png_color_16p values, int number, int color_type));
- #endif
-
- #if defined(PNG_WRITE_bKGD_SUPPORTED)
- PNG_EXTERN void png_write_bKGD PNGARG((png_structp png_ptr,
- png_color_16p values, int color_type));
- #endif
-
- #if defined(PNG_WRITE_hIST_SUPPORTED)
- PNG_EXTERN void png_write_hIST PNGARG((png_structp png_ptr, png_uint_16p hist,
- int num_hist));
- #endif
-
- #if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED) || \
- defined(PNG_WRITE_iCCP_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED)
- PNG_EXTERN png_size_t png_check_keyword PNGARG((png_structp png_ptr,
- png_charp key, png_charpp new_key));
- #endif
-
- #if defined(PNG_WRITE_tEXt_SUPPORTED)
- PNG_EXTERN void png_write_tEXt PNGARG((png_structp png_ptr, png_charp key,
- png_charp text, png_size_t text_len));
- #endif
-
- #if defined(PNG_WRITE_zTXt_SUPPORTED)
- PNG_EXTERN void png_write_zTXt PNGARG((png_structp png_ptr, png_charp key,
- png_charp text, png_size_t text_len, int compression));
- #endif
-
- #if defined(PNG_WRITE_iTXt_SUPPORTED)
- PNG_EXTERN void png_write_iTXt PNGARG((png_structp png_ptr,
- int compression, png_charp key, png_charp lang, png_charp lang_key,
- png_charp text));
- #endif
-
- #if defined(PNG_TEXT_SUPPORTED) /* Added at version 1.0.14 and 1.2.4 */
- PNG_EXTERN int png_set_text_2 PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_textp text_ptr, int num_text));
- #endif
-
- #if defined(PNG_WRITE_oFFs_SUPPORTED)
- PNG_EXTERN void png_write_oFFs PNGARG((png_structp png_ptr,
- png_int_32 x_offset, png_int_32 y_offset, int unit_type));
- #endif
-
- #if defined(PNG_WRITE_pCAL_SUPPORTED)
- PNG_EXTERN void png_write_pCAL PNGARG((png_structp png_ptr, png_charp purpose,
- png_int_32 X0, png_int_32 X1, int type, int nparams,
- png_charp units, png_charpp params));
- #endif
-
- #if defined(PNG_WRITE_pHYs_SUPPORTED)
- PNG_EXTERN void png_write_pHYs PNGARG((png_structp png_ptr,
- png_uint_32 x_pixels_per_unit, png_uint_32 y_pixels_per_unit,
- int unit_type));
- #endif
-
- #if defined(PNG_WRITE_tIME_SUPPORTED)
- PNG_EXTERN void png_write_tIME PNGARG((png_structp png_ptr,
- png_timep mod_time));
- #endif
-
- #if defined(PNG_WRITE_sCAL_SUPPORTED)
- #if defined(PNG_FLOATING_POINT_SUPPORTED) && !defined(PNG_NO_STDIO)
- PNG_EXTERN void png_write_sCAL PNGARG((png_structp png_ptr,
- int unit, double width, double height));
- #else
- #ifdef PNG_FIXED_POINT_SUPPORTED
- PNG_EXTERN void png_write_sCAL_s PNGARG((png_structp png_ptr,
- int unit, png_charp width, png_charp height));
- #endif
- #endif
- #endif
-
- /* Called when finished processing a row of data */
- PNG_EXTERN void png_write_finish_row PNGARG((png_structp png_ptr));
-
- /* Internal use only. Called before first row of data */
- PNG_EXTERN void png_write_start_row PNGARG((png_structp png_ptr));
-
- #if defined(PNG_READ_GAMMA_SUPPORTED)
- PNG_EXTERN void png_build_gamma_table PNGARG((png_structp png_ptr));
- #endif
-
- /* combine a row of data, dealing with alpha, etc. if requested */
- PNG_EXTERN void png_combine_row PNGARG((png_structp png_ptr, png_bytep row,
- int mask));
-
- #if defined(PNG_READ_INTERLACING_SUPPORTED)
- /* expand an interlaced row */
- /* OLD pre-1.0.9 interface:
- PNG_EXTERN void png_do_read_interlace PNGARG((png_row_infop row_info,
- png_bytep row, int pass, png_uint_32 transformations));
- */
- PNG_EXTERN void png_do_read_interlace PNGARG((png_structp png_ptr));
- #endif
-
- /* GRR TO DO (2.0 or whenever): simplify other internal calling interfaces */
-
- #if defined(PNG_WRITE_INTERLACING_SUPPORTED)
- /* grab pixels out of a row for an interlaced pass */
- PNG_EXTERN void png_do_write_interlace PNGARG((png_row_infop row_info,
- png_bytep row, int pass));
- #endif
-
- /* unfilter a row */
- PNG_EXTERN void png_read_filter_row PNGARG((png_structp png_ptr,
- png_row_infop row_info, png_bytep row, png_bytep prev_row, int filter));
-
- /* Choose the best filter to use and filter the row data */
- PNG_EXTERN void png_write_find_filter PNGARG((png_structp png_ptr,
- png_row_infop row_info));
-
- /* Write out the filtered row. */
- PNG_EXTERN void png_write_filtered_row PNGARG((png_structp png_ptr,
- png_bytep filtered_row));
- /* finish a row while reading, dealing with interlacing passes, etc. */
- PNG_EXTERN void png_read_finish_row PNGARG((png_structp png_ptr));
-
- /* initialize the row buffers, etc. */
- PNG_EXTERN void png_read_start_row PNGARG((png_structp png_ptr));
- /* optional call to update the users info structure */
- PNG_EXTERN void png_read_transform_info PNGARG((png_structp png_ptr,
- png_infop info_ptr));
-
- /* these are the functions that do the transformations */
- #if defined(PNG_READ_FILLER_SUPPORTED)
- PNG_EXTERN void png_do_read_filler PNGARG((png_row_infop row_info,
- png_bytep row, png_uint_32 filler, png_uint_32 flags));
- #endif
-
- #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
- PNG_EXTERN void png_do_read_swap_alpha PNGARG((png_row_infop row_info,
- png_bytep row));
- #endif
-
- #if defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
- PNG_EXTERN void png_do_write_swap_alpha PNGARG((png_row_infop row_info,
- png_bytep row));
- #endif
-
- #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
- PNG_EXTERN void png_do_read_invert_alpha PNGARG((png_row_infop row_info,
- png_bytep row));
- #endif
-
- #if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
- PNG_EXTERN void png_do_write_invert_alpha PNGARG((png_row_infop row_info,
- png_bytep row));
- #endif
-
- #if defined(PNG_WRITE_FILLER_SUPPORTED) || \
- defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
- PNG_EXTERN void png_do_strip_filler PNGARG((png_row_infop row_info,
- png_bytep row, png_uint_32 flags));
- #endif
-
- #if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
- PNG_EXTERN void png_do_swap PNGARG((png_row_infop row_info, png_bytep row));
- #endif
-
- #if defined(PNG_READ_PACKSWAP_SUPPORTED) || defined(PNG_WRITE_PACKSWAP_SUPPORTED)
- PNG_EXTERN void png_do_packswap PNGARG((png_row_infop row_info, png_bytep row));
- #endif
-
- #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
- PNG_EXTERN int png_do_rgb_to_gray PNGARG((png_structp png_ptr, png_row_infop
- row_info, png_bytep row));
- #endif
-
- #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
- PNG_EXTERN void png_do_gray_to_rgb PNGARG((png_row_infop row_info,
- png_bytep row));
- #endif
-
- #if defined(PNG_READ_PACK_SUPPORTED)
- PNG_EXTERN void png_do_unpack PNGARG((png_row_infop row_info, png_bytep row));
- #endif
-
- #if defined(PNG_READ_SHIFT_SUPPORTED)
- PNG_EXTERN void png_do_unshift PNGARG((png_row_infop row_info, png_bytep row,
- png_color_8p sig_bits));
- #endif
-
- #if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
- PNG_EXTERN void png_do_invert PNGARG((png_row_infop row_info, png_bytep row));
- #endif
-
- #if defined(PNG_READ_16_TO_8_SUPPORTED)
- PNG_EXTERN void png_do_chop PNGARG((png_row_infop row_info, png_bytep row));
- #endif
-
- #if defined(PNG_READ_DITHER_SUPPORTED)
- PNG_EXTERN void png_do_dither PNGARG((png_row_infop row_info,
- png_bytep row, png_bytep palette_lookup, png_bytep dither_lookup));
-
- # if defined(PNG_CORRECT_PALETTE_SUPPORTED)
- PNG_EXTERN void png_correct_palette PNGARG((png_structp png_ptr,
- png_colorp palette, int num_palette));
- # endif
- #endif
-
- #if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
- PNG_EXTERN void png_do_bgr PNGARG((png_row_infop row_info, png_bytep row));
- #endif
-
- #if defined(PNG_WRITE_PACK_SUPPORTED)
- PNG_EXTERN void png_do_pack PNGARG((png_row_infop row_info,
- png_bytep row, png_uint_32 bit_depth));
- #endif
-
- #if defined(PNG_WRITE_SHIFT_SUPPORTED)
- PNG_EXTERN void png_do_shift PNGARG((png_row_infop row_info, png_bytep row,
- png_color_8p bit_depth));
- #endif
-
- #if defined(PNG_READ_BACKGROUND_SUPPORTED)
- #if defined(PNG_READ_GAMMA_SUPPORTED)
- PNG_EXTERN void png_do_background PNGARG((png_row_infop row_info, png_bytep row,
- png_color_16p trans_values, png_color_16p background,
- png_color_16p background_1,
- png_bytep gamma_table, png_bytep gamma_from_1, png_bytep gamma_to_1,
- png_uint_16pp gamma_16, png_uint_16pp gamma_16_from_1,
- png_uint_16pp gamma_16_to_1, int gamma_shift));
- #else
- PNG_EXTERN void png_do_background PNGARG((png_row_infop row_info, png_bytep row,
- png_color_16p trans_values, png_color_16p background));
- #endif
- #endif
-
- #if defined(PNG_READ_GAMMA_SUPPORTED)
- PNG_EXTERN void png_do_gamma PNGARG((png_row_infop row_info, png_bytep row,
- png_bytep gamma_table, png_uint_16pp gamma_16_table,
- int gamma_shift));
- #endif
-
- #if defined(PNG_READ_EXPAND_SUPPORTED)
- PNG_EXTERN void png_do_expand_palette PNGARG((png_row_infop row_info,
- png_bytep row, png_colorp palette, png_bytep trans, int num_trans));
- PNG_EXTERN void png_do_expand PNGARG((png_row_infop row_info,
- png_bytep row, png_color_16p trans_value));
- #endif
-
- /* The following decodes the appropriate chunks, and does error correction,
- * then calls the appropriate callback for the chunk if it is valid.
- */
-
- /* decode the IHDR chunk */
- PNG_EXTERN void png_handle_IHDR PNGARG((png_structp png_ptr, png_infop info_ptr,
- png_uint_32 length));
- PNG_EXTERN void png_handle_PLTE PNGARG((png_structp png_ptr, png_infop info_ptr,
- png_uint_32 length));
- PNG_EXTERN void png_handle_IEND PNGARG((png_structp png_ptr, png_infop info_ptr,
- png_uint_32 length));
-
- #if defined(PNG_READ_bKGD_SUPPORTED)
- PNG_EXTERN void png_handle_bKGD PNGARG((png_structp png_ptr, png_infop info_ptr,
- png_uint_32 length));
- #endif
-
- #if defined(PNG_READ_cHRM_SUPPORTED)
- PNG_EXTERN void png_handle_cHRM PNGARG((png_structp png_ptr, png_infop info_ptr,
- png_uint_32 length));
- #endif
-
- #if defined(PNG_READ_gAMA_SUPPORTED)
- PNG_EXTERN void png_handle_gAMA PNGARG((png_structp png_ptr, png_infop info_ptr,
- png_uint_32 length));
- #endif
-
- #if defined(PNG_READ_hIST_SUPPORTED)
- PNG_EXTERN void png_handle_hIST PNGARG((png_structp png_ptr, png_infop info_ptr,
- png_uint_32 length));
- #endif
-
- #if defined(PNG_READ_iCCP_SUPPORTED)
- extern void png_handle_iCCP PNGARG((png_structp png_ptr, png_infop info_ptr,
- png_uint_32 length));
- #endif /* PNG_READ_iCCP_SUPPORTED */
-
- #if defined(PNG_READ_iTXt_SUPPORTED)
- PNG_EXTERN void png_handle_iTXt PNGARG((png_structp png_ptr, png_infop info_ptr,
- png_uint_32 length));
- #endif
-
- #if defined(PNG_READ_oFFs_SUPPORTED)
- PNG_EXTERN void png_handle_oFFs PNGARG((png_structp png_ptr, png_infop info_ptr,
- png_uint_32 length));
- #endif
-
- #if defined(PNG_READ_pCAL_SUPPORTED)
- PNG_EXTERN void png_handle_pCAL PNGARG((png_structp png_ptr, png_infop info_ptr,
- png_uint_32 length));
- #endif
-
- #if defined(PNG_READ_pHYs_SUPPORTED)
- PNG_EXTERN void png_handle_pHYs PNGARG((png_structp png_ptr, png_infop info_ptr,
- png_uint_32 length));
- #endif
-
- #if defined(PNG_READ_sBIT_SUPPORTED)
- PNG_EXTERN void png_handle_sBIT PNGARG((png_structp png_ptr, png_infop info_ptr,
- png_uint_32 length));
- #endif
-
- #if defined(PNG_READ_sCAL_SUPPORTED)
- PNG_EXTERN void png_handle_sCAL PNGARG((png_structp png_ptr, png_infop info_ptr,
- png_uint_32 length));
- #endif
-
- #if defined(PNG_READ_sPLT_SUPPORTED)
- extern void png_handle_sPLT PNGARG((png_structp png_ptr, png_infop info_ptr,
- png_uint_32 length));
- #endif /* PNG_READ_sPLT_SUPPORTED */
-
- #if defined(PNG_READ_sRGB_SUPPORTED)
- PNG_EXTERN void png_handle_sRGB PNGARG((png_structp png_ptr, png_infop info_ptr,
- png_uint_32 length));
- #endif
-
- #if defined(PNG_READ_tEXt_SUPPORTED)
- PNG_EXTERN void png_handle_tEXt PNGARG((png_structp png_ptr, png_infop info_ptr,
- png_uint_32 length));
- #endif
-
- #if defined(PNG_READ_tIME_SUPPORTED)
- PNG_EXTERN void png_handle_tIME PNGARG((png_structp png_ptr, png_infop info_ptr,
- png_uint_32 length));
- #endif
-
- #if defined(PNG_READ_tRNS_SUPPORTED)
- PNG_EXTERN void png_handle_tRNS PNGARG((png_structp png_ptr, png_infop info_ptr,
- png_uint_32 length));
- #endif
-
- #if defined(PNG_READ_zTXt_SUPPORTED)
- PNG_EXTERN void png_handle_zTXt PNGARG((png_structp png_ptr, png_infop info_ptr,
- png_uint_32 length));
- #endif
-
- PNG_EXTERN void png_handle_unknown PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_uint_32 length));
-
- PNG_EXTERN void png_check_chunk_name PNGARG((png_structp png_ptr,
- png_bytep chunk_name));
-
- /* handle the transformations for reading and writing */
- PNG_EXTERN void png_do_read_transformations PNGARG((png_structp png_ptr));
- PNG_EXTERN void png_do_write_transformations PNGARG((png_structp png_ptr));
-
- PNG_EXTERN void png_init_read_transformations PNGARG((png_structp png_ptr));
-
- #ifdef PNG_PROGRESSIVE_READ_SUPPORTED
- PNG_EXTERN void png_push_read_chunk PNGARG((png_structp png_ptr,
- png_infop info_ptr));
- PNG_EXTERN void png_push_read_sig PNGARG((png_structp png_ptr,
- png_infop info_ptr));
- PNG_EXTERN void png_push_check_crc PNGARG((png_structp png_ptr));
- PNG_EXTERN void png_push_crc_skip PNGARG((png_structp png_ptr,
- png_uint_32 length));
- PNG_EXTERN void png_push_crc_finish PNGARG((png_structp png_ptr));
- PNG_EXTERN void png_push_save_buffer PNGARG((png_structp png_ptr));
- PNG_EXTERN void png_push_restore_buffer PNGARG((png_structp png_ptr,
- png_bytep buffer, png_size_t buffer_length));
- PNG_EXTERN void png_push_read_IDAT PNGARG((png_structp png_ptr));
- PNG_EXTERN void png_process_IDAT_data PNGARG((png_structp png_ptr,
- png_bytep buffer, png_size_t buffer_length));
- PNG_EXTERN void png_push_process_row PNGARG((png_structp png_ptr));
- PNG_EXTERN void png_push_handle_unknown PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_uint_32 length));
- PNG_EXTERN void png_push_have_info PNGARG((png_structp png_ptr,
- png_infop info_ptr));
- PNG_EXTERN void png_push_have_end PNGARG((png_structp png_ptr,
- png_infop info_ptr));
- PNG_EXTERN void png_push_have_row PNGARG((png_structp png_ptr, png_bytep row));
- PNG_EXTERN void png_push_read_end PNGARG((png_structp png_ptr,
- png_infop info_ptr));
- PNG_EXTERN void png_process_some_data PNGARG((png_structp png_ptr,
- png_infop info_ptr));
- PNG_EXTERN void png_read_push_finish_row PNGARG((png_structp png_ptr));
- #if defined(PNG_READ_tEXt_SUPPORTED)
- PNG_EXTERN void png_push_handle_tEXt PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_uint_32 length));
- PNG_EXTERN void png_push_read_tEXt PNGARG((png_structp png_ptr,
- png_infop info_ptr));
- #endif
- #if defined(PNG_READ_zTXt_SUPPORTED)
- PNG_EXTERN void png_push_handle_zTXt PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_uint_32 length));
- PNG_EXTERN void png_push_read_zTXt PNGARG((png_structp png_ptr,
- png_infop info_ptr));
- #endif
- #if defined(PNG_READ_iTXt_SUPPORTED)
- PNG_EXTERN void png_push_handle_iTXt PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_uint_32 length));
- PNG_EXTERN void png_push_read_iTXt PNGARG((png_structp png_ptr,
- png_infop info_ptr));
- #endif
-
- #endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
-
- #ifdef PNG_MNG_FEATURES_SUPPORTED
- PNG_EXTERN void png_do_read_intrapixel PNGARG((png_row_infop row_info,
- png_bytep row));
- PNG_EXTERN void png_do_write_intrapixel PNGARG((png_row_infop row_info,
- png_bytep row));
- #endif
-
- #if defined(PNG_ASSEMBLER_CODE_SUPPORTED)
- #if defined(PNG_MMX_CODE_SUPPORTED)
- /* png.c */ /* PRIVATE */
- PNG_EXTERN void png_init_mmx_flags PNGARG((png_structp png_ptr));
- #endif
- #endif
-
- #if defined(PNG_INCH_CONVERSIONS) && defined(PNG_FLOATING_POINT_SUPPORTED)
- PNG_EXTERN png_uint_32 png_get_pixels_per_inch PNGARG((png_structp png_ptr,
- png_infop info_ptr));
-
- PNG_EXTERN png_uint_32 png_get_x_pixels_per_inch PNGARG((png_structp png_ptr,
- png_infop info_ptr));
-
- PNG_EXTERN png_uint_32 png_get_y_pixels_per_inch PNGARG((png_structp png_ptr,
- png_infop info_ptr));
-
- PNG_EXTERN float png_get_x_offset_inches PNGARG((png_structp png_ptr,
- png_infop info_ptr));
-
- PNG_EXTERN float png_get_y_offset_inches PNGARG((png_structp png_ptr,
- png_infop info_ptr));
-
- #if defined(PNG_pHYs_SUPPORTED)
- PNG_EXTERN png_uint_32 png_get_pHYs_dpi PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type));
- #endif /* PNG_pHYs_SUPPORTED */
- #endif /* PNG_INCH_CONVERSIONS && PNG_FLOATING_POINT_SUPPORTED */
-
- /* Maintainer: Put new private prototypes here ^ and in libpngpf.3 */
-
- #endif /* PNG_INTERNAL */
-
- #ifdef __cplusplus
- }
- #endif
-
- #endif /* PNG_VERSION_INFO_ONLY */
- /* do not put anything past this line */
- #endif /* PNG_H */
- /********* End of inlined file: png.h *********/
-
- #define PNG_NO_EXTERN
-
- /********* Start of inlined file: png.c *********/
- /* png.c - location for general purpose libpng functions
- *
- * Last changed in libpng 1.2.21 [October 4, 2007]
- * For conditions of distribution and use, see copyright notice in png.h
- * Copyright (c) 1998-2007 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
- */
-
- #define PNG_INTERNAL
- #define PNG_NO_EXTERN
-
- /* Generate a compiler error if there is an old png.h in the search path. */
- typedef version_1_2_21 Your_png_h_is_not_version_1_2_21;
-
- /* Version information for C files. This had better match the version
- * string defined in png.h. */
-
- #ifdef PNG_USE_GLOBAL_ARRAYS
- /* png_libpng_ver was changed to a function in version 1.0.5c */
- PNG_CONST char png_libpng_ver[18] = PNG_LIBPNG_VER_STRING;
-
- #ifdef PNG_READ_SUPPORTED
-
- /* png_sig was changed to a function in version 1.0.5c */
- /* Place to hold the signature string for a PNG file. */
- PNG_CONST png_byte FARDATA png_sig[8] = {137, 80, 78, 71, 13, 10, 26, 10};
- #endif /* PNG_READ_SUPPORTED */
-
- /* Invoke global declarations for constant strings for known chunk types */
- PNG_IHDR;
- PNG_IDAT;
- PNG_IEND;
- PNG_PLTE;
- PNG_bKGD;
- PNG_cHRM;
- PNG_gAMA;
- PNG_hIST;
- PNG_iCCP;
- PNG_iTXt;
- PNG_oFFs;
- PNG_pCAL;
- PNG_sCAL;
- PNG_pHYs;
- PNG_sBIT;
- PNG_sPLT;
- PNG_sRGB;
- PNG_tEXt;
- PNG_tIME;
- PNG_tRNS;
- PNG_zTXt;
-
- #ifdef PNG_READ_SUPPORTED
- /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
-
- /* start of interlace block */
- PNG_CONST int FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
-
- /* offset to next interlace block */
- PNG_CONST int FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
-
- /* start of interlace block in the y direction */
- PNG_CONST int FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
-
- /* offset to next interlace block in the y direction */
- PNG_CONST int FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
-
- /* Height of interlace block. This is not currently used - if you need
- * it, uncomment it here and in png.h
- PNG_CONST int FARDATA png_pass_height[] = {8, 8, 4, 4, 2, 2, 1};
- */
-
- /* Mask to determine which pixels are valid in a pass */
- PNG_CONST int FARDATA png_pass_mask[] = {0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff};
-
- /* Mask to determine which pixels to overwrite while displaying */
- PNG_CONST int FARDATA png_pass_dsp_mask[]
- = {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff};
-
- #endif /* PNG_READ_SUPPORTED */
- #endif /* PNG_USE_GLOBAL_ARRAYS */
-
- /* Tells libpng that we have already handled the first "num_bytes" bytes
- * of the PNG file signature. If the PNG data is embedded into another
- * stream we can set num_bytes = 8 so that libpng will not attempt to read
- * or write any of the magic bytes before it starts on the IHDR.
- */
-
- #ifdef PNG_READ_SUPPORTED
- void PNGAPI
- png_set_sig_bytes(png_structp png_ptr, int num_bytes)
- {
- if(png_ptr == NULL) return;
- png_debug(1, "in png_set_sig_bytes\n");
- if (num_bytes > 8)
- png_error(png_ptr, "Too many bytes for PNG signature.");
-
- png_ptr->sig_bytes = (png_byte)(num_bytes < 0 ? 0 : num_bytes);
- }
-
- /* Checks whether the supplied bytes match the PNG signature. We allow
- * checking less than the full 8-byte signature so that those apps that
- * already read the first few bytes of a file to determine the file type
- * can simply check the remaining bytes for extra assurance. Returns
- * an integer less than, equal to, or greater than zero if sig is found,
- * respectively, to be less than, to match, or be greater than the correct
- * PNG signature (this is the same behaviour as strcmp, memcmp, etc).
- */
- int PNGAPI
- png_sig_cmp(png_bytep sig, png_size_t start, png_size_t num_to_check)
- {
- png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10};
- if (num_to_check > 8)
- num_to_check = 8;
- else if (num_to_check < 1)
- return (-1);
-
- if (start > 7)
- return (-1);
-
- if (start + num_to_check > 8)
- num_to_check = 8 - start;
-
- return ((int)(png_memcmp(&sig[start], &png_signature[start], num_to_check)));
- }
-
- #if defined(PNG_1_0_X) || defined(PNG_1_2_X)
- /* (Obsolete) function to check signature bytes. It does not allow one
- * to check a partial signature. This function might be removed in the
- * future - use png_sig_cmp(). Returns true (nonzero) if the file is PNG.
- */
- int PNGAPI
- png_check_sig(png_bytep sig, int num)
- {
- return ((int)!png_sig_cmp(sig, (png_size_t)0, (png_size_t)num));
- }
- #endif
- #endif /* PNG_READ_SUPPORTED */
-
- #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
- /* Function to allocate memory for zlib and clear it to 0. */
- #ifdef PNG_1_0_X
- voidpf PNGAPI
- #else
- voidpf /* private */
- #endif
- png_zalloc(voidpf png_ptr, uInt items, uInt size)
- {
- png_voidp ptr;
- png_structp p=(png_structp)png_ptr;
- png_uint_32 save_flags=p->flags;
- png_uint_32 num_bytes;
-
- if(png_ptr == NULL) return (NULL);
- if (items > PNG_UINT_32_MAX/size)
- {
- png_warning (p, "Potential overflow in png_zalloc()");
- return (NULL);
- }
- num_bytes = (png_uint_32)items * size;
-
- p->flags|=PNG_FLAG_MALLOC_NULL_MEM_OK;
- ptr = (png_voidp)png_malloc((png_structp)png_ptr, num_bytes);
- p->flags=save_flags;
-
- #if defined(PNG_1_0_X) && !defined(PNG_NO_ZALLOC_ZERO)
- if (ptr == NULL)
- return ((voidpf)ptr);
-
- if (num_bytes > (png_uint_32)0x8000L)
- {
- png_memset(ptr, 0, (png_size_t)0x8000L);
- png_memset((png_bytep)ptr + (png_size_t)0x8000L, 0,
- (png_size_t)(num_bytes - (png_uint_32)0x8000L));
- }
- else
- {
- png_memset(ptr, 0, (png_size_t)num_bytes);
- }
- #endif
- return ((voidpf)ptr);
- }
-
- /* function to free memory for zlib */
- #ifdef PNG_1_0_X
- void PNGAPI
- #else
- void /* private */
- #endif
- png_zfree(voidpf png_ptr, voidpf ptr)
- {
- png_free((png_structp)png_ptr, (png_voidp)ptr);
- }
-
- /* Reset the CRC variable to 32 bits of 1's. Care must be taken
- * in case CRC is > 32 bits to leave the top bits 0.
- */
- void /* PRIVATE */
- png_reset_crc(png_structp png_ptr)
- {
- png_ptr->crc = crc32(0, Z_NULL, 0);
- }
-
- /* Calculate the CRC over a section of data. We can only pass as
- * much data to this routine as the largest single buffer size. We
- * also check that this data will actually be used before going to the
- * trouble of calculating it.
- */
- void /* PRIVATE */
- png_calculate_crc(png_structp png_ptr, png_bytep ptr, png_size_t length)
- {
- int need_crc = 1;
-
- if (png_ptr->chunk_name[0] & 0x20) /* ancillary */
- {
- if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
- (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
- need_crc = 0;
- }
- else /* critical */
- {
- if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE)
- need_crc = 0;
- }
-
- if (need_crc)
- png_ptr->crc = crc32(png_ptr->crc, ptr, (uInt)length);
- }
-
- /* Allocate the memory for an info_struct for the application. We don't
- * really need the png_ptr, but it could potentially be useful in the
- * future. This should be used in favour of malloc(png_sizeof(png_info))
- * and png_info_init() so that applications that want to use a shared
- * libpng don't have to be recompiled if png_info changes size.
- */
- png_infop PNGAPI
- png_create_info_struct(png_structp png_ptr)
- {
- png_infop info_ptr;
-
- png_debug(1, "in png_create_info_struct\n");
- if(png_ptr == NULL) return (NULL);
- #ifdef PNG_USER_MEM_SUPPORTED
- info_ptr = (png_infop)png_create_struct_2(PNG_STRUCT_INFO,
- png_ptr->malloc_fn, png_ptr->mem_ptr);
- #else
- info_ptr = (png_infop)png_create_struct(PNG_STRUCT_INFO);
- #endif
- if (info_ptr != NULL)
- png_info_init_3(&info_ptr, png_sizeof(png_info));
-
- return (info_ptr);
- }
-
- /* This function frees the memory associated with a single info struct.
- * Normally, one would use either png_destroy_read_struct() or
- * png_destroy_write_struct() to free an info struct, but this may be
- * useful for some applications.
- */
- void PNGAPI
- png_destroy_info_struct(png_structp png_ptr, png_infopp info_ptr_ptr)
- {
- png_infop info_ptr = NULL;
- if(png_ptr == NULL) return;
-
- png_debug(1, "in png_destroy_info_struct\n");
- if (info_ptr_ptr != NULL)
- info_ptr = *info_ptr_ptr;
-
- if (info_ptr != NULL)
- {
- png_info_destroy(png_ptr, info_ptr);
-
- #ifdef PNG_USER_MEM_SUPPORTED
- png_destroy_struct_2((png_voidp)info_ptr, png_ptr->free_fn,
- png_ptr->mem_ptr);
- #else
- png_destroy_struct((png_voidp)info_ptr);
- #endif
- *info_ptr_ptr = NULL;
- }
- }
-
- /* Initialize the info structure. This is now an internal function (0.89)
- * and applications using it are urged to use png_create_info_struct()
- * instead.
- */
- #if defined(PNG_1_0_X) || defined(PNG_1_2_X)
- #undef png_info_init
- void PNGAPI
- png_info_init(png_infop info_ptr)
- {
- /* We only come here via pre-1.0.12-compiled applications */
- png_info_init_3(&info_ptr, 0);
- }
- #endif
-
- void PNGAPI
- png_info_init_3(png_infopp ptr_ptr, png_size_t png_info_struct_size)
- {
- png_infop info_ptr = *ptr_ptr;
-
- if(info_ptr == NULL) return;
-
- png_debug(1, "in png_info_init_3\n");
-
- if(png_sizeof(png_info) > png_info_struct_size)
- {
- png_destroy_struct(info_ptr);
- info_ptr = (png_infop)png_create_struct(PNG_STRUCT_INFO);
- *ptr_ptr = info_ptr;
- }
-
- /* set everything to 0 */
- png_memset(info_ptr, 0, png_sizeof (png_info));
- }
-
- #ifdef PNG_FREE_ME_SUPPORTED
- void PNGAPI
- png_data_freer(png_structp png_ptr, png_infop info_ptr,
- int freer, png_uint_32 mask)
- {
- png_debug(1, "in png_data_freer\n");
- if (png_ptr == NULL || info_ptr == NULL)
- return;
- if(freer == PNG_DESTROY_WILL_FREE_DATA)
- info_ptr->free_me |= mask;
- else if(freer == PNG_USER_WILL_FREE_DATA)
- info_ptr->free_me &= ~mask;
- else
- png_warning(png_ptr,
- "Unknown freer parameter in png_data_freer.");
- }
- #endif
-
- void PNGAPI
- png_free_data(png_structp png_ptr, png_infop info_ptr, png_uint_32 mask,
- int num)
- {
- png_debug(1, "in png_free_data\n");
- if (png_ptr == NULL || info_ptr == NULL)
- return;
-
- #if defined(PNG_TEXT_SUPPORTED)
- /* free text item num or (if num == -1) all text items */
- #ifdef PNG_FREE_ME_SUPPORTED
- if ((mask & PNG_FREE_TEXT) & info_ptr->free_me)
- #else
- if (mask & PNG_FREE_TEXT)
- #endif
- {
- if (num != -1)
- {
- if (info_ptr->text && info_ptr->text[num].key)
- {
- png_free(png_ptr, info_ptr->text[num].key);
- info_ptr->text[num].key = NULL;
- }
- }
- else
- {
- int i;
- for (i = 0; i < info_ptr->num_text; i++)
- png_free_data(png_ptr, info_ptr, PNG_FREE_TEXT, i);
- png_free(png_ptr, info_ptr->text);
- info_ptr->text = NULL;
- info_ptr->num_text=0;
- }
- }
- #endif
-
- #if defined(PNG_tRNS_SUPPORTED)
- /* free any tRNS entry */
- #ifdef PNG_FREE_ME_SUPPORTED
- if ((mask & PNG_FREE_TRNS) & info_ptr->free_me)
- #else
- if ((mask & PNG_FREE_TRNS) && (png_ptr->flags & PNG_FLAG_FREE_TRNS))
- #endif
- {
- png_free(png_ptr, info_ptr->trans);
- info_ptr->valid &= ~PNG_INFO_tRNS;
- #ifndef PNG_FREE_ME_SUPPORTED
- png_ptr->flags &= ~PNG_FLAG_FREE_TRNS;
- #endif
- info_ptr->trans = NULL;
- }
- #endif
-
- #if defined(PNG_sCAL_SUPPORTED)
- /* free any sCAL entry */
- #ifdef PNG_FREE_ME_SUPPORTED
- if ((mask & PNG_FREE_SCAL) & info_ptr->free_me)
- #else
- if (mask & PNG_FREE_SCAL)
- #endif
- {
- #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
- png_free(png_ptr, info_ptr->scal_s_width);
- png_free(png_ptr, info_ptr->scal_s_height);
- info_ptr->scal_s_width = NULL;
- info_ptr->scal_s_height = NULL;
- #endif
- info_ptr->valid &= ~PNG_INFO_sCAL;
- }
- #endif
-
- #if defined(PNG_pCAL_SUPPORTED)
- /* free any pCAL entry */
- #ifdef PNG_FREE_ME_SUPPORTED
- if ((mask & PNG_FREE_PCAL) & info_ptr->free_me)
- #else
- if (mask & PNG_FREE_PCAL)
- #endif
- {
- png_free(png_ptr, info_ptr->pcal_purpose);
- png_free(png_ptr, info_ptr->pcal_units);
- info_ptr->pcal_purpose = NULL;
- info_ptr->pcal_units = NULL;
- if (info_ptr->pcal_params != NULL)
- {
- int i;
- for (i = 0; i < (int)info_ptr->pcal_nparams; i++)
- {
- png_free(png_ptr, info_ptr->pcal_params[i]);
- info_ptr->pcal_params[i]=NULL;
- }
- png_free(png_ptr, info_ptr->pcal_params);
- info_ptr->pcal_params = NULL;
- }
- info_ptr->valid &= ~PNG_INFO_pCAL;
- }
- #endif
-
- #if defined(PNG_iCCP_SUPPORTED)
- /* free any iCCP entry */
- #ifdef PNG_FREE_ME_SUPPORTED
- if ((mask & PNG_FREE_ICCP) & info_ptr->free_me)
- #else
- if (mask & PNG_FREE_ICCP)
- #endif
- {
- png_free(png_ptr, info_ptr->iccp_name);
- png_free(png_ptr, info_ptr->iccp_profile);
- info_ptr->iccp_name = NULL;
- info_ptr->iccp_profile = NULL;
- info_ptr->valid &= ~PNG_INFO_iCCP;
- }
- #endif
-
- #if defined(PNG_sPLT_SUPPORTED)
- /* free a given sPLT entry, or (if num == -1) all sPLT entries */
- #ifdef PNG_FREE_ME_SUPPORTED
- if ((mask & PNG_FREE_SPLT) & info_ptr->free_me)
- #else
- if (mask & PNG_FREE_SPLT)
- #endif
- {
- if (num != -1)
- {
- if(info_ptr->splt_palettes)
- {
- png_free(png_ptr, info_ptr->splt_palettes[num].name);
- png_free(png_ptr, info_ptr->splt_palettes[num].entries);
- info_ptr->splt_palettes[num].name = NULL;
- info_ptr->splt_palettes[num].entries = NULL;
- }
- }
- else
- {
- if(info_ptr->splt_palettes_num)
- {
- int i;
- for (i = 0; i < (int)info_ptr->splt_palettes_num; i++)
- png_free_data(png_ptr, info_ptr, PNG_FREE_SPLT, i);
-
- png_free(png_ptr, info_ptr->splt_palettes);
- info_ptr->splt_palettes = NULL;
- info_ptr->splt_palettes_num = 0;
- }
- info_ptr->valid &= ~PNG_INFO_sPLT;
- }
- }
- #endif
-
- #if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
- if(png_ptr->unknown_chunk.data)
- {
- png_free(png_ptr, png_ptr->unknown_chunk.data);
- png_ptr->unknown_chunk.data = NULL;
- }
- #ifdef PNG_FREE_ME_SUPPORTED
- if ((mask & PNG_FREE_UNKN) & info_ptr->free_me)
- #else
- if (mask & PNG_FREE_UNKN)
- #endif
- {
- if (num != -1)
- {
- if(info_ptr->unknown_chunks)
- {
- png_free(png_ptr, info_ptr->unknown_chunks[num].data);
- info_ptr->unknown_chunks[num].data = NULL;
- }
- }
- else
- {
- int i;
-
- if(info_ptr->unknown_chunks_num)
- {
- for (i = 0; i < (int)info_ptr->unknown_chunks_num; i++)
- png_free_data(png_ptr, info_ptr, PNG_FREE_UNKN, i);
-
- png_free(png_ptr, info_ptr->unknown_chunks);
- info_ptr->unknown_chunks = NULL;
- info_ptr->unknown_chunks_num = 0;
- }
- }
- }
- #endif
-
- #if defined(PNG_hIST_SUPPORTED)
- /* free any hIST entry */
- #ifdef PNG_FREE_ME_SUPPORTED
- if ((mask & PNG_FREE_HIST) & info_ptr->free_me)
- #else
- if ((mask & PNG_FREE_HIST) && (png_ptr->flags & PNG_FLAG_FREE_HIST))
- #endif
- {
- png_free(png_ptr, info_ptr->hist);
- info_ptr->hist = NULL;
- info_ptr->valid &= ~PNG_INFO_hIST;
- #ifndef PNG_FREE_ME_SUPPORTED
- png_ptr->flags &= ~PNG_FLAG_FREE_HIST;
- #endif
- }
- #endif
-
- /* free any PLTE entry that was internally allocated */
- #ifdef PNG_FREE_ME_SUPPORTED
- if ((mask & PNG_FREE_PLTE) & info_ptr->free_me)
- #else
- if ((mask & PNG_FREE_PLTE) && (png_ptr->flags & PNG_FLAG_FREE_PLTE))
- #endif
- {
- png_zfree(png_ptr, info_ptr->palette);
- info_ptr->palette = NULL;
- info_ptr->valid &= ~PNG_INFO_PLTE;
- #ifndef PNG_FREE_ME_SUPPORTED
- png_ptr->flags &= ~PNG_FLAG_FREE_PLTE;
- #endif
- info_ptr->num_palette = 0;
- }
-
- #if defined(PNG_INFO_IMAGE_SUPPORTED)
- /* free any image bits attached to the info structure */
- #ifdef PNG_FREE_ME_SUPPORTED
- if ((mask & PNG_FREE_ROWS) & info_ptr->free_me)
- #else
- if (mask & PNG_FREE_ROWS)
- #endif
- {
- if(info_ptr->row_pointers)
- {
- int row;
- for (row = 0; row < (int)info_ptr->height; row++)
- {
- png_free(png_ptr, info_ptr->row_pointers[row]);
- info_ptr->row_pointers[row]=NULL;
- }
- png_free(png_ptr, info_ptr->row_pointers);
- info_ptr->row_pointers=NULL;
- }
- info_ptr->valid &= ~PNG_INFO_IDAT;
- }
- #endif
-
- #ifdef PNG_FREE_ME_SUPPORTED
- if(num == -1)
- info_ptr->free_me &= ~mask;
- else
- info_ptr->free_me &= ~(mask & ~PNG_FREE_MUL);
- #endif
- }
-
- /* This is an internal routine to free any memory that the info struct is
- * pointing to before re-using it or freeing the struct itself. Recall
- * that png_free() checks for NULL pointers for us.
- */
- void /* PRIVATE */
- png_info_destroy(png_structp png_ptr, png_infop info_ptr)
- {
- png_debug(1, "in png_info_destroy\n");
-
- png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1);
-
- #if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
- if (png_ptr->num_chunk_list)
- {
- png_free(png_ptr, png_ptr->chunk_list);
- png_ptr->chunk_list=NULL;
- png_ptr->num_chunk_list=0;
- }
- #endif
-
- png_info_init_3(&info_ptr, png_sizeof(png_info));
- }
- #endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */
-
- /* This function returns a pointer to the io_ptr associated with the user
- * functions. The application should free any memory associated with this
- * pointer before png_write_destroy() or png_read_destroy() are called.
- */
- png_voidp PNGAPI
- png_get_io_ptr(png_structp png_ptr)
- {
- if(png_ptr == NULL) return (NULL);
- return (png_ptr->io_ptr);
- }
-
- #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
- #if !defined(PNG_NO_STDIO)
- /* Initialize the default input/output functions for the PNG file. If you
- * use your own read or write routines, you can call either png_set_read_fn()
- * or png_set_write_fn() instead of png_init_io(). If you have defined
- * PNG_NO_STDIO, you must use a function of your own because "FILE *" isn't
- * necessarily available.
- */
- void PNGAPI
- png_init_io(png_structp png_ptr, png_FILE_p fp)
- {
- png_debug(1, "in png_init_io\n");
- if(png_ptr == NULL) return;
- png_ptr->io_ptr = (png_voidp)fp;
- }
- #endif
-
- #if defined(PNG_TIME_RFC1123_SUPPORTED)
- /* Convert the supplied time into an RFC 1123 string suitable for use in
- * a "Creation Time" or other text-based time string.
- */
- png_charp PNGAPI
- png_convert_to_rfc1123(png_structp png_ptr, png_timep ptime)
- {
- static PNG_CONST char short_months[12][4] =
- {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
-
- if(png_ptr == NULL) return (NULL);
- if (png_ptr->time_buffer == NULL)
- {
- png_ptr->time_buffer = (png_charp)png_malloc(png_ptr, (png_uint_32)(29*
- png_sizeof(char)));
- }
-
- #if defined(_WIN32_WCE)
- {
- wchar_t time_buf[29];
- wsprintf(time_buf, TEXT("%d %S %d %02d:%02d:%02d +0000"),
- ptime->day % 32, short_months[(ptime->month - 1) % 12],
- ptime->year, ptime->hour % 24, ptime->minute % 60,
- ptime->second % 61);
- WideCharToMultiByte(CP_ACP, 0, time_buf, -1, png_ptr->time_buffer, 29,
- NULL, NULL);
- }
- #else
- #ifdef USE_FAR_KEYWORD
- {
- char near_time_buf[29];
- png_snprintf6(near_time_buf,29,"%d %s %d %02d:%02d:%02d +0000",
- ptime->day % 32, short_months[(ptime->month - 1) % 12],
- ptime->year, ptime->hour % 24, ptime->minute % 60,
- ptime->second % 61);
- png_memcpy(png_ptr->time_buffer, near_time_buf,
- 29*png_sizeof(char));
- }
- #else
- png_snprintf6(png_ptr->time_buffer,29,"%d %s %d %02d:%02d:%02d +0000",
- ptime->day % 32, short_months[(ptime->month - 1) % 12],
- ptime->year, ptime->hour % 24, ptime->minute % 60,
- ptime->second % 61);
- #endif
- #endif /* _WIN32_WCE */
- return ((png_charp)png_ptr->time_buffer);
- }
- #endif /* PNG_TIME_RFC1123_SUPPORTED */
-
- #endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */
-
- png_charp PNGAPI
- png_get_copyright(png_structp png_ptr)
- {
- png_ptr = png_ptr; /* silence compiler warning about unused png_ptr */
- return ((png_charp) "\n libpng version 1.2.21 - October 4, 2007\n\
- Copyright (c) 1998-2007 Glenn Randers-Pehrson\n\
- Copyright (c) 1996-1997 Andreas Dilger\n\
- Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.\n");
- }
-
- /* The following return the library version as a short string in the
- * format 1.0.0 through 99.99.99zz. To get the version of *.h files
- * used with your application, print out PNG_LIBPNG_VER_STRING, which
- * is defined in png.h.
- * Note: now there is no difference between png_get_libpng_ver() and
- * png_get_header_ver(). Due to the version_nn_nn_nn typedef guard,
- * it is guaranteed that png.c uses the correct version of png.h.
- */
- png_charp PNGAPI
- png_get_libpng_ver(png_structp png_ptr)
- {
- /* Version of *.c files used when building libpng */
- png_ptr = png_ptr; /* silence compiler warning about unused png_ptr */
- return ((png_charp) PNG_LIBPNG_VER_STRING);
- }
-
- png_charp PNGAPI
- png_get_header_ver(png_structp png_ptr)
- {
- /* Version of *.h files used when building libpng */
- png_ptr = png_ptr; /* silence compiler warning about unused png_ptr */
- return ((png_charp) PNG_LIBPNG_VER_STRING);
- }
-
- png_charp PNGAPI
- png_get_header_version(png_structp png_ptr)
- {
- /* Returns longer string containing both version and date */
- png_ptr = png_ptr; /* silence compiler warning about unused png_ptr */
- return ((png_charp) PNG_HEADER_VERSION_STRING
- #ifndef PNG_READ_SUPPORTED
- " (NO READ SUPPORT)"
- #endif
- "\n");
- }
-
- #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
- #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
- int PNGAPI
- png_handle_as_unknown(png_structp png_ptr, png_bytep chunk_name)
- {
- /* check chunk_name and return "keep" value if it's on the list, else 0 */
- int i;
- png_bytep p;
- if(png_ptr == NULL || chunk_name == NULL || png_ptr->num_chunk_list<=0)
- return 0;
- p=png_ptr->chunk_list+png_ptr->num_chunk_list*5-5;
- for (i = png_ptr->num_chunk_list; i; i--, p-=5)
- if (!png_memcmp(chunk_name, p, 4))
- return ((int)*(p+4));
- return 0;
- }
- #endif
-
- /* This function, added to libpng-1.0.6g, is untested. */
- int PNGAPI
- png_reset_zstream(png_structp png_ptr)
- {
- if (png_ptr == NULL) return Z_STREAM_ERROR;
- return (inflateReset(&png_ptr->zstream));
- }
- #endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */
-
- /* This function was added to libpng-1.0.7 */
- png_uint_32 PNGAPI
- png_access_version_number(void)
- {
- /* Version of *.c files used when building libpng */
- return((png_uint_32) PNG_LIBPNG_VER);
- }
-
- #if defined(PNG_READ_SUPPORTED) && defined(PNG_ASSEMBLER_CODE_SUPPORTED)
- #if !defined(PNG_1_0_X)
- /* this function was added to libpng 1.2.0 */
- int PNGAPI
- png_mmx_support(void)
- {
- /* obsolete, to be removed from libpng-1.4.0 */
- return -1;
- }
- #endif /* PNG_1_0_X */
- #endif /* PNG_READ_SUPPORTED && PNG_ASSEMBLER_CODE_SUPPORTED */
-
- #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
- #ifdef PNG_SIZE_T
- /* Added at libpng version 1.2.6 */
- PNG_EXTERN png_size_t PNGAPI png_convert_size PNGARG((size_t size));
- png_size_t PNGAPI
- png_convert_size(size_t size)
- {
- if (size > (png_size_t)-1)
- PNG_ABORT(); /* We haven't got access to png_ptr, so no png_error() */
- return ((png_size_t)size);
- }
- #endif /* PNG_SIZE_T */
- #endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */
- /********* End of inlined file: png.c *********/
-
- /********* Start of inlined file: pngerror.c *********/
- /* pngerror.c - stub functions for i/o and memory allocation
- *
- * Last changed in libpng 1.2.20 October 4, 2007
- * For conditions of distribution and use, see copyright notice in png.h
- * Copyright (c) 1998-2007 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
- *
- * This file provides a location for all error handling. Users who
- * need special error handling are expected to write replacement functions
- * and use png_set_error_fn() to use those functions. See the instructions
- * at each function.
- */
-
- #define PNG_INTERNAL
-
- #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
- static void /* PRIVATE */
- png_default_error PNGARG((png_structp png_ptr,
- png_const_charp error_message));
- #ifndef PNG_NO_WARNINGS
- static void /* PRIVATE */
- png_default_warning PNGARG((png_structp png_ptr,
- png_const_charp warning_message));
- #endif /* PNG_NO_WARNINGS */
-
- /* This function is called whenever there is a fatal error. This function
- * should not be changed. If there is a need to handle errors differently,
- * you should supply a replacement error function and use png_set_error_fn()
- * to replace the error function at run-time.
- */
- #ifndef PNG_NO_ERROR_TEXT
- void PNGAPI
- png_error(png_structp png_ptr, png_const_charp error_message)
- {
- #ifdef PNG_ERROR_NUMBERS_SUPPORTED
- char msg[16];
- if (png_ptr != NULL)
- {
- if (png_ptr->flags&
- (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT))
- {
- if (*error_message == '#')
- {
- int offset;
- for (offset=1; offset<15; offset++)
- if (*(error_message+offset) == ' ')
- break;
- if (png_ptr->flags&PNG_FLAG_STRIP_ERROR_TEXT)
- {
- int i;
- for (i=0; i<offset-1; i++)
- msg[i]=error_message[i+1];
- msg[i]='\0';
- error_message=msg;
- }
- else
- error_message+=offset;
- }
- else
- {
- if (png_ptr->flags&PNG_FLAG_STRIP_ERROR_TEXT)
- {
- msg[0]='0';
- msg[1]='\0';
- error_message=msg;
- }
- }
- }
- }
- #endif
- if (png_ptr != NULL && png_ptr->error_fn != NULL)
- (*(png_ptr->error_fn))(png_ptr, error_message);
-
- /* If the custom handler doesn't exist, or if it returns,
- use the default handler, which will not return. */
- png_default_error(png_ptr, error_message);
- }
- #else
- void PNGAPI
- png_err(png_structp png_ptr)
- {
- if (png_ptr != NULL && png_ptr->error_fn != NULL)
- (*(png_ptr->error_fn))(png_ptr, '\0');
-
- /* If the custom handler doesn't exist, or if it returns,
- use the default handler, which will not return. */
- png_default_error(png_ptr, '\0');
- }
- #endif /* PNG_NO_ERROR_TEXT */
-
- #ifndef PNG_NO_WARNINGS
- /* This function is called whenever there is a non-fatal error. This function
- * should not be changed. If there is a need to handle warnings differently,
- * you should supply a replacement warning function and use
- * png_set_error_fn() to replace the warning function at run-time.
- */
- void PNGAPI
- png_warning(png_structp png_ptr, png_const_charp warning_message)
- {
- int offset = 0;
- if (png_ptr != NULL)
- {
- #ifdef PNG_ERROR_NUMBERS_SUPPORTED
- if (png_ptr->flags&
- (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT))
- #endif
- {
- if (*warning_message == '#')
- {
- for (offset=1; offset<15; offset++)
- if (*(warning_message+offset) == ' ')
- break;
- }
- }
- if (png_ptr != NULL && png_ptr->warning_fn != NULL)
- (*(png_ptr->warning_fn))(png_ptr, warning_message+offset);
- }
- else
- png_default_warning(png_ptr, warning_message+offset);
- }
- #endif /* PNG_NO_WARNINGS */
-
- /* These utilities are used internally to build an error message that relates
- * to the current chunk. The chunk name comes from png_ptr->chunk_name,
- * this is used to prefix the message. The message is limited in length
- * to 63 bytes, the name characters are output as hex digits wrapped in []
- * if the character is invalid.
- */
- #define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
- /*static PNG_CONST char png_digit[16] = {
- '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
- 'A', 'B', 'C', 'D', 'E', 'F'
- };*/
-
- #if !defined(PNG_NO_WARNINGS) || !defined(PNG_NO_ERROR_TEXT)
- static void /* PRIVATE */
- png_format_buffer(png_structp png_ptr, png_charp buffer, png_const_charp
- error_message)
- {
- int iout = 0, iin = 0;
-
- while (iin < 4)
- {
- int c = png_ptr->chunk_name[iin++];
- if (isnonalpha(c))
- {
- buffer[iout++] = '[';
- buffer[iout++] = png_digit[(c & 0xf0) >> 4];
- buffer[iout++] = png_digit[c & 0x0f];
- buffer[iout++] = ']';
- }
- else
- {
- buffer[iout++] = (png_byte)c;
- }
- }
-
- if (error_message == NULL)
- buffer[iout] = 0;
- else
- {
- buffer[iout++] = ':';
- buffer[iout++] = ' ';
- png_strncpy(buffer+iout, error_message, 63);
- buffer[iout+63] = 0;
- }
- }
-
- #ifdef PNG_READ_SUPPORTED
- void PNGAPI
- png_chunk_error(png_structp png_ptr, png_const_charp error_message)
- {
- char msg[18+64];
- if (png_ptr == NULL)
- png_error(png_ptr, error_message);
- else
- {
- png_format_buffer(png_ptr, msg, error_message);
- png_error(png_ptr, msg);
- }
- }
- #endif /* PNG_READ_SUPPORTED */
- #endif /* !defined(PNG_NO_WARNINGS) || !defined(PNG_NO_ERROR_TEXT) */
-
- #ifndef PNG_NO_WARNINGS
- void PNGAPI
- png_chunk_warning(png_structp png_ptr, png_const_charp warning_message)
- {
- char msg[18+64];
- if (png_ptr == NULL)
- png_warning(png_ptr, warning_message);
- else
- {
- png_format_buffer(png_ptr, msg, warning_message);
- png_warning(png_ptr, msg);
- }
- }
- #endif /* PNG_NO_WARNINGS */
-
- /* This is the default error handling function. Note that replacements for
- * this function MUST NOT RETURN, or the program will likely crash. This
- * function is used by default, or if the program supplies NULL for the
- * error function pointer in png_set_error_fn().
- */
- static void /* PRIVATE */
- png_default_error(png_structp png_ptr, png_const_charp error_message)
- {
- #ifndef PNG_NO_CONSOLE_IO
- #ifdef PNG_ERROR_NUMBERS_SUPPORTED
- if (*error_message == '#')
- {
- int offset;
- char error_number[16];
- for (offset=0; offset<15; offset++)
- {
- error_number[offset] = *(error_message+offset+1);
- if (*(error_message+offset) == ' ')
- break;
- }
- if((offset > 1) && (offset < 15))
- {
- error_number[offset-1]='\0';
- fprintf(stderr, "libpng error no. %s: %s\n", error_number,
- error_message+offset);
- }
- else
- fprintf(stderr, "libpng error: %s, offset=%d\n", error_message,offset);
- }
- else
- #endif
- fprintf(stderr, "libpng error: %s\n", error_message);
- #endif
-
- #ifdef PNG_SETJMP_SUPPORTED
- if (png_ptr)
- {
- # ifdef USE_FAR_KEYWORD
- {
- jmp_buf jmpbuf;
- png_memcpy(jmpbuf, png_ptr->jmpbuf, png_sizeof(jmp_buf));
- longjmp(jmpbuf, 1);
- }
- # else
- longjmp(png_ptr->jmpbuf, 1);
- # endif
- }
- #else
- PNG_ABORT();
- #endif
- #ifdef PNG_NO_CONSOLE_IO
- error_message = error_message; /* make compiler happy */
- #endif
- }
-
- #ifndef PNG_NO_WARNINGS
- /* This function is called when there is a warning, but the library thinks
- * it can continue anyway. Replacement functions don't have to do anything
- * here if you don't want them to. In the default configuration, png_ptr is
- * not used, but it is passed in case it may be useful.
- */
- static void /* PRIVATE */
- png_default_warning(png_structp png_ptr, png_const_charp warning_message)
- {
- #ifndef PNG_NO_CONSOLE_IO
- # ifdef PNG_ERROR_NUMBERS_SUPPORTED
- if (*warning_message == '#')
- {
- int offset;
- char warning_number[16];
- for (offset=0; offset<15; offset++)
- {
- warning_number[offset]=*(warning_message+offset+1);
- if (*(warning_message+offset) == ' ')
- break;
- }
- if((offset > 1) && (offset < 15))
- {
- warning_number[offset-1]='\0';
- fprintf(stderr, "libpng warning no. %s: %s\n", warning_number,
- warning_message+offset);
- }
- else
- fprintf(stderr, "libpng warning: %s\n", warning_message);
- }
- else
- # endif
- fprintf(stderr, "libpng warning: %s\n", warning_message);
- #else
- warning_message = warning_message; /* make compiler happy */
- #endif
- png_ptr = png_ptr; /* make compiler happy */
- }
- #endif /* PNG_NO_WARNINGS */
-
- /* This function is called when the application wants to use another method
- * of handling errors and warnings. Note that the error function MUST NOT
- * return to the calling routine or serious problems will occur. The return
- * method used in the default routine calls longjmp(png_ptr->jmpbuf, 1)
- */
- void PNGAPI
- png_set_error_fn(png_structp png_ptr, png_voidp error_ptr,
- png_error_ptr error_fn, png_error_ptr warning_fn)
- {
- if (png_ptr == NULL)
- return;
- png_ptr->error_ptr = error_ptr;
- png_ptr->error_fn = error_fn;
- png_ptr->warning_fn = warning_fn;
- }
-
- /* This function returns a pointer to the error_ptr associated with the user
- * functions. The application should free any memory associated with this
- * pointer before png_write_destroy and png_read_destroy are called.
- */
- png_voidp PNGAPI
- png_get_error_ptr(png_structp png_ptr)
- {
- if (png_ptr == NULL)
- return NULL;
- return ((png_voidp)png_ptr->error_ptr);
- }
-
- #ifdef PNG_ERROR_NUMBERS_SUPPORTED
- void PNGAPI
- png_set_strip_error_numbers(png_structp png_ptr, png_uint_32 strip_mode)
- {
- if(png_ptr != NULL)
- {
- png_ptr->flags &=
- ((~(PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT))&strip_mode);
- }
- }
- #endif
- #endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */
- /********* End of inlined file: pngerror.c *********/
-
- /********* Start of inlined file: pngget.c *********/
- /* pngget.c - retrieval of values from info struct
- *
- * Last changed in libpng 1.2.15 January 5, 2007
- * For conditions of distribution and use, see copyright notice in png.h
- * Copyright (c) 1998-2007 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
- */
-
- #define PNG_INTERNAL
-
- #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
-
- png_uint_32 PNGAPI
- png_get_valid(png_structp png_ptr, png_infop info_ptr, png_uint_32 flag)
- {
- if (png_ptr != NULL && info_ptr != NULL)
- return(info_ptr->valid & flag);
- else
- return(0);
- }
-
- png_uint_32 PNGAPI
- png_get_rowbytes(png_structp png_ptr, png_infop info_ptr)
- {
- if (png_ptr != NULL && info_ptr != NULL)
- return(info_ptr->rowbytes);
- else
- return(0);
- }
-
- #if defined(PNG_INFO_IMAGE_SUPPORTED)
- png_bytepp PNGAPI
- png_get_rows(png_structp png_ptr, png_infop info_ptr)
- {
- if (png_ptr != NULL && info_ptr != NULL)
- return(info_ptr->row_pointers);
- else
- return(0);
- }
- #endif
-
- #ifdef PNG_EASY_ACCESS_SUPPORTED
- /* easy access to info, added in libpng-0.99 */
- png_uint_32 PNGAPI
- png_get_image_width(png_structp png_ptr, png_infop info_ptr)
- {
- if (png_ptr != NULL && info_ptr != NULL)
- {
- return info_ptr->width;
- }
- return (0);
- }
-
- png_uint_32 PNGAPI
- png_get_image_height(png_structp png_ptr, png_infop info_ptr)
- {
- if (png_ptr != NULL && info_ptr != NULL)
- {
- return info_ptr->height;
- }
- return (0);
- }
-
- png_byte PNGAPI
- png_get_bit_depth(png_structp png_ptr, png_infop info_ptr)
- {
- if (png_ptr != NULL && info_ptr != NULL)
- {
- return info_ptr->bit_depth;
- }
- return (0);
- }
-
- png_byte PNGAPI
- png_get_color_type(png_structp png_ptr, png_infop info_ptr)
- {
- if (png_ptr != NULL && info_ptr != NULL)
- {
- return info_ptr->color_type;
- }
- return (0);
- }
-
- png_byte PNGAPI
- png_get_filter_type(png_structp png_ptr, png_infop info_ptr)
- {
- if (png_ptr != NULL && info_ptr != NULL)
- {
- return info_ptr->filter_type;
- }
- return (0);
- }
-
- png_byte PNGAPI
- png_get_interlace_type(png_structp png_ptr, png_infop info_ptr)
- {
- if (png_ptr != NULL && info_ptr != NULL)
- {
- return info_ptr->interlace_type;
- }
- return (0);
- }
-
- png_byte PNGAPI
- png_get_compression_type(png_structp png_ptr, png_infop info_ptr)
- {
- if (png_ptr != NULL && info_ptr != NULL)
- {
- return info_ptr->compression_type;
- }
- return (0);
- }
-
- png_uint_32 PNGAPI
- png_get_x_pixels_per_meter(png_structp png_ptr, png_infop info_ptr)
- {
- if (png_ptr != NULL && info_ptr != NULL)
- #if defined(PNG_pHYs_SUPPORTED)
- if (info_ptr->valid & PNG_INFO_pHYs)
- {
- png_debug1(1, "in %s retrieval function\n", "png_get_x_pixels_per_meter");
- if(info_ptr->phys_unit_type != PNG_RESOLUTION_METER)
- return (0);
- else return (info_ptr->x_pixels_per_unit);
- }
- #else
- return (0);
- #endif
- return (0);
- }
-
- png_uint_32 PNGAPI
- png_get_y_pixels_per_meter(png_structp png_ptr, png_infop info_ptr)
- {
- if (png_ptr != NULL && info_ptr != NULL)
- #if defined(PNG_pHYs_SUPPORTED)
- if (info_ptr->valid & PNG_INFO_pHYs)
- {
- png_debug1(1, "in %s retrieval function\n", "png_get_y_pixels_per_meter");
- if(info_ptr->phys_unit_type != PNG_RESOLUTION_METER)
- return (0);
- else return (info_ptr->y_pixels_per_unit);
- }
- #else
- return (0);
- #endif
- return (0);
- }
-
- png_uint_32 PNGAPI
- png_get_pixels_per_meter(png_structp png_ptr, png_infop info_ptr)
- {
- if (png_ptr != NULL && info_ptr != NULL)
- #if defined(PNG_pHYs_SUPPORTED)
- if (info_ptr->valid & PNG_INFO_pHYs)
- {
- png_debug1(1, "in %s retrieval function\n", "png_get_pixels_per_meter");
- if(info_ptr->phys_unit_type != PNG_RESOLUTION_METER ||
- info_ptr->x_pixels_per_unit != info_ptr->y_pixels_per_unit)
- return (0);
- else return (info_ptr->x_pixels_per_unit);
- }
- #else
- return (0);
- #endif
- return (0);
- }
-
- #ifdef PNG_FLOATING_POINT_SUPPORTED
- float PNGAPI
- png_get_pixel_aspect_ratio(png_structp png_ptr, png_infop info_ptr)
- {
- if (png_ptr != NULL && info_ptr != NULL)
- #if defined(PNG_pHYs_SUPPORTED)
- if (info_ptr->valid & PNG_INFO_pHYs)
- {
- png_debug1(1, "in %s retrieval function\n", "png_get_aspect_ratio");
- if (info_ptr->x_pixels_per_unit == 0)
- return ((float)0.0);
- else
- return ((float)((float)info_ptr->y_pixels_per_unit
- /(float)info_ptr->x_pixels_per_unit));
- }
- #else
- return (0.0);
- #endif
- return ((float)0.0);
- }
- #endif
-
- png_int_32 PNGAPI
- png_get_x_offset_microns(png_structp png_ptr, png_infop info_ptr)
- {
- if (png_ptr != NULL && info_ptr != NULL)
- #if defined(PNG_oFFs_SUPPORTED)
- if (info_ptr->valid & PNG_INFO_oFFs)
- {
- png_debug1(1, "in %s retrieval function\n", "png_get_x_offset_microns");
- if(info_ptr->offset_unit_type != PNG_OFFSET_MICROMETER)
- return (0);
- else return (info_ptr->x_offset);
- }
- #else
- return (0);
- #endif
- return (0);
- }
-
- png_int_32 PNGAPI
- png_get_y_offset_microns(png_structp png_ptr, png_infop info_ptr)
- {
- if (png_ptr != NULL && info_ptr != NULL)
- #if defined(PNG_oFFs_SUPPORTED)
- if (info_ptr->valid & PNG_INFO_oFFs)
- {
- png_debug1(1, "in %s retrieval function\n", "png_get_y_offset_microns");
- if(info_ptr->offset_unit_type != PNG_OFFSET_MICROMETER)
- return (0);
- else return (info_ptr->y_offset);
- }
- #else
- return (0);
- #endif
- return (0);
- }
-
- png_int_32 PNGAPI
- png_get_x_offset_pixels(png_structp png_ptr, png_infop info_ptr)
- {
- if (png_ptr != NULL && info_ptr != NULL)
- #if defined(PNG_oFFs_SUPPORTED)
- if (info_ptr->valid & PNG_INFO_oFFs)
- {
- png_debug1(1, "in %s retrieval function\n", "png_get_x_offset_microns");
- if(info_ptr->offset_unit_type != PNG_OFFSET_PIXEL)
- return (0);
- else return (info_ptr->x_offset);
- }
- #else
- return (0);
- #endif
- return (0);
- }
-
- png_int_32 PNGAPI
- png_get_y_offset_pixels(png_structp png_ptr, png_infop info_ptr)
- {
- if (png_ptr != NULL && info_ptr != NULL)
- #if defined(PNG_oFFs_SUPPORTED)
- if (info_ptr->valid & PNG_INFO_oFFs)
- {
- png_debug1(1, "in %s retrieval function\n", "png_get_y_offset_microns");
- if(info_ptr->offset_unit_type != PNG_OFFSET_PIXEL)
- return (0);
- else return (info_ptr->y_offset);
- }
- #else
- return (0);
- #endif
- return (0);
- }
-
- #if defined(PNG_INCH_CONVERSIONS) && defined(PNG_FLOATING_POINT_SUPPORTED)
- png_uint_32 PNGAPI
- png_get_pixels_per_inch(png_structp png_ptr, png_infop info_ptr)
- {
- return ((png_uint_32)((float)png_get_pixels_per_meter(png_ptr, info_ptr)
- *.0254 +.5));
- }
-
- png_uint_32 PNGAPI
- png_get_x_pixels_per_inch(png_structp png_ptr, png_infop info_ptr)
- {
- return ((png_uint_32)((float)png_get_x_pixels_per_meter(png_ptr, info_ptr)
- *.0254 +.5));
- }
-
- png_uint_32 PNGAPI
- png_get_y_pixels_per_inch(png_structp png_ptr, png_infop info_ptr)
- {
- return ((png_uint_32)((float)png_get_y_pixels_per_meter(png_ptr, info_ptr)
- *.0254 +.5));
- }
-
- float PNGAPI
- png_get_x_offset_inches(png_structp png_ptr, png_infop info_ptr)
- {
- return ((float)png_get_x_offset_microns(png_ptr, info_ptr)
- *.00003937);
- }
-
- float PNGAPI
- png_get_y_offset_inches(png_structp png_ptr, png_infop info_ptr)
- {
- return ((float)png_get_y_offset_microns(png_ptr, info_ptr)
- *.00003937);
- }
-
- #if defined(PNG_pHYs_SUPPORTED)
- png_uint_32 PNGAPI
- png_get_pHYs_dpi(png_structp png_ptr, png_infop info_ptr,
- png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type)
- {
- png_uint_32 retval = 0;
-
- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
- {
- png_debug1(1, "in %s retrieval function\n", "pHYs");
- if (res_x != NULL)
- {
- *res_x = info_ptr->x_pixels_per_unit;
- retval |= PNG_INFO_pHYs;
- }
- if (res_y != NULL)
- {
- *res_y = info_ptr->y_pixels_per_unit;
- retval |= PNG_INFO_pHYs;
- }
- if (unit_type != NULL)
- {
- *unit_type = (int)info_ptr->phys_unit_type;
- retval |= PNG_INFO_pHYs;
- if(*unit_type == 1)
- {
- if (res_x != NULL) *res_x = (png_uint_32)(*res_x * .0254 + .50);
- if (res_y != NULL) *res_y = (png_uint_32)(*res_y * .0254 + .50);
- }
- }
- }
- return (retval);
- }
- #endif /* PNG_pHYs_SUPPORTED */
- #endif /* PNG_INCH_CONVERSIONS && PNG_FLOATING_POINT_SUPPORTED */
-
- /* png_get_channels really belongs in here, too, but it's been around longer */
-
- #endif /* PNG_EASY_ACCESS_SUPPORTED */
-
- png_byte PNGAPI
- png_get_channels(png_structp png_ptr, png_infop info_ptr)
- {
- if (png_ptr != NULL && info_ptr != NULL)
- return(info_ptr->channels);
- else
- return (0);
- }
-
- png_bytep PNGAPI
- png_get_signature(png_structp png_ptr, png_infop info_ptr)
- {
- if (png_ptr != NULL && info_ptr != NULL)
- return(info_ptr->signature);
- else
- return (NULL);
- }
-
- #if defined(PNG_bKGD_SUPPORTED)
- png_uint_32 PNGAPI
- png_get_bKGD(png_structp png_ptr, png_infop info_ptr,
- png_color_16p *background)
- {
- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD)
- && background != NULL)
- {
- png_debug1(1, "in %s retrieval function\n", "bKGD");
- *background = &(info_ptr->background);
- return (PNG_INFO_bKGD);
- }
- return (0);
- }
- #endif
-
- #if defined(PNG_cHRM_SUPPORTED)
- #ifdef PNG_FLOATING_POINT_SUPPORTED
- png_uint_32 PNGAPI
- png_get_cHRM(png_structp png_ptr, png_infop info_ptr,
- double *white_x, double *white_y, double *red_x, double *red_y,
- double *green_x, double *green_y, double *blue_x, double *blue_y)
- {
- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM))
- {
- png_debug1(1, "in %s retrieval function\n", "cHRM");
- if (white_x != NULL)
- *white_x = (double)info_ptr->x_white;
- if (white_y != NULL)
- *white_y = (double)info_ptr->y_white;
- if (red_x != NULL)
- *red_x = (double)info_ptr->x_red;
- if (red_y != NULL)
- *red_y = (double)info_ptr->y_red;
- if (green_x != NULL)
- *green_x = (double)info_ptr->x_green;
- if (green_y != NULL)
- *green_y = (double)info_ptr->y_green;
- if (blue_x != NULL)
- *blue_x = (double)info_ptr->x_blue;
- if (blue_y != NULL)
- *blue_y = (double)info_ptr->y_blue;
- return (PNG_INFO_cHRM);
- }
- return (0);
- }
- #endif
- #ifdef PNG_FIXED_POINT_SUPPORTED
- png_uint_32 PNGAPI
- png_get_cHRM_fixed(png_structp png_ptr, png_infop info_ptr,
- png_fixed_point *white_x, png_fixed_point *white_y, png_fixed_point *red_x,
- png_fixed_point *red_y, png_fixed_point *green_x, png_fixed_point *green_y,
- png_fixed_point *blue_x, png_fixed_point *blue_y)
- {
- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM))
- {
- png_debug1(1, "in %s retrieval function\n", "cHRM");
- if (white_x != NULL)
- *white_x = info_ptr->int_x_white;
- if (white_y != NULL)
- *white_y = info_ptr->int_y_white;
- if (red_x != NULL)
- *red_x = info_ptr->int_x_red;
- if (red_y != NULL)
- *red_y = info_ptr->int_y_red;
- if (green_x != NULL)
- *green_x = info_ptr->int_x_green;
- if (green_y != NULL)
- *green_y = info_ptr->int_y_green;
- if (blue_x != NULL)
- *blue_x = info_ptr->int_x_blue;
- if (blue_y != NULL)
- *blue_y = info_ptr->int_y_blue;
- return (PNG_INFO_cHRM);
- }
- return (0);
- }
- #endif
- #endif
-
- #if defined(PNG_gAMA_SUPPORTED)
- #ifdef PNG_FLOATING_POINT_SUPPORTED
- png_uint_32 PNGAPI
- png_get_gAMA(png_structp png_ptr, png_infop info_ptr, double *file_gamma)
- {
- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)
- && file_gamma != NULL)
- {
- png_debug1(1, "in %s retrieval function\n", "gAMA");
- *file_gamma = (double)info_ptr->gamma;
- return (PNG_INFO_gAMA);
- }
- return (0);
- }
- #endif
- #ifdef PNG_FIXED_POINT_SUPPORTED
- png_uint_32 PNGAPI
- png_get_gAMA_fixed(png_structp png_ptr, png_infop info_ptr,
- png_fixed_point *int_file_gamma)
- {
- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)
- && int_file_gamma != NULL)
- {
- png_debug1(1, "in %s retrieval function\n", "gAMA");
- *int_file_gamma = info_ptr->int_gamma;
- return (PNG_INFO_gAMA);
- }
- return (0);
- }
- #endif
- #endif
-
- #if defined(PNG_sRGB_SUPPORTED)
- png_uint_32 PNGAPI
- png_get_sRGB(png_structp png_ptr, png_infop info_ptr, int *file_srgb_intent)
- {
- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB)
- && file_srgb_intent != NULL)
- {
- png_debug1(1, "in %s retrieval function\n", "sRGB");
- *file_srgb_intent = (int)info_ptr->srgb_intent;
- return (PNG_INFO_sRGB);
- }
- return (0);
- }
- #endif
-
- #if defined(PNG_iCCP_SUPPORTED)
- png_uint_32 PNGAPI
- png_get_iCCP(png_structp png_ptr, png_infop info_ptr,
- png_charpp name, int *compression_type,
- png_charpp profile, png_uint_32 *proflen)
- {
- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP)
- && name != NULL && profile != NULL && proflen != NULL)
- {
- png_debug1(1, "in %s retrieval function\n", "iCCP");
- *name = info_ptr->iccp_name;
- *profile = info_ptr->iccp_profile;
- /* compression_type is a dummy so the API won't have to change
- if we introduce multiple compression types later. */
- *proflen = (int)info_ptr->iccp_proflen;
- *compression_type = (int)info_ptr->iccp_compression;
- return (PNG_INFO_iCCP);
- }
- return (0);
- }
- #endif
-
- #if defined(PNG_sPLT_SUPPORTED)
- png_uint_32 PNGAPI
- png_get_sPLT(png_structp png_ptr, png_infop info_ptr,
- png_sPLT_tpp spalettes)
- {
- if (png_ptr != NULL && info_ptr != NULL && spalettes != NULL)
- {
- *spalettes = info_ptr->splt_palettes;
- return ((png_uint_32)info_ptr->splt_palettes_num);
- }
- return (0);
- }
- #endif
-
- #if defined(PNG_hIST_SUPPORTED)
- png_uint_32 PNGAPI
- png_get_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_16p *hist)
- {
- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST)
- && hist != NULL)
- {
- png_debug1(1, "in %s retrieval function\n", "hIST");
- *hist = info_ptr->hist;
- return (PNG_INFO_hIST);
- }
- return (0);
- }
- #endif
-
- png_uint_32 PNGAPI
- png_get_IHDR(png_structp png_ptr, png_infop info_ptr,
- png_uint_32 *width, png_uint_32 *height, int *bit_depth,
- int *color_type, int *interlace_type, int *compression_type,
- int *filter_type)
-
- {
- if (png_ptr != NULL && info_ptr != NULL && width != NULL && height != NULL &&
- bit_depth != NULL && color_type != NULL)
- {
- png_debug1(1, "in %s retrieval function\n", "IHDR");
- *width = info_ptr->width;
- *height = info_ptr->height;
- *bit_depth = info_ptr->bit_depth;
- if (info_ptr->bit_depth < 1 || info_ptr->bit_depth > 16)
- png_error(png_ptr, "Invalid bit depth");
- *color_type = info_ptr->color_type;
- if (info_ptr->color_type > 6)
- png_error(png_ptr, "Invalid color type");
- if (compression_type != NULL)
- *compression_type = info_ptr->compression_type;
- if (filter_type != NULL)
- *filter_type = info_ptr->filter_type;
- if (interlace_type != NULL)
- *interlace_type = info_ptr->interlace_type;
-
- /* check for potential overflow of rowbytes */
- if (*width == 0 || *width > PNG_UINT_31_MAX)
- png_error(png_ptr, "Invalid image width");
- if (*height == 0 || *height > PNG_UINT_31_MAX)
- png_error(png_ptr, "Invalid image height");
- if (info_ptr->width > (PNG_UINT_32_MAX
- >> 3) /* 8-byte RGBA pixels */
- - 64 /* bigrowbuf hack */
- - 1 /* filter byte */
- - 7*8 /* rounding of width to multiple of 8 pixels */
- - 8) /* extra max_pixel_depth pad */
- {
- png_warning(png_ptr,
- "Width too large for libpng to process image data.");
- }
- return (1);
- }
- return (0);
- }
-
- #if defined(PNG_oFFs_SUPPORTED)
- png_uint_32 PNGAPI
- png_get_oFFs(png_structp png_ptr, png_infop info_ptr,
- png_int_32 *offset_x, png_int_32 *offset_y, int *unit_type)
- {
- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs)
- && offset_x != NULL && offset_y != NULL && unit_type != NULL)
- {
- png_debug1(1, "in %s retrieval function\n", "oFFs");
- *offset_x = info_ptr->x_offset;
- *offset_y = info_ptr->y_offset;
- *unit_type = (int)info_ptr->offset_unit_type;
- return (PNG_INFO_oFFs);
- }
- return (0);
- }
- #endif
-
- #if defined(PNG_pCAL_SUPPORTED)
- png_uint_32 PNGAPI
- png_get_pCAL(png_structp png_ptr, png_infop info_ptr,
- png_charp *purpose, png_int_32 *X0, png_int_32 *X1, int *type, int *nparams,
- png_charp *units, png_charpp *params)
- {
- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL)
- && purpose != NULL && X0 != NULL && X1 != NULL && type != NULL &&
- nparams != NULL && units != NULL && params != NULL)
- {
- png_debug1(1, "in %s retrieval function\n", "pCAL");
- *purpose = info_ptr->pcal_purpose;
- *X0 = info_ptr->pcal_X0;
- *X1 = info_ptr->pcal_X1;
- *type = (int)info_ptr->pcal_type;
- *nparams = (int)info_ptr->pcal_nparams;
- *units = info_ptr->pcal_units;
- *params = info_ptr->pcal_params;
- return (PNG_INFO_pCAL);
- }
- return (0);
- }
- #endif
-
- #if defined(PNG_sCAL_SUPPORTED)
- #ifdef PNG_FLOATING_POINT_SUPPORTED
- png_uint_32 PNGAPI
- png_get_sCAL(png_structp png_ptr, png_infop info_ptr,
- int *unit, double *width, double *height)
- {
- if (png_ptr != NULL && info_ptr != NULL &&
- (info_ptr->valid & PNG_INFO_sCAL))
- {
- *unit = info_ptr->scal_unit;
- *width = info_ptr->scal_pixel_width;
- *height = info_ptr->scal_pixel_height;
- return (PNG_INFO_sCAL);
- }
- return(0);
- }
- #else
- #ifdef PNG_FIXED_POINT_SUPPORTED
- png_uint_32 PNGAPI
- png_get_sCAL_s(png_structp png_ptr, png_infop info_ptr,
- int *unit, png_charpp width, png_charpp height)
- {
- if (png_ptr != NULL && info_ptr != NULL &&
- (info_ptr->valid & PNG_INFO_sCAL))
- {
- *unit = info_ptr->scal_unit;
- *width = info_ptr->scal_s_width;
- *height = info_ptr->scal_s_height;
- return (PNG_INFO_sCAL);
- }
- return(0);
- }
- #endif
- #endif
- #endif
-
- #if defined(PNG_pHYs_SUPPORTED)
- png_uint_32 PNGAPI
- png_get_pHYs(png_structp png_ptr, png_infop info_ptr,
- png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type)
- {
- png_uint_32 retval = 0;
-
- if (png_ptr != NULL && info_ptr != NULL &&
- (info_ptr->valid & PNG_INFO_pHYs))
- {
- png_debug1(1, "in %s retrieval function\n", "pHYs");
- if (res_x != NULL)
- {
- *res_x = info_ptr->x_pixels_per_unit;
- retval |= PNG_INFO_pHYs;
- }
- if (res_y != NULL)
- {
- *res_y = info_ptr->y_pixels_per_unit;
- retval |= PNG_INFO_pHYs;
- }
- if (unit_type != NULL)
- {
- *unit_type = (int)info_ptr->phys_unit_type;
- retval |= PNG_INFO_pHYs;
- }
- }
- return (retval);
- }
- #endif
-
- png_uint_32 PNGAPI
- png_get_PLTE(png_structp png_ptr, png_infop info_ptr, png_colorp *palette,
- int *num_palette)
- {
- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_PLTE)
- && palette != NULL)
- {
- png_debug1(1, "in %s retrieval function\n", "PLTE");
- *palette = info_ptr->palette;
- *num_palette = info_ptr->num_palette;
- png_debug1(3, "num_palette = %d\n", *num_palette);
- return (PNG_INFO_PLTE);
- }
- return (0);
- }
-
- #if defined(PNG_sBIT_SUPPORTED)
- png_uint_32 PNGAPI
- png_get_sBIT(png_structp png_ptr, png_infop info_ptr, png_color_8p *sig_bit)
- {
- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT)
- && sig_bit != NULL)
- {
- png_debug1(1, "in %s retrieval function\n", "sBIT");
- *sig_bit = &(info_ptr->sig_bit);
- return (PNG_INFO_sBIT);
- }
- return (0);
- }
- #endif
-
- #if defined(PNG_TEXT_SUPPORTED)
- png_uint_32 PNGAPI
- png_get_text(png_structp png_ptr, png_infop info_ptr, png_textp *text_ptr,
- int *num_text)
- {
- if (png_ptr != NULL && info_ptr != NULL && info_ptr->num_text > 0)
- {
- png_debug1(1, "in %s retrieval function\n",
- (png_ptr->chunk_name[0] == '\0' ? "text"
- : (png_const_charp)png_ptr->chunk_name));
- if (text_ptr != NULL)
- *text_ptr = info_ptr->text;
- if (num_text != NULL)
- *num_text = info_ptr->num_text;
- return ((png_uint_32)info_ptr->num_text);
- }
- if (num_text != NULL)
- *num_text = 0;
- return(0);
- }
- #endif
-
- #if defined(PNG_tIME_SUPPORTED)
- png_uint_32 PNGAPI
- png_get_tIME(png_structp png_ptr, png_infop info_ptr, png_timep *mod_time)
- {
- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME)
- && mod_time != NULL)
- {
- png_debug1(1, "in %s retrieval function\n", "tIME");
- *mod_time = &(info_ptr->mod_time);
- return (PNG_INFO_tIME);
- }
- return (0);
- }
- #endif
-
- #if defined(PNG_tRNS_SUPPORTED)
- png_uint_32 PNGAPI
- png_get_tRNS(png_structp png_ptr, png_infop info_ptr,
- png_bytep *trans, int *num_trans, png_color_16p *trans_values)
- {
- png_uint_32 retval = 0;
- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
- {
- png_debug1(1, "in %s retrieval function\n", "tRNS");
- if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
- {
- if (trans != NULL)
- {
- *trans = info_ptr->trans;
- retval |= PNG_INFO_tRNS;
- }
- if (trans_values != NULL)
- *trans_values = &(info_ptr->trans_values);
- }
- else /* if (info_ptr->color_type != PNG_COLOR_TYPE_PALETTE) */
- {
- if (trans_values != NULL)
- {
- *trans_values = &(info_ptr->trans_values);
- retval |= PNG_INFO_tRNS;
- }
- if(trans != NULL)
- *trans = NULL;
- }
- if(num_trans != NULL)
- {
- *num_trans = info_ptr->num_trans;
- retval |= PNG_INFO_tRNS;
- }
- }
- return (retval);
- }
- #endif
-
- #if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
- png_uint_32 PNGAPI
- png_get_unknown_chunks(png_structp png_ptr, png_infop info_ptr,
- png_unknown_chunkpp unknowns)
- {
- if (png_ptr != NULL && info_ptr != NULL && unknowns != NULL)
- {
- *unknowns = info_ptr->unknown_chunks;
- return ((png_uint_32)info_ptr->unknown_chunks_num);
- }
- return (0);
- }
- #endif
-
- #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
- png_byte PNGAPI
- png_get_rgb_to_gray_status (png_structp png_ptr)
- {
- return (png_byte)(png_ptr? png_ptr->rgb_to_gray_status : 0);
- }
- #endif
-
- #if defined(PNG_USER_CHUNKS_SUPPORTED)
- png_voidp PNGAPI
- png_get_user_chunk_ptr(png_structp png_ptr)
- {
- return (png_ptr? png_ptr->user_chunk_ptr : NULL);
- }
- #endif
-
- #ifdef PNG_WRITE_SUPPORTED
- png_uint_32 PNGAPI
- png_get_compression_buffer_size(png_structp png_ptr)
- {
- return (png_uint_32)(png_ptr? png_ptr->zbuf_size : 0L);
- }
- #endif
-
- #ifdef PNG_ASSEMBLER_CODE_SUPPORTED
- #ifndef PNG_1_0_X
- /* this function was added to libpng 1.2.0 and should exist by default */
- png_uint_32 PNGAPI
- png_get_asm_flags (png_structp png_ptr)
- {
- /* obsolete, to be removed from libpng-1.4.0 */
- return (png_ptr? 0L: 0L);
- }
-
- /* this function was added to libpng 1.2.0 and should exist by default */
- png_uint_32 PNGAPI
- png_get_asm_flagmask (int flag_select)
- {
- /* obsolete, to be removed from libpng-1.4.0 */
- flag_select=flag_select;
- return 0L;
- }
-
- /* GRR: could add this: && defined(PNG_MMX_CODE_SUPPORTED) */
- /* this function was added to libpng 1.2.0 */
- png_uint_32 PNGAPI
- png_get_mmx_flagmask (int flag_select, int *compilerID)
- {
- /* obsolete, to be removed from libpng-1.4.0 */
- flag_select=flag_select;
- *compilerID = -1; /* unknown (i.e., no asm/MMX code compiled) */
- return 0L;
- }
-
- /* this function was added to libpng 1.2.0 */
- png_byte PNGAPI
- png_get_mmx_bitdepth_threshold (png_structp png_ptr)
- {
- /* obsolete, to be removed from libpng-1.4.0 */
- return (png_ptr? 0: 0);
- }
-
- /* this function was added to libpng 1.2.0 */
- png_uint_32 PNGAPI
- png_get_mmx_rowbytes_threshold (png_structp png_ptr)
- {
- /* obsolete, to be removed from libpng-1.4.0 */
- return (png_ptr? 0L: 0L);
- }
- #endif /* ?PNG_1_0_X */
- #endif /* ?PNG_ASSEMBLER_CODE_SUPPORTED */
-
- #ifdef PNG_SET_USER_LIMITS_SUPPORTED
- /* these functions were added to libpng 1.2.6 */
- png_uint_32 PNGAPI
- png_get_user_width_max (png_structp png_ptr)
- {
- return (png_ptr? png_ptr->user_width_max : 0);
- }
- png_uint_32 PNGAPI
- png_get_user_height_max (png_structp png_ptr)
- {
- return (png_ptr? png_ptr->user_height_max : 0);
- }
- #endif /* ?PNG_SET_USER_LIMITS_SUPPORTED */
-
- #endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */
- /********* End of inlined file: pngget.c *********/
-
- /********* Start of inlined file: pngmem.c *********/
- /* pngmem.c - stub functions for memory allocation
- *
- * Last changed in libpng 1.2.13 November 13, 2006
- * For conditions of distribution and use, see copyright notice in png.h
- * Copyright (c) 1998-2006 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
- *
- * This file provides a location for all memory allocation. Users who
- * need special memory handling are expected to supply replacement
- * functions for png_malloc() and png_free(), and to use
- * png_create_read_struct_2() and png_create_write_struct_2() to
- * identify the replacement functions.
- */
-
- #define PNG_INTERNAL
-
- #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
-
- /* Borland DOS special memory handler */
- #if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__)
- /* if you change this, be sure to change the one in png.h also */
-
- /* Allocate memory for a png_struct. The malloc and memset can be replaced
- by a single call to calloc() if this is thought to improve performance. */
- png_voidp /* PRIVATE */
- png_create_struct(int type)
- {
- #ifdef PNG_USER_MEM_SUPPORTED
- return (png_create_struct_2(type, png_malloc_ptr_NULL, png_voidp_NULL));
- }
-
- /* Alternate version of png_create_struct, for use with user-defined malloc. */
- png_voidp /* PRIVATE */
- png_create_struct_2(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr)
- {
- #endif /* PNG_USER_MEM_SUPPORTED */
- png_size_t size;
- png_voidp struct_ptr;
-
- if (type == PNG_STRUCT_INFO)
- size = png_sizeof(png_info);
- else if (type == PNG_STRUCT_PNG)
- size = png_sizeof(png_struct);
- else
- return (png_get_copyright(NULL));
-
- #ifdef PNG_USER_MEM_SUPPORTED
- if(malloc_fn != NULL)
- {
- png_struct dummy_struct;
- png_structp png_ptr = &dummy_struct;
- png_ptr->mem_ptr=mem_ptr;
- struct_ptr = (*(malloc_fn))(png_ptr, (png_uint_32)size);
- }
- else
- #endif /* PNG_USER_MEM_SUPPORTED */
- struct_ptr = (png_voidp)farmalloc(size);
- if (struct_ptr != NULL)
- png_memset(struct_ptr, 0, size);
- return (struct_ptr);
- }
-
- /* Free memory allocated by a png_create_struct() call */
- void /* PRIVATE */
- png_destroy_struct(png_voidp struct_ptr)
- {
- #ifdef PNG_USER_MEM_SUPPORTED
- png_destroy_struct_2(struct_ptr, png_free_ptr_NULL, png_voidp_NULL);
- }
-
- /* Free memory allocated by a png_create_struct() call */
- void /* PRIVATE */
- png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn,
- png_voidp mem_ptr)
- {
- #endif
- if (struct_ptr != NULL)
- {
- #ifdef PNG_USER_MEM_SUPPORTED
- if(free_fn != NULL)
- {
- png_struct dummy_struct;
- png_structp png_ptr = &dummy_struct;
- png_ptr->mem_ptr=mem_ptr;
- (*(free_fn))(png_ptr, struct_ptr);
- return;
- }
- #endif /* PNG_USER_MEM_SUPPORTED */
- farfree (struct_ptr);
- }
- }
-
- /* Allocate memory. For reasonable files, size should never exceed
- * 64K. However, zlib may allocate more then 64K if you don't tell
- * it not to. See zconf.h and png.h for more information. zlib does
- * need to allocate exactly 64K, so whatever you call here must
- * have the ability to do that.
- *
- * Borland seems to have a problem in DOS mode for exactly 64K.
- * It gives you a segment with an offset of 8 (perhaps to store its
- * memory stuff). zlib doesn't like this at all, so we have to
- * detect and deal with it. This code should not be needed in
- * Windows or OS/2 modes, and only in 16 bit mode. This code has
- * been updated by Alexander Lehmann for version 0.89 to waste less
- * memory.
- *
- * Note that we can't use png_size_t for the "size" declaration,
- * since on some systems a png_size_t is a 16-bit quantity, and as a
- * result, we would be truncating potentially larger memory requests
- * (which should cause a fatal error) and introducing major problems.
- */
-
- png_voidp PNGAPI
- png_malloc(png_structp png_ptr, png_uint_32 size)
- {
- png_voidp ret;
-
- if (png_ptr == NULL || size == 0)
- return (NULL);
-
- #ifdef PNG_USER_MEM_SUPPORTED
- if(png_ptr->malloc_fn != NULL)
- ret = ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, (png_size_t)size));
- else
- ret = (png_malloc_default(png_ptr, size));
- if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
- png_error(png_ptr, "Out of memory!");
- return (ret);
- }
-
- png_voidp PNGAPI
- png_malloc_default(png_structp png_ptr, png_uint_32 size)
- {
- png_voidp ret;
- #endif /* PNG_USER_MEM_SUPPORTED */
-
- if (png_ptr == NULL || size == 0)
- return (NULL);
-
- #ifdef PNG_MAX_MALLOC_64K
- if (size > (png_uint_32)65536L)
- {
- png_warning(png_ptr, "Cannot Allocate > 64K");
- ret = NULL;
- }
- else
- #endif
-
- if (size != (size_t)size)
- ret = NULL;
- else if (size == (png_uint_32)65536L)
- {
- if (png_ptr->offset_table == NULL)
- {
- /* try to see if we need to do any of this fancy stuff */
- ret = farmalloc(size);
- if (ret == NULL || ((png_size_t)ret & 0xffff))
- {
- int num_blocks;
- png_uint_32 total_size;
- png_bytep table;
- int i;
- png_byte huge * hptr;
-
- if (ret != NULL)
- {
- farfree(ret);
- ret = NULL;
- }
-
- if(png_ptr->zlib_window_bits > 14)
- num_blocks = (int)(1 << (png_ptr->zlib_window_bits - 14));
- else
- num_blocks = 1;
- if (png_ptr->zlib_mem_level >= 7)
- num_blocks += (int)(1 << (png_ptr->zlib_mem_level - 7));
- else
- num_blocks++;
-
- total_size = ((png_uint_32)65536L) * (png_uint_32)num_blocks+16;
-
- table = farmalloc(total_size);
-
- if (table == NULL)
- {
- #ifndef PNG_USER_MEM_SUPPORTED
- if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
- png_error(png_ptr, "Out Of Memory."); /* Note "O" and "M" */
- else
- png_warning(png_ptr, "Out Of Memory.");
- #endif
- return (NULL);
- }
-
- if ((png_size_t)table & 0xfff0)
- {
- #ifndef PNG_USER_MEM_SUPPORTED
- if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
- png_error(png_ptr,
- "Farmalloc didn't return normalized pointer");
- else
- png_warning(png_ptr,
- "Farmalloc didn't return normalized pointer");
- #endif
- return (NULL);
- }
-
- png_ptr->offset_table = table;
- png_ptr->offset_table_ptr = farmalloc(num_blocks *
- png_sizeof (png_bytep));
-
- if (png_ptr->offset_table_ptr == NULL)
- {
- #ifndef PNG_USER_MEM_SUPPORTED
- if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
- png_error(png_ptr, "Out Of memory."); /* Note "O" and "M" */
- else
- png_warning(png_ptr, "Out Of memory.");
- #endif
- return (NULL);
- }
-
- hptr = (png_byte huge *)table;
- if ((png_size_t)hptr & 0xf)
- {
- hptr = (png_byte huge *)((long)(hptr) & 0xfffffff0L);
- hptr = hptr + 16L; /* "hptr += 16L" fails on Turbo C++ 3.0 */
- }
- for (i = 0; i < num_blocks; i++)
- {
- png_ptr->offset_table_ptr[i] = (png_bytep)hptr;
- hptr = hptr + (png_uint_32)65536L; /* "+=" fails on TC++3.0 */
- }
-
- png_ptr->offset_table_number = num_blocks;
- png_ptr->offset_table_count = 0;
- png_ptr->offset_table_count_free = 0;
- }
- }
-
- if (png_ptr->offset_table_count >= png_ptr->offset_table_number)
- {
- #ifndef PNG_USER_MEM_SUPPORTED
- if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
- png_error(png_ptr, "Out of Memory."); /* Note "o" and "M" */
- else
- png_warning(png_ptr, "Out of Memory.");
- #endif
- return (NULL);
- }
-
- ret = png_ptr->offset_table_ptr[png_ptr->offset_table_count++];
- }
- else
- ret = farmalloc(size);
-
- #ifndef PNG_USER_MEM_SUPPORTED
- if (ret == NULL)
- {
- if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
- png_error(png_ptr, "Out of memory."); /* Note "o" and "m" */
- else
- png_warning(png_ptr, "Out of memory."); /* Note "o" and "m" */
- }
- #endif
-
- return (ret);
- }
-
- /* free a pointer allocated by png_malloc(). In the default
- configuration, png_ptr is not used, but is passed in case it
- is needed. If ptr is NULL, return without taking any action. */
- void PNGAPI
- png_free(png_structp png_ptr, png_voidp ptr)
- {
- if (png_ptr == NULL || ptr == NULL)
- return;
-
- #ifdef PNG_USER_MEM_SUPPORTED
- if (png_ptr->free_fn != NULL)
- {
- (*(png_ptr->free_fn))(png_ptr, ptr);
- return;
- }
- else png_free_default(png_ptr, ptr);
- }
-
- void PNGAPI
- png_free_default(png_structp png_ptr, png_voidp ptr)
- {
- #endif /* PNG_USER_MEM_SUPPORTED */
-
- if(png_ptr == NULL) return;
-
- if (png_ptr->offset_table != NULL)
- {
- int i;
-
- for (i = 0; i < png_ptr->offset_table_count; i++)
- {
- if (ptr == png_ptr->offset_table_ptr[i])
- {
- ptr = NULL;
- png_ptr->offset_table_count_free++;
- break;
- }
- }
- if (png_ptr->offset_table_count_free == png_ptr->offset_table_count)
- {
- farfree(png_ptr->offset_table);
- farfree(png_ptr->offset_table_ptr);
- png_ptr->offset_table = NULL;
- png_ptr->offset_table_ptr = NULL;
- }
- }
-
- if (ptr != NULL)
- {
- farfree(ptr);
- }
- }
-
- #else /* Not the Borland DOS special memory handler */
-
- /* Allocate memory for a png_struct or a png_info. The malloc and
- memset can be replaced by a single call to calloc() if this is thought
- to improve performance noticably. */
- png_voidp /* PRIVATE */
- png_create_struct(int type)
- {
- #ifdef PNG_USER_MEM_SUPPORTED
- return (png_create_struct_2(type, png_malloc_ptr_NULL, png_voidp_NULL));
- }
-
- /* Allocate memory for a png_struct or a png_info. The malloc and
- memset can be replaced by a single call to calloc() if this is thought
- to improve performance noticably. */
- png_voidp /* PRIVATE */
- png_create_struct_2(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr)
- {
- #endif /* PNG_USER_MEM_SUPPORTED */
- png_size_t size;
- png_voidp struct_ptr;
-
- if (type == PNG_STRUCT_INFO)
- size = png_sizeof(png_info);
- else if (type == PNG_STRUCT_PNG)
- size = png_sizeof(png_struct);
- else
- return (NULL);
-
- #ifdef PNG_USER_MEM_SUPPORTED
- if(malloc_fn != NULL)
- {
- png_struct dummy_struct;
- png_structp png_ptr = &dummy_struct;
- png_ptr->mem_ptr=mem_ptr;
- struct_ptr = (*(malloc_fn))(png_ptr, size);
- if (struct_ptr != NULL)
- png_memset(struct_ptr, 0, size);
- return (struct_ptr);
- }
- #endif /* PNG_USER_MEM_SUPPORTED */
-
- #if defined(__TURBOC__) && !defined(__FLAT__)
- struct_ptr = (png_voidp)farmalloc(size);
- #else
- # if defined(_MSC_VER) && defined(MAXSEG_64K)
- struct_ptr = (png_voidp)halloc(size,1);
- # else
- struct_ptr = (png_voidp)malloc(size);
- # endif
- #endif
- if (struct_ptr != NULL)
- png_memset(struct_ptr, 0, size);
-
- return (struct_ptr);
- }
-
- /* Free memory allocated by a png_create_struct() call */
- void /* PRIVATE */
- png_destroy_struct(png_voidp struct_ptr)
- {
- #ifdef PNG_USER_MEM_SUPPORTED
- png_destroy_struct_2(struct_ptr, png_free_ptr_NULL, png_voidp_NULL);
- }
-
- /* Free memory allocated by a png_create_struct() call */
- void /* PRIVATE */
- png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn,
- png_voidp mem_ptr)
- {
- #endif /* PNG_USER_MEM_SUPPORTED */
- if (struct_ptr != NULL)
- {
- #ifdef PNG_USER_MEM_SUPPORTED
- if(free_fn != NULL)
- {
- png_struct dummy_struct;
- png_structp png_ptr = &dummy_struct;
- png_ptr->mem_ptr=mem_ptr;
- (*(free_fn))(png_ptr, struct_ptr);
- return;
- }
- #endif /* PNG_USER_MEM_SUPPORTED */
- #if defined(__TURBOC__) && !defined(__FLAT__)
- farfree(struct_ptr);
- #else
- # if defined(_MSC_VER) && defined(MAXSEG_64K)
- hfree(struct_ptr);
- # else
- free(struct_ptr);
- # endif
- #endif
- }
- }
-
- /* Allocate memory. For reasonable files, size should never exceed
- 64K. However, zlib may allocate more then 64K if you don't tell
- it not to. See zconf.h and png.h for more information. zlib does
- need to allocate exactly 64K, so whatever you call here must
- have the ability to do that. */
-
- png_voidp PNGAPI
- png_malloc(png_structp png_ptr, png_uint_32 size)
- {
- png_voidp ret;
-
- #ifdef PNG_USER_MEM_SUPPORTED
- if (png_ptr == NULL || size == 0)
- return (NULL);
-
- if(png_ptr->malloc_fn != NULL)
- ret = ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, (png_size_t)size));
- else
- ret = (png_malloc_default(png_ptr, size));
- if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
- png_error(png_ptr, "Out of Memory!");
- return (ret);
- }
-
- png_voidp PNGAPI
- png_malloc_default(png_structp png_ptr, png_uint_32 size)
- {
- png_voidp ret;
- #endif /* PNG_USER_MEM_SUPPORTED */
-
- if (png_ptr == NULL || size == 0)
- return (NULL);
-
- #ifdef PNG_MAX_MALLOC_64K
- if (size > (png_uint_32)65536L)
- {
- #ifndef PNG_USER_MEM_SUPPORTED
- if(png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
- png_error(png_ptr, "Cannot Allocate > 64K");
- else
- #endif
- return NULL;
- }
- #endif
-
- /* Check for overflow */
- #if defined(__TURBOC__) && !defined(__FLAT__)
- if (size != (unsigned long)size)
- ret = NULL;
- else
- ret = farmalloc(size);
- #else
- # if defined(_MSC_VER) && defined(MAXSEG_64K)
- if (size != (unsigned long)size)
- ret = NULL;
- else
- ret = halloc(size, 1);
- # else
- if (size != (size_t)size)
- ret = NULL;
- else
- ret = malloc((size_t)size);
- # endif
- #endif
-
- #ifndef PNG_USER_MEM_SUPPORTED
- if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
- png_error(png_ptr, "Out of Memory");
- #endif
-
- return (ret);
- }
-
- /* Free a pointer allocated by png_malloc(). If ptr is NULL, return
- without taking any action. */
- void PNGAPI
- png_free(png_structp png_ptr, png_voidp ptr)
- {
- if (png_ptr == NULL || ptr == NULL)
- return;
-
- #ifdef PNG_USER_MEM_SUPPORTED
- if (png_ptr->free_fn != NULL)
- {
- (*(png_ptr->free_fn))(png_ptr, ptr);
- return;
- }
- else png_free_default(png_ptr, ptr);
- }
- void PNGAPI
- png_free_default(png_structp png_ptr, png_voidp ptr)
- {
- if (png_ptr == NULL || ptr == NULL)
- return;
-
- #endif /* PNG_USER_MEM_SUPPORTED */
-
- #if defined(__TURBOC__) && !defined(__FLAT__)
- farfree(ptr);
- #else
- # if defined(_MSC_VER) && defined(MAXSEG_64K)
- hfree(ptr);
- # else
- free(ptr);
- # endif
- #endif
- }
-
- #endif /* Not Borland DOS special memory handler */
-
- #if defined(PNG_1_0_X)
- # define png_malloc_warn png_malloc
- #else
- /* This function was added at libpng version 1.2.3. The png_malloc_warn()
- * function will set up png_malloc() to issue a png_warning and return NULL
- * instead of issuing a png_error, if it fails to allocate the requested
- * memory.
- */
- png_voidp PNGAPI
- png_malloc_warn(png_structp png_ptr, png_uint_32 size)
- {
- png_voidp ptr;
- png_uint_32 save_flags;
- if(png_ptr == NULL) return (NULL);
-
- save_flags=png_ptr->flags;
- png_ptr->flags|=PNG_FLAG_MALLOC_NULL_MEM_OK;
- ptr = (png_voidp)png_malloc((png_structp)png_ptr, size);
- png_ptr->flags=save_flags;
- return(ptr);
- }
- #endif
-
- png_voidp PNGAPI
- png_memcpy_check (png_structp png_ptr, png_voidp s1, png_voidp s2,
- png_uint_32 length)
- {
- png_size_t size;
-
- size = (png_size_t)length;
- if ((png_uint_32)size != length)
- png_error(png_ptr,"Overflow in png_memcpy_check.");
-
- return(png_memcpy (s1, s2, size));
- }
-
- png_voidp PNGAPI
- png_memset_check (png_structp png_ptr, png_voidp s1, int value,
- png_uint_32 length)
- {
- png_size_t size;
-
- size = (png_size_t)length;
- if ((png_uint_32)size != length)
- png_error(png_ptr,"Overflow in png_memset_check.");
-
- return (png_memset (s1, value, size));
-
- }
-
- #ifdef PNG_USER_MEM_SUPPORTED
- /* This function is called when the application wants to use another method
- * of allocating and freeing memory.
- */
- void PNGAPI
- png_set_mem_fn(png_structp png_ptr, png_voidp mem_ptr, png_malloc_ptr
- malloc_fn, png_free_ptr free_fn)
- {
- if(png_ptr != NULL) {
- png_ptr->mem_ptr = mem_ptr;
- png_ptr->malloc_fn = malloc_fn;
- png_ptr->free_fn = free_fn;
- }
- }
-
- /* This function returns a pointer to the mem_ptr associated with the user
- * functions. The application should free any memory associated with this
- * pointer before png_write_destroy and png_read_destroy are called.
- */
- png_voidp PNGAPI
- png_get_mem_ptr(png_structp png_ptr)
- {
- if(png_ptr == NULL) return (NULL);
- return ((png_voidp)png_ptr->mem_ptr);
- }
- #endif /* PNG_USER_MEM_SUPPORTED */
- #endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */
- /********* End of inlined file: pngmem.c *********/
-
- /********* Start of inlined file: pngread.c *********/
- /* pngread.c - read a PNG file
- *
- * Last changed in libpng 1.2.20 September 7, 2007
- * For conditions of distribution and use, see copyright notice in png.h
- * Copyright (c) 1998-2007 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
- *
- * This file contains routines that an application calls directly to
- * read a PNG file or stream.
- */
-
- #define PNG_INTERNAL
-
- #if defined(PNG_READ_SUPPORTED)
-
- /* Create a PNG structure for reading, and allocate any memory needed. */
- png_structp PNGAPI
- png_create_read_struct(png_const_charp user_png_ver, png_voidp error_ptr,
- png_error_ptr error_fn, png_error_ptr warn_fn)
- {
-
- #ifdef PNG_USER_MEM_SUPPORTED
- return (png_create_read_struct_2(user_png_ver, error_ptr, error_fn,
- warn_fn, png_voidp_NULL, png_malloc_ptr_NULL, png_free_ptr_NULL));
- }
-
- /* Alternate create PNG structure for reading, and allocate any memory needed. */
- png_structp PNGAPI
- png_create_read_struct_2(png_const_charp user_png_ver, png_voidp error_ptr,
- png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
- png_malloc_ptr malloc_fn, png_free_ptr free_fn)
- {
- #endif /* PNG_USER_MEM_SUPPORTED */
-
- png_structp png_ptr;
-
- #ifdef PNG_SETJMP_SUPPORTED
- #ifdef USE_FAR_KEYWORD
- jmp_buf jmpbuf;
- #endif
- #endif
-
- int i;
-
- png_debug(1, "in png_create_read_struct\n");
- #ifdef PNG_USER_MEM_SUPPORTED
- png_ptr = (png_structp)png_create_struct_2(PNG_STRUCT_PNG,
- (png_malloc_ptr)malloc_fn, (png_voidp)mem_ptr);
- #else
- png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG);
- #endif
- if (png_ptr == NULL)
- return (NULL);
-
- /* added at libpng-1.2.6 */
- #ifdef PNG_SET_USER_LIMITS_SUPPORTED
- png_ptr->user_width_max=PNG_USER_WIDTH_MAX;
- png_ptr->user_height_max=PNG_USER_HEIGHT_MAX;
- #endif
-
- #ifdef PNG_SETJMP_SUPPORTED
- #ifdef USE_FAR_KEYWORD
- if (setjmp(jmpbuf))
- #else
- if (setjmp(png_ptr->jmpbuf))
- #endif
- {
- png_free(png_ptr, png_ptr->zbuf);
- png_ptr->zbuf=NULL;
- #ifdef PNG_USER_MEM_SUPPORTED
- png_destroy_struct_2((png_voidp)png_ptr,
- (png_free_ptr)free_fn, (png_voidp)mem_ptr);
- #else
- png_destroy_struct((png_voidp)png_ptr);
- #endif
- return (NULL);
- }
- #ifdef USE_FAR_KEYWORD
- png_memcpy(png_ptr->jmpbuf,jmpbuf,png_sizeof(jmp_buf));
- #endif
- #endif
-
- #ifdef PNG_USER_MEM_SUPPORTED
- png_set_mem_fn(png_ptr, mem_ptr, malloc_fn, free_fn);
- #endif
-
- png_set_error_fn(png_ptr, error_ptr, error_fn, warn_fn);
-
- i=0;
- do
- {
- if(user_png_ver[i] != png_libpng_ver[i])
- png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
- } while (png_libpng_ver[i++]);
-
- if (png_ptr->flags & PNG_FLAG_LIBRARY_MISMATCH)
- {
- /* Libpng 0.90 and later are binary incompatible with libpng 0.89, so
- * we must recompile any applications that use any older library version.
- * For versions after libpng 1.0, we will be compatible, so we need
- * only check the first digit.
- */
- if (user_png_ver == NULL || user_png_ver[0] != png_libpng_ver[0] ||
- (user_png_ver[0] == '1' && user_png_ver[2] != png_libpng_ver[2]) ||
- (user_png_ver[0] == '0' && user_png_ver[2] < '9'))
- {
- #if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
- char msg[80];
- if (user_png_ver)
- {
- png_snprintf(msg, 80,
- "Application was compiled with png.h from libpng-%.20s",
- user_png_ver);
- png_warning(png_ptr, msg);
- }
- png_snprintf(msg, 80,
- "Application is running with png.c from libpng-%.20s",
- png_libpng_ver);
- png_warning(png_ptr, msg);
- #endif
- #ifdef PNG_ERROR_NUMBERS_SUPPORTED
- png_ptr->flags=0;
- #endif
- png_error(png_ptr,
- "Incompatible libpng version in application and library");
- }
- }
-
- /* initialize zbuf - compression buffer */
- png_ptr->zbuf_size = PNG_ZBUF_SIZE;
- png_ptr->zbuf = (png_bytep)png_malloc(png_ptr,
- (png_uint_32)png_ptr->zbuf_size);
- png_ptr->zstream.zalloc = png_zalloc;
- png_ptr->zstream.zfree = png_zfree;
- png_ptr->zstream.opaque = (voidpf)png_ptr;
-
- switch (inflateInit(&png_ptr->zstream))
- {
- case Z_OK: /* Do nothing */ break;
- case Z_MEM_ERROR:
- case Z_STREAM_ERROR: png_error(png_ptr, "zlib memory error"); break;
- case Z_VERSION_ERROR: png_error(png_ptr, "zlib version error"); break;
- default: png_error(png_ptr, "Unknown zlib error");
- }
-
- png_ptr->zstream.next_out = png_ptr->zbuf;
- png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
-
- png_set_read_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL);
-
- #ifdef PNG_SETJMP_SUPPORTED
- /* Applications that neglect to set up their own setjmp() and then encounter
- a png_error() will longjmp here. Since the jmpbuf is then meaningless we
- abort instead of returning. */
- #ifdef USE_FAR_KEYWORD
- if (setjmp(jmpbuf))
- PNG_ABORT();
- png_memcpy(png_ptr->jmpbuf,jmpbuf,png_sizeof(jmp_buf));
- #else
- if (setjmp(png_ptr->jmpbuf))
- PNG_ABORT();
- #endif
- #endif
- return (png_ptr);
- }
-
- #if defined(PNG_1_0_X) || defined(PNG_1_2_X)
- /* Initialize PNG structure for reading, and allocate any memory needed.
- This interface is deprecated in favour of the png_create_read_struct(),
- and it will disappear as of libpng-1.3.0. */
- #undef png_read_init
- void PNGAPI
- png_read_init(png_structp png_ptr)
- {
- /* We only come here via pre-1.0.7-compiled applications */
- png_read_init_2(png_ptr, "1.0.6 or earlier", 0, 0);
- }
-
- void PNGAPI
- png_read_init_2(png_structp png_ptr, png_const_charp user_png_ver,
- png_size_t png_struct_size, png_size_t png_info_size)
- {
- /* We only come here via pre-1.0.12-compiled applications */
- if(png_ptr == NULL) return;
- #if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
- if(png_sizeof(png_struct) > png_struct_size ||
- png_sizeof(png_info) > png_info_size)
- {
- char msg[80];
- png_ptr->warning_fn=NULL;
- if (user_png_ver)
- {
- png_snprintf(msg, 80,
- "Application was compiled with png.h from libpng-%.20s",
- user_png_ver);
- png_warning(png_ptr, msg);
- }
- png_snprintf(msg, 80,
- "Application is running with png.c from libpng-%.20s",
- png_libpng_ver);
- png_warning(png_ptr, msg);
- }
- #endif
- if(png_sizeof(png_struct) > png_struct_size)
- {
- png_ptr->error_fn=NULL;
- #ifdef PNG_ERROR_NUMBERS_SUPPORTED
- png_ptr->flags=0;
- #endif
- png_error(png_ptr,
- "The png struct allocated by the application for reading is too small.");
- }
- if(png_sizeof(png_info) > png_info_size)
- {
- png_ptr->error_fn=NULL;
- #ifdef PNG_ERROR_NUMBERS_SUPPORTED
- png_ptr->flags=0;
- #endif
- png_error(png_ptr,
- "The info struct allocated by application for reading is too small.");
- }
- png_read_init_3(&png_ptr, user_png_ver, png_struct_size);
- }
- #endif /* PNG_1_0_X || PNG_1_2_X */
-
- void PNGAPI
- png_read_init_3(png_structpp ptr_ptr, png_const_charp user_png_ver,
- png_size_t png_struct_size)
- {
- #ifdef PNG_SETJMP_SUPPORTED
- jmp_buf tmp_jmp; /* to save current jump buffer */
- #endif
-
- int i=0;
-
- png_structp png_ptr=*ptr_ptr;
-
- if(png_ptr == NULL) return;
-
- do
- {
- if(user_png_ver[i] != png_libpng_ver[i])
- {
- #ifdef PNG_LEGACY_SUPPORTED
- png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
- #else
- png_ptr->warning_fn=NULL;
- png_warning(png_ptr,
- "Application uses deprecated png_read_init() and should be recompiled.");
- break;
- #endif
- }
- } while (png_libpng_ver[i++]);
-
- png_debug(1, "in png_read_init_3\n");
-
- #ifdef PNG_SETJMP_SUPPORTED
- /* save jump buffer and error functions */
- png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof (jmp_buf));
- #endif
-
- if(png_sizeof(png_struct) > png_struct_size)
- {
- png_destroy_struct(png_ptr);
- *ptr_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG);
- png_ptr = *ptr_ptr;
- }
-
- /* reset all variables to 0 */
- png_memset(png_ptr, 0, png_sizeof (png_struct));
-
- #ifdef PNG_SETJMP_SUPPORTED
- /* restore jump buffer */
- png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof (jmp_buf));
- #endif
-
- /* added at libpng-1.2.6 */
- #ifdef PNG_SET_USER_LIMITS_SUPPORTED
- png_ptr->user_width_max=PNG_USER_WIDTH_MAX;
- png_ptr->user_height_max=PNG_USER_HEIGHT_MAX;
- #endif
-
- /* initialize zbuf - compression buffer */
- png_ptr->zbuf_size = PNG_ZBUF_SIZE;
- png_ptr->zbuf = (png_bytep)png_malloc(png_ptr,
- (png_uint_32)png_ptr->zbuf_size);
- png_ptr->zstream.zalloc = png_zalloc;
- png_ptr->zstream.zfree = png_zfree;
- png_ptr->zstream.opaque = (voidpf)png_ptr;
-
- switch (inflateInit(&png_ptr->zstream))
- {
- case Z_OK: /* Do nothing */ break;
- case Z_MEM_ERROR:
- case Z_STREAM_ERROR: png_error(png_ptr, "zlib memory"); break;
- case Z_VERSION_ERROR: png_error(png_ptr, "zlib version"); break;
- default: png_error(png_ptr, "Unknown zlib error");
- }
-
- png_ptr->zstream.next_out = png_ptr->zbuf;
- png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
-
- png_set_read_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL);
- }
-
- #ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
- /* Read the information before the actual image data. This has been
- * changed in v0.90 to allow reading a file that already has the magic
- * bytes read from the stream. You can tell libpng how many bytes have
- * been read from the beginning of the stream (up to the maximum of 8)
- * via png_set_sig_bytes(), and we will only check the remaining bytes
- * here. The application can then have access to the signature bytes we
- * read if it is determined that this isn't a valid PNG file.
- */
- void PNGAPI
- png_read_info(png_structp png_ptr, png_infop info_ptr)
- {
- if(png_ptr == NULL) return;
- png_debug(1, "in png_read_info\n");
- /* If we haven't checked all of the PNG signature bytes, do so now. */
- if (png_ptr->sig_bytes < 8)
- {
- png_size_t num_checked = png_ptr->sig_bytes,
- num_to_check = 8 - num_checked;
-
- png_read_data(png_ptr, &(info_ptr->signature[num_checked]), num_to_check);
- png_ptr->sig_bytes = 8;
-
- if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check))
- {
- if (num_checked < 4 &&
- png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))
- png_error(png_ptr, "Not a PNG file");
- else
- png_error(png_ptr, "PNG file corrupted by ASCII conversion");
- }
- if (num_checked < 3)
- png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE;
- }
-
- for(;;)
- {
- #ifdef PNG_USE_LOCAL_ARRAYS
- PNG_CONST PNG_IHDR;
- PNG_CONST PNG_IDAT;
- PNG_CONST PNG_IEND;
- PNG_CONST PNG_PLTE;
- #if defined(PNG_READ_bKGD_SUPPORTED)
- PNG_CONST PNG_bKGD;
- #endif
- #if defined(PNG_READ_cHRM_SUPPORTED)
- PNG_CONST PNG_cHRM;
- #endif
- #if defined(PNG_READ_gAMA_SUPPORTED)
- PNG_CONST PNG_gAMA;
- #endif
- #if defined(PNG_READ_hIST_SUPPORTED)
- PNG_CONST PNG_hIST;
- #endif
- #if defined(PNG_READ_iCCP_SUPPORTED)
- PNG_CONST PNG_iCCP;
- #endif
- #if defined(PNG_READ_iTXt_SUPPORTED)
- PNG_CONST PNG_iTXt;
- #endif
- #if defined(PNG_READ_oFFs_SUPPORTED)
- PNG_CONST PNG_oFFs;
- #endif
- #if defined(PNG_READ_pCAL_SUPPORTED)
- PNG_CONST PNG_pCAL;
- #endif
- #if defined(PNG_READ_pHYs_SUPPORTED)
- PNG_CONST PNG_pHYs;
- #endif
- #if defined(PNG_READ_sBIT_SUPPORTED)
- PNG_CONST PNG_sBIT;
- #endif
- #if defined(PNG_READ_sCAL_SUPPORTED)
- PNG_CONST PNG_sCAL;
- #endif
- #if defined(PNG_READ_sPLT_SUPPORTED)
- PNG_CONST PNG_sPLT;
- #endif
- #if defined(PNG_READ_sRGB_SUPPORTED)
- PNG_CONST PNG_sRGB;
- #endif
- #if defined(PNG_READ_tEXt_SUPPORTED)
- PNG_CONST PNG_tEXt;
- #endif
- #if defined(PNG_READ_tIME_SUPPORTED)
- PNG_CONST PNG_tIME;
- #endif
- #if defined(PNG_READ_tRNS_SUPPORTED)
- PNG_CONST PNG_tRNS;
- #endif
- #if defined(PNG_READ_zTXt_SUPPORTED)
- PNG_CONST PNG_zTXt;
- #endif
- #endif /* PNG_USE_LOCAL_ARRAYS */
- png_byte chunk_length[4];
- png_uint_32 length;
-
- png_read_data(png_ptr, chunk_length, 4);
- length = png_get_uint_31(png_ptr,chunk_length);
-
- png_reset_crc(png_ptr);
- png_crc_read(png_ptr, png_ptr->chunk_name, 4);
-
- png_debug2(0, "Reading %s chunk, length=%lu.\n", png_ptr->chunk_name,
- length);
-
- /* This should be a binary subdivision search or a hash for
- * matching the chunk name rather than a linear search.
- */
- if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
- if(png_ptr->mode & PNG_AFTER_IDAT)
- png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT;
-
- if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4))
- png_handle_IHDR(png_ptr, info_ptr, length);
- else if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4))
- png_handle_IEND(png_ptr, info_ptr, length);
- #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
- else if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name))
- {
- if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
- png_ptr->mode |= PNG_HAVE_IDAT;
- png_handle_unknown(png_ptr, info_ptr, length);
- if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
- png_ptr->mode |= PNG_HAVE_PLTE;
- else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
- {
- if (!(png_ptr->mode & PNG_HAVE_IHDR))
- png_error(png_ptr, "Missing IHDR before IDAT");
- else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
- !(png_ptr->mode & PNG_HAVE_PLTE))
- png_error(png_ptr, "Missing PLTE before IDAT");
- break;
- }
- }
- #endif
- else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
- png_handle_PLTE(png_ptr, info_ptr, length);
- else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
- {
- if (!(png_ptr->mode & PNG_HAVE_IHDR))
- png_error(png_ptr, "Missing IHDR before IDAT");
- else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
- !(png_ptr->mode & PNG_HAVE_PLTE))
- png_error(png_ptr, "Missing PLTE before IDAT");
-
- png_ptr->idat_size = length;
- png_ptr->mode |= PNG_HAVE_IDAT;
- break;
- }
- #if defined(PNG_READ_bKGD_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_bKGD, 4))
- png_handle_bKGD(png_ptr, info_ptr, length);
- #endif
- #if defined(PNG_READ_cHRM_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_cHRM, 4))
- png_handle_cHRM(png_ptr, info_ptr, length);
- #endif
- #if defined(PNG_READ_gAMA_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_gAMA, 4))
- png_handle_gAMA(png_ptr, info_ptr, length);
- #endif
- #if defined(PNG_READ_hIST_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_hIST, 4))
- png_handle_hIST(png_ptr, info_ptr, length);
- #endif
- #if defined(PNG_READ_oFFs_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_oFFs, 4))
- png_handle_oFFs(png_ptr, info_ptr, length);
- #endif
- #if defined(PNG_READ_pCAL_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_pCAL, 4))
- png_handle_pCAL(png_ptr, info_ptr, length);
- #endif
- #if defined(PNG_READ_sCAL_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_sCAL, 4))
- png_handle_sCAL(png_ptr, info_ptr, length);
- #endif
- #if defined(PNG_READ_pHYs_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4))
- png_handle_pHYs(png_ptr, info_ptr, length);
- #endif
- #if defined(PNG_READ_sBIT_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_sBIT, 4))
- png_handle_sBIT(png_ptr, info_ptr, length);
- #endif
- #if defined(PNG_READ_sRGB_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_sRGB, 4))
- png_handle_sRGB(png_ptr, info_ptr, length);
- #endif
- #if defined(PNG_READ_iCCP_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_iCCP, 4))
- png_handle_iCCP(png_ptr, info_ptr, length);
- #endif
- #if defined(PNG_READ_sPLT_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_sPLT, 4))
- png_handle_sPLT(png_ptr, info_ptr, length);
- #endif
- #if defined(PNG_READ_tEXt_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4))
- png_handle_tEXt(png_ptr, info_ptr, length);
- #endif
- #if defined(PNG_READ_tIME_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_tIME, 4))
- png_handle_tIME(png_ptr, info_ptr, length);
- #endif
- #if defined(PNG_READ_tRNS_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_tRNS, 4))
- png_handle_tRNS(png_ptr, info_ptr, length);
- #endif
- #if defined(PNG_READ_zTXt_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4))
- png_handle_zTXt(png_ptr, info_ptr, length);
- #endif
- #if defined(PNG_READ_iTXt_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_iTXt, 4))
- png_handle_iTXt(png_ptr, info_ptr, length);
- #endif
- else
- png_handle_unknown(png_ptr, info_ptr, length);
- }
- }
- #endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
-
- /* optional call to update the users info_ptr structure */
- void PNGAPI
- png_read_update_info(png_structp png_ptr, png_infop info_ptr)
- {
- png_debug(1, "in png_read_update_info\n");
- if(png_ptr == NULL) return;
- if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
- png_read_start_row(png_ptr);
- else
- png_warning(png_ptr,
- "Ignoring extra png_read_update_info() call; row buffer not reallocated");
- png_read_transform_info(png_ptr, info_ptr);
- }
-
- #ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
- /* Initialize palette, background, etc, after transformations
- * are set, but before any reading takes place. This allows
- * the user to obtain a gamma-corrected palette, for example.
- * If the user doesn't call this, we will do it ourselves.
- */
- void PNGAPI
- png_start_read_image(png_structp png_ptr)
- {
- png_debug(1, "in png_start_read_image\n");
- if(png_ptr == NULL) return;
- if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
- png_read_start_row(png_ptr);
- }
- #endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
-
- #ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
- void PNGAPI
- png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
- {
- #ifdef PNG_USE_LOCAL_ARRAYS
- PNG_CONST PNG_IDAT;
- PNG_CONST int png_pass_dsp_mask[7] = {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55,
- 0xff};
- PNG_CONST int png_pass_mask[7] = {0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff};
- #endif
- int ret;
- if(png_ptr == NULL) return;
- png_debug2(1, "in png_read_row (row %lu, pass %d)\n",
- png_ptr->row_number, png_ptr->pass);
- if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
- png_read_start_row(png_ptr);
- if (png_ptr->row_number == 0 && png_ptr->pass == 0)
- {
- /* check for transforms that have been set but were defined out */
- #if defined(PNG_WRITE_INVERT_SUPPORTED) && !defined(PNG_READ_INVERT_SUPPORTED)
- if (png_ptr->transformations & PNG_INVERT_MONO)
- png_warning(png_ptr, "PNG_READ_INVERT_SUPPORTED is not defined.");
- #endif
- #if defined(PNG_WRITE_FILLER_SUPPORTED) && !defined(PNG_READ_FILLER_SUPPORTED)
- if (png_ptr->transformations & PNG_FILLER)
- png_warning(png_ptr, "PNG_READ_FILLER_SUPPORTED is not defined.");
- #endif
- #if defined(PNG_WRITE_PACKSWAP_SUPPORTED) && !defined(PNG_READ_PACKSWAP_SUPPORTED)
- if (png_ptr->transformations & PNG_PACKSWAP)
- png_warning(png_ptr, "PNG_READ_PACKSWAP_SUPPORTED is not defined.");
- #endif
- #if defined(PNG_WRITE_PACK_SUPPORTED) && !defined(PNG_READ_PACK_SUPPORTED)
- if (png_ptr->transformations & PNG_PACK)
- png_warning(png_ptr, "PNG_READ_PACK_SUPPORTED is not defined.");
- #endif
- #if defined(PNG_WRITE_SHIFT_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED)
- if (png_ptr->transformations & PNG_SHIFT)
- png_warning(png_ptr, "PNG_READ_SHIFT_SUPPORTED is not defined.");
- #endif
- #if defined(PNG_WRITE_BGR_SUPPORTED) && !defined(PNG_READ_BGR_SUPPORTED)
- if (png_ptr->transformations & PNG_BGR)
- png_warning(png_ptr, "PNG_READ_BGR_SUPPORTED is not defined.");
- #endif
- #if defined(PNG_WRITE_SWAP_SUPPORTED) && !defined(PNG_READ_SWAP_SUPPORTED)
- if (png_ptr->transformations & PNG_SWAP_BYTES)
- png_warning(png_ptr, "PNG_READ_SWAP_SUPPORTED is not defined.");
- #endif
- }
-
- #if defined(PNG_READ_INTERLACING_SUPPORTED)
- /* if interlaced and we do not need a new row, combine row and return */
- if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
- {
- switch (png_ptr->pass)
- {
- case 0:
- if (png_ptr->row_number & 0x07)
- {
- if (dsp_row != NULL)
- png_combine_row(png_ptr, dsp_row,
- png_pass_dsp_mask[png_ptr->pass]);
- png_read_finish_row(png_ptr);
- return;
- }
- break;
- case 1:
- if ((png_ptr->row_number & 0x07) || png_ptr->width < 5)
- {
- if (dsp_row != NULL)
- png_combine_row(png_ptr, dsp_row,
- png_pass_dsp_mask[png_ptr->pass]);
- png_read_finish_row(png_ptr);
- return;
- }
- break;
- case 2:
- if ((png_ptr->row_number & 0x07) != 4)
- {
- if (dsp_row != NULL && (png_ptr->row_number & 4))
- png_combine_row(png_ptr, dsp_row,
- png_pass_dsp_mask[png_ptr->pass]);
- png_read_finish_row(png_ptr);
- return;
- }
- break;
- case 3:
- if ((png_ptr->row_number & 3) || png_ptr->width < 3)
- {
- if (dsp_row != NULL)
- png_combine_row(png_ptr, dsp_row,
- png_pass_dsp_mask[png_ptr->pass]);
- png_read_finish_row(png_ptr);
- return;
- }
- break;
- case 4:
- if ((png_ptr->row_number & 3) != 2)
- {
- if (dsp_row != NULL && (png_ptr->row_number & 2))
- png_combine_row(png_ptr, dsp_row,
- png_pass_dsp_mask[png_ptr->pass]);
- png_read_finish_row(png_ptr);
- return;
- }
- break;
- case 5:
- if ((png_ptr->row_number & 1) || png_ptr->width < 2)
- {
- if (dsp_row != NULL)
- png_combine_row(png_ptr, dsp_row,
- png_pass_dsp_mask[png_ptr->pass]);
- png_read_finish_row(png_ptr);
- return;
- }
- break;
- case 6:
- if (!(png_ptr->row_number & 1))
- {
- png_read_finish_row(png_ptr);
- return;
- }
- break;
- }
- }
- #endif
-
- if (!(png_ptr->mode & PNG_HAVE_IDAT))
- png_error(png_ptr, "Invalid attempt to read row data");
-
- png_ptr->zstream.next_out = png_ptr->row_buf;
- png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes;
- do
- {
- if (!(png_ptr->zstream.avail_in))
- {
- while (!png_ptr->idat_size)
- {
- png_byte chunk_length[4];
-
- png_crc_finish(png_ptr, 0);
-
- png_read_data(png_ptr, chunk_length, 4);
- png_ptr->idat_size = png_get_uint_31(png_ptr,chunk_length);
-
- png_reset_crc(png_ptr);
- png_crc_read(png_ptr, png_ptr->chunk_name, 4);
- if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
- png_error(png_ptr, "Not enough image data");
- }
- png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size;
- png_ptr->zstream.next_in = png_ptr->zbuf;
- if (png_ptr->zbuf_size > png_ptr->idat_size)
- png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size;
- png_crc_read(png_ptr, png_ptr->zbuf,
- (png_size_t)png_ptr->zstream.avail_in);
- png_ptr->idat_size -= png_ptr->zstream.avail_in;
- }
- ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
- if (ret == Z_STREAM_END)
- {
- if (png_ptr->zstream.avail_out || png_ptr->zstream.avail_in ||
- png_ptr->idat_size)
- png_error(png_ptr, "Extra compressed data");
- png_ptr->mode |= PNG_AFTER_IDAT;
- png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
- break;
- }
- if (ret != Z_OK)
- png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg :
- "Decompression error");
-
- } while (png_ptr->zstream.avail_out);
-
- png_ptr->row_info.color_type = png_ptr->color_type;
- png_ptr->row_info.width = png_ptr->iwidth;
- png_ptr->row_info.channels = png_ptr->channels;
- png_ptr->row_info.bit_depth = png_ptr->bit_depth;
- png_ptr->row_info.pixel_depth = png_ptr->pixel_depth;
- png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth,
- png_ptr->row_info.width);
-
- if(png_ptr->row_buf[0])
- png_read_filter_row(png_ptr, &(png_ptr->row_info),
- png_ptr->row_buf + 1, png_ptr->prev_row + 1,
- (int)(png_ptr->row_buf[0]));
-
- png_memcpy_check(png_ptr, png_ptr->prev_row, png_ptr->row_buf,
- png_ptr->rowbytes + 1);
-
- #if defined(PNG_MNG_FEATURES_SUPPORTED)
- if((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
- (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING))
- {
- /* Intrapixel differencing */
- png_do_read_intrapixel(&(png_ptr->row_info), png_ptr->row_buf + 1);
- }
- #endif
-
- if (png_ptr->transformations || (png_ptr->flags&PNG_FLAG_STRIP_ALPHA))
- png_do_read_transformations(png_ptr);
-
- #if defined(PNG_READ_INTERLACING_SUPPORTED)
- /* blow up interlaced rows to full size */
- if (png_ptr->interlaced &&
- (png_ptr->transformations & PNG_INTERLACE))
- {
- if (png_ptr->pass < 6)
- /* old interface (pre-1.0.9):
- png_do_read_interlace(&(png_ptr->row_info),
- png_ptr->row_buf + 1, png_ptr->pass, png_ptr->transformations);
- */
- png_do_read_interlace(png_ptr);
-
- if (dsp_row != NULL)
- png_combine_row(png_ptr, dsp_row,
- png_pass_dsp_mask[png_ptr->pass]);
- if (row != NULL)
- png_combine_row(png_ptr, row,
- png_pass_mask[png_ptr->pass]);
- }
- else
- #endif
- {
- if (row != NULL)
- png_combine_row(png_ptr, row, 0xff);
- if (dsp_row != NULL)
- png_combine_row(png_ptr, dsp_row, 0xff);
- }
- png_read_finish_row(png_ptr);
-
- if (png_ptr->read_row_fn != NULL)
- (*(png_ptr->read_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass);
- }
- #endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
-
- #ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
- /* Read one or more rows of image data. If the image is interlaced,
- * and png_set_interlace_handling() has been called, the rows need to
- * contain the contents of the rows from the previous pass. If the
- * image has alpha or transparency, and png_handle_alpha()[*] has been
- * called, the rows contents must be initialized to the contents of the
- * screen.
- *
- * "row" holds the actual image, and pixels are placed in it
- * as they arrive. If the image is displayed after each pass, it will
- * appear to "sparkle" in. "display_row" can be used to display a
- * "chunky" progressive image, with finer detail added as it becomes
- * available. If you do not want this "chunky" display, you may pass
- * NULL for display_row. If you do not want the sparkle display, and
- * you have not called png_handle_alpha(), you may pass NULL for rows.
- * If you have called png_handle_alpha(), and the image has either an
- * alpha channel or a transparency chunk, you must provide a buffer for
- * rows. In this case, you do not have to provide a display_row buffer
- * also, but you may. If the image is not interlaced, or if you have
- * not called png_set_interlace_handling(), the display_row buffer will
- * be ignored, so pass NULL to it.
- *
- * [*] png_handle_alpha() does not exist yet, as of this version of libpng
- */
-
- void PNGAPI
- png_read_rows(png_structp png_ptr, png_bytepp row,
- png_bytepp display_row, png_uint_32 num_rows)
- {
- png_uint_32 i;
- png_bytepp rp;
- png_bytepp dp;
-
- png_debug(1, "in png_read_rows\n");
- if(png_ptr == NULL) return;
- rp = row;
- dp = display_row;
- if (rp != NULL && dp != NULL)
- for (i = 0; i < num_rows; i++)
- {
- png_bytep rptr = *rp++;
- png_bytep dptr = *dp++;
-
- png_read_row(png_ptr, rptr, dptr);
- }
- else if(rp != NULL)
- for (i = 0; i < num_rows; i++)
- {
- png_bytep rptr = *rp;
- png_read_row(png_ptr, rptr, png_bytep_NULL);
- rp++;
- }
- else if(dp != NULL)
- for (i = 0; i < num_rows; i++)
- {
- png_bytep dptr = *dp;
- png_read_row(png_ptr, png_bytep_NULL, dptr);
- dp++;
- }
- }
- #endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
-
- #ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
- /* Read the entire image. If the image has an alpha channel or a tRNS
- * chunk, and you have called png_handle_alpha()[*], you will need to
- * initialize the image to the current image that PNG will be overlaying.
- * We set the num_rows again here, in case it was incorrectly set in
- * png_read_start_row() by a call to png_read_update_info() or
- * png_start_read_image() if png_set_interlace_handling() wasn't called
- * prior to either of these functions like it should have been. You can
- * only call this function once. If you desire to have an image for
- * each pass of a interlaced image, use png_read_rows() instead.
- *
- * [*] png_handle_alpha() does not exist yet, as of this version of libpng
- */
- void PNGAPI
- png_read_image(png_structp png_ptr, png_bytepp image)
- {
- png_uint_32 i,image_height;
- int pass, j;
- png_bytepp rp;
-
- png_debug(1, "in png_read_image\n");
- if(png_ptr == NULL) return;
-
- #ifdef PNG_READ_INTERLACING_SUPPORTED
- pass = png_set_interlace_handling(png_ptr);
- #else
- if (png_ptr->interlaced)
- png_error(png_ptr,
- "Cannot read interlaced image -- interlace handler disabled.");
- pass = 1;
- #endif
-
- image_height=png_ptr->height;
- png_ptr->num_rows = image_height; /* Make sure this is set correctly */
-
- for (j = 0; j < pass; j++)
- {
- rp = image;
- for (i = 0; i < image_height; i++)
- {
- png_read_row(png_ptr, *rp, png_bytep_NULL);
- rp++;
- }
- }
- }
- #endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
-
- #ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
- /* Read the end of the PNG file. Will not read past the end of the
- * file, will verify the end is accurate, and will read any comments
- * or time information at the end of the file, if info is not NULL.
- */
- void PNGAPI
- png_read_end(png_structp png_ptr, png_infop info_ptr)
- {
- png_byte chunk_length[4];
- png_uint_32 length;
-
- png_debug(1, "in png_read_end\n");
- if(png_ptr == NULL) return;
- png_crc_finish(png_ptr, 0); /* Finish off CRC from last IDAT chunk */
-
- do
- {
- #ifdef PNG_USE_LOCAL_ARRAYS
- PNG_CONST PNG_IHDR;
- PNG_CONST PNG_IDAT;
- PNG_CONST PNG_IEND;
- PNG_CONST PNG_PLTE;
- #if defined(PNG_READ_bKGD_SUPPORTED)
- PNG_CONST PNG_bKGD;
- #endif
- #if defined(PNG_READ_cHRM_SUPPORTED)
- PNG_CONST PNG_cHRM;
- #endif
- #if defined(PNG_READ_gAMA_SUPPORTED)
- PNG_CONST PNG_gAMA;
- #endif
- #if defined(PNG_READ_hIST_SUPPORTED)
- PNG_CONST PNG_hIST;
- #endif
- #if defined(PNG_READ_iCCP_SUPPORTED)
- PNG_CONST PNG_iCCP;
- #endif
- #if defined(PNG_READ_iTXt_SUPPORTED)
- PNG_CONST PNG_iTXt;
- #endif
- #if defined(PNG_READ_oFFs_SUPPORTED)
- PNG_CONST PNG_oFFs;
- #endif
- #if defined(PNG_READ_pCAL_SUPPORTED)
- PNG_CONST PNG_pCAL;
- #endif
- #if defined(PNG_READ_pHYs_SUPPORTED)
- PNG_CONST PNG_pHYs;
- #endif
- #if defined(PNG_READ_sBIT_SUPPORTED)
- PNG_CONST PNG_sBIT;
- #endif
- #if defined(PNG_READ_sCAL_SUPPORTED)
- PNG_CONST PNG_sCAL;
- #endif
- #if defined(PNG_READ_sPLT_SUPPORTED)
- PNG_CONST PNG_sPLT;
- #endif
- #if defined(PNG_READ_sRGB_SUPPORTED)
- PNG_CONST PNG_sRGB;
- #endif
- #if defined(PNG_READ_tEXt_SUPPORTED)
- PNG_CONST PNG_tEXt;
- #endif
- #if defined(PNG_READ_tIME_SUPPORTED)
- PNG_CONST PNG_tIME;
- #endif
- #if defined(PNG_READ_tRNS_SUPPORTED)
- PNG_CONST PNG_tRNS;
- #endif
- #if defined(PNG_READ_zTXt_SUPPORTED)
- PNG_CONST PNG_zTXt;
- #endif
- #endif /* PNG_USE_LOCAL_ARRAYS */
-
- png_read_data(png_ptr, chunk_length, 4);
- length = png_get_uint_31(png_ptr,chunk_length);
-
- png_reset_crc(png_ptr);
- png_crc_read(png_ptr, png_ptr->chunk_name, 4);
-
- png_debug1(0, "Reading %s chunk.\n", png_ptr->chunk_name);
-
- if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4))
- png_handle_IHDR(png_ptr, info_ptr, length);
- else if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4))
- png_handle_IEND(png_ptr, info_ptr, length);
- #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
- else if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name))
- {
- if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
- {
- if ((length > 0) || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT))
- png_error(png_ptr, "Too many IDAT's found");
- }
- png_handle_unknown(png_ptr, info_ptr, length);
- if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
- png_ptr->mode |= PNG_HAVE_PLTE;
- }
- #endif
- else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
- {
- /* Zero length IDATs are legal after the last IDAT has been
- * read, but not after other chunks have been read.
- */
- if ((length > 0) || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT))
- png_error(png_ptr, "Too many IDAT's found");
- png_crc_finish(png_ptr, length);
- }
- else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
- png_handle_PLTE(png_ptr, info_ptr, length);
- #if defined(PNG_READ_bKGD_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_bKGD, 4))
- png_handle_bKGD(png_ptr, info_ptr, length);
- #endif
- #if defined(PNG_READ_cHRM_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_cHRM, 4))
- png_handle_cHRM(png_ptr, info_ptr, length);
- #endif
- #if defined(PNG_READ_gAMA_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_gAMA, 4))
- png_handle_gAMA(png_ptr, info_ptr, length);
- #endif
- #if defined(PNG_READ_hIST_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_hIST, 4))
- png_handle_hIST(png_ptr, info_ptr, length);
- #endif
- #if defined(PNG_READ_oFFs_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_oFFs, 4))
- png_handle_oFFs(png_ptr, info_ptr, length);
- #endif
- #if defined(PNG_READ_pCAL_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_pCAL, 4))
- png_handle_pCAL(png_ptr, info_ptr, length);
- #endif
- #if defined(PNG_READ_sCAL_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_sCAL, 4))
- png_handle_sCAL(png_ptr, info_ptr, length);
- #endif
- #if defined(PNG_READ_pHYs_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4))
- png_handle_pHYs(png_ptr, info_ptr, length);
- #endif
- #if defined(PNG_READ_sBIT_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_sBIT, 4))
- png_handle_sBIT(png_ptr, info_ptr, length);
- #endif
- #if defined(PNG_READ_sRGB_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_sRGB, 4))
- png_handle_sRGB(png_ptr, info_ptr, length);
- #endif
- #if defined(PNG_READ_iCCP_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_iCCP, 4))
- png_handle_iCCP(png_ptr, info_ptr, length);
- #endif
- #if defined(PNG_READ_sPLT_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_sPLT, 4))
- png_handle_sPLT(png_ptr, info_ptr, length);
- #endif
- #if defined(PNG_READ_tEXt_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4))
- png_handle_tEXt(png_ptr, info_ptr, length);
- #endif
- #if defined(PNG_READ_tIME_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_tIME, 4))
- png_handle_tIME(png_ptr, info_ptr, length);
- #endif
- #if defined(PNG_READ_tRNS_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_tRNS, 4))
- png_handle_tRNS(png_ptr, info_ptr, length);
- #endif
- #if defined(PNG_READ_zTXt_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4))
- png_handle_zTXt(png_ptr, info_ptr, length);
- #endif
- #if defined(PNG_READ_iTXt_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_iTXt, 4))
- png_handle_iTXt(png_ptr, info_ptr, length);
- #endif
- else
- png_handle_unknown(png_ptr, info_ptr, length);
- } while (!(png_ptr->mode & PNG_HAVE_IEND));
- }
- #endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
-
- /* free all memory used by the read */
- void PNGAPI
- png_destroy_read_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr,
- png_infopp end_info_ptr_ptr)
- {
- png_structp png_ptr = NULL;
- png_infop info_ptr = NULL, end_info_ptr = NULL;
- #ifdef PNG_USER_MEM_SUPPORTED
- png_free_ptr free_fn;
- png_voidp mem_ptr;
- #endif
-
- png_debug(1, "in png_destroy_read_struct\n");
- if (png_ptr_ptr != NULL)
- png_ptr = *png_ptr_ptr;
-
- if (info_ptr_ptr != NULL)
- info_ptr = *info_ptr_ptr;
-
- if (end_info_ptr_ptr != NULL)
- end_info_ptr = *end_info_ptr_ptr;
-
- #ifdef PNG_USER_MEM_SUPPORTED
- free_fn = png_ptr->free_fn;
- mem_ptr = png_ptr->mem_ptr;
- #endif
-
- png_read_destroy(png_ptr, info_ptr, end_info_ptr);
-
- if (info_ptr != NULL)
- {
- #if defined(PNG_TEXT_SUPPORTED)
- png_free_data(png_ptr, info_ptr, PNG_FREE_TEXT, -1);
- #endif
-
- #ifdef PNG_USER_MEM_SUPPORTED
- png_destroy_struct_2((png_voidp)info_ptr, (png_free_ptr)free_fn,
- (png_voidp)mem_ptr);
- #else
- png_destroy_struct((png_voidp)info_ptr);
- #endif
- *info_ptr_ptr = NULL;
- }
-
- if (end_info_ptr != NULL)
- {
- #if defined(PNG_READ_TEXT_SUPPORTED)
- png_free_data(png_ptr, end_info_ptr, PNG_FREE_TEXT, -1);
- #endif
- #ifdef PNG_USER_MEM_SUPPORTED
- png_destroy_struct_2((png_voidp)end_info_ptr, (png_free_ptr)free_fn,
- (png_voidp)mem_ptr);
- #else
- png_destroy_struct((png_voidp)end_info_ptr);
- #endif
- *end_info_ptr_ptr = NULL;
- }
-
- if (png_ptr != NULL)
- {
- #ifdef PNG_USER_MEM_SUPPORTED
- png_destroy_struct_2((png_voidp)png_ptr, (png_free_ptr)free_fn,
- (png_voidp)mem_ptr);
- #else
- png_destroy_struct((png_voidp)png_ptr);
- #endif
- *png_ptr_ptr = NULL;
- }
- }
-
- /* free all memory used by the read (old method) */
- void /* PRIVATE */
- png_read_destroy(png_structp png_ptr, png_infop info_ptr, png_infop end_info_ptr)
- {
- #ifdef PNG_SETJMP_SUPPORTED
- jmp_buf tmp_jmp;
- #endif
- png_error_ptr error_fn;
- png_error_ptr warning_fn;
- png_voidp error_ptr;
- #ifdef PNG_USER_MEM_SUPPORTED
- png_free_ptr free_fn;
- #endif
-
- png_debug(1, "in png_read_destroy\n");
- if (info_ptr != NULL)
- png_info_destroy(png_ptr, info_ptr);
-
- if (end_info_ptr != NULL)
- png_info_destroy(png_ptr, end_info_ptr);
-
- png_free(png_ptr, png_ptr->zbuf);
- png_free(png_ptr, png_ptr->big_row_buf);
- png_free(png_ptr, png_ptr->prev_row);
- #if defined(PNG_READ_DITHER_SUPPORTED)
- png_free(png_ptr, png_ptr->palette_lookup);
- png_free(png_ptr, png_ptr->dither_index);
- #endif
- #if defined(PNG_READ_GAMMA_SUPPORTED)
- png_free(png_ptr, png_ptr->gamma_table);
- #endif
- #if defined(PNG_READ_BACKGROUND_SUPPORTED)
- png_free(png_ptr, png_ptr->gamma_from_1);
- png_free(png_ptr, png_ptr->gamma_to_1);
- #endif
- #ifdef PNG_FREE_ME_SUPPORTED
- if (png_ptr->free_me & PNG_FREE_PLTE)
- png_zfree(png_ptr, png_ptr->palette);
- png_ptr->free_me &= ~PNG_FREE_PLTE;
- #else
- if (png_ptr->flags & PNG_FLAG_FREE_PLTE)
- png_zfree(png_ptr, png_ptr->palette);
- png_ptr->flags &= ~PNG_FLAG_FREE_PLTE;
- #endif
- #if defined(PNG_tRNS_SUPPORTED) || \
- defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
- #ifdef PNG_FREE_ME_SUPPORTED
- if (png_ptr->free_me & PNG_FREE_TRNS)
- png_free(png_ptr, png_ptr->trans);
- png_ptr->free_me &= ~PNG_FREE_TRNS;
- #else
- if (png_ptr->flags & PNG_FLAG_FREE_TRNS)
- png_free(png_ptr, png_ptr->trans);
- png_ptr->flags &= ~PNG_FLAG_FREE_TRNS;
- #endif
- #endif
- #if defined(PNG_READ_hIST_SUPPORTED)
- #ifdef PNG_FREE_ME_SUPPORTED
- if (png_ptr->free_me & PNG_FREE_HIST)
- png_free(png_ptr, png_ptr->hist);
- png_ptr->free_me &= ~PNG_FREE_HIST;
- #else
- if (png_ptr->flags & PNG_FLAG_FREE_HIST)
- png_free(png_ptr, png_ptr->hist);
- png_ptr->flags &= ~PNG_FLAG_FREE_HIST;
- #endif
- #endif
- #if defined(PNG_READ_GAMMA_SUPPORTED)
- if (png_ptr->gamma_16_table != NULL)
- {
- int i;
- int istop = (1 << (8 - png_ptr->gamma_shift));
- for (i = 0; i < istop; i++)
- {
- png_free(png_ptr, png_ptr->gamma_16_table[i]);
- }
- png_free(png_ptr, png_ptr->gamma_16_table);
- }
- #if defined(PNG_READ_BACKGROUND_SUPPORTED)
- if (png_ptr->gamma_16_from_1 != NULL)
- {
- int i;
- int istop = (1 << (8 - png_ptr->gamma_shift));
- for (i = 0; i < istop; i++)
- {
- png_free(png_ptr, png_ptr->gamma_16_from_1[i]);
- }
- png_free(png_ptr, png_ptr->gamma_16_from_1);
- }
- if (png_ptr->gamma_16_to_1 != NULL)
- {
- int i;
- int istop = (1 << (8 - png_ptr->gamma_shift));
- for (i = 0; i < istop; i++)
- {
- png_free(png_ptr, png_ptr->gamma_16_to_1[i]);
- }
- png_free(png_ptr, png_ptr->gamma_16_to_1);
- }
- #endif
- #endif
- #if defined(PNG_TIME_RFC1123_SUPPORTED)
- png_free(png_ptr, png_ptr->time_buffer);
- #endif
-
- inflateEnd(&png_ptr->zstream);
- #ifdef PNG_PROGRESSIVE_READ_SUPPORTED
- png_free(png_ptr, png_ptr->save_buffer);
- #endif
-
- #ifdef PNG_PROGRESSIVE_READ_SUPPORTED
- #ifdef PNG_TEXT_SUPPORTED
- png_free(png_ptr, png_ptr->current_text);
- #endif /* PNG_TEXT_SUPPORTED */
- #endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
-
- /* Save the important info out of the png_struct, in case it is
- * being used again.
- */
- #ifdef PNG_SETJMP_SUPPORTED
- png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof (jmp_buf));
- #endif
-
- error_fn = png_ptr->error_fn;
- warning_fn = png_ptr->warning_fn;
- error_ptr = png_ptr->error_ptr;
- #ifdef PNG_USER_MEM_SUPPORTED
- free_fn = png_ptr->free_fn;
- #endif
-
- png_memset(png_ptr, 0, png_sizeof (png_struct));
-
- png_ptr->error_fn = error_fn;
- png_ptr->warning_fn = warning_fn;
- png_ptr->error_ptr = error_ptr;
- #ifdef PNG_USER_MEM_SUPPORTED
- png_ptr->free_fn = free_fn;
- #endif
-
- #ifdef PNG_SETJMP_SUPPORTED
- png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof (jmp_buf));
- #endif
-
- }
-
- void PNGAPI
- png_set_read_status_fn(png_structp png_ptr, png_read_status_ptr read_row_fn)
- {
- if(png_ptr == NULL) return;
- png_ptr->read_row_fn = read_row_fn;
- }
-
- #ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
- #if defined(PNG_INFO_IMAGE_SUPPORTED)
- void PNGAPI
- png_read_png(png_structp png_ptr, png_infop info_ptr,
- int transforms,
- voidp params)
- {
- int row;
-
- if(png_ptr == NULL) return;
- #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
- /* invert the alpha channel from opacity to transparency
- */
- if (transforms & PNG_TRANSFORM_INVERT_ALPHA)
- png_set_invert_alpha(png_ptr);
- #endif
-
- /* png_read_info() gives us all of the information from the
- * PNG file before the first IDAT (image data chunk).
- */
- png_read_info(png_ptr, info_ptr);
- if (info_ptr->height > PNG_UINT_32_MAX/png_sizeof(png_bytep))
- png_error(png_ptr,"Image is too high to process with png_read_png()");
-
- /* -------------- image transformations start here ------------------- */
-
- #if defined(PNG_READ_16_TO_8_SUPPORTED)
- /* tell libpng to strip 16 bit/color files down to 8 bits per color
- */
- if (transforms & PNG_TRANSFORM_STRIP_16)
- png_set_strip_16(png_ptr);
- #endif
-
- #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
- /* Strip alpha bytes from the input data without combining with
- * the background (not recommended).
- */
- if (transforms & PNG_TRANSFORM_STRIP_ALPHA)
- png_set_strip_alpha(png_ptr);
- #endif
-
- #if defined(PNG_READ_PACK_SUPPORTED) && !defined(PNG_READ_EXPAND_SUPPORTED)
- /* Extract multiple pixels with bit depths of 1, 2, or 4 from a single
- * byte into separate bytes (useful for paletted and grayscale images).
- */
- if (transforms & PNG_TRANSFORM_PACKING)
- png_set_packing(png_ptr);
- #endif
-
- #if defined(PNG_READ_PACKSWAP_SUPPORTED)
- /* Change the order of packed pixels to least significant bit first
- * (not useful if you are using png_set_packing).
- */
- if (transforms & PNG_TRANSFORM_PACKSWAP)
- png_set_packswap(png_ptr);
- #endif
-
- #if defined(PNG_READ_EXPAND_SUPPORTED)
- /* Expand paletted colors into true RGB triplets
- * Expand grayscale images to full 8 bits from 1, 2, or 4 bits/pixel
- * Expand paletted or RGB images with transparency to full alpha
- * channels so the data will be available as RGBA quartets.
- */
- if (transforms & PNG_TRANSFORM_EXPAND)
- if ((png_ptr->bit_depth < 8) ||
- (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ||
- (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)))
- png_set_expand(png_ptr);
- #endif
-
- /* We don't handle background color or gamma transformation or dithering.
- */
-
- #if defined(PNG_READ_INVERT_SUPPORTED)
- /* invert monochrome files to have 0 as white and 1 as black
- */
- if (transforms & PNG_TRANSFORM_INVERT_MONO)
- png_set_invert_mono(png_ptr);
- #endif
-
- #if defined(PNG_READ_SHIFT_SUPPORTED)
- /* If you want to shift the pixel values from the range [0,255] or
- * [0,65535] to the original [0,7] or [0,31], or whatever range the
- * colors were originally in:
- */
- if ((transforms & PNG_TRANSFORM_SHIFT)
- && png_get_valid(png_ptr, info_ptr, PNG_INFO_sBIT))
- {
- png_color_8p sig_bit;
-
- png_get_sBIT(png_ptr, info_ptr, &sig_bit);
- png_set_shift(png_ptr, sig_bit);
- }
- #endif
-
- #if defined(PNG_READ_BGR_SUPPORTED)
- /* flip the RGB pixels to BGR (or RGBA to BGRA)
- */
- if (transforms & PNG_TRANSFORM_BGR)
- png_set_bgr(png_ptr);
- #endif
-
- #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
- /* swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR)
- */
- if (transforms & PNG_TRANSFORM_SWAP_ALPHA)
- png_set_swap_alpha(png_ptr);
- #endif
-
- #if defined(PNG_READ_SWAP_SUPPORTED)
- /* swap bytes of 16 bit files to least significant byte first
- */
- if (transforms & PNG_TRANSFORM_SWAP_ENDIAN)
- png_set_swap(png_ptr);
- #endif
-
- /* We don't handle adding filler bytes */
-
- /* Optional call to gamma correct and add the background to the palette
- * and update info structure. REQUIRED if you are expecting libpng to
- * update the palette for you (i.e., you selected such a transform above).
- */
- png_read_update_info(png_ptr, info_ptr);
-
- /* -------------- image transformations end here ------------------- */
-
- #ifdef PNG_FREE_ME_SUPPORTED
- png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0);
- #endif
- if(info_ptr->row_pointers == NULL)
- {
- info_ptr->row_pointers = (png_bytepp)png_malloc(png_ptr,
- info_ptr->height * png_sizeof(png_bytep));
- #ifdef PNG_FREE_ME_SUPPORTED
- info_ptr->free_me |= PNG_FREE_ROWS;
- #endif
- for (row = 0; row < (int)info_ptr->height; row++)
- {
- info_ptr->row_pointers[row] = (png_bytep)png_malloc(png_ptr,
- png_get_rowbytes(png_ptr, info_ptr));
- }
- }
-
- png_read_image(png_ptr, info_ptr->row_pointers);
- info_ptr->valid |= PNG_INFO_IDAT;
-
- /* read rest of file, and get additional chunks in info_ptr - REQUIRED */
- png_read_end(png_ptr, info_ptr);
-
- transforms = transforms; /* quiet compiler warnings */
- params = params;
-
- }
- #endif /* PNG_INFO_IMAGE_SUPPORTED */
- #endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
- #endif /* PNG_READ_SUPPORTED */
- /********* End of inlined file: pngread.c *********/
-
- /********* Start of inlined file: pngpread.c *********/
- /* pngpread.c - read a png file in push mode
- *
- * Last changed in libpng 1.2.21 October 4, 2007
- * For conditions of distribution and use, see copyright notice in png.h
- * Copyright (c) 1998-2007 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
- */
-
- #define PNG_INTERNAL
-
- #ifdef PNG_PROGRESSIVE_READ_SUPPORTED
-
- /* push model modes */
- #define PNG_READ_SIG_MODE 0
- #define PNG_READ_CHUNK_MODE 1
- #define PNG_READ_IDAT_MODE 2
- #define PNG_SKIP_MODE 3
- #define PNG_READ_tEXt_MODE 4
- #define PNG_READ_zTXt_MODE 5
- #define PNG_READ_DONE_MODE 6
- #define PNG_READ_iTXt_MODE 7
- #define PNG_ERROR_MODE 8
-
- void PNGAPI
- png_process_data(png_structp png_ptr, png_infop info_ptr,
- png_bytep buffer, png_size_t buffer_size)
- {
- if(png_ptr == NULL) return;
- png_push_restore_buffer(png_ptr, buffer, buffer_size);
-
- while (png_ptr->buffer_size)
- {
- png_process_some_data(png_ptr, info_ptr);
- }
- }
-
- /* What we do with the incoming data depends on what we were previously
- * doing before we ran out of data...
- */
- void /* PRIVATE */
- png_process_some_data(png_structp png_ptr, png_infop info_ptr)
- {
- if(png_ptr == NULL) return;
- switch (png_ptr->process_mode)
- {
- case PNG_READ_SIG_MODE:
- {
- png_push_read_sig(png_ptr, info_ptr);
- break;
- }
- case PNG_READ_CHUNK_MODE:
- {
- png_push_read_chunk(png_ptr, info_ptr);
- break;
- }
- case PNG_READ_IDAT_MODE:
- {
- png_push_read_IDAT(png_ptr);
- break;
- }
- #if defined(PNG_READ_tEXt_SUPPORTED)
- case PNG_READ_tEXt_MODE:
- {
- png_push_read_tEXt(png_ptr, info_ptr);
- break;
- }
- #endif
- #if defined(PNG_READ_zTXt_SUPPORTED)
- case PNG_READ_zTXt_MODE:
- {
- png_push_read_zTXt(png_ptr, info_ptr);
- break;
- }
- #endif
- #if defined(PNG_READ_iTXt_SUPPORTED)
- case PNG_READ_iTXt_MODE:
- {
- png_push_read_iTXt(png_ptr, info_ptr);
- break;
- }
- #endif
- case PNG_SKIP_MODE:
- {
- png_push_crc_finish(png_ptr);
- break;
- }
- default:
- {
- png_ptr->buffer_size = 0;
- break;
- }
- }
- }
-
- /* Read any remaining signature bytes from the stream and compare them with
- * the correct PNG signature. It is possible that this routine is called
- * with bytes already read from the signature, either because they have been
- * checked by the calling application, or because of multiple calls to this
- * routine.
- */
- void /* PRIVATE */
- png_push_read_sig(png_structp png_ptr, png_infop info_ptr)
- {
- png_size_t num_checked = png_ptr->sig_bytes,
- num_to_check = 8 - num_checked;
-
- if (png_ptr->buffer_size < num_to_check)
- {
- num_to_check = png_ptr->buffer_size;
- }
-
- png_push_fill_buffer(png_ptr, &(info_ptr->signature[num_checked]),
- num_to_check);
- png_ptr->sig_bytes = (png_byte)(png_ptr->sig_bytes+num_to_check);
-
- if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check))
- {
- if (num_checked < 4 &&
- png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))
- png_error(png_ptr, "Not a PNG file");
- else
- png_error(png_ptr, "PNG file corrupted by ASCII conversion");
- }
- else
- {
- if (png_ptr->sig_bytes >= 8)
- {
- png_ptr->process_mode = PNG_READ_CHUNK_MODE;
- }
- }
- }
-
- void /* PRIVATE */
- png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
- {
- #ifdef PNG_USE_LOCAL_ARRAYS
- PNG_CONST PNG_IHDR;
- PNG_CONST PNG_IDAT;
- PNG_CONST PNG_IEND;
- PNG_CONST PNG_PLTE;
- #if defined(PNG_READ_bKGD_SUPPORTED)
- PNG_CONST PNG_bKGD;
- #endif
- #if defined(PNG_READ_cHRM_SUPPORTED)
- PNG_CONST PNG_cHRM;
- #endif
- #if defined(PNG_READ_gAMA_SUPPORTED)
- PNG_CONST PNG_gAMA;
- #endif
- #if defined(PNG_READ_hIST_SUPPORTED)
- PNG_CONST PNG_hIST;
- #endif
- #if defined(PNG_READ_iCCP_SUPPORTED)
- PNG_CONST PNG_iCCP;
- #endif
- #if defined(PNG_READ_iTXt_SUPPORTED)
- PNG_CONST PNG_iTXt;
- #endif
- #if defined(PNG_READ_oFFs_SUPPORTED)
- PNG_CONST PNG_oFFs;
- #endif
- #if defined(PNG_READ_pCAL_SUPPORTED)
- PNG_CONST PNG_pCAL;
- #endif
- #if defined(PNG_READ_pHYs_SUPPORTED)
- PNG_CONST PNG_pHYs;
- #endif
- #if defined(PNG_READ_sBIT_SUPPORTED)
- PNG_CONST PNG_sBIT;
- #endif
- #if defined(PNG_READ_sCAL_SUPPORTED)
- PNG_CONST PNG_sCAL;
- #endif
- #if defined(PNG_READ_sRGB_SUPPORTED)
- PNG_CONST PNG_sRGB;
- #endif
- #if defined(PNG_READ_sPLT_SUPPORTED)
- PNG_CONST PNG_sPLT;
- #endif
- #if defined(PNG_READ_tEXt_SUPPORTED)
- PNG_CONST PNG_tEXt;
- #endif
- #if defined(PNG_READ_tIME_SUPPORTED)
- PNG_CONST PNG_tIME;
- #endif
- #if defined(PNG_READ_tRNS_SUPPORTED)
- PNG_CONST PNG_tRNS;
- #endif
- #if defined(PNG_READ_zTXt_SUPPORTED)
- PNG_CONST PNG_zTXt;
- #endif
- #endif /* PNG_USE_LOCAL_ARRAYS */
- /* First we make sure we have enough data for the 4 byte chunk name
- * and the 4 byte chunk length before proceeding with decoding the
- * chunk data. To fully decode each of these chunks, we also make
- * sure we have enough data in the buffer for the 4 byte CRC at the
- * end of every chunk (except IDAT, which is handled separately).
- */
- if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
- {
- png_byte chunk_length[4];
-
- if (png_ptr->buffer_size < 8)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
-
- png_push_fill_buffer(png_ptr, chunk_length, 4);
- png_ptr->push_length = png_get_uint_31(png_ptr,chunk_length);
- png_reset_crc(png_ptr);
- png_crc_read(png_ptr, png_ptr->chunk_name, 4);
- png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
- }
-
- if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
- if(png_ptr->mode & PNG_AFTER_IDAT)
- png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT;
-
- if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4))
- {
- if (png_ptr->push_length + 4 > png_ptr->buffer_size)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
- png_handle_IHDR(png_ptr, info_ptr, png_ptr->push_length);
- }
- else if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4))
- {
- if (png_ptr->push_length + 4 > png_ptr->buffer_size)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
- png_handle_IEND(png_ptr, info_ptr, png_ptr->push_length);
-
- png_ptr->process_mode = PNG_READ_DONE_MODE;
- png_push_have_end(png_ptr, info_ptr);
- }
- #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
- else if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name))
- {
- if (png_ptr->push_length + 4 > png_ptr->buffer_size)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
- if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
- png_ptr->mode |= PNG_HAVE_IDAT;
- png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length);
- if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
- png_ptr->mode |= PNG_HAVE_PLTE;
- else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
- {
- if (!(png_ptr->mode & PNG_HAVE_IHDR))
- png_error(png_ptr, "Missing IHDR before IDAT");
- else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
- !(png_ptr->mode & PNG_HAVE_PLTE))
- png_error(png_ptr, "Missing PLTE before IDAT");
- }
- }
- #endif
- else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
- {
- if (png_ptr->push_length + 4 > png_ptr->buffer_size)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
- png_handle_PLTE(png_ptr, info_ptr, png_ptr->push_length);
- }
- else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
- {
- /* If we reach an IDAT chunk, this means we have read all of the
- * header chunks, and we can start reading the image (or if this
- * is called after the image has been read - we have an error).
- */
- if (!(png_ptr->mode & PNG_HAVE_IHDR))
- png_error(png_ptr, "Missing IHDR before IDAT");
- else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
- !(png_ptr->mode & PNG_HAVE_PLTE))
- png_error(png_ptr, "Missing PLTE before IDAT");
-
- if (png_ptr->mode & PNG_HAVE_IDAT)
- {
- if (!(png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT))
- if (png_ptr->push_length == 0)
- return;
-
- if (png_ptr->mode & PNG_AFTER_IDAT)
- png_error(png_ptr, "Too many IDAT's found");
- }
-
- png_ptr->idat_size = png_ptr->push_length;
- png_ptr->mode |= PNG_HAVE_IDAT;
- png_ptr->process_mode = PNG_READ_IDAT_MODE;
- png_push_have_info(png_ptr, info_ptr);
- png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes;
- png_ptr->zstream.next_out = png_ptr->row_buf;
- return;
- }
- #if defined(PNG_READ_gAMA_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_gAMA, 4))
- {
- if (png_ptr->push_length + 4 > png_ptr->buffer_size)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
- png_handle_gAMA(png_ptr, info_ptr, png_ptr->push_length);
- }
- #endif
- #if defined(PNG_READ_sBIT_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_sBIT, 4))
- {
- if (png_ptr->push_length + 4 > png_ptr->buffer_size)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
- png_handle_sBIT(png_ptr, info_ptr, png_ptr->push_length);
- }
- #endif
- #if defined(PNG_READ_cHRM_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_cHRM, 4))
- {
- if (png_ptr->push_length + 4 > png_ptr->buffer_size)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
- png_handle_cHRM(png_ptr, info_ptr, png_ptr->push_length);
- }
- #endif
- #if defined(PNG_READ_sRGB_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_sRGB, 4))
- {
- if (png_ptr->push_length + 4 > png_ptr->buffer_size)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
- png_handle_sRGB(png_ptr, info_ptr, png_ptr->push_length);
- }
- #endif
- #if defined(PNG_READ_iCCP_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_iCCP, 4))
- {
- if (png_ptr->push_length + 4 > png_ptr->buffer_size)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
- png_handle_iCCP(png_ptr, info_ptr, png_ptr->push_length);
- }
- #endif
- #if defined(PNG_READ_sPLT_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_sPLT, 4))
- {
- if (png_ptr->push_length + 4 > png_ptr->buffer_size)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
- png_handle_sPLT(png_ptr, info_ptr, png_ptr->push_length);
- }
- #endif
- #if defined(PNG_READ_tRNS_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_tRNS, 4))
- {
- if (png_ptr->push_length + 4 > png_ptr->buffer_size)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
- png_handle_tRNS(png_ptr, info_ptr, png_ptr->push_length);
- }
- #endif
- #if defined(PNG_READ_bKGD_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_bKGD, 4))
- {
- if (png_ptr->push_length + 4 > png_ptr->buffer_size)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
- png_handle_bKGD(png_ptr, info_ptr, png_ptr->push_length);
- }
- #endif
- #if defined(PNG_READ_hIST_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_hIST, 4))
- {
- if (png_ptr->push_length + 4 > png_ptr->buffer_size)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
- png_handle_hIST(png_ptr, info_ptr, png_ptr->push_length);
- }
- #endif
- #if defined(PNG_READ_pHYs_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4))
- {
- if (png_ptr->push_length + 4 > png_ptr->buffer_size)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
- png_handle_pHYs(png_ptr, info_ptr, png_ptr->push_length);
- }
- #endif
- #if defined(PNG_READ_oFFs_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_oFFs, 4))
- {
- if (png_ptr->push_length + 4 > png_ptr->buffer_size)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
- png_handle_oFFs(png_ptr, info_ptr, png_ptr->push_length);
- }
- #endif
- #if defined(PNG_READ_pCAL_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_pCAL, 4))
- {
- if (png_ptr->push_length + 4 > png_ptr->buffer_size)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
- png_handle_pCAL(png_ptr, info_ptr, png_ptr->push_length);
- }
- #endif
- #if defined(PNG_READ_sCAL_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_sCAL, 4))
- {
- if (png_ptr->push_length + 4 > png_ptr->buffer_size)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
- png_handle_sCAL(png_ptr, info_ptr, png_ptr->push_length);
- }
- #endif
- #if defined(PNG_READ_tIME_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_tIME, 4))
- {
- if (png_ptr->push_length + 4 > png_ptr->buffer_size)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
- png_handle_tIME(png_ptr, info_ptr, png_ptr->push_length);
- }
- #endif
- #if defined(PNG_READ_tEXt_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4))
- {
- if (png_ptr->push_length + 4 > png_ptr->buffer_size)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
- png_push_handle_tEXt(png_ptr, info_ptr, png_ptr->push_length);
- }
- #endif
- #if defined(PNG_READ_zTXt_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4))
- {
- if (png_ptr->push_length + 4 > png_ptr->buffer_size)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
- png_push_handle_zTXt(png_ptr, info_ptr, png_ptr->push_length);
- }
- #endif
- #if defined(PNG_READ_iTXt_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_iTXt, 4))
- {
- if (png_ptr->push_length + 4 > png_ptr->buffer_size)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
- png_push_handle_iTXt(png_ptr, info_ptr, png_ptr->push_length);
- }
- #endif
- else
- {
- if (png_ptr->push_length + 4 > png_ptr->buffer_size)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
- png_push_handle_unknown(png_ptr, info_ptr, png_ptr->push_length);
- }
-
- png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
- }
-
- void /* PRIVATE */
- png_push_crc_skip(png_structp png_ptr, png_uint_32 skip)
- {
- png_ptr->process_mode = PNG_SKIP_MODE;
- png_ptr->skip_length = skip;
- }
-
- void /* PRIVATE */
- png_push_crc_finish(png_structp png_ptr)
- {
- if (png_ptr->skip_length && png_ptr->save_buffer_size)
- {
- png_size_t save_size;
-
- if (png_ptr->skip_length < (png_uint_32)png_ptr->save_buffer_size)
- save_size = (png_size_t)png_ptr->skip_length;
- else
- save_size = png_ptr->save_buffer_size;
-
- png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
-
- png_ptr->skip_length -= save_size;
- png_ptr->buffer_size -= save_size;
- png_ptr->save_buffer_size -= save_size;
- png_ptr->save_buffer_ptr += save_size;
- }
- if (png_ptr->skip_length && png_ptr->current_buffer_size)
- {
- png_size_t save_size;
-
- if (png_ptr->skip_length < (png_uint_32)png_ptr->current_buffer_size)
- save_size = (png_size_t)png_ptr->skip_length;
- else
- save_size = png_ptr->current_buffer_size;
-
- png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
-
- png_ptr->skip_length -= save_size;
- png_ptr->buffer_size -= save_size;
- png_ptr->current_buffer_size -= save_size;
- png_ptr->current_buffer_ptr += save_size;
- }
- if (!png_ptr->skip_length)
- {
- if (png_ptr->buffer_size < 4)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
-
- png_crc_finish(png_ptr, 0);
- png_ptr->process_mode = PNG_READ_CHUNK_MODE;
- }
- }
-
- void PNGAPI
- png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length)
- {
- png_bytep ptr;
-
- if(png_ptr == NULL) return;
- ptr = buffer;
- if (png_ptr->save_buffer_size)
- {
- png_size_t save_size;
-
- if (length < png_ptr->save_buffer_size)
- save_size = length;
- else
- save_size = png_ptr->save_buffer_size;
-
- png_memcpy(ptr, png_ptr->save_buffer_ptr, save_size);
- length -= save_size;
- ptr += save_size;
- png_ptr->buffer_size -= save_size;
- png_ptr->save_buffer_size -= save_size;
- png_ptr->save_buffer_ptr += save_size;
- }
- if (length && png_ptr->current_buffer_size)
- {
- png_size_t save_size;
-
- if (length < png_ptr->current_buffer_size)
- save_size = length;
- else
- save_size = png_ptr->current_buffer_size;
-
- png_memcpy(ptr, png_ptr->current_buffer_ptr, save_size);
- png_ptr->buffer_size -= save_size;
- png_ptr->current_buffer_size -= save_size;
- png_ptr->current_buffer_ptr += save_size;
- }
- }
-
- void /* PRIVATE */
- png_push_save_buffer(png_structp png_ptr)
- {
- if (png_ptr->save_buffer_size)
- {
- if (png_ptr->save_buffer_ptr != png_ptr->save_buffer)
- {
- png_size_t i,istop;
- png_bytep sp;
- png_bytep dp;
-
- istop = png_ptr->save_buffer_size;
- for (i = 0, sp = png_ptr->save_buffer_ptr, dp = png_ptr->save_buffer;
- i < istop; i++, sp++, dp++)
- {
- *dp = *sp;
- }
- }
- }
- if (png_ptr->save_buffer_size + png_ptr->current_buffer_size >
- png_ptr->save_buffer_max)
- {
- png_size_t new_max;
- png_bytep old_buffer;
-
- if (png_ptr->save_buffer_size > PNG_SIZE_MAX -
- (png_ptr->current_buffer_size + 256))
- {
- png_error(png_ptr, "Potential overflow of save_buffer");
- }
- new_max = png_ptr->save_buffer_size + png_ptr->current_buffer_size + 256;
- old_buffer = png_ptr->save_buffer;
- png_ptr->save_buffer = (png_bytep)png_malloc(png_ptr,
- (png_uint_32)new_max);
- png_memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size);
- png_free(png_ptr, old_buffer);
- png_ptr->save_buffer_max = new_max;
- }
- if (png_ptr->current_buffer_size)
- {
- png_memcpy(png_ptr->save_buffer + png_ptr->save_buffer_size,
- png_ptr->current_buffer_ptr, png_ptr->current_buffer_size);
- png_ptr->save_buffer_size += png_ptr->current_buffer_size;
- png_ptr->current_buffer_size = 0;
- }
- png_ptr->save_buffer_ptr = png_ptr->save_buffer;
- png_ptr->buffer_size = 0;
- }
-
- void /* PRIVATE */
- png_push_restore_buffer(png_structp png_ptr, png_bytep buffer,
- png_size_t buffer_length)
- {
- png_ptr->current_buffer = buffer;
- png_ptr->current_buffer_size = buffer_length;
- png_ptr->buffer_size = buffer_length + png_ptr->save_buffer_size;
- png_ptr->current_buffer_ptr = png_ptr->current_buffer;
- }
-
- void /* PRIVATE */
- png_push_read_IDAT(png_structp png_ptr)
- {
- #ifdef PNG_USE_LOCAL_ARRAYS
- PNG_CONST PNG_IDAT;
- #endif
- if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
- {
- png_byte chunk_length[4];
-
- if (png_ptr->buffer_size < 8)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
-
- png_push_fill_buffer(png_ptr, chunk_length, 4);
- png_ptr->push_length = png_get_uint_31(png_ptr,chunk_length);
- png_reset_crc(png_ptr);
- png_crc_read(png_ptr, png_ptr->chunk_name, 4);
- png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
-
- if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
- {
- png_ptr->process_mode = PNG_READ_CHUNK_MODE;
- if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
- png_error(png_ptr, "Not enough compressed data");
- return;
- }
-
- png_ptr->idat_size = png_ptr->push_length;
- }
- if (png_ptr->idat_size && png_ptr->save_buffer_size)
- {
- png_size_t save_size;
-
- if (png_ptr->idat_size < (png_uint_32)png_ptr->save_buffer_size)
- {
- save_size = (png_size_t)png_ptr->idat_size;
- /* check for overflow */
- if((png_uint_32)save_size != png_ptr->idat_size)
- png_error(png_ptr, "save_size overflowed in pngpread");
- }
- else
- save_size = png_ptr->save_buffer_size;
-
- png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
- if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
- png_process_IDAT_data(png_ptr, png_ptr->save_buffer_ptr, save_size);
- png_ptr->idat_size -= save_size;
- png_ptr->buffer_size -= save_size;
- png_ptr->save_buffer_size -= save_size;
- png_ptr->save_buffer_ptr += save_size;
- }
- if (png_ptr->idat_size && png_ptr->current_buffer_size)
- {
- png_size_t save_size;
-
- if (png_ptr->idat_size < (png_uint_32)png_ptr->current_buffer_size)
- {
- save_size = (png_size_t)png_ptr->idat_size;
- /* check for overflow */
- if((png_uint_32)save_size != png_ptr->idat_size)
- png_error(png_ptr, "save_size overflowed in pngpread");
- }
- else
- save_size = png_ptr->current_buffer_size;
-
- png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
- if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
- png_process_IDAT_data(png_ptr, png_ptr->current_buffer_ptr, save_size);
-
- png_ptr->idat_size -= save_size;
- png_ptr->buffer_size -= save_size;
- png_ptr->current_buffer_size -= save_size;
- png_ptr->current_buffer_ptr += save_size;
- }
- if (!png_ptr->idat_size)
- {
- if (png_ptr->buffer_size < 4)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
-
- png_crc_finish(png_ptr, 0);
- png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
- png_ptr->mode |= PNG_AFTER_IDAT;
- }
- }
-
- void /* PRIVATE */
- png_process_IDAT_data(png_structp png_ptr, png_bytep buffer,
- png_size_t buffer_length)
- {
- int ret;
-
- if ((png_ptr->flags & PNG_FLAG_ZLIB_FINISHED) && buffer_length)
- png_error(png_ptr, "Extra compression data");
-
- png_ptr->zstream.next_in = buffer;
- png_ptr->zstream.avail_in = (uInt)buffer_length;
- for(;;)
- {
- ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
- if (ret != Z_OK)
- {
- if (ret == Z_STREAM_END)
- {
- if (png_ptr->zstream.avail_in)
- png_error(png_ptr, "Extra compressed data");
- if (!(png_ptr->zstream.avail_out))
- {
- png_push_process_row(png_ptr);
- }
-
- png_ptr->mode |= PNG_AFTER_IDAT;
- png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
- break;
- }
- else if (ret == Z_BUF_ERROR)
- break;
- else
- png_error(png_ptr, "Decompression Error");
- }
- if (!(png_ptr->zstream.avail_out))
- {
- if ((
- #if defined(PNG_READ_INTERLACING_SUPPORTED)
- png_ptr->interlaced && png_ptr->pass > 6) ||
- (!png_ptr->interlaced &&
- #endif
- png_ptr->row_number == png_ptr->num_rows))
- {
- if (png_ptr->zstream.avail_in)
- {
- png_warning(png_ptr, "Too much data in IDAT chunks");
- }
-
- png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
- break;
- }
- png_push_process_row(png_ptr);
- png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes;
- png_ptr->zstream.next_out = png_ptr->row_buf;
- }
- else
- break;
- }
- }
-
- void /* PRIVATE */
- png_push_process_row(png_structp png_ptr)
- {
- png_ptr->row_info.color_type = png_ptr->color_type;
- png_ptr->row_info.width = png_ptr->iwidth;
- png_ptr->row_info.channels = png_ptr->channels;
- png_ptr->row_info.bit_depth = png_ptr->bit_depth;
- png_ptr->row_info.pixel_depth = png_ptr->pixel_depth;
-
- png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth,
- png_ptr->row_info.width);
-
- png_read_filter_row(png_ptr, &(png_ptr->row_info),
- png_ptr->row_buf + 1, png_ptr->prev_row + 1,
- (int)(png_ptr->row_buf[0]));
-
- png_memcpy_check(png_ptr, png_ptr->prev_row, png_ptr->row_buf,
- png_ptr->rowbytes + 1);
-
- if (png_ptr->transformations || (png_ptr->flags&PNG_FLAG_STRIP_ALPHA))
- png_do_read_transformations(png_ptr);
-
- #if defined(PNG_READ_INTERLACING_SUPPORTED)
- /* blow up interlaced rows to full size */
- if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
- {
- if (png_ptr->pass < 6)
- /* old interface (pre-1.0.9):
- png_do_read_interlace(&(png_ptr->row_info),
- png_ptr->row_buf + 1, png_ptr->pass, png_ptr->transformations);
- */
- png_do_read_interlace(png_ptr);
-
- switch (png_ptr->pass)
- {
- case 0:
- {
- int i;
- for (i = 0; i < 8 && png_ptr->pass == 0; i++)
- {
- png_push_have_row(png_ptr, png_ptr->row_buf + 1);
- png_read_push_finish_row(png_ptr); /* updates png_ptr->pass */
- }
- if (png_ptr->pass == 2) /* pass 1 might be empty */
- {
- for (i = 0; i < 4 && png_ptr->pass == 2; i++)
- {
- png_push_have_row(png_ptr, png_bytep_NULL);
- png_read_push_finish_row(png_ptr);
- }
- }
- if (png_ptr->pass == 4 && png_ptr->height <= 4)
- {
- for (i = 0; i < 2 && png_ptr->pass == 4; i++)
- {
- png_push_have_row(png_ptr, png_bytep_NULL);
- png_read_push_finish_row(png_ptr);
- }
- }
- if (png_ptr->pass == 6 && png_ptr->height <= 4)
- {
- png_push_have_row(png_ptr, png_bytep_NULL);
- png_read_push_finish_row(png_ptr);
- }
- break;
- }
- case 1:
- {
- int i;
- for (i = 0; i < 8 && png_ptr->pass == 1; i++)
- {
- png_push_have_row(png_ptr, png_ptr->row_buf + 1);
- png_read_push_finish_row(png_ptr);
- }
- if (png_ptr->pass == 2) /* skip top 4 generated rows */
- {
- for (i = 0; i < 4 && png_ptr->pass == 2; i++)
- {
- png_push_have_row(png_ptr, png_bytep_NULL);
- png_read_push_finish_row(png_ptr);
- }
- }
- break;
- }
- case 2:
- {
- int i;
- for (i = 0; i < 4 && png_ptr->pass == 2; i++)
- {
- png_push_have_row(png_ptr, png_ptr->row_buf + 1);
- png_read_push_finish_row(png_ptr);
- }
- for (i = 0; i < 4 && png_ptr->pass == 2; i++)
- {
- png_push_have_row(png_ptr, png_bytep_NULL);
- png_read_push_finish_row(png_ptr);
- }
- if (png_ptr->pass == 4) /* pass 3 might be empty */
- {
- for (i = 0; i < 2 && png_ptr->pass == 4; i++)
- {
- png_push_have_row(png_ptr, png_bytep_NULL);
- png_read_push_finish_row(png_ptr);
- }
- }
- break;
- }
- case 3:
- {
- int i;
- for (i = 0; i < 4 && png_ptr->pass == 3; i++)
- {
- png_push_have_row(png_ptr, png_ptr->row_buf + 1);
- png_read_push_finish_row(png_ptr);
- }
- if (png_ptr->pass == 4) /* skip top two generated rows */
- {
- for (i = 0; i < 2 && png_ptr->pass == 4; i++)
- {
- png_push_have_row(png_ptr, png_bytep_NULL);
- png_read_push_finish_row(png_ptr);
- }
- }
- break;
- }
- case 4:
- {
- int i;
- for (i = 0; i < 2 && png_ptr->pass == 4; i++)
- {
- png_push_have_row(png_ptr, png_ptr->row_buf + 1);
- png_read_push_finish_row(png_ptr);
- }
- for (i = 0; i < 2 && png_ptr->pass == 4; i++)
- {
- png_push_have_row(png_ptr, png_bytep_NULL);
- png_read_push_finish_row(png_ptr);
- }
- if (png_ptr->pass == 6) /* pass 5 might be empty */
- {
- png_push_have_row(png_ptr, png_bytep_NULL);
- png_read_push_finish_row(png_ptr);
- }
- break;
- }
- case 5:
- {
- int i;
- for (i = 0; i < 2 && png_ptr->pass == 5; i++)
- {
- png_push_have_row(png_ptr, png_ptr->row_buf + 1);
- png_read_push_finish_row(png_ptr);
- }
- if (png_ptr->pass == 6) /* skip top generated row */
- {
- png_push_have_row(png_ptr, png_bytep_NULL);
- png_read_push_finish_row(png_ptr);
- }
- break;
- }
- case 6:
- {
- png_push_have_row(png_ptr, png_ptr->row_buf + 1);
- png_read_push_finish_row(png_ptr);
- if (png_ptr->pass != 6)
- break;
- png_push_have_row(png_ptr, png_bytep_NULL);
- png_read_push_finish_row(png_ptr);
- }
- }
- }
- else
- #endif
- {
- png_push_have_row(png_ptr, png_ptr->row_buf + 1);
- png_read_push_finish_row(png_ptr);
- }
- }
-
- void /* PRIVATE */
- png_read_push_finish_row(png_structp png_ptr)
- {
- #ifdef PNG_USE_LOCAL_ARRAYS
- /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
-
- /* start of interlace block */
- PNG_CONST int FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
-
- /* offset to next interlace block */
- PNG_CONST int FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
-
- /* start of interlace block in the y direction */
- PNG_CONST int FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
-
- /* offset to next interlace block in the y direction */
- PNG_CONST int FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
-
- /* Height of interlace block. This is not currently used - if you need
- * it, uncomment it here and in png.h
- PNG_CONST int FARDATA png_pass_height[] = {8, 8, 4, 4, 2, 2, 1};
- */
- #endif
-
- png_ptr->row_number++;
- if (png_ptr->row_number < png_ptr->num_rows)
- return;
-
- if (png_ptr->interlaced)
- {
- png_ptr->row_number = 0;
- png_memset_check(png_ptr, png_ptr->prev_row, 0,
- png_ptr->rowbytes + 1);
- do
- {
- png_ptr->pass++;
- if ((png_ptr->pass == 1 && png_ptr->width < 5) ||
- (png_ptr->pass == 3 && png_ptr->width < 3) ||
- (png_ptr->pass == 5 && png_ptr->width < 2))
- png_ptr->pass++;
-
- if (png_ptr->pass > 7)
- png_ptr->pass--;
- if (png_ptr->pass >= 7)
- break;
-
- png_ptr->iwidth = (png_ptr->width +
- png_pass_inc[png_ptr->pass] - 1 -
- png_pass_start[png_ptr->pass]) /
- png_pass_inc[png_ptr->pass];
-
- png_ptr->irowbytes = PNG_ROWBYTES(png_ptr->pixel_depth,
- png_ptr->iwidth) + 1;
-
- if (png_ptr->transformations & PNG_INTERLACE)
- break;
-
- png_ptr->num_rows = (png_ptr->height +
- png_pass_yinc[png_ptr->pass] - 1 -
- png_pass_ystart[png_ptr->pass]) /
- png_pass_yinc[png_ptr->pass];
-
- } while (png_ptr->iwidth == 0 || png_ptr->num_rows == 0);
- }
- }
-
- #if defined(PNG_READ_tEXt_SUPPORTED)
- void /* PRIVATE */
- png_push_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
- length)
- {
- if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
- {
- png_error(png_ptr, "Out of place tEXt");
- info_ptr = info_ptr; /* to quiet some compiler warnings */
- }
-
- #ifdef PNG_MAX_MALLOC_64K
- png_ptr->skip_length = 0; /* This may not be necessary */
-
- if (length > (png_uint_32)65535L) /* Can't hold entire string in memory */
- {
- png_warning(png_ptr, "tEXt chunk too large to fit in memory");
- png_ptr->skip_length = length - (png_uint_32)65535L;
- length = (png_uint_32)65535L;
- }
- #endif
-
- png_ptr->current_text = (png_charp)png_malloc(png_ptr,
- (png_uint_32)(length+1));
- png_ptr->current_text[length] = '\0';
- png_ptr->current_text_ptr = png_ptr->current_text;
- png_ptr->current_text_size = (png_size_t)length;
- png_ptr->current_text_left = (png_size_t)length;
- png_ptr->process_mode = PNG_READ_tEXt_MODE;
- }
-
- void /* PRIVATE */
- png_push_read_tEXt(png_structp png_ptr, png_infop info_ptr)
- {
- if (png_ptr->buffer_size && png_ptr->current_text_left)
- {
- png_size_t text_size;
-
- if (png_ptr->buffer_size < png_ptr->current_text_left)
- text_size = png_ptr->buffer_size;
- else
- text_size = png_ptr->current_text_left;
- png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
- png_ptr->current_text_left -= text_size;
- png_ptr->current_text_ptr += text_size;
- }
- if (!(png_ptr->current_text_left))
- {
- png_textp text_ptr;
- png_charp text;
- png_charp key;
- int ret;
-
- if (png_ptr->buffer_size < 4)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
-
- png_push_crc_finish(png_ptr);
-
- #if defined(PNG_MAX_MALLOC_64K)
- if (png_ptr->skip_length)
- return;
- #endif
-
- key = png_ptr->current_text;
-
- for (text = key; *text; text++)
- /* empty loop */ ;
-
- if (text < key + png_ptr->current_text_size)
- text++;
-
- text_ptr = (png_textp)png_malloc(png_ptr,
- (png_uint_32)png_sizeof(png_text));
- text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
- text_ptr->key = key;
- #ifdef PNG_iTXt_SUPPORTED
- text_ptr->lang = NULL;
- text_ptr->lang_key = NULL;
- #endif
- text_ptr->text = text;
-
- ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
-
- png_free(png_ptr, key);
- png_free(png_ptr, text_ptr);
- png_ptr->current_text = NULL;
-
- if (ret)
- png_warning(png_ptr, "Insufficient memory to store text chunk.");
- }
- }
- #endif
-
- #if defined(PNG_READ_zTXt_SUPPORTED)
- void /* PRIVATE */
- png_push_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
- length)
- {
- if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
- {
- png_error(png_ptr, "Out of place zTXt");
- info_ptr = info_ptr; /* to quiet some compiler warnings */
- }
-
- #ifdef PNG_MAX_MALLOC_64K
- /* We can't handle zTXt chunks > 64K, since we don't have enough space
- * to be able to store the uncompressed data. Actually, the threshold
- * is probably around 32K, but it isn't as definite as 64K is.
- */
- if (length > (png_uint_32)65535L)
- {
- png_warning(png_ptr, "zTXt chunk too large to fit in memory");
- png_push_crc_skip(png_ptr, length);
- return;
- }
- #endif
-
- png_ptr->current_text = (png_charp)png_malloc(png_ptr,
- (png_uint_32)(length+1));
- png_ptr->current_text[length] = '\0';
- png_ptr->current_text_ptr = png_ptr->current_text;
- png_ptr->current_text_size = (png_size_t)length;
- png_ptr->current_text_left = (png_size_t)length;
- png_ptr->process_mode = PNG_READ_zTXt_MODE;
- }
-
- void /* PRIVATE */
- png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr)
- {
- if (png_ptr->buffer_size && png_ptr->current_text_left)
- {
- png_size_t text_size;
-
- if (png_ptr->buffer_size < (png_uint_32)png_ptr->current_text_left)
- text_size = png_ptr->buffer_size;
- else
- text_size = png_ptr->current_text_left;
- png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
- png_ptr->current_text_left -= text_size;
- png_ptr->current_text_ptr += text_size;
- }
- if (!(png_ptr->current_text_left))
- {
- png_textp text_ptr;
- png_charp text;
- png_charp key;
- int ret;
- png_size_t text_size, key_size;
-
- if (png_ptr->buffer_size < 4)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
-
- png_push_crc_finish(png_ptr);
-
- key = png_ptr->current_text;
-
- for (text = key; *text; text++)
- /* empty loop */ ;
-
- /* zTXt can't have zero text */
- if (text >= key + png_ptr->current_text_size)
- {
- png_ptr->current_text = NULL;
- png_free(png_ptr, key);
- return;
- }
-
- text++;
-
- if (*text != PNG_TEXT_COMPRESSION_zTXt) /* check compression byte */
- {
- png_ptr->current_text = NULL;
- png_free(png_ptr, key);
- return;
- }
-
- text++;
-
- png_ptr->zstream.next_in = (png_bytep )text;
- png_ptr->zstream.avail_in = (uInt)(png_ptr->current_text_size -
- (text - key));
- png_ptr->zstream.next_out = png_ptr->zbuf;
- png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
-
- key_size = text - key;
- text_size = 0;
- text = NULL;
- ret = Z_STREAM_END;
-
- while (png_ptr->zstream.avail_in)
- {
- ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
- if (ret != Z_OK && ret != Z_STREAM_END)
- {
- inflateReset(&png_ptr->zstream);
- png_ptr->zstream.avail_in = 0;
- png_ptr->current_text = NULL;
- png_free(png_ptr, key);
- png_free(png_ptr, text);
- return;
- }
- if (!(png_ptr->zstream.avail_out) || ret == Z_STREAM_END)
- {
- if (text == NULL)
- {
- text = (png_charp)png_malloc(png_ptr,
- (png_uint_32)(png_ptr->zbuf_size - png_ptr->zstream.avail_out
- + key_size + 1));
- png_memcpy(text + key_size, png_ptr->zbuf,
- png_ptr->zbuf_size - png_ptr->zstream.avail_out);
- png_memcpy(text, key, key_size);
- text_size = key_size + png_ptr->zbuf_size -
- png_ptr->zstream.avail_out;
- *(text + text_size) = '\0';
- }
- else
- {
- png_charp tmp;
-
- tmp = text;
- text = (png_charp)png_malloc(png_ptr, text_size +
- (png_uint_32)(png_ptr->zbuf_size - png_ptr->zstream.avail_out
- + 1));
- png_memcpy(text, tmp, text_size);
- png_free(png_ptr, tmp);
- png_memcpy(text + text_size, png_ptr->zbuf,
- png_ptr->zbuf_size - png_ptr->zstream.avail_out);
- text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out;
- *(text + text_size) = '\0';
- }
- if (ret != Z_STREAM_END)
- {
- png_ptr->zstream.next_out = png_ptr->zbuf;
- png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
- }
- }
- else
- {
- break;
- }
-
- if (ret == Z_STREAM_END)
- break;
- }
-
- inflateReset(&png_ptr->zstream);
- png_ptr->zstream.avail_in = 0;
-
- if (ret != Z_STREAM_END)
- {
- png_ptr->current_text = NULL;
- png_free(png_ptr, key);
- png_free(png_ptr, text);
- return;
- }
-
- png_ptr->current_text = NULL;
- png_free(png_ptr, key);
- key = text;
- text += key_size;
-
- text_ptr = (png_textp)png_malloc(png_ptr,
- (png_uint_32)png_sizeof(png_text));
- text_ptr->compression = PNG_TEXT_COMPRESSION_zTXt;
- text_ptr->key = key;
- #ifdef PNG_iTXt_SUPPORTED
- text_ptr->lang = NULL;
- text_ptr->lang_key = NULL;
- #endif
- text_ptr->text = text;
-
- ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
-
- png_free(png_ptr, key);
- png_free(png_ptr, text_ptr);
-
- if (ret)
- png_warning(png_ptr, "Insufficient memory to store text chunk.");
- }
- }
- #endif
-
- #if defined(PNG_READ_iTXt_SUPPORTED)
- void /* PRIVATE */
- png_push_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
- length)
- {
- if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
- {
- png_error(png_ptr, "Out of place iTXt");
- info_ptr = info_ptr; /* to quiet some compiler warnings */
- }
-
- #ifdef PNG_MAX_MALLOC_64K
- png_ptr->skip_length = 0; /* This may not be necessary */
-
- if (length > (png_uint_32)65535L) /* Can't hold entire string in memory */
- {
- png_warning(png_ptr, "iTXt chunk too large to fit in memory");
- png_ptr->skip_length = length - (png_uint_32)65535L;
- length = (png_uint_32)65535L;
- }
- #endif
-
- png_ptr->current_text = (png_charp)png_malloc(png_ptr,
- (png_uint_32)(length+1));
- png_ptr->current_text[length] = '\0';
- png_ptr->current_text_ptr = png_ptr->current_text;
- png_ptr->current_text_size = (png_size_t)length;
- png_ptr->current_text_left = (png_size_t)length;
- png_ptr->process_mode = PNG_READ_iTXt_MODE;
- }
-
- void /* PRIVATE */
- png_push_read_iTXt(png_structp png_ptr, png_infop info_ptr)
- {
-
- if (png_ptr->buffer_size && png_ptr->current_text_left)
- {
- png_size_t text_size;
-
- if (png_ptr->buffer_size < png_ptr->current_text_left)
- text_size = png_ptr->buffer_size;
- else
- text_size = png_ptr->current_text_left;
- png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
- png_ptr->current_text_left -= text_size;
- png_ptr->current_text_ptr += text_size;
- }
- if (!(png_ptr->current_text_left))
- {
- png_textp text_ptr;
- png_charp key;
- int comp_flag;
- png_charp lang;
- png_charp lang_key;
- png_charp text;
- int ret;
-
- if (png_ptr->buffer_size < 4)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
-
- png_push_crc_finish(png_ptr);
-
- #if defined(PNG_MAX_MALLOC_64K)
- if (png_ptr->skip_length)
- return;
- #endif
-
- key = png_ptr->current_text;
-
- for (lang = key; *lang; lang++)
- /* empty loop */ ;
-
- if (lang < key + png_ptr->current_text_size - 3)
- lang++;
-
- comp_flag = *lang++;
- lang++; /* skip comp_type, always zero */
-
- for (lang_key = lang; *lang_key; lang_key++)
- /* empty loop */ ;
- lang_key++; /* skip NUL separator */
-
- text=lang_key;
- if (lang_key < key + png_ptr->current_text_size - 1)
- {
- for (; *text; text++)
- /* empty loop */ ;
- }
-
- if (text < key + png_ptr->current_text_size)
- text++;
-
- text_ptr = (png_textp)png_malloc(png_ptr,
- (png_uint_32)png_sizeof(png_text));
- text_ptr->compression = comp_flag + 2;
- text_ptr->key = key;
- text_ptr->lang = lang;
- text_ptr->lang_key = lang_key;
- text_ptr->text = text;
- text_ptr->text_length = 0;
- text_ptr->itxt_length = png_strlen(text);
-
- ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
-
- png_ptr->current_text = NULL;
-
- png_free(png_ptr, text_ptr);
- if (ret)
- png_warning(png_ptr, "Insufficient memory to store iTXt chunk.");
- }
- }
- #endif
-
- /* This function is called when we haven't found a handler for this
- * chunk. If there isn't a problem with the chunk itself (ie a bad chunk
- * name or a critical chunk), the chunk is (currently) silently ignored.
- */
- void /* PRIVATE */
- png_push_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32
- length)
- {
- png_uint_32 skip=0;
- png_check_chunk_name(png_ptr, png_ptr->chunk_name);
-
- if (!(png_ptr->chunk_name[0] & 0x20))
- {
- #if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
- if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
- PNG_HANDLE_CHUNK_ALWAYS
- #if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
- && png_ptr->read_user_chunk_fn == NULL
- #endif
- )
- #endif
- png_chunk_error(png_ptr, "unknown critical chunk");
-
- info_ptr = info_ptr; /* to quiet some compiler warnings */
- }
-
- #if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
- if (png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS)
- {
- #ifdef PNG_MAX_MALLOC_64K
- if (length > (png_uint_32)65535L)
- {
- png_warning(png_ptr, "unknown chunk too large to fit in memory");
- skip = length - (png_uint_32)65535L;
- length = (png_uint_32)65535L;
- }
- #endif
- png_strncpy((png_charp)png_ptr->unknown_chunk.name,
- (png_charp)png_ptr->chunk_name, 5);
- png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr, length);
- png_ptr->unknown_chunk.size = (png_size_t)length;
- png_crc_read(png_ptr, (png_bytep)png_ptr->unknown_chunk.data, length);
- #if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
- if(png_ptr->read_user_chunk_fn != NULL)
- {
- /* callback to user unknown chunk handler */
- int ret;
- ret = (*(png_ptr->read_user_chunk_fn))
- (png_ptr, &png_ptr->unknown_chunk);
- if (ret < 0)
- png_chunk_error(png_ptr, "error in user chunk");
- if (ret == 0)
- {
- if (!(png_ptr->chunk_name[0] & 0x20))
- if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
- PNG_HANDLE_CHUNK_ALWAYS)
- png_chunk_error(png_ptr, "unknown critical chunk");
- png_set_unknown_chunks(png_ptr, info_ptr,
- &png_ptr->unknown_chunk, 1);
- }
- }
- #else
- png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1);
- #endif
- png_free(png_ptr, png_ptr->unknown_chunk.data);
- png_ptr->unknown_chunk.data = NULL;
- }
- else
- #endif
- skip=length;
- png_push_crc_skip(png_ptr, skip);
- }
-
- void /* PRIVATE */
- png_push_have_info(png_structp png_ptr, png_infop info_ptr)
- {
- if (png_ptr->info_fn != NULL)
- (*(png_ptr->info_fn))(png_ptr, info_ptr);
- }
-
- void /* PRIVATE */
- png_push_have_end(png_structp png_ptr, png_infop info_ptr)
- {
- if (png_ptr->end_fn != NULL)
- (*(png_ptr->end_fn))(png_ptr, info_ptr);
- }
-
- void /* PRIVATE */
- png_push_have_row(png_structp png_ptr, png_bytep row)
- {
- if (png_ptr->row_fn != NULL)
- (*(png_ptr->row_fn))(png_ptr, row, png_ptr->row_number,
- (int)png_ptr->pass);
- }
-
- void PNGAPI
- png_progressive_combine_row (png_structp png_ptr,
- png_bytep old_row, png_bytep new_row)
- {
- #ifdef PNG_USE_LOCAL_ARRAYS
- PNG_CONST int FARDATA png_pass_dsp_mask[7] =
- {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff};
- #endif
- if(png_ptr == NULL) return;
- if (new_row != NULL) /* new_row must == png_ptr->row_buf here. */
- png_combine_row(png_ptr, old_row, png_pass_dsp_mask[png_ptr->pass]);
- }
-
- void PNGAPI
- png_set_progressive_read_fn(png_structp png_ptr, png_voidp progressive_ptr,
- png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn,
- png_progressive_end_ptr end_fn)
- {
- if(png_ptr == NULL) return;
- png_ptr->info_fn = info_fn;
- png_ptr->row_fn = row_fn;
- png_ptr->end_fn = end_fn;
-
- png_set_read_fn(png_ptr, progressive_ptr, png_push_fill_buffer);
- }
-
- png_voidp PNGAPI
- png_get_progressive_ptr(png_structp png_ptr)
- {
- if(png_ptr == NULL) return (NULL);
- return png_ptr->io_ptr;
- }
- #endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
- /********* End of inlined file: pngpread.c *********/
-
- /********* Start of inlined file: pngrio.c *********/
- /* pngrio.c - functions for data input
- *
- * Last changed in libpng 1.2.13 November 13, 2006
- * For conditions of distribution and use, see copyright notice in png.h
- * Copyright (c) 1998-2006 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
- *
- * This file provides a location for all input. Users who need
- * special handling are expected to write a function that has the same
- * arguments as this and performs a similar function, but that possibly
- * has a different input method. Note that you shouldn't change this
- * function, but rather write a replacement function and then make
- * libpng use it at run time with png_set_read_fn(...).
- */
-
- #define PNG_INTERNAL
-
- #if defined(PNG_READ_SUPPORTED)
-
- /* Read the data from whatever input you are using. The default routine
- reads from a file pointer. Note that this routine sometimes gets called
- with very small lengths, so you should implement some kind of simple
- buffering if you are using unbuffered reads. This should never be asked
- to read more then 64K on a 16 bit machine. */
- void /* PRIVATE */
- png_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
- {
- png_debug1(4,"reading %d bytes\n", (int)length);
- if (png_ptr->read_data_fn != NULL)
- (*(png_ptr->read_data_fn))(png_ptr, data, length);
- else
- png_error(png_ptr, "Call to NULL read function");
- }
-
- #if !defined(PNG_NO_STDIO)
- /* This is the function that does the actual reading of data. If you are
- not reading from a standard C stream, you should create a replacement
- read_data function and use it at run time with png_set_read_fn(), rather
- than changing the library. */
- #ifndef USE_FAR_KEYWORD
- void PNGAPI
- png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
- {
- png_size_t check;
-
- if(png_ptr == NULL) return;
- /* fread() returns 0 on error, so it is OK to store this in a png_size_t
- * instead of an int, which is what fread() actually returns.
- */
- #if defined(_WIN32_WCE)
- if ( !ReadFile((HANDLE)(png_ptr->io_ptr), data, length, &check, NULL) )
- check = 0;
- #else
- check = (png_size_t)fread(data, (png_size_t)1, length,
- (png_FILE_p)png_ptr->io_ptr);
- #endif
-
- if (check != length)
- png_error(png_ptr, "Read Error");
- }
- #else
- /* this is the model-independent version. Since the standard I/O library
- can't handle far buffers in the medium and small models, we have to copy
- the data.
- */
-
- #define NEAR_BUF_SIZE 1024
- #define MIN(a,b) (a <= b ? a : b)
-
- static void PNGAPI
- png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
- {
- int check;
- png_byte *n_data;
- png_FILE_p io_ptr;
-
- if(png_ptr == NULL) return;
- /* Check if data really is near. If so, use usual code. */
- n_data = (png_byte *)CVT_PTR_NOCHECK(data);
- io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr);
- if ((png_bytep)n_data == data)
- {
- #if defined(_WIN32_WCE)
- if ( !ReadFile((HANDLE)(png_ptr->io_ptr), data, length, &check, NULL) )
- check = 0;
- #else
- check = fread(n_data, 1, length, io_ptr);
- #endif
- }
- else
- {
- png_byte buf[NEAR_BUF_SIZE];
- png_size_t read, remaining, err;
- check = 0;
- remaining = length;
- do
- {
- read = MIN(NEAR_BUF_SIZE, remaining);
- #if defined(_WIN32_WCE)
- if ( !ReadFile((HANDLE)(io_ptr), buf, read, &err, NULL) )
- err = 0;
- #else
- err = fread(buf, (png_size_t)1, read, io_ptr);
- #endif
- png_memcpy(data, buf, read); /* copy far buffer to near buffer */
- if(err != read)
- break;
- else
- check += err;
- data += read;
- remaining -= read;
- }
- while (remaining != 0);
- }
- if ((png_uint_32)check != (png_uint_32)length)
- png_error(png_ptr, "read Error");
- }
- #endif
- #endif
-
- /* This function allows the application to supply a new input function
- for libpng if standard C streams aren't being used.
-
- This function takes as its arguments:
- png_ptr - pointer to a png input data structure
- io_ptr - pointer to user supplied structure containing info about
- the input functions. May be NULL.
- read_data_fn - pointer to a new input function that takes as its
- arguments a pointer to a png_struct, a pointer to
- a location where input data can be stored, and a 32-bit
- unsigned int that is the number of bytes to be read.
- To exit and output any fatal error messages the new write
- function should call png_error(png_ptr, "Error msg"). */
- void PNGAPI
- png_set_read_fn(png_structp png_ptr, png_voidp io_ptr,
- png_rw_ptr read_data_fn)
- {
- if(png_ptr == NULL) return;
- png_ptr->io_ptr = io_ptr;
-
- #if !defined(PNG_NO_STDIO)
- if (read_data_fn != NULL)
- png_ptr->read_data_fn = read_data_fn;
- else
- png_ptr->read_data_fn = png_default_read_data;
- #else
- png_ptr->read_data_fn = read_data_fn;
- #endif
-
- /* It is an error to write to a read device */
- if (png_ptr->write_data_fn != NULL)
- {
- png_ptr->write_data_fn = NULL;
- png_warning(png_ptr,
- "It's an error to set both read_data_fn and write_data_fn in the ");
- png_warning(png_ptr,
- "same structure. Resetting write_data_fn to NULL.");
- }
-
- #if defined(PNG_WRITE_FLUSH_SUPPORTED)
- png_ptr->output_flush_fn = NULL;
- #endif
- }
- #endif /* PNG_READ_SUPPORTED */
- /********* End of inlined file: pngrio.c *********/
-
- /********* Start of inlined file: pngrtran.c *********/
- /* pngrtran.c - transforms the data in a row for PNG readers
- *
- * Last changed in libpng 1.2.21 [October 4, 2007]
- * For conditions of distribution and use, see copyright notice in png.h
- * Copyright (c) 1998-2007 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
- *
- * This file contains functions optionally called by an application
- * in order to tell libpng how to handle data when reading a PNG.
- * Transformations that are used in both reading and writing are
- * in pngtrans.c.
- */
-
- #define PNG_INTERNAL
-
- #if defined(PNG_READ_SUPPORTED)
-
- /* Set the action on getting a CRC error for an ancillary or critical chunk. */
- void PNGAPI
- png_set_crc_action(png_structp png_ptr, int crit_action, int ancil_action)
- {
- png_debug(1, "in png_set_crc_action\n");
- /* Tell libpng how we react to CRC errors in critical chunks */
- if(png_ptr == NULL) return;
- switch (crit_action)
- {
- case PNG_CRC_NO_CHANGE: /* leave setting as is */
- break;
- case PNG_CRC_WARN_USE: /* warn/use data */
- png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
- png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE;
- break;
- case PNG_CRC_QUIET_USE: /* quiet/use data */
- png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
- png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE |
- PNG_FLAG_CRC_CRITICAL_IGNORE;
- break;
- case PNG_CRC_WARN_DISCARD: /* not a valid action for critical data */
- png_warning(png_ptr, "Can't discard critical data on CRC error.");
- case PNG_CRC_ERROR_QUIT: /* error/quit */
- case PNG_CRC_DEFAULT:
- default:
- png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
- break;
- }
-
- switch (ancil_action)
- {
- case PNG_CRC_NO_CHANGE: /* leave setting as is */
- break;
- case PNG_CRC_WARN_USE: /* warn/use data */
- png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
- png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE;
- break;
- case PNG_CRC_QUIET_USE: /* quiet/use data */
- png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
- png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE |
- PNG_FLAG_CRC_ANCILLARY_NOWARN;
- break;
- case PNG_CRC_ERROR_QUIT: /* error/quit */
- png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
- png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_NOWARN;
- break;
- case PNG_CRC_WARN_DISCARD: /* warn/discard data */
- case PNG_CRC_DEFAULT:
- default:
- png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
- break;
- }
- }
-
- #if defined(PNG_READ_BACKGROUND_SUPPORTED) && \
- defined(PNG_FLOATING_POINT_SUPPORTED)
- /* handle alpha and tRNS via a background color */
- void PNGAPI
- png_set_background(png_structp png_ptr,
- png_color_16p background_color, int background_gamma_code,
- int need_expand, double background_gamma)
- {
- png_debug(1, "in png_set_background\n");
- if(png_ptr == NULL) return;
- if (background_gamma_code == PNG_BACKGROUND_GAMMA_UNKNOWN)
- {
- png_warning(png_ptr, "Application must supply a known background gamma");
- return;
- }
-
- png_ptr->transformations |= PNG_BACKGROUND;
- png_memcpy(&(png_ptr->background), background_color,
- png_sizeof(png_color_16));
- png_ptr->background_gamma = (float)background_gamma;
- png_ptr->background_gamma_type = (png_byte)(background_gamma_code);
- png_ptr->transformations |= (need_expand ? PNG_BACKGROUND_EXPAND : 0);
- }
- #endif
-
- #if defined(PNG_READ_16_TO_8_SUPPORTED)
- /* strip 16 bit depth files to 8 bit depth */
- void PNGAPI
- png_set_strip_16(png_structp png_ptr)
- {
- png_debug(1, "in png_set_strip_16\n");
- if(png_ptr == NULL) return;
- png_ptr->transformations |= PNG_16_TO_8;
- }
- #endif
-
- #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
- void PNGAPI
- png_set_strip_alpha(png_structp png_ptr)
- {
- png_debug(1, "in png_set_strip_alpha\n");
- if(png_ptr == NULL) return;
- png_ptr->flags |= PNG_FLAG_STRIP_ALPHA;
- }
- #endif
-
- #if defined(PNG_READ_DITHER_SUPPORTED)
- /* Dither file to 8 bit. Supply a palette, the current number
- * of elements in the palette, the maximum number of elements
- * allowed, and a histogram if possible. If the current number
- * of colors is greater then the maximum number, the palette will be
- * modified to fit in the maximum number. "full_dither" indicates
- * whether we need a dithering cube set up for RGB images, or if we
- * simply are reducing the number of colors in a paletted image.
- */
-
- typedef struct png_dsort_struct
- {
- struct png_dsort_struct FAR * next;
- png_byte left;
- png_byte right;
- } png_dsort;
- typedef png_dsort FAR * png_dsortp;
- typedef png_dsort FAR * FAR * png_dsortpp;
-
- void PNGAPI
- png_set_dither(png_structp png_ptr, png_colorp palette,
- int num_palette, int maximum_colors, png_uint_16p histogram,
- int full_dither)
- {
- png_debug(1, "in png_set_dither\n");
- if(png_ptr == NULL) return;
- png_ptr->transformations |= PNG_DITHER;
-
- if (!full_dither)
- {
- int i;
-
- png_ptr->dither_index = (png_bytep)png_malloc(png_ptr,
- (png_uint_32)(num_palette * png_sizeof (png_byte)));
- for (i = 0; i < num_palette; i++)
- png_ptr->dither_index[i] = (png_byte)i;
- }
-
- if (num_palette > maximum_colors)
- {
- if (histogram != NULL)
- {
- /* This is easy enough, just throw out the least used colors.
- Perhaps not the best solution, but good enough. */
-
- int i;
-
- /* initialize an array to sort colors */
- png_ptr->dither_sort = (png_bytep)png_malloc(png_ptr,
- (png_uint_32)(num_palette * png_sizeof (png_byte)));
-
- /* initialize the dither_sort array */
- for (i = 0; i < num_palette; i++)
- png_ptr->dither_sort[i] = (png_byte)i;
-
- /* Find the least used palette entries by starting a
- bubble sort, and running it until we have sorted
- out enough colors. Note that we don't care about
- sorting all the colors, just finding which are
- least used. */
-
- for (i = num_palette - 1; i >= maximum_colors; i--)
- {
- int done; /* to stop early if the list is pre-sorted */
- int j;
-
- done = 1;
- for (j = 0; j < i; j++)
- {
- if (histogram[png_ptr->dither_sort[j]]
- < histogram[png_ptr->dither_sort[j + 1]])
- {
- png_byte t;
-
- t = png_ptr->dither_sort[j];
- png_ptr->dither_sort[j] = png_ptr->dither_sort[j + 1];
- png_ptr->dither_sort[j + 1] = t;
- done = 0;
- }
- }
- if (done)
- break;
- }
-
- /* swap the palette around, and set up a table, if necessary */
- if (full_dither)
- {
- int j = num_palette;
-
- /* put all the useful colors within the max, but don't
- move the others */
- for (i = 0; i < maximum_colors; i++)
- {
- if ((int)png_ptr->dither_sort[i] >= maximum_colors)
- {
- do
- j--;
- while ((int)png_ptr->dither_sort[j] >= maximum_colors);
- palette[i] = palette[j];
- }
- }
- }
- else
- {
- int j = num_palette;
-
- /* move all the used colors inside the max limit, and
- develop a translation table */
- for (i = 0; i < maximum_colors; i++)
- {
- /* only move the colors we need to */
- if ((int)png_ptr->dither_sort[i] >= maximum_colors)
- {
- png_color tmp_color;
-
- do
- j--;
- while ((int)png_ptr->dither_sort[j] >= maximum_colors);
-
- tmp_color = palette[j];
- palette[j] = palette[i];
- palette[i] = tmp_color;
- /* indicate where the color went */
- png_ptr->dither_index[j] = (png_byte)i;
- png_ptr->dither_index[i] = (png_byte)j;
- }
- }
-
- /* find closest color for those colors we are not using */
- for (i = 0; i < num_palette; i++)
- {
- if ((int)png_ptr->dither_index[i] >= maximum_colors)
- {
- int min_d, k, min_k, d_index;
-
- /* find the closest color to one we threw out */
- d_index = png_ptr->dither_index[i];
- min_d = PNG_COLOR_DIST(palette[d_index], palette[0]);
- for (k = 1, min_k = 0; k < maximum_colors; k++)
- {
- int d;
-
- d = PNG_COLOR_DIST(palette[d_index], palette[k]);
-
- if (d < min_d)
- {
- min_d = d;
- min_k = k;
- }
- }
- /* point to closest color */
- png_ptr->dither_index[i] = (png_byte)min_k;
- }
- }
- }
- png_free(png_ptr, png_ptr->dither_sort);
- png_ptr->dither_sort=NULL;
- }
- else
- {
- /* This is much harder to do simply (and quickly). Perhaps
- we need to go through a median cut routine, but those
- don't always behave themselves with only a few colors
- as input. So we will just find the closest two colors,
- and throw out one of them (chosen somewhat randomly).
- [We don't understand this at all, so if someone wants to
- work on improving it, be our guest - AED, GRP]
- */
- int i;
- int max_d;
- int num_new_palette;
- png_dsortp t;
- png_dsortpp hash;
-
- t=NULL;
-
- /* initialize palette index arrays */
- png_ptr->index_to_palette = (png_bytep)png_malloc(png_ptr,
- (png_uint_32)(num_palette * png_sizeof (png_byte)));
- png_ptr->palette_to_index = (png_bytep)png_malloc(png_ptr,
- (png_uint_32)(num_palette * png_sizeof (png_byte)));
-
- /* initialize the sort array */
- for (i = 0; i < num_palette; i++)
- {
- png_ptr->index_to_palette[i] = (png_byte)i;
- png_ptr->palette_to_index[i] = (png_byte)i;
- }
-
- hash = (png_dsortpp)png_malloc(png_ptr, (png_uint_32)(769 *
- png_sizeof (png_dsortp)));
- for (i = 0; i < 769; i++)
- hash[i] = NULL;
- /* png_memset(hash, 0, 769 * png_sizeof (png_dsortp)); */
-
- num_new_palette = num_palette;
-
- /* initial wild guess at how far apart the farthest pixel
- pair we will be eliminating will be. Larger
- numbers mean more areas will be allocated, Smaller
- numbers run the risk of not saving enough data, and
- having to do this all over again.
-
- I have not done extensive checking on this number.
- */
- max_d = 96;
-
- while (num_new_palette > maximum_colors)
- {
- for (i = 0; i < num_new_palette - 1; i++)
- {
- int j;
-
- for (j = i + 1; j < num_new_palette; j++)
- {
- int d;
-
- d = PNG_COLOR_DIST(palette[i], palette[j]);
-
- if (d <= max_d)
- {
-
- t = (png_dsortp)png_malloc_warn(png_ptr,
- (png_uint_32)(png_sizeof(png_dsort)));
- if (t == NULL)
- break;
- t->next = hash[d];
- t->left = (png_byte)i;
- t->right = (png_byte)j;
- hash[d] = t;
- }
- }
- if (t == NULL)
- break;
- }
-
- if (t != NULL)
- for (i = 0; i <= max_d; i++)
- {
- if (hash[i] != NULL)
- {
- png_dsortp p;
-
- for (p = hash[i]; p; p = p->next)
- {
- if ((int)png_ptr->index_to_palette[p->left]
- < num_new_palette &&
- (int)png_ptr->index_to_palette[p->right]
- < num_new_palette)
- {
- int j, next_j;
-
- if (num_new_palette & 0x01)
- {
- j = p->left;
- next_j = p->right;
- }
- else
- {
- j = p->right;
- next_j = p->left;
- }
-
- num_new_palette--;
- palette[png_ptr->index_to_palette[j]]
- = palette[num_new_palette];
- if (!full_dither)
- {
- int k;
-
- for (k = 0; k < num_palette; k++)
- {
- if (png_ptr->dither_index[k] ==
- png_ptr->index_to_palette[j])
- png_ptr->dither_index[k] =
- png_ptr->index_to_palette[next_j];
- if ((int)png_ptr->dither_index[k] ==
- num_new_palette)
- png_ptr->dither_index[k] =
- png_ptr->index_to_palette[j];
- }
- }
-
- png_ptr->index_to_palette[png_ptr->palette_to_index
- [num_new_palette]] = png_ptr->index_to_palette[j];
- png_ptr->palette_to_index[png_ptr->index_to_palette[j]]
- = png_ptr->palette_to_index[num_new_palette];
-
- png_ptr->index_to_palette[j] = (png_byte)num_new_palette;
- png_ptr->palette_to_index[num_new_palette] = (png_byte)j;
- }
- if (num_new_palette <= maximum_colors)
- break;
- }
- if (num_new_palette <= maximum_colors)
- break;
- }
- }
-
- for (i = 0; i < 769; i++)
- {
- if (hash[i] != NULL)
- {
- png_dsortp p = hash[i];
- while (p)
- {
- t = p->next;
- png_free(png_ptr, p);
- p = t;
- }
- }
- hash[i] = 0;
- }
- max_d += 96;
- }
- png_free(png_ptr, hash);
- png_free(png_ptr, png_ptr->palette_to_index);
- png_free(png_ptr, png_ptr->index_to_palette);
- png_ptr->palette_to_index=NULL;
- png_ptr->index_to_palette=NULL;
- }
- num_palette = maximum_colors;
- }
- if (png_ptr->palette == NULL)
- {
- png_ptr->palette = palette;
- }
- png_ptr->num_palette = (png_uint_16)num_palette;
-
- if (full_dither)
- {
- int i;
- png_bytep distance;
- int total_bits = PNG_DITHER_RED_BITS + PNG_DITHER_GREEN_BITS +
- PNG_DITHER_BLUE_BITS;
- int num_red = (1 << PNG_DITHER_RED_BITS);
- int num_green = (1 << PNG_DITHER_GREEN_BITS);
- int num_blue = (1 << PNG_DITHER_BLUE_BITS);
- png_size_t num_entries = ((png_size_t)1 << total_bits);
-
- png_ptr->palette_lookup = (png_bytep )png_malloc(png_ptr,
- (png_uint_32)(num_entries * png_sizeof (png_byte)));
-
- png_memset(png_ptr->palette_lookup, 0, num_entries *
- png_sizeof (png_byte));
-
- distance = (png_bytep)png_malloc(png_ptr, (png_uint_32)(num_entries *
- png_sizeof(png_byte)));
-
- png_memset(distance, 0xff, num_entries * png_sizeof(png_byte));
-
- for (i = 0; i < num_palette; i++)
- {
- int ir, ig, ib;
- int r = (palette[i].red >> (8 - PNG_DITHER_RED_BITS));
- int g = (palette[i].green >> (8 - PNG_DITHER_GREEN_BITS));
- int b = (palette[i].blue >> (8 - PNG_DITHER_BLUE_BITS));
-
- for (ir = 0; ir < num_red; ir++)
- {
- /* int dr = abs(ir - r); */
- int dr = ((ir > r) ? ir - r : r - ir);
- int index_r = (ir << (PNG_DITHER_BLUE_BITS + PNG_DITHER_GREEN_BITS));
-
- for (ig = 0; ig < num_green; ig++)
- {
- /* int dg = abs(ig - g); */
- int dg = ((ig > g) ? ig - g : g - ig);
- int dt = dr + dg;
- int dm = ((dr > dg) ? dr : dg);
- int index_g = index_r | (ig << PNG_DITHER_BLUE_BITS);
-
- for (ib = 0; ib < num_blue; ib++)
- {
- int d_index = index_g | ib;
- /* int db = abs(ib - b); */
- int db = ((ib > b) ? ib - b : b - ib);
- int dmax = ((dm > db) ? dm : db);
- int d = dmax + dt + db;
-
- if (d < (int)distance[d_index])
- {
- distance[d_index] = (png_byte)d;
- png_ptr->palette_lookup[d_index] = (png_byte)i;
- }
- }
- }
- }
- }
-
- png_free(png_ptr, distance);
- }
- }
- #endif
-
- #if defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
- /* Transform the image from the file_gamma to the screen_gamma. We
- * only do transformations on images where the file_gamma and screen_gamma
- * are not close reciprocals, otherwise it slows things down slightly, and
- * also needlessly introduces small errors.
- *
- * We will turn off gamma transformation later if no semitransparent entries
- * are present in the tRNS array for palette images. We can't do it here
- * because we don't necessarily have the tRNS chunk yet.
- */
- void PNGAPI
- png_set_gamma(png_structp png_ptr, double scrn_gamma, double file_gamma)
- {
- png_debug(1, "in png_set_gamma\n");
- if(png_ptr == NULL) return;
- if ((fabs(scrn_gamma * file_gamma - 1.0) > PNG_GAMMA_THRESHOLD) ||
- (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) ||
- (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE))
- png_ptr->transformations |= PNG_GAMMA;
- png_ptr->gamma = (float)file_gamma;
- png_ptr->screen_gamma = (float)scrn_gamma;
- }
- #endif
-
- #if defined(PNG_READ_EXPAND_SUPPORTED)
- /* Expand paletted images to RGB, expand grayscale images of
- * less than 8-bit depth to 8-bit depth, and expand tRNS chunks
- * to alpha channels.
- */
- void PNGAPI
- png_set_expand(png_structp png_ptr)
- {
- png_debug(1, "in png_set_expand\n");
- if(png_ptr == NULL) return;
- png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
- #ifdef PNG_WARN_UNINITIALIZED_ROW
- png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
- #endif
- }
-
- /* GRR 19990627: the following three functions currently are identical
- * to png_set_expand(). However, it is entirely reasonable that someone
- * might wish to expand an indexed image to RGB but *not* expand a single,
- * fully transparent palette entry to a full alpha channel--perhaps instead
- * convert tRNS to the grayscale/RGB format (16-bit RGB value), or replace
- * the transparent color with a particular RGB value, or drop tRNS entirely.
- * IOW, a future version of the library may make the transformations flag
- * a bit more fine-grained, with separate bits for each of these three
- * functions.
- *
- * More to the point, these functions make it obvious what libpng will be
- * doing, whereas "expand" can (and does) mean any number of things.
- *
- * GRP 20060307: In libpng-1.4.0, png_set_gray_1_2_4_to_8() was modified
- * to expand only the sample depth but not to expand the tRNS to alpha.
- */
-
- /* Expand paletted images to RGB. */
- void PNGAPI
- png_set_palette_to_rgb(png_structp png_ptr)
- {
- png_debug(1, "in png_set_palette_to_rgb\n");
- if(png_ptr == NULL) return;
- png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
- #ifdef PNG_WARN_UNINITIALIZED_ROW
- png_ptr->flags &= !(PNG_FLAG_ROW_INIT);
- png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
- #endif
- }
-
- #if !defined(PNG_1_0_X)
- /* Expand grayscale images of less than 8-bit depth to 8 bits. */
- void PNGAPI
- png_set_expand_gray_1_2_4_to_8(png_structp png_ptr)
- {
- png_debug(1, "in png_set_expand_gray_1_2_4_to_8\n");
- if(png_ptr == NULL) return;
- png_ptr->transformations |= PNG_EXPAND;
- #ifdef PNG_WARN_UNINITIALIZED_ROW
- png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
- #endif
- }
- #endif
-
- #if defined(PNG_1_0_X) || defined(PNG_1_2_X)
- /* Expand grayscale images of less than 8-bit depth to 8 bits. */
- /* Deprecated as of libpng-1.2.9 */
- void PNGAPI
- png_set_gray_1_2_4_to_8(png_structp png_ptr)
- {
- png_debug(1, "in png_set_gray_1_2_4_to_8\n");
- if(png_ptr == NULL) return;
- png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
- }
- #endif
-
- /* Expand tRNS chunks to alpha channels. */
- void PNGAPI
- png_set_tRNS_to_alpha(png_structp png_ptr)
- {
- png_debug(1, "in png_set_tRNS_to_alpha\n");
- png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
- #ifdef PNG_WARN_UNINITIALIZED_ROW
- png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
- #endif
- }
- #endif /* defined(PNG_READ_EXPAND_SUPPORTED) */
-
- #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
- void PNGAPI
- png_set_gray_to_rgb(png_structp png_ptr)
- {
- png_debug(1, "in png_set_gray_to_rgb\n");
- png_ptr->transformations |= PNG_GRAY_TO_RGB;
- #ifdef PNG_WARN_UNINITIALIZED_ROW
- png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
- #endif
- }
- #endif
-
- #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
- #if defined(PNG_FLOATING_POINT_SUPPORTED)
- /* Convert a RGB image to a grayscale of the same width. This allows us,
- * for example, to convert a 24 bpp RGB image into an 8 bpp grayscale image.
- */
-
- void PNGAPI
- png_set_rgb_to_gray(png_structp png_ptr, int error_action, double red,
- double green)
- {
- int red_fixed = (int)((float)red*100000.0 + 0.5);
- int green_fixed = (int)((float)green*100000.0 + 0.5);
- if(png_ptr == NULL) return;
- png_set_rgb_to_gray_fixed(png_ptr, error_action, red_fixed, green_fixed);
- }
- #endif
-
- void PNGAPI
- png_set_rgb_to_gray_fixed(png_structp png_ptr, int error_action,
- png_fixed_point red, png_fixed_point green)
- {
- png_debug(1, "in png_set_rgb_to_gray\n");
- if(png_ptr == NULL) return;
- switch(error_action)
- {
- case 1: png_ptr->transformations |= PNG_RGB_TO_GRAY;
- break;
- case 2: png_ptr->transformations |= PNG_RGB_TO_GRAY_WARN;
- break;
- case 3: png_ptr->transformations |= PNG_RGB_TO_GRAY_ERR;
- }
- if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
- #if defined(PNG_READ_EXPAND_SUPPORTED)
- png_ptr->transformations |= PNG_EXPAND;
- #else
- {
- png_warning(png_ptr, "Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED.");
- png_ptr->transformations &= ~PNG_RGB_TO_GRAY;
- }
- #endif
- {
- png_uint_16 red_int, green_int;
- if(red < 0 || green < 0)
- {
- red_int = 6968; /* .212671 * 32768 + .5 */
- green_int = 23434; /* .715160 * 32768 + .5 */
- }
- else if(red + green < 100000L)
- {
- red_int = (png_uint_16)(((png_uint_32)red*32768L)/100000L);
- green_int = (png_uint_16)(((png_uint_32)green*32768L)/100000L);
- }
- else
- {
- png_warning(png_ptr, "ignoring out of range rgb_to_gray coefficients");
- red_int = 6968;
- green_int = 23434;
- }
- png_ptr->rgb_to_gray_red_coeff = red_int;
- png_ptr->rgb_to_gray_green_coeff = green_int;
- png_ptr->rgb_to_gray_blue_coeff = (png_uint_16)(32768-red_int-green_int);
- }
- }
- #endif
-
- #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
- defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \
- defined(PNG_LEGACY_SUPPORTED)
- void PNGAPI
- png_set_read_user_transform_fn(png_structp png_ptr, png_user_transform_ptr
- read_user_transform_fn)
- {
- png_debug(1, "in png_set_read_user_transform_fn\n");
- if(png_ptr == NULL) return;
- #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
- png_ptr->transformations |= PNG_USER_TRANSFORM;
- png_ptr->read_user_transform_fn = read_user_transform_fn;
- #endif
- #ifdef PNG_LEGACY_SUPPORTED
- if(read_user_transform_fn)
- png_warning(png_ptr,
- "This version of libpng does not support user transforms");
- #endif
- }
- #endif
-
- /* Initialize everything needed for the read. This includes modifying
- * the palette.
- */
- void /* PRIVATE */
- png_init_read_transformations(png_structp png_ptr)
- {
- png_debug(1, "in png_init_read_transformations\n");
- #if defined(PNG_USELESS_TESTS_SUPPORTED)
- if(png_ptr != NULL)
- #endif
- {
- #if defined(PNG_READ_BACKGROUND_SUPPORTED) || defined(PNG_READ_SHIFT_SUPPORTED) \
- || defined(PNG_READ_GAMMA_SUPPORTED)
- int color_type = png_ptr->color_type;
- #endif
-
- #if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)
-
- #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
- /* Detect gray background and attempt to enable optimization
- * for gray --> RGB case */
- /* Note: if PNG_BACKGROUND_EXPAND is set and color_type is either RGB or
- * RGB_ALPHA (in which case need_expand is superfluous anyway), the
- * background color might actually be gray yet not be flagged as such.
- * This is not a problem for the current code, which uses
- * PNG_BACKGROUND_IS_GRAY only to decide when to do the
- * png_do_gray_to_rgb() transformation.
- */
- if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&
- !(color_type & PNG_COLOR_MASK_COLOR))
- {
- png_ptr->mode |= PNG_BACKGROUND_IS_GRAY;
- } else if ((png_ptr->transformations & PNG_BACKGROUND) &&
- !(png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&
- (png_ptr->transformations & PNG_GRAY_TO_RGB) &&
- png_ptr->background.red == png_ptr->background.green &&
- png_ptr->background.red == png_ptr->background.blue)
- {
- png_ptr->mode |= PNG_BACKGROUND_IS_GRAY;
- png_ptr->background.gray = png_ptr->background.red;
- }
- #endif
-
- if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&
- (png_ptr->transformations & PNG_EXPAND))
- {
- if (!(color_type & PNG_COLOR_MASK_COLOR)) /* i.e., GRAY or GRAY_ALPHA */
- {
- /* expand background and tRNS chunks */
- switch (png_ptr->bit_depth)
- {
- case 1:
- png_ptr->background.gray *= (png_uint_16)0xff;
- png_ptr->background.red = png_ptr->background.green
- = png_ptr->background.blue = png_ptr->background.gray;
- if (!(png_ptr->transformations & PNG_EXPAND_tRNS))
- {
- png_ptr->trans_values.gray *= (png_uint_16)0xff;
- png_ptr->trans_values.red = png_ptr->trans_values.green
- = png_ptr->trans_values.blue = png_ptr->trans_values.gray;
- }
- break;
- case 2:
- png_ptr->background.gray *= (png_uint_16)0x55;
- png_ptr->background.red = png_ptr->background.green
- = png_ptr->background.blue = png_ptr->background.gray;
- if (!(png_ptr->transformations & PNG_EXPAND_tRNS))
- {
- png_ptr->trans_values.gray *= (png_uint_16)0x55;
- png_ptr->trans_values.red = png_ptr->trans_values.green
- = png_ptr->trans_values.blue = png_ptr->trans_values.gray;
- }
- break;
- case 4:
- png_ptr->background.gray *= (png_uint_16)0x11;
- png_ptr->background.red = png_ptr->background.green
- = png_ptr->background.blue = png_ptr->background.gray;
- if (!(png_ptr->transformations & PNG_EXPAND_tRNS))
- {
- png_ptr->trans_values.gray *= (png_uint_16)0x11;
- png_ptr->trans_values.red = png_ptr->trans_values.green
- = png_ptr->trans_values.blue = png_ptr->trans_values.gray;
- }
- break;
- case 8:
- case 16:
- png_ptr->background.red = png_ptr->background.green
- = png_ptr->background.blue = png_ptr->background.gray;
- break;
- }
- }
- else if (color_type == PNG_COLOR_TYPE_PALETTE)
- {
- png_ptr->background.red =
- png_ptr->palette[png_ptr->background.index].red;
- png_ptr->background.green =
- png_ptr->palette[png_ptr->background.index].green;
- png_ptr->background.blue =
- png_ptr->palette[png_ptr->background.index].blue;
-
- #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
- if (png_ptr->transformations & PNG_INVERT_ALPHA)
- {
- #if defined(PNG_READ_EXPAND_SUPPORTED)
- if (!(png_ptr->transformations & PNG_EXPAND_tRNS))
- #endif
- {
- /* invert the alpha channel (in tRNS) unless the pixels are
- going to be expanded, in which case leave it for later */
- int i,istop;
- istop=(int)png_ptr->num_trans;
- for (i=0; i<istop; i++)
- png_ptr->trans[i] = (png_byte)(255 - png_ptr->trans[i]);
- }
- }
- #endif
-
- }
- }
- #endif
-
- #if defined(PNG_READ_BACKGROUND_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
- png_ptr->background_1 = png_ptr->background;
- #endif
- #if defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
-
- if ((color_type == PNG_COLOR_TYPE_PALETTE && png_ptr->num_trans != 0)
- && (fabs(png_ptr->screen_gamma * png_ptr->gamma - 1.0)
- < PNG_GAMMA_THRESHOLD))
- {
- int i,k;
- k=0;
- for (i=0; i<png_ptr->num_trans; i++)
- {
- if (png_ptr->trans[i] != 0 && png_ptr->trans[i] != 0xff)
- k=1; /* partial transparency is present */
- }
- if (k == 0)
- png_ptr->transformations &= (~PNG_GAMMA);
- }
-
- if ((png_ptr->transformations & (PNG_GAMMA | PNG_RGB_TO_GRAY)) &&
- png_ptr->gamma != 0.0)
- {
- png_build_gamma_table(png_ptr);
- #if defined(PNG_READ_BACKGROUND_SUPPORTED)
- if (png_ptr->transformations & PNG_BACKGROUND)
- {
- if (color_type == PNG_COLOR_TYPE_PALETTE)
- {
- /* could skip if no transparency and
- */
- png_color back, back_1;
- png_colorp palette = png_ptr->palette;
- int num_palette = png_ptr->num_palette;
- int i;
- if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE)
- {
- back.red = png_ptr->gamma_table[png_ptr->background.red];
- back.green = png_ptr->gamma_table[png_ptr->background.green];
- back.blue = png_ptr->gamma_table[png_ptr->background.blue];
-
- back_1.red = png_ptr->gamma_to_1[png_ptr->background.red];
- back_1.green = png_ptr->gamma_to_1[png_ptr->background.green];
- back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue];
- }
- else
- {
- double g, gs;
-
- switch (png_ptr->background_gamma_type)
- {
- case PNG_BACKGROUND_GAMMA_SCREEN:
- g = (png_ptr->screen_gamma);
- gs = 1.0;
- break;
- case PNG_BACKGROUND_GAMMA_FILE:
- g = 1.0 / (png_ptr->gamma);
- gs = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
- break;
- case PNG_BACKGROUND_GAMMA_UNIQUE:
- g = 1.0 / (png_ptr->background_gamma);
- gs = 1.0 / (png_ptr->background_gamma *
- png_ptr->screen_gamma);
- break;
- default:
- g = 1.0; /* back_1 */
- gs = 1.0; /* back */
- }
-
- if ( fabs(gs - 1.0) < PNG_GAMMA_THRESHOLD)
- {
- back.red = (png_byte)png_ptr->background.red;
- back.green = (png_byte)png_ptr->background.green;
- back.blue = (png_byte)png_ptr->background.blue;
- }
- else
- {
- back.red = (png_byte)(pow(
- (double)png_ptr->background.red/255, gs) * 255.0 + .5);
- back.green = (png_byte)(pow(
- (double)png_ptr->background.green/255, gs) * 255.0 + .5);
- back.blue = (png_byte)(pow(
- (double)png_ptr->background.blue/255, gs) * 255.0 + .5);
- }
-
- back_1.red = (png_byte)(pow(
- (double)png_ptr->background.red/255, g) * 255.0 + .5);
- back_1.green = (png_byte)(pow(
- (double)png_ptr->background.green/255, g) * 255.0 + .5);
- back_1.blue = (png_byte)(pow(
- (double)png_ptr->background.blue/255, g) * 255.0 + .5);
- }
- for (i = 0; i < num_palette; i++)
- {
- if (i < (int)png_ptr->num_trans && png_ptr->trans[i] != 0xff)
- {
- if (png_ptr->trans[i] == 0)
- {
- palette[i] = back;
- }
- else /* if (png_ptr->trans[i] != 0xff) */
- {
- png_byte v, w;
-
- v = png_ptr->gamma_to_1[palette[i].red];
- png_composite(w, v, png_ptr->trans[i], back_1.red);
- palette[i].red = png_ptr->gamma_from_1[w];
-
- v = png_ptr->gamma_to_1[palette[i].green];
- png_composite(w, v, png_ptr->trans[i], back_1.green);
- palette[i].green = png_ptr->gamma_from_1[w];
-
- v = png_ptr->gamma_to_1[palette[i].blue];
- png_composite(w, v, png_ptr->trans[i], back_1.blue);
- palette[i].blue = png_ptr->gamma_from_1[w];
- }
- }
- else
- {
- palette[i].red = png_ptr->gamma_table[palette[i].red];
- palette[i].green = png_ptr->gamma_table[palette[i].green];
- palette[i].blue = png_ptr->gamma_table[palette[i].blue];
- }
- }
- }
- /* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN) */
- else
- /* color_type != PNG_COLOR_TYPE_PALETTE */
- {
- double m = (double)(((png_uint_32)1 << png_ptr->bit_depth) - 1);
- double g = 1.0;
- double gs = 1.0;
-
- switch (png_ptr->background_gamma_type)
- {
- case PNG_BACKGROUND_GAMMA_SCREEN:
- g = (png_ptr->screen_gamma);
- gs = 1.0;
- break;
- case PNG_BACKGROUND_GAMMA_FILE:
- g = 1.0 / (png_ptr->gamma);
- gs = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
- break;
- case PNG_BACKGROUND_GAMMA_UNIQUE:
- g = 1.0 / (png_ptr->background_gamma);
- gs = 1.0 / (png_ptr->background_gamma *
- png_ptr->screen_gamma);
- break;
- }
-
- png_ptr->background_1.gray = (png_uint_16)(pow(
- (double)png_ptr->background.gray / m, g) * m + .5);
- png_ptr->background.gray = (png_uint_16)(pow(
- (double)png_ptr->background.gray / m, gs) * m + .5);
-
- if ((png_ptr->background.red != png_ptr->background.green) ||
- (png_ptr->background.red != png_ptr->background.blue) ||
- (png_ptr->background.red != png_ptr->background.gray))
- {
- /* RGB or RGBA with color background */
- png_ptr->background_1.red = (png_uint_16)(pow(
- (double)png_ptr->background.red / m, g) * m + .5);
- png_ptr->background_1.green = (png_uint_16)(pow(
- (double)png_ptr->background.green / m, g) * m + .5);
- png_ptr->background_1.blue = (png_uint_16)(pow(
- (double)png_ptr->background.blue / m, g) * m + .5);
- png_ptr->background.red = (png_uint_16)(pow(
- (double)png_ptr->background.red / m, gs) * m + .5);
- png_ptr->background.green = (png_uint_16)(pow(
- (double)png_ptr->background.green / m, gs) * m + .5);
- png_ptr->background.blue = (png_uint_16)(pow(
- (double)png_ptr->background.blue / m, gs) * m + .5);
- }
- else
- {
- /* GRAY, GRAY ALPHA, RGB, or RGBA with gray background */
- png_ptr->background_1.red = png_ptr->background_1.green
- = png_ptr->background_1.blue = png_ptr->background_1.gray;
- png_ptr->background.red = png_ptr->background.green
- = png_ptr->background.blue = png_ptr->background.gray;
- }
- }
- }
- else
- /* transformation does not include PNG_BACKGROUND */
- #endif /* PNG_READ_BACKGROUND_SUPPORTED */
- if (color_type == PNG_COLOR_TYPE_PALETTE)
- {
- png_colorp palette = png_ptr->palette;
- int num_palette = png_ptr->num_palette;
- int i;
-
- for (i = 0; i < num_palette; i++)
- {
- palette[i].red = png_ptr->gamma_table[palette[i].red];
- palette[i].green = png_ptr->gamma_table[palette[i].green];
- palette[i].blue = png_ptr->gamma_table[palette[i].blue];
- }
- }
- }
- #if defined(PNG_READ_BACKGROUND_SUPPORTED)
- else
- #endif
- #endif /* PNG_READ_GAMMA_SUPPORTED && PNG_FLOATING_POINT_SUPPORTED */
- #if defined(PNG_READ_BACKGROUND_SUPPORTED)
- /* No GAMMA transformation */
- if ((png_ptr->transformations & PNG_BACKGROUND) &&
- (color_type == PNG_COLOR_TYPE_PALETTE))
- {
- int i;
- int istop = (int)png_ptr->num_trans;
- png_color back;
- png_colorp palette = png_ptr->palette;
-
- back.red = (png_byte)png_ptr->background.red;
- back.green = (png_byte)png_ptr->background.green;
- back.blue = (png_byte)png_ptr->background.blue;
-
- for (i = 0; i < istop; i++)
- {
- if (png_ptr->trans[i] == 0)
- {
- palette[i] = back;
- }
- else if (png_ptr->trans[i] != 0xff)
- {
- /* The png_composite() macro is defined in png.h */
- png_composite(palette[i].red, palette[i].red,
- png_ptr->trans[i], back.red);
- png_composite(palette[i].green, palette[i].green,
- png_ptr->trans[i], back.green);
- png_composite(palette[i].blue, palette[i].blue,
- png_ptr->trans[i], back.blue);
- }
- }
- }
- #endif /* PNG_READ_BACKGROUND_SUPPORTED */
-
- #if defined(PNG_READ_SHIFT_SUPPORTED)
- if ((png_ptr->transformations & PNG_SHIFT) &&
- (color_type == PNG_COLOR_TYPE_PALETTE))
- {
- png_uint_16 i;
- png_uint_16 istop = png_ptr->num_palette;
- int sr = 8 - png_ptr->sig_bit.red;
- int sg = 8 - png_ptr->sig_bit.green;
- int sb = 8 - png_ptr->sig_bit.blue;
-
- if (sr < 0 || sr > 8)
- sr = 0;
- if (sg < 0 || sg > 8)
- sg = 0;
- if (sb < 0 || sb > 8)
- sb = 0;
- for (i = 0; i < istop; i++)
- {
- png_ptr->palette[i].red >>= sr;
- png_ptr->palette[i].green >>= sg;
- png_ptr->palette[i].blue >>= sb;
- }
- }
- #endif /* PNG_READ_SHIFT_SUPPORTED */
- }
- #if !defined(PNG_READ_GAMMA_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED) \
- && !defined(PNG_READ_BACKGROUND_SUPPORTED)
- if(png_ptr)
- return;
- #endif
- }
-
- /* Modify the info structure to reflect the transformations. The
- * info should be updated so a PNG file could be written with it,
- * assuming the transformations result in valid PNG data.
- */
- void /* PRIVATE */
- png_read_transform_info(png_structp png_ptr, png_infop info_ptr)
- {
- png_debug(1, "in png_read_transform_info\n");
- #if defined(PNG_READ_EXPAND_SUPPORTED)
- if (png_ptr->transformations & PNG_EXPAND)
- {
- if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
- {
- if (png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND_tRNS))
- info_ptr->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
- else
- info_ptr->color_type = PNG_COLOR_TYPE_RGB;
- info_ptr->bit_depth = 8;
- info_ptr->num_trans = 0;
- }
- else
- {
- if (png_ptr->num_trans)
- {
- if (png_ptr->transformations & PNG_EXPAND_tRNS)
- info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
- else
- info_ptr->color_type |= PNG_COLOR_MASK_COLOR;
- }
- if (info_ptr->bit_depth < 8)
- info_ptr->bit_depth = 8;
- info_ptr->num_trans = 0;
- }
- }
- #endif
-
- #if defined(PNG_READ_BACKGROUND_SUPPORTED)
- if (png_ptr->transformations & PNG_BACKGROUND)
- {
- info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA;
- info_ptr->num_trans = 0;
- info_ptr->background = png_ptr->background;
- }
- #endif
-
- #if defined(PNG_READ_GAMMA_SUPPORTED)
- if (png_ptr->transformations & PNG_GAMMA)
- {
- #ifdef PNG_FLOATING_POINT_SUPPORTED
- info_ptr->gamma = png_ptr->gamma;
- #endif
- #ifdef PNG_FIXED_POINT_SUPPORTED
- info_ptr->int_gamma = png_ptr->int_gamma;
- #endif
- }
- #endif
-
- #if defined(PNG_READ_16_TO_8_SUPPORTED)
- if ((png_ptr->transformations & PNG_16_TO_8) && (info_ptr->bit_depth == 16))
- info_ptr->bit_depth = 8;
- #endif
-
- #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
- if (png_ptr->transformations & PNG_GRAY_TO_RGB)
- info_ptr->color_type |= PNG_COLOR_MASK_COLOR;
- #endif
-
- #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
- if (png_ptr->transformations & PNG_RGB_TO_GRAY)
- info_ptr->color_type &= ~PNG_COLOR_MASK_COLOR;
- #endif
-
- #if defined(PNG_READ_DITHER_SUPPORTED)
- if (png_ptr->transformations & PNG_DITHER)
- {
- if (((info_ptr->color_type == PNG_COLOR_TYPE_RGB) ||
- (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)) &&
- png_ptr->palette_lookup && info_ptr->bit_depth == 8)
- {
- info_ptr->color_type = PNG_COLOR_TYPE_PALETTE;
- }
- }
- #endif
-
- #if defined(PNG_READ_PACK_SUPPORTED)
- if ((png_ptr->transformations & PNG_PACK) && (info_ptr->bit_depth < 8))
- info_ptr->bit_depth = 8;
- #endif
-
- if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
- info_ptr->channels = 1;
- else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR)
- info_ptr->channels = 3;
- else
- info_ptr->channels = 1;
-
- #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
- if (png_ptr->flags & PNG_FLAG_STRIP_ALPHA)
- info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA;
- #endif
-
- if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA)
- info_ptr->channels++;
-
- #if defined(PNG_READ_FILLER_SUPPORTED)
- /* STRIP_ALPHA and FILLER allowed: MASK_ALPHA bit stripped above */
- if ((png_ptr->transformations & PNG_FILLER) &&
- ((info_ptr->color_type == PNG_COLOR_TYPE_RGB) ||
- (info_ptr->color_type == PNG_COLOR_TYPE_GRAY)))
- {
- info_ptr->channels++;
- /* if adding a true alpha channel not just filler */
- #if !defined(PNG_1_0_X)
- if (png_ptr->transformations & PNG_ADD_ALPHA)
- info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
- #endif
- }
- #endif
-
- #if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) && \
- defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
- if(png_ptr->transformations & PNG_USER_TRANSFORM)
- {
- if(info_ptr->bit_depth < png_ptr->user_transform_depth)
- info_ptr->bit_depth = png_ptr->user_transform_depth;
- if(info_ptr->channels < png_ptr->user_transform_channels)
- info_ptr->channels = png_ptr->user_transform_channels;
- }
- #endif
-
- info_ptr->pixel_depth = (png_byte)(info_ptr->channels *
- info_ptr->bit_depth);
-
- info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth,info_ptr->width);
-
- #if !defined(PNG_READ_EXPAND_SUPPORTED)
- if(png_ptr)
- return;
- #endif
- }
-
- /* Transform the row. The order of transformations is significant,
- * and is very touchy. If you add a transformation, take care to
- * decide how it fits in with the other transformations here.
- */
- void /* PRIVATE */
- png_do_read_transformations(png_structp png_ptr)
- {
- png_debug(1, "in png_do_read_transformations\n");
- if (png_ptr->row_buf == NULL)
- {
- #if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
- char msg[50];
-
- png_snprintf2(msg, 50,
- "NULL row buffer for row %ld, pass %d", png_ptr->row_number,
- png_ptr->pass);
- png_error(png_ptr, msg);
- #else
- png_error(png_ptr, "NULL row buffer");
- #endif
- }
- #ifdef PNG_WARN_UNINITIALIZED_ROW
- if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
- /* Application has failed to call either png_read_start_image()
- * or png_read_update_info() after setting transforms that expand
- * pixels. This check added to libpng-1.2.19 */
- #if (PNG_WARN_UNINITIALIZED_ROW==1)
- png_error(png_ptr, "Uninitialized row");
- #else
- png_warning(png_ptr, "Uninitialized row");
- #endif
- #endif
-
- #if defined(PNG_READ_EXPAND_SUPPORTED)
- if (png_ptr->transformations & PNG_EXPAND)
- {
- if (png_ptr->row_info.color_type == PNG_COLOR_TYPE_PALETTE)
- {
- png_do_expand_palette(&(png_ptr->row_info), png_ptr->row_buf + 1,
- png_ptr->palette, png_ptr->trans, png_ptr->num_trans);
- }
- else
- {
- if (png_ptr->num_trans &&
- (png_ptr->transformations & PNG_EXPAND_tRNS))
- png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1,
- &(png_ptr->trans_values));
- else
- png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1,
- NULL);
- }
- }
- #endif
-
- #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
- if (png_ptr->flags & PNG_FLAG_STRIP_ALPHA)
- png_do_strip_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
- PNG_FLAG_FILLER_AFTER | (png_ptr->flags & PNG_FLAG_STRIP_ALPHA));
- #endif
-
- #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
- if (png_ptr->transformations & PNG_RGB_TO_GRAY)
- {
- int rgb_error =
- png_do_rgb_to_gray(png_ptr, &(png_ptr->row_info), png_ptr->row_buf + 1);
- if(rgb_error)
- {
- png_ptr->rgb_to_gray_status=1;
- if((png_ptr->transformations & PNG_RGB_TO_GRAY) ==
- PNG_RGB_TO_GRAY_WARN)
- png_warning(png_ptr, "png_do_rgb_to_gray found nongray pixel");
- if((png_ptr->transformations & PNG_RGB_TO_GRAY) ==
- PNG_RGB_TO_GRAY_ERR)
- png_error(png_ptr, "png_do_rgb_to_gray found nongray pixel");
- }
- }
- #endif
-
- /*
- From Andreas Dilger e-mail to png-implement, 26 March 1998:
-
- In most cases, the "simple transparency" should be done prior to doing
- gray-to-RGB, or you will have to test 3x as many bytes to check if a
- pixel is transparent. You would also need to make sure that the
- transparency information is upgraded to RGB.
-
- To summarize, the current flow is:
- - Gray + simple transparency -> compare 1 or 2 gray bytes and composite
- with background "in place" if transparent,
- convert to RGB if necessary
- - Gray + alpha -> composite with gray background and remove alpha bytes,
- convert to RGB if necessary
-
- To support RGB backgrounds for gray images we need:
- - Gray + simple transparency -> convert to RGB + simple transparency, compare
- 3 or 6 bytes and composite with background
- "in place" if transparent (3x compare/pixel
- compared to doing composite with gray bkgrnd)
- - Gray + alpha -> convert to RGB + alpha, composite with background and
- remove alpha bytes (3x float operations/pixel
- compared with composite on gray background)
-
- Greg's change will do this. The reason it wasn't done before is for
- performance, as this increases the per-pixel operations. If we would check
- in advance if the background was gray or RGB, and position the gray-to-RGB
- transform appropriately, then it would save a lot of work/time.
- */
-
- #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
- /* if gray -> RGB, do so now only if background is non-gray; else do later
- * for performance reasons */
- if ((png_ptr->transformations & PNG_GRAY_TO_RGB) &&
- !(png_ptr->mode & PNG_BACKGROUND_IS_GRAY))
- png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1);
- #endif
-
- #if defined(PNG_READ_BACKGROUND_SUPPORTED)
- if ((png_ptr->transformations & PNG_BACKGROUND) &&
- ((png_ptr->num_trans != 0 ) ||
- (png_ptr->color_type & PNG_COLOR_MASK_ALPHA)))
- png_do_background(&(png_ptr->row_info), png_ptr->row_buf + 1,
- &(png_ptr->trans_values), &(png_ptr->background)
- #if defined(PNG_READ_GAMMA_SUPPORTED)
- , &(png_ptr->background_1),
- png_ptr->gamma_table, png_ptr->gamma_from_1,
- png_ptr->gamma_to_1, png_ptr->gamma_16_table,
- png_ptr->gamma_16_from_1, png_ptr->gamma_16_to_1,
- png_ptr->gamma_shift
- #endif
- );
- #endif
-
- #if defined(PNG_READ_GAMMA_SUPPORTED)
- if ((png_ptr->transformations & PNG_GAMMA) &&
- #if defined(PNG_READ_BACKGROUND_SUPPORTED)
- !((png_ptr->transformations & PNG_BACKGROUND) &&
- ((png_ptr->num_trans != 0) ||
- (png_ptr->color_type & PNG_COLOR_MASK_ALPHA))) &&
- #endif
- (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE))
- png_do_gamma(&(png_ptr->row_info), png_ptr->row_buf + 1,
- png_ptr->gamma_table, png_ptr->gamma_16_table,
- png_ptr->gamma_shift);
- #endif
-
- #if defined(PNG_READ_16_TO_8_SUPPORTED)
- if (png_ptr->transformations & PNG_16_TO_8)
- png_do_chop(&(png_ptr->row_info), png_ptr->row_buf + 1);
- #endif
-
- #if defined(PNG_READ_DITHER_SUPPORTED)
- if (png_ptr->transformations & PNG_DITHER)
- {
- png_do_dither((png_row_infop)&(png_ptr->row_info), png_ptr->row_buf + 1,
- png_ptr->palette_lookup, png_ptr->dither_index);
- if(png_ptr->row_info.rowbytes == (png_uint_32)0)
- png_error(png_ptr, "png_do_dither returned rowbytes=0");
- }
- #endif
-
- #if defined(PNG_READ_INVERT_SUPPORTED)
- if (png_ptr->transformations & PNG_INVERT_MONO)
- png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1);
- #endif
-
- #if defined(PNG_READ_SHIFT_SUPPORTED)
- if (png_ptr->transformations & PNG_SHIFT)
- png_do_unshift(&(png_ptr->row_info), png_ptr->row_buf + 1,
- &(png_ptr->shift));
- #endif
-
- #if defined(PNG_READ_PACK_SUPPORTED)
- if (png_ptr->transformations & PNG_PACK)
- png_do_unpack(&(png_ptr->row_info), png_ptr->row_buf + 1);
- #endif
-
- #if defined(PNG_READ_BGR_SUPPORTED)
- if (png_ptr->transformations & PNG_BGR)
- png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1);
- #endif
-
- #if defined(PNG_READ_PACKSWAP_SUPPORTED)
- if (png_ptr->transformations & PNG_PACKSWAP)
- png_do_packswap(&(png_ptr->row_info), png_ptr->row_buf + 1);
- #endif
-
- #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
- /* if gray -> RGB, do so now only if we did not do so above */
- if ((png_ptr->transformations & PNG_GRAY_TO_RGB) &&
- (png_ptr->mode & PNG_BACKGROUND_IS_GRAY))
- png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1);
- #endif
-
- #if defined(PNG_READ_FILLER_SUPPORTED)
- if (png_ptr->transformations & PNG_FILLER)
- png_do_read_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
- (png_uint_32)png_ptr->filler, png_ptr->flags);
- #endif
-
- #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
- if (png_ptr->transformations & PNG_INVERT_ALPHA)
- png_do_read_invert_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
- #endif
-
- #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
- if (png_ptr->transformations & PNG_SWAP_ALPHA)
- png_do_read_swap_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
- #endif
-
- #if defined(PNG_READ_SWAP_SUPPORTED)
- if (png_ptr->transformations & PNG_SWAP_BYTES)
- png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1);
- #endif
-
- #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
- if (png_ptr->transformations & PNG_USER_TRANSFORM)
- {
- if(png_ptr->read_user_transform_fn != NULL)
- (*(png_ptr->read_user_transform_fn)) /* user read transform function */
- (png_ptr, /* png_ptr */
- &(png_ptr->row_info), /* row_info: */
- /* png_uint_32 width; width of row */
- /* png_uint_32 rowbytes; number of bytes in row */
- /* png_byte color_type; color type of pixels */
- /* png_byte bit_depth; bit depth of samples */
- /* png_byte channels; number of channels (1-4) */
- /* png_byte pixel_depth; bits per pixel (depth*channels) */
- png_ptr->row_buf + 1); /* start of pixel data for row */
- #if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
- if(png_ptr->user_transform_depth)
- png_ptr->row_info.bit_depth = png_ptr->user_transform_depth;
- if(png_ptr->user_transform_channels)
- png_ptr->row_info.channels = png_ptr->user_transform_channels;
- #endif
- png_ptr->row_info.pixel_depth = (png_byte)(png_ptr->row_info.bit_depth *
- png_ptr->row_info.channels);
- png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth,
- png_ptr->row_info.width);
- }
- #endif
-
- }
-
- #if defined(PNG_READ_PACK_SUPPORTED)
- /* Unpack pixels of 1, 2, or 4 bits per pixel into 1 byte per pixel,
- * without changing the actual values. Thus, if you had a row with
- * a bit depth of 1, you would end up with bytes that only contained
- * the numbers 0 or 1. If you would rather they contain 0 and 255, use
- * png_do_shift() after this.
- */
- void /* PRIVATE */
- png_do_unpack(png_row_infop row_info, png_bytep row)
- {
- png_debug(1, "in png_do_unpack\n");
- #if defined(PNG_USELESS_TESTS_SUPPORTED)
- if (row != NULL && row_info != NULL && row_info->bit_depth < 8)
- #else
- if (row_info->bit_depth < 8)
- #endif
- {
- png_uint_32 i;
- png_uint_32 row_width=row_info->width;
-
- switch (row_info->bit_depth)
- {
- case 1:
- {
- png_bytep sp = row + (png_size_t)((row_width - 1) >> 3);
- png_bytep dp = row + (png_size_t)row_width - 1;
- png_uint_32 shift = 7 - (int)((row_width + 7) & 0x07);
- for (i = 0; i < row_width; i++)
- {
- *dp = (png_byte)((*sp >> shift) & 0x01);
- if (shift == 7)
- {
- shift = 0;
- sp--;
- }
- else
- shift++;
-
- dp--;
- }
- break;
- }
- case 2:
- {
-
- png_bytep sp = row + (png_size_t)((row_width - 1) >> 2);
- png_bytep dp = row + (png_size_t)row_width - 1;
- png_uint_32 shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
- for (i = 0; i < row_width; i++)
- {
- *dp = (png_byte)((*sp >> shift) & 0x03);
- if (shift == 6)
- {
- shift = 0;
- sp--;
- }
- else
- shift += 2;
-
- dp--;
- }
- break;
- }
- case 4:
- {
- png_bytep sp = row + (png_size_t)((row_width - 1) >> 1);
- png_bytep dp = row + (png_size_t)row_width - 1;
- png_uint_32 shift = (int)((1 - ((row_width + 1) & 0x01)) << 2);
- for (i = 0; i < row_width; i++)
- {
- *dp = (png_byte)((*sp >> shift) & 0x0f);
- if (shift == 4)
- {
- shift = 0;
- sp--;
- }
- else
- shift = 4;
-
- dp--;
- }
- break;
- }
- }
- row_info->bit_depth = 8;
- row_info->pixel_depth = (png_byte)(8 * row_info->channels);
- row_info->rowbytes = row_width * row_info->channels;
- }
- }
- #endif
-
- #if defined(PNG_READ_SHIFT_SUPPORTED)
- /* Reverse the effects of png_do_shift. This routine merely shifts the
- * pixels back to their significant bits values. Thus, if you have
- * a row of bit depth 8, but only 5 are significant, this will shift
- * the values back to 0 through 31.
- */
- void /* PRIVATE */
- png_do_unshift(png_row_infop row_info, png_bytep row, png_color_8p sig_bits)
- {
- png_debug(1, "in png_do_unshift\n");
- if (
- #if defined(PNG_USELESS_TESTS_SUPPORTED)
- row != NULL && row_info != NULL && sig_bits != NULL &&
- #endif
- row_info->color_type != PNG_COLOR_TYPE_PALETTE)
- {
- int shift[4];
- int channels = 0;
- int c;
- png_uint_16 value = 0;
- png_uint_32 row_width = row_info->width;
-
- if (row_info->color_type & PNG_COLOR_MASK_COLOR)
- {
- shift[channels++] = row_info->bit_depth - sig_bits->red;
- shift[channels++] = row_info->bit_depth - sig_bits->green;
- shift[channels++] = row_info->bit_depth - sig_bits->blue;
- }
- else
- {
- shift[channels++] = row_info->bit_depth - sig_bits->gray;
- }
- if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
- {
- shift[channels++] = row_info->bit_depth - sig_bits->alpha;
- }
-
- for (c = 0; c < channels; c++)
- {
- if (shift[c] <= 0)
- shift[c] = 0;
- else
- value = 1;
- }
-
- if (!value)
- return;
-
- switch (row_info->bit_depth)
- {
- case 2:
- {
- png_bytep bp;
- png_uint_32 i;
- png_uint_32 istop = row_info->rowbytes;
-
- for (bp = row, i = 0; i < istop; i++)
- {
- *bp >>= 1;
- *bp++ &= 0x55;
- }
- break;
- }
- case 4:
- {
- png_bytep bp = row;
- png_uint_32 i;
- png_uint_32 istop = row_info->rowbytes;
- png_byte mask = (png_byte)((((int)0xf0 >> shift[0]) & (int)0xf0) |
- (png_byte)((int)0xf >> shift[0]));
-
- for (i = 0; i < istop; i++)
- {
- *bp >>= shift[0];
- *bp++ &= mask;
- }
- break;
- }
- case 8:
- {
- png_bytep bp = row;
- png_uint_32 i;
- png_uint_32 istop = row_width * channels;
-
- for (i = 0; i < istop; i++)
- {
- *bp++ >>= shift[i%channels];
- }
- break;
- }
- case 16:
- {
- png_bytep bp = row;
- png_uint_32 i;
- png_uint_32 istop = channels * row_width;
-
- for (i = 0; i < istop; i++)
- {
- value = (png_uint_16)((*bp << 8) + *(bp + 1));
- value >>= shift[i%channels];
- *bp++ = (png_byte)(value >> 8);
- *bp++ = (png_byte)(value & 0xff);
- }
- break;
- }
- }
- }
- }
- #endif
-
- #if defined(PNG_READ_16_TO_8_SUPPORTED)
- /* chop rows of bit depth 16 down to 8 */
- void /* PRIVATE */
- png_do_chop(png_row_infop row_info, png_bytep row)
- {
- png_debug(1, "in png_do_chop\n");
- #if defined(PNG_USELESS_TESTS_SUPPORTED)
- if (row != NULL && row_info != NULL && row_info->bit_depth == 16)
- #else
- if (row_info->bit_depth == 16)
- #endif
- {
- png_bytep sp = row;
- png_bytep dp = row;
- png_uint_32 i;
- png_uint_32 istop = row_info->width * row_info->channels;
-
- for (i = 0; i<istop; i++, sp += 2, dp++)
- {
- #if defined(PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED)
- /* This does a more accurate scaling of the 16-bit color
- * value, rather than a simple low-byte truncation.
- *
- * What the ideal calculation should be:
- * *dp = (((((png_uint_32)(*sp) << 8) |
- * (png_uint_32)(*(sp + 1))) * 255 + 127) / (png_uint_32)65535L;
- *
- * GRR: no, I think this is what it really should be:
- * *dp = (((((png_uint_32)(*sp) << 8) |
- * (png_uint_32)(*(sp + 1))) + 128L) / (png_uint_32)257L;
- *
- * GRR: here's the exact calculation with shifts:
- * temp = (((png_uint_32)(*sp) << 8) | (png_uint_32)(*(sp + 1))) + 128L;
- * *dp = (temp - (temp >> 8)) >> 8;
- *
- * Approximate calculation with shift/add instead of multiply/divide:
- * *dp = ((((png_uint_32)(*sp) << 8) |
- * (png_uint_32)((int)(*(sp + 1)) - *sp)) + 128) >> 8;
- *
- * What we actually do to avoid extra shifting and conversion:
- */
-
- *dp = *sp + ((((int)(*(sp + 1)) - *sp) > 128) ? 1 : 0);
- #else
- /* Simply discard the low order byte */
- *dp = *sp;
- #endif
- }
- row_info->bit_depth = 8;
- row_info->pixel_depth = (png_byte)(8 * row_info->channels);
- row_info->rowbytes = row_info->width * row_info->channels;
- }
- }
- #endif
-
- #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
- void /* PRIVATE */
- png_do_read_swap_alpha(png_row_infop row_info, png_bytep row)
- {
- png_debug(1, "in png_do_read_swap_alpha\n");
- #if defined(PNG_USELESS_TESTS_SUPPORTED)
- if (row != NULL && row_info != NULL)
- #endif
- {
- png_uint_32 row_width = row_info->width;
- if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
- {
- /* This converts from RGBA to ARGB */
- if (row_info->bit_depth == 8)
- {
- png_bytep sp = row + row_info->rowbytes;
- png_bytep dp = sp;
- png_byte save;
- png_uint_32 i;
-
- for (i = 0; i < row_width; i++)
- {
- save = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = save;
- }
- }
- /* This converts from RRGGBBAA to AARRGGBB */
- else
- {
- png_bytep sp = row + row_info->rowbytes;
- png_bytep dp = sp;
- png_byte save[2];
- png_uint_32 i;
-
- for (i = 0; i < row_width; i++)
- {
- save[0] = *(--sp);
- save[1] = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = save[0];
- *(--dp) = save[1];
- }
- }
- }
- else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
- {
- /* This converts from GA to AG */
- if (row_info->bit_depth == 8)
- {
- png_bytep sp = row + row_info->rowbytes;
- png_bytep dp = sp;
- png_byte save;
- png_uint_32 i;
-
- for (i = 0; i < row_width; i++)
- {
- save = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = save;
- }
- }
- /* This converts from GGAA to AAGG */
- else
- {
- png_bytep sp = row + row_info->rowbytes;
- png_bytep dp = sp;
- png_byte save[2];
- png_uint_32 i;
-
- for (i = 0; i < row_width; i++)
- {
- save[0] = *(--sp);
- save[1] = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = save[0];
- *(--dp) = save[1];
- }
- }
- }
- }
- }
- #endif
-
- #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
- void /* PRIVATE */
- png_do_read_invert_alpha(png_row_infop row_info, png_bytep row)
- {
- png_debug(1, "in png_do_read_invert_alpha\n");
- #if defined(PNG_USELESS_TESTS_SUPPORTED)
- if (row != NULL && row_info != NULL)
- #endif
- {
- png_uint_32 row_width = row_info->width;
- if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
- {
- /* This inverts the alpha channel in RGBA */
- if (row_info->bit_depth == 8)
- {
- png_bytep sp = row + row_info->rowbytes;
- png_bytep dp = sp;
- png_uint_32 i;
-
- for (i = 0; i < row_width; i++)
- {
- *(--dp) = (png_byte)(255 - *(--sp));
-
- /* This does nothing:
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- We can replace it with:
- */
- sp-=3;
- dp=sp;
- }
- }
- /* This inverts the alpha channel in RRGGBBAA */
- else
- {
- png_bytep sp = row + row_info->rowbytes;
- png_bytep dp = sp;
- png_uint_32 i;
-
- for (i = 0; i < row_width; i++)
- {
- *(--dp) = (png_byte)(255 - *(--sp));
- *(--dp) = (png_byte)(255 - *(--sp));
-
- /* This does nothing:
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- We can replace it with:
- */
- sp-=6;
- dp=sp;
- }
- }
- }
- else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
- {
- /* This inverts the alpha channel in GA */
- if (row_info->bit_depth == 8)
- {
- png_bytep sp = row + row_info->rowbytes;
- png_bytep dp = sp;
- png_uint_32 i;
-
- for (i = 0; i < row_width; i++)
- {
- *(--dp) = (png_byte)(255 - *(--sp));
- *(--dp) = *(--sp);
- }
- }
- /* This inverts the alpha channel in GGAA */
- else
- {
- png_bytep sp = row + row_info->rowbytes;
- png_bytep dp = sp;
- png_uint_32 i;
-
- for (i = 0; i < row_width; i++)
- {
- *(--dp) = (png_byte)(255 - *(--sp));
- *(--dp) = (png_byte)(255 - *(--sp));
- /*
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- */
- sp-=2;
- dp=sp;
- }
- }
- }
- }
- }
- #endif
-
- #if defined(PNG_READ_FILLER_SUPPORTED)
- /* Add filler channel if we have RGB color */
- void /* PRIVATE */
- png_do_read_filler(png_row_infop row_info, png_bytep row,
- png_uint_32 filler, png_uint_32 flags)
- {
- png_uint_32 i;
- png_uint_32 row_width = row_info->width;
-
- png_byte hi_filler = (png_byte)((filler>>8) & 0xff);
- png_byte lo_filler = (png_byte)(filler & 0xff);
-
- png_debug(1, "in png_do_read_filler\n");
- if (
- #if defined(PNG_USELESS_TESTS_SUPPORTED)
- row != NULL && row_info != NULL &&
- #endif
- row_info->color_type == PNG_COLOR_TYPE_GRAY)
- {
- if(row_info->bit_depth == 8)
- {
- /* This changes the data from G to GX */
- if (flags & PNG_FLAG_FILLER_AFTER)
- {
- png_bytep sp = row + (png_size_t)row_width;
- png_bytep dp = sp + (png_size_t)row_width;
- for (i = 1; i < row_width; i++)
- {
- *(--dp) = lo_filler;
- *(--dp) = *(--sp);
- }
- *(--dp) = lo_filler;
- row_info->channels = 2;
- row_info->pixel_depth = 16;
- row_info->rowbytes = row_width * 2;
- }
- /* This changes the data from G to XG */
- else
- {
- png_bytep sp = row + (png_size_t)row_width;
- png_bytep dp = sp + (png_size_t)row_width;
- for (i = 0; i < row_width; i++)
- {
- *(--dp) = *(--sp);
- *(--dp) = lo_filler;
- }
- row_info->channels = 2;
- row_info->pixel_depth = 16;
- row_info->rowbytes = row_width * 2;
- }
- }
- else if(row_info->bit_depth == 16)
- {
- /* This changes the data from GG to GGXX */
- if (flags & PNG_FLAG_FILLER_AFTER)
- {
- png_bytep sp = row + (png_size_t)row_width * 2;
- png_bytep dp = sp + (png_size_t)row_width * 2;
- for (i = 1; i < row_width; i++)
- {
- *(--dp) = hi_filler;
- *(--dp) = lo_filler;
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- }
- *(--dp) = hi_filler;
- *(--dp) = lo_filler;
- row_info->channels = 2;
- row_info->pixel_depth = 32;
- row_info->rowbytes = row_width * 4;
- }
- /* This changes the data from GG to XXGG */
- else
- {
- png_bytep sp = row + (png_size_t)row_width * 2;
- png_bytep dp = sp + (png_size_t)row_width * 2;
- for (i = 0; i < row_width; i++)
- {
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = hi_filler;
- *(--dp) = lo_filler;
- }
- row_info->channels = 2;
- row_info->pixel_depth = 32;
- row_info->rowbytes = row_width * 4;
- }
- }
- } /* COLOR_TYPE == GRAY */
- else if (row_info->color_type == PNG_COLOR_TYPE_RGB)
- {
- if(row_info->bit_depth == 8)
- {
- /* This changes the data from RGB to RGBX */
- if (flags & PNG_FLAG_FILLER_AFTER)
- {
- png_bytep sp = row + (png_size_t)row_width * 3;
- png_bytep dp = sp + (png_size_t)row_width;
- for (i = 1; i < row_width; i++)
- {
- *(--dp) = lo_filler;
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- }
- *(--dp) = lo_filler;
- row_info->channels = 4;
- row_info->pixel_depth = 32;
- row_info->rowbytes = row_width * 4;
- }
- /* This changes the data from RGB to XRGB */
- else
- {
- png_bytep sp = row + (png_size_t)row_width * 3;
- png_bytep dp = sp + (png_size_t)row_width;
- for (i = 0; i < row_width; i++)
- {
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = lo_filler;
- }
- row_info->channels = 4;
- row_info->pixel_depth = 32;
- row_info->rowbytes = row_width * 4;
- }
- }
- else if(row_info->bit_depth == 16)
- {
- /* This changes the data from RRGGBB to RRGGBBXX */
- if (flags & PNG_FLAG_FILLER_AFTER)
- {
- png_bytep sp = row + (png_size_t)row_width * 6;
- png_bytep dp = sp + (png_size_t)row_width * 2;
- for (i = 1; i < row_width; i++)
- {
- *(--dp) = hi_filler;
- *(--dp) = lo_filler;
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- }
- *(--dp) = hi_filler;
- *(--dp) = lo_filler;
- row_info->channels = 4;
- row_info->pixel_depth = 64;
- row_info->rowbytes = row_width * 8;
- }
- /* This changes the data from RRGGBB to XXRRGGBB */
- else
- {
- png_bytep sp = row + (png_size_t)row_width * 6;
- png_bytep dp = sp + (png_size_t)row_width * 2;
- for (i = 0; i < row_width; i++)
- {
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = hi_filler;
- *(--dp) = lo_filler;
- }
- row_info->channels = 4;
- row_info->pixel_depth = 64;
- row_info->rowbytes = row_width * 8;
- }
- }
- } /* COLOR_TYPE == RGB */
- }
- #endif
-
- #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
- /* expand grayscale files to RGB, with or without alpha */
- void /* PRIVATE */
- png_do_gray_to_rgb(png_row_infop row_info, png_bytep row)
- {
- png_uint_32 i;
- png_uint_32 row_width = row_info->width;
-
- png_debug(1, "in png_do_gray_to_rgb\n");
- if (row_info->bit_depth >= 8 &&
- #if defined(PNG_USELESS_TESTS_SUPPORTED)
- row != NULL && row_info != NULL &&
- #endif
- !(row_info->color_type & PNG_COLOR_MASK_COLOR))
- {
- if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
- {
- if (row_info->bit_depth == 8)
- {
- png_bytep sp = row + (png_size_t)row_width - 1;
- png_bytep dp = sp + (png_size_t)row_width * 2;
- for (i = 0; i < row_width; i++)
- {
- *(dp--) = *sp;
- *(dp--) = *sp;
- *(dp--) = *(sp--);
- }
- }
- else
- {
- png_bytep sp = row + (png_size_t)row_width * 2 - 1;
- png_bytep dp = sp + (png_size_t)row_width * 4;
- for (i = 0; i < row_width; i++)
- {
- *(dp--) = *sp;
- *(dp--) = *(sp - 1);
- *(dp--) = *sp;
- *(dp--) = *(sp - 1);
- *(dp--) = *(sp--);
- *(dp--) = *(sp--);
- }
- }
- }
- else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
- {
- if (row_info->bit_depth == 8)
- {
- png_bytep sp = row + (png_size_t)row_width * 2 - 1;
- png_bytep dp = sp + (png_size_t)row_width * 2;
- for (i = 0; i < row_width; i++)
- {
- *(dp--) = *(sp--);
- *(dp--) = *sp;
- *(dp--) = *sp;
- *(dp--) = *(sp--);
- }
- }
- else
- {
- png_bytep sp = row + (png_size_t)row_width * 4 - 1;
- png_bytep dp = sp + (png_size_t)row_width * 4;
- for (i = 0; i < row_width; i++)
- {
- *(dp--) = *(sp--);
- *(dp--) = *(sp--);
- *(dp--) = *sp;
- *(dp--) = *(sp - 1);
- *(dp--) = *sp;
- *(dp--) = *(sp - 1);
- *(dp--) = *(sp--);
- *(dp--) = *(sp--);
- }
- }
- }
- row_info->channels += (png_byte)2;
- row_info->color_type |= PNG_COLOR_MASK_COLOR;
- row_info->pixel_depth = (png_byte)(row_info->channels *
- row_info->bit_depth);
- row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,row_width);
- }
- }
- #endif
-
- #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
- /* reduce RGB files to grayscale, with or without alpha
- * using the equation given in Poynton's ColorFAQ at
- * <http://www.inforamp.net/~poynton/>
- * Copyright (c) 1998-01-04 Charles Poynton poynton at inforamp.net
- *
- * Y = 0.212671 * R + 0.715160 * G + 0.072169 * B
- *
- * We approximate this with
- *
- * Y = 0.21268 * R + 0.7151 * G + 0.07217 * B
- *
- * which can be expressed with integers as
- *
- * Y = (6969 * R + 23434 * G + 2365 * B)/32768
- *
- * The calculation is to be done in a linear colorspace.
- *
- * Other integer coefficents can be used via png_set_rgb_to_gray().
- */
- int /* PRIVATE */
- png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row)
-
- {
- png_uint_32 i;
-
- png_uint_32 row_width = row_info->width;
- int rgb_error = 0;
-
- png_debug(1, "in png_do_rgb_to_gray\n");
- if (
- #if defined(PNG_USELESS_TESTS_SUPPORTED)
- row != NULL && row_info != NULL &&
- #endif
- (row_info->color_type & PNG_COLOR_MASK_COLOR))
- {
- png_uint_32 rc = png_ptr->rgb_to_gray_red_coeff;
- png_uint_32 gc = png_ptr->rgb_to_gray_green_coeff;
- png_uint_32 bc = png_ptr->rgb_to_gray_blue_coeff;
-
- if (row_info->color_type == PNG_COLOR_TYPE_RGB)
- {
- if (row_info->bit_depth == 8)
- {
- #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
- if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL)
- {
- png_bytep sp = row;
- png_bytep dp = row;
-
- for (i = 0; i < row_width; i++)
- {
- png_byte red = png_ptr->gamma_to_1[*(sp++)];
- png_byte green = png_ptr->gamma_to_1[*(sp++)];
- png_byte blue = png_ptr->gamma_to_1[*(sp++)];
- if(red != green || red != blue)
- {
- rgb_error |= 1;
- *(dp++) = png_ptr->gamma_from_1[
- (rc*red+gc*green+bc*blue)>>15];
- }
- else
- *(dp++) = *(sp-1);
- }
- }
- else
- #endif
- {
- png_bytep sp = row;
- png_bytep dp = row;
- for (i = 0; i < row_width; i++)
- {
- png_byte red = *(sp++);
- png_byte green = *(sp++);
- png_byte blue = *(sp++);
- if(red != green || red != blue)
- {
- rgb_error |= 1;
- *(dp++) = (png_byte)((rc*red+gc*green+bc*blue)>>15);
- }
- else
- *(dp++) = *(sp-1);
- }
- }
- }
-
- else /* RGB bit_depth == 16 */
- {
- #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
- if (png_ptr->gamma_16_to_1 != NULL &&
- png_ptr->gamma_16_from_1 != NULL)
- {
- png_bytep sp = row;
- png_bytep dp = row;
- for (i = 0; i < row_width; i++)
- {
- png_uint_16 red, green, blue, w;
-
- red = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
- green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
- blue = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
-
- if(red == green && red == blue)
- w = red;
- else
- {
- png_uint_16 red_1 = png_ptr->gamma_16_to_1[(red&0xff) >>
- png_ptr->gamma_shift][red>>8];
- png_uint_16 green_1 = png_ptr->gamma_16_to_1[(green&0xff) >>
- png_ptr->gamma_shift][green>>8];
- png_uint_16 blue_1 = png_ptr->gamma_16_to_1[(blue&0xff) >>
- png_ptr->gamma_shift][blue>>8];
- png_uint_16 gray16 = (png_uint_16)((rc*red_1 + gc*green_1
- + bc*blue_1)>>15);
- w = png_ptr->gamma_16_from_1[(gray16&0xff) >>
- png_ptr->gamma_shift][gray16 >> 8];
- rgb_error |= 1;
- }
-
- *(dp++) = (png_byte)((w>>8) & 0xff);
- *(dp++) = (png_byte)(w & 0xff);
- }
- }
- else
- #endif
- {
- png_bytep sp = row;
- png_bytep dp = row;
- for (i = 0; i < row_width; i++)
- {
- png_uint_16 red, green, blue, gray16;
-
- red = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
- green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
- blue = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
-
- if(red != green || red != blue)
- rgb_error |= 1;
- gray16 = (png_uint_16)((rc*red + gc*green + bc*blue)>>15);
- *(dp++) = (png_byte)((gray16>>8) & 0xff);
- *(dp++) = (png_byte)(gray16 & 0xff);
- }
- }
- }
- }
- if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
- {
- if (row_info->bit_depth == 8)
- {
- #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
- if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL)
- {
- png_bytep sp = row;
- png_bytep dp = row;
- for (i = 0; i < row_width; i++)
- {
- png_byte red = png_ptr->gamma_to_1[*(sp++)];
- png_byte green = png_ptr->gamma_to_1[*(sp++)];
- png_byte blue = png_ptr->gamma_to_1[*(sp++)];
- if(red != green || red != blue)
- rgb_error |= 1;
- *(dp++) = png_ptr->gamma_from_1
- [(rc*red + gc*green + bc*blue)>>15];
- *(dp++) = *(sp++); /* alpha */
- }
- }
- else
- #endif
- {
- png_bytep sp = row;
- png_bytep dp = row;
- for (i = 0; i < row_width; i++)
- {
- png_byte red = *(sp++);
- png_byte green = *(sp++);
- png_byte blue = *(sp++);
- if(red != green || red != blue)
- rgb_error |= 1;
- *(dp++) = (png_byte)((rc*red + gc*green + bc*blue)>>15);
- *(dp++) = *(sp++); /* alpha */
- }
- }
- }
- else /* RGBA bit_depth == 16 */
- {
- #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
- if (png_ptr->gamma_16_to_1 != NULL &&
- png_ptr->gamma_16_from_1 != NULL)
- {
- png_bytep sp = row;
- png_bytep dp = row;
- for (i = 0; i < row_width; i++)
- {
- png_uint_16 red, green, blue, w;
-
- red = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
- green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
- blue = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
-
- if(red == green && red == blue)
- w = red;
- else
- {
- png_uint_16 red_1 = png_ptr->gamma_16_to_1[(red&0xff) >>
- png_ptr->gamma_shift][red>>8];
- png_uint_16 green_1 = png_ptr->gamma_16_to_1[(green&0xff) >>
- png_ptr->gamma_shift][green>>8];
- png_uint_16 blue_1 = png_ptr->gamma_16_to_1[(blue&0xff) >>
- png_ptr->gamma_shift][blue>>8];
- png_uint_16 gray16 = (png_uint_16)((rc * red_1
- + gc * green_1 + bc * blue_1)>>15);
- w = png_ptr->gamma_16_from_1[(gray16&0xff) >>
- png_ptr->gamma_shift][gray16 >> 8];
- rgb_error |= 1;
- }
-
- *(dp++) = (png_byte)((w>>8) & 0xff);
- *(dp++) = (png_byte)(w & 0xff);
- *(dp++) = *(sp++); /* alpha */
- *(dp++) = *(sp++);
- }
- }
- else
- #endif
- {
- png_bytep sp = row;
- png_bytep dp = row;
- for (i = 0; i < row_width; i++)
- {
- png_uint_16 red, green, blue, gray16;
- red = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2;
- green = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2;
- blue = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2;
- if(red != green || red != blue)
- rgb_error |= 1;
- gray16 = (png_uint_16)((rc*red + gc*green + bc*blue)>>15);
- *(dp++) = (png_byte)((gray16>>8) & 0xff);
- *(dp++) = (png_byte)(gray16 & 0xff);
- *(dp++) = *(sp++); /* alpha */
- *(dp++) = *(sp++);
- }
- }
- }
- }
- row_info->channels -= (png_byte)2;
- row_info->color_type &= ~PNG_COLOR_MASK_COLOR;
- row_info->pixel_depth = (png_byte)(row_info->channels *
- row_info->bit_depth);
- row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,row_width);
- }
- return rgb_error;
- }
- #endif
-
- /* Build a grayscale palette. Palette is assumed to be 1 << bit_depth
- * large of png_color. This lets grayscale images be treated as
- * paletted. Most useful for gamma correction and simplification
- * of code.
- */
- void PNGAPI
- png_build_grayscale_palette(int bit_depth, png_colorp palette)
- {
- int num_palette;
- int color_inc;
- int i;
- int v;
-
- png_debug(1, "in png_do_build_grayscale_palette\n");
- if (palette == NULL)
- return;
-
- switch (bit_depth)
- {
- case 1:
- num_palette = 2;
- color_inc = 0xff;
- break;
- case 2:
- num_palette = 4;
- color_inc = 0x55;
- break;
- case 4:
- num_palette = 16;
- color_inc = 0x11;
- break;
- case 8:
- num_palette = 256;
- color_inc = 1;
- break;
- default:
- num_palette = 0;
- color_inc = 0;
- break;
- }
-
- for (i = 0, v = 0; i < num_palette; i++, v += color_inc)
- {
- palette[i].red = (png_byte)v;
- palette[i].green = (png_byte)v;
- palette[i].blue = (png_byte)v;
- }
- }
-
- /* This function is currently unused. Do we really need it? */
- #if defined(PNG_READ_DITHER_SUPPORTED) && defined(PNG_CORRECT_PALETTE_SUPPORTED)
- void /* PRIVATE */
- png_correct_palette(png_structp png_ptr, png_colorp palette,
- int num_palette)
- {
- png_debug(1, "in png_correct_palette\n");
- #if defined(PNG_READ_BACKGROUND_SUPPORTED) && \
- defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
- if (png_ptr->transformations & (PNG_GAMMA | PNG_BACKGROUND))
- {
- png_color back, back_1;
-
- if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE)
- {
- back.red = png_ptr->gamma_table[png_ptr->background.red];
- back.green = png_ptr->gamma_table[png_ptr->background.green];
- back.blue = png_ptr->gamma_table[png_ptr->background.blue];
-
- back_1.red = png_ptr->gamma_to_1[png_ptr->background.red];
- back_1.green = png_ptr->gamma_to_1[png_ptr->background.green];
- back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue];
- }
- else
- {
- double g;
-
- g = 1.0 / (png_ptr->background_gamma * png_ptr->screen_gamma);
-
- if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_SCREEN ||
- fabs(g - 1.0) < PNG_GAMMA_THRESHOLD)
- {
- back.red = png_ptr->background.red;
- back.green = png_ptr->background.green;
- back.blue = png_ptr->background.blue;
- }
- else
- {
- back.red =
- (png_byte)(pow((double)png_ptr->background.red/255, g) *
- 255.0 + 0.5);
- back.green =
- (png_byte)(pow((double)png_ptr->background.green/255, g) *
- 255.0 + 0.5);
- back.blue =
- (png_byte)(pow((double)png_ptr->background.blue/255, g) *
- 255.0 + 0.5);
- }
-
- g = 1.0 / png_ptr->background_gamma;
-
- back_1.red =
- (png_byte)(pow((double)png_ptr->background.red/255, g) *
- 255.0 + 0.5);
- back_1.green =
- (png_byte)(pow((double)png_ptr->background.green/255, g) *
- 255.0 + 0.5);
- back_1.blue =
- (png_byte)(pow((double)png_ptr->background.blue/255, g) *
- 255.0 + 0.5);
- }
-
- if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
- {
- png_uint_32 i;
-
- for (i = 0; i < (png_uint_32)num_palette; i++)
- {
- if (i < png_ptr->num_trans && png_ptr->trans[i] == 0)
- {
- palette[i] = back;
- }
- else if (i < png_ptr->num_trans && png_ptr->trans[i] != 0xff)
- {
- png_byte v, w;
-
- v = png_ptr->gamma_to_1[png_ptr->palette[i].red];
- png_composite(w, v, png_ptr->trans[i], back_1.red);
- palette[i].red = png_ptr->gamma_from_1[w];
-
- v = png_ptr->gamma_to_1[png_ptr->palette[i].green];
- png_composite(w, v, png_ptr->trans[i], back_1.green);
- palette[i].green = png_ptr->gamma_from_1[w];
-
- v = png_ptr->gamma_to_1[png_ptr->palette[i].blue];
- png_composite(w, v, png_ptr->trans[i], back_1.blue);
- palette[i].blue = png_ptr->gamma_from_1[w];
- }
- else
- {
- palette[i].red = png_ptr->gamma_table[palette[i].red];
- palette[i].green = png_ptr->gamma_table[palette[i].green];
- palette[i].blue = png_ptr->gamma_table[palette[i].blue];
- }
- }
- }
- else
- {
- int i;
-
- for (i = 0; i < num_palette; i++)
- {
- if (palette[i].red == (png_byte)png_ptr->trans_values.gray)
- {
- palette[i] = back;
- }
- else
- {
- palette[i].red = png_ptr->gamma_table[palette[i].red];
- palette[i].green = png_ptr->gamma_table[palette[i].green];
- palette[i].blue = png_ptr->gamma_table[palette[i].blue];
- }
- }
- }
- }
- else
- #endif
- #if defined(PNG_READ_GAMMA_SUPPORTED)
- if (png_ptr->transformations & PNG_GAMMA)
- {
- int i;
-
- for (i = 0; i < num_palette; i++)
- {
- palette[i].red = png_ptr->gamma_table[palette[i].red];
- palette[i].green = png_ptr->gamma_table[palette[i].green];
- palette[i].blue = png_ptr->gamma_table[palette[i].blue];
- }
- }
- #if defined(PNG_READ_BACKGROUND_SUPPORTED)
- else
- #endif
- #endif
- #if defined(PNG_READ_BACKGROUND_SUPPORTED)
- if (png_ptr->transformations & PNG_BACKGROUND)
- {
- if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
- {
- png_color back;
-
- back.red = (png_byte)png_ptr->background.red;
- back.green = (png_byte)png_ptr->background.green;
- back.blue = (png_byte)png_ptr->background.blue;
-
- for (i = 0; i < (int)png_ptr->num_trans; i++)
- {
- if (png_ptr->trans[i] == 0)
- {
- palette[i].red = back.red;
- palette[i].green = back.green;
- palette[i].blue = back.blue;
- }
- else if (png_ptr->trans[i] != 0xff)
- {
- png_composite(palette[i].red, png_ptr->palette[i].red,
- png_ptr->trans[i], back.red);
- png_composite(palette[i].green, png_ptr->palette[i].green,
- png_ptr->trans[i], back.green);
- png_composite(palette[i].blue, png_ptr->palette[i].blue,
- png_ptr->trans[i], back.blue);
- }
- }
- }
- else /* assume grayscale palette (what else could it be?) */
- {
- int i;
-
- for (i = 0; i < num_palette; i++)
- {
- if (i == (png_byte)png_ptr->trans_values.gray)
- {
- palette[i].red = (png_byte)png_ptr->background.red;
- palette[i].green = (png_byte)png_ptr->background.green;
- palette[i].blue = (png_byte)png_ptr->background.blue;
- }
- }
- }
- }
- #endif
- }
- #endif
-
- #if defined(PNG_READ_BACKGROUND_SUPPORTED)
- /* Replace any alpha or transparency with the supplied background color.
- * "background" is already in the screen gamma, while "background_1" is
- * at a gamma of 1.0. Paletted files have already been taken care of.
- */
- void /* PRIVATE */
- png_do_background(png_row_infop row_info, png_bytep row,
- png_color_16p trans_values, png_color_16p background
- #if defined(PNG_READ_GAMMA_SUPPORTED)
- , png_color_16p background_1,
- png_bytep gamma_table, png_bytep gamma_from_1, png_bytep gamma_to_1,
- png_uint_16pp gamma_16, png_uint_16pp gamma_16_from_1,
- png_uint_16pp gamma_16_to_1, int gamma_shift
- #endif
- )
- {
- png_bytep sp, dp;
- png_uint_32 i;
- png_uint_32 row_width=row_info->width;
- int shift;
-
- png_debug(1, "in png_do_background\n");
- if (background != NULL &&
- #if defined(PNG_USELESS_TESTS_SUPPORTED)
- row != NULL && row_info != NULL &&
- #endif
- (!(row_info->color_type & PNG_COLOR_MASK_ALPHA) ||
- (row_info->color_type != PNG_COLOR_TYPE_PALETTE && trans_values)))
- {
- switch (row_info->color_type)
- {
- case PNG_COLOR_TYPE_GRAY:
- {
- switch (row_info->bit_depth)
- {
- case 1:
- {
- sp = row;
- shift = 7;
- for (i = 0; i < row_width; i++)
- {
- if ((png_uint_16)((*sp >> shift) & 0x01)
- == trans_values->gray)
- {
- *sp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff);
- *sp |= (png_byte)(background->gray << shift);
- }
- if (!shift)
- {
- shift = 7;
- sp++;
- }
- else
- shift--;
- }
- break;
- }
- case 2:
- {
- #if defined(PNG_READ_GAMMA_SUPPORTED)
- if (gamma_table != NULL)
- {
- sp = row;
- shift = 6;
- for (i = 0; i < row_width; i++)
- {
- if ((png_uint_16)((*sp >> shift) & 0x03)
- == trans_values->gray)
- {
- *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
- *sp |= (png_byte)(background->gray << shift);
- }
- else
- {
- png_byte p = (png_byte)((*sp >> shift) & 0x03);
- png_byte g = (png_byte)((gamma_table [p | (p << 2) |
- (p << 4) | (p << 6)] >> 6) & 0x03);
- *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
- *sp |= (png_byte)(g << shift);
- }
- if (!shift)
- {
- shift = 6;
- sp++;
- }
- else
- shift -= 2;
- }
- }
- else
- #endif
- {
- sp = row;
- shift = 6;
- for (i = 0; i < row_width; i++)
- {
- if ((png_uint_16)((*sp >> shift) & 0x03)
- == trans_values->gray)
- {
- *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
- *sp |= (png_byte)(background->gray << shift);
- }
- if (!shift)
- {
- shift = 6;
- sp++;
- }
- else
- shift -= 2;
- }
- }
- break;
- }
- case 4:
- {
- #if defined(PNG_READ_GAMMA_SUPPORTED)
- if (gamma_table != NULL)
- {
- sp = row;
- shift = 4;
- for (i = 0; i < row_width; i++)
- {
- if ((png_uint_16)((*sp >> shift) & 0x0f)
- == trans_values->gray)
- {
- *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
- *sp |= (png_byte)(background->gray << shift);
- }
- else
- {
- png_byte p = (png_byte)((*sp >> shift) & 0x0f);
- png_byte g = (png_byte)((gamma_table[p |
- (p << 4)] >> 4) & 0x0f);
- *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
- *sp |= (png_byte)(g << shift);
- }
- if (!shift)
- {
- shift = 4;
- sp++;
- }
- else
- shift -= 4;
- }
- }
- else
- #endif
- {
- sp = row;
- shift = 4;
- for (i = 0; i < row_width; i++)
- {
- if ((png_uint_16)((*sp >> shift) & 0x0f)
- == trans_values->gray)
- {
- *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
- *sp |= (png_byte)(background->gray << shift);
- }
- if (!shift)
- {
- shift = 4;
- sp++;
- }
- else
- shift -= 4;
- }
- }
- break;
- }
- case 8:
- {
- #if defined(PNG_READ_GAMMA_SUPPORTED)
- if (gamma_table != NULL)
- {
- sp = row;
- for (i = 0; i < row_width; i++, sp++)
- {
- if (*sp == trans_values->gray)
- {
- *sp = (png_byte)background->gray;
- }
- else
- {
- *sp = gamma_table[*sp];
- }
- }
- }
- else
- #endif
- {
- sp = row;
- for (i = 0; i < row_width; i++, sp++)
- {
- if (*sp == trans_values->gray)
- {
- *sp = (png_byte)background->gray;
- }
- }
- }
- break;
- }
- case 16:
- {
- #if defined(PNG_READ_GAMMA_SUPPORTED)
- if (gamma_16 != NULL)
- {
- sp = row;
- for (i = 0; i < row_width; i++, sp += 2)
- {
- png_uint_16 v;
-
- v = (png_uint_16)(((*sp) << 8) + *(sp + 1));
- if (v == trans_values->gray)
- {
- /* background is already in screen gamma */
- *sp = (png_byte)((background->gray >> 8) & 0xff);
- *(sp + 1) = (png_byte)(background->gray & 0xff);
- }
- else
- {
- v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
- *sp = (png_byte)((v >> 8) & 0xff);
- *(sp + 1) = (png_byte)(v & 0xff);
- }
- }
- }
- else
- #endif
- {
- sp = row;
- for (i = 0; i < row_width; i++, sp += 2)
- {
- png_uint_16 v;
-
- v = (png_uint_16)(((*sp) << 8) + *(sp + 1));
- if (v == trans_values->gray)
- {
- *sp = (png_byte)((background->gray >> 8) & 0xff);
- *(sp + 1) = (png_byte)(background->gray & 0xff);
- }
- }
- }
- break;
- }
- }
- break;
- }
- case PNG_COLOR_TYPE_RGB:
- {
- if (row_info->bit_depth == 8)
- {
- #if defined(PNG_READ_GAMMA_SUPPORTED)
- if (gamma_table != NULL)
- {
- sp = row;
- for (i = 0; i < row_width; i++, sp += 3)
- {
- if (*sp == trans_values->red &&
- *(sp + 1) == trans_values->green &&
- *(sp + 2) == trans_values->blue)
- {
- *sp = (png_byte)background->red;
- *(sp + 1) = (png_byte)background->green;
- *(sp + 2) = (png_byte)background->blue;
- }
- else
- {
- *sp = gamma_table[*sp];
- *(sp + 1) = gamma_table[*(sp + 1)];
- *(sp + 2) = gamma_table[*(sp + 2)];
- }
- }
- }
- else
- #endif
- {
- sp = row;
- for (i = 0; i < row_width; i++, sp += 3)
- {
- if (*sp == trans_values->red &&
- *(sp + 1) == trans_values->green &&
- *(sp + 2) == trans_values->blue)
- {
- *sp = (png_byte)background->red;
- *(sp + 1) = (png_byte)background->green;
- *(sp + 2) = (png_byte)background->blue;
- }
- }
- }
- }
- else /* if (row_info->bit_depth == 16) */
- {
- #if defined(PNG_READ_GAMMA_SUPPORTED)
- if (gamma_16 != NULL)
- {
- sp = row;
- for (i = 0; i < row_width; i++, sp += 6)
- {
- png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
- png_uint_16 g = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
- png_uint_16 b = (png_uint_16)(((*(sp+4)) << 8) + *(sp+5));
- if (r == trans_values->red && g == trans_values->green &&
- b == trans_values->blue)
- {
- /* background is already in screen gamma */
- *sp = (png_byte)((background->red >> 8) & 0xff);
- *(sp + 1) = (png_byte)(background->red & 0xff);
- *(sp + 2) = (png_byte)((background->green >> 8) & 0xff);
- *(sp + 3) = (png_byte)(background->green & 0xff);
- *(sp + 4) = (png_byte)((background->blue >> 8) & 0xff);
- *(sp + 5) = (png_byte)(background->blue & 0xff);
- }
- else
- {
- png_uint_16 v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
- *sp = (png_byte)((v >> 8) & 0xff);
- *(sp + 1) = (png_byte)(v & 0xff);
- v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];
- *(sp + 2) = (png_byte)((v >> 8) & 0xff);
- *(sp + 3) = (png_byte)(v & 0xff);
- v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];
- *(sp + 4) = (png_byte)((v >> 8) & 0xff);
- *(sp + 5) = (png_byte)(v & 0xff);
- }
- }
- }
- else
- #endif
- {
- sp = row;
- for (i = 0; i < row_width; i++, sp += 6)
- {
- png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp+1));
- png_uint_16 g = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
- png_uint_16 b = (png_uint_16)(((*(sp+4)) << 8) + *(sp+5));
-
- if (r == trans_values->red && g == trans_values->green &&
- b == trans_values->blue)
- {
- *sp = (png_byte)((background->red >> 8) & 0xff);
- *(sp + 1) = (png_byte)(background->red & 0xff);
- *(sp + 2) = (png_byte)((background->green >> 8) & 0xff);
- *(sp + 3) = (png_byte)(background->green & 0xff);
- *(sp + 4) = (png_byte)((background->blue >> 8) & 0xff);
- *(sp + 5) = (png_byte)(background->blue & 0xff);
- }
- }
- }
- }
- break;
- }
- case PNG_COLOR_TYPE_GRAY_ALPHA:
- {
- if (row_info->bit_depth == 8)
- {
- #if defined(PNG_READ_GAMMA_SUPPORTED)
- if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
- gamma_table != NULL)
- {
- sp = row;
- dp = row;
- for (i = 0; i < row_width; i++, sp += 2, dp++)
- {
- png_uint_16 a = *(sp + 1);
-
- if (a == 0xff)
- {
- *dp = gamma_table[*sp];
- }
- else if (a == 0)
- {
- /* background is already in screen gamma */
- *dp = (png_byte)background->gray;
- }
- else
- {
- png_byte v, w;
-
- v = gamma_to_1[*sp];
- png_composite(w, v, a, background_1->gray);
- *dp = gamma_from_1[w];
- }
- }
- }
- else
- #endif
- {
- sp = row;
- dp = row;
- for (i = 0; i < row_width; i++, sp += 2, dp++)
- {
- png_byte a = *(sp + 1);
-
- if (a == 0xff)
- {
- *dp = *sp;
- }
- #if defined(PNG_READ_GAMMA_SUPPORTED)
- else if (a == 0)
- {
- *dp = (png_byte)background->gray;
- }
- else
- {
- png_composite(*dp, *sp, a, background_1->gray);
- }
- #else
- *dp = (png_byte)background->gray;
- #endif
- }
- }
- }
- else /* if (png_ptr->bit_depth == 16) */
- {
- #if defined(PNG_READ_GAMMA_SUPPORTED)
- if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
- gamma_16_to_1 != NULL)
- {
- sp = row;
- dp = row;
- for (i = 0; i < row_width; i++, sp += 4, dp += 2)
- {
- png_uint_16 a = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
-
- if (a == (png_uint_16)0xffff)
- {
- png_uint_16 v;
-
- v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
- *dp = (png_byte)((v >> 8) & 0xff);
- *(dp + 1) = (png_byte)(v & 0xff);
- }
- #if defined(PNG_READ_GAMMA_SUPPORTED)
- else if (a == 0)
- #else
- else
- #endif
- {
- /* background is already in screen gamma */
- *dp = (png_byte)((background->gray >> 8) & 0xff);
- *(dp + 1) = (png_byte)(background->gray & 0xff);
- }
- #if defined(PNG_READ_GAMMA_SUPPORTED)
- else
- {
- png_uint_16 g, v, w;
-
- g = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
- png_composite_16(v, g, a, background_1->gray);
- w = gamma_16_from_1[(v&0xff) >> gamma_shift][v >> 8];
- *dp = (png_byte)((w >> 8) & 0xff);
- *(dp + 1) = (png_byte)(w & 0xff);
- }
- #endif
- }
- }
- else
- #endif
- {
- sp = row;
- dp = row;
- for (i = 0; i < row_width; i++, sp += 4, dp += 2)
- {
- png_uint_16 a = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
- if (a == (png_uint_16)0xffff)
- {
- png_memcpy(dp, sp, 2);
- }
- #if defined(PNG_READ_GAMMA_SUPPORTED)
- else if (a == 0)
- #else
- else
- #endif
- {
- *dp = (png_byte)((background->gray >> 8) & 0xff);
- *(dp + 1) = (png_byte)(background->gray & 0xff);
- }
- #if defined(PNG_READ_GAMMA_SUPPORTED)
- else
- {
- png_uint_16 g, v;
-
- g = (png_uint_16)(((*sp) << 8) + *(sp + 1));
- png_composite_16(v, g, a, background_1->gray);
- *dp = (png_byte)((v >> 8) & 0xff);
- *(dp + 1) = (png_byte)(v & 0xff);
- }
- #endif
- }
- }
- }
- break;
- }
- case PNG_COLOR_TYPE_RGB_ALPHA:
- {
- if (row_info->bit_depth == 8)
- {
- #if defined(PNG_READ_GAMMA_SUPPORTED)
- if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
- gamma_table != NULL)
- {
- sp = row;
- dp = row;
- for (i = 0; i < row_width; i++, sp += 4, dp += 3)
- {
- png_byte a = *(sp + 3);
-
- if (a == 0xff)
- {
- *dp = gamma_table[*sp];
- *(dp + 1) = gamma_table[*(sp + 1)];
- *(dp + 2) = gamma_table[*(sp + 2)];
- }
- else if (a == 0)
- {
- /* background is already in screen gamma */
- *dp = (png_byte)background->red;
- *(dp + 1) = (png_byte)background->green;
- *(dp + 2) = (png_byte)background->blue;
- }
- else
- {
- png_byte v, w;
-
- v = gamma_to_1[*sp];
- png_composite(w, v, a, background_1->red);
- *dp = gamma_from_1[w];
- v = gamma_to_1[*(sp + 1)];
- png_composite(w, v, a, background_1->green);
- *(dp + 1) = gamma_from_1[w];
- v = gamma_to_1[*(sp + 2)];
- png_composite(w, v, a, background_1->blue);
- *(dp + 2) = gamma_from_1[w];
- }
- }
- }
- else
- #endif
- {
- sp = row;
- dp = row;
- for (i = 0; i < row_width; i++, sp += 4, dp += 3)
- {
- png_byte a = *(sp + 3);
-
- if (a == 0xff)
- {
- *dp = *sp;
- *(dp + 1) = *(sp + 1);
- *(dp + 2) = *(sp + 2);
- }
- else if (a == 0)
- {
- *dp = (png_byte)background->red;
- *(dp + 1) = (png_byte)background->green;
- *(dp + 2) = (png_byte)background->blue;
- }
- else
- {
- png_composite(*dp, *sp, a, background->red);
- png_composite(*(dp + 1), *(sp + 1), a,
- background->green);
- png_composite(*(dp + 2), *(sp + 2), a,
- background->blue);
- }
- }
- }
- }
- else /* if (row_info->bit_depth == 16) */
- {
- #if defined(PNG_READ_GAMMA_SUPPORTED)
- if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
- gamma_16_to_1 != NULL)
- {
- sp = row;
- dp = row;
- for (i = 0; i < row_width; i++, sp += 8, dp += 6)
- {
- png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))
- << 8) + (png_uint_16)(*(sp + 7)));
- if (a == (png_uint_16)0xffff)
- {
- png_uint_16 v;
-
- v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
- *dp = (png_byte)((v >> 8) & 0xff);
- *(dp + 1) = (png_byte)(v & 0xff);
- v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];
- *(dp + 2) = (png_byte)((v >> 8) & 0xff);
- *(dp + 3) = (png_byte)(v & 0xff);
- v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];
- *(dp + 4) = (png_byte)((v >> 8) & 0xff);
- *(dp + 5) = (png_byte)(v & 0xff);
- }
- else if (a == 0)
- {
- /* background is already in screen gamma */
- *dp = (png_byte)((background->red >> 8) & 0xff);
- *(dp + 1) = (png_byte)(background->red & 0xff);
- *(dp + 2) = (png_byte)((background->green >> 8) & 0xff);
- *(dp + 3) = (png_byte)(background->green & 0xff);
- *(dp + 4) = (png_byte)((background->blue >> 8) & 0xff);
- *(dp + 5) = (png_byte)(background->blue & 0xff);
- }
- else
- {
- png_uint_16 v, w, x;
-
- v = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
- png_composite_16(w, v, a, background_1->red);
- x = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 8];
- *dp = (png_byte)((x >> 8) & 0xff);
- *(dp + 1) = (png_byte)(x & 0xff);
- v = gamma_16_to_1[*(sp + 3) >> gamma_shift][*(sp + 2)];
- png_composite_16(w, v, a, background_1->green);
- x = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 8];
- *(dp + 2) = (png_byte)((x >> 8) & 0xff);
- *(dp + 3) = (png_byte)(x & 0xff);
- v = gamma_16_to_1[*(sp + 5) >> gamma_shift][*(sp + 4)];
- png_composite_16(w, v, a, background_1->blue);
- x = gamma_16_from_1[(w & 0xff) >> gamma_shift][w >> 8];
- *(dp + 4) = (png_byte)((x >> 8) & 0xff);
- *(dp + 5) = (png_byte)(x & 0xff);
- }
- }
- }
- else
- #endif
- {
- sp = row;
- dp = row;
- for (i = 0; i < row_width; i++, sp += 8, dp += 6)
- {
- png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))
- << 8) + (png_uint_16)(*(sp + 7)));
- if (a == (png_uint_16)0xffff)
- {
- png_memcpy(dp, sp, 6);
- }
- else if (a == 0)
- {
- *dp = (png_byte)((background->red >> 8) & 0xff);
- *(dp + 1) = (png_byte)(background->red & 0xff);
- *(dp + 2) = (png_byte)((background->green >> 8) & 0xff);
- *(dp + 3) = (png_byte)(background->green & 0xff);
- *(dp + 4) = (png_byte)((background->blue >> 8) & 0xff);
- *(dp + 5) = (png_byte)(background->blue & 0xff);
- }
- else
- {
- png_uint_16 v;
-
- png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
- png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8)
- + *(sp + 3));
- png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8)
- + *(sp + 5));
-
- png_composite_16(v, r, a, background->red);
- *dp = (png_byte)((v >> 8) & 0xff);
- *(dp + 1) = (png_byte)(v & 0xff);
- png_composite_16(v, g, a, background->green);
- *(dp + 2) = (png_byte)((v >> 8) & 0xff);
- *(dp + 3) = (png_byte)(v & 0xff);
- png_composite_16(v, b, a, background->blue);
- *(dp + 4) = (png_byte)((v >> 8) & 0xff);
- *(dp + 5) = (png_byte)(v & 0xff);
- }
- }
- }
- }
- break;
- }
- }
-
- if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
- {
- row_info->color_type &= ~PNG_COLOR_MASK_ALPHA;
- row_info->channels--;
- row_info->pixel_depth = (png_byte)(row_info->channels *
- row_info->bit_depth);
- row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,row_width);
- }
- }
- }
- #endif
-
- #if defined(PNG_READ_GAMMA_SUPPORTED)
- /* Gamma correct the image, avoiding the alpha channel. Make sure
- * you do this after you deal with the transparency issue on grayscale
- * or RGB images. If your bit depth is 8, use gamma_table, if it
- * is 16, use gamma_16_table and gamma_shift. Build these with
- * build_gamma_table().
- */
- void /* PRIVATE */
- png_do_gamma(png_row_infop row_info, png_bytep row,
- png_bytep gamma_table, png_uint_16pp gamma_16_table,
- int gamma_shift)
- {
- png_bytep sp;
- png_uint_32 i;
- png_uint_32 row_width=row_info->width;
-
- png_debug(1, "in png_do_gamma\n");
- if (
- #if defined(PNG_USELESS_TESTS_SUPPORTED)
- row != NULL && row_info != NULL &&
- #endif
- ((row_info->bit_depth <= 8 && gamma_table != NULL) ||
- (row_info->bit_depth == 16 && gamma_16_table != NULL)))
- {
- switch (row_info->color_type)
- {
- case PNG_COLOR_TYPE_RGB:
- {
- if (row_info->bit_depth == 8)
- {
- sp = row;
- for (i = 0; i < row_width; i++)
- {
- *sp = gamma_table[*sp];
- sp++;
- *sp = gamma_table[*sp];
- sp++;
- *sp = gamma_table[*sp];
- sp++;
- }
- }
- else /* if (row_info->bit_depth == 16) */
- {
- sp = row;
- for (i = 0; i < row_width; i++)
- {
- png_uint_16 v;
-
- v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
- *sp = (png_byte)((v >> 8) & 0xff);
- *(sp + 1) = (png_byte)(v & 0xff);
- sp += 2;
- v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
- *sp = (png_byte)((v >> 8) & 0xff);
- *(sp + 1) = (png_byte)(v & 0xff);
- sp += 2;
- v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
- *sp = (png_byte)((v >> 8) & 0xff);
- *(sp + 1) = (png_byte)(v & 0xff);
- sp += 2;
- }
- }
- break;
- }
- case PNG_COLOR_TYPE_RGB_ALPHA:
- {
- if (row_info->bit_depth == 8)
- {
- sp = row;
- for (i = 0; i < row_width; i++)
- {
- *sp = gamma_table[*sp];
- sp++;
- *sp = gamma_table[*sp];
- sp++;
- *sp = gamma_table[*sp];
- sp++;
- sp++;
- }
- }
- else /* if (row_info->bit_depth == 16) */
- {
- sp = row;
- for (i = 0; i < row_width; i++)
- {
- png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
- *sp = (png_byte)((v >> 8) & 0xff);
- *(sp + 1) = (png_byte)(v & 0xff);
- sp += 2;
- v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
- *sp = (png_byte)((v >> 8) & 0xff);
- *(sp + 1) = (png_byte)(v & 0xff);
- sp += 2;
- v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
- *sp = (png_byte)((v >> 8) & 0xff);
- *(sp + 1) = (png_byte)(v & 0xff);
- sp += 4;
- }
- }
- break;
- }
- case PNG_COLOR_TYPE_GRAY_ALPHA:
- {
- if (row_info->bit_depth == 8)
- {
- sp = row;
- for (i = 0; i < row_width; i++)
- {
- *sp = gamma_table[*sp];
- sp += 2;
- }
- }
- else /* if (row_info->bit_depth == 16) */
- {
- sp = row;
- for (i = 0; i < row_width; i++)
- {
- png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
- *sp = (png_byte)((v >> 8) & 0xff);
- *(sp + 1) = (png_byte)(v & 0xff);
- sp += 4;
- }
- }
- break;
- }
- case PNG_COLOR_TYPE_GRAY:
- {
- if (row_info->bit_depth == 2)
- {
- sp = row;
- for (i = 0; i < row_width; i += 4)
- {
- int a = *sp & 0xc0;
- int b = *sp & 0x30;
- int c = *sp & 0x0c;
- int d = *sp & 0x03;
-
- *sp = (png_byte)(
- ((((int)gamma_table[a|(a>>2)|(a>>4)|(a>>6)]) ) & 0xc0)|
- ((((int)gamma_table[(b<<2)|b|(b>>2)|(b>>4)])>>2) & 0x30)|
- ((((int)gamma_table[(c<<4)|(c<<2)|c|(c>>2)])>>4) & 0x0c)|
- ((((int)gamma_table[(d<<6)|(d<<4)|(d<<2)|d])>>6) ));
- sp++;
- }
- }
- if (row_info->bit_depth == 4)
- {
- sp = row;
- for (i = 0; i < row_width; i += 2)
- {
- int msb = *sp & 0xf0;
- int lsb = *sp & 0x0f;
-
- *sp = (png_byte)((((int)gamma_table[msb | (msb >> 4)]) & 0xf0)
- | (((int)gamma_table[(lsb << 4) | lsb]) >> 4));
- sp++;
- }
- }
- else if (row_info->bit_depth == 8)
- {
- sp = row;
- for (i = 0; i < row_width; i++)
- {
- *sp = gamma_table[*sp];
- sp++;
- }
- }
- else if (row_info->bit_depth == 16)
- {
- sp = row;
- for (i = 0; i < row_width; i++)
- {
- png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
- *sp = (png_byte)((v >> 8) & 0xff);
- *(sp + 1) = (png_byte)(v & 0xff);
- sp += 2;
- }
- }
- break;
- }
- }
- }
- }
- #endif
-
- #if defined(PNG_READ_EXPAND_SUPPORTED)
- /* Expands a palette row to an RGB or RGBA row depending
- * upon whether you supply trans and num_trans.
- */
- void /* PRIVATE */
- png_do_expand_palette(png_row_infop row_info, png_bytep row,
- png_colorp palette, png_bytep trans, int num_trans)
- {
- int shift, value;
- png_bytep sp, dp;
- png_uint_32 i;
- png_uint_32 row_width=row_info->width;
-
- png_debug(1, "in png_do_expand_palette\n");
- if (
- #if defined(PNG_USELESS_TESTS_SUPPORTED)
- row != NULL && row_info != NULL &&
- #endif
- row_info->color_type == PNG_COLOR_TYPE_PALETTE)
- {
- if (row_info->bit_depth < 8)
- {
- switch (row_info->bit_depth)
- {
- case 1:
- {
- sp = row + (png_size_t)((row_width - 1) >> 3);
- dp = row + (png_size_t)row_width - 1;
- shift = 7 - (int)((row_width + 7) & 0x07);
- for (i = 0; i < row_width; i++)
- {
- if ((*sp >> shift) & 0x01)
- *dp = 1;
- else
- *dp = 0;
- if (shift == 7)
- {
- shift = 0;
- sp--;
- }
- else
- shift++;
-
- dp--;
- }
- break;
- }
- case 2:
- {
- sp = row + (png_size_t)((row_width - 1) >> 2);
- dp = row + (png_size_t)row_width - 1;
- shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
- for (i = 0; i < row_width; i++)
- {
- value = (*sp >> shift) & 0x03;
- *dp = (png_byte)value;
- if (shift == 6)
- {
- shift = 0;
- sp--;
- }
- else
- shift += 2;
-
- dp--;
- }
- break;
- }
- case 4:
- {
- sp = row + (png_size_t)((row_width - 1) >> 1);
- dp = row + (png_size_t)row_width - 1;
- shift = (int)((row_width & 0x01) << 2);
- for (i = 0; i < row_width; i++)
- {
- value = (*sp >> shift) & 0x0f;
- *dp = (png_byte)value;
- if (shift == 4)
- {
- shift = 0;
- sp--;
- }
- else
- shift += 4;
-
- dp--;
- }
- break;
- }
- }
- row_info->bit_depth = 8;
- row_info->pixel_depth = 8;
- row_info->rowbytes = row_width;
- }
- switch (row_info->bit_depth)
- {
- case 8:
- {
- if (trans != NULL)
- {
- sp = row + (png_size_t)row_width - 1;
- dp = row + (png_size_t)(row_width << 2) - 1;
-
- for (i = 0; i < row_width; i++)
- {
- if ((int)(*sp) >= num_trans)
- *dp-- = 0xff;
- else
- *dp-- = trans[*sp];
- *dp-- = palette[*sp].blue;
- *dp-- = palette[*sp].green;
- *dp-- = palette[*sp].red;
- sp--;
- }
- row_info->bit_depth = 8;
- row_info->pixel_depth = 32;
- row_info->rowbytes = row_width * 4;
- row_info->color_type = 6;
- row_info->channels = 4;
- }
- else
- {
- sp = row + (png_size_t)row_width - 1;
- dp = row + (png_size_t)(row_width * 3) - 1;
-
- for (i = 0; i < row_width; i++)
- {
- *dp-- = palette[*sp].blue;
- *dp-- = palette[*sp].green;
- *dp-- = palette[*sp].red;
- sp--;
- }
- row_info->bit_depth = 8;
- row_info->pixel_depth = 24;
- row_info->rowbytes = row_width * 3;
- row_info->color_type = 2;
- row_info->channels = 3;
- }
- break;
- }
- }
- }
- }
-
- /* If the bit depth < 8, it is expanded to 8. Also, if the already
- * expanded transparency value is supplied, an alpha channel is built.
- */
- void /* PRIVATE */
- png_do_expand(png_row_infop row_info, png_bytep row,
- png_color_16p trans_value)
- {
- int shift, value;
- png_bytep sp, dp;
- png_uint_32 i;
- png_uint_32 row_width=row_info->width;
-
- png_debug(1, "in png_do_expand\n");
- #if defined(PNG_USELESS_TESTS_SUPPORTED)
- if (row != NULL && row_info != NULL)
- #endif
- {
- if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
- {
- png_uint_16 gray = (png_uint_16)(trans_value ? trans_value->gray : 0);
-
- if (row_info->bit_depth < 8)
- {
- switch (row_info->bit_depth)
- {
- case 1:
- {
- gray = (png_uint_16)((gray&0x01)*0xff);
- sp = row + (png_size_t)((row_width - 1) >> 3);
- dp = row + (png_size_t)row_width - 1;
- shift = 7 - (int)((row_width + 7) & 0x07);
- for (i = 0; i < row_width; i++)
- {
- if ((*sp >> shift) & 0x01)
- *dp = 0xff;
- else
- *dp = 0;
- if (shift == 7)
- {
- shift = 0;
- sp--;
- }
- else
- shift++;
-
- dp--;
- }
- break;
- }
- case 2:
- {
- gray = (png_uint_16)((gray&0x03)*0x55);
- sp = row + (png_size_t)((row_width - 1) >> 2);
- dp = row + (png_size_t)row_width - 1;
- shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
- for (i = 0; i < row_width; i++)
- {
- value = (*sp >> shift) & 0x03;
- *dp = (png_byte)(value | (value << 2) | (value << 4) |
- (value << 6));
- if (shift == 6)
- {
- shift = 0;
- sp--;
- }
- else
- shift += 2;
-
- dp--;
- }
- break;
- }
- case 4:
- {
- gray = (png_uint_16)((gray&0x0f)*0x11);
- sp = row + (png_size_t)((row_width - 1) >> 1);
- dp = row + (png_size_t)row_width - 1;
- shift = (int)((1 - ((row_width + 1) & 0x01)) << 2);
- for (i = 0; i < row_width; i++)
- {
- value = (*sp >> shift) & 0x0f;
- *dp = (png_byte)(value | (value << 4));
- if (shift == 4)
- {
- shift = 0;
- sp--;
- }
- else
- shift = 4;
-
- dp--;
- }
- break;
- }
- }
- row_info->bit_depth = 8;
- row_info->pixel_depth = 8;
- row_info->rowbytes = row_width;
- }
-
- if (trans_value != NULL)
- {
- if (row_info->bit_depth == 8)
- {
- gray = gray & 0xff;
- sp = row + (png_size_t)row_width - 1;
- dp = row + (png_size_t)(row_width << 1) - 1;
- for (i = 0; i < row_width; i++)
- {
- if (*sp == gray)
- *dp-- = 0;
- else
- *dp-- = 0xff;
- *dp-- = *sp--;
- }
- }
- else if (row_info->bit_depth == 16)
- {
- png_byte gray_high = (gray >> 8) & 0xff;
- png_byte gray_low = gray & 0xff;
- sp = row + row_info->rowbytes - 1;
- dp = row + (row_info->rowbytes << 1) - 1;
- for (i = 0; i < row_width; i++)
- {
- if (*(sp-1) == gray_high && *(sp) == gray_low)
- {
- *dp-- = 0;
- *dp-- = 0;
- }
- else
- {
- *dp-- = 0xff;
- *dp-- = 0xff;
- }
- *dp-- = *sp--;
- *dp-- = *sp--;
- }
- }
- row_info->color_type = PNG_COLOR_TYPE_GRAY_ALPHA;
- row_info->channels = 2;
- row_info->pixel_depth = (png_byte)(row_info->bit_depth << 1);
- row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
- row_width);
- }
- }
- else if (row_info->color_type == PNG_COLOR_TYPE_RGB && trans_value)
- {
- if (row_info->bit_depth == 8)
- {
- png_byte red = trans_value->red & 0xff;
- png_byte green = trans_value->green & 0xff;
- png_byte blue = trans_value->blue & 0xff;
- sp = row + (png_size_t)row_info->rowbytes - 1;
- dp = row + (png_size_t)(row_width << 2) - 1;
- for (i = 0; i < row_width; i++)
- {
- if (*(sp - 2) == red && *(sp - 1) == green && *(sp) == blue)
- *dp-- = 0;
- else
- *dp-- = 0xff;
- *dp-- = *sp--;
- *dp-- = *sp--;
- *dp-- = *sp--;
- }
- }
- else if (row_info->bit_depth == 16)
- {
- png_byte red_high = (trans_value->red >> 8) & 0xff;
- png_byte green_high = (trans_value->green >> 8) & 0xff;
- png_byte blue_high = (trans_value->blue >> 8) & 0xff;
- png_byte red_low = trans_value->red & 0xff;
- png_byte green_low = trans_value->green & 0xff;
- png_byte blue_low = trans_value->blue & 0xff;
- sp = row + row_info->rowbytes - 1;
- dp = row + (png_size_t)(row_width << 3) - 1;
- for (i = 0; i < row_width; i++)
- {
- if (*(sp - 5) == red_high &&
- *(sp - 4) == red_low &&
- *(sp - 3) == green_high &&
- *(sp - 2) == green_low &&
- *(sp - 1) == blue_high &&
- *(sp ) == blue_low)
- {
- *dp-- = 0;
- *dp-- = 0;
- }
- else
- {
- *dp-- = 0xff;
- *dp-- = 0xff;
- }
- *dp-- = *sp--;
- *dp-- = *sp--;
- *dp-- = *sp--;
- *dp-- = *sp--;
- *dp-- = *sp--;
- *dp-- = *sp--;
- }
- }
- row_info->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
- row_info->channels = 4;
- row_info->pixel_depth = (png_byte)(row_info->bit_depth << 2);
- row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,row_width);
- }
- }
- }
- #endif
-
- #if defined(PNG_READ_DITHER_SUPPORTED)
- void /* PRIVATE */
- png_do_dither(png_row_infop row_info, png_bytep row,
- png_bytep palette_lookup, png_bytep dither_lookup)
- {
- png_bytep sp, dp;
- png_uint_32 i;
- png_uint_32 row_width=row_info->width;
-
- png_debug(1, "in png_do_dither\n");
- #if defined(PNG_USELESS_TESTS_SUPPORTED)
- if (row != NULL && row_info != NULL)
- #endif
- {
- if (row_info->color_type == PNG_COLOR_TYPE_RGB &&
- palette_lookup && row_info->bit_depth == 8)
- {
- int r, g, b, p;
- sp = row;
- dp = row;
- for (i = 0; i < row_width; i++)
- {
- r = *sp++;
- g = *sp++;
- b = *sp++;
-
- /* this looks real messy, but the compiler will reduce
- it down to a reasonable formula. For example, with
- 5 bits per color, we get:
- p = (((r >> 3) & 0x1f) << 10) |
- (((g >> 3) & 0x1f) << 5) |
- ((b >> 3) & 0x1f);
- */
- p = (((r >> (8 - PNG_DITHER_RED_BITS)) &
- ((1 << PNG_DITHER_RED_BITS) - 1)) <<
- (PNG_DITHER_GREEN_BITS + PNG_DITHER_BLUE_BITS)) |
- (((g >> (8 - PNG_DITHER_GREEN_BITS)) &
- ((1 << PNG_DITHER_GREEN_BITS) - 1)) <<
- (PNG_DITHER_BLUE_BITS)) |
- ((b >> (8 - PNG_DITHER_BLUE_BITS)) &
- ((1 << PNG_DITHER_BLUE_BITS) - 1));
-
- *dp++ = palette_lookup[p];
- }
- row_info->color_type = PNG_COLOR_TYPE_PALETTE;
- row_info->channels = 1;
- row_info->pixel_depth = row_info->bit_depth;
- row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,row_width);
- }
- else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA &&
- palette_lookup != NULL && row_info->bit_depth == 8)
- {
- int r, g, b, p;
- sp = row;
- dp = row;
- for (i = 0; i < row_width; i++)
- {
- r = *sp++;
- g = *sp++;
- b = *sp++;
- sp++;
-
- p = (((r >> (8 - PNG_DITHER_RED_BITS)) &
- ((1 << PNG_DITHER_RED_BITS) - 1)) <<
- (PNG_DITHER_GREEN_BITS + PNG_DITHER_BLUE_BITS)) |
- (((g >> (8 - PNG_DITHER_GREEN_BITS)) &
- ((1 << PNG_DITHER_GREEN_BITS) - 1)) <<
- (PNG_DITHER_BLUE_BITS)) |
- ((b >> (8 - PNG_DITHER_BLUE_BITS)) &
- ((1 << PNG_DITHER_BLUE_BITS) - 1));
-
- *dp++ = palette_lookup[p];
- }
- row_info->color_type = PNG_COLOR_TYPE_PALETTE;
- row_info->channels = 1;
- row_info->pixel_depth = row_info->bit_depth;
- row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,row_width);
- }
- else if (row_info->color_type == PNG_COLOR_TYPE_PALETTE &&
- dither_lookup && row_info->bit_depth == 8)
- {
- sp = row;
- for (i = 0; i < row_width; i++, sp++)
- {
- *sp = dither_lookup[*sp];
- }
- }
- }
- }
- #endif
-
- #ifdef PNG_FLOATING_POINT_SUPPORTED
- #if defined(PNG_READ_GAMMA_SUPPORTED)
- static PNG_CONST int png_gamma_shift[] =
- {0x10, 0x21, 0x42, 0x84, 0x110, 0x248, 0x550, 0xff0, 0x00};
-
- /* We build the 8- or 16-bit gamma tables here. Note that for 16-bit
- * tables, we don't make a full table if we are reducing to 8-bit in
- * the future. Note also how the gamma_16 tables are segmented so that
- * we don't need to allocate > 64K chunks for a full 16-bit table.
- */
- void /* PRIVATE */
- png_build_gamma_table(png_structp png_ptr)
- {
- png_debug(1, "in png_build_gamma_table\n");
-
- if (png_ptr->bit_depth <= 8)
- {
- int i;
- double g;
-
- if (png_ptr->screen_gamma > .000001)
- g = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
- else
- g = 1.0;
-
- png_ptr->gamma_table = (png_bytep)png_malloc(png_ptr,
- (png_uint_32)256);
-
- for (i = 0; i < 256; i++)
- {
- png_ptr->gamma_table[i] = (png_byte)(pow((double)i / 255.0,
- g) * 255.0 + .5);
- }
-
- #if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
- defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
- if (png_ptr->transformations & ((PNG_BACKGROUND) | PNG_RGB_TO_GRAY))
- {
-
- g = 1.0 / (png_ptr->gamma);
-
- png_ptr->gamma_to_1 = (png_bytep)png_malloc(png_ptr,
- (png_uint_32)256);
-
- for (i = 0; i < 256; i++)
- {
- png_ptr->gamma_to_1[i] = (png_byte)(pow((double)i / 255.0,
- g) * 255.0 + .5);
- }
-
- png_ptr->gamma_from_1 = (png_bytep)png_malloc(png_ptr,
- (png_uint_32)256);
-
- if(png_ptr->screen_gamma > 0.000001)
- g = 1.0 / png_ptr->screen_gamma;
- else
- g = png_ptr->gamma; /* probably doing rgb_to_gray */
-
- for (i = 0; i < 256; i++)
- {
- png_ptr->gamma_from_1[i] = (png_byte)(pow((double)i / 255.0,
- g) * 255.0 + .5);
-
- }
- }
- #endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_RGB_TO_GRAY_SUPPORTED */
- }
- else
- {
- double g;
- int i, j, shift, num;
- int sig_bit;
- png_uint_32 ig;
-
- if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
- {
- sig_bit = (int)png_ptr->sig_bit.red;
- if ((int)png_ptr->sig_bit.green > sig_bit)
- sig_bit = png_ptr->sig_bit.green;
- if ((int)png_ptr->sig_bit.blue > sig_bit)
- sig_bit = png_ptr->sig_bit.blue;
- }
- else
- {
- sig_bit = (int)png_ptr->sig_bit.gray;
- }
-
- if (sig_bit > 0)
- shift = 16 - sig_bit;
- else
- shift = 0;
-
- if (png_ptr->transformations & PNG_16_TO_8)
- {
- if (shift < (16 - PNG_MAX_GAMMA_8))
- shift = (16 - PNG_MAX_GAMMA_8);
- }
-
- if (shift > 8)
- shift = 8;
- if (shift < 0)
- shift = 0;
-
- png_ptr->gamma_shift = (png_byte)shift;
-
- num = (1 << (8 - shift));
-
- if (png_ptr->screen_gamma > .000001)
- g = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
- else
- g = 1.0;
-
- png_ptr->gamma_16_table = (png_uint_16pp)png_malloc(png_ptr,
- (png_uint_32)(num * png_sizeof (png_uint_16p)));
-
- if (png_ptr->transformations & (PNG_16_TO_8 | PNG_BACKGROUND))
- {
- double fin, fout;
- png_uint_32 last, max;
-
- for (i = 0; i < num; i++)
- {
- png_ptr->gamma_16_table[i] = (png_uint_16p)png_malloc(png_ptr,
- (png_uint_32)(256 * png_sizeof (png_uint_16)));
- }
-
- g = 1.0 / g;
- last = 0;
- for (i = 0; i < 256; i++)
- {
- fout = ((double)i + 0.5) / 256.0;
- fin = pow(fout, g);
- max = (png_uint_32)(fin * (double)((png_uint_32)num << 8));
- while (last <= max)
- {
- png_ptr->gamma_16_table[(int)(last & (0xff >> shift))]
- [(int)(last >> (8 - shift))] = (png_uint_16)(
- (png_uint_16)i | ((png_uint_16)i << 8));
- last++;
- }
- }
- while (last < ((png_uint_32)num << 8))
- {
- png_ptr->gamma_16_table[(int)(last & (0xff >> shift))]
- [(int)(last >> (8 - shift))] = (png_uint_16)65535L;
- last++;
- }
- }
- else
- {
- for (i = 0; i < num; i++)
- {
- png_ptr->gamma_16_table[i] = (png_uint_16p)png_malloc(png_ptr,
- (png_uint_32)(256 * png_sizeof (png_uint_16)));
-
- ig = (((png_uint_32)i * (png_uint_32)png_gamma_shift[shift]) >> 4);
- for (j = 0; j < 256; j++)
- {
- png_ptr->gamma_16_table[i][j] =
- (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) /
- 65535.0, g) * 65535.0 + .5);
- }
- }
- }
-
- #if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
- defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
- if (png_ptr->transformations & (PNG_BACKGROUND | PNG_RGB_TO_GRAY))
- {
-
- g = 1.0 / (png_ptr->gamma);
-
- png_ptr->gamma_16_to_1 = (png_uint_16pp)png_malloc(png_ptr,
- (png_uint_32)(num * png_sizeof (png_uint_16p )));
-
- for (i = 0; i < num; i++)
- {
- png_ptr->gamma_16_to_1[i] = (png_uint_16p)png_malloc(png_ptr,
- (png_uint_32)(256 * png_sizeof (png_uint_16)));
-
- ig = (((png_uint_32)i *
- (png_uint_32)png_gamma_shift[shift]) >> 4);
- for (j = 0; j < 256; j++)
- {
- png_ptr->gamma_16_to_1[i][j] =
- (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) /
- 65535.0, g) * 65535.0 + .5);
- }
- }
-
- if(png_ptr->screen_gamma > 0.000001)
- g = 1.0 / png_ptr->screen_gamma;
- else
- g = png_ptr->gamma; /* probably doing rgb_to_gray */
-
- png_ptr->gamma_16_from_1 = (png_uint_16pp)png_malloc(png_ptr,
- (png_uint_32)(num * png_sizeof (png_uint_16p)));
-
- for (i = 0; i < num; i++)
- {
- png_ptr->gamma_16_from_1[i] = (png_uint_16p)png_malloc(png_ptr,
- (png_uint_32)(256 * png_sizeof (png_uint_16)));
-
- ig = (((png_uint_32)i *
- (png_uint_32)png_gamma_shift[shift]) >> 4);
- for (j = 0; j < 256; j++)
- {
- png_ptr->gamma_16_from_1[i][j] =
- (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) /
- 65535.0, g) * 65535.0 + .5);
- }
- }
- }
- #endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_RGB_TO_GRAY_SUPPORTED */
- }
- }
- #endif
- /* To do: install integer version of png_build_gamma_table here */
- #endif
-
- #if defined(PNG_MNG_FEATURES_SUPPORTED)
- /* undoes intrapixel differencing */
- void /* PRIVATE */
- png_do_read_intrapixel(png_row_infop row_info, png_bytep row)
- {
- png_debug(1, "in png_do_read_intrapixel\n");
- if (
- #if defined(PNG_USELESS_TESTS_SUPPORTED)
- row != NULL && row_info != NULL &&
- #endif
- (row_info->color_type & PNG_COLOR_MASK_COLOR))
- {
- int bytes_per_pixel;
- png_uint_32 row_width = row_info->width;
- if (row_info->bit_depth == 8)
- {
- png_bytep rp;
- png_uint_32 i;
-
- if (row_info->color_type == PNG_COLOR_TYPE_RGB)
- bytes_per_pixel = 3;
- else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
- bytes_per_pixel = 4;
- else
- return;
-
- for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
- {
- *(rp) = (png_byte)((256 + *rp + *(rp+1))&0xff);
- *(rp+2) = (png_byte)((256 + *(rp+2) + *(rp+1))&0xff);
- }
- }
- else if (row_info->bit_depth == 16)
- {
- png_bytep rp;
- png_uint_32 i;
-
- if (row_info->color_type == PNG_COLOR_TYPE_RGB)
- bytes_per_pixel = 6;
- else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
- bytes_per_pixel = 8;
- else
- return;
-
- for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
- {
- png_uint_32 s0 = (*(rp ) << 8) | *(rp+1);
- png_uint_32 s1 = (*(rp+2) << 8) | *(rp+3);
- png_uint_32 s2 = (*(rp+4) << 8) | *(rp+5);
- png_uint_32 red = (png_uint_32)((s0+s1+65536L) & 0xffffL);
- png_uint_32 blue = (png_uint_32)((s2+s1+65536L) & 0xffffL);
- *(rp ) = (png_byte)((red >> 8) & 0xff);
- *(rp+1) = (png_byte)(red & 0xff);
- *(rp+4) = (png_byte)((blue >> 8) & 0xff);
- *(rp+5) = (png_byte)(blue & 0xff);
- }
- }
- }
- }
- #endif /* PNG_MNG_FEATURES_SUPPORTED */
- #endif /* PNG_READ_SUPPORTED */
- /********* End of inlined file: pngrtran.c *********/
-
- /********* Start of inlined file: pngrutil.c *********/
- /* pngrutil.c - utilities to read a PNG file
- *
- * Last changed in libpng 1.2.21 [October 4, 2007]
- * For conditions of distribution and use, see copyright notice in png.h
- * Copyright (c) 1998-2007 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
- *
- * This file contains routines that are only called from within
- * libpng itself during the course of reading an image.
- */
-
- #define PNG_INTERNAL
-
- #if defined(PNG_READ_SUPPORTED)
-
- #if defined(_WIN32_WCE) && (_WIN32_WCE<0x500)
- # define WIN32_WCE_OLD
- #endif
-
- #ifdef PNG_FLOATING_POINT_SUPPORTED
- # if defined(WIN32_WCE_OLD)
- /* strtod() function is not supported on WindowsCE */
- __inline double png_strtod(png_structp png_ptr, PNG_CONST char *nptr, char **endptr)
- {
- double result = 0;
- int len;
- wchar_t *str, *end;
-
- len = MultiByteToWideChar(CP_ACP, 0, nptr, -1, NULL, 0);
- str = (wchar_t *)png_malloc(png_ptr, len * sizeof(wchar_t));
- if ( NULL != str )
- {
- MultiByteToWideChar(CP_ACP, 0, nptr, -1, str, len);
- result = wcstod(str, &end);
- len = WideCharToMultiByte(CP_ACP, 0, end, -1, NULL, 0, NULL, NULL);
- *endptr = (char *)nptr + (png_strlen(nptr) - len + 1);
- png_free(png_ptr, str);
- }
- return result;
- }
- # else
- # define png_strtod(p,a,b) strtod(a,b)
- # endif
- #endif
-
- png_uint_32 PNGAPI
- png_get_uint_31(png_structp png_ptr, png_bytep buf)
- {
- png_uint_32 i = png_get_uint_32(buf);
- if (i > PNG_UINT_31_MAX)
- png_error(png_ptr, "PNG unsigned integer out of range.");
- return (i);
- }
- #ifndef PNG_READ_BIG_ENDIAN_SUPPORTED
- /* Grab an unsigned 32-bit integer from a buffer in big-endian format. */
- png_uint_32 PNGAPI
- png_get_uint_32(png_bytep buf)
- {
- png_uint_32 i = ((png_uint_32)(*buf) << 24) +
- ((png_uint_32)(*(buf + 1)) << 16) +
- ((png_uint_32)(*(buf + 2)) << 8) +
- (png_uint_32)(*(buf + 3));
-
- return (i);
- }
-
- /* Grab a signed 32-bit integer from a buffer in big-endian format. The
- * data is stored in the PNG file in two's complement format, and it is
- * assumed that the machine format for signed integers is the same. */
- png_int_32 PNGAPI
- png_get_int_32(png_bytep buf)
- {
- png_int_32 i = ((png_int_32)(*buf) << 24) +
- ((png_int_32)(*(buf + 1)) << 16) +
- ((png_int_32)(*(buf + 2)) << 8) +
- (png_int_32)(*(buf + 3));
-
- return (i);
- }
-
- /* Grab an unsigned 16-bit integer from a buffer in big-endian format. */
- png_uint_16 PNGAPI
- png_get_uint_16(png_bytep buf)
- {
- png_uint_16 i = (png_uint_16)(((png_uint_16)(*buf) << 8) +
- (png_uint_16)(*(buf + 1)));
-
- return (i);
- }
- #endif /* PNG_READ_BIG_ENDIAN_SUPPORTED */
-
- /* Read data, and (optionally) run it through the CRC. */
- void /* PRIVATE */
- png_crc_read(png_structp png_ptr, png_bytep buf, png_size_t length)
- {
- if(png_ptr == NULL) return;
- png_read_data(png_ptr, buf, length);
- png_calculate_crc(png_ptr, buf, length);
- }
-
- /* Optionally skip data and then check the CRC. Depending on whether we
- are reading a ancillary or critical chunk, and how the program has set
- things up, we may calculate the CRC on the data and print a message.
- Returns '1' if there was a CRC error, '0' otherwise. */
- int /* PRIVATE */
- png_crc_finish(png_structp png_ptr, png_uint_32 skip)
- {
- png_size_t i;
- png_size_t istop = png_ptr->zbuf_size;
-
- for (i = (png_size_t)skip; i > istop; i -= istop)
- {
- png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
- }
- if (i)
- {
- png_crc_read(png_ptr, png_ptr->zbuf, i);
- }
-
- if (png_crc_error(png_ptr))
- {
- if (((png_ptr->chunk_name[0] & 0x20) && /* Ancillary */
- !(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)) ||
- (!(png_ptr->chunk_name[0] & 0x20) && /* Critical */
- (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_USE)))
- {
- png_chunk_warning(png_ptr, "CRC error");
- }
- else
- {
- png_chunk_error(png_ptr, "CRC error");
- }
- return (1);
- }
-
- return (0);
- }
-
- /* Compare the CRC stored in the PNG file with that calculated by libpng from
- the data it has read thus far. */
- int /* PRIVATE */
- png_crc_error(png_structp png_ptr)
- {
- png_byte crc_bytes[4];
- png_uint_32 crc;
- int need_crc = 1;
-
- if (png_ptr->chunk_name[0] & 0x20) /* ancillary */
- {
- if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
- (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
- need_crc = 0;
- }
- else /* critical */
- {
- if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE)
- need_crc = 0;
- }
-
- png_read_data(png_ptr, crc_bytes, 4);
-
- if (need_crc)
- {
- crc = png_get_uint_32(crc_bytes);
- return ((int)(crc != png_ptr->crc));
- }
- else
- return (0);
- }
-
- #if defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) || \
- defined(PNG_READ_iCCP_SUPPORTED)
- /*
- * Decompress trailing data in a chunk. The assumption is that chunkdata
- * points at an allocated area holding the contents of a chunk with a
- * trailing compressed part. What we get back is an allocated area
- * holding the original prefix part and an uncompressed version of the
- * trailing part (the malloc area passed in is freed).
- */
- png_charp /* PRIVATE */
- png_decompress_chunk(png_structp png_ptr, int comp_type,
- png_charp chunkdata, png_size_t chunklength,
- png_size_t prefix_size, png_size_t *newlength)
- {
- static PNG_CONST char msg[] = "Error decoding compressed text";
- png_charp text;
- png_size_t text_size;
-
- if (comp_type == PNG_COMPRESSION_TYPE_BASE)
- {
- int ret = Z_OK;
- png_ptr->zstream.next_in = (png_bytep)(chunkdata + prefix_size);
- png_ptr->zstream.avail_in = (uInt)(chunklength - prefix_size);
- png_ptr->zstream.next_out = png_ptr->zbuf;
- png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
-
- text_size = 0;
- text = NULL;
-
- while (png_ptr->zstream.avail_in)
- {
- ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
- if (ret != Z_OK && ret != Z_STREAM_END)
- {
- if (png_ptr->zstream.msg != NULL)
- png_warning(png_ptr, png_ptr->zstream.msg);
- else
- png_warning(png_ptr, msg);
- inflateReset(&png_ptr->zstream);
- png_ptr->zstream.avail_in = 0;
-
- if (text == NULL)
- {
- text_size = prefix_size + png_sizeof(msg) + 1;
- text = (png_charp)png_malloc_warn(png_ptr, text_size);
- if (text == NULL)
- {
- png_free(png_ptr,chunkdata);
- png_error(png_ptr,"Not enough memory to decompress chunk");
- }
- png_memcpy(text, chunkdata, prefix_size);
- }
-
- text[text_size - 1] = 0x00;
-
- /* Copy what we can of the error message into the text chunk */
- text_size = (png_size_t)(chunklength - (text - chunkdata) - 1);
- text_size = png_sizeof(msg) > text_size ? text_size :
- png_sizeof(msg);
- png_memcpy(text + prefix_size, msg, text_size + 1);
- break;
- }
- if (!png_ptr->zstream.avail_out || ret == Z_STREAM_END)
- {
- if (text == NULL)
- {
- text_size = prefix_size +
- png_ptr->zbuf_size - png_ptr->zstream.avail_out;
- text = (png_charp)png_malloc_warn(png_ptr, text_size + 1);
- if (text == NULL)
- {
- png_free(png_ptr,chunkdata);
- png_error(png_ptr,"Not enough memory to decompress chunk.");
- }
- png_memcpy(text + prefix_size, png_ptr->zbuf,
- text_size - prefix_size);
- png_memcpy(text, chunkdata, prefix_size);
- *(text + text_size) = 0x00;
- }
- else
- {
- png_charp tmp;
-
- tmp = text;
- text = (png_charp)png_malloc_warn(png_ptr,
- (png_uint_32)(text_size +
- png_ptr->zbuf_size - png_ptr->zstream.avail_out + 1));
- if (text == NULL)
- {
- png_free(png_ptr, tmp);
- png_free(png_ptr, chunkdata);
- png_error(png_ptr,"Not enough memory to decompress chunk..");
- }
- png_memcpy(text, tmp, text_size);
- png_free(png_ptr, tmp);
- png_memcpy(text + text_size, png_ptr->zbuf,
- (png_ptr->zbuf_size - png_ptr->zstream.avail_out));
- text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out;
- *(text + text_size) = 0x00;
- }
- if (ret == Z_STREAM_END)
- break;
- else
- {
- png_ptr->zstream.next_out = png_ptr->zbuf;
- png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
- }
- }
- }
- if (ret != Z_STREAM_END)
- {
- #if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
- char umsg[52];
-
- if (ret == Z_BUF_ERROR)
- png_snprintf(umsg, 52,
- "Buffer error in compressed datastream in %s chunk",
- png_ptr->chunk_name);
- else if (ret == Z_DATA_ERROR)
- png_snprintf(umsg, 52,
- "Data error in compressed datastream in %s chunk",
- png_ptr->chunk_name);
- else
- png_snprintf(umsg, 52,
- "Incomplete compressed datastream in %s chunk",
- png_ptr->chunk_name);
- png_warning(png_ptr, umsg);
- #else
- png_warning(png_ptr,
- "Incomplete compressed datastream in chunk other than IDAT");
- #endif
- text_size=prefix_size;
- if (text == NULL)
- {
- text = (png_charp)png_malloc_warn(png_ptr, text_size+1);
- if (text == NULL)
- {
- png_free(png_ptr, chunkdata);
- png_error(png_ptr,"Not enough memory for text.");
- }
- png_memcpy(text, chunkdata, prefix_size);
- }
- *(text + text_size) = 0x00;
- }
-
- inflateReset(&png_ptr->zstream);
- png_ptr->zstream.avail_in = 0;
-
- png_free(png_ptr, chunkdata);
- chunkdata = text;
- *newlength=text_size;
- }
- else /* if (comp_type != PNG_COMPRESSION_TYPE_BASE) */
- {
- #if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
- char umsg[50];
-
- png_snprintf(umsg, 50,
- "Unknown zTXt compression type %d", comp_type);
- png_warning(png_ptr, umsg);
- #else
- png_warning(png_ptr, "Unknown zTXt compression type");
- #endif
-
- *(chunkdata + prefix_size) = 0x00;
- *newlength=prefix_size;
- }
-
- return chunkdata;
- }
- #endif
-
- /* read and check the IDHR chunk */
- void /* PRIVATE */
- png_handle_IHDR(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
- {
- png_byte buf[13];
- png_uint_32 width, height;
- int bit_depth, color_type, compression_type, filter_type;
- int interlace_type;
-
- png_debug(1, "in png_handle_IHDR\n");
-
- if (png_ptr->mode & PNG_HAVE_IHDR)
- png_error(png_ptr, "Out of place IHDR");
-
- /* check the length */
- if (length != 13)
- png_error(png_ptr, "Invalid IHDR chunk");
-
- png_ptr->mode |= PNG_HAVE_IHDR;
-
- png_crc_read(png_ptr, buf, 13);
- png_crc_finish(png_ptr, 0);
-
- width = png_get_uint_31(png_ptr, buf);
- height = png_get_uint_31(png_ptr, buf + 4);
- bit_depth = buf[8];
- color_type = buf[9];
- compression_type = buf[10];
- filter_type = buf[11];
- interlace_type = buf[12];
-
- /* set internal variables */
- png_ptr->width = width;
- png_ptr->height = height;
- png_ptr->bit_depth = (png_byte)bit_depth;
- png_ptr->interlaced = (png_byte)interlace_type;
- png_ptr->color_type = (png_byte)color_type;
- #if defined(PNG_MNG_FEATURES_SUPPORTED)
- png_ptr->filter_type = (png_byte)filter_type;
- #endif
- png_ptr->compression_type = (png_byte)compression_type;
-
- /* find number of channels */
- switch (png_ptr->color_type)
- {
- case PNG_COLOR_TYPE_GRAY:
- case PNG_COLOR_TYPE_PALETTE:
- png_ptr->channels = 1;
- break;
- case PNG_COLOR_TYPE_RGB:
- png_ptr->channels = 3;
- break;
- case PNG_COLOR_TYPE_GRAY_ALPHA:
- png_ptr->channels = 2;
- break;
- case PNG_COLOR_TYPE_RGB_ALPHA:
- png_ptr->channels = 4;
- break;
- }
-
- /* set up other useful info */
- png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth *
- png_ptr->channels);
- png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth,png_ptr->width);
- png_debug1(3,"bit_depth = %d\n", png_ptr->bit_depth);
- png_debug1(3,"channels = %d\n", png_ptr->channels);
- png_debug1(3,"rowbytes = %lu\n", png_ptr->rowbytes);
- png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth,
- color_type, interlace_type, compression_type, filter_type);
- }
-
- /* read and check the palette */
- void /* PRIVATE */
- png_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
- {
- png_color palette[PNG_MAX_PALETTE_LENGTH];
- int num, i;
- #ifndef PNG_NO_POINTER_INDEXING
- png_colorp pal_ptr;
- #endif
-
- png_debug(1, "in png_handle_PLTE\n");
-
- if (!(png_ptr->mode & PNG_HAVE_IHDR))
- png_error(png_ptr, "Missing IHDR before PLTE");
- else if (png_ptr->mode & PNG_HAVE_IDAT)
- {
- png_warning(png_ptr, "Invalid PLTE after IDAT");
- png_crc_finish(png_ptr, length);
- return;
- }
- else if (png_ptr->mode & PNG_HAVE_PLTE)
- png_error(png_ptr, "Duplicate PLTE chunk");
-
- png_ptr->mode |= PNG_HAVE_PLTE;
-
- if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR))
- {
- png_warning(png_ptr,
- "Ignoring PLTE chunk in grayscale PNG");
- png_crc_finish(png_ptr, length);
- return;
- }
- #if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
- if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
- {
- png_crc_finish(png_ptr, length);
- return;
- }
- #endif
-
- if (length > 3*PNG_MAX_PALETTE_LENGTH || length % 3)
- {
- if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
- {
- png_warning(png_ptr, "Invalid palette chunk");
- png_crc_finish(png_ptr, length);
- return;
- }
- else
- {
- png_error(png_ptr, "Invalid palette chunk");
- }
- }
-
- num = (int)length / 3;
-
- #ifndef PNG_NO_POINTER_INDEXING
- for (i = 0, pal_ptr = palette; i < num; i++, pal_ptr++)
- {
- png_byte buf[3];
-
- png_crc_read(png_ptr, buf, 3);
- pal_ptr->red = buf[0];
- pal_ptr->green = buf[1];
- pal_ptr->blue = buf[2];
- }
- #else
- for (i = 0; i < num; i++)
- {
- png_byte buf[3];
-
- png_crc_read(png_ptr, buf, 3);
- /* don't depend upon png_color being any order */
- palette[i].red = buf[0];
- palette[i].green = buf[1];
- palette[i].blue = buf[2];
- }
- #endif
-
- /* If we actually NEED the PLTE chunk (ie for a paletted image), we do
- whatever the normal CRC configuration tells us. However, if we
- have an RGB image, the PLTE can be considered ancillary, so
- we will act as though it is. */
- #if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
- if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
- #endif
- {
- png_crc_finish(png_ptr, 0);
- }
- #if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
- else if (png_crc_error(png_ptr)) /* Only if we have a CRC error */
- {
- /* If we don't want to use the data from an ancillary chunk,
- we have two options: an error abort, or a warning and we
- ignore the data in this chunk (which should be OK, since
- it's considered ancillary for a RGB or RGBA image). */
- if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_USE))
- {
- if (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)
- {
- png_chunk_error(png_ptr, "CRC error");
- }
- else
- {
- png_chunk_warning(png_ptr, "CRC error");
- return;
- }
- }
- /* Otherwise, we (optionally) emit a warning and use the chunk. */
- else if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN))
- {
- png_chunk_warning(png_ptr, "CRC error");
- }
- }
- #endif
-
- png_set_PLTE(png_ptr, info_ptr, palette, num);
-
- #if defined(PNG_READ_tRNS_SUPPORTED)
- if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
- {
- if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
- {
- if (png_ptr->num_trans > (png_uint_16)num)
- {
- png_warning(png_ptr, "Truncating incorrect tRNS chunk length");
- png_ptr->num_trans = (png_uint_16)num;
- }
- if (info_ptr->num_trans > (png_uint_16)num)
- {
- png_warning(png_ptr, "Truncating incorrect info tRNS chunk length");
- info_ptr->num_trans = (png_uint_16)num;
- }
- }
- }
- #endif
-
- }
-
- void /* PRIVATE */
- png_handle_IEND(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
- {
- png_debug(1, "in png_handle_IEND\n");
-
- if (!(png_ptr->mode & PNG_HAVE_IHDR) || !(png_ptr->mode & PNG_HAVE_IDAT))
- {
- png_error(png_ptr, "No image in file");
- }
-
- png_ptr->mode |= (PNG_AFTER_IDAT | PNG_HAVE_IEND);
-
- if (length != 0)
- {
- png_warning(png_ptr, "Incorrect IEND chunk length");
- }
- png_crc_finish(png_ptr, length);
-
- info_ptr =info_ptr; /* quiet compiler warnings about unused info_ptr */
- }
-
- #if defined(PNG_READ_gAMA_SUPPORTED)
- void /* PRIVATE */
- png_handle_gAMA(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
- {
- png_fixed_point igamma;
- #ifdef PNG_FLOATING_POINT_SUPPORTED
- float file_gamma;
- #endif
- png_byte buf[4];
-
- png_debug(1, "in png_handle_gAMA\n");
-
- if (!(png_ptr->mode & PNG_HAVE_IHDR))
- png_error(png_ptr, "Missing IHDR before gAMA");
- else if (png_ptr->mode & PNG_HAVE_IDAT)
- {
- png_warning(png_ptr, "Invalid gAMA after IDAT");
- png_crc_finish(png_ptr, length);
- return;
- }
- else if (png_ptr->mode & PNG_HAVE_PLTE)
- /* Should be an error, but we can cope with it */
- png_warning(png_ptr, "Out of place gAMA chunk");
-
- if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)
- #if defined(PNG_READ_sRGB_SUPPORTED)
- && !(info_ptr->valid & PNG_INFO_sRGB)
- #endif
- )
- {
- png_warning(png_ptr, "Duplicate gAMA chunk");
- png_crc_finish(png_ptr, length);
- return;
- }
-
- if (length != 4)
- {
- png_warning(png_ptr, "Incorrect gAMA chunk length");
- png_crc_finish(png_ptr, length);
- return;
- }
-
- png_crc_read(png_ptr, buf, 4);
- if (png_crc_finish(png_ptr, 0))
- return;
-
- igamma = (png_fixed_point)png_get_uint_32(buf);
- /* check for zero gamma */
- if (igamma == 0)
- {
- png_warning(png_ptr,
- "Ignoring gAMA chunk with gamma=0");
- return;
- }
-
- #if defined(PNG_READ_sRGB_SUPPORTED)
- if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB))
- if (PNG_OUT_OF_RANGE(igamma, 45500L, 500))
- {
- png_warning(png_ptr,
- "Ignoring incorrect gAMA value when sRGB is also present");
- #ifndef PNG_NO_CONSOLE_IO
- fprintf(stderr, "gamma = (%d/100000)\n", (int)igamma);
- #endif
- return;
- }
- #endif /* PNG_READ_sRGB_SUPPORTED */
-
- #ifdef PNG_FLOATING_POINT_SUPPORTED
- file_gamma = (float)igamma / (float)100000.0;
- # ifdef PNG_READ_GAMMA_SUPPORTED
- png_ptr->gamma = file_gamma;
- # endif
- png_set_gAMA(png_ptr, info_ptr, file_gamma);
- #endif
- #ifdef PNG_FIXED_POINT_SUPPORTED
- png_set_gAMA_fixed(png_ptr, info_ptr, igamma);
- #endif
- }
- #endif
-
- #if defined(PNG_READ_sBIT_SUPPORTED)
- void /* PRIVATE */
- png_handle_sBIT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
- {
- png_size_t truelen;
- png_byte buf[4];
-
- png_debug(1, "in png_handle_sBIT\n");
-
- buf[0] = buf[1] = buf[2] = buf[3] = 0;
-
- if (!(png_ptr->mode & PNG_HAVE_IHDR))
- png_error(png_ptr, "Missing IHDR before sBIT");
- else if (png_ptr->mode & PNG_HAVE_IDAT)
- {
- png_warning(png_ptr, "Invalid sBIT after IDAT");
- png_crc_finish(png_ptr, length);
- return;
- }
- else if (png_ptr->mode & PNG_HAVE_PLTE)
- {
- /* Should be an error, but we can cope with it */
- png_warning(png_ptr, "Out of place sBIT chunk");
- }
- if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT))
- {
- png_warning(png_ptr, "Duplicate sBIT chunk");
- png_crc_finish(png_ptr, length);
- return;
- }
-
- if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
- truelen = 3;
- else
- truelen = (png_size_t)png_ptr->channels;
-
- if (length != truelen || length > 4)
- {
- png_warning(png_ptr, "Incorrect sBIT chunk length");
- png_crc_finish(png_ptr, length);
- return;
- }
-
- png_crc_read(png_ptr, buf, truelen);
- if (png_crc_finish(png_ptr, 0))
- return;
-
- if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
- {
- png_ptr->sig_bit.red = buf[0];
- png_ptr->sig_bit.green = buf[1];
- png_ptr->sig_bit.blue = buf[2];
- png_ptr->sig_bit.alpha = buf[3];
- }
- else
- {
- png_ptr->sig_bit.gray = buf[0];
- png_ptr->sig_bit.red = buf[0];
- png_ptr->sig_bit.green = buf[0];
- png_ptr->sig_bit.blue = buf[0];
- png_ptr->sig_bit.alpha = buf[1];
- }
- png_set_sBIT(png_ptr, info_ptr, &(png_ptr->sig_bit));
- }
- #endif
-
- #if defined(PNG_READ_cHRM_SUPPORTED)
- void /* PRIVATE */
- png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
- {
- png_byte buf[4];
- #ifdef PNG_FLOATING_POINT_SUPPORTED
- float white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y;
- #endif
- png_fixed_point int_x_white, int_y_white, int_x_red, int_y_red, int_x_green,
- int_y_green, int_x_blue, int_y_blue;
-
- png_uint_32 uint_x, uint_y;
-
- png_debug(1, "in png_handle_cHRM\n");
-
- if (!(png_ptr->mode & PNG_HAVE_IHDR))
- png_error(png_ptr, "Missing IHDR before cHRM");
- else if (png_ptr->mode & PNG_HAVE_IDAT)
- {
- png_warning(png_ptr, "Invalid cHRM after IDAT");
- png_crc_finish(png_ptr, length);
- return;
- }
- else if (png_ptr->mode & PNG_HAVE_PLTE)
- /* Should be an error, but we can cope with it */
- png_warning(png_ptr, "Missing PLTE before cHRM");
-
- if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)
- #if defined(PNG_READ_sRGB_SUPPORTED)
- && !(info_ptr->valid & PNG_INFO_sRGB)
- #endif
- )
- {
- png_warning(png_ptr, "Duplicate cHRM chunk");
- png_crc_finish(png_ptr, length);
- return;
- }
-
- if (length != 32)
- {
- png_warning(png_ptr, "Incorrect cHRM chunk length");
- png_crc_finish(png_ptr, length);
- return;
- }
-
- png_crc_read(png_ptr, buf, 4);
- uint_x = png_get_uint_32(buf);
-
- png_crc_read(png_ptr, buf, 4);
- uint_y = png_get_uint_32(buf);
-
- if (uint_x > 80000L || uint_y > 80000L ||
- uint_x + uint_y > 100000L)
- {
- png_warning(png_ptr, "Invalid cHRM white point");
- png_crc_finish(png_ptr, 24);
- return;
- }
- int_x_white = (png_fixed_point)uint_x;
- int_y_white = (png_fixed_point)uint_y;
-
- png_crc_read(png_ptr, buf, 4);
- uint_x = png_get_uint_32(buf);
-
- png_crc_read(png_ptr, buf, 4);
- uint_y = png_get_uint_32(buf);
-
- if (uint_x + uint_y > 100000L)
- {
- png_warning(png_ptr, "Invalid cHRM red point");
- png_crc_finish(png_ptr, 16);
- return;
- }
- int_x_red = (png_fixed_point)uint_x;
- int_y_red = (png_fixed_point)uint_y;
-
- png_crc_read(png_ptr, buf, 4);
- uint_x = png_get_uint_32(buf);
-
- png_crc_read(png_ptr, buf, 4);
- uint_y = png_get_uint_32(buf);
-
- if (uint_x + uint_y > 100000L)
- {
- png_warning(png_ptr, "Invalid cHRM green point");
- png_crc_finish(png_ptr, 8);
- return;
- }
- int_x_green = (png_fixed_point)uint_x;
- int_y_green = (png_fixed_point)uint_y;
-
- png_crc_read(png_ptr, buf, 4);
- uint_x = png_get_uint_32(buf);
-
- png_crc_read(png_ptr, buf, 4);
- uint_y = png_get_uint_32(buf);
-
- if (uint_x + uint_y > 100000L)
- {
- png_warning(png_ptr, "Invalid cHRM blue point");
- png_crc_finish(png_ptr, 0);
- return;
- }
- int_x_blue = (png_fixed_point)uint_x;
- int_y_blue = (png_fixed_point)uint_y;
-
- #ifdef PNG_FLOATING_POINT_SUPPORTED
- white_x = (float)int_x_white / (float)100000.0;
- white_y = (float)int_y_white / (float)100000.0;
- red_x = (float)int_x_red / (float)100000.0;
- red_y = (float)int_y_red / (float)100000.0;
- green_x = (float)int_x_green / (float)100000.0;
- green_y = (float)int_y_green / (float)100000.0;
- blue_x = (float)int_x_blue / (float)100000.0;
- blue_y = (float)int_y_blue / (float)100000.0;
- #endif
-
- #if defined(PNG_READ_sRGB_SUPPORTED)
- if ((info_ptr != NULL) && (info_ptr->valid & PNG_INFO_sRGB))
- {
- if (PNG_OUT_OF_RANGE(int_x_white, 31270, 1000) ||
- PNG_OUT_OF_RANGE(int_y_white, 32900, 1000) ||
- PNG_OUT_OF_RANGE(int_x_red, 64000L, 1000) ||
- PNG_OUT_OF_RANGE(int_y_red, 33000, 1000) ||
- PNG_OUT_OF_RANGE(int_x_green, 30000, 1000) ||
- PNG_OUT_OF_RANGE(int_y_green, 60000L, 1000) ||
- PNG_OUT_OF_RANGE(int_x_blue, 15000, 1000) ||
- PNG_OUT_OF_RANGE(int_y_blue, 6000, 1000))
- {
- png_warning(png_ptr,
- "Ignoring incorrect cHRM value when sRGB is also present");
- #ifndef PNG_NO_CONSOLE_IO
- #ifdef PNG_FLOATING_POINT_SUPPORTED
- fprintf(stderr,"wx=%f, wy=%f, rx=%f, ry=%f\n",
- white_x, white_y, red_x, red_y);
- fprintf(stderr,"gx=%f, gy=%f, bx=%f, by=%f\n",
- green_x, green_y, blue_x, blue_y);
- #else
- fprintf(stderr,"wx=%ld, wy=%ld, rx=%ld, ry=%ld\n",
- int_x_white, int_y_white, int_x_red, int_y_red);
- fprintf(stderr,"gx=%ld, gy=%ld, bx=%ld, by=%ld\n",
- int_x_green, int_y_green, int_x_blue, int_y_blue);
- #endif
- #endif /* PNG_NO_CONSOLE_IO */
- }
- png_crc_finish(png_ptr, 0);
- return;
- }
- #endif /* PNG_READ_sRGB_SUPPORTED */
-
- #ifdef PNG_FLOATING_POINT_SUPPORTED
- png_set_cHRM(png_ptr, info_ptr,
- white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y);
- #endif
- #ifdef PNG_FIXED_POINT_SUPPORTED
- png_set_cHRM_fixed(png_ptr, info_ptr,
- int_x_white, int_y_white, int_x_red, int_y_red, int_x_green,
- int_y_green, int_x_blue, int_y_blue);
- #endif
- if (png_crc_finish(png_ptr, 0))
- return;
- }
- #endif
-
- #if defined(PNG_READ_sRGB_SUPPORTED)
- void /* PRIVATE */
- png_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
- {
- int intent;
- png_byte buf[1];
-
- png_debug(1, "in png_handle_sRGB\n");
-
- if (!(png_ptr->mode & PNG_HAVE_IHDR))
- png_error(png_ptr, "Missing IHDR before sRGB");
- else if (png_ptr->mode & PNG_HAVE_IDAT)
- {
- png_warning(png_ptr, "Invalid sRGB after IDAT");
- png_crc_finish(png_ptr, length);
- return;
- }
- else if (png_ptr->mode & PNG_HAVE_PLTE)
- /* Should be an error, but we can cope with it */
- png_warning(png_ptr, "Out of place sRGB chunk");
-
- if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB))
- {
- png_warning(png_ptr, "Duplicate sRGB chunk");
- png_crc_finish(png_ptr, length);
- return;
- }
-
- if (length != 1)
- {
- png_warning(png_ptr, "Incorrect sRGB chunk length");
- png_crc_finish(png_ptr, length);
- return;
- }
-
- png_crc_read(png_ptr, buf, 1);
- if (png_crc_finish(png_ptr, 0))
- return;
-
- intent = buf[0];
- /* check for bad intent */
- if (intent >= PNG_sRGB_INTENT_LAST)
- {
- png_warning(png_ptr, "Unknown sRGB intent");
- return;
- }
-
- #if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
- if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA))
- {
- png_fixed_point igamma;
- #ifdef PNG_FIXED_POINT_SUPPORTED
- igamma=info_ptr->int_gamma;
- #else
- # ifdef PNG_FLOATING_POINT_SUPPORTED
- igamma=(png_fixed_point)(info_ptr->gamma * 100000.);
- # endif
- #endif
- if (PNG_OUT_OF_RANGE(igamma, 45500L, 500))
- {
- png_warning(png_ptr,
- "Ignoring incorrect gAMA value when sRGB is also present");
- #ifndef PNG_NO_CONSOLE_IO
- # ifdef PNG_FIXED_POINT_SUPPORTED
- fprintf(stderr,"incorrect gamma=(%d/100000)\n",(int)png_ptr->int_gamma);
- # else
- # ifdef PNG_FLOATING_POINT_SUPPORTED
- fprintf(stderr,"incorrect gamma=%f\n",png_ptr->gamma);
- # endif
- # endif
- #endif
- }
- }
- #endif /* PNG_READ_gAMA_SUPPORTED */
-
- #ifdef PNG_READ_cHRM_SUPPORTED
- #ifdef PNG_FIXED_POINT_SUPPORTED
- if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM))
- if (PNG_OUT_OF_RANGE(info_ptr->int_x_white, 31270, 1000) ||
- PNG_OUT_OF_RANGE(info_ptr->int_y_white, 32900, 1000) ||
- PNG_OUT_OF_RANGE(info_ptr->int_x_red, 64000L, 1000) ||
- PNG_OUT_OF_RANGE(info_ptr->int_y_red, 33000, 1000) ||
- PNG_OUT_OF_RANGE(info_ptr->int_x_green, 30000, 1000) ||
- PNG_OUT_OF_RANGE(info_ptr->int_y_green, 60000L, 1000) ||
- PNG_OUT_OF_RANGE(info_ptr->int_x_blue, 15000, 1000) ||
- PNG_OUT_OF_RANGE(info_ptr->int_y_blue, 6000, 1000))
- {
- png_warning(png_ptr,
- "Ignoring incorrect cHRM value when sRGB is also present");
- }
- #endif /* PNG_FIXED_POINT_SUPPORTED */
- #endif /* PNG_READ_cHRM_SUPPORTED */
-
- png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr, intent);
- }
- #endif /* PNG_READ_sRGB_SUPPORTED */
-
- #if defined(PNG_READ_iCCP_SUPPORTED)
- void /* PRIVATE */
- png_handle_iCCP(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
- /* Note: this does not properly handle chunks that are > 64K under DOS */
- {
- png_charp chunkdata;
- png_byte compression_type;
- png_bytep pC;
- png_charp profile;
- png_uint_32 skip = 0;
- png_uint_32 profile_size, profile_length;
- png_size_t slength, prefix_length, data_length;
-
- png_debug(1, "in png_handle_iCCP\n");
-
- if (!(png_ptr->mode & PNG_HAVE_IHDR))
- png_error(png_ptr, "Missing IHDR before iCCP");
- else if (png_ptr->mode & PNG_HAVE_IDAT)
- {
- png_warning(png_ptr, "Invalid iCCP after IDAT");
- png_crc_finish(png_ptr, length);
- return;
- }
- else if (png_ptr->mode & PNG_HAVE_PLTE)
- /* Should be an error, but we can cope with it */
- png_warning(png_ptr, "Out of place iCCP chunk");
-
- if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP))
- {
- png_warning(png_ptr, "Duplicate iCCP chunk");
- png_crc_finish(png_ptr, length);
- return;
- }
-
- #ifdef PNG_MAX_MALLOC_64K
- if (length > (png_uint_32)65535L)
- {
- png_warning(png_ptr, "iCCP chunk too large to fit in memory");
- skip = length - (png_uint_32)65535L;
- length = (png_uint_32)65535L;
- }
- #endif
-
- chunkdata = (png_charp)png_malloc(png_ptr, length + 1);
- slength = (png_size_t)length;
- png_crc_read(png_ptr, (png_bytep)chunkdata, slength);
-
- if (png_crc_finish(png_ptr, skip))
- {
- png_free(png_ptr, chunkdata);
- return;
- }
-
- chunkdata[slength] = 0x00;
-
- for (profile = chunkdata; *profile; profile++)
- /* empty loop to find end of name */ ;
-
- ++profile;
-
- /* there should be at least one zero (the compression type byte)
- following the separator, and we should be on it */
- if ( profile >= chunkdata + slength - 1)
- {
- png_free(png_ptr, chunkdata);
- png_warning(png_ptr, "Malformed iCCP chunk");
- return;
- }
-
- /* compression_type should always be zero */
- compression_type = *profile++;
- if (compression_type)
- {
- png_warning(png_ptr, "Ignoring nonzero compression type in iCCP chunk");
- compression_type=0x00; /* Reset it to zero (libpng-1.0.6 through 1.0.8
- wrote nonzero) */
- }
-
- prefix_length = profile - chunkdata;
- chunkdata = png_decompress_chunk(png_ptr, compression_type, chunkdata,
- slength, prefix_length, &data_length);
-
- profile_length = data_length - prefix_length;
-
- if ( prefix_length > data_length || profile_length < 4)
- {
- png_free(png_ptr, chunkdata);
- png_warning(png_ptr, "Profile size field missing from iCCP chunk");
- return;
- }
-
- /* Check the profile_size recorded in the first 32 bits of the ICC profile */
- pC = (png_bytep)(chunkdata+prefix_length);
- profile_size = ((*(pC ))<<24) |
- ((*(pC+1))<<16) |
- ((*(pC+2))<< 8) |
- ((*(pC+3)) );
-
- if(profile_size < profile_length)
- profile_length = profile_size;
-
- if(profile_size > profile_length)
- {
- png_free(png_ptr, chunkdata);
- png_warning(png_ptr, "Ignoring truncated iCCP profile.");
- return;
- }
-
- png_set_iCCP(png_ptr, info_ptr, chunkdata, compression_type,
- chunkdata + prefix_length, profile_length);
- png_free(png_ptr, chunkdata);
- }
- #endif /* PNG_READ_iCCP_SUPPORTED */
-
- #if defined(PNG_READ_sPLT_SUPPORTED)
- void /* PRIVATE */
- png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
- /* Note: this does not properly handle chunks that are > 64K under DOS */
- {
- png_bytep chunkdata;
- png_bytep entry_start;
- png_sPLT_t new_palette;
- #ifdef PNG_NO_POINTER_INDEXING
- png_sPLT_entryp pp;
- #endif
- int data_length, entry_size, i;
- png_uint_32 skip = 0;
- png_size_t slength;
-
- png_debug(1, "in png_handle_sPLT\n");
-
- if (!(png_ptr->mode & PNG_HAVE_IHDR))
- png_error(png_ptr, "Missing IHDR before sPLT");
- else if (png_ptr->mode & PNG_HAVE_IDAT)
- {
- png_warning(png_ptr, "Invalid sPLT after IDAT");
- png_crc_finish(png_ptr, length);
- return;
- }
-
- #ifdef PNG_MAX_MALLOC_64K
- if (length > (png_uint_32)65535L)
- {
- png_warning(png_ptr, "sPLT chunk too large to fit in memory");
- skip = length - (png_uint_32)65535L;
- length = (png_uint_32)65535L;
- }
- #endif
-
- chunkdata = (png_bytep)png_malloc(png_ptr, length + 1);
- slength = (png_size_t)length;
- png_crc_read(png_ptr, (png_bytep)chunkdata, slength);
-
- if (png_crc_finish(png_ptr, skip))
- {
- png_free(png_ptr, chunkdata);
- return;
- }
-
- chunkdata[slength] = 0x00;
-
- for (entry_start = chunkdata; *entry_start; entry_start++)
- /* empty loop to find end of name */ ;
- ++entry_start;
-
- /* a sample depth should follow the separator, and we should be on it */
- if (entry_start > chunkdata + slength - 2)
- {
- png_free(png_ptr, chunkdata);
- png_warning(png_ptr, "malformed sPLT chunk");
- return;
- }
-
- new_palette.depth = *entry_start++;
- entry_size = (new_palette.depth == 8 ? 6 : 10);
- data_length = (slength - (entry_start - chunkdata));
-
- /* integrity-check the data length */
- if (data_length % entry_size)
- {
- png_free(png_ptr, chunkdata);
- png_warning(png_ptr, "sPLT chunk has bad length");
- return;
- }
-
- new_palette.nentries = (png_int_32) ( data_length / entry_size);
- if ((png_uint_32) new_palette.nentries > (png_uint_32) (PNG_SIZE_MAX /
- png_sizeof(png_sPLT_entry)))
- {
- png_warning(png_ptr, "sPLT chunk too long");
- return;
- }
- new_palette.entries = (png_sPLT_entryp)png_malloc_warn(
- png_ptr, new_palette.nentries * png_sizeof(png_sPLT_entry));
- if (new_palette.entries == NULL)
- {
- png_warning(png_ptr, "sPLT chunk requires too much memory");
- return;
- }
-
- #ifndef PNG_NO_POINTER_INDEXING
- for (i = 0; i < new_palette.nentries; i++)
- {
- png_sPLT_entryp pp = new_palette.entries + i;
-
- if (new_palette.depth == 8)
- {
- pp->red = *entry_start++;
- pp->green = *entry_start++;
- pp->blue = *entry_start++;
- pp->alpha = *entry_start++;
- }
- else
- {
- pp->red = png_get_uint_16(entry_start); entry_start += 2;
- pp->green = png_get_uint_16(entry_start); entry_start += 2;
- pp->blue = png_get_uint_16(entry_start); entry_start += 2;
- pp->alpha = png_get_uint_16(entry_start); entry_start += 2;
- }
- pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
- }
- #else
- pp = new_palette.entries;
- for (i = 0; i < new_palette.nentries; i++)
- {
-
- if (new_palette.depth == 8)
- {
- pp[i].red = *entry_start++;
- pp[i].green = *entry_start++;
- pp[i].blue = *entry_start++;
- pp[i].alpha = *entry_start++;
- }
- else
- {
- pp[i].red = png_get_uint_16(entry_start); entry_start += 2;
- pp[i].green = png_get_uint_16(entry_start); entry_start += 2;
- pp[i].blue = png_get_uint_16(entry_start); entry_start += 2;
- pp[i].alpha = png_get_uint_16(entry_start); entry_start += 2;
- }
- pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
- }
- #endif
-
- /* discard all chunk data except the name and stash that */
- new_palette.name = (png_charp)chunkdata;
-
- png_set_sPLT(png_ptr, info_ptr, &new_palette, 1);
-
- png_free(png_ptr, chunkdata);
- png_free(png_ptr, new_palette.entries);
- }
- #endif /* PNG_READ_sPLT_SUPPORTED */
-
- #if defined(PNG_READ_tRNS_SUPPORTED)
- void /* PRIVATE */
- png_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
- {
- png_byte readbuf[PNG_MAX_PALETTE_LENGTH];
- int bit_mask;
-
- png_debug(1, "in png_handle_tRNS\n");
-
- /* For non-indexed color, mask off any bits in the tRNS value that
- * exceed the bit depth. Some creators were writing extra bits there.
- * This is not needed for indexed color. */
- bit_mask = (1 << png_ptr->bit_depth) - 1;
-
- if (!(png_ptr->mode & PNG_HAVE_IHDR))
- png_error(png_ptr, "Missing IHDR before tRNS");
- else if (png_ptr->mode & PNG_HAVE_IDAT)
- {
- png_warning(png_ptr, "Invalid tRNS after IDAT");
- png_crc_finish(png_ptr, length);
- return;
- }
- else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
- {
- png_warning(png_ptr, "Duplicate tRNS chunk");
- png_crc_finish(png_ptr, length);
- return;
- }
-
- if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
- {
- png_byte buf[2];
-
- if (length != 2)
- {
- png_warning(png_ptr, "Incorrect tRNS chunk length");
- png_crc_finish(png_ptr, length);
- return;
- }
-
- png_crc_read(png_ptr, buf, 2);
- png_ptr->num_trans = 1;
- png_ptr->trans_values.gray = png_get_uint_16(buf) & bit_mask;
- }
- else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
- {
- png_byte buf[6];
-
- if (length != 6)
- {
- png_warning(png_ptr, "Incorrect tRNS chunk length");
- png_crc_finish(png_ptr, length);
- return;
- }
- png_crc_read(png_ptr, buf, (png_size_t)length);
- png_ptr->num_trans = 1;
- png_ptr->trans_values.red = png_get_uint_16(buf) & bit_mask;
- png_ptr->trans_values.green = png_get_uint_16(buf + 2) & bit_mask;
- png_ptr->trans_values.blue = png_get_uint_16(buf + 4) & bit_mask;
- }
- else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
- {
- if (!(png_ptr->mode & PNG_HAVE_PLTE))
- {
- /* Should be an error, but we can cope with it. */
- png_warning(png_ptr, "Missing PLTE before tRNS");
- }
- if (length > (png_uint_32)png_ptr->num_palette ||
- length > PNG_MAX_PALETTE_LENGTH)
- {
- png_warning(png_ptr, "Incorrect tRNS chunk length");
- png_crc_finish(png_ptr, length);
- return;
- }
- if (length == 0)
- {
- png_warning(png_ptr, "Zero length tRNS chunk");
- png_crc_finish(png_ptr, length);
- return;
- }
- png_crc_read(png_ptr, readbuf, (png_size_t)length);
- png_ptr->num_trans = (png_uint_16)length;
- }
- else
- {
- png_warning(png_ptr, "tRNS chunk not allowed with alpha channel");
- png_crc_finish(png_ptr, length);
- return;
- }
-
- if (png_crc_finish(png_ptr, 0))
- {
- png_ptr->num_trans = 0;
- return;
- }
-
- png_set_tRNS(png_ptr, info_ptr, readbuf, png_ptr->num_trans,
- &(png_ptr->trans_values));
- }
- #endif
-
- #if defined(PNG_READ_bKGD_SUPPORTED)
- void /* PRIVATE */
- png_handle_bKGD(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
- {
- png_size_t truelen;
- png_byte buf[6];
-
- png_debug(1, "in png_handle_bKGD\n");
-
- if (!(png_ptr->mode & PNG_HAVE_IHDR))
- png_error(png_ptr, "Missing IHDR before bKGD");
- else if (png_ptr->mode & PNG_HAVE_IDAT)
- {
- png_warning(png_ptr, "Invalid bKGD after IDAT");
- png_crc_finish(png_ptr, length);
- return;
- }
- else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
- !(png_ptr->mode & PNG_HAVE_PLTE))
- {
- png_warning(png_ptr, "Missing PLTE before bKGD");
- png_crc_finish(png_ptr, length);
- return;
- }
- else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD))
- {
- png_warning(png_ptr, "Duplicate bKGD chunk");
- png_crc_finish(png_ptr, length);
- return;
- }
-
- if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
- truelen = 1;
- else if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
- truelen = 6;
- else
- truelen = 2;
-
- if (length != truelen)
- {
- png_warning(png_ptr, "Incorrect bKGD chunk length");
- png_crc_finish(png_ptr, length);
- return;
- }
-
- png_crc_read(png_ptr, buf, truelen);
- if (png_crc_finish(png_ptr, 0))
- return;
-
- /* We convert the index value into RGB components so that we can allow
- * arbitrary RGB values for background when we have transparency, and
- * so it is easy to determine the RGB values of the background color
- * from the info_ptr struct. */
- if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
- {
- png_ptr->background.index = buf[0];
- if(info_ptr->num_palette)
- {
- if(buf[0] > info_ptr->num_palette)
- {
- png_warning(png_ptr, "Incorrect bKGD chunk index value");
- return;
- }
- png_ptr->background.red =
- (png_uint_16)png_ptr->palette[buf[0]].red;
- png_ptr->background.green =
- (png_uint_16)png_ptr->palette[buf[0]].green;
- png_ptr->background.blue =
- (png_uint_16)png_ptr->palette[buf[0]].blue;
- }
- }
- else if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) /* GRAY */
- {
- png_ptr->background.red =
- png_ptr->background.green =
- png_ptr->background.blue =
- png_ptr->background.gray = png_get_uint_16(buf);
- }
- else
- {
- png_ptr->background.red = png_get_uint_16(buf);
- png_ptr->background.green = png_get_uint_16(buf + 2);
- png_ptr->background.blue = png_get_uint_16(buf + 4);
- }
-
- png_set_bKGD(png_ptr, info_ptr, &(png_ptr->background));
- }
- #endif
-
- #if defined(PNG_READ_hIST_SUPPORTED)
- void /* PRIVATE */
- png_handle_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
- {
- unsigned int num, i;
- png_uint_16 readbuf[PNG_MAX_PALETTE_LENGTH];
-
- png_debug(1, "in png_handle_hIST\n");
-
- if (!(png_ptr->mode & PNG_HAVE_IHDR))
- png_error(png_ptr, "Missing IHDR before hIST");
- else if (png_ptr->mode & PNG_HAVE_IDAT)
- {
- png_warning(png_ptr, "Invalid hIST after IDAT");
- png_crc_finish(png_ptr, length);
- return;
- }
- else if (!(png_ptr->mode & PNG_HAVE_PLTE))
- {
- png_warning(png_ptr, "Missing PLTE before hIST");
- png_crc_finish(png_ptr, length);
- return;
- }
- else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST))
- {
- png_warning(png_ptr, "Duplicate hIST chunk");
- png_crc_finish(png_ptr, length);
- return;
- }
-
- num = length / 2 ;
- if (num != (unsigned int) png_ptr->num_palette || num >
- (unsigned int) PNG_MAX_PALETTE_LENGTH)
- {
- png_warning(png_ptr, "Incorrect hIST chunk length");
- png_crc_finish(png_ptr, length);
- return;
- }
-
- for (i = 0; i < num; i++)
- {
- png_byte buf[2];
-
- png_crc_read(png_ptr, buf, 2);
- readbuf[i] = png_get_uint_16(buf);
- }
-
- if (png_crc_finish(png_ptr, 0))
- return;
-
- png_set_hIST(png_ptr, info_ptr, readbuf);
- }
- #endif
-
- #if defined(PNG_READ_pHYs_SUPPORTED)
- void /* PRIVATE */
- png_handle_pHYs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
- {
- png_byte buf[9];
- png_uint_32 res_x, res_y;
- int unit_type;
-
- png_debug(1, "in png_handle_pHYs\n");
-
- if (!(png_ptr->mode & PNG_HAVE_IHDR))
- png_error(png_ptr, "Missing IHDR before pHYs");
- else if (png_ptr->mode & PNG_HAVE_IDAT)
- {
- png_warning(png_ptr, "Invalid pHYs after IDAT");
- png_crc_finish(png_ptr, length);
- return;
- }
- else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
- {
- png_warning(png_ptr, "Duplicate pHYs chunk");
- png_crc_finish(png_ptr, length);
- return;
- }
-
- if (length != 9)
- {
- png_warning(png_ptr, "Incorrect pHYs chunk length");
- png_crc_finish(png_ptr, length);
- return;
- }
-
- png_crc_read(png_ptr, buf, 9);
- if (png_crc_finish(png_ptr, 0))
- return;
-
- res_x = png_get_uint_32(buf);
- res_y = png_get_uint_32(buf + 4);
- unit_type = buf[8];
- png_set_pHYs(png_ptr, info_ptr, res_x, res_y, unit_type);
- }
- #endif
-
- #if defined(PNG_READ_oFFs_SUPPORTED)
- void /* PRIVATE */
- png_handle_oFFs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
- {
- png_byte buf[9];
- png_int_32 offset_x, offset_y;
- int unit_type;
-
- png_debug(1, "in png_handle_oFFs\n");
-
- if (!(png_ptr->mode & PNG_HAVE_IHDR))
- png_error(png_ptr, "Missing IHDR before oFFs");
- else if (png_ptr->mode & PNG_HAVE_IDAT)
- {
- png_warning(png_ptr, "Invalid oFFs after IDAT");
- png_crc_finish(png_ptr, length);
- return;
- }
- else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs))
- {
- png_warning(png_ptr, "Duplicate oFFs chunk");
- png_crc_finish(png_ptr, length);
- return;
- }
-
- if (length != 9)
- {
- png_warning(png_ptr, "Incorrect oFFs chunk length");
- png_crc_finish(png_ptr, length);
- return;
- }
-
- png_crc_read(png_ptr, buf, 9);
- if (png_crc_finish(png_ptr, 0))
- return;
-
- offset_x = png_get_int_32(buf);
- offset_y = png_get_int_32(buf + 4);
- unit_type = buf[8];
- png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y, unit_type);
- }
- #endif
-
- #if defined(PNG_READ_pCAL_SUPPORTED)
- /* read the pCAL chunk (described in the PNG Extensions document) */
- void /* PRIVATE */
- png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
- {
- png_charp purpose;
- png_int_32 X0, X1;
- png_byte type, nparams;
- png_charp buf, units, endptr;
- png_charpp params;
- png_size_t slength;
- int i;
-
- png_debug(1, "in png_handle_pCAL\n");
-
- if (!(png_ptr->mode & PNG_HAVE_IHDR))
- png_error(png_ptr, "Missing IHDR before pCAL");
- else if (png_ptr->mode & PNG_HAVE_IDAT)
- {
- png_warning(png_ptr, "Invalid pCAL after IDAT");
- png_crc_finish(png_ptr, length);
- return;
- }
- else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL))
- {
- png_warning(png_ptr, "Duplicate pCAL chunk");
- png_crc_finish(png_ptr, length);
- return;
- }
-
- png_debug1(2, "Allocating and reading pCAL chunk data (%lu bytes)\n",
- length + 1);
- purpose = (png_charp)png_malloc_warn(png_ptr, length + 1);
- if (purpose == NULL)
- {
- png_warning(png_ptr, "No memory for pCAL purpose.");
- return;
- }
- slength = (png_size_t)length;
- png_crc_read(png_ptr, (png_bytep)purpose, slength);
-
- if (png_crc_finish(png_ptr, 0))
- {
- png_free(png_ptr, purpose);
- return;
- }
-
- purpose[slength] = 0x00; /* null terminate the last string */
-
- png_debug(3, "Finding end of pCAL purpose string\n");
- for (buf = purpose; *buf; buf++)
- /* empty loop */ ;
-
- endptr = purpose + slength;
-
- /* We need to have at least 12 bytes after the purpose string
- in order to get the parameter information. */
- if (endptr <= buf + 12)
- {
- png_warning(png_ptr, "Invalid pCAL data");
- png_free(png_ptr, purpose);
- return;
- }
-
- png_debug(3, "Reading pCAL X0, X1, type, nparams, and units\n");
- X0 = png_get_int_32((png_bytep)buf+1);
- X1 = png_get_int_32((png_bytep)buf+5);
- type = buf[9];
- nparams = buf[10];
- units = buf + 11;
-
- png_debug(3, "Checking pCAL equation type and number of parameters\n");
- /* Check that we have the right number of parameters for known
- equation types. */
- if ((type == PNG_EQUATION_LINEAR && nparams != 2) ||
- (type == PNG_EQUATION_BASE_E && nparams != 3) ||
- (type == PNG_EQUATION_ARBITRARY && nparams != 3) ||
- (type == PNG_EQUATION_HYPERBOLIC && nparams != 4))
- {
- png_warning(png_ptr, "Invalid pCAL parameters for equation type");
- png_free(png_ptr, purpose);
- return;
- }
- else if (type >= PNG_EQUATION_LAST)
- {
- png_warning(png_ptr, "Unrecognized equation type for pCAL chunk");
- }
-
- for (buf = units; *buf; buf++)
- /* Empty loop to move past the units string. */ ;
-
- png_debug(3, "Allocating pCAL parameters array\n");
- params = (png_charpp)png_malloc_warn(png_ptr, (png_uint_32)(nparams
- *png_sizeof(png_charp))) ;
- if (params == NULL)
- {
- png_free(png_ptr, purpose);
- png_warning(png_ptr, "No memory for pCAL params.");
- return;
- }
-
- /* Get pointers to the start of each parameter string. */
- for (i = 0; i < (int)nparams; i++)
- {
- buf++; /* Skip the null string terminator from previous parameter. */
-
- png_debug1(3, "Reading pCAL parameter %d\n", i);
- for (params[i] = buf; buf <= endptr && *buf != 0x00; buf++)
- /* Empty loop to move past each parameter string */ ;
-
- /* Make sure we haven't run out of data yet */
- if (buf > endptr)
- {
- png_warning(png_ptr, "Invalid pCAL data");
- png_free(png_ptr, purpose);
- png_free(png_ptr, params);
- return;
- }
- }
-
- png_set_pCAL(png_ptr, info_ptr, purpose, X0, X1, type, nparams,
- units, params);
-
- png_free(png_ptr, purpose);
- png_free(png_ptr, params);
- }
- #endif
-
- #if defined(PNG_READ_sCAL_SUPPORTED)
- /* read the sCAL chunk */
- void /* PRIVATE */
- png_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
- {
- png_charp buffer, ep;
- #ifdef PNG_FLOATING_POINT_SUPPORTED
- double width, height;
- png_charp vp;
- #else
- #ifdef PNG_FIXED_POINT_SUPPORTED
- png_charp swidth, sheight;
- #endif
- #endif
- png_size_t slength;
-
- png_debug(1, "in png_handle_sCAL\n");
-
- if (!(png_ptr->mode & PNG_HAVE_IHDR))
- png_error(png_ptr, "Missing IHDR before sCAL");
- else if (png_ptr->mode & PNG_HAVE_IDAT)
- {
- png_warning(png_ptr, "Invalid sCAL after IDAT");
- png_crc_finish(png_ptr, length);
- return;
- }
- else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL))
- {
- png_warning(png_ptr, "Duplicate sCAL chunk");
- png_crc_finish(png_ptr, length);
- return;
- }
-
- png_debug1(2, "Allocating and reading sCAL chunk data (%lu bytes)\n",
- length + 1);
- buffer = (png_charp)png_malloc_warn(png_ptr, length + 1);
- if (buffer == NULL)
- {
- png_warning(png_ptr, "Out of memory while processing sCAL chunk");
- return;
- }
- slength = (png_size_t)length;
- png_crc_read(png_ptr, (png_bytep)buffer, slength);
-
- if (png_crc_finish(png_ptr, 0))
- {
- png_free(png_ptr, buffer);
- return;
- }
-
- buffer[slength] = 0x00; /* null terminate the last string */
-
- ep = buffer + 1; /* skip unit byte */
-
- #ifdef PNG_FLOATING_POINT_SUPPORTED
- width = png_strtod(png_ptr, ep, &vp);
- if (*vp)
- {
- png_warning(png_ptr, "malformed width string in sCAL chunk");
- return;
- }
- #else
- #ifdef PNG_FIXED_POINT_SUPPORTED
- swidth = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1);
- if (swidth == NULL)
- {
- png_warning(png_ptr, "Out of memory while processing sCAL chunk width");
- return;
- }
- png_memcpy(swidth, ep, (png_size_t)png_strlen(ep));
- #endif
- #endif
-
- for (ep = buffer; *ep; ep++)
- /* empty loop */ ;
- ep++;
-
- if (buffer + slength < ep)
- {
- png_warning(png_ptr, "Truncated sCAL chunk");
- #if defined(PNG_FIXED_POINT_SUPPORTED) && \
- !defined(PNG_FLOATING_POINT_SUPPORTED)
- png_free(png_ptr, swidth);
- #endif
- png_free(png_ptr, buffer);
- return;
- }
-
- #ifdef PNG_FLOATING_POINT_SUPPORTED
- height = png_strtod(png_ptr, ep, &vp);
- if (*vp)
- {
- png_warning(png_ptr, "malformed height string in sCAL chunk");
- return;
- }
- #else
- #ifdef PNG_FIXED_POINT_SUPPORTED
- sheight = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1);
- if (swidth == NULL)
- {
- png_warning(png_ptr, "Out of memory while processing sCAL chunk height");
- return;
- }
- png_memcpy(sheight, ep, (png_size_t)png_strlen(ep));
- #endif
- #endif
-
- if (buffer + slength < ep
- #ifdef PNG_FLOATING_POINT_SUPPORTED
- || width <= 0. || height <= 0.
- #endif
- )
- {
- png_warning(png_ptr, "Invalid sCAL data");
- png_free(png_ptr, buffer);
- #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
- png_free(png_ptr, swidth);
- png_free(png_ptr, sheight);
- #endif
- return;
- }
-
- #ifdef PNG_FLOATING_POINT_SUPPORTED
- png_set_sCAL(png_ptr, info_ptr, buffer[0], width, height);
- #else
- #ifdef PNG_FIXED_POINT_SUPPORTED
- png_set_sCAL_s(png_ptr, info_ptr, buffer[0], swidth, sheight);
- #endif
- #endif
-
- png_free(png_ptr, buffer);
- #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
- png_free(png_ptr, swidth);
- png_free(png_ptr, sheight);
- #endif
- }
- #endif
-
- #if defined(PNG_READ_tIME_SUPPORTED)
- void /* PRIVATE */
- png_handle_tIME(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
- {
- png_byte buf[7];
- png_time mod_time;
-
- png_debug(1, "in png_handle_tIME\n");
-
- if (!(png_ptr->mode & PNG_HAVE_IHDR))
- png_error(png_ptr, "Out of place tIME chunk");
- else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME))
- {
- png_warning(png_ptr, "Duplicate tIME chunk");
- png_crc_finish(png_ptr, length);
- return;
- }
-
- if (png_ptr->mode & PNG_HAVE_IDAT)
- png_ptr->mode |= PNG_AFTER_IDAT;
-
- if (length != 7)
- {
- png_warning(png_ptr, "Incorrect tIME chunk length");
- png_crc_finish(png_ptr, length);
- return;
- }
-
- png_crc_read(png_ptr, buf, 7);
- if (png_crc_finish(png_ptr, 0))
- return;
-
- mod_time.second = buf[6];
- mod_time.minute = buf[5];
- mod_time.hour = buf[4];
- mod_time.day = buf[3];
- mod_time.month = buf[2];
- mod_time.year = png_get_uint_16(buf);
-
- png_set_tIME(png_ptr, info_ptr, &mod_time);
- }
- #endif
-
- #if defined(PNG_READ_tEXt_SUPPORTED)
- /* Note: this does not properly handle chunks that are > 64K under DOS */
- void /* PRIVATE */
- png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
- {
- png_textp text_ptr;
- png_charp key;
- png_charp text;
- png_uint_32 skip = 0;
- png_size_t slength;
- int ret;
-
- png_debug(1, "in png_handle_tEXt\n");
-
- if (!(png_ptr->mode & PNG_HAVE_IHDR))
- png_error(png_ptr, "Missing IHDR before tEXt");
-
- if (png_ptr->mode & PNG_HAVE_IDAT)
- png_ptr->mode |= PNG_AFTER_IDAT;
-
- #ifdef PNG_MAX_MALLOC_64K
- if (length > (png_uint_32)65535L)
- {
- png_warning(png_ptr, "tEXt chunk too large to fit in memory");
- skip = length - (png_uint_32)65535L;
- length = (png_uint_32)65535L;
- }
- #endif
-
- key = (png_charp)png_malloc_warn(png_ptr, length + 1);
- if (key == NULL)
- {
- png_warning(png_ptr, "No memory to process text chunk.");
- return;
- }
- slength = (png_size_t)length;
- png_crc_read(png_ptr, (png_bytep)key, slength);
-
- if (png_crc_finish(png_ptr, skip))
- {
- png_free(png_ptr, key);
- return;
- }
-
- key[slength] = 0x00;
-
- for (text = key; *text; text++)
- /* empty loop to find end of key */ ;
-
- if (text != key + slength)
- text++;
-
- text_ptr = (png_textp)png_malloc_warn(png_ptr,
- (png_uint_32)png_sizeof(png_text));
- if (text_ptr == NULL)
- {
- png_warning(png_ptr, "Not enough memory to process text chunk.");
- png_free(png_ptr, key);
- return;
- }
- text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
- text_ptr->key = key;
- #ifdef PNG_iTXt_SUPPORTED
- text_ptr->lang = NULL;
- text_ptr->lang_key = NULL;
- text_ptr->itxt_length = 0;
- #endif
- text_ptr->text = text;
- text_ptr->text_length = png_strlen(text);
-
- ret=png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
-
- png_free(png_ptr, key);
- png_free(png_ptr, text_ptr);
- if (ret)
- png_warning(png_ptr, "Insufficient memory to process text chunk.");
- }
- #endif
-
- #if defined(PNG_READ_zTXt_SUPPORTED)
- /* note: this does not correctly handle chunks that are > 64K under DOS */
- void /* PRIVATE */
- png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
- {
- png_textp text_ptr;
- png_charp chunkdata;
- png_charp text;
- int comp_type;
- int ret;
- png_size_t slength, prefix_len, data_len;
-
- png_debug(1, "in png_handle_zTXt\n");
- if (!(png_ptr->mode & PNG_HAVE_IHDR))
- png_error(png_ptr, "Missing IHDR before zTXt");
-
- if (png_ptr->mode & PNG_HAVE_IDAT)
- png_ptr->mode |= PNG_AFTER_IDAT;
-
- #ifdef PNG_MAX_MALLOC_64K
- /* We will no doubt have problems with chunks even half this size, but
- there is no hard and fast rule to tell us where to stop. */
- if (length > (png_uint_32)65535L)
- {
- png_warning(png_ptr,"zTXt chunk too large to fit in memory");
- png_crc_finish(png_ptr, length);
- return;
- }
- #endif
-
- chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
- if (chunkdata == NULL)
- {
- png_warning(png_ptr,"Out of memory processing zTXt chunk.");
- return;
- }
- slength = (png_size_t)length;
- png_crc_read(png_ptr, (png_bytep)chunkdata, slength);
- if (png_crc_finish(png_ptr, 0))
- {
- png_free(png_ptr, chunkdata);
- return;
- }
-
- chunkdata[slength] = 0x00;
-
- for (text = chunkdata; *text; text++)
- /* empty loop */ ;
-
- /* zTXt must have some text after the chunkdataword */
- if (text >= chunkdata + slength - 2)
- {
- png_warning(png_ptr, "Truncated zTXt chunk");
- png_free(png_ptr, chunkdata);
- return;
- }
- else
- {
- comp_type = *(++text);
- if (comp_type != PNG_TEXT_COMPRESSION_zTXt)
- {
- png_warning(png_ptr, "Unknown compression type in zTXt chunk");
- comp_type = PNG_TEXT_COMPRESSION_zTXt;
- }
- text++; /* skip the compression_method byte */
- }
- prefix_len = text - chunkdata;
-
- chunkdata = (png_charp)png_decompress_chunk(png_ptr, comp_type, chunkdata,
- (png_size_t)length, prefix_len, &data_len);
-
- text_ptr = (png_textp)png_malloc_warn(png_ptr,
- (png_uint_32)png_sizeof(png_text));
- if (text_ptr == NULL)
- {
- png_warning(png_ptr,"Not enough memory to process zTXt chunk.");
- png_free(png_ptr, chunkdata);
- return;
- }
- text_ptr->compression = comp_type;
- text_ptr->key = chunkdata;
- #ifdef PNG_iTXt_SUPPORTED
- text_ptr->lang = NULL;
- text_ptr->lang_key = NULL;
- text_ptr->itxt_length = 0;
- #endif
- text_ptr->text = chunkdata + prefix_len;
- text_ptr->text_length = data_len;
-
- ret=png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
-
- png_free(png_ptr, text_ptr);
- png_free(png_ptr, chunkdata);
- if (ret)
- png_error(png_ptr, "Insufficient memory to store zTXt chunk.");
- }
- #endif
-
- #if defined(PNG_READ_iTXt_SUPPORTED)
- /* note: this does not correctly handle chunks that are > 64K under DOS */
- void /* PRIVATE */
- png_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
- {
- png_textp text_ptr;
- png_charp chunkdata;
- png_charp key, lang, text, lang_key;
- int comp_flag;
- int comp_type = 0;
- int ret;
- png_size_t slength, prefix_len, data_len;
-
- png_debug(1, "in png_handle_iTXt\n");
-
- if (!(png_ptr->mode & PNG_HAVE_IHDR))
- png_error(png_ptr, "Missing IHDR before iTXt");
-
- if (png_ptr->mode & PNG_HAVE_IDAT)
- png_ptr->mode |= PNG_AFTER_IDAT;
-
- #ifdef PNG_MAX_MALLOC_64K
- /* We will no doubt have problems with chunks even half this size, but
- there is no hard and fast rule to tell us where to stop. */
- if (length > (png_uint_32)65535L)
- {
- png_warning(png_ptr,"iTXt chunk too large to fit in memory");
- png_crc_finish(png_ptr, length);
- return;
- }
- #endif
-
- chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
- if (chunkdata == NULL)
- {
- png_warning(png_ptr, "No memory to process iTXt chunk.");
- return;
- }
- slength = (png_size_t)length;
- png_crc_read(png_ptr, (png_bytep)chunkdata, slength);
- if (png_crc_finish(png_ptr, 0))
- {
- png_free(png_ptr, chunkdata);
- return;
- }
-
- chunkdata[slength] = 0x00;
-
- for (lang = chunkdata; *lang; lang++)
- /* empty loop */ ;
- lang++; /* skip NUL separator */
-
- /* iTXt must have a language tag (possibly empty), two compression bytes,
- translated keyword (possibly empty), and possibly some text after the
- keyword */
-
- if (lang >= chunkdata + slength - 3)
- {
- png_warning(png_ptr, "Truncated iTXt chunk");
- png_free(png_ptr, chunkdata);
- return;
- }
- else
- {
- comp_flag = *lang++;
- comp_type = *lang++;
- }
-
- for (lang_key = lang; *lang_key; lang_key++)
- /* empty loop */ ;
- lang_key++; /* skip NUL separator */
-
- if (lang_key >= chunkdata + slength)
- {
- png_warning(png_ptr, "Truncated iTXt chunk");
- png_free(png_ptr, chunkdata);
- return;
- }
-
- for (text = lang_key; *text; text++)
- /* empty loop */ ;
- text++; /* skip NUL separator */
- if (text >= chunkdata + slength)
- {
- png_warning(png_ptr, "Malformed iTXt chunk");
- png_free(png_ptr, chunkdata);
- return;
- }
-
- prefix_len = text - chunkdata;
-
- key=chunkdata;
- if (comp_flag)
- chunkdata = png_decompress_chunk(png_ptr, comp_type, chunkdata,
- (size_t)length, prefix_len, &data_len);
- else
- data_len=png_strlen(chunkdata + prefix_len);
- text_ptr = (png_textp)png_malloc_warn(png_ptr,
- (png_uint_32)png_sizeof(png_text));
- if (text_ptr == NULL)
- {
- png_warning(png_ptr,"Not enough memory to process iTXt chunk.");
- png_free(png_ptr, chunkdata);
- return;
- }
- text_ptr->compression = (int)comp_flag + 1;
- text_ptr->lang_key = chunkdata+(lang_key-key);
- text_ptr->lang = chunkdata+(lang-key);
- text_ptr->itxt_length = data_len;
- text_ptr->text_length = 0;
- text_ptr->key = chunkdata;
- text_ptr->text = chunkdata + prefix_len;
-
- ret=png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
-
- png_free(png_ptr, text_ptr);
- png_free(png_ptr, chunkdata);
- if (ret)
- png_error(png_ptr, "Insufficient memory to store iTXt chunk.");
- }
- #endif
-
- /* This function is called when we haven't found a handler for a
- chunk. If there isn't a problem with the chunk itself (ie bad
- chunk name, CRC, or a critical chunk), the chunk is silently ignored
- -- unless the PNG_FLAG_UNKNOWN_CHUNKS_SUPPORTED flag is on in which
- case it will be saved away to be written out later. */
- void /* PRIVATE */
- png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
- {
- png_uint_32 skip = 0;
-
- png_debug(1, "in png_handle_unknown\n");
-
- if (png_ptr->mode & PNG_HAVE_IDAT)
- {
- #ifdef PNG_USE_LOCAL_ARRAYS
- PNG_CONST PNG_IDAT;
- #endif
- if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) /* not an IDAT */
- png_ptr->mode |= PNG_AFTER_IDAT;
- }
-
- png_check_chunk_name(png_ptr, png_ptr->chunk_name);
-
- if (!(png_ptr->chunk_name[0] & 0x20))
- {
- #if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
- if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
- PNG_HANDLE_CHUNK_ALWAYS
- #if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
- && png_ptr->read_user_chunk_fn == NULL
- #endif
- )
- #endif
- png_chunk_error(png_ptr, "unknown critical chunk");
- }
-
- #if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
- if ((png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS) ||
- (png_ptr->read_user_chunk_fn != NULL))
- {
- #ifdef PNG_MAX_MALLOC_64K
- if (length > (png_uint_32)65535L)
- {
- png_warning(png_ptr, "unknown chunk too large to fit in memory");
- skip = length - (png_uint_32)65535L;
- length = (png_uint_32)65535L;
- }
- #endif
- png_strncpy((png_charp)png_ptr->unknown_chunk.name,
- (png_charp)png_ptr->chunk_name, 5);
- png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr, length);
- png_ptr->unknown_chunk.size = (png_size_t)length;
- png_crc_read(png_ptr, (png_bytep)png_ptr->unknown_chunk.data, length);
- #if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
- if(png_ptr->read_user_chunk_fn != NULL)
- {
- /* callback to user unknown chunk handler */
- int ret;
- ret = (*(png_ptr->read_user_chunk_fn))
- (png_ptr, &png_ptr->unknown_chunk);
- if (ret < 0)
- png_chunk_error(png_ptr, "error in user chunk");
- if (ret == 0)
- {
- if (!(png_ptr->chunk_name[0] & 0x20))
- if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
- PNG_HANDLE_CHUNK_ALWAYS)
- png_chunk_error(png_ptr, "unknown critical chunk");
- png_set_unknown_chunks(png_ptr, info_ptr,
- &png_ptr->unknown_chunk, 1);
- }
- }
- #else
- png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1);
- #endif
- png_free(png_ptr, png_ptr->unknown_chunk.data);
- png_ptr->unknown_chunk.data = NULL;
- }
- else
- #endif
- skip = length;
-
- png_crc_finish(png_ptr, skip);
-
- #if !defined(PNG_READ_USER_CHUNKS_SUPPORTED)
- info_ptr = info_ptr; /* quiet compiler warnings about unused info_ptr */
- #endif
- }
-
- /* This function is called to verify that a chunk name is valid.
- This function can't have the "critical chunk check" incorporated
- into it, since in the future we will need to be able to call user
- functions to handle unknown critical chunks after we check that
- the chunk name itself is valid. */
-
- #define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
-
- void /* PRIVATE */
- png_check_chunk_name(png_structp png_ptr, png_bytep chunk_name)
- {
- png_debug(1, "in png_check_chunk_name\n");
- if (isnonalpha(chunk_name[0]) || isnonalpha(chunk_name[1]) ||
- isnonalpha(chunk_name[2]) || isnonalpha(chunk_name[3]))
- {
- png_chunk_error(png_ptr, "invalid chunk type");
- }
- }
-
- /* Combines the row recently read in with the existing pixels in the
- row. This routine takes care of alpha and transparency if requested.
- This routine also handles the two methods of progressive display
- of interlaced images, depending on the mask value.
- The mask value describes which pixels are to be combined with
- the row. The pattern always repeats every 8 pixels, so just 8
- bits are needed. A one indicates the pixel is to be combined,
- a zero indicates the pixel is to be skipped. This is in addition
- to any alpha or transparency value associated with the pixel. If
- you want all pixels to be combined, pass 0xff (255) in mask. */
-
- void /* PRIVATE */
- png_combine_row(png_structp png_ptr, png_bytep row, int mask)
- {
- png_debug(1,"in png_combine_row\n");
- if (mask == 0xff)
- {
- png_memcpy(row, png_ptr->row_buf + 1,
- PNG_ROWBYTES(png_ptr->row_info.pixel_depth, png_ptr->width));
- }
- else
- {
- switch (png_ptr->row_info.pixel_depth)
- {
- case 1:
- {
- png_bytep sp = png_ptr->row_buf + 1;
- png_bytep dp = row;
- int s_inc, s_start, s_end;
- int m = 0x80;
- int shift;
- png_uint_32 i;
- png_uint_32 row_width = png_ptr->width;
-
- #if defined(PNG_READ_PACKSWAP_SUPPORTED)
- if (png_ptr->transformations & PNG_PACKSWAP)
- {
- s_start = 0;
- s_end = 7;
- s_inc = 1;
- }
- else
- #endif
- {
- s_start = 7;
- s_end = 0;
- s_inc = -1;
- }
-
- shift = s_start;
-
- for (i = 0; i < row_width; i++)
- {
- if (m & mask)
- {
- int value;
-
- value = (*sp >> shift) & 0x01;
- *dp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff);
- *dp |= (png_byte)(value << shift);
- }
-
- if (shift == s_end)
- {
- shift = s_start;
- sp++;
- dp++;
- }
- else
- shift += s_inc;
-
- if (m == 1)
- m = 0x80;
- else
- m >>= 1;
- }
- break;
- }
- case 2:
- {
- png_bytep sp = png_ptr->row_buf + 1;
- png_bytep dp = row;
- int s_start, s_end, s_inc;
- int m = 0x80;
- int shift;
- png_uint_32 i;
- png_uint_32 row_width = png_ptr->width;
- int value;
-
- #if defined(PNG_READ_PACKSWAP_SUPPORTED)
- if (png_ptr->transformations & PNG_PACKSWAP)
- {
- s_start = 0;
- s_end = 6;
- s_inc = 2;
- }
- else
- #endif
- {
- s_start = 6;
- s_end = 0;
- s_inc = -2;
- }
-
- shift = s_start;
-
- for (i = 0; i < row_width; i++)
- {
- if (m & mask)
- {
- value = (*sp >> shift) & 0x03;
- *dp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
- *dp |= (png_byte)(value << shift);
- }
-
- if (shift == s_end)
- {
- shift = s_start;
- sp++;
- dp++;
- }
- else
- shift += s_inc;
- if (m == 1)
- m = 0x80;
- else
- m >>= 1;
- }
- break;
- }
- case 4:
- {
- png_bytep sp = png_ptr->row_buf + 1;
- png_bytep dp = row;
- int s_start, s_end, s_inc;
- int m = 0x80;
- int shift;
- png_uint_32 i;
- png_uint_32 row_width = png_ptr->width;
- int value;
-
- #if defined(PNG_READ_PACKSWAP_SUPPORTED)
- if (png_ptr->transformations & PNG_PACKSWAP)
- {
- s_start = 0;
- s_end = 4;
- s_inc = 4;
- }
- else
- #endif
- {
- s_start = 4;
- s_end = 0;
- s_inc = -4;
- }
- shift = s_start;
-
- for (i = 0; i < row_width; i++)
- {
- if (m & mask)
- {
- value = (*sp >> shift) & 0xf;
- *dp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
- *dp |= (png_byte)(value << shift);
- }
-
- if (shift == s_end)
- {
- shift = s_start;
- sp++;
- dp++;
- }
- else
- shift += s_inc;
- if (m == 1)
- m = 0x80;
- else
- m >>= 1;
- }
- break;
- }
- default:
- {
- png_bytep sp = png_ptr->row_buf + 1;
- png_bytep dp = row;
- png_size_t pixel_bytes = (png_ptr->row_info.pixel_depth >> 3);
- png_uint_32 i;
- png_uint_32 row_width = png_ptr->width;
- png_byte m = 0x80;
-
- for (i = 0; i < row_width; i++)
- {
- if (m & mask)
- {
- png_memcpy(dp, sp, pixel_bytes);
- }
-
- sp += pixel_bytes;
- dp += pixel_bytes;
-
- if (m == 1)
- m = 0x80;
- else
- m >>= 1;
- }
- break;
- }
- }
- }
- }
-
- #ifdef PNG_READ_INTERLACING_SUPPORTED
- /* OLD pre-1.0.9 interface:
- void png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
- png_uint_32 transformations)
- */
- void /* PRIVATE */
- png_do_read_interlace(png_structp png_ptr)
- {
- png_row_infop row_info = &(png_ptr->row_info);
- png_bytep row = png_ptr->row_buf + 1;
- int pass = png_ptr->pass;
- png_uint_32 transformations = png_ptr->transformations;
- #ifdef PNG_USE_LOCAL_ARRAYS
- /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
- /* offset to next interlace block */
- PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
- #endif
-
- png_debug(1,"in png_do_read_interlace\n");
- if (row != NULL && row_info != NULL)
- {
- png_uint_32 final_width;
-
- final_width = row_info->width * png_pass_inc[pass];
-
- switch (row_info->pixel_depth)
- {
- case 1:
- {
- png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 3);
- png_bytep dp = row + (png_size_t)((final_width - 1) >> 3);
- int sshift, dshift;
- int s_start, s_end, s_inc;
- int jstop = png_pass_inc[pass];
- png_byte v;
- png_uint_32 i;
- int j;
-
- #if defined(PNG_READ_PACKSWAP_SUPPORTED)
- if (transformations & PNG_PACKSWAP)
- {
- sshift = (int)((row_info->width + 7) & 0x07);
- dshift = (int)((final_width + 7) & 0x07);
- s_start = 7;
- s_end = 0;
- s_inc = -1;
- }
- else
- #endif
- {
- sshift = 7 - (int)((row_info->width + 7) & 0x07);
- dshift = 7 - (int)((final_width + 7) & 0x07);
- s_start = 0;
- s_end = 7;
- s_inc = 1;
- }
-
- for (i = 0; i < row_info->width; i++)
- {
- v = (png_byte)((*sp >> sshift) & 0x01);
- for (j = 0; j < jstop; j++)
- {
- *dp &= (png_byte)((0x7f7f >> (7 - dshift)) & 0xff);
- *dp |= (png_byte)(v << dshift);
- if (dshift == s_end)
- {
- dshift = s_start;
- dp--;
- }
- else
- dshift += s_inc;
- }
- if (sshift == s_end)
- {
- sshift = s_start;
- sp--;
- }
- else
- sshift += s_inc;
- }
- break;
- }
- case 2:
- {
- png_bytep sp = row + (png_uint_32)((row_info->width - 1) >> 2);
- png_bytep dp = row + (png_uint_32)((final_width - 1) >> 2);
- int sshift, dshift;
- int s_start, s_end, s_inc;
- int jstop = png_pass_inc[pass];
- png_uint_32 i;
-
- #if defined(PNG_READ_PACKSWAP_SUPPORTED)
- if (transformations & PNG_PACKSWAP)
- {
- sshift = (int)(((row_info->width + 3) & 0x03) << 1);
- dshift = (int)(((final_width + 3) & 0x03) << 1);
- s_start = 6;
- s_end = 0;
- s_inc = -2;
- }
- else
- #endif
- {
- sshift = (int)((3 - ((row_info->width + 3) & 0x03)) << 1);
- dshift = (int)((3 - ((final_width + 3) & 0x03)) << 1);
- s_start = 0;
- s_end = 6;
- s_inc = 2;
- }
-
- for (i = 0; i < row_info->width; i++)
- {
- png_byte v;
- int j;
-
- v = (png_byte)((*sp >> sshift) & 0x03);
- for (j = 0; j < jstop; j++)
- {
- *dp &= (png_byte)((0x3f3f >> (6 - dshift)) & 0xff);
- *dp |= (png_byte)(v << dshift);
- if (dshift == s_end)
- {
- dshift = s_start;
- dp--;
- }
- else
- dshift += s_inc;
- }
- if (sshift == s_end)
- {
- sshift = s_start;
- sp--;
- }
- else
- sshift += s_inc;
- }
- break;
- }
- case 4:
- {
- png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 1);
- png_bytep dp = row + (png_size_t)((final_width - 1) >> 1);
- int sshift, dshift;
- int s_start, s_end, s_inc;
- png_uint_32 i;
- int jstop = png_pass_inc[pass];
-
- #if defined(PNG_READ_PACKSWAP_SUPPORTED)
- if (transformations & PNG_PACKSWAP)
- {
- sshift = (int)(((row_info->width + 1) & 0x01) << 2);
- dshift = (int)(((final_width + 1) & 0x01) << 2);
- s_start = 4;
- s_end = 0;
- s_inc = -4;
- }
- else
- #endif
- {
- sshift = (int)((1 - ((row_info->width + 1) & 0x01)) << 2);
- dshift = (int)((1 - ((final_width + 1) & 0x01)) << 2);
- s_start = 0;
- s_end = 4;
- s_inc = 4;
- }
-
- for (i = 0; i < row_info->width; i++)
- {
- png_byte v = (png_byte)((*sp >> sshift) & 0xf);
- int j;
-
- for (j = 0; j < jstop; j++)
- {
- *dp &= (png_byte)((0xf0f >> (4 - dshift)) & 0xff);
- *dp |= (png_byte)(v << dshift);
- if (dshift == s_end)
- {
- dshift = s_start;
- dp--;
- }
- else
- dshift += s_inc;
- }
- if (sshift == s_end)
- {
- sshift = s_start;
- sp--;
- }
- else
- sshift += s_inc;
- }
- break;
- }
- default:
- {
- png_size_t pixel_bytes = (row_info->pixel_depth >> 3);
- png_bytep sp = row + (png_size_t)(row_info->width - 1) * pixel_bytes;
- png_bytep dp = row + (png_size_t)(final_width - 1) * pixel_bytes;
-
- int jstop = png_pass_inc[pass];
- png_uint_32 i;
-
- for (i = 0; i < row_info->width; i++)
- {
- png_byte v[8];
- int j;
-
- png_memcpy(v, sp, pixel_bytes);
- for (j = 0; j < jstop; j++)
- {
- png_memcpy(dp, v, pixel_bytes);
- dp -= pixel_bytes;
- }
- sp -= pixel_bytes;
- }
- break;
- }
- }
- row_info->width = final_width;
- row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,final_width);
- }
- #if !defined(PNG_READ_PACKSWAP_SUPPORTED)
- transformations = transformations; /* silence compiler warning */
- #endif
- }
- #endif /* PNG_READ_INTERLACING_SUPPORTED */
-
- void /* PRIVATE */
- png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep row,
- png_bytep prev_row, int filter)
- {
- png_debug(1, "in png_read_filter_row\n");
- png_debug2(2,"row = %lu, filter = %d\n", png_ptr->row_number, filter);
- switch (filter)
- {
- case PNG_FILTER_VALUE_NONE:
- break;
- case PNG_FILTER_VALUE_SUB:
- {
- png_uint_32 i;
- png_uint_32 istop = row_info->rowbytes;
- png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
- png_bytep rp = row + bpp;
- png_bytep lp = row;
-
- for (i = bpp; i < istop; i++)
- {
- *rp = (png_byte)(((int)(*rp) + (int)(*lp++)) & 0xff);
- rp++;
- }
- break;
- }
- case PNG_FILTER_VALUE_UP:
- {
- png_uint_32 i;
- png_uint_32 istop = row_info->rowbytes;
- png_bytep rp = row;
- png_bytep pp = prev_row;
-
- for (i = 0; i < istop; i++)
- {
- *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
- rp++;
- }
- break;
- }
- case PNG_FILTER_VALUE_AVG:
- {
- png_uint_32 i;
- png_bytep rp = row;
- png_bytep pp = prev_row;
- png_bytep lp = row;
- png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
- png_uint_32 istop = row_info->rowbytes - bpp;
-
- for (i = 0; i < bpp; i++)
- {
- *rp = (png_byte)(((int)(*rp) +
- ((int)(*pp++) / 2 )) & 0xff);
- rp++;
- }
-
- for (i = 0; i < istop; i++)
- {
- *rp = (png_byte)(((int)(*rp) +
- (int)(*pp++ + *lp++) / 2 ) & 0xff);
- rp++;
- }
- break;
- }
- case PNG_FILTER_VALUE_PAETH:
- {
- png_uint_32 i;
- png_bytep rp = row;
- png_bytep pp = prev_row;
- png_bytep lp = row;
- png_bytep cp = prev_row;
- png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
- png_uint_32 istop=row_info->rowbytes - bpp;
-
- for (i = 0; i < bpp; i++)
- {
- *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
- rp++;
- }
-
- for (i = 0; i < istop; i++) /* use leftover rp,pp */
- {
- int a, b, c, pa, pb, pc, p;
-
- a = *lp++;
- b = *pp++;
- c = *cp++;
-
- p = b - c;
- pc = a - c;
-
- #ifdef PNG_USE_ABS
- pa = abs(p);
- pb = abs(pc);
- pc = abs(p + pc);
- #else
- pa = p < 0 ? -p : p;
- pb = pc < 0 ? -pc : pc;
- pc = (p + pc) < 0 ? -(p + pc) : p + pc;
- #endif
-
- /*
- if (pa <= pb && pa <= pc)
- p = a;
- else if (pb <= pc)
- p = b;
- else
- p = c;
- */
-
- p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c;
-
- *rp = (png_byte)(((int)(*rp) + p) & 0xff);
- rp++;
- }
- break;
- }
- default:
- png_warning(png_ptr, "Ignoring bad adaptive filter type");
- *row=0;
- break;
- }
- }
-
- void /* PRIVATE */
- png_read_finish_row(png_structp png_ptr)
- {
- #ifdef PNG_USE_LOCAL_ARRAYS
- /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
-
- /* start of interlace block */
- PNG_CONST int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
-
- /* offset to next interlace block */
- PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
-
- /* start of interlace block in the y direction */
- PNG_CONST int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
-
- /* offset to next interlace block in the y direction */
- PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
- #endif
-
- png_debug(1, "in png_read_finish_row\n");
- png_ptr->row_number++;
- if (png_ptr->row_number < png_ptr->num_rows)
- return;
-
- if (png_ptr->interlaced)
- {
- png_ptr->row_number = 0;
- png_memset_check(png_ptr, png_ptr->prev_row, 0,
- png_ptr->rowbytes + 1);
- do
- {
- png_ptr->pass++;
- if (png_ptr->pass >= 7)
- break;
- png_ptr->iwidth = (png_ptr->width +
- png_pass_inc[png_ptr->pass] - 1 -
- png_pass_start[png_ptr->pass]) /
- png_pass_inc[png_ptr->pass];
-
- png_ptr->irowbytes = PNG_ROWBYTES(png_ptr->pixel_depth,
- png_ptr->iwidth) + 1;
-
- if (!(png_ptr->transformations & PNG_INTERLACE))
- {
- png_ptr->num_rows = (png_ptr->height +
- png_pass_yinc[png_ptr->pass] - 1 -
- png_pass_ystart[png_ptr->pass]) /
- png_pass_yinc[png_ptr->pass];
- if (!(png_ptr->num_rows))
- continue;
- }
- else /* if (png_ptr->transformations & PNG_INTERLACE) */
- break;
- } while (png_ptr->iwidth == 0);
-
- if (png_ptr->pass < 7)
- return;
- }
-
- if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
- {
- #ifdef PNG_USE_LOCAL_ARRAYS
- PNG_CONST PNG_IDAT;
- #endif
- char extra;
- int ret;
-
- png_ptr->zstream.next_out = (Byte *)&extra;
- png_ptr->zstream.avail_out = (uInt)1;
- for(;;)
- {
- if (!(png_ptr->zstream.avail_in))
- {
- while (!png_ptr->idat_size)
- {
- png_byte chunk_length[4];
-
- png_crc_finish(png_ptr, 0);
-
- png_read_data(png_ptr, chunk_length, 4);
- png_ptr->idat_size = png_get_uint_31(png_ptr, chunk_length);
- png_reset_crc(png_ptr);
- png_crc_read(png_ptr, png_ptr->chunk_name, 4);
- if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
- png_error(png_ptr, "Not enough image data");
-
- }
- png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size;
- png_ptr->zstream.next_in = png_ptr->zbuf;
- if (png_ptr->zbuf_size > png_ptr->idat_size)
- png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size;
- png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zstream.avail_in);
- png_ptr->idat_size -= png_ptr->zstream.avail_in;
- }
- ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
- if (ret == Z_STREAM_END)
- {
- if (!(png_ptr->zstream.avail_out) || png_ptr->zstream.avail_in ||
- png_ptr->idat_size)
- png_warning(png_ptr, "Extra compressed data");
- png_ptr->mode |= PNG_AFTER_IDAT;
- png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
- break;
- }
- if (ret != Z_OK)
- png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg :
- "Decompression Error");
-
- if (!(png_ptr->zstream.avail_out))
- {
- png_warning(png_ptr, "Extra compressed data.");
- png_ptr->mode |= PNG_AFTER_IDAT;
- png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
- break;
- }
-
- }
- png_ptr->zstream.avail_out = 0;
- }
-
- if (png_ptr->idat_size || png_ptr->zstream.avail_in)
- png_warning(png_ptr, "Extra compression data");
-
- inflateReset(&png_ptr->zstream);
-
- png_ptr->mode |= PNG_AFTER_IDAT;
- }
-
- void /* PRIVATE */
- png_read_start_row(png_structp png_ptr)
- {
- #ifdef PNG_USE_LOCAL_ARRAYS
- /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
-
- /* start of interlace block */
- PNG_CONST int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
-
- /* offset to next interlace block */
- PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
-
- /* start of interlace block in the y direction */
- PNG_CONST int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
-
- /* offset to next interlace block in the y direction */
- PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
- #endif
-
- int max_pixel_depth;
- png_uint_32 row_bytes;
-
- png_debug(1, "in png_read_start_row\n");
- png_ptr->zstream.avail_in = 0;
- png_init_read_transformations(png_ptr);
- if (png_ptr->interlaced)
- {
- if (!(png_ptr->transformations & PNG_INTERLACE))
- png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
- png_pass_ystart[0]) / png_pass_yinc[0];
- else
- png_ptr->num_rows = png_ptr->height;
-
- png_ptr->iwidth = (png_ptr->width +
- png_pass_inc[png_ptr->pass] - 1 -
- png_pass_start[png_ptr->pass]) /
- png_pass_inc[png_ptr->pass];
-
- row_bytes = PNG_ROWBYTES(png_ptr->pixel_depth,png_ptr->iwidth) + 1;
-
- png_ptr->irowbytes = (png_size_t)row_bytes;
- if((png_uint_32)png_ptr->irowbytes != row_bytes)
- png_error(png_ptr, "Rowbytes overflow in png_read_start_row");
- }
- else
- {
- png_ptr->num_rows = png_ptr->height;
- png_ptr->iwidth = png_ptr->width;
- png_ptr->irowbytes = png_ptr->rowbytes + 1;
- }
- max_pixel_depth = png_ptr->pixel_depth;
-
- #if defined(PNG_READ_PACK_SUPPORTED)
- if ((png_ptr->transformations & PNG_PACK) && png_ptr->bit_depth < 8)
- max_pixel_depth = 8;
- #endif
-
- #if defined(PNG_READ_EXPAND_SUPPORTED)
- if (png_ptr->transformations & PNG_EXPAND)
- {
- if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
- {
- if (png_ptr->num_trans)
- max_pixel_depth = 32;
- else
- max_pixel_depth = 24;
- }
- else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
- {
- if (max_pixel_depth < 8)
- max_pixel_depth = 8;
- if (png_ptr->num_trans)
- max_pixel_depth *= 2;
- }
- else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
- {
- if (png_ptr->num_trans)
- {
- max_pixel_depth *= 4;
- max_pixel_depth /= 3;
- }
- }
- }
- #endif
-
- #if defined(PNG_READ_FILLER_SUPPORTED)
- if (png_ptr->transformations & (PNG_FILLER))
- {
- if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
- max_pixel_depth = 32;
- else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
- {
- if (max_pixel_depth <= 8)
- max_pixel_depth = 16;
- else
- max_pixel_depth = 32;
- }
- else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
- {
- if (max_pixel_depth <= 32)
- max_pixel_depth = 32;
- else
- max_pixel_depth = 64;
- }
- }
- #endif
-
- #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
- if (png_ptr->transformations & PNG_GRAY_TO_RGB)
- {
- if (
- #if defined(PNG_READ_EXPAND_SUPPORTED)
- (png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND)) ||
- #endif
- #if defined(PNG_READ_FILLER_SUPPORTED)
- (png_ptr->transformations & (PNG_FILLER)) ||
- #endif
- png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
- {
- if (max_pixel_depth <= 16)
- max_pixel_depth = 32;
- else
- max_pixel_depth = 64;
- }
- else
- {
- if (max_pixel_depth <= 8)
- {
- if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
- max_pixel_depth = 32;
- else
- max_pixel_depth = 24;
- }
- else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
- max_pixel_depth = 64;
- else
- max_pixel_depth = 48;
- }
- }
- #endif
-
- #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) && \
- defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
- if(png_ptr->transformations & PNG_USER_TRANSFORM)
- {
- int user_pixel_depth=png_ptr->user_transform_depth*
- png_ptr->user_transform_channels;
- if(user_pixel_depth > max_pixel_depth)
- max_pixel_depth=user_pixel_depth;
- }
- #endif
-
- /* align the width on the next larger 8 pixels. Mainly used
- for interlacing */
- row_bytes = ((png_ptr->width + 7) & ~((png_uint_32)7));
- /* calculate the maximum bytes needed, adding a byte and a pixel
- for safety's sake */
- row_bytes = PNG_ROWBYTES(max_pixel_depth,row_bytes) +
- 1 + ((max_pixel_depth + 7) >> 3);
- #ifdef PNG_MAX_MALLOC_64K
- if (row_bytes > (png_uint_32)65536L)
- png_error(png_ptr, "This image requires a row greater than 64KB");
- #endif
- png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr, row_bytes+64);
- png_ptr->row_buf = png_ptr->big_row_buf+32;
-
- #ifdef PNG_MAX_MALLOC_64K
- if ((png_uint_32)png_ptr->rowbytes + 1 > (png_uint_32)65536L)
- png_error(png_ptr, "This image requires a row greater than 64KB");
- #endif
- if ((png_uint_32)png_ptr->rowbytes > (png_uint_32)(PNG_SIZE_MAX - 1))
- png_error(png_ptr, "Row has too many bytes to allocate in memory.");
- png_ptr->prev_row = (png_bytep)png_malloc(png_ptr, (png_uint_32)(
- png_ptr->rowbytes + 1));
-
- png_memset_check(png_ptr, png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
-
- png_debug1(3, "width = %lu,\n", png_ptr->width);
- png_debug1(3, "height = %lu,\n", png_ptr->height);
- png_debug1(3, "iwidth = %lu,\n", png_ptr->iwidth);
- png_debug1(3, "num_rows = %lu\n", png_ptr->num_rows);
- png_debug1(3, "rowbytes = %lu,\n", png_ptr->rowbytes);
- png_debug1(3, "irowbytes = %lu,\n", png_ptr->irowbytes);
-
- png_ptr->flags |= PNG_FLAG_ROW_INIT;
- }
- #endif /* PNG_READ_SUPPORTED */
- /********* End of inlined file: pngrutil.c *********/
-
- /********* Start of inlined file: pngset.c *********/
- /* pngset.c - storage of image information into info struct
- *
- * Last changed in libpng 1.2.21 [October 4, 2007]
- * For conditions of distribution and use, see copyright notice in png.h
- * Copyright (c) 1998-2007 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
- *
- * The functions here are used during reads to store data from the file
- * into the info struct, and during writes to store application data
- * into the info struct for writing into the file. This abstracts the
- * info struct and allows us to change the structure in the future.
- */
-
- #define PNG_INTERNAL
-
- #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
-
- #if defined(PNG_bKGD_SUPPORTED)
- void PNGAPI
- png_set_bKGD(png_structp png_ptr, png_infop info_ptr, png_color_16p background)
- {
- png_debug1(1, "in %s storage function\n", "bKGD");
- if (png_ptr == NULL || info_ptr == NULL)
- return;
-
- png_memcpy(&(info_ptr->background), background, png_sizeof(png_color_16));
- info_ptr->valid |= PNG_INFO_bKGD;
- }
- #endif
-
- #if defined(PNG_cHRM_SUPPORTED)
- #ifdef PNG_FLOATING_POINT_SUPPORTED
- void PNGAPI
- png_set_cHRM(png_structp png_ptr, png_infop info_ptr,
- double white_x, double white_y, double red_x, double red_y,
- double green_x, double green_y, double blue_x, double blue_y)
- {
- png_debug1(1, "in %s storage function\n", "cHRM");
- if (png_ptr == NULL || info_ptr == NULL)
- return;
-
- if (white_x < 0.0 || white_y < 0.0 ||
- red_x < 0.0 || red_y < 0.0 ||
- green_x < 0.0 || green_y < 0.0 ||
- blue_x < 0.0 || blue_y < 0.0)
- {
- png_warning(png_ptr,
- "Ignoring attempt to set negative chromaticity value");
- return;
- }
- if (white_x > 21474.83 || white_y > 21474.83 ||
- red_x > 21474.83 || red_y > 21474.83 ||
- green_x > 21474.83 || green_y > 21474.83 ||
- blue_x > 21474.83 || blue_y > 21474.83)
- {
- png_warning(png_ptr,
- "Ignoring attempt to set chromaticity value exceeding 21474.83");
- return;
- }
-
- info_ptr->x_white = (float)white_x;
- info_ptr->y_white = (float)white_y;
- info_ptr->x_red = (float)red_x;
- info_ptr->y_red = (float)red_y;
- info_ptr->x_green = (float)green_x;
- info_ptr->y_green = (float)green_y;
- info_ptr->x_blue = (float)blue_x;
- info_ptr->y_blue = (float)blue_y;
- #ifdef PNG_FIXED_POINT_SUPPORTED
- info_ptr->int_x_white = (png_fixed_point)(white_x*100000.+0.5);
- info_ptr->int_y_white = (png_fixed_point)(white_y*100000.+0.5);
- info_ptr->int_x_red = (png_fixed_point)( red_x*100000.+0.5);
- info_ptr->int_y_red = (png_fixed_point)( red_y*100000.+0.5);
- info_ptr->int_x_green = (png_fixed_point)(green_x*100000.+0.5);
- info_ptr->int_y_green = (png_fixed_point)(green_y*100000.+0.5);
- info_ptr->int_x_blue = (png_fixed_point)( blue_x*100000.+0.5);
- info_ptr->int_y_blue = (png_fixed_point)( blue_y*100000.+0.5);
- #endif
- info_ptr->valid |= PNG_INFO_cHRM;
- }
- #endif
- #ifdef PNG_FIXED_POINT_SUPPORTED
- void PNGAPI
- png_set_cHRM_fixed(png_structp png_ptr, png_infop info_ptr,
- png_fixed_point white_x, png_fixed_point white_y, png_fixed_point red_x,
- png_fixed_point red_y, png_fixed_point green_x, png_fixed_point green_y,
- png_fixed_point blue_x, png_fixed_point blue_y)
- {
- png_debug1(1, "in %s storage function\n", "cHRM");
- if (png_ptr == NULL || info_ptr == NULL)
- return;
-
- if (white_x < 0 || white_y < 0 ||
- red_x < 0 || red_y < 0 ||
- green_x < 0 || green_y < 0 ||
- blue_x < 0 || blue_y < 0)
- {
- png_warning(png_ptr,
- "Ignoring attempt to set negative chromaticity value");
- return;
- }
- #ifdef PNG_FLOATING_POINT_SUPPORTED
- if (white_x > (double) PNG_UINT_31_MAX ||
- white_y > (double) PNG_UINT_31_MAX ||
- red_x > (double) PNG_UINT_31_MAX ||
- red_y > (double) PNG_UINT_31_MAX ||
- green_x > (double) PNG_UINT_31_MAX ||
- green_y > (double) PNG_UINT_31_MAX ||
- blue_x > (double) PNG_UINT_31_MAX ||
- blue_y > (double) PNG_UINT_31_MAX)
- #else
- if (white_x > (png_fixed_point) PNG_UINT_31_MAX/100000L ||
- white_y > (png_fixed_point) PNG_UINT_31_MAX/100000L ||
- red_x > (png_fixed_point) PNG_UINT_31_MAX/100000L ||
- red_y > (png_fixed_point) PNG_UINT_31_MAX/100000L ||
- green_x > (png_fixed_point) PNG_UINT_31_MAX/100000L ||
- green_y > (png_fixed_point) PNG_UINT_31_MAX/100000L ||
- blue_x > (png_fixed_point) PNG_UINT_31_MAX/100000L ||
- blue_y > (png_fixed_point) PNG_UINT_31_MAX/100000L)
- #endif
- {
- png_warning(png_ptr,
- "Ignoring attempt to set chromaticity value exceeding 21474.83");
- return;
- }
- info_ptr->int_x_white = white_x;
- info_ptr->int_y_white = white_y;
- info_ptr->int_x_red = red_x;
- info_ptr->int_y_red = red_y;
- info_ptr->int_x_green = green_x;
- info_ptr->int_y_green = green_y;
- info_ptr->int_x_blue = blue_x;
- info_ptr->int_y_blue = blue_y;
- #ifdef PNG_FLOATING_POINT_SUPPORTED
- info_ptr->x_white = (float)(white_x/100000.);
- info_ptr->y_white = (float)(white_y/100000.);
- info_ptr->x_red = (float)( red_x/100000.);
- info_ptr->y_red = (float)( red_y/100000.);
- info_ptr->x_green = (float)(green_x/100000.);
- info_ptr->y_green = (float)(green_y/100000.);
- info_ptr->x_blue = (float)( blue_x/100000.);
- info_ptr->y_blue = (float)( blue_y/100000.);
- #endif
- info_ptr->valid |= PNG_INFO_cHRM;
- }
- #endif
- #endif
-
- #if defined(PNG_gAMA_SUPPORTED)
- #ifdef PNG_FLOATING_POINT_SUPPORTED
- void PNGAPI
- png_set_gAMA(png_structp png_ptr, png_infop info_ptr, double file_gamma)
- {
- double gamma;
- png_debug1(1, "in %s storage function\n", "gAMA");
- if (png_ptr == NULL || info_ptr == NULL)
- return;
-
- /* Check for overflow */
- if (file_gamma > 21474.83)
- {
- png_warning(png_ptr, "Limiting gamma to 21474.83");
- gamma=21474.83;
- }
- else
- gamma=file_gamma;
- info_ptr->gamma = (float)gamma;
- #ifdef PNG_FIXED_POINT_SUPPORTED
- info_ptr->int_gamma = (int)(gamma*100000.+.5);
- #endif
- info_ptr->valid |= PNG_INFO_gAMA;
- if(gamma == 0.0)
- png_warning(png_ptr, "Setting gamma=0");
- }
- #endif
- void PNGAPI
- png_set_gAMA_fixed(png_structp png_ptr, png_infop info_ptr, png_fixed_point
- int_gamma)
- {
- png_fixed_point gamma;
-
- png_debug1(1, "in %s storage function\n", "gAMA");
- if (png_ptr == NULL || info_ptr == NULL)
- return;
-
- if (int_gamma > (png_fixed_point) PNG_UINT_31_MAX)
- {
- png_warning(png_ptr, "Limiting gamma to 21474.83");
- gamma=PNG_UINT_31_MAX;
- }
- else
- {
- if (int_gamma < 0)
- {
- png_warning(png_ptr, "Setting negative gamma to zero");
- gamma=0;
- }
- else
- gamma=int_gamma;
- }
- #ifdef PNG_FLOATING_POINT_SUPPORTED
- info_ptr->gamma = (float)(gamma/100000.);
- #endif
- #ifdef PNG_FIXED_POINT_SUPPORTED
- info_ptr->int_gamma = gamma;
- #endif
- info_ptr->valid |= PNG_INFO_gAMA;
- if(gamma == 0)
- png_warning(png_ptr, "Setting gamma=0");
- }
- #endif
-
- #if defined(PNG_hIST_SUPPORTED)
- void PNGAPI
- png_set_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_16p hist)
- {
- int i;
-
- png_debug1(1, "in %s storage function\n", "hIST");
- if (png_ptr == NULL || info_ptr == NULL)
- return;
- if (info_ptr->num_palette == 0 || info_ptr->num_palette
- > PNG_MAX_PALETTE_LENGTH)
- {
- png_warning(png_ptr,
- "Invalid palette size, hIST allocation skipped.");
- return;
- }
-
- #ifdef PNG_FREE_ME_SUPPORTED
- png_free_data(png_ptr, info_ptr, PNG_FREE_HIST, 0);
- #endif
- /* Changed from info->num_palette to PNG_MAX_PALETTE_LENGTH in version
- 1.2.1 */
- png_ptr->hist = (png_uint_16p)png_malloc_warn(png_ptr,
- (png_uint_32)(PNG_MAX_PALETTE_LENGTH * png_sizeof (png_uint_16)));
- if (png_ptr->hist == NULL)
- {
- png_warning(png_ptr, "Insufficient memory for hIST chunk data.");
- return;
- }
-
- for (i = 0; i < info_ptr->num_palette; i++)
- png_ptr->hist[i] = hist[i];
- info_ptr->hist = png_ptr->hist;
- info_ptr->valid |= PNG_INFO_hIST;
-
- #ifdef PNG_FREE_ME_SUPPORTED
- info_ptr->free_me |= PNG_FREE_HIST;
- #else
- png_ptr->flags |= PNG_FLAG_FREE_HIST;
- #endif
- }
- #endif
-
- void PNGAPI
- png_set_IHDR(png_structp png_ptr, png_infop info_ptr,
- png_uint_32 width, png_uint_32 height, int bit_depth,
- int color_type, int interlace_type, int compression_type,
- int filter_type)
- {
- png_debug1(1, "in %s storage function\n", "IHDR");
- if (png_ptr == NULL || info_ptr == NULL)
- return;
-
- /* check for width and height valid values */
- if (width == 0 || height == 0)
- png_error(png_ptr, "Image width or height is zero in IHDR");
- #ifdef PNG_SET_USER_LIMITS_SUPPORTED
- if (width > png_ptr->user_width_max || height > png_ptr->user_height_max)
- png_error(png_ptr, "image size exceeds user limits in IHDR");
- #else
- if (width > PNG_USER_WIDTH_MAX || height > PNG_USER_HEIGHT_MAX)
- png_error(png_ptr, "image size exceeds user limits in IHDR");
- #endif
- if (width > PNG_UINT_31_MAX || height > PNG_UINT_31_MAX)
- png_error(png_ptr, "Invalid image size in IHDR");
- if ( width > (PNG_UINT_32_MAX
- >> 3) /* 8-byte RGBA pixels */
- - 64 /* bigrowbuf hack */
- - 1 /* filter byte */
- - 7*8 /* rounding of width to multiple of 8 pixels */
- - 8) /* extra max_pixel_depth pad */
- png_warning(png_ptr, "Width is too large for libpng to process pixels");
-
- /* check other values */
- if (bit_depth != 1 && bit_depth != 2 && bit_depth != 4 &&
- bit_depth != 8 && bit_depth != 16)
- png_error(png_ptr, "Invalid bit depth in IHDR");
-
- if (color_type < 0 || color_type == 1 ||
- color_type == 5 || color_type > 6)
- png_error(png_ptr, "Invalid color type in IHDR");
-
- if (((color_type == PNG_COLOR_TYPE_PALETTE) && bit_depth > 8) ||
- ((color_type == PNG_COLOR_TYPE_RGB ||
- color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
- color_type == PNG_COLOR_TYPE_RGB_ALPHA) && bit_depth < 8))
- png_error(png_ptr, "Invalid color type/bit depth combination in IHDR");
-
- if (interlace_type >= PNG_INTERLACE_LAST)
- png_error(png_ptr, "Unknown interlace method in IHDR");
-
- if (compression_type != PNG_COMPRESSION_TYPE_BASE)
- png_error(png_ptr, "Unknown compression method in IHDR");
-
- #if defined(PNG_MNG_FEATURES_SUPPORTED)
- /* Accept filter_method 64 (intrapixel differencing) only if
- * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and
- * 2. Libpng did not read a PNG signature (this filter_method is only
- * used in PNG datastreams that are embedded in MNG datastreams) and
- * 3. The application called png_permit_mng_features with a mask that
- * included PNG_FLAG_MNG_FILTER_64 and
- * 4. The filter_method is 64 and
- * 5. The color_type is RGB or RGBA
- */
- if((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE)&&png_ptr->mng_features_permitted)
- png_warning(png_ptr,"MNG features are not allowed in a PNG datastream");
- if(filter_type != PNG_FILTER_TYPE_BASE)
- {
- if(!((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
- (filter_type == PNG_INTRAPIXEL_DIFFERENCING) &&
- ((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE) == 0) &&
- (color_type == PNG_COLOR_TYPE_RGB ||
- color_type == PNG_COLOR_TYPE_RGB_ALPHA)))
- png_error(png_ptr, "Unknown filter method in IHDR");
- if(png_ptr->mode&PNG_HAVE_PNG_SIGNATURE)
- png_warning(png_ptr, "Invalid filter method in IHDR");
- }
- #else
- if(filter_type != PNG_FILTER_TYPE_BASE)
- png_error(png_ptr, "Unknown filter method in IHDR");
- #endif
-
- info_ptr->width = width;
- info_ptr->height = height;
- info_ptr->bit_depth = (png_byte)bit_depth;
- info_ptr->color_type =(png_byte) color_type;
- info_ptr->compression_type = (png_byte)compression_type;
- info_ptr->filter_type = (png_byte)filter_type;
- info_ptr->interlace_type = (png_byte)interlace_type;
- if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
- info_ptr->channels = 1;
- else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR)
- info_ptr->channels = 3;
- else
- info_ptr->channels = 1;
- if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA)
- info_ptr->channels++;
- info_ptr->pixel_depth = (png_byte)(info_ptr->channels * info_ptr->bit_depth);
-
- /* check for potential overflow */
- if (width > (PNG_UINT_32_MAX
- >> 3) /* 8-byte RGBA pixels */
- - 64 /* bigrowbuf hack */
- - 1 /* filter byte */
- - 7*8 /* rounding of width to multiple of 8 pixels */
- - 8) /* extra max_pixel_depth pad */
- info_ptr->rowbytes = (png_size_t)0;
- else
- info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth,width);
- }
-
- #if defined(PNG_oFFs_SUPPORTED)
- void PNGAPI
- png_set_oFFs(png_structp png_ptr, png_infop info_ptr,
- png_int_32 offset_x, png_int_32 offset_y, int unit_type)
- {
- png_debug1(1, "in %s storage function\n", "oFFs");
- if (png_ptr == NULL || info_ptr == NULL)
- return;
-
- info_ptr->x_offset = offset_x;
- info_ptr->y_offset = offset_y;
- info_ptr->offset_unit_type = (png_byte)unit_type;
- info_ptr->valid |= PNG_INFO_oFFs;
- }
- #endif
-
- #if defined(PNG_pCAL_SUPPORTED)
- void PNGAPI
- png_set_pCAL(png_structp png_ptr, png_infop info_ptr,
- png_charp purpose, png_int_32 X0, png_int_32 X1, int type, int nparams,
- png_charp units, png_charpp params)
- {
- png_uint_32 length;
- int i;
-
- png_debug1(1, "in %s storage function\n", "pCAL");
- if (png_ptr == NULL || info_ptr == NULL)
- return;
-
- length = png_strlen(purpose) + 1;
- png_debug1(3, "allocating purpose for info (%lu bytes)\n", length);
- info_ptr->pcal_purpose = (png_charp)png_malloc_warn(png_ptr, length);
- if (info_ptr->pcal_purpose == NULL)
- {
- png_warning(png_ptr, "Insufficient memory for pCAL purpose.");
- return;
- }
- png_memcpy(info_ptr->pcal_purpose, purpose, (png_size_t)length);
-
- png_debug(3, "storing X0, X1, type, and nparams in info\n");
- info_ptr->pcal_X0 = X0;
- info_ptr->pcal_X1 = X1;
- info_ptr->pcal_type = (png_byte)type;
- info_ptr->pcal_nparams = (png_byte)nparams;
-
- length = png_strlen(units) + 1;
- png_debug1(3, "allocating units for info (%lu bytes)\n", length);
- info_ptr->pcal_units = (png_charp)png_malloc_warn(png_ptr, length);
- if (info_ptr->pcal_units == NULL)
- {
- png_warning(png_ptr, "Insufficient memory for pCAL units.");
- return;
- }
- png_memcpy(info_ptr->pcal_units, units, (png_size_t)length);
-
- info_ptr->pcal_params = (png_charpp)png_malloc_warn(png_ptr,
- (png_uint_32)((nparams + 1) * png_sizeof(png_charp)));
- if (info_ptr->pcal_params == NULL)
- {
- png_warning(png_ptr, "Insufficient memory for pCAL params.");
- return;
- }
-
- info_ptr->pcal_params[nparams] = NULL;
-
- for (i = 0; i < nparams; i++)
- {
- length = png_strlen(params[i]) + 1;
- png_debug2(3, "allocating parameter %d for info (%lu bytes)\n", i, length);
- info_ptr->pcal_params[i] = (png_charp)png_malloc_warn(png_ptr, length);
- if (info_ptr->pcal_params[i] == NULL)
- {
- png_warning(png_ptr, "Insufficient memory for pCAL parameter.");
- return;
- }
- png_memcpy(info_ptr->pcal_params[i], params[i], (png_size_t)length);
- }
-
- info_ptr->valid |= PNG_INFO_pCAL;
- #ifdef PNG_FREE_ME_SUPPORTED
- info_ptr->free_me |= PNG_FREE_PCAL;
- #endif
- }
- #endif
-
- #if defined(PNG_READ_sCAL_SUPPORTED) || defined(PNG_WRITE_sCAL_SUPPORTED)
- #ifdef PNG_FLOATING_POINT_SUPPORTED
- void PNGAPI
- png_set_sCAL(png_structp png_ptr, png_infop info_ptr,
- int unit, double width, double height)
- {
- png_debug1(1, "in %s storage function\n", "sCAL");
- if (png_ptr == NULL || info_ptr == NULL)
- return;
-
- info_ptr->scal_unit = (png_byte)unit;
- info_ptr->scal_pixel_width = width;
- info_ptr->scal_pixel_height = height;
-
- info_ptr->valid |= PNG_INFO_sCAL;
- }
- #else
- #ifdef PNG_FIXED_POINT_SUPPORTED
- void PNGAPI
- png_set_sCAL_s(png_structp png_ptr, png_infop info_ptr,
- int unit, png_charp swidth, png_charp sheight)
- {
- png_uint_32 length;
-
- png_debug1(1, "in %s storage function\n", "sCAL");
- if (png_ptr == NULL || info_ptr == NULL)
- return;
-
- info_ptr->scal_unit = (png_byte)unit;
-
- length = png_strlen(swidth) + 1;
- png_debug1(3, "allocating unit for info (%d bytes)\n", length);
- info_ptr->scal_s_width = (png_charp)png_malloc_warn(png_ptr, length);
- if (info_ptr->scal_s_width == NULL)
- {
- png_warning(png_ptr,
- "Memory allocation failed while processing sCAL.");
- }
- png_memcpy(info_ptr->scal_s_width, swidth, (png_size_t)length);
-
- length = png_strlen(sheight) + 1;
- png_debug1(3, "allocating unit for info (%d bytes)\n", length);
- info_ptr->scal_s_height = (png_charp)png_malloc_warn(png_ptr, length);
- if (info_ptr->scal_s_height == NULL)
- {
- png_free (png_ptr, info_ptr->scal_s_width);
- png_warning(png_ptr,
- "Memory allocation failed while processing sCAL.");
- }
- png_memcpy(info_ptr->scal_s_height, sheight, (png_size_t)length);
-
- info_ptr->valid |= PNG_INFO_sCAL;
- #ifdef PNG_FREE_ME_SUPPORTED
- info_ptr->free_me |= PNG_FREE_SCAL;
- #endif
- }
- #endif
- #endif
- #endif
-
- #if defined(PNG_pHYs_SUPPORTED)
- void PNGAPI
- png_set_pHYs(png_structp png_ptr, png_infop info_ptr,
- png_uint_32 res_x, png_uint_32 res_y, int unit_type)
- {
- png_debug1(1, "in %s storage function\n", "pHYs");
- if (png_ptr == NULL || info_ptr == NULL)
- return;
-
- info_ptr->x_pixels_per_unit = res_x;
- info_ptr->y_pixels_per_unit = res_y;
- info_ptr->phys_unit_type = (png_byte)unit_type;
- info_ptr->valid |= PNG_INFO_pHYs;
- }
- #endif
-
- void PNGAPI
- png_set_PLTE(png_structp png_ptr, png_infop info_ptr,
- png_colorp palette, int num_palette)
- {
-
- png_debug1(1, "in %s storage function\n", "PLTE");
- if (png_ptr == NULL || info_ptr == NULL)
- return;
-
- if (num_palette < 0 || num_palette > PNG_MAX_PALETTE_LENGTH)
- {
- if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
- png_error(png_ptr, "Invalid palette length");
- else
- {
- png_warning(png_ptr, "Invalid palette length");
- return;
- }
- }
-
- /*
- * It may not actually be necessary to set png_ptr->palette here;
- * we do it for backward compatibility with the way the png_handle_tRNS
- * function used to do the allocation.
- */
- #ifdef PNG_FREE_ME_SUPPORTED
- png_free_data(png_ptr, info_ptr, PNG_FREE_PLTE, 0);
- #endif
-
- /* Changed in libpng-1.2.1 to allocate PNG_MAX_PALETTE_LENGTH instead
- of num_palette entries,
- in case of an invalid PNG file that has too-large sample values. */
- png_ptr->palette = (png_colorp)png_malloc(png_ptr,
- PNG_MAX_PALETTE_LENGTH * png_sizeof(png_color));
- png_memset(png_ptr->palette, 0, PNG_MAX_PALETTE_LENGTH *
- png_sizeof(png_color));
- png_memcpy(png_ptr->palette, palette, num_palette * png_sizeof (png_color));
- info_ptr->palette = png_ptr->palette;
- info_ptr->num_palette = png_ptr->num_palette = (png_uint_16)num_palette;
-
- #ifdef PNG_FREE_ME_SUPPORTED
- info_ptr->free_me |= PNG_FREE_PLTE;
- #else
- png_ptr->flags |= PNG_FLAG_FREE_PLTE;
- #endif
-
- info_ptr->valid |= PNG_INFO_PLTE;
- }
-
- #if defined(PNG_sBIT_SUPPORTED)
- void PNGAPI
- png_set_sBIT(png_structp png_ptr, png_infop info_ptr,
- png_color_8p sig_bit)
- {
- png_debug1(1, "in %s storage function\n", "sBIT");
- if (png_ptr == NULL || info_ptr == NULL)
- return;
-
- png_memcpy(&(info_ptr->sig_bit), sig_bit, png_sizeof (png_color_8));
- info_ptr->valid |= PNG_INFO_sBIT;
- }
- #endif
-
- #if defined(PNG_sRGB_SUPPORTED)
- void PNGAPI
- png_set_sRGB(png_structp png_ptr, png_infop info_ptr, int intent)
- {
- png_debug1(1, "in %s storage function\n", "sRGB");
- if (png_ptr == NULL || info_ptr == NULL)
- return;
-
- info_ptr->srgb_intent = (png_byte)intent;
- info_ptr->valid |= PNG_INFO_sRGB;
- }
-
- void PNGAPI
- png_set_sRGB_gAMA_and_cHRM(png_structp png_ptr, png_infop info_ptr,
- int intent)
- {
- #if defined(PNG_gAMA_SUPPORTED)
- #ifdef PNG_FLOATING_POINT_SUPPORTED
- float file_gamma;
- #endif
- #ifdef PNG_FIXED_POINT_SUPPORTED
- png_fixed_point int_file_gamma;
- #endif
- #endif
- #if defined(PNG_cHRM_SUPPORTED)
- #ifdef PNG_FLOATING_POINT_SUPPORTED
- float white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y;
- #endif
- #ifdef PNG_FIXED_POINT_SUPPORTED
- png_fixed_point int_white_x, int_white_y, int_red_x, int_red_y, int_green_x,
- int_green_y, int_blue_x, int_blue_y;
- #endif
- #endif
- png_debug1(1, "in %s storage function\n", "sRGB_gAMA_and_cHRM");
- if (png_ptr == NULL || info_ptr == NULL)
- return;
-
- png_set_sRGB(png_ptr, info_ptr, intent);
-
- #if defined(PNG_gAMA_SUPPORTED)
- #ifdef PNG_FLOATING_POINT_SUPPORTED
- file_gamma = (float).45455;
- png_set_gAMA(png_ptr, info_ptr, file_gamma);
- #endif
- #ifdef PNG_FIXED_POINT_SUPPORTED
- int_file_gamma = 45455L;
- png_set_gAMA_fixed(png_ptr, info_ptr, int_file_gamma);
- #endif
- #endif
-
- #if defined(PNG_cHRM_SUPPORTED)
- #ifdef PNG_FIXED_POINT_SUPPORTED
- int_white_x = 31270L;
- int_white_y = 32900L;
- int_red_x = 64000L;
- int_red_y = 33000L;
- int_green_x = 30000L;
- int_green_y = 60000L;
- int_blue_x = 15000L;
- int_blue_y = 6000L;
-
- png_set_cHRM_fixed(png_ptr, info_ptr,
- int_white_x, int_white_y, int_red_x, int_red_y, int_green_x, int_green_y,
- int_blue_x, int_blue_y);
- #endif
- #ifdef PNG_FLOATING_POINT_SUPPORTED
- white_x = (float).3127;
- white_y = (float).3290;
- red_x = (float).64;
- red_y = (float).33;
- green_x = (float).30;
- green_y = (float).60;
- blue_x = (float).15;
- blue_y = (float).06;
-
- png_set_cHRM(png_ptr, info_ptr,
- white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y);
- #endif
- #endif
- }
- #endif
-
- #if defined(PNG_iCCP_SUPPORTED)
- void PNGAPI
- png_set_iCCP(png_structp png_ptr, png_infop info_ptr,
- png_charp name, int compression_type,
- png_charp profile, png_uint_32 proflen)
- {
- png_charp new_iccp_name;
- png_charp new_iccp_profile;
-
- png_debug1(1, "in %s storage function\n", "iCCP");
- if (png_ptr == NULL || info_ptr == NULL || name == NULL || profile == NULL)
- return;
-
- new_iccp_name = (png_charp)png_malloc_warn(png_ptr, png_strlen(name)+1);
- if (new_iccp_name == NULL)
- {
- png_warning(png_ptr, "Insufficient memory to process iCCP chunk.");
- return;
- }
- png_strncpy(new_iccp_name, name, png_strlen(name)+1);
- new_iccp_profile = (png_charp)png_malloc_warn(png_ptr, proflen);
- if (new_iccp_profile == NULL)
- {
- png_free (png_ptr, new_iccp_name);
- png_warning(png_ptr, "Insufficient memory to process iCCP profile.");
- return;
- }
- png_memcpy(new_iccp_profile, profile, (png_size_t)proflen);
-
- png_free_data(png_ptr, info_ptr, PNG_FREE_ICCP, 0);
-
- info_ptr->iccp_proflen = proflen;
- info_ptr->iccp_name = new_iccp_name;
- info_ptr->iccp_profile = new_iccp_profile;
- /* Compression is always zero but is here so the API and info structure
- * does not have to change if we introduce multiple compression types */
- info_ptr->iccp_compression = (png_byte)compression_type;
- #ifdef PNG_FREE_ME_SUPPORTED
- info_ptr->free_me |= PNG_FREE_ICCP;
- #endif
- info_ptr->valid |= PNG_INFO_iCCP;
- }
- #endif
-
- #if defined(PNG_TEXT_SUPPORTED)
- void PNGAPI
- png_set_text(png_structp png_ptr, png_infop info_ptr, png_textp text_ptr,
- int num_text)
- {
- int ret;
- ret=png_set_text_2(png_ptr, info_ptr, text_ptr, num_text);
- if (ret)
- png_error(png_ptr, "Insufficient memory to store text");
- }
-
- int /* PRIVATE */
- png_set_text_2(png_structp png_ptr, png_infop info_ptr, png_textp text_ptr,
- int num_text)
- {
- int i;
-
- png_debug1(1, "in %s storage function\n", (png_ptr->chunk_name[0] == '\0' ?
- "text" : (png_const_charp)png_ptr->chunk_name));
-
- if (png_ptr == NULL || info_ptr == NULL || num_text == 0)
- return(0);
-
- /* Make sure we have enough space in the "text" array in info_struct
- * to hold all of the incoming text_ptr objects.
- */
- if (info_ptr->num_text + num_text > info_ptr->max_text)
- {
- if (info_ptr->text != NULL)
- {
- png_textp old_text;
- int old_max;
-
- old_max = info_ptr->max_text;
- info_ptr->max_text = info_ptr->num_text + num_text + 8;
- old_text = info_ptr->text;
- info_ptr->text = (png_textp)png_malloc_warn(png_ptr,
- (png_uint_32)(info_ptr->max_text * png_sizeof (png_text)));
- if (info_ptr->text == NULL)
- {
- png_free(png_ptr, old_text);
- return(1);
- }
- png_memcpy(info_ptr->text, old_text, (png_size_t)(old_max *
- png_sizeof(png_text)));
- png_free(png_ptr, old_text);
- }
- else
- {
- info_ptr->max_text = num_text + 8;
- info_ptr->num_text = 0;
- info_ptr->text = (png_textp)png_malloc_warn(png_ptr,
- (png_uint_32)(info_ptr->max_text * png_sizeof (png_text)));
- if (info_ptr->text == NULL)
- return(1);
- #ifdef PNG_FREE_ME_SUPPORTED
- info_ptr->free_me |= PNG_FREE_TEXT;
- #endif
- }
- png_debug1(3, "allocated %d entries for info_ptr->text\n",
- info_ptr->max_text);
- }
- for (i = 0; i < num_text; i++)
- {
- png_size_t text_length,key_len;
- png_size_t lang_len,lang_key_len;
- png_textp textp = &(info_ptr->text[info_ptr->num_text]);
-
- if (text_ptr[i].key == NULL)
- continue;
-
- key_len = png_strlen(text_ptr[i].key);
-
- if(text_ptr[i].compression <= 0)
- {
- lang_len = 0;
- lang_key_len = 0;
- }
- else
- #ifdef PNG_iTXt_SUPPORTED
- {
- /* set iTXt data */
- if (text_ptr[i].lang != NULL)
- lang_len = png_strlen(text_ptr[i].lang);
- else
- lang_len = 0;
- if (text_ptr[i].lang_key != NULL)
- lang_key_len = png_strlen(text_ptr[i].lang_key);
- else
- lang_key_len = 0;
- }
- #else
- {
- png_warning(png_ptr, "iTXt chunk not supported.");
- continue;
- }
- #endif
-
- if (text_ptr[i].text == NULL || text_ptr[i].text[0] == '\0')
- {
- text_length = 0;
- #ifdef PNG_iTXt_SUPPORTED
- if(text_ptr[i].compression > 0)
- textp->compression = PNG_ITXT_COMPRESSION_NONE;
- else
- #endif
- textp->compression = PNG_TEXT_COMPRESSION_NONE;
- }
- else
- {
- text_length = png_strlen(text_ptr[i].text);
- textp->compression = text_ptr[i].compression;
- }
-
- textp->key = (png_charp)png_malloc_warn(png_ptr,
- (png_uint_32)(key_len + text_length + lang_len + lang_key_len + 4));
- if (textp->key == NULL)
- return(1);
- png_debug2(2, "Allocated %lu bytes at %x in png_set_text\n",
- (png_uint_32)(key_len + lang_len + lang_key_len + text_length + 4),
- (int)textp->key);
-
- png_memcpy(textp->key, text_ptr[i].key,
- (png_size_t)(key_len));
- *(textp->key+key_len) = '\0';
- #ifdef PNG_iTXt_SUPPORTED
- if (text_ptr[i].compression > 0)
- {
- textp->lang=textp->key + key_len + 1;
- png_memcpy(textp->lang, text_ptr[i].lang, lang_len);
- *(textp->lang+lang_len) = '\0';
- textp->lang_key=textp->lang + lang_len + 1;
- png_memcpy(textp->lang_key, text_ptr[i].lang_key, lang_key_len);
- *(textp->lang_key+lang_key_len) = '\0';
- textp->text=textp->lang_key + lang_key_len + 1;
- }
- else
- #endif
- {
- #ifdef PNG_iTXt_SUPPORTED
- textp->lang=NULL;
- textp->lang_key=NULL;
- #endif
- textp->text=textp->key + key_len + 1;
- }
- if(text_length)
- png_memcpy(textp->text, text_ptr[i].text,
- (png_size_t)(text_length));
- *(textp->text+text_length) = '\0';
-
- #ifdef PNG_iTXt_SUPPORTED
- if(textp->compression > 0)
- {
- textp->text_length = 0;
- textp->itxt_length = text_length;
- }
- else
- #endif
- {
- textp->text_length = text_length;
- #ifdef PNG_iTXt_SUPPORTED
- textp->itxt_length = 0;
- #endif
- }
- info_ptr->num_text++;
- png_debug1(3, "transferred text chunk %d\n", info_ptr->num_text);
- }
- return(0);
- }
- #endif
-
- #if defined(PNG_tIME_SUPPORTED)
- void PNGAPI
- png_set_tIME(png_structp png_ptr, png_infop info_ptr, png_timep mod_time)
- {
- png_debug1(1, "in %s storage function\n", "tIME");
- if (png_ptr == NULL || info_ptr == NULL ||
- (png_ptr->mode & PNG_WROTE_tIME))
- return;
-
- png_memcpy(&(info_ptr->mod_time), mod_time, png_sizeof (png_time));
- info_ptr->valid |= PNG_INFO_tIME;
- }
- #endif
-
- #if defined(PNG_tRNS_SUPPORTED)
- void PNGAPI
- png_set_tRNS(png_structp png_ptr, png_infop info_ptr,
- png_bytep trans, int num_trans, png_color_16p trans_values)
- {
- png_debug1(1, "in %s storage function\n", "tRNS");
- if (png_ptr == NULL || info_ptr == NULL)
- return;
-
- if (trans != NULL)
- {
- /*
- * It may not actually be necessary to set png_ptr->trans here;
- * we do it for backward compatibility with the way the png_handle_tRNS
- * function used to do the allocation.
- */
- #ifdef PNG_FREE_ME_SUPPORTED
- png_free_data(png_ptr, info_ptr, PNG_FREE_TRNS, 0);
- #endif
- /* Changed from num_trans to PNG_MAX_PALETTE_LENGTH in version 1.2.1 */
- png_ptr->trans = info_ptr->trans = (png_bytep)png_malloc(png_ptr,
- (png_uint_32)PNG_MAX_PALETTE_LENGTH);
- if (num_trans <= PNG_MAX_PALETTE_LENGTH)
- png_memcpy(info_ptr->trans, trans, (png_size_t)num_trans);
- #ifdef PNG_FREE_ME_SUPPORTED
- info_ptr->free_me |= PNG_FREE_TRNS;
- #else
- png_ptr->flags |= PNG_FLAG_FREE_TRNS;
- #endif
- }
-
- if (trans_values != NULL)
- {
- png_memcpy(&(info_ptr->trans_values), trans_values,
- png_sizeof(png_color_16));
- if (num_trans == 0)
- num_trans = 1;
- }
- info_ptr->num_trans = (png_uint_16)num_trans;
- info_ptr->valid |= PNG_INFO_tRNS;
- }
- #endif
-
- #if defined(PNG_sPLT_SUPPORTED)
- void PNGAPI
- png_set_sPLT(png_structp png_ptr,
- png_infop info_ptr, png_sPLT_tp entries, int nentries)
- {
- png_sPLT_tp np;
- int i;
-
- if (png_ptr == NULL || info_ptr == NULL)
- return;
-
- np = (png_sPLT_tp)png_malloc_warn(png_ptr,
- (info_ptr->splt_palettes_num + nentries) * png_sizeof(png_sPLT_t));
- if (np == NULL)
- {
- png_warning(png_ptr, "No memory for sPLT palettes.");
- return;
- }
-
- png_memcpy(np, info_ptr->splt_palettes,
- info_ptr->splt_palettes_num * png_sizeof(png_sPLT_t));
- png_free(png_ptr, info_ptr->splt_palettes);
- info_ptr->splt_palettes=NULL;
-
- for (i = 0; i < nentries; i++)
- {
- png_sPLT_tp to = np + info_ptr->splt_palettes_num + i;
- png_sPLT_tp from = entries + i;
-
- to->name = (png_charp)png_malloc_warn(png_ptr,
- png_strlen(from->name) + 1);
- if (to->name == NULL)
- {
- png_warning(png_ptr,
- "Out of memory while processing sPLT chunk");
- }
- /* TODO: use png_malloc_warn */
- png_strncpy(to->name, from->name, png_strlen(from->name)+1);
- to->entries = (png_sPLT_entryp)png_malloc_warn(png_ptr,
- from->nentries * png_sizeof(png_sPLT_entry));
- /* TODO: use png_malloc_warn */
- png_memcpy(to->entries, from->entries,
- from->nentries * png_sizeof(png_sPLT_entry));
- if (to->entries == NULL)
- {
- png_warning(png_ptr,
- "Out of memory while processing sPLT chunk");
- png_free(png_ptr,to->name);
- to->name = NULL;
- }
- to->nentries = from->nentries;
- to->depth = from->depth;
- }
-
- info_ptr->splt_palettes = np;
- info_ptr->splt_palettes_num += nentries;
- info_ptr->valid |= PNG_INFO_sPLT;
- #ifdef PNG_FREE_ME_SUPPORTED
- info_ptr->free_me |= PNG_FREE_SPLT;
- #endif
- }
- #endif /* PNG_sPLT_SUPPORTED */
-
- #if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
- void PNGAPI
- png_set_unknown_chunks(png_structp png_ptr,
- png_infop info_ptr, png_unknown_chunkp unknowns, int num_unknowns)
- {
- png_unknown_chunkp np;
- int i;
-
- if (png_ptr == NULL || info_ptr == NULL || num_unknowns == 0)
- return;
-
- np = (png_unknown_chunkp)png_malloc_warn(png_ptr,
- (info_ptr->unknown_chunks_num + num_unknowns) *
- png_sizeof(png_unknown_chunk));
- if (np == NULL)
- {
- png_warning(png_ptr,
- "Out of memory while processing unknown chunk.");
- return;
- }
-
- png_memcpy(np, info_ptr->unknown_chunks,
- info_ptr->unknown_chunks_num * png_sizeof(png_unknown_chunk));
- png_free(png_ptr, info_ptr->unknown_chunks);
- info_ptr->unknown_chunks=NULL;
-
- for (i = 0; i < num_unknowns; i++)
- {
- png_unknown_chunkp to = np + info_ptr->unknown_chunks_num + i;
- png_unknown_chunkp from = unknowns + i;
-
- png_strncpy((png_charp)to->name, (png_charp)from->name, 5);
- to->data = (png_bytep)png_malloc_warn(png_ptr, from->size);
- if (to->data == NULL)
- {
- png_warning(png_ptr,
- "Out of memory while processing unknown chunk.");
- }
- else
- {
- png_memcpy(to->data, from->data, from->size);
- to->size = from->size;
-
- /* note our location in the read or write sequence */
- to->location = (png_byte)(png_ptr->mode & 0xff);
- }
- }
-
- info_ptr->unknown_chunks = np;
- info_ptr->unknown_chunks_num += num_unknowns;
- #ifdef PNG_FREE_ME_SUPPORTED
- info_ptr->free_me |= PNG_FREE_UNKN;
- #endif
- }
- void PNGAPI
- png_set_unknown_chunk_location(png_structp png_ptr, png_infop info_ptr,
- int chunk, int location)
- {
- if(png_ptr != NULL && info_ptr != NULL && chunk >= 0 && chunk <
- (int)info_ptr->unknown_chunks_num)
- info_ptr->unknown_chunks[chunk].location = (png_byte)location;
- }
- #endif
-
- #if defined(PNG_1_0_X) || defined(PNG_1_2_X)
- #if defined(PNG_READ_EMPTY_PLTE_SUPPORTED) || \
- defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED)
- void PNGAPI
- png_permit_empty_plte (png_structp png_ptr, int empty_plte_permitted)
- {
- /* This function is deprecated in favor of png_permit_mng_features()
- and will be removed from libpng-1.3.0 */
- png_debug(1, "in png_permit_empty_plte, DEPRECATED.\n");
- if (png_ptr == NULL)
- return;
- png_ptr->mng_features_permitted = (png_byte)
- ((png_ptr->mng_features_permitted & (~(PNG_FLAG_MNG_EMPTY_PLTE))) |
- ((empty_plte_permitted & PNG_FLAG_MNG_EMPTY_PLTE)));
- }
- #endif
- #endif
-
- #if defined(PNG_MNG_FEATURES_SUPPORTED)
- png_uint_32 PNGAPI
- png_permit_mng_features (png_structp png_ptr, png_uint_32 mng_features)
- {
- png_debug(1, "in png_permit_mng_features\n");
- if (png_ptr == NULL)
- return (png_uint_32)0;
- png_ptr->mng_features_permitted =
- (png_byte)(mng_features & PNG_ALL_MNG_FEATURES);
- return (png_uint_32)png_ptr->mng_features_permitted;
- }
- #endif
-
- #if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
- void PNGAPI
- png_set_keep_unknown_chunks(png_structp png_ptr, int keep, png_bytep
- chunk_list, int num_chunks)
- {
- png_bytep new_list, p;
- int i, old_num_chunks;
- if (png_ptr == NULL)
- return;
- if (num_chunks == 0)
- {
- if(keep == PNG_HANDLE_CHUNK_ALWAYS || keep == PNG_HANDLE_CHUNK_IF_SAFE)
- png_ptr->flags |= PNG_FLAG_KEEP_UNKNOWN_CHUNKS;
- else
- png_ptr->flags &= ~PNG_FLAG_KEEP_UNKNOWN_CHUNKS;
-
- if(keep == PNG_HANDLE_CHUNK_ALWAYS)
- png_ptr->flags |= PNG_FLAG_KEEP_UNSAFE_CHUNKS;
- else
- png_ptr->flags &= ~PNG_FLAG_KEEP_UNSAFE_CHUNKS;
- return;
- }
- if (chunk_list == NULL)
- return;
- old_num_chunks=png_ptr->num_chunk_list;
- new_list=(png_bytep)png_malloc(png_ptr,
- (png_uint_32)(5*(num_chunks+old_num_chunks)));
- if(png_ptr->chunk_list != NULL)
- {
- png_memcpy(new_list, png_ptr->chunk_list,
- (png_size_t)(5*old_num_chunks));
- png_free(png_ptr, png_ptr->chunk_list);
- png_ptr->chunk_list=NULL;
- }
- png_memcpy(new_list+5*old_num_chunks, chunk_list,
- (png_size_t)(5*num_chunks));
- for (p=new_list+5*old_num_chunks+4, i=0; i<num_chunks; i++, p+=5)
- *p=(png_byte)keep;
- png_ptr->num_chunk_list=old_num_chunks+num_chunks;
- png_ptr->chunk_list=new_list;
- #ifdef PNG_FREE_ME_SUPPORTED
- png_ptr->free_me |= PNG_FREE_LIST;
- #endif
- }
- #endif
-
- #if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
- void PNGAPI
- png_set_read_user_chunk_fn(png_structp png_ptr, png_voidp user_chunk_ptr,
- png_user_chunk_ptr read_user_chunk_fn)
- {
- png_debug(1, "in png_set_read_user_chunk_fn\n");
- if (png_ptr == NULL)
- return;
- png_ptr->read_user_chunk_fn = read_user_chunk_fn;
- png_ptr->user_chunk_ptr = user_chunk_ptr;
- }
- #endif
-
- #if defined(PNG_INFO_IMAGE_SUPPORTED)
- void PNGAPI
- png_set_rows(png_structp png_ptr, png_infop info_ptr, png_bytepp row_pointers)
- {
- png_debug1(1, "in %s storage function\n", "rows");
-
- if (png_ptr == NULL || info_ptr == NULL)
- return;
-
- if(info_ptr->row_pointers && (info_ptr->row_pointers != row_pointers))
- png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0);
- info_ptr->row_pointers = row_pointers;
- if(row_pointers)
- info_ptr->valid |= PNG_INFO_IDAT;
- }
- #endif
-
- #ifdef PNG_WRITE_SUPPORTED
- void PNGAPI
- png_set_compression_buffer_size(png_structp png_ptr, png_uint_32 size)
- {
- if (png_ptr == NULL)
- return;
- if(png_ptr->zbuf)
- png_free(png_ptr, png_ptr->zbuf);
- png_ptr->zbuf_size = (png_size_t)size;
- png_ptr->zbuf = (png_bytep)png_malloc(png_ptr, size);
- png_ptr->zstream.next_out = png_ptr->zbuf;
- png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
- }
- #endif
-
- void PNGAPI
- png_set_invalid(png_structp png_ptr, png_infop info_ptr, int mask)
- {
- if (png_ptr && info_ptr)
- info_ptr->valid &= ~(mask);
- }
-
- #ifndef PNG_1_0_X
- #ifdef PNG_ASSEMBLER_CODE_SUPPORTED
- /* function was added to libpng 1.2.0 and should always exist by default */
- void PNGAPI
- png_set_asm_flags (png_structp png_ptr, png_uint_32 asm_flags)
- {
- /* Obsolete as of libpng-1.2.20 and will be removed from libpng-1.4.0 */
- if (png_ptr != NULL)
- png_ptr->asm_flags = 0;
- }
-
- /* this function was added to libpng 1.2.0 */
- void PNGAPI
- png_set_mmx_thresholds (png_structp png_ptr,
- png_byte mmx_bitdepth_threshold,
- png_uint_32 mmx_rowbytes_threshold)
- {
- /* Obsolete as of libpng-1.2.20 and will be removed from libpng-1.4.0 */
- if (png_ptr == NULL)
- return;
- }
- #endif /* ?PNG_ASSEMBLER_CODE_SUPPORTED */
-
- #ifdef PNG_SET_USER_LIMITS_SUPPORTED
- /* this function was added to libpng 1.2.6 */
- void PNGAPI
- png_set_user_limits (png_structp png_ptr, png_uint_32 user_width_max,
- png_uint_32 user_height_max)
- {
- /* Images with dimensions larger than these limits will be
- * rejected by png_set_IHDR(). To accept any PNG datastream
- * regardless of dimensions, set both limits to 0x7ffffffL.
- */
- if(png_ptr == NULL) return;
- png_ptr->user_width_max = user_width_max;
- png_ptr->user_height_max = user_height_max;
- }
- #endif /* ?PNG_SET_USER_LIMITS_SUPPORTED */
-
- #endif /* ?PNG_1_0_X */
- #endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */
- /********* End of inlined file: pngset.c *********/
-
- /********* Start of inlined file: pngtrans.c *********/
- /* pngtrans.c - transforms the data in a row (used by both readers and writers)
- *
- * Last changed in libpng 1.2.17 May 15, 2007
- * For conditions of distribution and use, see copyright notice in png.h
- * Copyright (c) 1998-2007 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
- */
-
- #define PNG_INTERNAL
-
- #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
- #if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
- /* turn on BGR-to-RGB mapping */
- void PNGAPI
- png_set_bgr(png_structp png_ptr)
- {
- png_debug(1, "in png_set_bgr\n");
- if(png_ptr == NULL) return;
- png_ptr->transformations |= PNG_BGR;
- }
- #endif
-
- #if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
- /* turn on 16 bit byte swapping */
- void PNGAPI
- png_set_swap(png_structp png_ptr)
- {
- png_debug(1, "in png_set_swap\n");
- if(png_ptr == NULL) return;
- if (png_ptr->bit_depth == 16)
- png_ptr->transformations |= PNG_SWAP_BYTES;
- }
- #endif
-
- #if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
- /* turn on pixel packing */
- void PNGAPI
- png_set_packing(png_structp png_ptr)
- {
- png_debug(1, "in png_set_packing\n");
- if(png_ptr == NULL) return;
- if (png_ptr->bit_depth < 8)
- {
- png_ptr->transformations |= PNG_PACK;
- png_ptr->usr_bit_depth = 8;
- }
- }
- #endif
-
- #if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
- /* turn on packed pixel swapping */
- void PNGAPI
- png_set_packswap(png_structp png_ptr)
- {
- png_debug(1, "in png_set_packswap\n");
- if(png_ptr == NULL) return;
- if (png_ptr->bit_depth < 8)
- png_ptr->transformations |= PNG_PACKSWAP;
- }
- #endif
-
- #if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
- void PNGAPI
- png_set_shift(png_structp png_ptr, png_color_8p true_bits)
- {
- png_debug(1, "in png_set_shift\n");
- if(png_ptr == NULL) return;
- png_ptr->transformations |= PNG_SHIFT;
- png_ptr->shift = *true_bits;
- }
- #endif
-
- #if defined(PNG_READ_INTERLACING_SUPPORTED) || \
- defined(PNG_WRITE_INTERLACING_SUPPORTED)
- int PNGAPI
- png_set_interlace_handling(png_structp png_ptr)
- {
- png_debug(1, "in png_set_interlace handling\n");
- if (png_ptr && png_ptr->interlaced)
- {
- png_ptr->transformations |= PNG_INTERLACE;
- return (7);
- }
-
- return (1);
- }
- #endif
-
- #if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
- /* Add a filler byte on read, or remove a filler or alpha byte on write.
- * The filler type has changed in v0.95 to allow future 2-byte fillers
- * for 48-bit input data, as well as to avoid problems with some compilers
- * that don't like bytes as parameters.
- */
- void PNGAPI
- png_set_filler(png_structp png_ptr, png_uint_32 filler, int filler_loc)
- {
- png_debug(1, "in png_set_filler\n");
- if(png_ptr == NULL) return;
- png_ptr->transformations |= PNG_FILLER;
- png_ptr->filler = (png_byte)filler;
- if (filler_loc == PNG_FILLER_AFTER)
- png_ptr->flags |= PNG_FLAG_FILLER_AFTER;
- else
- png_ptr->flags &= ~PNG_FLAG_FILLER_AFTER;
-
- /* This should probably go in the "do_read_filler" routine.
- * I attempted to do that in libpng-1.0.1a but that caused problems
- * so I restored it in libpng-1.0.2a
- */
-
- if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
- {
- png_ptr->usr_channels = 4;
- }
-
- /* Also I added this in libpng-1.0.2a (what happens when we expand
- * a less-than-8-bit grayscale to GA? */
-
- if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY && png_ptr->bit_depth >= 8)
- {
- png_ptr->usr_channels = 2;
- }
- }
-
- #if !defined(PNG_1_0_X)
- /* Added to libpng-1.2.7 */
- void PNGAPI
- png_set_add_alpha(png_structp png_ptr, png_uint_32 filler, int filler_loc)
- {
- png_debug(1, "in png_set_add_alpha\n");
- if(png_ptr == NULL) return;
- png_set_filler(png_ptr, filler, filler_loc);
- png_ptr->transformations |= PNG_ADD_ALPHA;
- }
- #endif
-
- #endif
-
- #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \
- defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
- void PNGAPI
- png_set_swap_alpha(png_structp png_ptr)
- {
- png_debug(1, "in png_set_swap_alpha\n");
- if(png_ptr == NULL) return;
- png_ptr->transformations |= PNG_SWAP_ALPHA;
- }
- #endif
-
- #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \
- defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
- void PNGAPI
- png_set_invert_alpha(png_structp png_ptr)
- {
- png_debug(1, "in png_set_invert_alpha\n");
- if(png_ptr == NULL) return;
- png_ptr->transformations |= PNG_INVERT_ALPHA;
- }
- #endif
-
- #if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
- void PNGAPI
- png_set_invert_mono(png_structp png_ptr)
- {
- png_debug(1, "in png_set_invert_mono\n");
- if(png_ptr == NULL) return;
- png_ptr->transformations |= PNG_INVERT_MONO;
- }
-
- /* invert monochrome grayscale data */
- void /* PRIVATE */
- png_do_invert(png_row_infop row_info, png_bytep row)
- {
- png_debug(1, "in png_do_invert\n");
- /* This test removed from libpng version 1.0.13 and 1.2.0:
- * if (row_info->bit_depth == 1 &&
- */
- #if defined(PNG_USELESS_TESTS_SUPPORTED)
- if (row == NULL || row_info == NULL)
- return;
- #endif
- if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
- {
- png_bytep rp = row;
- png_uint_32 i;
- png_uint_32 istop = row_info->rowbytes;
-
- for (i = 0; i < istop; i++)
- {
- *rp = (png_byte)(~(*rp));
- rp++;
- }
- }
- else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
- row_info->bit_depth == 8)
- {
- png_bytep rp = row;
- png_uint_32 i;
- png_uint_32 istop = row_info->rowbytes;
-
- for (i = 0; i < istop; i+=2)
- {
- *rp = (png_byte)(~(*rp));
- rp+=2;
- }
- }
- else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
- row_info->bit_depth == 16)
- {
- png_bytep rp = row;
- png_uint_32 i;
- png_uint_32 istop = row_info->rowbytes;
-
- for (i = 0; i < istop; i+=4)
- {
- *rp = (png_byte)(~(*rp));
- *(rp+1) = (png_byte)(~(*(rp+1)));
- rp+=4;
- }
- }
- }
- #endif
-
- #if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
- /* swaps byte order on 16 bit depth images */
- void /* PRIVATE */
- png_do_swap(png_row_infop row_info, png_bytep row)
- {
- png_debug(1, "in png_do_swap\n");
- if (
- #if defined(PNG_USELESS_TESTS_SUPPORTED)
- row != NULL && row_info != NULL &&
- #endif
- row_info->bit_depth == 16)
- {
- png_bytep rp = row;
- png_uint_32 i;
- png_uint_32 istop= row_info->width * row_info->channels;
-
- for (i = 0; i < istop; i++, rp += 2)
- {
- png_byte t = *rp;
- *rp = *(rp + 1);
- *(rp + 1) = t;
- }
- }
- }
- #endif
-
- #if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
- static PNG_CONST png_byte onebppswaptable[256] = {
- 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
- 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
- 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
- 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
- 0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,
- 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
- 0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC,
- 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
- 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
- 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
- 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
- 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
- 0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
- 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
- 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
- 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
- 0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1,
- 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
- 0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9,
- 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
- 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
- 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
- 0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED,
- 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
- 0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3,
- 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
- 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
- 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
- 0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7,
- 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
- 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF,
- 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
- };
-
- static PNG_CONST png_byte twobppswaptable[256] = {
- 0x00, 0x40, 0x80, 0xC0, 0x10, 0x50, 0x90, 0xD0,
- 0x20, 0x60, 0xA0, 0xE0, 0x30, 0x70, 0xB0, 0xF0,
- 0x04, 0x44, 0x84, 0xC4, 0x14, 0x54, 0x94, 0xD4,
- 0x24, 0x64, 0xA4, 0xE4, 0x34, 0x74, 0xB4, 0xF4,
- 0x08, 0x48, 0x88, 0xC8, 0x18, 0x58, 0x98, 0xD8,
- 0x28, 0x68, 0xA8, 0xE8, 0x38, 0x78, 0xB8, 0xF8,
- 0x0C, 0x4C, 0x8C, 0xCC, 0x1C, 0x5C, 0x9C, 0xDC,
- 0x2C, 0x6C, 0xAC, 0xEC, 0x3C, 0x7C, 0xBC, 0xFC,
- 0x01, 0x41, 0x81, 0xC1, 0x11, 0x51, 0x91, 0xD1,
- 0x21, 0x61, 0xA1, 0xE1, 0x31, 0x71, 0xB1, 0xF1,
- 0x05, 0x45, 0x85, 0xC5, 0x15, 0x55, 0x95, 0xD5,
- 0x25, 0x65, 0xA5, 0xE5, 0x35, 0x75, 0xB5, 0xF5,
- 0x09, 0x49, 0x89, 0xC9, 0x19, 0x59, 0x99, 0xD9,
- 0x29, 0x69, 0xA9, 0xE9, 0x39, 0x79, 0xB9, 0xF9,
- 0x0D, 0x4D, 0x8D, 0xCD, 0x1D, 0x5D, 0x9D, 0xDD,
- 0x2D, 0x6D, 0xAD, 0xED, 0x3D, 0x7D, 0xBD, 0xFD,
- 0x02, 0x42, 0x82, 0xC2, 0x12, 0x52, 0x92, 0xD2,
- 0x22, 0x62, 0xA2, 0xE2, 0x32, 0x72, 0xB2, 0xF2,
- 0x06, 0x46, 0x86, 0xC6, 0x16, 0x56, 0x96, 0xD6,
- 0x26, 0x66, 0xA6, 0xE6, 0x36, 0x76, 0xB6, 0xF6,
- 0x0A, 0x4A, 0x8A, 0xCA, 0x1A, 0x5A, 0x9A, 0xDA,
- 0x2A, 0x6A, 0xAA, 0xEA, 0x3A, 0x7A, 0xBA, 0xFA,
- 0x0E, 0x4E, 0x8E, 0xCE, 0x1E, 0x5E, 0x9E, 0xDE,
- 0x2E, 0x6E, 0xAE, 0xEE, 0x3E, 0x7E, 0xBE, 0xFE,
- 0x03, 0x43, 0x83, 0xC3, 0x13, 0x53, 0x93, 0xD3,
- 0x23, 0x63, 0xA3, 0xE3, 0x33, 0x73, 0xB3, 0xF3,
- 0x07, 0x47, 0x87, 0xC7, 0x17, 0x57, 0x97, 0xD7,
- 0x27, 0x67, 0xA7, 0xE7, 0x37, 0x77, 0xB7, 0xF7,
- 0x0B, 0x4B, 0x8B, 0xCB, 0x1B, 0x5B, 0x9B, 0xDB,
- 0x2B, 0x6B, 0xAB, 0xEB, 0x3B, 0x7B, 0xBB, 0xFB,
- 0x0F, 0x4F, 0x8F, 0xCF, 0x1F, 0x5F, 0x9F, 0xDF,
- 0x2F, 0x6F, 0xAF, 0xEF, 0x3F, 0x7F, 0xBF, 0xFF
- };
-
- static PNG_CONST png_byte fourbppswaptable[256] = {
- 0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70,
- 0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0,
- 0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71,
- 0x81, 0x91, 0xA1, 0xB1, 0xC1, 0xD1, 0xE1, 0xF1,
- 0x02, 0x12, 0x22, 0x32, 0x42, 0x52, 0x62, 0x72,
- 0x82, 0x92, 0xA2, 0xB2, 0xC2, 0xD2, 0xE2, 0xF2,
- 0x03, 0x13, 0x23, 0x33, 0x43, 0x53, 0x63, 0x73,
- 0x83, 0x93, 0xA3, 0xB3, 0xC3, 0xD3, 0xE3, 0xF3,
- 0x04, 0x14, 0x24, 0x34, 0x44, 0x54, 0x64, 0x74,
- 0x84, 0x94, 0xA4, 0xB4, 0xC4, 0xD4, 0xE4, 0xF4,
- 0x05, 0x15, 0x25, 0x35, 0x45, 0x55, 0x65, 0x75,
- 0x85, 0x95, 0xA5, 0xB5, 0xC5, 0xD5, 0xE5, 0xF5,
- 0x06, 0x16, 0x26, 0x36, 0x46, 0x56, 0x66, 0x76,
- 0x86, 0x96, 0xA6, 0xB6, 0xC6, 0xD6, 0xE6, 0xF6,
- 0x07, 0x17, 0x27, 0x37, 0x47, 0x57, 0x67, 0x77,
- 0x87, 0x97, 0xA7, 0xB7, 0xC7, 0xD7, 0xE7, 0xF7,
- 0x08, 0x18, 0x28, 0x38, 0x48, 0x58, 0x68, 0x78,
- 0x88, 0x98, 0xA8, 0xB8, 0xC8, 0xD8, 0xE8, 0xF8,
- 0x09, 0x19, 0x29, 0x39, 0x49, 0x59, 0x69, 0x79,
- 0x89, 0x99, 0xA9, 0xB9, 0xC9, 0xD9, 0xE9, 0xF9,
- 0x0A, 0x1A, 0x2A, 0x3A, 0x4A, 0x5A, 0x6A, 0x7A,
- 0x8A, 0x9A, 0xAA, 0xBA, 0xCA, 0xDA, 0xEA, 0xFA,
- 0x0B, 0x1B, 0x2B, 0x3B, 0x4B, 0x5B, 0x6B, 0x7B,
- 0x8B, 0x9B, 0xAB, 0xBB, 0xCB, 0xDB, 0xEB, 0xFB,
- 0x0C, 0x1C, 0x2C, 0x3C, 0x4C, 0x5C, 0x6C, 0x7C,
- 0x8C, 0x9C, 0xAC, 0xBC, 0xCC, 0xDC, 0xEC, 0xFC,
- 0x0D, 0x1D, 0x2D, 0x3D, 0x4D, 0x5D, 0x6D, 0x7D,
- 0x8D, 0x9D, 0xAD, 0xBD, 0xCD, 0xDD, 0xED, 0xFD,
- 0x0E, 0x1E, 0x2E, 0x3E, 0x4E, 0x5E, 0x6E, 0x7E,
- 0x8E, 0x9E, 0xAE, 0xBE, 0xCE, 0xDE, 0xEE, 0xFE,
- 0x0F, 0x1F, 0x2F, 0x3F, 0x4F, 0x5F, 0x6F, 0x7F,
- 0x8F, 0x9F, 0xAF, 0xBF, 0xCF, 0xDF, 0xEF, 0xFF
- };
-
- /* swaps pixel packing order within bytes */
- void /* PRIVATE */
- png_do_packswap(png_row_infop row_info, png_bytep row)
- {
- png_debug(1, "in png_do_packswap\n");
- if (
- #if defined(PNG_USELESS_TESTS_SUPPORTED)
- row != NULL && row_info != NULL &&
- #endif
- row_info->bit_depth < 8)
- {
- png_bytep rp, end, table;
-
- end = row + row_info->rowbytes;
-
- if (row_info->bit_depth == 1)
- table = (png_bytep)onebppswaptable;
- else if (row_info->bit_depth == 2)
- table = (png_bytep)twobppswaptable;
- else if (row_info->bit_depth == 4)
- table = (png_bytep)fourbppswaptable;
- else
- return;
-
- for (rp = row; rp < end; rp++)
- *rp = table[*rp];
- }
- }
- #endif /* PNG_READ_PACKSWAP_SUPPORTED or PNG_WRITE_PACKSWAP_SUPPORTED */
-
- #if defined(PNG_WRITE_FILLER_SUPPORTED) || \
- defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
- /* remove filler or alpha byte(s) */
- void /* PRIVATE */
- png_do_strip_filler(png_row_infop row_info, png_bytep row, png_uint_32 flags)
- {
- png_debug(1, "in png_do_strip_filler\n");
- #if defined(PNG_USELESS_TESTS_SUPPORTED)
- if (row != NULL && row_info != NULL)
- #endif
- {
- png_bytep sp=row;
- png_bytep dp=row;
- png_uint_32 row_width=row_info->width;
- png_uint_32 i;
-
- if ((row_info->color_type == PNG_COLOR_TYPE_RGB ||
- (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA &&
- (flags & PNG_FLAG_STRIP_ALPHA))) &&
- row_info->channels == 4)
- {
- if (row_info->bit_depth == 8)
- {
- /* This converts from RGBX or RGBA to RGB */
- if (flags & PNG_FLAG_FILLER_AFTER)
- {
- dp+=3; sp+=4;
- for (i = 1; i < row_width; i++)
- {
- *dp++ = *sp++;
- *dp++ = *sp++;
- *dp++ = *sp++;
- sp++;
- }
- }
- /* This converts from XRGB or ARGB to RGB */
- else
- {
- for (i = 0; i < row_width; i++)
- {
- sp++;
- *dp++ = *sp++;
- *dp++ = *sp++;
- *dp++ = *sp++;
- }
- }
- row_info->pixel_depth = 24;
- row_info->rowbytes = row_width * 3;
- }
- else /* if (row_info->bit_depth == 16) */
- {
- if (flags & PNG_FLAG_FILLER_AFTER)
- {
- /* This converts from RRGGBBXX or RRGGBBAA to RRGGBB */
- sp += 8; dp += 6;
- for (i = 1; i < row_width; i++)
- {
- /* This could be (although png_memcpy is probably slower):
- png_memcpy(dp, sp, 6);
- sp += 8;
- dp += 6;
- */
-
- *dp++ = *sp++;
- *dp++ = *sp++;
- *dp++ = *sp++;
- *dp++ = *sp++;
- *dp++ = *sp++;
- *dp++ = *sp++;
- sp += 2;
- }
- }
- else
- {
- /* This converts from XXRRGGBB or AARRGGBB to RRGGBB */
- for (i = 0; i < row_width; i++)
- {
- /* This could be (although png_memcpy is probably slower):
- png_memcpy(dp, sp, 6);
- sp += 8;
- dp += 6;
- */
-
- sp+=2;
- *dp++ = *sp++;
- *dp++ = *sp++;
- *dp++ = *sp++;
- *dp++ = *sp++;
- *dp++ = *sp++;
- *dp++ = *sp++;
- }
- }
- row_info->pixel_depth = 48;
- row_info->rowbytes = row_width * 6;
- }
- row_info->channels = 3;
- }
- else if ((row_info->color_type == PNG_COLOR_TYPE_GRAY ||
- (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
- (flags & PNG_FLAG_STRIP_ALPHA))) &&
- row_info->channels == 2)
- {
- if (row_info->bit_depth == 8)
- {
- /* This converts from GX or GA to G */
- if (flags & PNG_FLAG_FILLER_AFTER)
- {
- for (i = 0; i < row_width; i++)
- {
- *dp++ = *sp++;
- sp++;
- }
- }
- /* This converts from XG or AG to G */
- else
- {
- for (i = 0; i < row_width; i++)
- {
- sp++;
- *dp++ = *sp++;
- }
- }
- row_info->pixel_depth = 8;
- row_info->rowbytes = row_width;
- }
- else /* if (row_info->bit_depth == 16) */
- {
- if (flags & PNG_FLAG_FILLER_AFTER)
- {
- /* This converts from GGXX or GGAA to GG */
- sp += 4; dp += 2;
- for (i = 1; i < row_width; i++)
- {
- *dp++ = *sp++;
- *dp++ = *sp++;
- sp += 2;
- }
- }
- else
- {
- /* This converts from XXGG or AAGG to GG */
- for (i = 0; i < row_width; i++)
- {
- sp += 2;
- *dp++ = *sp++;
- *dp++ = *sp++;
- }
- }
- row_info->pixel_depth = 16;
- row_info->rowbytes = row_width * 2;
- }
- row_info->channels = 1;
- }
- if (flags & PNG_FLAG_STRIP_ALPHA)
- row_info->color_type &= ~PNG_COLOR_MASK_ALPHA;
- }
- }
- #endif
-
- #if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
- /* swaps red and blue bytes within a pixel */
- void /* PRIVATE */
- png_do_bgr(png_row_infop row_info, png_bytep row)
- {
- png_debug(1, "in png_do_bgr\n");
- if (
- #if defined(PNG_USELESS_TESTS_SUPPORTED)
- row != NULL && row_info != NULL &&
- #endif
- (row_info->color_type & PNG_COLOR_MASK_COLOR))
- {
- png_uint_32 row_width = row_info->width;
- if (row_info->bit_depth == 8)
- {
- if (row_info->color_type == PNG_COLOR_TYPE_RGB)
- {
- png_bytep rp;
- png_uint_32 i;
-
- for (i = 0, rp = row; i < row_width; i++, rp += 3)
- {
- png_byte save = *rp;
- *rp = *(rp + 2);
- *(rp + 2) = save;
- }
- }
- else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
- {
- png_bytep rp;
- png_uint_32 i;
-
- for (i = 0, rp = row; i < row_width; i++, rp += 4)
- {
- png_byte save = *rp;
- *rp = *(rp + 2);
- *(rp + 2) = save;
- }
- }
- }
- else if (row_info->bit_depth == 16)
- {
- if (row_info->color_type == PNG_COLOR_TYPE_RGB)
- {
- png_bytep rp;
- png_uint_32 i;
-
- for (i = 0, rp = row; i < row_width; i++, rp += 6)
- {
- png_byte save = *rp;
- *rp = *(rp + 4);
- *(rp + 4) = save;
- save = *(rp + 1);
- *(rp + 1) = *(rp + 5);
- *(rp + 5) = save;
- }
- }
- else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
- {
- png_bytep rp;
- png_uint_32 i;
-
- for (i = 0, rp = row; i < row_width; i++, rp += 8)
- {
- png_byte save = *rp;
- *rp = *(rp + 4);
- *(rp + 4) = save;
- save = *(rp + 1);
- *(rp + 1) = *(rp + 5);
- *(rp + 5) = save;
- }
- }
- }
- }
- }
- #endif /* PNG_READ_BGR_SUPPORTED or PNG_WRITE_BGR_SUPPORTED */
-
- #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
- defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \
- defined(PNG_LEGACY_SUPPORTED)
- void PNGAPI
- png_set_user_transform_info(png_structp png_ptr, png_voidp
- user_transform_ptr, int user_transform_depth, int user_transform_channels)
- {
- png_debug(1, "in png_set_user_transform_info\n");
- if(png_ptr == NULL) return;
- #if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
- png_ptr->user_transform_ptr = user_transform_ptr;
- png_ptr->user_transform_depth = (png_byte)user_transform_depth;
- png_ptr->user_transform_channels = (png_byte)user_transform_channels;
- #else
- if(user_transform_ptr || user_transform_depth || user_transform_channels)
- png_warning(png_ptr,
- "This version of libpng does not support user transform info");
- #endif
- }
- #endif
-
- /* This function returns a pointer to the user_transform_ptr associated with
- * the user transform functions. The application should free any memory
- * associated with this pointer before png_write_destroy and png_read_destroy
- * are called.
- */
- png_voidp PNGAPI
- png_get_user_transform_ptr(png_structp png_ptr)
- {
- #if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
- if (png_ptr == NULL) return (NULL);
- return ((png_voidp)png_ptr->user_transform_ptr);
- #else
- return (NULL);
- #endif
- }
- #endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */
- /********* End of inlined file: pngtrans.c *********/
-
- /********* Start of inlined file: pngwio.c *********/
- /* pngwio.c - functions for data output
- *
- * Last changed in libpng 1.2.13 November 13, 2006
- * For conditions of distribution and use, see copyright notice in png.h
- * Copyright (c) 1998-2006 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
- *
- * This file provides a location for all output. Users who need
- * special handling are expected to write functions that have the same
- * arguments as these and perform similar functions, but that possibly
- * use different output methods. Note that you shouldn't change these
- * functions, but rather write replacement functions and then change
- * them at run time with png_set_write_fn(...).
- */
-
- #define PNG_INTERNAL
-
- #ifdef PNG_WRITE_SUPPORTED
-
- /* Write the data to whatever output you are using. The default routine
- writes to a file pointer. Note that this routine sometimes gets called
- with very small lengths, so you should implement some kind of simple
- buffering if you are using unbuffered writes. This should never be asked
- to write more than 64K on a 16 bit machine. */
-
- void /* PRIVATE */
- png_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
- {
- if (png_ptr->write_data_fn != NULL )
- (*(png_ptr->write_data_fn))(png_ptr, data, length);
- else
- png_error(png_ptr, "Call to NULL write function");
- }
-
- #if !defined(PNG_NO_STDIO)
- /* This is the function that does the actual writing of data. If you are
- not writing to a standard C stream, you should create a replacement
- write_data function and use it at run time with png_set_write_fn(), rather
- than changing the library. */
- #ifndef USE_FAR_KEYWORD
- void PNGAPI
- png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
- {
- png_uint_32 check;
-
- if(png_ptr == NULL) return;
- #if defined(_WIN32_WCE)
- if ( !WriteFile((HANDLE)(png_ptr->io_ptr), data, length, &check, NULL) )
- check = 0;
- #else
- check = fwrite(data, 1, length, (png_FILE_p)(png_ptr->io_ptr));
- #endif
- if (check != length)
- png_error(png_ptr, "Write Error");
- }
- #else
- /* this is the model-independent version. Since the standard I/O library
- can't handle far buffers in the medium and small models, we have to copy
- the data.
- */
-
- #define NEAR_BUF_SIZE 1024
- #define MIN(a,b) (a <= b ? a : b)
-
- void PNGAPI
- png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
- {
- png_uint_32 check;
- png_byte *near_data; /* Needs to be "png_byte *" instead of "png_bytep" */
- png_FILE_p io_ptr;
-
- if(png_ptr == NULL) return;
- /* Check if data really is near. If so, use usual code. */
- near_data = (png_byte *)CVT_PTR_NOCHECK(data);
- io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr);
- if ((png_bytep)near_data == data)
- {
- #if defined(_WIN32_WCE)
- if ( !WriteFile(io_ptr, near_data, length, &check, NULL) )
- check = 0;
- #else
- check = fwrite(near_data, 1, length, io_ptr);
- #endif
- }
- else
- {
- png_byte buf[NEAR_BUF_SIZE];
- png_size_t written, remaining, err;
- check = 0;
- remaining = length;
- do
- {
- written = MIN(NEAR_BUF_SIZE, remaining);
- png_memcpy(buf, data, written); /* copy far buffer to near buffer */
- #if defined(_WIN32_WCE)
- if ( !WriteFile(io_ptr, buf, written, &err, NULL) )
- err = 0;
- #else
- err = fwrite(buf, 1, written, io_ptr);
- #endif
- if (err != written)
- break;
- else
- check += err;
- data += written;
- remaining -= written;
- }
- while (remaining != 0);
- }
- if (check != length)
- png_error(png_ptr, "Write Error");
- }
-
- #endif
- #endif
-
- /* This function is called to output any data pending writing (normally
- to disk). After png_flush is called, there should be no data pending
- writing in any buffers. */
- #if defined(PNG_WRITE_FLUSH_SUPPORTED)
- void /* PRIVATE */
- png_flush(png_structp png_ptr)
- {
- if (png_ptr->output_flush_fn != NULL)
- (*(png_ptr->output_flush_fn))(png_ptr);
- }
-
- #if !defined(PNG_NO_STDIO)
- void PNGAPI
- png_default_flush(png_structp png_ptr)
- {
- #if !defined(_WIN32_WCE)
- png_FILE_p io_ptr;
- #endif
- if(png_ptr == NULL) return;
- #if !defined(_WIN32_WCE)
- io_ptr = (png_FILE_p)CVT_PTR((png_ptr->io_ptr));
- if (io_ptr != NULL)
- fflush(io_ptr);
- #endif
- }
- #endif
- #endif
-
- /* This function allows the application to supply new output functions for
- libpng if standard C streams aren't being used.
-
- This function takes as its arguments:
- png_ptr - pointer to a png output data structure
- io_ptr - pointer to user supplied structure containing info about
- the output functions. May be NULL.
- write_data_fn - pointer to a new output function that takes as its
- arguments a pointer to a png_struct, a pointer to
- data to be written, and a 32-bit unsigned int that is
- the number of bytes to be written. The new write
- function should call png_error(png_ptr, "Error msg")
- to exit and output any fatal error messages.
- flush_data_fn - pointer to a new flush function that takes as its
- arguments a pointer to a png_struct. After a call to
- the flush function, there should be no data in any buffers
- or pending transmission. If the output method doesn't do
- any buffering of ouput, a function prototype must still be
- supplied although it doesn't have to do anything. If
- PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng compile
- time, output_flush_fn will be ignored, although it must be
- supplied for compatibility. */
- void PNGAPI
- png_set_write_fn(png_structp png_ptr, png_voidp io_ptr,
- png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn)
- {
- if(png_ptr == NULL) return;
- png_ptr->io_ptr = io_ptr;
-
- #if !defined(PNG_NO_STDIO)
- if (write_data_fn != NULL)
- png_ptr->write_data_fn = write_data_fn;
- else
- png_ptr->write_data_fn = png_default_write_data;
- #else
- png_ptr->write_data_fn = write_data_fn;
- #endif
-
- #if defined(PNG_WRITE_FLUSH_SUPPORTED)
- #if !defined(PNG_NO_STDIO)
- if (output_flush_fn != NULL)
- png_ptr->output_flush_fn = output_flush_fn;
- else
- png_ptr->output_flush_fn = png_default_flush;
- #else
- png_ptr->output_flush_fn = output_flush_fn;
- #endif
- #endif /* PNG_WRITE_FLUSH_SUPPORTED */
-
- /* It is an error to read while writing a png file */
- if (png_ptr->read_data_fn != NULL)
- {
- png_ptr->read_data_fn = NULL;
- png_warning(png_ptr,
- "Attempted to set both read_data_fn and write_data_fn in");
- png_warning(png_ptr,
- "the same structure. Resetting read_data_fn to NULL.");
- }
- }
-
- #if defined(USE_FAR_KEYWORD)
- #if defined(_MSC_VER)
- void *png_far_to_near(png_structp png_ptr,png_voidp ptr, int check)
- {
- void *near_ptr;
- void FAR *far_ptr;
- FP_OFF(near_ptr) = FP_OFF(ptr);
- far_ptr = (void FAR *)near_ptr;
- if(check != 0)
- if(FP_SEG(ptr) != FP_SEG(far_ptr))
- png_error(png_ptr,"segment lost in conversion");
- return(near_ptr);
- }
- # else
- void *png_far_to_near(png_structp png_ptr,png_voidp ptr, int check)
- {
- void *near_ptr;
- void FAR *far_ptr;
- near_ptr = (void FAR *)ptr;
- far_ptr = (void FAR *)near_ptr;
- if(check != 0)
- if(far_ptr != ptr)
- png_error(png_ptr,"segment lost in conversion");
- return(near_ptr);
- }
- # endif
- # endif
- #endif /* PNG_WRITE_SUPPORTED */
- /********* End of inlined file: pngwio.c *********/
-
- /********* Start of inlined file: pngwrite.c *********/
- /* pngwrite.c - general routines to write a PNG file
- *
- * Last changed in libpng 1.2.15 January 5, 2007
- * For conditions of distribution and use, see copyright notice in png.h
- * Copyright (c) 1998-2007 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
- */
-
- /* get internal access to png.h */
- #define PNG_INTERNAL
-
- #ifdef PNG_WRITE_SUPPORTED
-
- /* Writes all the PNG information. This is the suggested way to use the
- * library. If you have a new chunk to add, make a function to write it,
- * and put it in the correct location here. If you want the chunk written
- * after the image data, put it in png_write_end(). I strongly encourage
- * you to supply a PNG_INFO_ flag, and check info_ptr->valid before writing
- * the chunk, as that will keep the code from breaking if you want to just
- * write a plain PNG file. If you have long comments, I suggest writing
- * them in png_write_end(), and compressing them.
- */
- void PNGAPI
- png_write_info_before_PLTE(png_structp png_ptr, png_infop info_ptr)
- {
- png_debug(1, "in png_write_info_before_PLTE\n");
- if (png_ptr == NULL || info_ptr == NULL)
- return;
- if (!(png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE))
- {
- png_write_sig(png_ptr); /* write PNG signature */
- #if defined(PNG_MNG_FEATURES_SUPPORTED)
- if((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE)&&(png_ptr->mng_features_permitted))
- {
- png_warning(png_ptr,"MNG features are not allowed in a PNG datastream");
- png_ptr->mng_features_permitted=0;
- }
- #endif
- /* write IHDR information. */
- png_write_IHDR(png_ptr, info_ptr->width, info_ptr->height,
- info_ptr->bit_depth, info_ptr->color_type, info_ptr->compression_type,
- info_ptr->filter_type,
- #if defined(PNG_WRITE_INTERLACING_SUPPORTED)
- info_ptr->interlace_type);
- #else
- 0);
- #endif
- /* the rest of these check to see if the valid field has the appropriate
- flag set, and if it does, writes the chunk. */
- #if defined(PNG_WRITE_gAMA_SUPPORTED)
- if (info_ptr->valid & PNG_INFO_gAMA)
- {
- # ifdef PNG_FLOATING_POINT_SUPPORTED
- png_write_gAMA(png_ptr, info_ptr->gamma);
- #else
- #ifdef PNG_FIXED_POINT_SUPPORTED
- png_write_gAMA_fixed(png_ptr, info_ptr->int_gamma);
- # endif
- #endif
- }
- #endif
- #if defined(PNG_WRITE_sRGB_SUPPORTED)
- if (info_ptr->valid & PNG_INFO_sRGB)
- png_write_sRGB(png_ptr, (int)info_ptr->srgb_intent);
- #endif
- #if defined(PNG_WRITE_iCCP_SUPPORTED)
- if (info_ptr->valid & PNG_INFO_iCCP)
- png_write_iCCP(png_ptr, info_ptr->iccp_name, PNG_COMPRESSION_TYPE_BASE,
- info_ptr->iccp_profile, (int)info_ptr->iccp_proflen);
- #endif
- #if defined(PNG_WRITE_sBIT_SUPPORTED)
- if (info_ptr->valid & PNG_INFO_sBIT)
- png_write_sBIT(png_ptr, &(info_ptr->sig_bit), info_ptr->color_type);
- #endif
- #if defined(PNG_WRITE_cHRM_SUPPORTED)
- if (info_ptr->valid & PNG_INFO_cHRM)
- {
- #ifdef PNG_FLOATING_POINT_SUPPORTED
- png_write_cHRM(png_ptr,
- info_ptr->x_white, info_ptr->y_white,
- info_ptr->x_red, info_ptr->y_red,
- info_ptr->x_green, info_ptr->y_green,
- info_ptr->x_blue, info_ptr->y_blue);
- #else
- # ifdef PNG_FIXED_POINT_SUPPORTED
- png_write_cHRM_fixed(png_ptr,
- info_ptr->int_x_white, info_ptr->int_y_white,
- info_ptr->int_x_red, info_ptr->int_y_red,
- info_ptr->int_x_green, info_ptr->int_y_green,
- info_ptr->int_x_blue, info_ptr->int_y_blue);
- # endif
- #endif
- }
- #endif
- #if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED)
- if (info_ptr->unknown_chunks_num)
- {
- png_unknown_chunk *up;
-
- png_debug(5, "writing extra chunks\n");
-
- for (up = info_ptr->unknown_chunks;
- up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num;
- up++)
- {
- int keep=png_handle_as_unknown(png_ptr, up->name);
- if (keep != PNG_HANDLE_CHUNK_NEVER &&
- up->location && !(up->location & PNG_HAVE_PLTE) &&
- !(up->location & PNG_HAVE_IDAT) &&
- ((up->name[3] & 0x20) || keep == PNG_HANDLE_CHUNK_ALWAYS ||
- (png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS)))
- {
- png_write_chunk(png_ptr, up->name, up->data, up->size);
- }
- }
- }
- #endif
- png_ptr->mode |= PNG_WROTE_INFO_BEFORE_PLTE;
- }
- }
-
- void PNGAPI
- png_write_info(png_structp png_ptr, png_infop info_ptr)
- {
- #if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED)
- int i;
- #endif
-
- png_debug(1, "in png_write_info\n");
-
- if (png_ptr == NULL || info_ptr == NULL)
- return;
-
- png_write_info_before_PLTE(png_ptr, info_ptr);
-
- if (info_ptr->valid & PNG_INFO_PLTE)
- png_write_PLTE(png_ptr, info_ptr->palette,
- (png_uint_32)info_ptr->num_palette);
- else if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
- png_error(png_ptr, "Valid palette required for paletted images");
-
- #if defined(PNG_WRITE_tRNS_SUPPORTED)
- if (info_ptr->valid & PNG_INFO_tRNS)
- {
- #if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
- /* invert the alpha channel (in tRNS) */
- if ((png_ptr->transformations & PNG_INVERT_ALPHA) &&
- info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
- {
- int j;
- for (j=0; j<(int)info_ptr->num_trans; j++)
- info_ptr->trans[j] = (png_byte)(255 - info_ptr->trans[j]);
- }
- #endif
- png_write_tRNS(png_ptr, info_ptr->trans, &(info_ptr->trans_values),
- info_ptr->num_trans, info_ptr->color_type);
- }
- #endif
- #if defined(PNG_WRITE_bKGD_SUPPORTED)
- if (info_ptr->valid & PNG_INFO_bKGD)
- png_write_bKGD(png_ptr, &(info_ptr->background), info_ptr->color_type);
- #endif
- #if defined(PNG_WRITE_hIST_SUPPORTED)
- if (info_ptr->valid & PNG_INFO_hIST)
- png_write_hIST(png_ptr, info_ptr->hist, info_ptr->num_palette);
- #endif
- #if defined(PNG_WRITE_oFFs_SUPPORTED)
- if (info_ptr->valid & PNG_INFO_oFFs)
- png_write_oFFs(png_ptr, info_ptr->x_offset, info_ptr->y_offset,
- info_ptr->offset_unit_type);
- #endif
- #if defined(PNG_WRITE_pCAL_SUPPORTED)
- if (info_ptr->valid & PNG_INFO_pCAL)
- png_write_pCAL(png_ptr, info_ptr->pcal_purpose, info_ptr->pcal_X0,
- info_ptr->pcal_X1, info_ptr->pcal_type, info_ptr->pcal_nparams,
- info_ptr->pcal_units, info_ptr->pcal_params);
- #endif
- #if defined(PNG_WRITE_sCAL_SUPPORTED)
- if (info_ptr->valid & PNG_INFO_sCAL)
- #if defined(PNG_FLOATING_POINT_SUPPORTED) && !defined(PNG_NO_STDIO)
- png_write_sCAL(png_ptr, (int)info_ptr->scal_unit,
- info_ptr->scal_pixel_width, info_ptr->scal_pixel_height);
- #else
- #ifdef PNG_FIXED_POINT_SUPPORTED
- png_write_sCAL_s(png_ptr, (int)info_ptr->scal_unit,
- info_ptr->scal_s_width, info_ptr->scal_s_height);
- #else
- png_warning(png_ptr,
- "png_write_sCAL not supported; sCAL chunk not written.");
- #endif
- #endif
- #endif
- #if defined(PNG_WRITE_pHYs_SUPPORTED)
- if (info_ptr->valid & PNG_INFO_pHYs)
- png_write_pHYs(png_ptr, info_ptr->x_pixels_per_unit,
- info_ptr->y_pixels_per_unit, info_ptr->phys_unit_type);
- #endif
- #if defined(PNG_WRITE_tIME_SUPPORTED)
- if (info_ptr->valid & PNG_INFO_tIME)
- {
- png_write_tIME(png_ptr, &(info_ptr->mod_time));
- png_ptr->mode |= PNG_WROTE_tIME;
- }
- #endif
- #if defined(PNG_WRITE_sPLT_SUPPORTED)
- if (info_ptr->valid & PNG_INFO_sPLT)
- for (i = 0; i < (int)info_ptr->splt_palettes_num; i++)
- png_write_sPLT(png_ptr, info_ptr->splt_palettes + i);
- #endif
- #if defined(PNG_WRITE_TEXT_SUPPORTED)
- /* Check to see if we need to write text chunks */
- for (i = 0; i < info_ptr->num_text; i++)
- {
- png_debug2(2, "Writing header text chunk %d, type %d\n", i,
- info_ptr->text[i].compression);
- /* an internationalized chunk? */
- if (info_ptr->text[i].compression > 0)
- {
- #if defined(PNG_WRITE_iTXt_SUPPORTED)
- /* write international chunk */
- png_write_iTXt(png_ptr,
- info_ptr->text[i].compression,
- info_ptr->text[i].key,
- info_ptr->text[i].lang,
- info_ptr->text[i].lang_key,
- info_ptr->text[i].text);
- #else
- png_warning(png_ptr, "Unable to write international text");
- #endif
- /* Mark this chunk as written */
- info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
- }
- /* If we want a compressed text chunk */
- else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_zTXt)
- {
- #if defined(PNG_WRITE_zTXt_SUPPORTED)
- /* write compressed chunk */
- png_write_zTXt(png_ptr, info_ptr->text[i].key,
- info_ptr->text[i].text, 0,
- info_ptr->text[i].compression);
- #else
- png_warning(png_ptr, "Unable to write compressed text");
- #endif
- /* Mark this chunk as written */
- info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR;
- }
- else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE)
- {
- #if defined(PNG_WRITE_tEXt_SUPPORTED)
- /* write uncompressed chunk */
- png_write_tEXt(png_ptr, info_ptr->text[i].key,
- info_ptr->text[i].text,
- 0);
- #else
- png_warning(png_ptr, "Unable to write uncompressed text");
- #endif
- /* Mark this chunk as written */
- info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
- }
- }
- #endif
- #if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED)
- if (info_ptr->unknown_chunks_num)
- {
- png_unknown_chunk *up;
-
- png_debug(5, "writing extra chunks\n");
-
- for (up = info_ptr->unknown_chunks;
- up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num;
- up++)
- {
- int keep=png_handle_as_unknown(png_ptr, up->name);
- if (keep != PNG_HANDLE_CHUNK_NEVER &&
- up->location && (up->location & PNG_HAVE_PLTE) &&
- !(up->location & PNG_HAVE_IDAT) &&
- ((up->name[3] & 0x20) || keep == PNG_HANDLE_CHUNK_ALWAYS ||
- (png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS)))
- {
- png_write_chunk(png_ptr, up->name, up->data, up->size);
- }
- }
- }
- #endif
- }
-
- /* Writes the end of the PNG file. If you don't want to write comments or
- * time information, you can pass NULL for info. If you already wrote these
- * in png_write_info(), do not write them again here. If you have long
- * comments, I suggest writing them here, and compressing them.
- */
- void PNGAPI
- png_write_end(png_structp png_ptr, png_infop info_ptr)
- {
- png_debug(1, "in png_write_end\n");
- if (png_ptr == NULL)
- return;
- if (!(png_ptr->mode & PNG_HAVE_IDAT))
- png_error(png_ptr, "No IDATs written into file");
-
- /* see if user wants us to write information chunks */
- if (info_ptr != NULL)
- {
- #if defined(PNG_WRITE_TEXT_SUPPORTED)
- int i; /* local index variable */
- #endif
- #if defined(PNG_WRITE_tIME_SUPPORTED)
- /* check to see if user has supplied a time chunk */
- if ((info_ptr->valid & PNG_INFO_tIME) &&
- !(png_ptr->mode & PNG_WROTE_tIME))
- png_write_tIME(png_ptr, &(info_ptr->mod_time));
- #endif
- #if defined(PNG_WRITE_TEXT_SUPPORTED)
- /* loop through comment chunks */
- for (i = 0; i < info_ptr->num_text; i++)
- {
- png_debug2(2, "Writing trailer text chunk %d, type %d\n", i,
- info_ptr->text[i].compression);
- /* an internationalized chunk? */
- if (info_ptr->text[i].compression > 0)
- {
- #if defined(PNG_WRITE_iTXt_SUPPORTED)
- /* write international chunk */
- png_write_iTXt(png_ptr,
- info_ptr->text[i].compression,
- info_ptr->text[i].key,
- info_ptr->text[i].lang,
- info_ptr->text[i].lang_key,
- info_ptr->text[i].text);
- #else
- png_warning(png_ptr, "Unable to write international text");
- #endif
- /* Mark this chunk as written */
- info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
- }
- else if (info_ptr->text[i].compression >= PNG_TEXT_COMPRESSION_zTXt)
- {
- #if defined(PNG_WRITE_zTXt_SUPPORTED)
- /* write compressed chunk */
- png_write_zTXt(png_ptr, info_ptr->text[i].key,
- info_ptr->text[i].text, 0,
- info_ptr->text[i].compression);
- #else
- png_warning(png_ptr, "Unable to write compressed text");
- #endif
- /* Mark this chunk as written */
- info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR;
- }
- else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE)
- {
- #if defined(PNG_WRITE_tEXt_SUPPORTED)
- /* write uncompressed chunk */
- png_write_tEXt(png_ptr, info_ptr->text[i].key,
- info_ptr->text[i].text, 0);
- #else
- png_warning(png_ptr, "Unable to write uncompressed text");
- #endif
-
- /* Mark this chunk as written */
- info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
- }
- }
- #endif
- #if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED)
- if (info_ptr->unknown_chunks_num)
- {
- png_unknown_chunk *up;
-
- png_debug(5, "writing extra chunks\n");
-
- for (up = info_ptr->unknown_chunks;
- up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num;
- up++)
- {
- int keep=png_handle_as_unknown(png_ptr, up->name);
- if (keep != PNG_HANDLE_CHUNK_NEVER &&
- up->location && (up->location & PNG_AFTER_IDAT) &&
- ((up->name[3] & 0x20) || keep == PNG_HANDLE_CHUNK_ALWAYS ||
- (png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS)))
- {
- png_write_chunk(png_ptr, up->name, up->data, up->size);
- }
- }
- }
- #endif
- }
-
- png_ptr->mode |= PNG_AFTER_IDAT;
-
- /* write end of PNG file */
- png_write_IEND(png_ptr);
- }
-
- #if defined(PNG_WRITE_tIME_SUPPORTED)
- #if !defined(_WIN32_WCE)
- /* "time.h" functions are not supported on WindowsCE */
- void PNGAPI
- png_convert_from_struct_tm(png_timep ptime, struct tm FAR * ttime)
- {
- png_debug(1, "in png_convert_from_struct_tm\n");
- ptime->year = (png_uint_16)(1900 + ttime->tm_year);
- ptime->month = (png_byte)(ttime->tm_mon + 1);
- ptime->day = (png_byte)ttime->tm_mday;
- ptime->hour = (png_byte)ttime->tm_hour;
- ptime->minute = (png_byte)ttime->tm_min;
- ptime->second = (png_byte)ttime->tm_sec;
- }
-
- void PNGAPI
- png_convert_from_time_t(png_timep ptime, time_t ttime)
- {
- struct tm *tbuf;
-
- png_debug(1, "in png_convert_from_time_t\n");
- tbuf = gmtime(&ttime);
- png_convert_from_struct_tm(ptime, tbuf);
- }
- #endif
- #endif
-
- /* Initialize png_ptr structure, and allocate any memory needed */
- png_structp PNGAPI
- png_create_write_struct(png_const_charp user_png_ver, png_voidp error_ptr,
- png_error_ptr error_fn, png_error_ptr warn_fn)
- {
- #ifdef PNG_USER_MEM_SUPPORTED
- return (png_create_write_struct_2(user_png_ver, error_ptr, error_fn,
- warn_fn, png_voidp_NULL, png_malloc_ptr_NULL, png_free_ptr_NULL));
- }
-
- /* Alternate initialize png_ptr structure, and allocate any memory needed */
- png_structp PNGAPI
- png_create_write_struct_2(png_const_charp user_png_ver, png_voidp error_ptr,
- png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
- png_malloc_ptr malloc_fn, png_free_ptr free_fn)
- {
- #endif /* PNG_USER_MEM_SUPPORTED */
- png_structp png_ptr;
- #ifdef PNG_SETJMP_SUPPORTED
- #ifdef USE_FAR_KEYWORD
- jmp_buf jmpbuf;
- #endif
- #endif
- int i;
- png_debug(1, "in png_create_write_struct\n");
- #ifdef PNG_USER_MEM_SUPPORTED
- png_ptr = (png_structp)png_create_struct_2(PNG_STRUCT_PNG,
- (png_malloc_ptr)malloc_fn, (png_voidp)mem_ptr);
- #else
- png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG);
- #endif /* PNG_USER_MEM_SUPPORTED */
- if (png_ptr == NULL)
- return (NULL);
-
- /* added at libpng-1.2.6 */
- #ifdef PNG_SET_USER_LIMITS_SUPPORTED
- png_ptr->user_width_max=PNG_USER_WIDTH_MAX;
- png_ptr->user_height_max=PNG_USER_HEIGHT_MAX;
- #endif
-
- #ifdef PNG_SETJMP_SUPPORTED
- #ifdef USE_FAR_KEYWORD
- if (setjmp(jmpbuf))
- #else
- if (setjmp(png_ptr->jmpbuf))
- #endif
- {
- png_free(png_ptr, png_ptr->zbuf);
- png_ptr->zbuf=NULL;
- png_destroy_struct(png_ptr);
- return (NULL);
- }
- #ifdef USE_FAR_KEYWORD
- png_memcpy(png_ptr->jmpbuf,jmpbuf,png_sizeof(jmp_buf));
- #endif
- #endif
-
- #ifdef PNG_USER_MEM_SUPPORTED
- png_set_mem_fn(png_ptr, mem_ptr, malloc_fn, free_fn);
- #endif /* PNG_USER_MEM_SUPPORTED */
- png_set_error_fn(png_ptr, error_ptr, error_fn, warn_fn);
-
- i=0;
- do
- {
- if(user_png_ver[i] != png_libpng_ver[i])
- png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
- } while (png_libpng_ver[i++]);
-
- if (png_ptr->flags & PNG_FLAG_LIBRARY_MISMATCH)
- {
- /* Libpng 0.90 and later are binary incompatible with libpng 0.89, so
- * we must recompile any applications that use any older library version.
- * For versions after libpng 1.0, we will be compatible, so we need
- * only check the first digit.
- */
- if (user_png_ver == NULL || user_png_ver[0] != png_libpng_ver[0] ||
- (user_png_ver[0] == '1' && user_png_ver[2] != png_libpng_ver[2]) ||
- (user_png_ver[0] == '0' && user_png_ver[2] < '9'))
- {
- #if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
- char msg[80];
- if (user_png_ver)
- {
- png_snprintf(msg, 80,
- "Application was compiled with png.h from libpng-%.20s",
- user_png_ver);
- png_warning(png_ptr, msg);
- }
- png_snprintf(msg, 80,
- "Application is running with png.c from libpng-%.20s",
- png_libpng_ver);
- png_warning(png_ptr, msg);
- #endif
- #ifdef PNG_ERROR_NUMBERS_SUPPORTED
- png_ptr->flags=0;
- #endif
- png_error(png_ptr,
- "Incompatible libpng version in application and library");
- }
- }
-
- /* initialize zbuf - compression buffer */
- png_ptr->zbuf_size = PNG_ZBUF_SIZE;
- png_ptr->zbuf = (png_bytep)png_malloc(png_ptr,
- (png_uint_32)png_ptr->zbuf_size);
-
- png_set_write_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL,
- png_flush_ptr_NULL);
-
- #if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
- png_set_filter_heuristics(png_ptr, PNG_FILTER_HEURISTIC_DEFAULT,
- 1, png_doublep_NULL, png_doublep_NULL);
- #endif
-
- #ifdef PNG_SETJMP_SUPPORTED
- /* Applications that neglect to set up their own setjmp() and then encounter
- a png_error() will longjmp here. Since the jmpbuf is then meaningless we
- abort instead of returning. */
- #ifdef USE_FAR_KEYWORD
- if (setjmp(jmpbuf))
- PNG_ABORT();
- png_memcpy(png_ptr->jmpbuf,jmpbuf,png_sizeof(jmp_buf));
- #else
- if (setjmp(png_ptr->jmpbuf))
- PNG_ABORT();
- #endif
- #endif
- return (png_ptr);
- }
-
- /* Initialize png_ptr structure, and allocate any memory needed */
- #if defined(PNG_1_0_X) || defined(PNG_1_2_X)
- /* Deprecated. */
- #undef png_write_init
- void PNGAPI
- png_write_init(png_structp png_ptr)
- {
- /* We only come here via pre-1.0.7-compiled applications */
- png_write_init_2(png_ptr, "1.0.6 or earlier", 0, 0);
- }
-
- void PNGAPI
- png_write_init_2(png_structp png_ptr, png_const_charp user_png_ver,
- png_size_t png_struct_size, png_size_t png_info_size)
- {
- /* We only come here via pre-1.0.12-compiled applications */
- if(png_ptr == NULL) return;
- #if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
- if(png_sizeof(png_struct) > png_struct_size ||
- png_sizeof(png_info) > png_info_size)
- {
- char msg[80];
- png_ptr->warning_fn=NULL;
- if (user_png_ver)
- {
- png_snprintf(msg, 80,
- "Application was compiled with png.h from libpng-%.20s",
- user_png_ver);
- png_warning(png_ptr, msg);
- }
- png_snprintf(msg, 80,
- "Application is running with png.c from libpng-%.20s",
- png_libpng_ver);
- png_warning(png_ptr, msg);
- }
- #endif
- if(png_sizeof(png_struct) > png_struct_size)
- {
- png_ptr->error_fn=NULL;
- #ifdef PNG_ERROR_NUMBERS_SUPPORTED
- png_ptr->flags=0;
- #endif
- png_error(png_ptr,
- "The png struct allocated by the application for writing is too small.");
- }
- if(png_sizeof(png_info) > png_info_size)
- {
- png_ptr->error_fn=NULL;
- #ifdef PNG_ERROR_NUMBERS_SUPPORTED
- png_ptr->flags=0;
- #endif
- png_error(png_ptr,
- "The info struct allocated by the application for writing is too small.");
- }
- png_write_init_3(&png_ptr, user_png_ver, png_struct_size);
- }
- #endif /* PNG_1_0_X || PNG_1_2_X */
-
- void PNGAPI
- png_write_init_3(png_structpp ptr_ptr, png_const_charp user_png_ver,
- png_size_t png_struct_size)
- {
- png_structp png_ptr=*ptr_ptr;
- #ifdef PNG_SETJMP_SUPPORTED
- jmp_buf tmp_jmp; /* to save current jump buffer */
- #endif
-
- int i = 0;
-
- if (png_ptr == NULL)
- return;
-
- do
- {
- if (user_png_ver[i] != png_libpng_ver[i])
- {
- #ifdef PNG_LEGACY_SUPPORTED
- png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
- #else
- png_ptr->warning_fn=NULL;
- png_warning(png_ptr,
- "Application uses deprecated png_write_init() and should be recompiled.");
- break;
- #endif
- }
- } while (png_libpng_ver[i++]);
-
- png_debug(1, "in png_write_init_3\n");
-
- #ifdef PNG_SETJMP_SUPPORTED
- /* save jump buffer and error functions */
- png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof (jmp_buf));
- #endif
-
- if (png_sizeof(png_struct) > png_struct_size)
- {
- png_destroy_struct(png_ptr);
- png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG);
- *ptr_ptr = png_ptr;
- }
-
- /* reset all variables to 0 */
- png_memset(png_ptr, 0, png_sizeof (png_struct));
-
- /* added at libpng-1.2.6 */
- #ifdef PNG_SET_USER_LIMITS_SUPPORTED
- png_ptr->user_width_max=PNG_USER_WIDTH_MAX;
- png_ptr->user_height_max=PNG_USER_HEIGHT_MAX;
- #endif
-
- #ifdef PNG_SETJMP_SUPPORTED
- /* restore jump buffer */
- png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof (jmp_buf));
- #endif
-
- png_set_write_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL,
- png_flush_ptr_NULL);
-
- /* initialize zbuf - compression buffer */
- png_ptr->zbuf_size = PNG_ZBUF_SIZE;
- png_ptr->zbuf = (png_bytep)png_malloc(png_ptr,
- (png_uint_32)png_ptr->zbuf_size);
-
- #if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
- png_set_filter_heuristics(png_ptr, PNG_FILTER_HEURISTIC_DEFAULT,
- 1, png_doublep_NULL, png_doublep_NULL);
- #endif
- }
-
- /* Write a few rows of image data. If the image is interlaced,
- * either you will have to write the 7 sub images, or, if you
- * have called png_set_interlace_handling(), you will have to
- * "write" the image seven times.
- */
- void PNGAPI
- png_write_rows(png_structp png_ptr, png_bytepp row,
- png_uint_32 num_rows)
- {
- png_uint_32 i; /* row counter */
- png_bytepp rp; /* row pointer */
-
- png_debug(1, "in png_write_rows\n");
-
- if (png_ptr == NULL)
- return;
-
- /* loop through the rows */
- for (i = 0, rp = row; i < num_rows; i++, rp++)
- {
- png_write_row(png_ptr, *rp);
- }
- }
-
- /* Write the image. You only need to call this function once, even
- * if you are writing an interlaced image.
- */
- void PNGAPI
- png_write_image(png_structp png_ptr, png_bytepp image)
- {
- png_uint_32 i; /* row index */
- int pass, num_pass; /* pass variables */
- png_bytepp rp; /* points to current row */
-
- if (png_ptr == NULL)
- return;
-
- png_debug(1, "in png_write_image\n");
- #if defined(PNG_WRITE_INTERLACING_SUPPORTED)
- /* intialize interlace handling. If image is not interlaced,
- this will set pass to 1 */
- num_pass = png_set_interlace_handling(png_ptr);
- #else
- num_pass = 1;
- #endif
- /* loop through passes */
- for (pass = 0; pass < num_pass; pass++)
- {
- /* loop through image */
- for (i = 0, rp = image; i < png_ptr->height; i++, rp++)
- {
- png_write_row(png_ptr, *rp);
- }
- }
- }
-
- /* called by user to write a row of image data */
- void PNGAPI
- png_write_row(png_structp png_ptr, png_bytep row)
- {
- if (png_ptr == NULL)
- return;
- png_debug2(1, "in png_write_row (row %ld, pass %d)\n",
- png_ptr->row_number, png_ptr->pass);
-
- /* initialize transformations and other stuff if first time */
- if (png_ptr->row_number == 0 && png_ptr->pass == 0)
- {
- /* make sure we wrote the header info */
- if (!(png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE))
- png_error(png_ptr,
- "png_write_info was never called before png_write_row.");
-
- /* check for transforms that have been set but were defined out */
- #if !defined(PNG_WRITE_INVERT_SUPPORTED) && defined(PNG_READ_INVERT_SUPPORTED)
- if (png_ptr->transformations & PNG_INVERT_MONO)
- png_warning(png_ptr, "PNG_WRITE_INVERT_SUPPORTED is not defined.");
- #endif
- #if !defined(PNG_WRITE_FILLER_SUPPORTED) && defined(PNG_READ_FILLER_SUPPORTED)
- if (png_ptr->transformations & PNG_FILLER)
- png_warning(png_ptr, "PNG_WRITE_FILLER_SUPPORTED is not defined.");
- #endif
- #if !defined(PNG_WRITE_PACKSWAP_SUPPORTED) && defined(PNG_READ_PACKSWAP_SUPPORTED)
- if (png_ptr->transformations & PNG_PACKSWAP)
- png_warning(png_ptr, "PNG_WRITE_PACKSWAP_SUPPORTED is not defined.");
- #endif
- #if !defined(PNG_WRITE_PACK_SUPPORTED) && defined(PNG_READ_PACK_SUPPORTED)
- if (png_ptr->transformations & PNG_PACK)
- png_warning(png_ptr, "PNG_WRITE_PACK_SUPPORTED is not defined.");
- #endif
- #if !defined(PNG_WRITE_SHIFT_SUPPORTED) && defined(PNG_READ_SHIFT_SUPPORTED)
- if (png_ptr->transformations & PNG_SHIFT)
- png_warning(png_ptr, "PNG_WRITE_SHIFT_SUPPORTED is not defined.");
- #endif
- #if !defined(PNG_WRITE_BGR_SUPPORTED) && defined(PNG_READ_BGR_SUPPORTED)
- if (png_ptr->transformations & PNG_BGR)
- png_warning(png_ptr, "PNG_WRITE_BGR_SUPPORTED is not defined.");
- #endif
- #if !defined(PNG_WRITE_SWAP_SUPPORTED) && defined(PNG_READ_SWAP_SUPPORTED)
- if (png_ptr->transformations & PNG_SWAP_BYTES)
- png_warning(png_ptr, "PNG_WRITE_SWAP_SUPPORTED is not defined.");
- #endif
-
- png_write_start_row(png_ptr);
- }
-
- #if defined(PNG_WRITE_INTERLACING_SUPPORTED)
- /* if interlaced and not interested in row, return */
- if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
- {
- switch (png_ptr->pass)
- {
- case 0:
- if (png_ptr->row_number & 0x07)
- {
- png_write_finish_row(png_ptr);
- return;
- }
- break;
- case 1:
- if ((png_ptr->row_number & 0x07) || png_ptr->width < 5)
- {
- png_write_finish_row(png_ptr);
- return;
- }
- break;
- case 2:
- if ((png_ptr->row_number & 0x07) != 4)
- {
- png_write_finish_row(png_ptr);
- return;
- }
- break;
- case 3:
- if ((png_ptr->row_number & 0x03) || png_ptr->width < 3)
- {
- png_write_finish_row(png_ptr);
- return;
- }
- break;
- case 4:
- if ((png_ptr->row_number & 0x03) != 2)
- {
- png_write_finish_row(png_ptr);
- return;
- }
- break;
- case 5:
- if ((png_ptr->row_number & 0x01) || png_ptr->width < 2)
- {
- png_write_finish_row(png_ptr);
- return;
- }
- break;
- case 6:
- if (!(png_ptr->row_number & 0x01))
- {
- png_write_finish_row(png_ptr);
- return;
- }
- break;
- }
- }
- #endif
-
- /* set up row info for transformations */
- png_ptr->row_info.color_type = png_ptr->color_type;
- png_ptr->row_info.width = png_ptr->usr_width;
- png_ptr->row_info.channels = png_ptr->usr_channels;
- png_ptr->row_info.bit_depth = png_ptr->usr_bit_depth;
- png_ptr->row_info.pixel_depth = (png_byte)(png_ptr->row_info.bit_depth *
- png_ptr->row_info.channels);
-
- png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth,
- png_ptr->row_info.width);
-
- png_debug1(3, "row_info->color_type = %d\n", png_ptr->row_info.color_type);
- png_debug1(3, "row_info->width = %lu\n", png_ptr->row_info.width);
- png_debug1(3, "row_info->channels = %d\n", png_ptr->row_info.channels);
- png_debug1(3, "row_info->bit_depth = %d\n", png_ptr->row_info.bit_depth);
- png_debug1(3, "row_info->pixel_depth = %d\n", png_ptr->row_info.pixel_depth);
- png_debug1(3, "row_info->rowbytes = %lu\n", png_ptr->row_info.rowbytes);
-
- /* Copy user's row into buffer, leaving room for filter byte. */
- png_memcpy_check(png_ptr, png_ptr->row_buf + 1, row,
- png_ptr->row_info.rowbytes);
-
- #if defined(PNG_WRITE_INTERLACING_SUPPORTED)
- /* handle interlacing */
- if (png_ptr->interlaced && png_ptr->pass < 6 &&
- (png_ptr->transformations & PNG_INTERLACE))
- {
- png_do_write_interlace(&(png_ptr->row_info),
- png_ptr->row_buf + 1, png_ptr->pass);
- /* this should always get caught above, but still ... */
- if (!(png_ptr->row_info.width))
- {
- png_write_finish_row(png_ptr);
- return;
- }
- }
- #endif
-
- /* handle other transformations */
- if (png_ptr->transformations)
- png_do_write_transformations(png_ptr);
-
- #if defined(PNG_MNG_FEATURES_SUPPORTED)
- /* Write filter_method 64 (intrapixel differencing) only if
- * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and
- * 2. Libpng did not write a PNG signature (this filter_method is only
- * used in PNG datastreams that are embedded in MNG datastreams) and
- * 3. The application called png_permit_mng_features with a mask that
- * included PNG_FLAG_MNG_FILTER_64 and
- * 4. The filter_method is 64 and
- * 5. The color_type is RGB or RGBA
- */
- if((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
- (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING))
- {
- /* Intrapixel differencing */
- png_do_write_intrapixel(&(png_ptr->row_info), png_ptr->row_buf + 1);
- }
- #endif
-
- /* Find a filter if necessary, filter the row and write it out. */
- png_write_find_filter(png_ptr, &(png_ptr->row_info));
-
- if (png_ptr->write_row_fn != NULL)
- (*(png_ptr->write_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass);
- }
-
- #if defined(PNG_WRITE_FLUSH_SUPPORTED)
- /* Set the automatic flush interval or 0 to turn flushing off */
- void PNGAPI
- png_set_flush(png_structp png_ptr, int nrows)
- {
- png_debug(1, "in png_set_flush\n");
- if (png_ptr == NULL)
- return;
- png_ptr->flush_dist = (nrows < 0 ? 0 : nrows);
- }
-
- /* flush the current output buffers now */
- void PNGAPI
- png_write_flush(png_structp png_ptr)
- {
- int wrote_IDAT;
-
- png_debug(1, "in png_write_flush\n");
- if (png_ptr == NULL)
- return;
- /* We have already written out all of the data */
- if (png_ptr->row_number >= png_ptr->num_rows)
- return;
-
- do
- {
- int ret;
-
- /* compress the data */
- ret = deflate(&png_ptr->zstream, Z_SYNC_FLUSH);
- wrote_IDAT = 0;
-
- /* check for compression errors */
- if (ret != Z_OK)
- {
- if (png_ptr->zstream.msg != NULL)
- png_error(png_ptr, png_ptr->zstream.msg);
- else
- png_error(png_ptr, "zlib error");
- }
-
- if (!(png_ptr->zstream.avail_out))
- {
- /* write the IDAT and reset the zlib output buffer */
- png_write_IDAT(png_ptr, png_ptr->zbuf,
- png_ptr->zbuf_size);
- png_ptr->zstream.next_out = png_ptr->zbuf;
- png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
- wrote_IDAT = 1;
- }
- } while(wrote_IDAT == 1);
-
- /* If there is any data left to be output, write it into a new IDAT */
- if (png_ptr->zbuf_size != png_ptr->zstream.avail_out)
- {
- /* write the IDAT and reset the zlib output buffer */
- png_write_IDAT(png_ptr, png_ptr->zbuf,
- png_ptr->zbuf_size - png_ptr->zstream.avail_out);
- png_ptr->zstream.next_out = png_ptr->zbuf;
- png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
- }
- png_ptr->flush_rows = 0;
- png_flush(png_ptr);
- }
- #endif /* PNG_WRITE_FLUSH_SUPPORTED */
-
- /* free all memory used by the write */
- void PNGAPI
- png_destroy_write_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr)
- {
- png_structp png_ptr = NULL;
- png_infop info_ptr = NULL;
- #ifdef PNG_USER_MEM_SUPPORTED
- png_free_ptr free_fn = NULL;
- png_voidp mem_ptr = NULL;
- #endif
-
- png_debug(1, "in png_destroy_write_struct\n");
- if (png_ptr_ptr != NULL)
- {
- png_ptr = *png_ptr_ptr;
- #ifdef PNG_USER_MEM_SUPPORTED
- free_fn = png_ptr->free_fn;
- mem_ptr = png_ptr->mem_ptr;
- #endif
- }
-
- if (info_ptr_ptr != NULL)
- info_ptr = *info_ptr_ptr;
-
- if (info_ptr != NULL)
- {
- png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1);
-
- #if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
- if (png_ptr->num_chunk_list)
- {
- png_free(png_ptr, png_ptr->chunk_list);
- png_ptr->chunk_list=NULL;
- png_ptr->num_chunk_list=0;
- }
- #endif
-
- #ifdef PNG_USER_MEM_SUPPORTED
- png_destroy_struct_2((png_voidp)info_ptr, (png_free_ptr)free_fn,
- (png_voidp)mem_ptr);
- #else
- png_destroy_struct((png_voidp)info_ptr);
- #endif
- *info_ptr_ptr = NULL;
- }
-
- if (png_ptr != NULL)
- {
- png_write_destroy(png_ptr);
- #ifdef PNG_USER_MEM_SUPPORTED
- png_destroy_struct_2((png_voidp)png_ptr, (png_free_ptr)free_fn,
- (png_voidp)mem_ptr);
- #else
- png_destroy_struct((png_voidp)png_ptr);
- #endif
- *png_ptr_ptr = NULL;
- }
- }
-
- /* Free any memory used in png_ptr struct (old method) */
- void /* PRIVATE */
- png_write_destroy(png_structp png_ptr)
- {
- #ifdef PNG_SETJMP_SUPPORTED
- jmp_buf tmp_jmp; /* save jump buffer */
- #endif
- png_error_ptr error_fn;
- png_error_ptr warning_fn;
- png_voidp error_ptr;
- #ifdef PNG_USER_MEM_SUPPORTED
- png_free_ptr free_fn;
- #endif
-
- png_debug(1, "in png_write_destroy\n");
- /* free any memory zlib uses */
- deflateEnd(&png_ptr->zstream);
-
- /* free our memory. png_free checks NULL for us. */
- png_free(png_ptr, png_ptr->zbuf);
- png_free(png_ptr, png_ptr->row_buf);
- png_free(png_ptr, png_ptr->prev_row);
- png_free(png_ptr, png_ptr->sub_row);
- png_free(png_ptr, png_ptr->up_row);
- png_free(png_ptr, png_ptr->avg_row);
- png_free(png_ptr, png_ptr->paeth_row);
-
- #if defined(PNG_TIME_RFC1123_SUPPORTED)
- png_free(png_ptr, png_ptr->time_buffer);
- #endif
-
- #if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
- png_free(png_ptr, png_ptr->prev_filters);
- png_free(png_ptr, png_ptr->filter_weights);
- png_free(png_ptr, png_ptr->inv_filter_weights);
- png_free(png_ptr, png_ptr->filter_costs);
- png_free(png_ptr, png_ptr->inv_filter_costs);
- #endif
-
- #ifdef PNG_SETJMP_SUPPORTED
- /* reset structure */
- png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof (jmp_buf));
- #endif
-
- error_fn = png_ptr->error_fn;
- warning_fn = png_ptr->warning_fn;
- error_ptr = png_ptr->error_ptr;
- #ifdef PNG_USER_MEM_SUPPORTED
- free_fn = png_ptr->free_fn;
- #endif
-
- png_memset(png_ptr, 0, png_sizeof (png_struct));
-
- png_ptr->error_fn = error_fn;
- png_ptr->warning_fn = warning_fn;
- png_ptr->error_ptr = error_ptr;
- #ifdef PNG_USER_MEM_SUPPORTED
- png_ptr->free_fn = free_fn;
- #endif
-
- #ifdef PNG_SETJMP_SUPPORTED
- png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof (jmp_buf));
- #endif
- }
-
- /* Allow the application to select one or more row filters to use. */
- void PNGAPI
- png_set_filter(png_structp png_ptr, int method, int filters)
- {
- png_debug(1, "in png_set_filter\n");
- if (png_ptr == NULL)
- return;
- #if defined(PNG_MNG_FEATURES_SUPPORTED)
- if((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
- (method == PNG_INTRAPIXEL_DIFFERENCING))
- method = PNG_FILTER_TYPE_BASE;
- #endif
- if (method == PNG_FILTER_TYPE_BASE)
- {
- switch (filters & (PNG_ALL_FILTERS | 0x07))
- {
- #ifndef PNG_NO_WRITE_FILTER
- case 5:
- case 6:
- case 7: png_warning(png_ptr, "Unknown row filter for method 0");
- #endif /* PNG_NO_WRITE_FILTER */
- case PNG_FILTER_VALUE_NONE:
- png_ptr->do_filter=PNG_FILTER_NONE; break;
- #ifndef PNG_NO_WRITE_FILTER
- case PNG_FILTER_VALUE_SUB:
- png_ptr->do_filter=PNG_FILTER_SUB; break;
- case PNG_FILTER_VALUE_UP:
- png_ptr->do_filter=PNG_FILTER_UP; break;
- case PNG_FILTER_VALUE_AVG:
- png_ptr->do_filter=PNG_FILTER_AVG; break;
- case PNG_FILTER_VALUE_PAETH:
- png_ptr->do_filter=PNG_FILTER_PAETH; break;
- default: png_ptr->do_filter = (png_byte)filters; break;
- #else
- default: png_warning(png_ptr, "Unknown row filter for method 0");
- #endif /* PNG_NO_WRITE_FILTER */
- }
-
- /* If we have allocated the row_buf, this means we have already started
- * with the image and we should have allocated all of the filter buffers
- * that have been selected. If prev_row isn't already allocated, then
- * it is too late to start using the filters that need it, since we
- * will be missing the data in the previous row. If an application
- * wants to start and stop using particular filters during compression,
- * it should start out with all of the filters, and then add and
- * remove them after the start of compression.
- */
- if (png_ptr->row_buf != NULL)
- {
- #ifndef PNG_NO_WRITE_FILTER
- if ((png_ptr->do_filter & PNG_FILTER_SUB) && png_ptr->sub_row == NULL)
- {
- png_ptr->sub_row = (png_bytep)png_malloc(png_ptr,
- (png_ptr->rowbytes + 1));
- png_ptr->sub_row[0] = PNG_FILTER_VALUE_SUB;
- }
-
- if ((png_ptr->do_filter & PNG_FILTER_UP) && png_ptr->up_row == NULL)
- {
- if (png_ptr->prev_row == NULL)
- {
- png_warning(png_ptr, "Can't add Up filter after starting");
- png_ptr->do_filter &= ~PNG_FILTER_UP;
- }
- else
- {
- png_ptr->up_row = (png_bytep)png_malloc(png_ptr,
- (png_ptr->rowbytes + 1));
- png_ptr->up_row[0] = PNG_FILTER_VALUE_UP;
- }
- }
-
- if ((png_ptr->do_filter & PNG_FILTER_AVG) && png_ptr->avg_row == NULL)
- {
- if (png_ptr->prev_row == NULL)
- {
- png_warning(png_ptr, "Can't add Average filter after starting");
- png_ptr->do_filter &= ~PNG_FILTER_AVG;
- }
- else
- {
- png_ptr->avg_row = (png_bytep)png_malloc(png_ptr,
- (png_ptr->rowbytes + 1));
- png_ptr->avg_row[0] = PNG_FILTER_VALUE_AVG;
- }
- }
-
- if ((png_ptr->do_filter & PNG_FILTER_PAETH) &&
- png_ptr->paeth_row == NULL)
- {
- if (png_ptr->prev_row == NULL)
- {
- png_warning(png_ptr, "Can't add Paeth filter after starting");
- png_ptr->do_filter &= (png_byte)(~PNG_FILTER_PAETH);
- }
- else
- {
- png_ptr->paeth_row = (png_bytep)png_malloc(png_ptr,
- (png_ptr->rowbytes + 1));
- png_ptr->paeth_row[0] = PNG_FILTER_VALUE_PAETH;
- }
- }
-
- if (png_ptr->do_filter == PNG_NO_FILTERS)
- #endif /* PNG_NO_WRITE_FILTER */
- png_ptr->do_filter = PNG_FILTER_NONE;
- }
- }
- else
- png_error(png_ptr, "Unknown custom filter method");
- }
-
- /* This allows us to influence the way in which libpng chooses the "best"
- * filter for the current scanline. While the "minimum-sum-of-absolute-
- * differences metric is relatively fast and effective, there is some
- * question as to whether it can be improved upon by trying to keep the
- * filtered data going to zlib more consistent, hopefully resulting in
- * better compression.
- */
- #if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) /* GRR 970116 */
- void PNGAPI
- png_set_filter_heuristics(png_structp png_ptr, int heuristic_method,
- int num_weights, png_doublep filter_weights,
- png_doublep filter_costs)
- {
- int i;
-
- png_debug(1, "in png_set_filter_heuristics\n");
- if (png_ptr == NULL)
- return;
- if (heuristic_method >= PNG_FILTER_HEURISTIC_LAST)
- {
- png_warning(png_ptr, "Unknown filter heuristic method");
- return;
- }
-
- if (heuristic_method == PNG_FILTER_HEURISTIC_DEFAULT)
- {
- heuristic_method = PNG_FILTER_HEURISTIC_UNWEIGHTED;
- }
-
- if (num_weights < 0 || filter_weights == NULL ||
- heuristic_method == PNG_FILTER_HEURISTIC_UNWEIGHTED)
- {
- num_weights = 0;
- }
-
- png_ptr->num_prev_filters = (png_byte)num_weights;
- png_ptr->heuristic_method = (png_byte)heuristic_method;
-
- if (num_weights > 0)
- {
- if (png_ptr->prev_filters == NULL)
- {
- png_ptr->prev_filters = (png_bytep)png_malloc(png_ptr,
- (png_uint_32)(png_sizeof(png_byte) * num_weights));
-
- /* To make sure that the weighting starts out fairly */
- for (i = 0; i < num_weights; i++)
- {
- png_ptr->prev_filters[i] = 255;
- }
- }
-
- if (png_ptr->filter_weights == NULL)
- {
- png_ptr->filter_weights = (png_uint_16p)png_malloc(png_ptr,
- (png_uint_32)(png_sizeof(png_uint_16) * num_weights));
-
- png_ptr->inv_filter_weights = (png_uint_16p)png_malloc(png_ptr,
- (png_uint_32)(png_sizeof(png_uint_16) * num_weights));
- for (i = 0; i < num_weights; i++)
- {
- png_ptr->inv_filter_weights[i] =
- png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR;
- }
- }
-
- for (i = 0; i < num_weights; i++)
- {
- if (filter_weights[i] < 0.0)
- {
- png_ptr->inv_filter_weights[i] =
- png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR;
- }
- else
- {
- png_ptr->inv_filter_weights[i] =
- (png_uint_16)((double)PNG_WEIGHT_FACTOR*filter_weights[i]+0.5);
- png_ptr->filter_weights[i] =
- (png_uint_16)((double)PNG_WEIGHT_FACTOR/filter_weights[i]+0.5);
- }
- }
- }
-
- /* If, in the future, there are other filter methods, this would
- * need to be based on png_ptr->filter.
- */
- if (png_ptr->filter_costs == NULL)
- {
- png_ptr->filter_costs = (png_uint_16p)png_malloc(png_ptr,
- (png_uint_32)(png_sizeof(png_uint_16) * PNG_FILTER_VALUE_LAST));
-
- png_ptr->inv_filter_costs = (png_uint_16p)png_malloc(png_ptr,
- (png_uint_32)(png_sizeof(png_uint_16) * PNG_FILTER_VALUE_LAST));
-
- for (i = 0; i < PNG_FILTER_VALUE_LAST; i++)
- {
- png_ptr->inv_filter_costs[i] =
- png_ptr->filter_costs[i] = PNG_COST_FACTOR;
- }
- }
-
- /* Here is where we set the relative costs of the different filters. We
- * should take the desired compression level into account when setting
- * the costs, so that Paeth, for instance, has a high relative cost at low
- * compression levels, while it has a lower relative cost at higher
- * compression settings. The filter types are in order of increasing
- * relative cost, so it would be possible to do this with an algorithm.
- */
- for (i = 0; i < PNG_FILTER_VALUE_LAST; i++)
- {
- if (filter_costs == NULL || filter_costs[i] < 0.0)
- {
- png_ptr->inv_filter_costs[i] =
- png_ptr->filter_costs[i] = PNG_COST_FACTOR;
- }
- else if (filter_costs[i] >= 1.0)
- {
- png_ptr->inv_filter_costs[i] =
- (png_uint_16)((double)PNG_COST_FACTOR / filter_costs[i] + 0.5);
- png_ptr->filter_costs[i] =
- (png_uint_16)((double)PNG_COST_FACTOR * filter_costs[i] + 0.5);
- }
- }
- }
- #endif /* PNG_WRITE_WEIGHTED_FILTER_SUPPORTED */
-
- void PNGAPI
- png_set_compression_level(png_structp png_ptr, int level)
- {
- png_debug(1, "in png_set_compression_level\n");
- if (png_ptr == NULL)
- return;
- png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_LEVEL;
- png_ptr->zlib_level = level;
- }
-
- void PNGAPI
- png_set_compression_mem_level(png_structp png_ptr, int mem_level)
- {
- png_debug(1, "in png_set_compression_mem_level\n");
- if (png_ptr == NULL)
- return;
- png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL;
- png_ptr->zlib_mem_level = mem_level;
- }
-
- void PNGAPI
- png_set_compression_strategy(png_structp png_ptr, int strategy)
- {
- png_debug(1, "in png_set_compression_strategy\n");
- if (png_ptr == NULL)
- return;
- png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_STRATEGY;
- png_ptr->zlib_strategy = strategy;
- }
-
- void PNGAPI
- png_set_compression_window_bits(png_structp png_ptr, int window_bits)
- {
- if (png_ptr == NULL)
- return;
- if (window_bits > 15)
- png_warning(png_ptr, "Only compression windows <= 32k supported by PNG");
- else if (window_bits < 8)
- png_warning(png_ptr, "Only compression windows >= 256 supported by PNG");
- #ifndef WBITS_8_OK
- /* avoid libpng bug with 256-byte windows */
- if (window_bits == 8)
- {
- png_warning(png_ptr, "Compression window is being reset to 512");
- window_bits=9;
- }
- #endif
- png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS;
- png_ptr->zlib_window_bits = window_bits;
- }
-
- void PNGAPI
- png_set_compression_method(png_structp png_ptr, int method)
- {
- png_debug(1, "in png_set_compression_method\n");
- if (png_ptr == NULL)
- return;
- if (method != 8)
- png_warning(png_ptr, "Only compression method 8 is supported by PNG");
- png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_METHOD;
- png_ptr->zlib_method = method;
- }
-
- void PNGAPI
- png_set_write_status_fn(png_structp png_ptr, png_write_status_ptr write_row_fn)
- {
- if (png_ptr == NULL)
- return;
- png_ptr->write_row_fn = write_row_fn;
- }
-
- #if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
- void PNGAPI
- png_set_write_user_transform_fn(png_structp png_ptr, png_user_transform_ptr
- write_user_transform_fn)
- {
- png_debug(1, "in png_set_write_user_transform_fn\n");
- if (png_ptr == NULL)
- return;
- png_ptr->transformations |= PNG_USER_TRANSFORM;
- png_ptr->write_user_transform_fn = write_user_transform_fn;
- }
- #endif
-
- #if defined(PNG_INFO_IMAGE_SUPPORTED)
- void PNGAPI
- png_write_png(png_structp png_ptr, png_infop info_ptr,
- int transforms, voidp params)
- {
- if (png_ptr == NULL || info_ptr == NULL)
- return;
- #if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
- /* invert the alpha channel from opacity to transparency */
- if (transforms & PNG_TRANSFORM_INVERT_ALPHA)
- png_set_invert_alpha(png_ptr);
- #endif
-
- /* Write the file header information. */
- png_write_info(png_ptr, info_ptr);
-
- /* ------ these transformations don't touch the info structure ------- */
-
- #if defined(PNG_WRITE_INVERT_SUPPORTED)
- /* invert monochrome pixels */
- if (transforms & PNG_TRANSFORM_INVERT_MONO)
- png_set_invert_mono(png_ptr);
- #endif
-
- #if defined(PNG_WRITE_SHIFT_SUPPORTED)
- /* Shift the pixels up to a legal bit depth and fill in
- * as appropriate to correctly scale the image.
- */
- if ((transforms & PNG_TRANSFORM_SHIFT)
- && (info_ptr->valid & PNG_INFO_sBIT))
- png_set_shift(png_ptr, &info_ptr->sig_bit);
- #endif
-
- #if defined(PNG_WRITE_PACK_SUPPORTED)
- /* pack pixels into bytes */
- if (transforms & PNG_TRANSFORM_PACKING)
- png_set_packing(png_ptr);
- #endif
-
- #if defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
- /* swap location of alpha bytes from ARGB to RGBA */
- if (transforms & PNG_TRANSFORM_SWAP_ALPHA)
- png_set_swap_alpha(png_ptr);
- #endif
-
- #if defined(PNG_WRITE_FILLER_SUPPORTED)
- /* Get rid of filler (OR ALPHA) bytes, pack XRGB/RGBX/ARGB/RGBA into
- * RGB (4 channels -> 3 channels). The second parameter is not used.
- */
- if (transforms & PNG_TRANSFORM_STRIP_FILLER)
- png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE);
- #endif
-
- #if defined(PNG_WRITE_BGR_SUPPORTED)
- /* flip BGR pixels to RGB */
- if (transforms & PNG_TRANSFORM_BGR)
- png_set_bgr(png_ptr);
- #endif
-
- #if defined(PNG_WRITE_SWAP_SUPPORTED)
- /* swap bytes of 16-bit files to most significant byte first */
- if (transforms & PNG_TRANSFORM_SWAP_ENDIAN)
- png_set_swap(png_ptr);
- #endif
-
- #if defined(PNG_WRITE_PACKSWAP_SUPPORTED)
- /* swap bits of 1, 2, 4 bit packed pixel formats */
- if (transforms & PNG_TRANSFORM_PACKSWAP)
- png_set_packswap(png_ptr);
- #endif
-
- /* ----------------------- end of transformations ------------------- */
-
- /* write the bits */
- if (info_ptr->valid & PNG_INFO_IDAT)
- png_write_image(png_ptr, info_ptr->row_pointers);
-
- /* It is REQUIRED to call this to finish writing the rest of the file */
- png_write_end(png_ptr, info_ptr);
-
- transforms = transforms; /* quiet compiler warnings */
- params = params;
- }
- #endif
- #endif /* PNG_WRITE_SUPPORTED */
- /********* End of inlined file: pngwrite.c *********/
-
- /********* Start of inlined file: pngwtran.c *********/
- /* pngwtran.c - transforms the data in a row for PNG writers
- *
- * Last changed in libpng 1.2.9 April 14, 2006
- * For conditions of distribution and use, see copyright notice in png.h
- * Copyright (c) 1998-2006 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
- */
-
- #define PNG_INTERNAL
-
- #ifdef PNG_WRITE_SUPPORTED
-
- /* Transform the data according to the user's wishes. The order of
- * transformations is significant.
- */
- void /* PRIVATE */
- png_do_write_transformations(png_structp png_ptr)
- {
- png_debug(1, "in png_do_write_transformations\n");
-
- if (png_ptr == NULL)
- return;
-
- #if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
- if (png_ptr->transformations & PNG_USER_TRANSFORM)
- if(png_ptr->write_user_transform_fn != NULL)
- (*(png_ptr->write_user_transform_fn)) /* user write transform function */
- (png_ptr, /* png_ptr */
- &(png_ptr->row_info), /* row_info: */
- /* png_uint_32 width; width of row */
- /* png_uint_32 rowbytes; number of bytes in row */
- /* png_byte color_type; color type of pixels */
- /* png_byte bit_depth; bit depth of samples */
- /* png_byte channels; number of channels (1-4) */
- /* png_byte pixel_depth; bits per pixel (depth*channels) */
- png_ptr->row_buf + 1); /* start of pixel data for row */
- #endif
- #if defined(PNG_WRITE_FILLER_SUPPORTED)
- if (png_ptr->transformations & PNG_FILLER)
- png_do_strip_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
- png_ptr->flags);
- #endif
- #if defined(PNG_WRITE_PACKSWAP_SUPPORTED)
- if (png_ptr->transformations & PNG_PACKSWAP)
- png_do_packswap(&(png_ptr->row_info), png_ptr->row_buf + 1);
- #endif
- #if defined(PNG_WRITE_PACK_SUPPORTED)
- if (png_ptr->transformations & PNG_PACK)
- png_do_pack(&(png_ptr->row_info), png_ptr->row_buf + 1,
- (png_uint_32)png_ptr->bit_depth);
- #endif
- #if defined(PNG_WRITE_SWAP_SUPPORTED)
- if (png_ptr->transformations & PNG_SWAP_BYTES)
- png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1);
- #endif
- #if defined(PNG_WRITE_SHIFT_SUPPORTED)
- if (png_ptr->transformations & PNG_SHIFT)
- png_do_shift(&(png_ptr->row_info), png_ptr->row_buf + 1,
- &(png_ptr->shift));
- #endif
- #if defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
- if (png_ptr->transformations & PNG_SWAP_ALPHA)
- png_do_write_swap_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
- #endif
- #if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
- if (png_ptr->transformations & PNG_INVERT_ALPHA)
- png_do_write_invert_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
- #endif
- #if defined(PNG_WRITE_BGR_SUPPORTED)
- if (png_ptr->transformations & PNG_BGR)
- png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1);
- #endif
- #if defined(PNG_WRITE_INVERT_SUPPORTED)
- if (png_ptr->transformations & PNG_INVERT_MONO)
- png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1);
- #endif
- }
-
- #if defined(PNG_WRITE_PACK_SUPPORTED)
- /* Pack pixels into bytes. Pass the true bit depth in bit_depth. The
- * row_info bit depth should be 8 (one pixel per byte). The channels
- * should be 1 (this only happens on grayscale and paletted images).
- */
- void /* PRIVATE */
- png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth)
- {
- png_debug(1, "in png_do_pack\n");
- if (row_info->bit_depth == 8 &&
- #if defined(PNG_USELESS_TESTS_SUPPORTED)
- row != NULL && row_info != NULL &&
- #endif
- row_info->channels == 1)
- {
- switch ((int)bit_depth)
- {
- case 1:
- {
- png_bytep sp, dp;
- int mask, v;
- png_uint_32 i;
- png_uint_32 row_width = row_info->width;
-
- sp = row;
- dp = row;
- mask = 0x80;
- v = 0;
-
- for (i = 0; i < row_width; i++)
- {
- if (*sp != 0)
- v |= mask;
- sp++;
- if (mask > 1)
- mask >>= 1;
- else
- {
- mask = 0x80;
- *dp = (png_byte)v;
- dp++;
- v = 0;
- }
- }
- if (mask != 0x80)
- *dp = (png_byte)v;
- break;
- }
- case 2:
- {
- png_bytep sp, dp;
- int shift, v;
- png_uint_32 i;
- png_uint_32 row_width = row_info->width;
-
- sp = row;
- dp = row;
- shift = 6;
- v = 0;
- for (i = 0; i < row_width; i++)
- {
- png_byte value;
-
- value = (png_byte)(*sp & 0x03);
- v |= (value << shift);
- if (shift == 0)
- {
- shift = 6;
- *dp = (png_byte)v;
- dp++;
- v = 0;
- }
- else
- shift -= 2;
- sp++;
- }
- if (shift != 6)
- *dp = (png_byte)v;
- break;
- }
- case 4:
- {
- png_bytep sp, dp;
- int shift, v;
- png_uint_32 i;
- png_uint_32 row_width = row_info->width;
-
- sp = row;
- dp = row;
- shift = 4;
- v = 0;
- for (i = 0; i < row_width; i++)
- {
- png_byte value;
-
- value = (png_byte)(*sp & 0x0f);
- v |= (value << shift);
-
- if (shift == 0)
- {
- shift = 4;
- *dp = (png_byte)v;
- dp++;
- v = 0;
- }
- else
- shift -= 4;
-
- sp++;
- }
- if (shift != 4)
- *dp = (png_byte)v;
- break;
- }
- }
- row_info->bit_depth = (png_byte)bit_depth;
- row_info->pixel_depth = (png_byte)(bit_depth * row_info->channels);
- row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
- row_info->width);
- }
- }
- #endif
-
- #if defined(PNG_WRITE_SHIFT_SUPPORTED)
- /* Shift pixel values to take advantage of whole range. Pass the
- * true number of bits in bit_depth. The row should be packed
- * according to row_info->bit_depth. Thus, if you had a row of
- * bit depth 4, but the pixels only had values from 0 to 7, you
- * would pass 3 as bit_depth, and this routine would translate the
- * data to 0 to 15.
- */
- void /* PRIVATE */
- png_do_shift(png_row_infop row_info, png_bytep row, png_color_8p bit_depth)
- {
- png_debug(1, "in png_do_shift\n");
- #if defined(PNG_USELESS_TESTS_SUPPORTED)
- if (row != NULL && row_info != NULL &&
- #else
- if (
- #endif
- row_info->color_type != PNG_COLOR_TYPE_PALETTE)
- {
- int shift_start[4], shift_dec[4];
- int channels = 0;
-
- if (row_info->color_type & PNG_COLOR_MASK_COLOR)
- {
- shift_start[channels] = row_info->bit_depth - bit_depth->red;
- shift_dec[channels] = bit_depth->red;
- channels++;
- shift_start[channels] = row_info->bit_depth - bit_depth->green;
- shift_dec[channels] = bit_depth->green;
- channels++;
- shift_start[channels] = row_info->bit_depth - bit_depth->blue;
- shift_dec[channels] = bit_depth->blue;
- channels++;
- }
- else
- {
- shift_start[channels] = row_info->bit_depth - bit_depth->gray;
- shift_dec[channels] = bit_depth->gray;
- channels++;
- }
- if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
- {
- shift_start[channels] = row_info->bit_depth - bit_depth->alpha;
- shift_dec[channels] = bit_depth->alpha;
- channels++;
- }
-
- /* with low row depths, could only be grayscale, so one channel */
- if (row_info->bit_depth < 8)
- {
- png_bytep bp = row;
- png_uint_32 i;
- png_byte mask;
- png_uint_32 row_bytes = row_info->rowbytes;
-
- if (bit_depth->gray == 1 && row_info->bit_depth == 2)
- mask = 0x55;
- else if (row_info->bit_depth == 4 && bit_depth->gray == 3)
- mask = 0x11;
- else
- mask = 0xff;
-
- for (i = 0; i < row_bytes; i++, bp++)
- {
- png_uint_16 v;
- int j;
-
- v = *bp;
- *bp = 0;
- for (j = shift_start[0]; j > -shift_dec[0]; j -= shift_dec[0])
- {
- if (j > 0)
- *bp |= (png_byte)((v << j) & 0xff);
- else
- *bp |= (png_byte)((v >> (-j)) & mask);
- }
- }
- }
- else if (row_info->bit_depth == 8)
- {
- png_bytep bp = row;
- png_uint_32 i;
- png_uint_32 istop = channels * row_info->width;
-
- for (i = 0; i < istop; i++, bp++)
- {
-
- png_uint_16 v;
- int j;
- int c = (int)(i%channels);
-
- v = *bp;
- *bp = 0;
- for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
- {
- if (j > 0)
- *bp |= (png_byte)((v << j) & 0xff);
- else
- *bp |= (png_byte)((v >> (-j)) & 0xff);
- }
- }
- }
- else
- {
- png_bytep bp;
- png_uint_32 i;
- png_uint_32 istop = channels * row_info->width;
-
- for (bp = row, i = 0; i < istop; i++)
- {
- int c = (int)(i%channels);
- png_uint_16 value, v;
- int j;
-
- v = (png_uint_16)(((png_uint_16)(*bp) << 8) + *(bp + 1));
- value = 0;
- for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
- {
- if (j > 0)
- value |= (png_uint_16)((v << j) & (png_uint_16)0xffff);
- else
- value |= (png_uint_16)((v >> (-j)) & (png_uint_16)0xffff);
- }
- *bp++ = (png_byte)(value >> 8);
- *bp++ = (png_byte)(value & 0xff);
- }
- }
- }
- }
- #endif
-
- #if defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
- void /* PRIVATE */
- png_do_write_swap_alpha(png_row_infop row_info, png_bytep row)
- {
- png_debug(1, "in png_do_write_swap_alpha\n");
- #if defined(PNG_USELESS_TESTS_SUPPORTED)
- if (row != NULL && row_info != NULL)
- #endif
- {
- if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
- {
- /* This converts from ARGB to RGBA */
- if (row_info->bit_depth == 8)
- {
- png_bytep sp, dp;
- png_uint_32 i;
- png_uint_32 row_width = row_info->width;
- for (i = 0, sp = dp = row; i < row_width; i++)
- {
- png_byte save = *(sp++);
- *(dp++) = *(sp++);
- *(dp++) = *(sp++);
- *(dp++) = *(sp++);
- *(dp++) = save;
- }
- }
- /* This converts from AARRGGBB to RRGGBBAA */
- else
- {
- png_bytep sp, dp;
- png_uint_32 i;
- png_uint_32 row_width = row_info->width;
-
- for (i = 0, sp = dp = row; i < row_width; i++)
- {
- png_byte save[2];
- save[0] = *(sp++);
- save[1] = *(sp++);
- *(dp++) = *(sp++);
- *(dp++) = *(sp++);
- *(dp++) = *(sp++);
- *(dp++) = *(sp++);
- *(dp++) = *(sp++);
- *(dp++) = *(sp++);
- *(dp++) = save[0];
- *(dp++) = save[1];
- }
- }
- }
- else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
- {
- /* This converts from AG to GA */
- if (row_info->bit_depth == 8)
- {
- png_bytep sp, dp;
- png_uint_32 i;
- png_uint_32 row_width = row_info->width;
-
- for (i = 0, sp = dp = row; i < row_width; i++)
- {
- png_byte save = *(sp++);
- *(dp++) = *(sp++);
- *(dp++) = save;
- }
- }
- /* This converts from AAGG to GGAA */
- else
- {
- png_bytep sp, dp;
- png_uint_32 i;
- png_uint_32 row_width = row_info->width;
-
- for (i = 0, sp = dp = row; i < row_width; i++)
- {
- png_byte save[2];
- save[0] = *(sp++);
- save[1] = *(sp++);
- *(dp++) = *(sp++);
- *(dp++) = *(sp++);
- *(dp++) = save[0];
- *(dp++) = save[1];
- }
- }
- }
- }
- }
- #endif
-
- #if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
- void /* PRIVATE */
- png_do_write_invert_alpha(png_row_infop row_info, png_bytep row)
- {
- png_debug(1, "in png_do_write_invert_alpha\n");
- #if defined(PNG_USELESS_TESTS_SUPPORTED)
- if (row != NULL && row_info != NULL)
- #endif
- {
- if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
- {
- /* This inverts the alpha channel in RGBA */
- if (row_info->bit_depth == 8)
- {
- png_bytep sp, dp;
- png_uint_32 i;
- png_uint_32 row_width = row_info->width;
- for (i = 0, sp = dp = row; i < row_width; i++)
- {
- /* does nothing
- *(dp++) = *(sp++);
- *(dp++) = *(sp++);
- *(dp++) = *(sp++);
- */
- sp+=3; dp = sp;
- *(dp++) = (png_byte)(255 - *(sp++));
- }
- }
- /* This inverts the alpha channel in RRGGBBAA */
- else
- {
- png_bytep sp, dp;
- png_uint_32 i;
- png_uint_32 row_width = row_info->width;
-
- for (i = 0, sp = dp = row; i < row_width; i++)
- {
- /* does nothing
- *(dp++) = *(sp++);
- *(dp++) = *(sp++);
- *(dp++) = *(sp++);
- *(dp++) = *(sp++);
- *(dp++) = *(sp++);
- *(dp++) = *(sp++);
- */
- sp+=6; dp = sp;
- *(dp++) = (png_byte)(255 - *(sp++));
- *(dp++) = (png_byte)(255 - *(sp++));
- }
- }
- }
- else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
- {
- /* This inverts the alpha channel in GA */
- if (row_info->bit_depth == 8)
- {
- png_bytep sp, dp;
- png_uint_32 i;
- png_uint_32 row_width = row_info->width;
-
- for (i = 0, sp = dp = row; i < row_width; i++)
- {
- *(dp++) = *(sp++);
- *(dp++) = (png_byte)(255 - *(sp++));
- }
- }
- /* This inverts the alpha channel in GGAA */
- else
- {
- png_bytep sp, dp;
- png_uint_32 i;
- png_uint_32 row_width = row_info->width;
-
- for (i = 0, sp = dp = row; i < row_width; i++)
- {
- /* does nothing
- *(dp++) = *(sp++);
- *(dp++) = *(sp++);
- */
- sp+=2; dp = sp;
- *(dp++) = (png_byte)(255 - *(sp++));
- *(dp++) = (png_byte)(255 - *(sp++));
- }
- }
- }
- }
- }
- #endif
-
- #if defined(PNG_MNG_FEATURES_SUPPORTED)
- /* undoes intrapixel differencing */
- void /* PRIVATE */
- png_do_write_intrapixel(png_row_infop row_info, png_bytep row)
- {
- png_debug(1, "in png_do_write_intrapixel\n");
- if (
- #if defined(PNG_USELESS_TESTS_SUPPORTED)
- row != NULL && row_info != NULL &&
- #endif
- (row_info->color_type & PNG_COLOR_MASK_COLOR))
- {
- int bytes_per_pixel;
- png_uint_32 row_width = row_info->width;
- if (row_info->bit_depth == 8)
- {
- png_bytep rp;
- png_uint_32 i;
-
- if (row_info->color_type == PNG_COLOR_TYPE_RGB)
- bytes_per_pixel = 3;
- else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
- bytes_per_pixel = 4;
- else
- return;
-
- for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
- {
- *(rp) = (png_byte)((*rp - *(rp+1))&0xff);
- *(rp+2) = (png_byte)((*(rp+2) - *(rp+1))&0xff);
- }
- }
- else if (row_info->bit_depth == 16)
- {
- png_bytep rp;
- png_uint_32 i;
-
- if (row_info->color_type == PNG_COLOR_TYPE_RGB)
- bytes_per_pixel = 6;
- else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
- bytes_per_pixel = 8;
- else
- return;
-
- for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
- {
- png_uint_32 s0 = (*(rp ) << 8) | *(rp+1);
- png_uint_32 s1 = (*(rp+2) << 8) | *(rp+3);
- png_uint_32 s2 = (*(rp+4) << 8) | *(rp+5);
- png_uint_32 red = (png_uint_32)((s0-s1) & 0xffffL);
- png_uint_32 blue = (png_uint_32)((s2-s1) & 0xffffL);
- *(rp ) = (png_byte)((red >> 8) & 0xff);
- *(rp+1) = (png_byte)(red & 0xff);
- *(rp+4) = (png_byte)((blue >> 8) & 0xff);
- *(rp+5) = (png_byte)(blue & 0xff);
- }
- }
- }
- }
- #endif /* PNG_MNG_FEATURES_SUPPORTED */
- #endif /* PNG_WRITE_SUPPORTED */
- /********* End of inlined file: pngwtran.c *********/
-
- /********* Start of inlined file: pngwutil.c *********/
- /* pngwutil.c - utilities to write a PNG file
- *
- * Last changed in libpng 1.2.20 Septhember 3, 2007
- * For conditions of distribution and use, see copyright notice in png.h
- * Copyright (c) 1998-2007 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
- */
-
- #define PNG_INTERNAL
-
- #ifdef PNG_WRITE_SUPPORTED
-
- /* Place a 32-bit number into a buffer in PNG byte order. We work
- * with unsigned numbers for convenience, although one supported
- * ancillary chunk uses signed (two's complement) numbers.
- */
- void PNGAPI
- png_save_uint_32(png_bytep buf, png_uint_32 i)
- {
- buf[0] = (png_byte)((i >> 24) & 0xff);
- buf[1] = (png_byte)((i >> 16) & 0xff);
- buf[2] = (png_byte)((i >> 8) & 0xff);
- buf[3] = (png_byte)(i & 0xff);
- }
-
- /* The png_save_int_32 function assumes integers are stored in two's
- * complement format. If this isn't the case, then this routine needs to
- * be modified to write data in two's complement format.
- */
- void PNGAPI
- png_save_int_32(png_bytep buf, png_int_32 i)
- {
- buf[0] = (png_byte)((i >> 24) & 0xff);
- buf[1] = (png_byte)((i >> 16) & 0xff);
- buf[2] = (png_byte)((i >> 8) & 0xff);
- buf[3] = (png_byte)(i & 0xff);
- }
-
- /* Place a 16-bit number into a buffer in PNG byte order.
- * The parameter is declared unsigned int, not png_uint_16,
- * just to avoid potential problems on pre-ANSI C compilers.
- */
- void PNGAPI
- png_save_uint_16(png_bytep buf, unsigned int i)
- {
- buf[0] = (png_byte)((i >> 8) & 0xff);
- buf[1] = (png_byte)(i & 0xff);
- }
-
- /* Write a PNG chunk all at once. The type is an array of ASCII characters
- * representing the chunk name. The array must be at least 4 bytes in
- * length, and does not need to be null terminated. To be safe, pass the
- * pre-defined chunk names here, and if you need a new one, define it
- * where the others are defined. The length is the length of the data.
- * All the data must be present. If that is not possible, use the
- * png_write_chunk_start(), png_write_chunk_data(), and png_write_chunk_end()
- * functions instead.
- */
- void PNGAPI
- png_write_chunk(png_structp png_ptr, png_bytep chunk_name,
- png_bytep data, png_size_t length)
- {
- if(png_ptr == NULL) return;
- png_write_chunk_start(png_ptr, chunk_name, (png_uint_32)length);
- png_write_chunk_data(png_ptr, data, length);
- png_write_chunk_end(png_ptr);
- }
-
- /* Write the start of a PNG chunk. The type is the chunk type.
- * The total_length is the sum of the lengths of all the data you will be
- * passing in png_write_chunk_data().
- */
- void PNGAPI
- png_write_chunk_start(png_structp png_ptr, png_bytep chunk_name,
- png_uint_32 length)
- {
- png_byte buf[4];
- png_debug2(0, "Writing %s chunk (%lu bytes)\n", chunk_name, length);
- if(png_ptr == NULL) return;
-
- /* write the length */
- png_save_uint_32(buf, length);
- png_write_data(png_ptr, buf, (png_size_t)4);
-
- /* write the chunk name */
- png_write_data(png_ptr, chunk_name, (png_size_t)4);
- /* reset the crc and run it over the chunk name */
- png_reset_crc(png_ptr);
- png_calculate_crc(png_ptr, chunk_name, (png_size_t)4);
- }
-
- /* Write the data of a PNG chunk started with png_write_chunk_start().
- * Note that multiple calls to this function are allowed, and that the
- * sum of the lengths from these calls *must* add up to the total_length
- * given to png_write_chunk_start().
- */
- void PNGAPI
- png_write_chunk_data(png_structp png_ptr, png_bytep data, png_size_t length)
- {
- /* write the data, and run the CRC over it */
- if(png_ptr == NULL) return;
- if (data != NULL && length > 0)
- {
- png_calculate_crc(png_ptr, data, length);
- png_write_data(png_ptr, data, length);
- }
- }
-
- /* Finish a chunk started with png_write_chunk_start(). */
- void PNGAPI
- png_write_chunk_end(png_structp png_ptr)
- {
- png_byte buf[4];
-
- if(png_ptr == NULL) return;
-
- /* write the crc */
- png_save_uint_32(buf, png_ptr->crc);
-
- png_write_data(png_ptr, buf, (png_size_t)4);
- }
-
- /* Simple function to write the signature. If we have already written
- * the magic bytes of the signature, or more likely, the PNG stream is
- * being embedded into another stream and doesn't need its own signature,
- * we should call png_set_sig_bytes() to tell libpng how many of the
- * bytes have already been written.
- */
- void /* PRIVATE */
- png_write_sig(png_structp png_ptr)
- {
- png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10};
- /* write the rest of the 8 byte signature */
- png_write_data(png_ptr, &png_signature[png_ptr->sig_bytes],
- (png_size_t)8 - png_ptr->sig_bytes);
- if(png_ptr->sig_bytes < 3)
- png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE;
- }
-
- #if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_iCCP_SUPPORTED)
- /*
- * This pair of functions encapsulates the operation of (a) compressing a
- * text string, and (b) issuing it later as a series of chunk data writes.
- * The compression_state structure is shared context for these functions
- * set up by the caller in order to make the whole mess thread-safe.
- */
-
- typedef struct
- {
- char *input; /* the uncompressed input data */
- int input_len; /* its length */
- int num_output_ptr; /* number of output pointers used */
- int max_output_ptr; /* size of output_ptr */
- png_charpp output_ptr; /* array of pointers to output */
- } compression_state;
-
- /* compress given text into storage in the png_ptr structure */
- static int /* PRIVATE */
- png_text_compress(png_structp png_ptr,
- png_charp text, png_size_t text_len, int compression,
- compression_state *comp)
- {
- int ret;
-
- comp->num_output_ptr = 0;
- comp->max_output_ptr = 0;
- comp->output_ptr = NULL;
- comp->input = NULL;
- comp->input_len = 0;
-
- /* we may just want to pass the text right through */
- if (compression == PNG_TEXT_COMPRESSION_NONE)
- {
- comp->input = text;
- comp->input_len = text_len;
- return((int)text_len);
- }
-
- if (compression >= PNG_TEXT_COMPRESSION_LAST)
- {
- #if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
- char msg[50];
- png_snprintf(msg, 50, "Unknown compression type %d", compression);
- png_warning(png_ptr, msg);
- #else
- png_warning(png_ptr, "Unknown compression type");
- #endif
- }
-
- /* We can't write the chunk until we find out how much data we have,
- * which means we need to run the compressor first and save the
- * output. This shouldn't be a problem, as the vast majority of
- * comments should be reasonable, but we will set up an array of
- * malloc'd pointers to be sure.
- *
- * If we knew the application was well behaved, we could simplify this
- * greatly by assuming we can always malloc an output buffer large
- * enough to hold the compressed text ((1001 * text_len / 1000) + 12)
- * and malloc this directly. The only time this would be a bad idea is
- * if we can't malloc more than 64K and we have 64K of random input
- * data, or if the input string is incredibly large (although this
- * wouldn't cause a failure, just a slowdown due to swapping).
- */
-
- /* set up the compression buffers */
- png_ptr->zstream.avail_in = (uInt)text_len;
- png_ptr->zstream.next_in = (Bytef *)text;
- png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
- png_ptr->zstream.next_out = (Bytef *)png_ptr->zbuf;
-
- /* this is the same compression loop as in png_write_row() */
- do
- {
- /* compress the data */
- ret = deflate(&png_ptr->zstream, Z_NO_FLUSH);
- if (ret != Z_OK)
- {
- /* error */
- if (png_ptr->zstream.msg != NULL)
- png_error(png_ptr, png_ptr->zstream.msg);
- else
- png_error(png_ptr, "zlib error");
- }
- /* check to see if we need more room */
- if (!(png_ptr->zstream.avail_out))
- {
- /* make sure the output array has room */
- if (comp->num_output_ptr >= comp->max_output_ptr)
- {
- int old_max;
-
- old_max = comp->max_output_ptr;
- comp->max_output_ptr = comp->num_output_ptr + 4;
- if (comp->output_ptr != NULL)
- {
- png_charpp old_ptr;
-
- old_ptr = comp->output_ptr;
- comp->output_ptr = (png_charpp)png_malloc(png_ptr,
- (png_uint_32)(comp->max_output_ptr *
- png_sizeof (png_charpp)));
- png_memcpy(comp->output_ptr, old_ptr, old_max
- * png_sizeof (png_charp));
- png_free(png_ptr, old_ptr);
- }
- else
- comp->output_ptr = (png_charpp)png_malloc(png_ptr,
- (png_uint_32)(comp->max_output_ptr *
- png_sizeof (png_charp)));
- }
-
- /* save the data */
- comp->output_ptr[comp->num_output_ptr] = (png_charp)png_malloc(png_ptr,
- (png_uint_32)png_ptr->zbuf_size);
- png_memcpy(comp->output_ptr[comp->num_output_ptr], png_ptr->zbuf,
- png_ptr->zbuf_size);
- comp->num_output_ptr++;
-
- /* and reset the buffer */
- png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
- png_ptr->zstream.next_out = png_ptr->zbuf;
- }
- /* continue until we don't have any more to compress */
- } while (png_ptr->zstream.avail_in);
-
- /* finish the compression */
- do
- {
- /* tell zlib we are finished */
- ret = deflate(&png_ptr->zstream, Z_FINISH);
-
- if (ret == Z_OK)
- {
- /* check to see if we need more room */
- if (!(png_ptr->zstream.avail_out))
- {
- /* check to make sure our output array has room */
- if (comp->num_output_ptr >= comp->max_output_ptr)
- {
- int old_max;
-
- old_max = comp->max_output_ptr;
- comp->max_output_ptr = comp->num_output_ptr + 4;
- if (comp->output_ptr != NULL)
- {
- png_charpp old_ptr;
-
- old_ptr = comp->output_ptr;
- /* This could be optimized to realloc() */
- comp->output_ptr = (png_charpp)png_malloc(png_ptr,
- (png_uint_32)(comp->max_output_ptr *
- png_sizeof (png_charpp)));
- png_memcpy(comp->output_ptr, old_ptr,
- old_max * png_sizeof (png_charp));
- png_free(png_ptr, old_ptr);
- }
- else
- comp->output_ptr = (png_charpp)png_malloc(png_ptr,
- (png_uint_32)(comp->max_output_ptr *
- png_sizeof (png_charp)));
- }
-
- /* save off the data */
- comp->output_ptr[comp->num_output_ptr] =
- (png_charp)png_malloc(png_ptr, (png_uint_32)png_ptr->zbuf_size);
- png_memcpy(comp->output_ptr[comp->num_output_ptr], png_ptr->zbuf,
- png_ptr->zbuf_size);
- comp->num_output_ptr++;
-
- /* and reset the buffer pointers */
- png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
- png_ptr->zstream.next_out = png_ptr->zbuf;
- }
- }
- else if (ret != Z_STREAM_END)
- {
- /* we got an error */
- if (png_ptr->zstream.msg != NULL)
- png_error(png_ptr, png_ptr->zstream.msg);
- else
- png_error(png_ptr, "zlib error");
- }
- } while (ret != Z_STREAM_END);
-
- /* text length is number of buffers plus last buffer */
- text_len = png_ptr->zbuf_size * comp->num_output_ptr;
- if (png_ptr->zstream.avail_out < png_ptr->zbuf_size)
- text_len += png_ptr->zbuf_size - (png_size_t)png_ptr->zstream.avail_out;
-
- return((int)text_len);
- }
-
- /* ship the compressed text out via chunk writes */
- static void /* PRIVATE */
- png_write_compressed_data_out(png_structp png_ptr, compression_state *comp)
- {
- int i;
-
- /* handle the no-compression case */
- if (comp->input)
- {
- png_write_chunk_data(png_ptr, (png_bytep)comp->input,
- (png_size_t)comp->input_len);
- return;
- }
-
- /* write saved output buffers, if any */
- for (i = 0; i < comp->num_output_ptr; i++)
- {
- png_write_chunk_data(png_ptr,(png_bytep)comp->output_ptr[i],
- png_ptr->zbuf_size);
- png_free(png_ptr, comp->output_ptr[i]);
- comp->output_ptr[i]=NULL;
- }
- if (comp->max_output_ptr != 0)
- png_free(png_ptr, comp->output_ptr);
- comp->output_ptr=NULL;
- /* write anything left in zbuf */
- if (png_ptr->zstream.avail_out < (png_uint_32)png_ptr->zbuf_size)
- png_write_chunk_data(png_ptr, png_ptr->zbuf,
- png_ptr->zbuf_size - png_ptr->zstream.avail_out);
-
- /* reset zlib for another zTXt/iTXt or image data */
- deflateReset(&png_ptr->zstream);
- png_ptr->zstream.data_type = Z_BINARY;
- }
- #endif
-
- /* Write the IHDR chunk, and update the png_struct with the necessary
- * information. Note that the rest of this code depends upon this
- * information being correct.
- */
- void /* PRIVATE */
- png_write_IHDR(png_structp png_ptr, png_uint_32 width, png_uint_32 height,
- int bit_depth, int color_type, int compression_type, int filter_type,
- int interlace_type)
- {
- #ifdef PNG_USE_LOCAL_ARRAYS
- PNG_IHDR;
- #endif
- png_byte buf[13]; /* buffer to store the IHDR info */
-
- png_debug(1, "in png_write_IHDR\n");
- /* Check that we have valid input data from the application info */
- switch (color_type)
- {
- case PNG_COLOR_TYPE_GRAY:
- switch (bit_depth)
- {
- case 1:
- case 2:
- case 4:
- case 8:
- case 16: png_ptr->channels = 1; break;
- default: png_error(png_ptr,"Invalid bit depth for grayscale image");
- }
- break;
- case PNG_COLOR_TYPE_RGB:
- if (bit_depth != 8 && bit_depth != 16)
- png_error(png_ptr, "Invalid bit depth for RGB image");
- png_ptr->channels = 3;
- break;
- case PNG_COLOR_TYPE_PALETTE:
- switch (bit_depth)
- {
- case 1:
- case 2:
- case 4:
- case 8: png_ptr->channels = 1; break;
- default: png_error(png_ptr, "Invalid bit depth for paletted image");
- }
- break;
- case PNG_COLOR_TYPE_GRAY_ALPHA:
- if (bit_depth != 8 && bit_depth != 16)
- png_error(png_ptr, "Invalid bit depth for grayscale+alpha image");
- png_ptr->channels = 2;
- break;
- case PNG_COLOR_TYPE_RGB_ALPHA:
- if (bit_depth != 8 && bit_depth != 16)
- png_error(png_ptr, "Invalid bit depth for RGBA image");
- png_ptr->channels = 4;
- break;
- default:
- png_error(png_ptr, "Invalid image color type specified");
- }
-
- if (compression_type != PNG_COMPRESSION_TYPE_BASE)
- {
- png_warning(png_ptr, "Invalid compression type specified");
- compression_type = PNG_COMPRESSION_TYPE_BASE;
- }
-
- /* Write filter_method 64 (intrapixel differencing) only if
- * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and
- * 2. Libpng did not write a PNG signature (this filter_method is only
- * used in PNG datastreams that are embedded in MNG datastreams) and
- * 3. The application called png_permit_mng_features with a mask that
- * included PNG_FLAG_MNG_FILTER_64 and
- * 4. The filter_method is 64 and
- * 5. The color_type is RGB or RGBA
- */
- if (
- #if defined(PNG_MNG_FEATURES_SUPPORTED)
- !((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
- ((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE) == 0) &&
- (color_type == PNG_COLOR_TYPE_RGB ||
- color_type == PNG_COLOR_TYPE_RGB_ALPHA) &&
- (filter_type == PNG_INTRAPIXEL_DIFFERENCING)) &&
- #endif
- filter_type != PNG_FILTER_TYPE_BASE)
- {
- png_warning(png_ptr, "Invalid filter type specified");
- filter_type = PNG_FILTER_TYPE_BASE;
- }
-
- #ifdef PNG_WRITE_INTERLACING_SUPPORTED
- if (interlace_type != PNG_INTERLACE_NONE &&
- interlace_type != PNG_INTERLACE_ADAM7)
- {
- png_warning(png_ptr, "Invalid interlace type specified");
- interlace_type = PNG_INTERLACE_ADAM7;
- }
- #else
- interlace_type=PNG_INTERLACE_NONE;
- #endif
-
- /* save off the relevent information */
- png_ptr->bit_depth = (png_byte)bit_depth;
- png_ptr->color_type = (png_byte)color_type;
- png_ptr->interlaced = (png_byte)interlace_type;
- #if defined(PNG_MNG_FEATURES_SUPPORTED)
- png_ptr->filter_type = (png_byte)filter_type;
- #endif
- png_ptr->compression_type = (png_byte)compression_type;
- png_ptr->width = width;
- png_ptr->height = height;
-
- png_ptr->pixel_depth = (png_byte)(bit_depth * png_ptr->channels);
- png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, width);
- /* set the usr info, so any transformations can modify it */
- png_ptr->usr_width = png_ptr->width;
- png_ptr->usr_bit_depth = png_ptr->bit_depth;
- png_ptr->usr_channels = png_ptr->channels;
-
- /* pack the header information into the buffer */
- png_save_uint_32(buf, width);
- png_save_uint_32(buf + 4, height);
- buf[8] = (png_byte)bit_depth;
- buf[9] = (png_byte)color_type;
- buf[10] = (png_byte)compression_type;
- buf[11] = (png_byte)filter_type;
- buf[12] = (png_byte)interlace_type;
-
- /* write the chunk */
- png_write_chunk(png_ptr, png_IHDR, buf, (png_size_t)13);
-
- /* initialize zlib with PNG info */
- png_ptr->zstream.zalloc = png_zalloc;
- png_ptr->zstream.zfree = png_zfree;
- png_ptr->zstream.opaque = (voidpf)png_ptr;
- if (!(png_ptr->do_filter))
- {
- if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE ||
- png_ptr->bit_depth < 8)
- png_ptr->do_filter = PNG_FILTER_NONE;
- else
- png_ptr->do_filter = PNG_ALL_FILTERS;
- }
- if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_STRATEGY))
- {
- if (png_ptr->do_filter != PNG_FILTER_NONE)
- png_ptr->zlib_strategy = Z_FILTERED;
- else
- png_ptr->zlib_strategy = Z_DEFAULT_STRATEGY;
- }
- if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_LEVEL))
- png_ptr->zlib_level = Z_DEFAULT_COMPRESSION;
- if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL))
- png_ptr->zlib_mem_level = 8;
- if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS))
- png_ptr->zlib_window_bits = 15;
- if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_METHOD))
- png_ptr->zlib_method = 8;
- if (deflateInit2(&png_ptr->zstream, png_ptr->zlib_level,
- png_ptr->zlib_method, png_ptr->zlib_window_bits,
- png_ptr->zlib_mem_level, png_ptr->zlib_strategy) != Z_OK)
- png_error(png_ptr, "zlib failed to initialize compressor");
- png_ptr->zstream.next_out = png_ptr->zbuf;
- png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
- /* libpng is not interested in zstream.data_type */
- /* set it to a predefined value, to avoid its evaluation inside zlib */
- png_ptr->zstream.data_type = Z_BINARY;
-
- png_ptr->mode = PNG_HAVE_IHDR;
- }
-
- /* write the palette. We are careful not to trust png_color to be in the
- * correct order for PNG, so people can redefine it to any convenient
- * structure.
- */
- void /* PRIVATE */
- png_write_PLTE(png_structp png_ptr, png_colorp palette, png_uint_32 num_pal)
- {
- #ifdef PNG_USE_LOCAL_ARRAYS
- PNG_PLTE;
- #endif
- png_uint_32 i;
- png_colorp pal_ptr;
- png_byte buf[3];
-
- png_debug(1, "in png_write_PLTE\n");
- if ((
- #if defined(PNG_MNG_FEATURES_SUPPORTED)
- !(png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) &&
- #endif
- num_pal == 0) || num_pal > 256)
- {
- if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
- {
- png_error(png_ptr, "Invalid number of colors in palette");
- }
- else
- {
- png_warning(png_ptr, "Invalid number of colors in palette");
- return;
- }
- }
-
- if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR))
- {
- png_warning(png_ptr,
- "Ignoring request to write a PLTE chunk in grayscale PNG");
- return;
- }
-
- png_ptr->num_palette = (png_uint_16)num_pal;
- png_debug1(3, "num_palette = %d\n", png_ptr->num_palette);
-
- png_write_chunk_start(png_ptr, png_PLTE, num_pal * 3);
- #ifndef PNG_NO_POINTER_INDEXING
- for (i = 0, pal_ptr = palette; i < num_pal; i++, pal_ptr++)
- {
- buf[0] = pal_ptr->red;
- buf[1] = pal_ptr->green;
- buf[2] = pal_ptr->blue;
- png_write_chunk_data(png_ptr, buf, (png_size_t)3);
- }
- #else
- /* This is a little slower but some buggy compilers need to do this instead */
- pal_ptr=palette;
- for (i = 0; i < num_pal; i++)
- {
- buf[0] = pal_ptr[i].red;
- buf[1] = pal_ptr[i].green;
- buf[2] = pal_ptr[i].blue;
- png_write_chunk_data(png_ptr, buf, (png_size_t)3);
- }
- #endif
- png_write_chunk_end(png_ptr);
- png_ptr->mode |= PNG_HAVE_PLTE;
- }
-
- /* write an IDAT chunk */
- void /* PRIVATE */
- png_write_IDAT(png_structp png_ptr, png_bytep data, png_size_t length)
- {
- #ifdef PNG_USE_LOCAL_ARRAYS
- PNG_IDAT;
- #endif
- png_debug(1, "in png_write_IDAT\n");
-
- /* Optimize the CMF field in the zlib stream. */
- /* This hack of the zlib stream is compliant to the stream specification. */
- if (!(png_ptr->mode & PNG_HAVE_IDAT) &&
- png_ptr->compression_type == PNG_COMPRESSION_TYPE_BASE)
- {
- unsigned int z_cmf = data[0]; /* zlib compression method and flags */
- if ((z_cmf & 0x0f) == 8 && (z_cmf & 0xf0) <= 0x70)
- {
- /* Avoid memory underflows and multiplication overflows. */
- /* The conditions below are practically always satisfied;
- however, they still must be checked. */
- if (length >= 2 &&
- png_ptr->height < 16384 && png_ptr->width < 16384)
- {
- png_uint_32 uncompressed_idat_size = png_ptr->height *
- ((png_ptr->width *
- png_ptr->channels * png_ptr->bit_depth + 15) >> 3);
- unsigned int z_cinfo = z_cmf >> 4;
- unsigned int half_z_window_size = 1 << (z_cinfo + 7);
- while (uncompressed_idat_size <= half_z_window_size &&
- half_z_window_size >= 256)
- {
- z_cinfo--;
- half_z_window_size >>= 1;
- }
- z_cmf = (z_cmf & 0x0f) | (z_cinfo << 4);
- if (data[0] != (png_byte)z_cmf)
- {
- data[0] = (png_byte)z_cmf;
- data[1] &= 0xe0;
- data[1] += (png_byte)(0x1f - ((z_cmf << 8) + data[1]) % 0x1f);
- }
- }
- }
- else
- png_error(png_ptr,
- "Invalid zlib compression method or flags in IDAT");
- }
-
- png_write_chunk(png_ptr, png_IDAT, data, length);
- png_ptr->mode |= PNG_HAVE_IDAT;
- }
-
- /* write an IEND chunk */
- void /* PRIVATE */
- png_write_IEND(png_structp png_ptr)
- {
- #ifdef PNG_USE_LOCAL_ARRAYS
- PNG_IEND;
- #endif
- png_debug(1, "in png_write_IEND\n");
- png_write_chunk(png_ptr, png_IEND, png_bytep_NULL,
- (png_size_t)0);
- png_ptr->mode |= PNG_HAVE_IEND;
- }
-
- #if defined(PNG_WRITE_gAMA_SUPPORTED)
- /* write a gAMA chunk */
- #ifdef PNG_FLOATING_POINT_SUPPORTED
- void /* PRIVATE */
- png_write_gAMA(png_structp png_ptr, double file_gamma)
- {
- #ifdef PNG_USE_LOCAL_ARRAYS
- PNG_gAMA;
- #endif
- png_uint_32 igamma;
- png_byte buf[4];
-
- png_debug(1, "in png_write_gAMA\n");
- /* file_gamma is saved in 1/100,000ths */
- igamma = (png_uint_32)(file_gamma * 100000.0 + 0.5);
- png_save_uint_32(buf, igamma);
- png_write_chunk(png_ptr, png_gAMA, buf, (png_size_t)4);
- }
- #endif
- #ifdef PNG_FIXED_POINT_SUPPORTED
- void /* PRIVATE */
- png_write_gAMA_fixed(png_structp png_ptr, png_fixed_point file_gamma)
- {
- #ifdef PNG_USE_LOCAL_ARRAYS
- PNG_gAMA;
- #endif
- png_byte buf[4];
-
- png_debug(1, "in png_write_gAMA\n");
- /* file_gamma is saved in 1/100,000ths */
- png_save_uint_32(buf, (png_uint_32)file_gamma);
- png_write_chunk(png_ptr, png_gAMA, buf, (png_size_t)4);
- }
- #endif
- #endif
-
- #if defined(PNG_WRITE_sRGB_SUPPORTED)
- /* write a sRGB chunk */
- void /* PRIVATE */
- png_write_sRGB(png_structp png_ptr, int srgb_intent)
- {
- #ifdef PNG_USE_LOCAL_ARRAYS
- PNG_sRGB;
- #endif
- png_byte buf[1];
-
- png_debug(1, "in png_write_sRGB\n");
- if(srgb_intent >= PNG_sRGB_INTENT_LAST)
- png_warning(png_ptr,
- "Invalid sRGB rendering intent specified");
- buf[0]=(png_byte)srgb_intent;
- png_write_chunk(png_ptr, png_sRGB, buf, (png_size_t)1);
- }
- #endif
-
- #if defined(PNG_WRITE_iCCP_SUPPORTED)
- /* write an iCCP chunk */
- void /* PRIVATE */
- png_write_iCCP(png_structp png_ptr, png_charp name, int compression_type,
- png_charp profile, int profile_len)
- {
- #ifdef PNG_USE_LOCAL_ARRAYS
- PNG_iCCP;
- #endif
- png_size_t name_len;
- png_charp new_name;
- compression_state comp;
- int embedded_profile_len = 0;
-
- png_debug(1, "in png_write_iCCP\n");
-
- comp.num_output_ptr = 0;
- comp.max_output_ptr = 0;
- comp.output_ptr = NULL;
- comp.input = NULL;
- comp.input_len = 0;
-
- if (name == NULL || (name_len = png_check_keyword(png_ptr, name,
- &new_name)) == 0)
- {
- png_warning(png_ptr, "Empty keyword in iCCP chunk");
- return;
- }
-
- if (compression_type != PNG_COMPRESSION_TYPE_BASE)
- png_warning(png_ptr, "Unknown compression type in iCCP chunk");
-
- if (profile == NULL)
- profile_len = 0;
-
- if (profile_len > 3)
- embedded_profile_len =
- ((*( (png_bytep)profile ))<<24) |
- ((*( (png_bytep)profile+1))<<16) |
- ((*( (png_bytep)profile+2))<< 8) |
- ((*( (png_bytep)profile+3)) );
-
- if (profile_len < embedded_profile_len)
- {
- png_warning(png_ptr,
- "Embedded profile length too large in iCCP chunk");
- return;
- }
-
- if (profile_len > embedded_profile_len)
- {
- png_warning(png_ptr,
- "Truncating profile to actual length in iCCP chunk");
- profile_len = embedded_profile_len;
- }
-
- if (profile_len)
- profile_len = png_text_compress(png_ptr, profile, (png_size_t)profile_len,
- PNG_COMPRESSION_TYPE_BASE, &comp);
-
- /* make sure we include the NULL after the name and the compression type */
- png_write_chunk_start(png_ptr, png_iCCP,
- (png_uint_32)name_len+profile_len+2);
- new_name[name_len+1]=0x00;
- png_write_chunk_data(png_ptr, (png_bytep)new_name, name_len + 2);
-
- if (profile_len)
- png_write_compressed_data_out(png_ptr, &comp);
-
- png_write_chunk_end(png_ptr);
- png_free(png_ptr, new_name);
- }
- #endif
-
- #if defined(PNG_WRITE_sPLT_SUPPORTED)
- /* write a sPLT chunk */
- void /* PRIVATE */
- png_write_sPLT(png_structp png_ptr, png_sPLT_tp spalette)
- {
- #ifdef PNG_USE_LOCAL_ARRAYS
- PNG_sPLT;
- #endif
- png_size_t name_len;
- png_charp new_name;
- png_byte entrybuf[10];
- int entry_size = (spalette->depth == 8 ? 6 : 10);
- int palette_size = entry_size * spalette->nentries;
- png_sPLT_entryp ep;
- #ifdef PNG_NO_POINTER_INDEXING
- int i;
- #endif
-
- png_debug(1, "in png_write_sPLT\n");
- if (spalette->name == NULL || (name_len = png_check_keyword(png_ptr,
- spalette->name, &new_name))==0)
- {
- png_warning(png_ptr, "Empty keyword in sPLT chunk");
- return;
- }
-
- /* make sure we include the NULL after the name */
- png_write_chunk_start(png_ptr, png_sPLT,
- (png_uint_32)(name_len + 2 + palette_size));
- png_write_chunk_data(png_ptr, (png_bytep)new_name, name_len + 1);
- png_write_chunk_data(png_ptr, (png_bytep)&spalette->depth, 1);
-
- /* loop through each palette entry, writing appropriately */
- #ifndef PNG_NO_POINTER_INDEXING
- for (ep = spalette->entries; ep<spalette->entries+spalette->nentries; ep++)
- {
- if (spalette->depth == 8)
- {
- entrybuf[0] = (png_byte)ep->red;
- entrybuf[1] = (png_byte)ep->green;
- entrybuf[2] = (png_byte)ep->blue;
- entrybuf[3] = (png_byte)ep->alpha;
- png_save_uint_16(entrybuf + 4, ep->frequency);
- }
- else
- {
- png_save_uint_16(entrybuf + 0, ep->red);
- png_save_uint_16(entrybuf + 2, ep->green);
- png_save_uint_16(entrybuf + 4, ep->blue);
- png_save_uint_16(entrybuf + 6, ep->alpha);
- png_save_uint_16(entrybuf + 8, ep->frequency);
- }
- png_write_chunk_data(png_ptr, entrybuf, (png_size_t)entry_size);
- }
- #else
- ep=spalette->entries;
- for (i=0; i>spalette->nentries; i++)
- {
- if (spalette->depth == 8)
- {
- entrybuf[0] = (png_byte)ep[i].red;
- entrybuf[1] = (png_byte)ep[i].green;
- entrybuf[2] = (png_byte)ep[i].blue;
- entrybuf[3] = (png_byte)ep[i].alpha;
- png_save_uint_16(entrybuf + 4, ep[i].frequency);
- }
- else
- {
- png_save_uint_16(entrybuf + 0, ep[i].red);
- png_save_uint_16(entrybuf + 2, ep[i].green);
- png_save_uint_16(entrybuf + 4, ep[i].blue);
- png_save_uint_16(entrybuf + 6, ep[i].alpha);
- png_save_uint_16(entrybuf + 8, ep[i].frequency);
- }
- png_write_chunk_data(png_ptr, entrybuf, entry_size);
- }
- #endif
-
- png_write_chunk_end(png_ptr);
- png_free(png_ptr, new_name);
- }
- #endif
-
- #if defined(PNG_WRITE_sBIT_SUPPORTED)
- /* write the sBIT chunk */
- void /* PRIVATE */
- png_write_sBIT(png_structp png_ptr, png_color_8p sbit, int color_type)
- {
- #ifdef PNG_USE_LOCAL_ARRAYS
- PNG_sBIT;
- #endif
- png_byte buf[4];
- png_size_t size;
-
- png_debug(1, "in png_write_sBIT\n");
- /* make sure we don't depend upon the order of PNG_COLOR_8 */
- if (color_type & PNG_COLOR_MASK_COLOR)
- {
- png_byte maxbits;
-
- maxbits = (png_byte)(color_type==PNG_COLOR_TYPE_PALETTE ? 8 :
- png_ptr->usr_bit_depth);
- if (sbit->red == 0 || sbit->red > maxbits ||
- sbit->green == 0 || sbit->green > maxbits ||
- sbit->blue == 0 || sbit->blue > maxbits)
- {
- png_warning(png_ptr, "Invalid sBIT depth specified");
- return;
- }
- buf[0] = sbit->red;
- buf[1] = sbit->green;
- buf[2] = sbit->blue;
- size = 3;
- }
- else
- {
- if (sbit->gray == 0 || sbit->gray > png_ptr->usr_bit_depth)
- {
- png_warning(png_ptr, "Invalid sBIT depth specified");
- return;
- }
- buf[0] = sbit->gray;
- size = 1;
- }
-
- if (color_type & PNG_COLOR_MASK_ALPHA)
- {
- if (sbit->alpha == 0 || sbit->alpha > png_ptr->usr_bit_depth)
- {
- png_warning(png_ptr, "Invalid sBIT depth specified");
- return;
- }
- buf[size++] = sbit->alpha;
- }
-
- png_write_chunk(png_ptr, png_sBIT, buf, size);
- }
- #endif
-
- #if defined(PNG_WRITE_cHRM_SUPPORTED)
- /* write the cHRM chunk */
- #ifdef PNG_FLOATING_POINT_SUPPORTED
- void /* PRIVATE */
- png_write_cHRM(png_structp png_ptr, double white_x, double white_y,
- double red_x, double red_y, double green_x, double green_y,
- double blue_x, double blue_y)
- {
- #ifdef PNG_USE_LOCAL_ARRAYS
- PNG_cHRM;
- #endif
- png_byte buf[32];
- png_uint_32 itemp;
-
- png_debug(1, "in png_write_cHRM\n");
- /* each value is saved in 1/100,000ths */
- if (white_x < 0 || white_x > 0.8 || white_y < 0 || white_y > 0.8 ||
- white_x + white_y > 1.0)
- {
- png_warning(png_ptr, "Invalid cHRM white point specified");
- #if !defined(PNG_NO_CONSOLE_IO)
- fprintf(stderr,"white_x=%f, white_y=%f\n",white_x, white_y);
- #endif
- return;
- }
- itemp = (png_uint_32)(white_x * 100000.0 + 0.5);
- png_save_uint_32(buf, itemp);
- itemp = (png_uint_32)(white_y * 100000.0 + 0.5);
- png_save_uint_32(buf + 4, itemp);
-
- if (red_x < 0 || red_y < 0 || red_x + red_y > 1.0)
- {
- png_warning(png_ptr, "Invalid cHRM red point specified");
- return;
- }
- itemp = (png_uint_32)(red_x * 100000.0 + 0.5);
- png_save_uint_32(buf + 8, itemp);
- itemp = (png_uint_32)(red_y * 100000.0 + 0.5);
- png_save_uint_32(buf + 12, itemp);
-
- if (green_x < 0 || green_y < 0 || green_x + green_y > 1.0)
- {
- png_warning(png_ptr, "Invalid cHRM green point specified");
- return;
- }
- itemp = (png_uint_32)(green_x * 100000.0 + 0.5);
- png_save_uint_32(buf + 16, itemp);
- itemp = (png_uint_32)(green_y * 100000.0 + 0.5);
- png_save_uint_32(buf + 20, itemp);
-
- if (blue_x < 0 || blue_y < 0 || blue_x + blue_y > 1.0)
- {
- png_warning(png_ptr, "Invalid cHRM blue point specified");
- return;
- }
- itemp = (png_uint_32)(blue_x * 100000.0 + 0.5);
- png_save_uint_32(buf + 24, itemp);
- itemp = (png_uint_32)(blue_y * 100000.0 + 0.5);
- png_save_uint_32(buf + 28, itemp);
-
- png_write_chunk(png_ptr, png_cHRM, buf, (png_size_t)32);
- }
- #endif
- #ifdef PNG_FIXED_POINT_SUPPORTED
- void /* PRIVATE */
- png_write_cHRM_fixed(png_structp png_ptr, png_fixed_point white_x,
- png_fixed_point white_y, png_fixed_point red_x, png_fixed_point red_y,
- png_fixed_point green_x, png_fixed_point green_y, png_fixed_point blue_x,
- png_fixed_point blue_y)
- {
- #ifdef PNG_USE_LOCAL_ARRAYS
- PNG_cHRM;
- #endif
- png_byte buf[32];
-
- png_debug(1, "in png_write_cHRM\n");
- /* each value is saved in 1/100,000ths */
- if (white_x > 80000L || white_y > 80000L || white_x + white_y > 100000L)
- {
- png_warning(png_ptr, "Invalid fixed cHRM white point specified");
- #if !defined(PNG_NO_CONSOLE_IO)
- fprintf(stderr,"white_x=%ld, white_y=%ld\n",white_x, white_y);
- #endif
- return;
- }
- png_save_uint_32(buf, (png_uint_32)white_x);
- png_save_uint_32(buf + 4, (png_uint_32)white_y);
-
- if (red_x + red_y > 100000L)
- {
- png_warning(png_ptr, "Invalid cHRM fixed red point specified");
- return;
- }
- png_save_uint_32(buf + 8, (png_uint_32)red_x);
- png_save_uint_32(buf + 12, (png_uint_32)red_y);
-
- if (green_x + green_y > 100000L)
- {
- png_warning(png_ptr, "Invalid fixed cHRM green point specified");
- return;
- }
- png_save_uint_32(buf + 16, (png_uint_32)green_x);
- png_save_uint_32(buf + 20, (png_uint_32)green_y);
-
- if (blue_x + blue_y > 100000L)
- {
- png_warning(png_ptr, "Invalid fixed cHRM blue point specified");
- return;
- }
- png_save_uint_32(buf + 24, (png_uint_32)blue_x);
- png_save_uint_32(buf + 28, (png_uint_32)blue_y);
-
- png_write_chunk(png_ptr, png_cHRM, buf, (png_size_t)32);
- }
- #endif
- #endif
-
- #if defined(PNG_WRITE_tRNS_SUPPORTED)
- /* write the tRNS chunk */
- void /* PRIVATE */
- png_write_tRNS(png_structp png_ptr, png_bytep trans, png_color_16p tran,
- int num_trans, int color_type)
- {
- #ifdef PNG_USE_LOCAL_ARRAYS
- PNG_tRNS;
- #endif
- png_byte buf[6];
-
- png_debug(1, "in png_write_tRNS\n");
- if (color_type == PNG_COLOR_TYPE_PALETTE)
- {
- if (num_trans <= 0 || num_trans > (int)png_ptr->num_palette)
- {
- png_warning(png_ptr,"Invalid number of transparent colors specified");
- return;
- }
- /* write the chunk out as it is */
- png_write_chunk(png_ptr, png_tRNS, trans, (png_size_t)num_trans);
- }
- else if (color_type == PNG_COLOR_TYPE_GRAY)
- {
- /* one 16 bit value */
- if(tran->gray >= (1 << png_ptr->bit_depth))
- {
- png_warning(png_ptr,
- "Ignoring attempt to write tRNS chunk out-of-range for bit_depth");
- return;
- }
- png_save_uint_16(buf, tran->gray);
- png_write_chunk(png_ptr, png_tRNS, buf, (png_size_t)2);
- }
- else if (color_type == PNG_COLOR_TYPE_RGB)
- {
- /* three 16 bit values */
- png_save_uint_16(buf, tran->red);
- png_save_uint_16(buf + 2, tran->green);
- png_save_uint_16(buf + 4, tran->blue);
- if(png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4]))
- {
- png_warning(png_ptr,
- "Ignoring attempt to write 16-bit tRNS chunk when bit_depth is 8");
- return;
- }
- png_write_chunk(png_ptr, png_tRNS, buf, (png_size_t)6);
- }
- else
- {
- png_warning(png_ptr, "Can't write tRNS with an alpha channel");
- }
- }
- #endif
-
- #if defined(PNG_WRITE_bKGD_SUPPORTED)
- /* write the background chunk */
- void /* PRIVATE */
- png_write_bKGD(png_structp png_ptr, png_color_16p back, int color_type)
- {
- #ifdef PNG_USE_LOCAL_ARRAYS
- PNG_bKGD;
- #endif
- png_byte buf[6];
-
- png_debug(1, "in png_write_bKGD\n");
- if (color_type == PNG_COLOR_TYPE_PALETTE)
- {
- if (
- #if defined(PNG_MNG_FEATURES_SUPPORTED)
- (png_ptr->num_palette ||
- (!(png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE))) &&
- #endif
- back->index > png_ptr->num_palette)
- {
- png_warning(png_ptr, "Invalid background palette index");
- return;
- }
- buf[0] = back->index;
- png_write_chunk(png_ptr, png_bKGD, buf, (png_size_t)1);
- }
- else if (color_type & PNG_COLOR_MASK_COLOR)
- {
- png_save_uint_16(buf, back->red);
- png_save_uint_16(buf + 2, back->green);
- png_save_uint_16(buf + 4, back->blue);
- if(png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4]))
- {
- png_warning(png_ptr,
- "Ignoring attempt to write 16-bit bKGD chunk when bit_depth is 8");
- return;
- }
- png_write_chunk(png_ptr, png_bKGD, buf, (png_size_t)6);
- }
- else
- {
- if(back->gray >= (1 << png_ptr->bit_depth))
- {
- png_warning(png_ptr,
- "Ignoring attempt to write bKGD chunk out-of-range for bit_depth");
- return;
- }
- png_save_uint_16(buf, back->gray);
- png_write_chunk(png_ptr, png_bKGD, buf, (png_size_t)2);
- }
- }
- #endif
-
- #if defined(PNG_WRITE_hIST_SUPPORTED)
- /* write the histogram */
- void /* PRIVATE */
- png_write_hIST(png_structp png_ptr, png_uint_16p hist, int num_hist)
- {
- #ifdef PNG_USE_LOCAL_ARRAYS
- PNG_hIST;
- #endif
- int i;
- png_byte buf[3];
-
- png_debug(1, "in png_write_hIST\n");
- if (num_hist > (int)png_ptr->num_palette)
- {
- png_debug2(3, "num_hist = %d, num_palette = %d\n", num_hist,
- png_ptr->num_palette);
- png_warning(png_ptr, "Invalid number of histogram entries specified");
- return;
- }
-
- png_write_chunk_start(png_ptr, png_hIST, (png_uint_32)(num_hist * 2));
- for (i = 0; i < num_hist; i++)
- {
- png_save_uint_16(buf, hist[i]);
- png_write_chunk_data(png_ptr, buf, (png_size_t)2);
- }
- png_write_chunk_end(png_ptr);
- }
- #endif
-
- #if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED) || \
- defined(PNG_WRITE_iCCP_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED)
- /* Check that the tEXt or zTXt keyword is valid per PNG 1.0 specification,
- * and if invalid, correct the keyword rather than discarding the entire
- * chunk. The PNG 1.0 specification requires keywords 1-79 characters in
- * length, forbids leading or trailing whitespace, multiple internal spaces,
- * and the non-break space (0x80) from ISO 8859-1. Returns keyword length.
- *
- * The new_key is allocated to hold the corrected keyword and must be freed
- * by the calling routine. This avoids problems with trying to write to
- * static keywords without having to have duplicate copies of the strings.
- */
- png_size_t /* PRIVATE */
- png_check_keyword(png_structp png_ptr, png_charp key, png_charpp new_key)
- {
- png_size_t key_len;
- png_charp kp, dp;
- int kflag;
- int kwarn=0;
-
- png_debug(1, "in png_check_keyword\n");
- *new_key = NULL;
-
- if (key == NULL || (key_len = png_strlen(key)) == 0)
- {
- png_warning(png_ptr, "zero length keyword");
- return ((png_size_t)0);
- }
-
- png_debug1(2, "Keyword to be checked is '%s'\n", key);
-
- *new_key = (png_charp)png_malloc_warn(png_ptr, (png_uint_32)(key_len + 2));
- if (*new_key == NULL)
- {
- png_warning(png_ptr, "Out of memory while procesing keyword");
- return ((png_size_t)0);
- }
-
- /* Replace non-printing characters with a blank and print a warning */
- for (kp = key, dp = *new_key; *kp != '\0'; kp++, dp++)
- {
- if ((png_byte)*kp < 0x20 ||
- ((png_byte)*kp > 0x7E && (png_byte)*kp < 0xA1))
- {
- #if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
- char msg[40];
-
- png_snprintf(msg, 40,
- "invalid keyword character 0x%02X", (png_byte)*kp);
- png_warning(png_ptr, msg);
- #else
- png_warning(png_ptr, "invalid character in keyword");
- #endif
- *dp = ' ';
- }
- else
- {
- *dp = *kp;
- }
- }
- *dp = '\0';
-
- /* Remove any trailing white space. */
- kp = *new_key + key_len - 1;
- if (*kp == ' ')
- {
- png_warning(png_ptr, "trailing spaces removed from keyword");
-
- while (*kp == ' ')
- {
- *(kp--) = '\0';
- key_len--;
- }
- }
-
- /* Remove any leading white space. */
- kp = *new_key;
- if (*kp == ' ')
- {
- png_warning(png_ptr, "leading spaces removed from keyword");
-
- while (*kp == ' ')
- {
- kp++;
- key_len--;
- }
- }
-
- png_debug1(2, "Checking for multiple internal spaces in '%s'\n", kp);
-
- /* Remove multiple internal spaces. */
- for (kflag = 0, dp = *new_key; *kp != '\0'; kp++)
- {
- if (*kp == ' ' && kflag == 0)
- {
- *(dp++) = *kp;
- kflag = 1;
- }
- else if (*kp == ' ')
- {
- key_len--;
- kwarn=1;
- }
- else
- {
- *(dp++) = *kp;
- kflag = 0;
- }
- }
- *dp = '\0';
- if(kwarn)
- png_warning(png_ptr, "extra interior spaces removed from keyword");
-
- if (key_len == 0)
- {
- png_free(png_ptr, *new_key);
- *new_key=NULL;
- png_warning(png_ptr, "Zero length keyword");
- }
-
- if (key_len > 79)
- {
- png_warning(png_ptr, "keyword length must be 1 - 79 characters");
- new_key[79] = '\0';
- key_len = 79;
- }
-
- return (key_len);
- }
- #endif
-
- #if defined(PNG_WRITE_tEXt_SUPPORTED)
- /* write a tEXt chunk */
- void /* PRIVATE */
- png_write_tEXt(png_structp png_ptr, png_charp key, png_charp text,
- png_size_t text_len)
- {
- #ifdef PNG_USE_LOCAL_ARRAYS
- PNG_tEXt;
- #endif
- png_size_t key_len;
- png_charp new_key;
-
- png_debug(1, "in png_write_tEXt\n");
- if (key == NULL || (key_len = png_check_keyword(png_ptr, key, &new_key))==0)
- {
- png_warning(png_ptr, "Empty keyword in tEXt chunk");
- return;
- }
-
- if (text == NULL || *text == '\0')
- text_len = 0;
- else
- text_len = png_strlen(text);
-
- /* make sure we include the 0 after the key */
- png_write_chunk_start(png_ptr, png_tEXt, (png_uint_32)key_len+text_len+1);
- /*
- * We leave it to the application to meet PNG-1.0 requirements on the
- * contents of the text. PNG-1.0 through PNG-1.2 discourage the use of
- * any non-Latin-1 characters except for NEWLINE. ISO PNG will forbid them.
- * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG.
- */
- png_write_chunk_data(png_ptr, (png_bytep)new_key, key_len + 1);
- if (text_len)
- png_write_chunk_data(png_ptr, (png_bytep)text, text_len);
-
- png_write_chunk_end(png_ptr);
- png_free(png_ptr, new_key);
- }
- #endif
-
- #if defined(PNG_WRITE_zTXt_SUPPORTED)
- /* write a compressed text chunk */
- void /* PRIVATE */
- png_write_zTXt(png_structp png_ptr, png_charp key, png_charp text,
- png_size_t text_len, int compression)
- {
- #ifdef PNG_USE_LOCAL_ARRAYS
- PNG_zTXt;
- #endif
- png_size_t key_len;
- char buf[1];
- png_charp new_key;
- compression_state comp;
-
- png_debug(1, "in png_write_zTXt\n");
-
- comp.num_output_ptr = 0;
- comp.max_output_ptr = 0;
- comp.output_ptr = NULL;
- comp.input = NULL;
- comp.input_len = 0;
-
- if (key == NULL || (key_len = png_check_keyword(png_ptr, key, &new_key))==0)
- {
- png_warning(png_ptr, "Empty keyword in zTXt chunk");
- return;
- }
-
- if (text == NULL || *text == '\0' || compression==PNG_TEXT_COMPRESSION_NONE)
- {
- png_write_tEXt(png_ptr, new_key, text, (png_size_t)0);
- png_free(png_ptr, new_key);
- return;
- }
-
- text_len = png_strlen(text);
-
- /* compute the compressed data; do it now for the length */
- text_len = png_text_compress(png_ptr, text, text_len, compression,
- &comp);
-
- /* write start of chunk */
- png_write_chunk_start(png_ptr, png_zTXt, (png_uint_32)
- (key_len+text_len+2));
- /* write key */
- png_write_chunk_data(png_ptr, (png_bytep)new_key, key_len + 1);
- png_free(png_ptr, new_key);
-
- buf[0] = (png_byte)compression;
- /* write compression */
- png_write_chunk_data(png_ptr, (png_bytep)buf, (png_size_t)1);
- /* write the compressed data */
- png_write_compressed_data_out(png_ptr, &comp);
-
- /* close the chunk */
- png_write_chunk_end(png_ptr);
- }
- #endif
-
- #if defined(PNG_WRITE_iTXt_SUPPORTED)
- /* write an iTXt chunk */
- void /* PRIVATE */
- png_write_iTXt(png_structp png_ptr, int compression, png_charp key,
- png_charp lang, png_charp lang_key, png_charp text)
- {
- #ifdef PNG_USE_LOCAL_ARRAYS
- PNG_iTXt;
- #endif
- png_size_t lang_len, key_len, lang_key_len, text_len;
- png_charp new_lang, new_key;
- png_byte cbuf[2];
- compression_state comp;
-
- png_debug(1, "in png_write_iTXt\n");
-
- comp.num_output_ptr = 0;
- comp.max_output_ptr = 0;
- comp.output_ptr = NULL;
- comp.input = NULL;
-
- if (key == NULL || (key_len = png_check_keyword(png_ptr, key, &new_key))==0)
- {
- png_warning(png_ptr, "Empty keyword in iTXt chunk");
- return;
- }
- if (lang == NULL || (lang_len = png_check_keyword(png_ptr, lang, &new_lang))==0)
- {
- png_warning(png_ptr, "Empty language field in iTXt chunk");
- new_lang = NULL;
- lang_len = 0;
- }
-
- if (lang_key == NULL)
- lang_key_len = 0;
- else
- lang_key_len = png_strlen(lang_key);
-
- if (text == NULL)
- text_len = 0;
- else
- text_len = png_strlen(text);
-
- /* compute the compressed data; do it now for the length */
- text_len = png_text_compress(png_ptr, text, text_len, compression-2,
- &comp);
-
- /* make sure we include the compression flag, the compression byte,
- * and the NULs after the key, lang, and lang_key parts */
-
- png_write_chunk_start(png_ptr, png_iTXt,
- (png_uint_32)(
- 5 /* comp byte, comp flag, terminators for key, lang and lang_key */
- + key_len
- + lang_len
- + lang_key_len
- + text_len));
-
- /*
- * We leave it to the application to meet PNG-1.0 requirements on the
- * contents of the text. PNG-1.0 through PNG-1.2 discourage the use of
- * any non-Latin-1 characters except for NEWLINE. ISO PNG will forbid them.
- * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG.
- */
- png_write_chunk_data(png_ptr, (png_bytep)new_key, key_len + 1);
-
- /* set the compression flag */
- if (compression == PNG_ITXT_COMPRESSION_NONE || \
- compression == PNG_TEXT_COMPRESSION_NONE)
- cbuf[0] = 0;
- else /* compression == PNG_ITXT_COMPRESSION_zTXt */
- cbuf[0] = 1;
- /* set the compression method */
- cbuf[1] = 0;
- png_write_chunk_data(png_ptr, cbuf, 2);
-
- cbuf[0] = 0;
- png_write_chunk_data(png_ptr, (new_lang ? (png_bytep)new_lang : cbuf), lang_len + 1);
- png_write_chunk_data(png_ptr, (lang_key ? (png_bytep)lang_key : cbuf), lang_key_len + 1);
- png_write_compressed_data_out(png_ptr, &comp);
-
- png_write_chunk_end(png_ptr);
- png_free(png_ptr, new_key);
- if (new_lang)
- png_free(png_ptr, new_lang);
- }
- #endif
-
- #if defined(PNG_WRITE_oFFs_SUPPORTED)
- /* write the oFFs chunk */
- void /* PRIVATE */
- png_write_oFFs(png_structp png_ptr, png_int_32 x_offset, png_int_32 y_offset,
- int unit_type)
- {
- #ifdef PNG_USE_LOCAL_ARRAYS
- PNG_oFFs;
- #endif
- png_byte buf[9];
-
- png_debug(1, "in png_write_oFFs\n");
- if (unit_type >= PNG_OFFSET_LAST)
- png_warning(png_ptr, "Unrecognized unit type for oFFs chunk");
-
- png_save_int_32(buf, x_offset);
- png_save_int_32(buf + 4, y_offset);
- buf[8] = (png_byte)unit_type;
-
- png_write_chunk(png_ptr, png_oFFs, buf, (png_size_t)9);
- }
- #endif
- #if defined(PNG_WRITE_pCAL_SUPPORTED)
- /* write the pCAL chunk (described in the PNG extensions document) */
- void /* PRIVATE */
- png_write_pCAL(png_structp png_ptr, png_charp purpose, png_int_32 X0,
- png_int_32 X1, int type, int nparams, png_charp units, png_charpp params)
- {
- #ifdef PNG_USE_LOCAL_ARRAYS
- PNG_pCAL;
- #endif
- png_size_t purpose_len, units_len, total_len;
- png_uint_32p params_len;
- png_byte buf[10];
- png_charp new_purpose;
- int i;
-
- png_debug1(1, "in png_write_pCAL (%d parameters)\n", nparams);
- if (type >= PNG_EQUATION_LAST)
- png_warning(png_ptr, "Unrecognized equation type for pCAL chunk");
-
- purpose_len = png_check_keyword(png_ptr, purpose, &new_purpose) + 1;
- png_debug1(3, "pCAL purpose length = %d\n", (int)purpose_len);
- units_len = png_strlen(units) + (nparams == 0 ? 0 : 1);
- png_debug1(3, "pCAL units length = %d\n", (int)units_len);
- total_len = purpose_len + units_len + 10;
-
- params_len = (png_uint_32p)png_malloc(png_ptr, (png_uint_32)(nparams
- *png_sizeof(png_uint_32)));
-
- /* Find the length of each parameter, making sure we don't count the
- null terminator for the last parameter. */
- for (i = 0; i < nparams; i++)
- {
- params_len[i] = png_strlen(params[i]) + (i == nparams - 1 ? 0 : 1);
- png_debug2(3, "pCAL parameter %d length = %lu\n", i, params_len[i]);
- total_len += (png_size_t)params_len[i];
- }
-
- png_debug1(3, "pCAL total length = %d\n", (int)total_len);
- png_write_chunk_start(png_ptr, png_pCAL, (png_uint_32)total_len);
- png_write_chunk_data(png_ptr, (png_bytep)new_purpose, purpose_len);
- png_save_int_32(buf, X0);
- png_save_int_32(buf + 4, X1);
- buf[8] = (png_byte)type;
- buf[9] = (png_byte)nparams;
- png_write_chunk_data(png_ptr, buf, (png_size_t)10);
- png_write_chunk_data(png_ptr, (png_bytep)units, (png_size_t)units_len);
-
- png_free(png_ptr, new_purpose);
-
- for (i = 0; i < nparams; i++)
- {
- png_write_chunk_data(png_ptr, (png_bytep)params[i],
- (png_size_t)params_len[i]);
- }
-
- png_free(png_ptr, params_len);
- png_write_chunk_end(png_ptr);
- }
- #endif
-
- #if defined(PNG_WRITE_sCAL_SUPPORTED)
- /* write the sCAL chunk */
- #if defined(PNG_FLOATING_POINT_SUPPORTED) && !defined(PNG_NO_STDIO)
- void /* PRIVATE */
- png_write_sCAL(png_structp png_ptr, int unit, double width, double height)
- {
- #ifdef PNG_USE_LOCAL_ARRAYS
- PNG_sCAL;
- #endif
- char buf[64];
- png_size_t total_len;
-
- png_debug(1, "in png_write_sCAL\n");
-
- buf[0] = (char)unit;
- #if defined(_WIN32_WCE)
- /* sprintf() function is not supported on WindowsCE */
- {
- wchar_t wc_buf[32];
- size_t wc_len;
- swprintf(wc_buf, TEXT("%12.12e"), width);
- wc_len = wcslen(wc_buf);
- WideCharToMultiByte(CP_ACP, 0, wc_buf, -1, buf + 1, wc_len, NULL, NULL);
- total_len = wc_len + 2;
- swprintf(wc_buf, TEXT("%12.12e"), height);
- wc_len = wcslen(wc_buf);
- WideCharToMultiByte(CP_ACP, 0, wc_buf, -1, buf + total_len, wc_len,
- NULL, NULL);
- total_len += wc_len;
- }
- #else
- png_snprintf(buf + 1, 63, "%12.12e", width);
- total_len = 1 + png_strlen(buf + 1) + 1;
- png_snprintf(buf + total_len, 64-total_len, "%12.12e", height);
- total_len += png_strlen(buf + total_len);
- #endif
-
- png_debug1(3, "sCAL total length = %u\n", (unsigned int)total_len);
- png_write_chunk(png_ptr, png_sCAL, (png_bytep)buf, total_len);
- }
- #else
- #ifdef PNG_FIXED_POINT_SUPPORTED
- void /* PRIVATE */
- png_write_sCAL_s(png_structp png_ptr, int unit, png_charp width,
- png_charp height)
- {
- #ifdef PNG_USE_LOCAL_ARRAYS
- PNG_sCAL;
- #endif
- png_byte buf[64];
- png_size_t wlen, hlen, total_len;
-
- png_debug(1, "in png_write_sCAL_s\n");
-
- wlen = png_strlen(width);
- hlen = png_strlen(height);
- total_len = wlen + hlen + 2;
- if (total_len > 64)
- {
- png_warning(png_ptr, "Can't write sCAL (buffer too small)");
- return;
- }
-
- buf[0] = (png_byte)unit;
- png_memcpy(buf + 1, width, wlen + 1); /* append the '\0' here */
- png_memcpy(buf + wlen + 2, height, hlen); /* do NOT append the '\0' here */
-
- png_debug1(3, "sCAL total length = %u\n", (unsigned int)total_len);
- png_write_chunk(png_ptr, png_sCAL, buf, total_len);
- }
- #endif
- #endif
- #endif
-
- #if defined(PNG_WRITE_pHYs_SUPPORTED)
- /* write the pHYs chunk */
- void /* PRIVATE */
- png_write_pHYs(png_structp png_ptr, png_uint_32 x_pixels_per_unit,
- png_uint_32 y_pixels_per_unit,
- int unit_type)
- {
- #ifdef PNG_USE_LOCAL_ARRAYS
- PNG_pHYs;
- #endif
- png_byte buf[9];
-
- png_debug(1, "in png_write_pHYs\n");
- if (unit_type >= PNG_RESOLUTION_LAST)
- png_warning(png_ptr, "Unrecognized unit type for pHYs chunk");
-
- png_save_uint_32(buf, x_pixels_per_unit);
- png_save_uint_32(buf + 4, y_pixels_per_unit);
- buf[8] = (png_byte)unit_type;
-
- png_write_chunk(png_ptr, png_pHYs, buf, (png_size_t)9);
- }
- #endif
-
- #if defined(PNG_WRITE_tIME_SUPPORTED)
- /* Write the tIME chunk. Use either png_convert_from_struct_tm()
- * or png_convert_from_time_t(), or fill in the structure yourself.
- */
- void /* PRIVATE */
- png_write_tIME(png_structp png_ptr, png_timep mod_time)
- {
- #ifdef PNG_USE_LOCAL_ARRAYS
- PNG_tIME;
- #endif
- png_byte buf[7];
-
- png_debug(1, "in png_write_tIME\n");
- if (mod_time->month > 12 || mod_time->month < 1 ||
- mod_time->day > 31 || mod_time->day < 1 ||
- mod_time->hour > 23 || mod_time->second > 60)
- {
- png_warning(png_ptr, "Invalid time specified for tIME chunk");
- return;
- }
-
- png_save_uint_16(buf, mod_time->year);
- buf[2] = mod_time->month;
- buf[3] = mod_time->day;
- buf[4] = mod_time->hour;
- buf[5] = mod_time->minute;
- buf[6] = mod_time->second;
-
- png_write_chunk(png_ptr, png_tIME, buf, (png_size_t)7);
- }
- #endif
-
- /* initializes the row writing capability of libpng */
- void /* PRIVATE */
- png_write_start_row(png_structp png_ptr)
- {
- #ifdef PNG_WRITE_INTERLACING_SUPPORTED
- #ifdef PNG_USE_LOCAL_ARRAYS
- /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
-
- /* start of interlace block */
- int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
-
- /* offset to next interlace block */
- int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
-
- /* start of interlace block in the y direction */
- int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
-
- /* offset to next interlace block in the y direction */
- int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
- #endif
- #endif
-
- png_size_t buf_size;
-
- png_debug(1, "in png_write_start_row\n");
- buf_size = (png_size_t)(PNG_ROWBYTES(
- png_ptr->usr_channels*png_ptr->usr_bit_depth,png_ptr->width)+1);
-
- /* set up row buffer */
- png_ptr->row_buf = (png_bytep)png_malloc(png_ptr, (png_uint_32)buf_size);
- png_ptr->row_buf[0] = PNG_FILTER_VALUE_NONE;
-
- #ifndef PNG_NO_WRITE_FILTERING
- /* set up filtering buffer, if using this filter */
- if (png_ptr->do_filter & PNG_FILTER_SUB)
- {
- png_ptr->sub_row = (png_bytep)png_malloc(png_ptr,
- (png_ptr->rowbytes + 1));
- png_ptr->sub_row[0] = PNG_FILTER_VALUE_SUB;
- }
-
- /* We only need to keep the previous row if we are using one of these. */
- if (png_ptr->do_filter & (PNG_FILTER_AVG | PNG_FILTER_UP | PNG_FILTER_PAETH))
- {
- /* set up previous row buffer */
- png_ptr->prev_row = (png_bytep)png_malloc(png_ptr, (png_uint_32)buf_size);
- png_memset(png_ptr->prev_row, 0, buf_size);
-
- if (png_ptr->do_filter & PNG_FILTER_UP)
- {
- png_ptr->up_row = (png_bytep)png_malloc(png_ptr,
- (png_ptr->rowbytes + 1));
- png_ptr->up_row[0] = PNG_FILTER_VALUE_UP;
- }
-
- if (png_ptr->do_filter & PNG_FILTER_AVG)
- {
- png_ptr->avg_row = (png_bytep)png_malloc(png_ptr,
- (png_ptr->rowbytes + 1));
- png_ptr->avg_row[0] = PNG_FILTER_VALUE_AVG;
- }
-
- if (png_ptr->do_filter & PNG_FILTER_PAETH)
- {
- png_ptr->paeth_row = (png_bytep)png_malloc(png_ptr,
- (png_ptr->rowbytes + 1));
- png_ptr->paeth_row[0] = PNG_FILTER_VALUE_PAETH;
- }
- #endif /* PNG_NO_WRITE_FILTERING */
- }
-
- #ifdef PNG_WRITE_INTERLACING_SUPPORTED
- /* if interlaced, we need to set up width and height of pass */
- if (png_ptr->interlaced)
- {
- if (!(png_ptr->transformations & PNG_INTERLACE))
- {
- png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
- png_pass_ystart[0]) / png_pass_yinc[0];
- png_ptr->usr_width = (png_ptr->width + png_pass_inc[0] - 1 -
- png_pass_start[0]) / png_pass_inc[0];
- }
- else
- {
- png_ptr->num_rows = png_ptr->height;
- png_ptr->usr_width = png_ptr->width;
- }
- }
- else
- #endif
- {
- png_ptr->num_rows = png_ptr->height;
- png_ptr->usr_width = png_ptr->width;
- }
- png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
- png_ptr->zstream.next_out = png_ptr->zbuf;
- }
-
- /* Internal use only. Called when finished processing a row of data. */
- void /* PRIVATE */
- png_write_finish_row(png_structp png_ptr)
- {
- #ifdef PNG_WRITE_INTERLACING_SUPPORTED
- #ifdef PNG_USE_LOCAL_ARRAYS
- /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
-
- /* start of interlace block */
- int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
-
- /* offset to next interlace block */
- int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
-
- /* start of interlace block in the y direction */
- int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
-
- /* offset to next interlace block in the y direction */
- int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
- #endif
- #endif
-
- int ret;
-
- png_debug(1, "in png_write_finish_row\n");
- /* next row */
- png_ptr->row_number++;
-
- /* see if we are done */
- if (png_ptr->row_number < png_ptr->num_rows)
- return;
-
- #ifdef PNG_WRITE_INTERLACING_SUPPORTED
- /* if interlaced, go to next pass */
- if (png_ptr->interlaced)
- {
- png_ptr->row_number = 0;
- if (png_ptr->transformations & PNG_INTERLACE)
- {
- png_ptr->pass++;
- }
- else
- {
- /* loop until we find a non-zero width or height pass */
- do
- {
- png_ptr->pass++;
- if (png_ptr->pass >= 7)
- break;
- png_ptr->usr_width = (png_ptr->width +
- png_pass_inc[png_ptr->pass] - 1 -
- png_pass_start[png_ptr->pass]) /
- png_pass_inc[png_ptr->pass];
- png_ptr->num_rows = (png_ptr->height +
- png_pass_yinc[png_ptr->pass] - 1 -
- png_pass_ystart[png_ptr->pass]) /
- png_pass_yinc[png_ptr->pass];
- if (png_ptr->transformations & PNG_INTERLACE)
- break;
- } while (png_ptr->usr_width == 0 || png_ptr->num_rows == 0);
-
- }
-
- /* reset the row above the image for the next pass */
- if (png_ptr->pass < 7)
- {
- if (png_ptr->prev_row != NULL)
- png_memset(png_ptr->prev_row, 0,
- (png_size_t)(PNG_ROWBYTES(png_ptr->usr_channels*
- png_ptr->usr_bit_depth,png_ptr->width))+1);
- return;
- }
- }
- #endif
-
- /* if we get here, we've just written the last row, so we need
- to flush the compressor */
- do
- {
- /* tell the compressor we are done */
- ret = deflate(&png_ptr->zstream, Z_FINISH);
- /* check for an error */
- if (ret == Z_OK)
- {
- /* check to see if we need more room */
- if (!(png_ptr->zstream.avail_out))
- {
- png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
- png_ptr->zstream.next_out = png_ptr->zbuf;
- png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
- }
- }
- else if (ret != Z_STREAM_END)
- {
- if (png_ptr->zstream.msg != NULL)
- png_error(png_ptr, png_ptr->zstream.msg);
- else
- png_error(png_ptr, "zlib error");
- }
- } while (ret != Z_STREAM_END);
-
- /* write any extra space */
- if (png_ptr->zstream.avail_out < png_ptr->zbuf_size)
- {
- png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size -
- png_ptr->zstream.avail_out);
- }
-
- deflateReset(&png_ptr->zstream);
- png_ptr->zstream.data_type = Z_BINARY;
- }
-
- #if defined(PNG_WRITE_INTERLACING_SUPPORTED)
- /* Pick out the correct pixels for the interlace pass.
- * The basic idea here is to go through the row with a source
- * pointer and a destination pointer (sp and dp), and copy the
- * correct pixels for the pass. As the row gets compacted,
- * sp will always be >= dp, so we should never overwrite anything.
- * See the default: case for the easiest code to understand.
- */
- void /* PRIVATE */
- png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass)
- {
- #ifdef PNG_USE_LOCAL_ARRAYS
- /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
-
- /* start of interlace block */
- int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
-
- /* offset to next interlace block */
- int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
- #endif
-
- png_debug(1, "in png_do_write_interlace\n");
- /* we don't have to do anything on the last pass (6) */
- #if defined(PNG_USELESS_TESTS_SUPPORTED)
- if (row != NULL && row_info != NULL && pass < 6)
- #else
- if (pass < 6)
- #endif
- {
- /* each pixel depth is handled separately */
- switch (row_info->pixel_depth)
- {
- case 1:
- {
- png_bytep sp;
- png_bytep dp;
- int shift;
- int d;
- int value;
- png_uint_32 i;
- png_uint_32 row_width = row_info->width;
-
- dp = row;
- d = 0;
- shift = 7;
- for (i = png_pass_start[pass]; i < row_width;
- i += png_pass_inc[pass])
- {
- sp = row + (png_size_t)(i >> 3);
- value = (int)(*sp >> (7 - (int)(i & 0x07))) & 0x01;
- d |= (value << shift);
-
- if (shift == 0)
- {
- shift = 7;
- *dp++ = (png_byte)d;
- d = 0;
- }
- else
- shift--;
-
- }
- if (shift != 7)
- *dp = (png_byte)d;
- break;
- }
- case 2:
- {
- png_bytep sp;
- png_bytep dp;
- int shift;
- int d;
- int value;
- png_uint_32 i;
- png_uint_32 row_width = row_info->width;
-
- dp = row;
- shift = 6;
- d = 0;
- for (i = png_pass_start[pass]; i < row_width;
- i += png_pass_inc[pass])
- {
- sp = row + (png_size_t)(i >> 2);
- value = (*sp >> ((3 - (int)(i & 0x03)) << 1)) & 0x03;
- d |= (value << shift);
-
- if (shift == 0)
- {
- shift = 6;
- *dp++ = (png_byte)d;
- d = 0;
- }
- else
- shift -= 2;
- }
- if (shift != 6)
- *dp = (png_byte)d;
- break;
- }
- case 4:
- {
- png_bytep sp;
- png_bytep dp;
- int shift;
- int d;
- int value;
- png_uint_32 i;
- png_uint_32 row_width = row_info->width;
-
- dp = row;
- shift = 4;
- d = 0;
- for (i = png_pass_start[pass]; i < row_width;
- i += png_pass_inc[pass])
- {
- sp = row + (png_size_t)(i >> 1);
- value = (*sp >> ((1 - (int)(i & 0x01)) << 2)) & 0x0f;
- d |= (value << shift);
-
- if (shift == 0)
- {
- shift = 4;
- *dp++ = (png_byte)d;
- d = 0;
- }
- else
- shift -= 4;
- }
- if (shift != 4)
- *dp = (png_byte)d;
- break;
- }
- default:
- {
- png_bytep sp;
- png_bytep dp;
- png_uint_32 i;
- png_uint_32 row_width = row_info->width;
- png_size_t pixel_bytes;
-
- /* start at the beginning */
- dp = row;
- /* find out how many bytes each pixel takes up */
- pixel_bytes = (row_info->pixel_depth >> 3);
- /* loop through the row, only looking at the pixels that
- matter */
- for (i = png_pass_start[pass]; i < row_width;
- i += png_pass_inc[pass])
- {
- /* find out where the original pixel is */
- sp = row + (png_size_t)i * pixel_bytes;
- /* move the pixel */
- if (dp != sp)
- png_memcpy(dp, sp, pixel_bytes);
- /* next pixel */
- dp += pixel_bytes;
- }
- break;
- }
- }
- /* set new row width */
- row_info->width = (row_info->width +
- png_pass_inc[pass] - 1 -
- png_pass_start[pass]) /
- png_pass_inc[pass];
- row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
- row_info->width);
- }
- }
- #endif
-
- /* This filters the row, chooses which filter to use, if it has not already
- * been specified by the application, and then writes the row out with the
- * chosen filter.
- */
- #define PNG_MAXSUM (((png_uint_32)(-1)) >> 1)
- #define PNG_HISHIFT 10
- #define PNG_LOMASK ((png_uint_32)0xffffL)
- #define PNG_HIMASK ((png_uint_32)(~PNG_LOMASK >> PNG_HISHIFT))
- void /* PRIVATE */
- png_write_find_filter(png_structp png_ptr, png_row_infop row_info)
- {
- png_bytep best_row;
- #ifndef PNG_NO_WRITE_FILTER
- png_bytep prev_row, row_buf;
- png_uint_32 mins, bpp;
- png_byte filter_to_do = png_ptr->do_filter;
- png_uint_32 row_bytes = row_info->rowbytes;
- #if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
- int num_p_filters = (int)png_ptr->num_prev_filters;
- #endif
-
- png_debug(1, "in png_write_find_filter\n");
- /* find out how many bytes offset each pixel is */
- bpp = (row_info->pixel_depth + 7) >> 3;
-
- prev_row = png_ptr->prev_row;
- #endif
- best_row = png_ptr->row_buf;
- #ifndef PNG_NO_WRITE_FILTER
- row_buf = best_row;
- mins = PNG_MAXSUM;
-
- /* The prediction method we use is to find which method provides the
- * smallest value when summing the absolute values of the distances
- * from zero, using anything >= 128 as negative numbers. This is known
- * as the "minimum sum of absolute differences" heuristic. Other
- * heuristics are the "weighted minimum sum of absolute differences"
- * (experimental and can in theory improve compression), and the "zlib
- * predictive" method (not implemented yet), which does test compressions
- * of lines using different filter methods, and then chooses the
- * (series of) filter(s) that give minimum compressed data size (VERY
- * computationally expensive).
- *
- * GRR 980525: consider also
- * (1) minimum sum of absolute differences from running average (i.e.,
- * keep running sum of non-absolute differences & count of bytes)
- * [track dispersion, too? restart average if dispersion too large?]
- * (1b) minimum sum of absolute differences from sliding average, probably
- * with window size <= deflate window (usually 32K)
- * (2) minimum sum of squared differences from zero or running average
- * (i.e., ~ root-mean-square approach)
- */
-
- /* We don't need to test the 'no filter' case if this is the only filter
- * that has been chosen, as it doesn't actually do anything to the data.
- */
- if ((filter_to_do & PNG_FILTER_NONE) &&
- filter_to_do != PNG_FILTER_NONE)
- {
- png_bytep rp;
- png_uint_32 sum = 0;
- png_uint_32 i;
- int v;
-
- for (i = 0, rp = row_buf + 1; i < row_bytes; i++, rp++)
- {
- v = *rp;
- sum += (v < 128) ? v : 256 - v;
- }
-
- #if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
- if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
- {
- png_uint_32 sumhi, sumlo;
- int j;
- sumlo = sum & PNG_LOMASK;
- sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK; /* Gives us some footroom */
-
- /* Reduce the sum if we match any of the previous rows */
- for (j = 0; j < num_p_filters; j++)
- {
- if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_NONE)
- {
- sumlo = (sumlo * png_ptr->filter_weights[j]) >>
- PNG_WEIGHT_SHIFT;
- sumhi = (sumhi * png_ptr->filter_weights[j]) >>
- PNG_WEIGHT_SHIFT;
- }
- }
-
- /* Factor in the cost of this filter (this is here for completeness,
- * but it makes no sense to have a "cost" for the NONE filter, as
- * it has the minimum possible computational cost - none).
- */
- sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_NONE]) >>
- PNG_COST_SHIFT;
- sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_NONE]) >>
- PNG_COST_SHIFT;
-
- if (sumhi > PNG_HIMASK)
- sum = PNG_MAXSUM;
- else
- sum = (sumhi << PNG_HISHIFT) + sumlo;
- }
- #endif
- mins = sum;
- }
-
- /* sub filter */
- if (filter_to_do == PNG_FILTER_SUB)
- /* it's the only filter so no testing is needed */
- {
- png_bytep rp, lp, dp;
- png_uint_32 i;
- for (i = 0, rp = row_buf + 1, dp = png_ptr->sub_row + 1; i < bpp;
- i++, rp++, dp++)
- {
- *dp = *rp;
- }
- for (lp = row_buf + 1; i < row_bytes;
- i++, rp++, lp++, dp++)
- {
- *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff);
- }
- best_row = png_ptr->sub_row;
- }
-
- else if (filter_to_do & PNG_FILTER_SUB)
- {
- png_bytep rp, dp, lp;
- png_uint_32 sum = 0, lmins = mins;
- png_uint_32 i;
- int v;
-
- #if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
- /* We temporarily increase the "minimum sum" by the factor we
- * would reduce the sum of this filter, so that we can do the
- * early exit comparison without scaling the sum each time.
- */
- if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
- {
- int j;
- png_uint_32 lmhi, lmlo;
- lmlo = lmins & PNG_LOMASK;
- lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
-
- for (j = 0; j < num_p_filters; j++)
- {
- if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_SUB)
- {
- lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
- PNG_WEIGHT_SHIFT;
- lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
- PNG_WEIGHT_SHIFT;
- }
- }
-
- lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
- PNG_COST_SHIFT;
- lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
- PNG_COST_SHIFT;
-
- if (lmhi > PNG_HIMASK)
- lmins = PNG_MAXSUM;
- else
- lmins = (lmhi << PNG_HISHIFT) + lmlo;
- }
- #endif
-
- for (i = 0, rp = row_buf + 1, dp = png_ptr->sub_row + 1; i < bpp;
- i++, rp++, dp++)
- {
- v = *dp = *rp;
-
- sum += (v < 128) ? v : 256 - v;
- }
- for (lp = row_buf + 1; i < row_bytes;
- i++, rp++, lp++, dp++)
- {
- v = *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff);
-
- sum += (v < 128) ? v : 256 - v;
-
- if (sum > lmins) /* We are already worse, don't continue. */
- break;
- }
-
- #if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
- if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
- {
- int j;
- png_uint_32 sumhi, sumlo;
- sumlo = sum & PNG_LOMASK;
- sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;
-
- for (j = 0; j < num_p_filters; j++)
- {
- if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_SUB)
- {
- sumlo = (sumlo * png_ptr->inv_filter_weights[j]) >>
- PNG_WEIGHT_SHIFT;
- sumhi = (sumhi * png_ptr->inv_filter_weights[j]) >>
- PNG_WEIGHT_SHIFT;
- }
- }
-
- sumlo = (sumlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
- PNG_COST_SHIFT;
- sumhi = (sumhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
- PNG_COST_SHIFT;
-
- if (sumhi > PNG_HIMASK)
- sum = PNG_MAXSUM;
- else
- sum = (sumhi << PNG_HISHIFT) + sumlo;
- }
- #endif
-
- if (sum < mins)
- {
- mins = sum;
- best_row = png_ptr->sub_row;
- }
- }
-
- /* up filter */
- if (filter_to_do == PNG_FILTER_UP)
- {
- png_bytep rp, dp, pp;
- png_uint_32 i;
-
- for (i = 0, rp = row_buf + 1, dp = png_ptr->up_row + 1,
- pp = prev_row + 1; i < row_bytes;
- i++, rp++, pp++, dp++)
- {
- *dp = (png_byte)(((int)*rp - (int)*pp) & 0xff);
- }
- best_row = png_ptr->up_row;
- }
-
- else if (filter_to_do & PNG_FILTER_UP)
- {
- png_bytep rp, dp, pp;
- png_uint_32 sum = 0, lmins = mins;
- png_uint_32 i;
- int v;
-
- #if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
- if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
- {
- int j;
- png_uint_32 lmhi, lmlo;
- lmlo = lmins & PNG_LOMASK;
- lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
-
- for (j = 0; j < num_p_filters; j++)
- {
- if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_UP)
- {
- lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
- PNG_WEIGHT_SHIFT;
- lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
- PNG_WEIGHT_SHIFT;
- }
- }
-
- lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_UP]) >>
- PNG_COST_SHIFT;
- lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_UP]) >>
- PNG_COST_SHIFT;
-
- if (lmhi > PNG_HIMASK)
- lmins = PNG_MAXSUM;
- else
- lmins = (lmhi << PNG_HISHIFT) + lmlo;
- }
- #endif
-
- for (i = 0, rp = row_buf + 1, dp = png_ptr->up_row + 1,
- pp = prev_row + 1; i < row_bytes; i++)
- {
- v = *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
-
- sum += (v < 128) ? v : 256 - v;
-
- if (sum > lmins) /* We are already worse, don't continue. */
- break;
- }
-
- #if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
- if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
- {
- int j;
- png_uint_32 sumhi, sumlo;
- sumlo = sum & PNG_LOMASK;
- sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;
-
- for (j = 0; j < num_p_filters; j++)
- {
- if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_UP)
- {
- sumlo = (sumlo * png_ptr->filter_weights[j]) >>
- PNG_WEIGHT_SHIFT;
- sumhi = (sumhi * png_ptr->filter_weights[j]) >>
- PNG_WEIGHT_SHIFT;
- }
- }
-
- sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_UP]) >>
- PNG_COST_SHIFT;
- sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_UP]) >>
- PNG_COST_SHIFT;
-
- if (sumhi > PNG_HIMASK)
- sum = PNG_MAXSUM;
- else
- sum = (sumhi << PNG_HISHIFT) + sumlo;
- }
- #endif
-
- if (sum < mins)
- {
- mins = sum;
- best_row = png_ptr->up_row;
- }
- }
-
- /* avg filter */
- if (filter_to_do == PNG_FILTER_AVG)
- {
- png_bytep rp, dp, pp, lp;
- png_uint_32 i;
- for (i = 0, rp = row_buf + 1, dp = png_ptr->avg_row + 1,
- pp = prev_row + 1; i < bpp; i++)
- {
- *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff);
- }
- for (lp = row_buf + 1; i < row_bytes; i++)
- {
- *dp++ = (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2))
- & 0xff);
- }
- best_row = png_ptr->avg_row;
- }
-
- else if (filter_to_do & PNG_FILTER_AVG)
- {
- png_bytep rp, dp, pp, lp;
- png_uint_32 sum = 0, lmins = mins;
- png_uint_32 i;
- int v;
-
- #if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
- if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
- {
- int j;
- png_uint_32 lmhi, lmlo;
- lmlo = lmins & PNG_LOMASK;
- lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
-
- for (j = 0; j < num_p_filters; j++)
- {
- if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_AVG)
- {
- lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
- PNG_WEIGHT_SHIFT;
- lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
- PNG_WEIGHT_SHIFT;
- }
- }
-
- lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_AVG]) >>
- PNG_COST_SHIFT;
- lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_AVG]) >>
- PNG_COST_SHIFT;
-
- if (lmhi > PNG_HIMASK)
- lmins = PNG_MAXSUM;
- else
- lmins = (lmhi << PNG_HISHIFT) + lmlo;
- }
- #endif
-
- for (i = 0, rp = row_buf + 1, dp = png_ptr->avg_row + 1,
- pp = prev_row + 1; i < bpp; i++)
- {
- v = *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff);
-
- sum += (v < 128) ? v : 256 - v;
- }
- for (lp = row_buf + 1; i < row_bytes; i++)
- {
- v = *dp++ =
- (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2)) & 0xff);
-
- sum += (v < 128) ? v : 256 - v;
-
- if (sum > lmins) /* We are already worse, don't continue. */
- break;
- }
-
- #if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
- if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
- {
- int j;
- png_uint_32 sumhi, sumlo;
- sumlo = sum & PNG_LOMASK;
- sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;
-
- for (j = 0; j < num_p_filters; j++)
- {
- if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_NONE)
- {
- sumlo = (sumlo * png_ptr->filter_weights[j]) >>
- PNG_WEIGHT_SHIFT;
- sumhi = (sumhi * png_ptr->filter_weights[j]) >>
- PNG_WEIGHT_SHIFT;
- }
- }
-
- sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_AVG]) >>
- PNG_COST_SHIFT;
- sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_AVG]) >>
- PNG_COST_SHIFT;
-
- if (sumhi > PNG_HIMASK)
- sum = PNG_MAXSUM;
- else
- sum = (sumhi << PNG_HISHIFT) + sumlo;
- }
- #endif
-
- if (sum < mins)
- {
- mins = sum;
- best_row = png_ptr->avg_row;
- }
- }
-
- /* Paeth filter */
- if (filter_to_do == PNG_FILTER_PAETH)
- {
- png_bytep rp, dp, pp, cp, lp;
- png_uint_32 i;
- for (i = 0, rp = row_buf + 1, dp = png_ptr->paeth_row + 1,
- pp = prev_row + 1; i < bpp; i++)
- {
- *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
- }
-
- for (lp = row_buf + 1, cp = prev_row + 1; i < row_bytes; i++)
- {
- int a, b, c, pa, pb, pc, p;
-
- b = *pp++;
- c = *cp++;
- a = *lp++;
-
- p = b - c;
- pc = a - c;
-
- #ifdef PNG_USE_ABS
- pa = abs(p);
- pb = abs(pc);
- pc = abs(p + pc);
- #else
- pa = p < 0 ? -p : p;
- pb = pc < 0 ? -pc : pc;
- pc = (p + pc) < 0 ? -(p + pc) : p + pc;
- #endif
-
- p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c;
-
- *dp++ = (png_byte)(((int)*rp++ - p) & 0xff);
- }
- best_row = png_ptr->paeth_row;
- }
-
- else if (filter_to_do & PNG_FILTER_PAETH)
- {
- png_bytep rp, dp, pp, cp, lp;
- png_uint_32 sum = 0, lmins = mins;
- png_uint_32 i;
- int v;
-
- #if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
- if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
- {
- int j;
- png_uint_32 lmhi, lmlo;
- lmlo = lmins & PNG_LOMASK;
- lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
-
- for (j = 0; j < num_p_filters; j++)
- {
- if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_PAETH)
- {
- lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
- PNG_WEIGHT_SHIFT;
- lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
- PNG_WEIGHT_SHIFT;
- }
- }
-
- lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_PAETH]) >>
- PNG_COST_SHIFT;
- lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_PAETH]) >>
- PNG_COST_SHIFT;
-
- if (lmhi > PNG_HIMASK)
- lmins = PNG_MAXSUM;
- else
- lmins = (lmhi << PNG_HISHIFT) + lmlo;
- }
- #endif
-
- for (i = 0, rp = row_buf + 1, dp = png_ptr->paeth_row + 1,
- pp = prev_row + 1; i < bpp; i++)
- {
- v = *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
-
- sum += (v < 128) ? v : 256 - v;
- }
-
- for (lp = row_buf + 1, cp = prev_row + 1; i < row_bytes; i++)
- {
- int a, b, c, pa, pb, pc, p;
-
- b = *pp++;
- c = *cp++;
- a = *lp++;
-
- #ifndef PNG_SLOW_PAETH
- p = b - c;
- pc = a - c;
- #ifdef PNG_USE_ABS
- pa = abs(p);
- pb = abs(pc);
- pc = abs(p + pc);
- #else
- pa = p < 0 ? -p : p;
- pb = pc < 0 ? -pc : pc;
- pc = (p + pc) < 0 ? -(p + pc) : p + pc;
- #endif
- p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c;
- #else /* PNG_SLOW_PAETH */
- p = a + b - c;
- pa = abs(p - a);
- pb = abs(p - b);
- pc = abs(p - c);
- if (pa <= pb && pa <= pc)
- p = a;
- else if (pb <= pc)
- p = b;
- else
- p = c;
- #endif /* PNG_SLOW_PAETH */
-
- v = *dp++ = (png_byte)(((int)*rp++ - p) & 0xff);
-
- sum += (v < 128) ? v : 256 - v;
-
- if (sum > lmins) /* We are already worse, don't continue. */
- break;
- }
-
- #if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
- if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
- {
- int j;
- png_uint_32 sumhi, sumlo;
- sumlo = sum & PNG_LOMASK;
- sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;
-
- for (j = 0; j < num_p_filters; j++)
- {
- if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_PAETH)
- {
- sumlo = (sumlo * png_ptr->filter_weights[j]) >>
- PNG_WEIGHT_SHIFT;
- sumhi = (sumhi * png_ptr->filter_weights[j]) >>
- PNG_WEIGHT_SHIFT;
- }
- }
-
- sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_PAETH]) >>
- PNG_COST_SHIFT;
- sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_PAETH]) >>
- PNG_COST_SHIFT;
-
- if (sumhi > PNG_HIMASK)
- sum = PNG_MAXSUM;
- else
- sum = (sumhi << PNG_HISHIFT) + sumlo;
- }
- #endif
-
- if (sum < mins)
- {
- best_row = png_ptr->paeth_row;
- }
- }
- #endif /* PNG_NO_WRITE_FILTER */
- /* Do the actual writing of the filtered row data from the chosen filter. */
-
- png_write_filtered_row(png_ptr, best_row);
-
- #ifndef PNG_NO_WRITE_FILTER
- #if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
- /* Save the type of filter we picked this time for future calculations */
- if (png_ptr->num_prev_filters > 0)
- {
- int j;
- for (j = 1; j < num_p_filters; j++)
- {
- png_ptr->prev_filters[j] = png_ptr->prev_filters[j - 1];
- }
- png_ptr->prev_filters[j] = best_row[0];
- }
- #endif
- #endif /* PNG_NO_WRITE_FILTER */
- }
-
- /* Do the actual writing of a previously filtered row. */
- void /* PRIVATE */
- png_write_filtered_row(png_structp png_ptr, png_bytep filtered_row)
- {
- png_debug(1, "in png_write_filtered_row\n");
- png_debug1(2, "filter = %d\n", filtered_row[0]);
- /* set up the zlib input buffer */
-
- png_ptr->zstream.next_in = filtered_row;
- png_ptr->zstream.avail_in = (uInt)png_ptr->row_info.rowbytes + 1;
- /* repeat until we have compressed all the data */
- do
- {
- int ret; /* return of zlib */
-
- /* compress the data */
- ret = deflate(&png_ptr->zstream, Z_NO_FLUSH);
- /* check for compression errors */
- if (ret != Z_OK)
- {
- if (png_ptr->zstream.msg != NULL)
- png_error(png_ptr, png_ptr->zstream.msg);
- else
- png_error(png_ptr, "zlib error");
- }
-
- /* see if it is time to write another IDAT */
- if (!(png_ptr->zstream.avail_out))
- {
- /* write the IDAT and reset the zlib output buffer */
- png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
- png_ptr->zstream.next_out = png_ptr->zbuf;
- png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
- }
- /* repeat until all data has been compressed */
- } while (png_ptr->zstream.avail_in);
-
- /* swap the current and previous rows */
- if (png_ptr->prev_row != NULL)
- {
- png_bytep tptr;
-
- tptr = png_ptr->prev_row;
- png_ptr->prev_row = png_ptr->row_buf;
- png_ptr->row_buf = tptr;
- }
-
- /* finish row - updates counters and flushes zlib if last row */
- png_write_finish_row(png_ptr);
-
- #if defined(PNG_WRITE_FLUSH_SUPPORTED)
- png_ptr->flush_rows++;
-
- if (png_ptr->flush_dist > 0 &&
- png_ptr->flush_rows >= png_ptr->flush_dist)
- {
- png_write_flush(png_ptr);
- }
- #endif
- }
- #endif /* PNG_WRITE_SUPPORTED */
- /********* End of inlined file: pngwutil.c *********/
-
- }
- }
-
- #ifdef _MSC_VER
- #pragma warning (pop)
- #endif
-
- BEGIN_JUCE_NAMESPACE
-
- using namespace pnglibNamespace;
- using ::malloc;
- using ::free;
-
- static void pngReadCallback (png_structp pngReadStruct, png_bytep data, png_size_t length) throw()
- {
- InputStream* const in = (InputStream*) png_get_io_ptr (pngReadStruct);
- in->read (data, (int) length);
- }
-
- struct PNGErrorStruct {};
-
- static void pngErrorCallback (png_structp, png_const_charp)
- {
- throw PNGErrorStruct();
- }
-
- Image* juce_loadPNGImageFromStream (InputStream& in) throw()
- {
- Image* image = 0;
-
- png_structp pngReadStruct;
- png_infop pngInfoStruct;
-
- pngReadStruct = png_create_read_struct (PNG_LIBPNG_VER_STRING, 0, 0, 0);
-
- if (pngReadStruct != 0)
- {
- pngInfoStruct = png_create_info_struct (pngReadStruct);
-
- if (pngInfoStruct == 0)
- {
- png_destroy_read_struct (&pngReadStruct, 0, 0);
- return 0;
- }
-
- png_set_error_fn (pngReadStruct, 0, pngErrorCallback, pngErrorCallback);
-
- // read the header..
- png_set_read_fn (pngReadStruct, &in, pngReadCallback);
-
- png_uint_32 width, height;
- int bitDepth, colorType, interlaceType;
-
- try
- {
- png_read_info (pngReadStruct, pngInfoStruct);
-
- png_get_IHDR (pngReadStruct, pngInfoStruct,
- &width, &height,
- &bitDepth, &colorType,
- &interlaceType, 0, 0);
- }
- catch (...)
- {
- png_destroy_read_struct (&pngReadStruct, 0, 0);
- return 0;
- }
-
- if (bitDepth == 16)
- png_set_strip_16 (pngReadStruct);
-
- if (colorType == PNG_COLOR_TYPE_PALETTE)
- png_set_expand (pngReadStruct);
-
- if (bitDepth < 8)
- png_set_expand (pngReadStruct);
-
- if (png_get_valid (pngReadStruct, pngInfoStruct, PNG_INFO_tRNS))
- png_set_expand (pngReadStruct);
-
- if (colorType == PNG_COLOR_TYPE_GRAY || colorType == PNG_COLOR_TYPE_GRAY_ALPHA)
- png_set_gray_to_rgb (pngReadStruct);
-
- png_set_add_alpha (pngReadStruct, 0xff, PNG_FILLER_AFTER);
-
- const bool hasAlphaChan = (colorType & PNG_COLOR_MASK_ALPHA) != 0
- || pngInfoStruct->num_trans > 0;
-
- // Load the image into a temp buffer in the pnglib format..
- uint8* const tempBuffer = (uint8*) juce_malloc (height * (width << 2));
-
- png_bytepp rows = (png_bytepp) juce_malloc (sizeof (png_bytep) * height);
- int y;
- for (y = (int) height; --y >= 0;)
- rows[y] = (png_bytep) (tempBuffer + (width << 2) * y);
-
- bool crashed = false;
-
- try
- {
- png_read_image (pngReadStruct, rows);
- png_read_end (pngReadStruct, pngInfoStruct);
- }
- catch (...)
- {
- crashed = true;
- }
-
- juce_free (rows);
- png_destroy_read_struct (&pngReadStruct, &pngInfoStruct, 0);
-
- if (crashed)
- return 0;
-
- // now convert the data to a juce image format..
- image = new Image (hasAlphaChan ? Image::ARGB : Image::RGB,
- width, height, hasAlphaChan);
-
- int stride, pixelStride;
- uint8* const pixels = image->lockPixelDataReadWrite (0, 0, width, height, stride, pixelStride);
- uint8* srcRow = tempBuffer;
- uint8* destRow = pixels;
-
- for (y = 0; y < (int) height; ++y)
- {
- const uint8* src = srcRow;
- srcRow += (width << 2);
- uint8* dest = destRow;
- destRow += stride;
-
- if (hasAlphaChan)
- {
- for (int i = width; --i >= 0;)
- {
- ((PixelARGB*) dest)->setARGB (src[3], src[0], src[1], src[2]);
- ((PixelARGB*) dest)->premultiply();
- dest += pixelStride;
- src += 4;
- }
- }
- else
- {
- for (int i = width; --i >= 0;)
- {
- ((PixelRGB*) dest)->setARGB (0, src[0], src[1], src[2]);
- dest += pixelStride;
- src += 4;
- }
- }
- }
-
- image->releasePixelDataReadWrite (pixels);
- juce_free (tempBuffer);
- }
-
- return image;
- }
-
- static void pngWriteDataCallback (png_structp png_ptr, png_bytep data, png_size_t length) throw()
- {
- OutputStream* const out = (OutputStream*) png_ptr->io_ptr;
-
- const bool ok = out->write (data, length);
-
- (void) ok;
- jassert (ok);
- }
-
- bool juce_writePNGImageToStream (const Image& image, OutputStream& out) throw()
- {
- const int width = image.getWidth();
- const int height = image.getHeight();
-
- png_structp pngWriteStruct = png_create_write_struct (PNG_LIBPNG_VER_STRING, 0, 0, 0);
-
- if (pngWriteStruct == 0)
- return false;
-
- png_infop pngInfoStruct = png_create_info_struct (pngWriteStruct);
-
- if (pngInfoStruct == 0)
- {
- png_destroy_write_struct (&pngWriteStruct, (png_infopp) 0);
- return false;
- }
-
- png_set_write_fn (pngWriteStruct, &out, pngWriteDataCallback, 0);
-
- png_set_IHDR (pngWriteStruct, pngInfoStruct, width, height, 8,
- image.hasAlphaChannel() ? PNG_COLOR_TYPE_RGB_ALPHA
- : PNG_COLOR_TYPE_RGB,
- PNG_INTERLACE_NONE,
- PNG_COMPRESSION_TYPE_BASE,
- PNG_FILTER_TYPE_BASE);
-
- png_bytep rowData = (png_bytep) juce_malloc (width * 4 * sizeof (png_byte));
-
- png_color_8 sig_bit;
- sig_bit.red = 8;
- sig_bit.green = 8;
- sig_bit.blue = 8;
- sig_bit.alpha = 8;
- png_set_sBIT (pngWriteStruct, pngInfoStruct, &sig_bit);
-
- png_write_info (pngWriteStruct, pngInfoStruct);
-
- png_set_shift (pngWriteStruct, &sig_bit);
- png_set_packing (pngWriteStruct);
-
- for (int y = 0; y < height; ++y)
- {
- uint8* dst = (uint8*) rowData;
- int stride, pixelStride;
- const uint8* pixels = image.lockPixelDataReadOnly (0, y, width, 1, stride, pixelStride);
- const uint8* src = pixels;
-
- if (image.hasAlphaChannel())
- {
- for (int i = width; --i >= 0;)
- {
- PixelARGB p (*(const PixelARGB*) src);
- p.unpremultiply();
-
- *dst++ = p.getRed();
- *dst++ = p.getGreen();
- *dst++ = p.getBlue();
- *dst++ = p.getAlpha();
- src += pixelStride;
- }
- }
- else
- {
- for (int i = width; --i >= 0;)
- {
- *dst++ = ((const PixelRGB*) src)->getRed();
- *dst++ = ((const PixelRGB*) src)->getGreen();
- *dst++ = ((const PixelRGB*) src)->getBlue();
- src += pixelStride;
- }
- }
-
- png_write_rows (pngWriteStruct, &rowData, 1);
- image.releasePixelDataReadOnly (pixels);
- }
-
- juce_free (rowData);
-
- png_write_end (pngWriteStruct, pngInfoStruct);
- png_destroy_write_struct (&pngWriteStruct, &pngInfoStruct);
-
- out.flush();
-
- return true;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_PNGLoader.cpp *********/
-
- #endif
-
- //==============================================================================
- #if JUCE_WIN32
-
- /********* Start of inlined file: juce_win32_Files.cpp *********/
- #ifdef _MSC_VER
- #pragma warning (disable: 4514)
- #pragma warning (push)
- #endif
-
- #include <ctime>
-
- #ifndef _WIN32_IE
- #define _WIN32_IE 0x0400
- #endif
- #include <shlobj.h>
-
- #ifndef CSIDL_MYMUSIC
- #define CSIDL_MYMUSIC 0x000d
- #endif
-
- #ifndef CSIDL_MYVIDEO
- #define CSIDL_MYVIDEO 0x000e
- #endif
-
- BEGIN_JUCE_NAMESPACE
-
- #ifdef _MSC_VER
- #pragma warning (pop)
- #endif
-
- const tchar File::separator = T('\\');
- const tchar* File::separatorString = T("\\");
-
- bool juce_fileExists (const String& fileName,
- const bool dontCountDirectories) throw()
- {
- if (fileName.isEmpty())
- return false;
-
- const DWORD attr = GetFileAttributes (fileName);
-
- return dontCountDirectories ? ((attr & FILE_ATTRIBUTE_DIRECTORY) == 0)
- : (attr != 0xffffffff);
- }
-
- bool juce_isDirectory (const String& fileName) throw()
- {
- const DWORD attr = GetFileAttributes (fileName);
-
- return (attr != 0xffffffff)
- && ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0);
- }
-
- bool juce_canWriteToFile (const String& fileName) throw()
- {
- const DWORD attr = GetFileAttributes (fileName);
-
- return ((attr & FILE_ATTRIBUTE_READONLY) == 0);
- }
-
- bool juce_setFileReadOnly (const String& fileName,
- bool isReadOnly)
- {
- DWORD attr = GetFileAttributes (fileName);
-
- if (attr == 0xffffffff)
- return false;
-
- if (isReadOnly != juce_canWriteToFile (fileName))
- return true;
-
- if (isReadOnly)
- attr |= FILE_ATTRIBUTE_READONLY;
- else
- attr &= ~FILE_ATTRIBUTE_READONLY;
-
- return SetFileAttributes (fileName, attr) != FALSE;
- }
-
- bool File::isHidden() const throw()
- {
- return (GetFileAttributes (getFullPathName()) & FILE_ATTRIBUTE_HIDDEN) != 0;
- }
-
- bool juce_deleteFile (const String& fileName) throw()
- {
- if (juce_isDirectory (fileName))
- return RemoveDirectory (fileName) != 0;
-
- return DeleteFile (fileName) != 0;
- }
-
- bool juce_moveFile (const String& source, const String& dest) throw()
- {
- return MoveFile (source, dest) != 0;
- }
-
- bool juce_copyFile (const String& source, const String& dest) throw()
- {
- return CopyFile (source, dest, false) != 0;
- }
-
- void juce_createDirectory (const String& fileName) throw()
- {
- if (! juce_fileExists (fileName, true))
- {
- CreateDirectory (fileName, 0);
- }
- }
-
- // return 0 if not possible
- void* juce_fileOpen (const String& fileName, bool forWriting) throw()
- {
- HANDLE h;
-
- if (forWriting)
- {
- h = CreateFile (fileName, GENERIC_WRITE, FILE_SHARE_READ, 0,
- OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
-
- if (h != INVALID_HANDLE_VALUE)
- SetFilePointer (h, 0, 0, FILE_END);
- else
- h = 0;
- }
- else
- {
- h = CreateFile (fileName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0,
- OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, 0);
-
- if (h == INVALID_HANDLE_VALUE)
- h = 0;
- }
-
- return (void*) h;
- }
-
- void juce_fileClose (void* handle) throw()
- {
- CloseHandle (handle);
- }
-
- int juce_fileRead (void* handle, void* buffer, int size) throw()
- {
- DWORD num = 0;
- ReadFile ((HANDLE) handle, buffer, size, &num, 0);
- return num;
- }
-
- int juce_fileWrite (void* handle, const void* buffer, int size) throw()
- {
- DWORD num;
-
- WriteFile ((HANDLE) handle,
- buffer, size,
- &num, 0);
-
- return num;
- }
-
- int64 juce_fileSetPosition (void* handle, int64 pos) throw()
- {
- LARGE_INTEGER li;
- li.QuadPart = pos;
- li.LowPart = SetFilePointer ((HANDLE) handle,
- li.LowPart,
- &li.HighPart,
- FILE_BEGIN); // (returns -1 if it fails)
-
- return li.QuadPart;
- }
-
- int64 juce_fileGetPosition (void* handle) throw()
- {
- LARGE_INTEGER li;
- li.QuadPart = 0;
- li.LowPart = SetFilePointer ((HANDLE) handle,
- 0, &li.HighPart,
- FILE_CURRENT); // (returns -1 if it fails)
-
- return jmax ((int64) 0, li.QuadPart);
- }
-
- void juce_fileFlush (void* handle) throw()
- {
- FlushFileBuffers ((HANDLE) handle);
- }
-
- int64 juce_getFileSize (const String& fileName) throw()
- {
- WIN32_FILE_ATTRIBUTE_DATA attributes;
-
- if (GetFileAttributesEx (fileName, GetFileExInfoStandard, &attributes))
- {
- return (((int64) attributes.nFileSizeHigh) << 32)
- | attributes.nFileSizeLow;
- }
-
- return 0;
- }
-
- static int64 fileTimeToTime (const FILETIME* const ft) throw()
- {
- // tell me if this fails!
- static_jassert (sizeof (ULARGE_INTEGER) == sizeof (FILETIME));
-
- #if JUCE_GCC
- return (((const ULARGE_INTEGER*) ft)->QuadPart - 116444736000000000LL) / 10000;
- #else
- return (((const ULARGE_INTEGER*) ft)->QuadPart - 116444736000000000) / 10000;
- #endif
- }
-
- static void timeToFileTime (const int64 time, FILETIME* const ft) throw()
- {
- #if JUCE_GCC
- ((ULARGE_INTEGER*) ft)->QuadPart = time * 10000 + 116444736000000000LL;
- #else
- ((ULARGE_INTEGER*) ft)->QuadPart = time * 10000 + 116444736000000000;
- #endif
- }
-
- void juce_getFileTimes (const String& fileName,
- int64& modificationTime,
- int64& accessTime,
- int64& creationTime) throw()
- {
- WIN32_FILE_ATTRIBUTE_DATA attributes;
-
- if (GetFileAttributesEx (fileName, GetFileExInfoStandard, &attributes))
- {
- modificationTime = fileTimeToTime (&attributes.ftLastWriteTime);
- creationTime = fileTimeToTime (&attributes.ftCreationTime);
- accessTime = fileTimeToTime (&attributes.ftLastAccessTime);
- }
- else
- {
- creationTime = accessTime = modificationTime = 0;
- }
- }
-
- bool juce_setFileTimes (const String& fileName,
- int64 modificationTime,
- int64 accessTime,
- int64 creationTime) throw()
- {
- FILETIME m, a, c;
-
- if (modificationTime > 0)
- timeToFileTime (modificationTime, &m);
-
- if (accessTime > 0)
- timeToFileTime (accessTime, &a);
-
- if (creationTime > 0)
- timeToFileTime (creationTime, &c);
-
- void* const h = juce_fileOpen (fileName, true);
- bool ok = false;
-
- if (h != 0)
- {
- ok = SetFileTime ((HANDLE) h,
- (creationTime > 0) ? &c : 0,
- (accessTime > 0) ? &a : 0,
- (modificationTime > 0) ? &m : 0) != 0;
- juce_fileClose (h);
- }
-
- return ok;
- }
-
- // return '\0' separated list of strings
- const StringArray juce_getFileSystemRoots() throw()
- {
- TCHAR buffer [2048];
- buffer[0] = 0;
- buffer[1] = 0;
- GetLogicalDriveStrings (2048, buffer);
-
- TCHAR* n = buffer;
- StringArray roots;
-
- while (*n != 0)
- {
- roots.add (String (n));
-
- while (*n++ != 0)
- {
- }
- }
-
- roots.sort (true);
- return roots;
- }
-
- const String juce_getVolumeLabel (const String& filenameOnVolume,
- int& volumeSerialNumber) throw()
- {
- TCHAR n [4];
- n[0] = *(const TCHAR*) filenameOnVolume;
- n[1] = L':';
- n[2] = L'\\';
- n[3] = 0;
-
- TCHAR dest [64];
- DWORD serialNum;
-
- if (! GetVolumeInformation (n, dest, 64, (DWORD*) &serialNum, 0, 0, 0, 0))
- {
- dest[0] = 0;
- serialNum = 0;
- }
-
- volumeSerialNumber = serialNum;
- return String (dest);
- }
-
- int64 File::getBytesFreeOnVolume() const throw()
- {
- String fn (getFullPathName());
- if (fn[1] == T(':'))
- fn = fn.substring (0, 2) + T("\\");
-
- ULARGE_INTEGER spc;
- ULARGE_INTEGER tot;
- ULARGE_INTEGER totFree;
-
- if (GetDiskFreeSpaceEx (fn, &spc, &tot, &totFree))
- return (int64)(spc.QuadPart);
-
- return 0;
- }
-
- static unsigned int getWindowsDriveType (const String& fileName) throw()
- {
- TCHAR n[4];
- n[0] = *(const TCHAR*) fileName;
- n[1] = L':';
- n[2] = L'\\';
- n[3] = 0;
-
- return GetDriveType (n);
- }
-
- bool File::isOnCDRomDrive() const throw()
- {
- return getWindowsDriveType (getFullPathName()) == DRIVE_CDROM;
- }
-
- bool File::isOnHardDisk() const throw()
- {
- if (fullPath.isEmpty())
- return false;
-
- const unsigned int n = getWindowsDriveType (getFullPathName());
-
- if (fullPath.toLowerCase()[0] <= 'b'
- && fullPath[1] == T(':'))
- {
- return n != DRIVE_REMOVABLE;
- }
- else
- {
- return n != DRIVE_CDROM && n != DRIVE_REMOTE;
- }
- }
-
- bool File::isOnRemovableDrive() const throw()
- {
- if (fullPath.isEmpty())
- return false;
-
- const unsigned int n = getWindowsDriveType (getFullPathName());
-
- return n == DRIVE_CDROM
- || n == DRIVE_REMOTE
- || n == DRIVE_REMOVABLE
- || n == DRIVE_RAMDISK;
- }
-
- #define MAX_PATH_CHARS (MAX_PATH + 256)
-
- static const File juce_getSpecialFolderPath (int type) throw()
- {
- WCHAR path [MAX_PATH_CHARS];
-
- if (SHGetSpecialFolderPath (0, path, type, 0))
- return File (String (path));
-
- return File::nonexistent;
- }
-
- const File JUCE_CALLTYPE File::getSpecialLocation (const SpecialLocationType type)
- {
- int csidlType = 0;
-
- switch (type)
- {
- case userHomeDirectory:
- case userDocumentsDirectory:
- csidlType = CSIDL_PERSONAL;
- break;
-
- case userDesktopDirectory:
- csidlType = CSIDL_DESKTOP;
- break;
-
- case userApplicationDataDirectory:
- csidlType = CSIDL_APPDATA;
- break;
-
- case commonApplicationDataDirectory:
- csidlType = CSIDL_COMMON_APPDATA;
- break;
-
- case globalApplicationsDirectory:
- csidlType = CSIDL_PROGRAM_FILES;
- break;
-
- case userMusicDirectory:
- csidlType = CSIDL_MYMUSIC;
- break;
-
- case userMoviesDirectory:
- csidlType = CSIDL_MYVIDEO;
- break;
-
- case tempDirectory:
- {
- WCHAR dest [2048];
- dest[0] = 0;
- GetTempPath (2048, dest);
- return File (String (dest));
- }
-
- case currentExecutableFile:
- case currentApplicationFile:
- {
- HINSTANCE moduleHandle = (HINSTANCE) PlatformUtilities::getCurrentModuleInstanceHandle();
-
- WCHAR dest [MAX_PATH_CHARS];
- dest[0] = 0;
- GetModuleFileName (moduleHandle, dest, MAX_PATH_CHARS);
- return File (String (dest));
- }
- break;
-
- default:
- jassertfalse // unknown type?
- return File::nonexistent;
- }
-
- return juce_getSpecialFolderPath (csidlType);
- }
-
- void juce_setCurrentExecutableFileName (const String&) throw()
- {
- // n/a on windows
- }
-
- const File File::getCurrentWorkingDirectory() throw()
- {
- WCHAR dest [MAX_PATH_CHARS];
- dest[0] = 0;
- GetCurrentDirectory (MAX_PATH_CHARS, dest);
- return File (String (dest));
- }
-
- bool File::setAsCurrentWorkingDirectory() const throw()
- {
- return SetCurrentDirectory (getFullPathName()) != FALSE;
- }
-
- template <class FindDataType>
- static void getFindFileInfo (FindDataType& findData,
- String& filename, bool* const isDir, bool* const isHidden,
- int64* const fileSize, Time* const modTime, Time* const creationTime,
- bool* const isReadOnly) throw()
- {
- filename = findData.cFileName;
-
- if (isDir != 0)
- *isDir = ((findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0);
-
- if (isHidden != 0)
- *isHidden = ((findData.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) != 0);
-
- if (fileSize != 0)
- *fileSize = findData.nFileSizeLow + (((int64) findData.nFileSizeHigh) << 32);
-
- if (modTime != 0)
- *modTime = fileTimeToTime (&findData.ftLastWriteTime);
-
- if (creationTime != 0)
- *creationTime = fileTimeToTime (&findData.ftCreationTime);
-
- if (isReadOnly != 0)
- *isReadOnly = ((findData.dwFileAttributes & FILE_ATTRIBUTE_READONLY) != 0);
-
- }
-
- void* juce_findFileStart (const String& directory, const String& wildCard, String& firstResult,
- bool* isDir, bool* isHidden, int64* fileSize,
- Time* modTime, Time* creationTime, bool* isReadOnly) throw()
- {
- String wc (directory);
-
- if (! wc.endsWithChar (File::separator))
- wc += File::separator;
-
- wc += wildCard;
-
- WIN32_FIND_DATA findData;
- HANDLE h = FindFirstFile (wc, &findData);
-
- if (h != INVALID_HANDLE_VALUE)
- {
- getFindFileInfo (findData, firstResult, isDir, isHidden, fileSize,
- modTime, creationTime, isReadOnly);
- return h;
- }
-
- firstResult = String::empty;
- return 0;
- }
-
- bool juce_findFileNext (void* handle, String& resultFile,
- bool* isDir, bool* isHidden, int64* fileSize,
- Time* modTime, Time* creationTime, bool* isReadOnly) throw()
- {
- WIN32_FIND_DATA findData;
-
- if (handle != 0 && FindNextFile ((HANDLE) handle, &findData) != 0)
- {
- getFindFileInfo (findData, resultFile, isDir, isHidden, fileSize,
- modTime, creationTime, isReadOnly);
- return true;
- }
-
- resultFile = String::empty;
- return false;
- }
-
- void juce_findFileClose (void* handle) throw()
- {
- FindClose (handle);
- }
-
- bool juce_launchFile (const String& fileName,
- const String& parameters) throw()
- {
- HINSTANCE hInstance = 0;
-
- JUCE_TRY
- {
- hInstance = ShellExecute (0, 0, fileName, parameters, 0, SW_SHOWDEFAULT);
- }
- JUCE_CATCH_ALL
-
- return hInstance > (HINSTANCE) 32;
- }
-
- struct NamedPipeInternal
- {
- HANDLE pipeH;
- HANDLE cancelEvent;
- bool connected, createdPipe;
-
- NamedPipeInternal()
- : pipeH (0),
- cancelEvent (0),
- connected (false),
- createdPipe (false)
- {
- cancelEvent = CreateEvent (0, FALSE, FALSE, 0);
- }
-
- ~NamedPipeInternal()
- {
- disconnect();
-
- if (pipeH != 0)
- CloseHandle (pipeH);
-
- CloseHandle (cancelEvent);
- }
-
- bool connect (const int timeOutMs)
- {
- if (! createdPipe)
- return true;
-
- if (! connected)
- {
- OVERLAPPED over;
- zerostruct (over);
-
- over.hEvent = CreateEvent (0, TRUE, FALSE, 0);
-
- if (ConnectNamedPipe (pipeH, &over))
- {
- connected = false; // yes, you read that right. In overlapped mode it should always return 0.
- }
- else
- {
- const int err = GetLastError();
-
- if (err == ERROR_IO_PENDING || err == ERROR_PIPE_LISTENING)
- {
- HANDLE handles[] = { over.hEvent, cancelEvent };
-
- if (WaitForMultipleObjects (2, handles, FALSE,
- timeOutMs >= 0 ? timeOutMs : INFINITE) == WAIT_OBJECT_0)
- connected = true;
- }
- else if (err == ERROR_PIPE_CONNECTED)
- {
- connected = true;
- }
- }
-
- CloseHandle (over.hEvent);
- }
-
- return connected;
- }
-
- void disconnect()
- {
- if (connected)
- {
- DisconnectNamedPipe (pipeH);
- connected = false;
- }
- }
- };
-
- void NamedPipe::close()
- {
- NamedPipeInternal* const intern = (NamedPipeInternal*) internal;
- delete intern;
- internal = 0;
- }
-
- bool NamedPipe::openInternal (const String& pipeName, const bool createPipe)
- {
- close();
-
- NamedPipeInternal* const intern = new NamedPipeInternal();
-
- String file ("\\\\.\\pipe\\");
- file += pipeName;
-
- intern->createdPipe = createPipe;
-
- if (createPipe)
- {
- intern->pipeH = CreateNamedPipe (file, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, 0,
- 1, 64, 64, 0, NULL);
- }
- else
- {
- intern->pipeH = CreateFile (file, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING,
- FILE_FLAG_OVERLAPPED, 0);
- }
-
- if (intern->pipeH != INVALID_HANDLE_VALUE)
- {
- internal = intern;
- return true;
- }
-
- delete intern;
- return false;
- }
-
- int NamedPipe::read (void* destBuffer, int maxBytesToRead, int timeOutMilliseconds)
- {
- int bytesRead = -1;
- bool waitAgain = true;
-
- while (waitAgain && internal != 0)
- {
- NamedPipeInternal* const intern = (NamedPipeInternal*) internal;
- waitAgain = false;
-
- if (! intern->connect (timeOutMilliseconds))
- break;
-
- if (maxBytesToRead <= 0)
- return 0;
-
- OVERLAPPED over;
- zerostruct (over);
- over.hEvent = CreateEvent (0, TRUE, FALSE, 0);
-
- unsigned long numRead;
-
- if (ReadFile (intern->pipeH, destBuffer, maxBytesToRead, &numRead, &over))
- {
- bytesRead = (int) numRead;
- }
- else if (GetLastError() == ERROR_IO_PENDING)
- {
- HANDLE handles[] = { over.hEvent, intern->cancelEvent };
-
- if (WaitForMultipleObjects (2, handles, FALSE,
- timeOutMilliseconds >= 0 ? timeOutMilliseconds
- : INFINITE) == WAIT_OBJECT_0)
- {
- if (GetOverlappedResult (intern->pipeH, &over, &numRead, FALSE))
- {
- bytesRead = (int) numRead;
- }
- else if (GetLastError() == ERROR_BROKEN_PIPE && intern->createdPipe)
- {
- intern->disconnect();
- waitAgain = true;
- }
- }
- }
- else
- {
- waitAgain = internal != 0;
- Sleep (5);
- }
-
- CloseHandle (over.hEvent);
- }
-
- return bytesRead;
- }
-
- int NamedPipe::write (const void* sourceBuffer, int numBytesToWrite, int timeOutMilliseconds)
- {
- int bytesWritten = -1;
- NamedPipeInternal* const intern = (NamedPipeInternal*) internal;
-
- if (intern != 0 && intern->connect (timeOutMilliseconds))
- {
- if (numBytesToWrite <= 0)
- return 0;
-
- OVERLAPPED over;
- zerostruct (over);
-
- over.hEvent = CreateEvent (0, TRUE, FALSE, 0);
-
- unsigned long numWritten;
-
- if (WriteFile (intern->pipeH, sourceBuffer, numBytesToWrite, &numWritten, &over))
- {
- bytesWritten = (int) numWritten;
- }
- else if (GetLastError() == ERROR_IO_PENDING)
- {
- HANDLE handles[] = { over.hEvent, intern->cancelEvent };
-
- if (WaitForMultipleObjects (2, handles, FALSE, timeOutMilliseconds >= 0 ? timeOutMilliseconds
- : INFINITE) == WAIT_OBJECT_0)
- {
- if (GetOverlappedResult (intern->pipeH, &over, &numWritten, FALSE))
- {
- bytesWritten = (int) numWritten;
- }
- else if (GetLastError() == ERROR_BROKEN_PIPE && intern->createdPipe)
- {
- intern->disconnect();
- }
- }
- }
-
- CloseHandle (over.hEvent);
- }
-
- return bytesWritten;
- }
-
- void NamedPipe::cancelPendingReads()
- {
- NamedPipeInternal* const intern = (NamedPipeInternal*) internal;
-
- if (intern != 0)
- SetEvent (intern->cancelEvent);
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_win32_Files.cpp *********/
-
- /********* Start of inlined file: juce_win32_Network.cpp *********/
- #ifdef _MSC_VER
- #pragma warning (disable: 4514)
- #pragma warning (push)
- #endif
-
- #include <wininet.h>
- #include <nb30.h>
- #include <iphlpapi.h>
- #include <mapi.h>
-
- BEGIN_JUCE_NAMESPACE
-
- /********* Start of inlined file: juce_win32_DynamicLibraryLoader.h *********/
- #ifndef __JUCE_WIN32_DYNAMICLIBRARYLOADER_JUCEHEADER__
- #define __JUCE_WIN32_DYNAMICLIBRARYLOADER_JUCEHEADER__
-
- #ifndef DOXYGEN
-
- // use with DynamicLibraryLoader to simplify importing functions
- //
- // functionName: function to import
- // localFunctionName: name you want to use to actually call it (must be different)
- // returnType: the return type
- // object: the DynamicLibraryLoader to use
- // params: list of params (bracketed)
- //
- #define DynamicLibraryImport(functionName, localFunctionName, returnType, object, params) \
- typedef returnType (WINAPI *type##localFunctionName) params; \
- type##localFunctionName localFunctionName \
- = (type##localFunctionName)object.findProcAddress (#functionName);
-
- // loads and unloads a DLL automatically
- class JUCE_API DynamicLibraryLoader
- {
- public:
- DynamicLibraryLoader (const String& name);
- ~DynamicLibraryLoader();
-
- void* findProcAddress (const String& functionName);
-
- private:
- void* libHandle;
- };
-
- #endif
- #endif // __JUCE_WIN32_DYNAMICLIBRARYLOADER_JUCEHEADER__
- /********* End of inlined file: juce_win32_DynamicLibraryLoader.h *********/
-
- #ifndef INTERNET_FLAG_NEED_FILE
- #define INTERNET_FLAG_NEED_FILE 0x00000010
- #endif
-
- #ifdef _MSC_VER
- #pragma warning (pop)
- #endif
-
- bool juce_isOnLine()
- {
- DWORD connectionType;
-
- return InternetGetConnectedState (&connectionType, 0) != 0
- || (connectionType & (INTERNET_CONNECTION_LAN | INTERNET_CONNECTION_PROXY)) != 0;
- }
-
- struct ConnectionAndRequestStruct
- {
- HINTERNET connection, request;
- };
-
- static HINTERNET sessionHandle = 0;
-
- void* juce_openInternetFile (const String& url,
- const String& headers,
- const MemoryBlock& postData,
- const bool isPost,
- URL::OpenStreamProgressCallback* callback,
- void* callbackContext,
- int timeOutMs)
- {
- if (sessionHandle == 0)
- sessionHandle = InternetOpen (_T("juce"),
- INTERNET_OPEN_TYPE_PRECONFIG,
- 0, 0, 0);
-
- if (sessionHandle != 0)
- {
- // break up the url..
- TCHAR file[1024], server[1024];
-
- URL_COMPONENTS uc;
- zerostruct (uc);
-
- uc.dwStructSize = sizeof (uc);
- uc.dwUrlPathLength = sizeof (file);
- uc.dwHostNameLength = sizeof (server);
- uc.lpszUrlPath = file;
- uc.lpszHostName = server;
-
- if (InternetCrackUrl (url, 0, 0, &uc))
- {
- if (timeOutMs == 0)
- timeOutMs = 30000;
- else if (timeOutMs < 0)
- timeOutMs = -1;
-
- InternetSetOption (sessionHandle, INTERNET_OPTION_CONNECT_TIMEOUT, &timeOutMs, sizeof (timeOutMs));
-
- const bool isFtp = url.startsWithIgnoreCase (T("ftp:"));
-
- HINTERNET connection = InternetConnect (sessionHandle,
- uc.lpszHostName,
- uc.nPort,
- _T(""), _T(""),
- isFtp ? INTERNET_SERVICE_FTP
- : INTERNET_SERVICE_HTTP,
- 0, 0);
-
- if (connection != 0)
- {
- if (isFtp)
- {
- HINTERNET request = FtpOpenFile (connection,
- uc.lpszUrlPath,
- GENERIC_READ,
- FTP_TRANSFER_TYPE_BINARY | INTERNET_FLAG_NEED_FILE,
- 0);
-
- ConnectionAndRequestStruct* const result = new ConnectionAndRequestStruct();
- result->connection = connection;
- result->request = request;
- return result;
- }
- else
- {
- const TCHAR* mimeTypes[] = { _T("*/*"), 0 };
-
- HINTERNET request = HttpOpenRequest (connection,
- isPost ? _T("POST")
- : _T("GET"),
- uc.lpszUrlPath,
- 0, 0, mimeTypes,
- INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_CACHE_WRITE,
- 0);
-
- if (request != 0)
- {
- INTERNET_BUFFERS buffers;
- zerostruct (buffers);
- buffers.dwStructSize = sizeof (INTERNET_BUFFERS);
- buffers.lpcszHeader = (LPCTSTR) headers;
- buffers.dwHeadersLength = headers.length();
- buffers.dwBufferTotal = (DWORD) postData.getSize();
- ConnectionAndRequestStruct* result = 0;
-
- if (HttpSendRequestEx (request, &buffers, 0, HSR_INITIATE, 0))
- {
- int bytesSent = 0;
-
- for (;;)
- {
- const int bytesToDo = jmin (1024, postData.getSize() - bytesSent);
- DWORD bytesDone = 0;
-
- if (bytesToDo > 0
- && ! InternetWriteFile (request,
- ((const char*) postData.getData()) + bytesSent,
- bytesToDo, &bytesDone))
- {
- break;
- }
-
- if (bytesToDo == 0 || (int) bytesDone < bytesToDo)
- {
- result = new ConnectionAndRequestStruct();
- result->connection = connection;
- result->request = request;
-
- HttpEndRequest (request, 0, 0, 0);
- return result;
- }
-
- bytesSent += bytesDone;
-
- if (callback != 0 && ! callback (callbackContext, bytesSent, postData.getSize()))
- break;
- }
- }
-
- InternetCloseHandle (request);
- }
-
- InternetCloseHandle (connection);
- }
- }
- }
- }
-
- return 0;
- }
-
- int juce_readFromInternetFile (void* handle, void* buffer, int bytesToRead)
- {
- DWORD bytesRead = 0;
-
- const ConnectionAndRequestStruct* const crs = (const ConnectionAndRequestStruct*) handle;
-
- if (crs != 0)
- InternetReadFile (crs->request,
- buffer, bytesToRead,
- &bytesRead);
-
- return bytesRead;
- }
-
- int juce_seekInInternetFile (void* handle, int newPosition)
- {
- if (handle != 0)
- {
- const ConnectionAndRequestStruct* const crs = (const ConnectionAndRequestStruct*) handle;
-
- return InternetSetFilePointer (crs->request,
- newPosition, 0,
- FILE_BEGIN, 0);
- }
- else
- {
- return -1;
- }
- }
-
- void juce_closeInternetFile (void* handle)
- {
- if (handle != 0)
- {
- ConnectionAndRequestStruct* const crs = (ConnectionAndRequestStruct*) handle;
- InternetCloseHandle (crs->request);
- InternetCloseHandle (crs->connection);
- delete crs;
- }
- }
-
- static int getMACAddressViaGetAdaptersInfo (int64* addresses, int maxNum, const bool littleEndian) throw()
- {
- int numFound = 0;
-
- DynamicLibraryLoader dll ("iphlpapi.dll");
- DynamicLibraryImport (GetAdaptersInfo, getAdaptersInfo, DWORD, dll, (PIP_ADAPTER_INFO, PULONG))
-
- if (getAdaptersInfo != 0)
- {
- ULONG len = sizeof (IP_ADAPTER_INFO);
- MemoryBlock mb;
- PIP_ADAPTER_INFO adapterInfo = (PIP_ADAPTER_INFO) mb.getData();
-
- if (getAdaptersInfo (adapterInfo, &len) == ERROR_BUFFER_OVERFLOW)
- {
- mb.setSize (len);
- adapterInfo = (PIP_ADAPTER_INFO) mb.getData();
- }
-
- if (getAdaptersInfo (adapterInfo, &len) == NO_ERROR)
- {
- PIP_ADAPTER_INFO adapter = adapterInfo;
-
- while (adapter != 0)
- {
- int64 mac = 0;
- for (unsigned int i = 0; i < adapter->AddressLength; ++i)
- mac = (mac << 8) | adapter->Address[i];
-
- if (littleEndian)
- mac = (int64) swapByteOrder ((uint64) mac);
-
- if (numFound < maxNum && mac != 0)
- addresses [numFound++] = mac;
-
- adapter = adapter->Next;
- }
- }
- }
-
- return numFound;
- }
-
- static int getMACAddressesViaNetBios (int64* addresses, int maxNum, const bool littleEndian) throw()
- {
- int numFound = 0;
-
- DynamicLibraryLoader dll ("netapi32.dll");
- DynamicLibraryImport (Netbios, NetbiosCall, UCHAR, dll, (PNCB))
-
- if (NetbiosCall != 0)
- {
- NCB ncb;
- zerostruct (ncb);
-
- typedef struct _ASTAT_
- {
- ADAPTER_STATUS adapt;
- NAME_BUFFER NameBuff [30];
- } ASTAT;
-
- ASTAT astat;
- zerostruct (astat);
-
- LANA_ENUM enums;
- zerostruct (enums);
-
- ncb.ncb_command = NCBENUM;
- ncb.ncb_buffer = (unsigned char*) &enums;
- ncb.ncb_length = sizeof (LANA_ENUM);
- NetbiosCall (&ncb);
-
- for (int i = 0; i < enums.length; ++i)
- {
- zerostruct (ncb);
- ncb.ncb_command = NCBRESET;
- ncb.ncb_lana_num = enums.lana[i];
-
- if (NetbiosCall (&ncb) == 0)
- {
- zerostruct (ncb);
- memcpy (ncb.ncb_callname, "* ", NCBNAMSZ);
- ncb.ncb_command = NCBASTAT;
- ncb.ncb_lana_num = enums.lana[i];
-
- ncb.ncb_buffer = (unsigned char*) &astat;
- ncb.ncb_length = sizeof (ASTAT);
-
- if (NetbiosCall (&ncb) == 0)
- {
- if (astat.adapt.adapter_type == 0xfe)
- {
- int64 mac = 0;
- for (unsigned int i = 0; i < 6; ++i)
- mac = (mac << 8) | astat.adapt.adapter_address[i];
-
- if (littleEndian)
- mac = (int64) swapByteOrder ((uint64) mac);
-
- if (numFound < maxNum && mac != 0)
- addresses [numFound++] = mac;
- }
- }
- }
- }
- }
-
- return numFound;
- }
-
- int SystemStats::getMACAddresses (int64* addresses, int maxNum, const bool littleEndian) throw()
- {
- int numFound = getMACAddressViaGetAdaptersInfo (addresses, maxNum, littleEndian);
-
- if (numFound == 0)
- numFound = getMACAddressesViaNetBios (addresses, maxNum, littleEndian);
-
- return numFound;
- }
-
- typedef ULONG (WINAPI *MAPISendMailType) (LHANDLE, ULONG, lpMapiMessage, ::FLAGS, ULONG);
-
- bool PlatformUtilities::launchEmailWithAttachments (const String& targetEmailAddress,
- const String& emailSubject,
- const String& bodyText,
- const StringArray& filesToAttach)
- {
- HMODULE h = LoadLibraryA ("MAPI32.dll");
-
- MAPISendMailType mapiSendMail = (MAPISendMailType) GetProcAddress (h, "MAPISendMail");
- bool ok = false;
-
- if (mapiSendMail != 0)
- {
- MapiMessage message;
- zerostruct (message);
- message.lpszSubject = (LPSTR) (LPCSTR) emailSubject;
- message.lpszNoteText = (LPSTR) (LPCSTR) bodyText;
-
- MapiRecipDesc recip;
- zerostruct (recip);
- recip.ulRecipClass = MAPI_TO;
- recip.lpszName = (LPSTR) (LPCSTR) targetEmailAddress;
- message.nRecipCount = 1;
- message.lpRecips = &recip;
-
- MemoryBlock mb (sizeof (MapiFileDesc) * filesToAttach.size());
- mb.fillWith (0);
- MapiFileDesc* files = (MapiFileDesc*) mb.getData();
-
- message.nFileCount = filesToAttach.size();
- message.lpFiles = files;
-
- for (int i = 0; i < filesToAttach.size(); ++i)
- {
- files[i].nPosition = (ULONG) -1;
- files[i].lpszPathName = (LPSTR) (LPCSTR) filesToAttach [i];
- }
-
- ok = (mapiSendMail (0, 0, &message, MAPI_DIALOG | MAPI_LOGON_UI, 0) == SUCCESS_SUCCESS);
- }
-
- FreeLibrary (h);
- return ok;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_win32_Network.cpp *********/
-
- /********* Start of inlined file: juce_win32_Misc.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- #if ! JUCE_ONLY_BUILD_CORE_LIBRARY
- bool AlertWindow::showNativeDialogBox (const String& title,
- const String& bodyText,
- bool isOkCancel)
- {
- return MessageBox (0, bodyText, title,
- (isOkCancel) ? MB_OKCANCEL
- : MB_OK) == IDOK;
- }
-
- #endif
-
- void PlatformUtilities::beep()
- {
- MessageBeep (MB_OK);
- }
-
- #if JUCE_MSVC
- #pragma warning (disable : 4127) // "Conditional expression is constant" warning
- #endif
-
- #if ! JUCE_ONLY_BUILD_CORE_LIBRARY
-
- void SystemClipboard::copyTextToClipboard (const String& text) throw()
- {
- if (OpenClipboard (0) != 0)
- {
- if (EmptyClipboard() != 0)
- {
- const int len = text.length();
-
- if (len > 0)
- {
- HGLOBAL bufH = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE,
- (len + 1) * sizeof (wchar_t));
-
- if (bufH != 0)
- {
- wchar_t* const data = (wchar_t*) GlobalLock (bufH);
- text.copyToBuffer (data, len);
- GlobalUnlock (bufH);
-
- SetClipboardData (CF_UNICODETEXT, bufH);
- }
- }
- }
-
- CloseClipboard();
- }
- }
-
- const String SystemClipboard::getTextFromClipboard() throw()
- {
- String result;
-
- if (OpenClipboard (0) != 0)
- {
- HANDLE bufH = GetClipboardData (CF_UNICODETEXT);
-
- if (bufH != 0)
- {
- const wchar_t* const data = (const wchar_t*) GlobalLock (bufH);
-
- if (data != 0)
- {
- result = String (data, (int) (GlobalSize (bufH) / sizeof (tchar)));
-
- GlobalUnlock (bufH);
- }
- }
-
- CloseClipboard();
- }
-
- return result;
- }
-
- #endif
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_win32_Misc.cpp *********/
-
- /********* Start of inlined file: juce_win32_PlatformUtils.cpp *********/
- #ifdef _MSC_VER
- #pragma warning (disable: 4514)
- #pragma warning (push)
- #endif
-
- #include <float.h>
-
- BEGIN_JUCE_NAMESPACE
-
- #ifdef _MSC_VER
- #pragma warning (pop)
- #endif
-
- static HKEY findKeyForPath (String name,
- const bool createForWriting,
- String& valueName) throw()
- {
- HKEY rootKey = 0;
-
- if (name.startsWithIgnoreCase (T("HKEY_CURRENT_USER\\")))
- rootKey = HKEY_CURRENT_USER;
- else if (name.startsWithIgnoreCase (T("HKEY_LOCAL_MACHINE\\")))
- rootKey = HKEY_LOCAL_MACHINE;
- else if (name.startsWithIgnoreCase (T("HKEY_CLASSES_ROOT\\")))
- rootKey = HKEY_CLASSES_ROOT;
-
- if (rootKey != 0)
- {
- name = name.substring (name.indexOfChar (T('\\')) + 1);
-
- const int lastSlash = name.lastIndexOfChar (T('\\'));
- valueName = name.substring (lastSlash + 1);
- name = name.substring (0, lastSlash);
-
- HKEY key;
- DWORD result;
-
- if (createForWriting)
- {
- if (RegCreateKeyEx (rootKey, name, 0, L"", REG_OPTION_NON_VOLATILE,
- (KEY_WRITE | KEY_QUERY_VALUE), 0, &key, &result) == ERROR_SUCCESS)
- return key;
- }
- else
- {
- if (RegOpenKeyEx (rootKey, name, 0, KEY_READ, &key) == ERROR_SUCCESS)
- return key;
- }
- }
-
- return 0;
- }
-
- const String PlatformUtilities::getRegistryValue (const String& regValuePath,
- const String& defaultValue)
- {
- String valueName, s;
- HKEY k = findKeyForPath (regValuePath, false, valueName);
-
- if (k != 0)
- {
- WCHAR buffer [2048];
- unsigned long bufferSize = sizeof (buffer);
- DWORD type = REG_SZ;
-
- if (RegQueryValueEx (k, valueName, 0, &type, (LPBYTE) buffer, &bufferSize) == ERROR_SUCCESS)
- s = buffer;
- else
- s = defaultValue;
-
- RegCloseKey (k);
- }
-
- return s;
- }
-
- void PlatformUtilities::setRegistryValue (const String& regValuePath,
- const String& value)
- {
- String valueName;
- HKEY k = findKeyForPath (regValuePath, true, valueName);
-
- if (k != 0)
- {
- RegSetValueEx (k, valueName, 0, REG_SZ,
- (const BYTE*) (const WCHAR*) value,
- sizeof (WCHAR) * (value.length() + 1));
-
- RegCloseKey (k);
- }
- }
-
- bool PlatformUtilities::registryValueExists (const String& regValuePath)
- {
- bool exists = false;
- String valueName;
- HKEY k = findKeyForPath (regValuePath, false, valueName);
-
- if (k != 0)
- {
- unsigned char buffer [2048];
- unsigned long bufferSize = sizeof (buffer);
- DWORD type = 0;
-
- if (RegQueryValueEx (k, valueName, 0, &type, buffer, &bufferSize) == ERROR_SUCCESS)
- exists = true;
-
- RegCloseKey (k);
- }
-
- return exists;
- }
-
- void PlatformUtilities::deleteRegistryValue (const String& regValuePath)
- {
- String valueName;
- HKEY k = findKeyForPath (regValuePath, true, valueName);
-
- if (k != 0)
- {
- RegDeleteValue (k, valueName);
- RegCloseKey (k);
- }
- }
-
- void PlatformUtilities::deleteRegistryKey (const String& regKeyPath)
- {
- String valueName;
- HKEY k = findKeyForPath (regKeyPath, true, valueName);
-
- if (k != 0)
- {
- RegDeleteKey (k, valueName);
- RegCloseKey (k);
- }
- }
-
- bool juce_IsRunningInWine() throw()
- {
- HKEY key;
- if (RegOpenKeyEx (HKEY_CURRENT_USER, _T("Software\\Wine"), 0, KEY_READ, &key) == ERROR_SUCCESS)
- {
- RegCloseKey (key);
- return true;
- }
-
- return false;
- }
-
- const String JUCE_CALLTYPE PlatformUtilities::getCurrentCommandLineParams() throw()
- {
- String s (::GetCommandLineW());
-
- StringArray tokens;
- tokens.addTokens (s, true); // tokenise so that we can remove the initial filename argument
-
- return tokens.joinIntoString (T(" "), 1);
- }
-
- static void* currentModuleHandle = 0;
-
- void* PlatformUtilities::getCurrentModuleInstanceHandle() throw()
- {
- if (currentModuleHandle == 0)
- currentModuleHandle = GetModuleHandle (0);
-
- return currentModuleHandle;
- }
-
- void PlatformUtilities::setCurrentModuleInstanceHandle (void* const newHandle) throw()
- {
- currentModuleHandle = newHandle;
- }
-
- void PlatformUtilities::fpuReset()
- {
- #if JUCE_MSVC
- _clearfp();
- #endif
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_win32_PlatformUtils.cpp *********/
-
- /********* Start of inlined file: juce_win32_SystemStats.cpp *********/
-
- // Auto-link the other win32 libs that are needed by library calls..
- #if defined (JUCE_DLL_BUILD) && JUCE_MSVC
-
- /********* Start of inlined file: juce_win32_AutoLinkLibraries.h *********/
- // Auto-links to various win32 libs that are needed by library calls..
- #pragma comment(lib, "kernel32.lib")
- #pragma comment(lib, "user32.lib")
- #pragma comment(lib, "shell32.lib")
- #pragma comment(lib, "gdi32.lib")
- #pragma comment(lib, "vfw32.lib")
- #pragma comment(lib, "comdlg32.lib")
- #pragma comment(lib, "winmm.lib")
- #pragma comment(lib, "wininet.lib")
- #pragma comment(lib, "ole32.lib")
- #pragma comment(lib, "advapi32.lib")
- #pragma comment(lib, "ws2_32.lib")
- #pragma comment(lib, "comsupp.lib")
-
- #if JUCE_OPENGL
- #pragma comment(lib, "OpenGL32.Lib")
- #pragma comment(lib, "GlU32.Lib")
- #endif
-
- #if JUCE_QUICKTIME
- #pragma comment (lib, "QTMLClient.lib")
- #endif
- /********* End of inlined file: juce_win32_AutoLinkLibraries.h *********/
-
- #endif
-
- BEGIN_JUCE_NAMESPACE
-
- extern void juce_updateMultiMonitorInfo() throw();
- extern void juce_initialiseThreadEvents() throw();
-
- void Logger::outputDebugString (const String& text) throw()
- {
- OutputDebugString (text + T("\n"));
- }
-
- void Logger::outputDebugPrintf (const tchar* format, ...) throw()
- {
- String text;
- va_list args;
- va_start (args, format);
- text.vprintf(format, args);
- outputDebugString (text);
- }
-
- static int64 hiResTicksPerSecond;
- static double hiResTicksScaleFactor;
-
- #if JUCE_USE_INTRINSICS
-
- // CPU info functions using intrinsics...
-
- #pragma intrinsic (__cpuid)
- #pragma intrinsic (__rdtsc)
-
- /*static unsigned int getCPUIDWord (int* familyModel = 0, int* extFeatures = 0) throw()
- {
- int info [4];
- __cpuid (info, 1);
-
- if (familyModel != 0)
- *familyModel = info [0];
-
- if (extFeatures != 0)
- *extFeatures = info[1];
-
- return info[3];
- }*/
-
- const String SystemStats::getCpuVendor() throw()
- {
- int info [4];
- __cpuid (info, 0);
-
- char v [12];
- memcpy (v, info + 1, 4);
- memcpy (v + 4, info + 3, 4);
- memcpy (v + 8, info + 2, 4);
-
- return String (v, 12);
- }
-
- #else
-
- // CPU info functions using old fashioned inline asm...
-
- /*static juce_noinline unsigned int getCPUIDWord (int* familyModel = 0, int* extFeatures = 0)
- {
- unsigned int cpu = 0;
- unsigned int ext = 0;
- unsigned int family = 0;
-
- #if JUCE_GCC
- unsigned int dummy = 0;
- #endif
-
- #ifndef __MINGW32__
- __try
- #endif
- {
- #if JUCE_GCC
- __asm__ ("cpuid" : "=a" (family), "=b" (ext), "=c" (dummy),"=d" (cpu) : "a" (1));
- #else
- __asm
- {
- mov eax, 1
- cpuid
- mov cpu, edx
- mov family, eax
- mov ext, ebx
- }
-
- #endif
- }
- #ifndef __MINGW32__
- __except (EXCEPTION_EXECUTE_HANDLER)
- {
- return 0;
- }
- #endif
-
- if (familyModel != 0)
- *familyModel = family;
-
- if (extFeatures != 0)
- *extFeatures = ext;
-
- return cpu;
- }*/
-
- static void juce_getCpuVendor (char* const v)
- {
- int vendor[4];
- zeromem (vendor, 16);
-
- #ifdef JUCE_64BIT
- #else
- #ifndef __MINGW32__
- __try
- #endif
- {
- #if JUCE_GCC
- unsigned int dummy = 0;
- __asm__ ("cpuid" : "=a" (dummy), "=b" (vendor[0]), "=c" (vendor[2]),"=d" (vendor[1]) : "a" (0));
- #else
- __asm
- {
- mov eax, 0
- cpuid
- mov [vendor], ebx
- mov [vendor + 4], edx
- mov [vendor + 8], ecx
- }
- #endif
- }
- #ifndef __MINGW32__
- __except (EXCEPTION_EXECUTE_HANDLER)
- {
- *v = 0;
- }
- #endif
- #endif
-
- memcpy (v, vendor, 16);
- }
-
- const String SystemStats::getCpuVendor() throw()
- {
- char v [16];
- juce_getCpuVendor (v);
- return String (v, 16);
- }
- #endif
-
- struct CPUFlags
- {
- bool hasMMX : 1;
- bool hasSSE : 1;
- bool hasSSE2 : 1;
- bool has3DNow : 1;
- };
-
- static CPUFlags cpuFlags;
-
- bool SystemStats::hasMMX() throw()
- {
- return cpuFlags.hasMMX;
- }
-
- bool SystemStats::hasSSE() throw()
- {
- return cpuFlags.hasSSE;
- }
-
- bool SystemStats::hasSSE2() throw()
- {
- return cpuFlags.hasSSE2;
- }
-
- bool SystemStats::has3DNow() throw()
- {
- return cpuFlags.has3DNow;
- }
-
- void SystemStats::initialiseStats() throw()
- {
- juce_initialiseThreadEvents();
-
- cpuFlags.hasMMX = IsProcessorFeaturePresent (PF_MMX_INSTRUCTIONS_AVAILABLE) != 0;
- cpuFlags.hasSSE = IsProcessorFeaturePresent (PF_XMMI_INSTRUCTIONS_AVAILABLE) != 0;
- cpuFlags.hasSSE2 = IsProcessorFeaturePresent (PF_XMMI64_INSTRUCTIONS_AVAILABLE) != 0;
- #ifdef PF_AMD3D_INSTRUCTIONS_AVAILABLE
- cpuFlags.has3DNow = IsProcessorFeaturePresent (PF_AMD3D_INSTRUCTIONS_AVAILABLE) != 0;
- #else
- cpuFlags.has3DNow = IsProcessorFeaturePresent (PF_3DNOW_INSTRUCTIONS_AVAILABLE) != 0;
- #endif
-
- LARGE_INTEGER f;
- QueryPerformanceFrequency (&f);
- hiResTicksPerSecond = f.QuadPart;
- hiResTicksScaleFactor = 1000.0 / hiResTicksPerSecond;
-
- String s (SystemStats::getJUCEVersion());
-
- #ifdef JUCE_DEBUG
- const MMRESULT res = timeBeginPeriod (1);
- jassert (res == TIMERR_NOERROR);
- #else
- timeBeginPeriod (1);
- #endif
-
- #if defined (JUCE_DEBUG) && JUCE_MSVC && JUCE_CHECK_MEMORY_LEAKS
- _CrtSetDbgFlag (_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
- #endif
- }
-
- SystemStats::OperatingSystemType SystemStats::getOperatingSystemType() throw()
- {
- OSVERSIONINFO info;
- info.dwOSVersionInfoSize = sizeof (info);
- GetVersionEx (&info);
-
- if (info.dwPlatformId == VER_PLATFORM_WIN32_NT)
- {
- switch (info.dwMajorVersion)
- {
- case 5:
- return (info.dwMinorVersion == 0) ? Win2000 : WinXP;
-
- case 6:
- return WinVista;
-
- default:
- jassertfalse // !! not a supported OS!
- break;
- }
- }
- else if (info.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
- {
- jassert (info.dwMinorVersion != 0); // !! still running on Windows 95??
-
- return Win98;
- }
-
- return UnknownOS;
- }
-
- const String SystemStats::getOperatingSystemName() throw()
- {
- const char* name = "Unknown OS";
-
- switch (getOperatingSystemType())
- {
- case WinVista:
- name = "Windows Vista";
- break;
-
- case WinXP:
- name = "Windows XP";
- break;
-
- case Win2000:
- name = "Windows 2000";
- break;
-
- case Win98:
- name = "Windows 98";
- break;
-
- default:
- jassertfalse // !! new type of OS?
- break;
- }
-
- return name;
- }
-
- bool SystemStats::isOperatingSystem64Bit() throw()
- {
- #ifdef _WIN64
- return true;
- #else
- typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
-
- LPFN_ISWOW64PROCESS fnIsWow64Process = (LPFN_ISWOW64PROCESS) GetProcAddress (GetModuleHandle (L"kernel32"), "IsWow64Process");
-
- BOOL isWow64 = FALSE;
-
- return (fnIsWow64Process != 0)
- && fnIsWow64Process (GetCurrentProcess(), &isWow64)
- && (isWow64 != FALSE);
- #endif
- }
-
- int SystemStats::getMemorySizeInMegabytes() throw()
- {
- MEMORYSTATUS mem;
- GlobalMemoryStatus (&mem);
- return (int) (mem.dwTotalPhys / (1024 * 1024)) + 1;
- }
-
- int SystemStats::getNumCpus() throw()
- {
- SYSTEM_INFO systemInfo;
- GetSystemInfo (&systemInfo);
-
- return systemInfo.dwNumberOfProcessors;
- }
-
- uint32 juce_millisecondsSinceStartup() throw()
- {
- return (uint32) GetTickCount();
- }
-
- int64 Time::getHighResolutionTicks() throw()
- {
- LARGE_INTEGER ticks;
- QueryPerformanceCounter (&ticks);
-
- const int64 mainCounterAsHiResTicks = (GetTickCount() * hiResTicksPerSecond) / 1000;
- const int64 newOffset = mainCounterAsHiResTicks - ticks.QuadPart;
-
- // fix for a very obscure PCI hardware bug that can make the counter
- // sometimes jump forwards by a few seconds..
- static int64 hiResTicksOffset = 0;
- const int64 offsetDrift = abs64 (newOffset - hiResTicksOffset);
-
- if (offsetDrift > (hiResTicksPerSecond >> 1))
- hiResTicksOffset = newOffset;
-
- return ticks.QuadPart + hiResTicksOffset;
- }
-
- double Time::getMillisecondCounterHiRes() throw()
- {
- return getHighResolutionTicks() * hiResTicksScaleFactor;
- }
-
- int64 Time::getHighResolutionTicksPerSecond() throw()
- {
- return hiResTicksPerSecond;
- }
-
- int64 SystemStats::getClockCycleCounter() throw()
- {
- #if JUCE_USE_INTRINSICS
- // MS intrinsics version...
- return __rdtsc();
-
- #elif JUCE_GCC
- // GNU inline asm version...
- unsigned int hi = 0, lo = 0;
-
- __asm__ __volatile__ (
- "xor %%eax, %%eax \n\
- xor %%edx, %%edx \n\
- rdtsc \n\
- movl %%eax, %[lo] \n\
- movl %%edx, %[hi]"
- :
- : [hi] "m" (hi),
- [lo] "m" (lo)
- : "cc", "eax", "ebx", "ecx", "edx", "memory");
-
- return (int64) ((((uint64) hi) << 32) | lo);
- #else
- // MSVC inline asm version...
- unsigned int hi = 0, lo = 0;
-
- __asm
- {
- xor eax, eax
- xor edx, edx
- rdtsc
- mov lo, eax
- mov hi, edx
- }
-
- return (int64) ((((uint64) hi) << 32) | lo);
- #endif
- }
-
- int SystemStats::getCpuSpeedInMegaherz() throw()
- {
- const int64 cycles = SystemStats::getClockCycleCounter();
- const uint32 millis = Time::getMillisecondCounter();
- int lastResult = 0;
-
- for (;;)
- {
- int n = 1000000;
- while (--n > 0) {}
-
- const uint32 millisElapsed = Time::getMillisecondCounter() - millis;
- const int64 cyclesNow = SystemStats::getClockCycleCounter();
-
- if (millisElapsed > 80)
- {
- const int newResult = (int) (((cyclesNow - cycles) / millisElapsed) / 1000);
-
- if (millisElapsed > 500 || (lastResult == newResult && newResult > 100))
- return newResult;
-
- lastResult = newResult;
- }
- }
- }
-
- bool Time::setSystemTimeToThisTime() const throw()
- {
- SYSTEMTIME st;
-
- st.wDayOfWeek = 0;
- st.wYear = (WORD) getYear();
- st.wMonth = (WORD) (getMonth() + 1);
- st.wDay = (WORD) getDayOfMonth();
- st.wHour = (WORD) getHours();
- st.wMinute = (WORD) getMinutes();
- st.wSecond = (WORD) getSeconds();
- st.wMilliseconds = (WORD) (millisSinceEpoch % 1000);
-
- // do this twice because of daylight saving conversion problems - the
- // first one sets it up, the second one kicks it in.
- return SetLocalTime (&st) != 0
- && SetLocalTime (&st) != 0;
- }
-
- int SystemStats::getPageSize() throw()
- {
- SYSTEM_INFO systemInfo;
- GetSystemInfo (&systemInfo);
-
- return systemInfo.dwPageSize;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_win32_SystemStats.cpp *********/
-
- /********* Start of inlined file: juce_win32_Threads.cpp *********/
-
- #ifdef _MSC_VER
- #pragma warning (disable: 4514)
- #pragma warning (push)
- #include <crtdbg.h>
- #endif
-
- #include <process.h>
-
- BEGIN_JUCE_NAMESPACE
-
- #if ! JUCE_ONLY_BUILD_CORE_LIBRARY
- extern HWND juce_messageWindowHandle;
- #endif
-
- #ifdef _MSC_VER
- #pragma warning (pop)
- #endif
-
- CriticalSection::CriticalSection() throw()
- {
- // (just to check the MS haven't changed this structure and broken things...)
- #if _MSC_VER >= 1400
- static_jassert (sizeof (CRITICAL_SECTION) <= sizeof (internal));
- #else
- static_jassert (sizeof (CRITICAL_SECTION) <= 24);
- #endif
-
- InitializeCriticalSection ((CRITICAL_SECTION*) internal);
- }
-
- CriticalSection::~CriticalSection() throw()
- {
- DeleteCriticalSection ((CRITICAL_SECTION*) internal);
- }
-
- void CriticalSection::enter() const throw()
- {
- EnterCriticalSection ((CRITICAL_SECTION*) internal);
- }
-
- bool CriticalSection::tryEnter() const throw()
- {
- return TryEnterCriticalSection ((CRITICAL_SECTION*) internal) != FALSE;
- }
-
- void CriticalSection::exit() const throw()
- {
- LeaveCriticalSection ((CRITICAL_SECTION*) internal);
- }
-
- WaitableEvent::WaitableEvent() throw()
- : internal (CreateEvent (0, FALSE, FALSE, 0))
- {
- }
-
- WaitableEvent::~WaitableEvent() throw()
- {
- CloseHandle (internal);
- }
-
- bool WaitableEvent::wait (const int timeOutMillisecs) const throw()
- {
- return WaitForSingleObject (internal, timeOutMillisecs) == WAIT_OBJECT_0;
- }
-
- void WaitableEvent::signal() const throw()
- {
- SetEvent (internal);
- }
-
- void WaitableEvent::reset() const throw()
- {
- ResetEvent (internal);
- }
-
- void JUCE_API juce_threadEntryPoint (void*);
-
- static unsigned int __stdcall threadEntryProc (void* userData) throw()
- {
- #if ! JUCE_ONLY_BUILD_CORE_LIBRARY
- AttachThreadInput (GetWindowThreadProcessId (juce_messageWindowHandle, 0),
- GetCurrentThreadId(), TRUE);
- #endif
-
- juce_threadEntryPoint (userData);
-
- _endthreadex(0);
- return 0;
- }
-
- void juce_CloseThreadHandle (void* handle) throw()
- {
- CloseHandle ((HANDLE) handle);
- }
-
- void* juce_createThread (void* userData) throw()
- {
- unsigned int threadId;
-
- return (void*) _beginthreadex (0, 0,
- &threadEntryProc,
- userData,
- 0, &threadId);
- }
-
- void juce_killThread (void* handle) throw()
- {
- if (handle != 0)
- {
- #ifdef JUCE_DEBUG
- OutputDebugString (_T("** Warning - Forced thread termination **\n"));
- #endif
- TerminateThread (handle, 0);
- }
- }
-
- void juce_setCurrentThreadName (const String& name) throw()
- {
- #if defined (JUCE_DEBUG) && JUCE_MSVC
- struct
- {
- DWORD dwType;
- LPCSTR szName;
- DWORD dwThreadID;
- DWORD dwFlags;
- } info;
-
- info.dwType = 0x1000;
- info.szName = name;
- info.dwThreadID = GetCurrentThreadId();
- info.dwFlags = 0;
-
- #define MS_VC_EXCEPTION 0x406d1388
-
- __try
- {
- RaiseException (MS_VC_EXCEPTION, 0, sizeof (info) / sizeof (ULONG_PTR), (ULONG_PTR*) &info);
- }
- __except (EXCEPTION_CONTINUE_EXECUTION)
- {}
- #else
- (void) name;
- #endif
- }
-
- int Thread::getCurrentThreadId() throw()
- {
- return (int) GetCurrentThreadId();
- }
-
- // priority 1 to 10 where 5=normal, 1=low
- void juce_setThreadPriority (void* threadHandle, int priority) throw()
- {
- int pri = THREAD_PRIORITY_TIME_CRITICAL;
-
- if (priority < 1)
- pri = THREAD_PRIORITY_IDLE;
- else if (priority < 2)
- pri = THREAD_PRIORITY_LOWEST;
- else if (priority < 5)
- pri = THREAD_PRIORITY_BELOW_NORMAL;
- else if (priority < 7)
- pri = THREAD_PRIORITY_NORMAL;
- else if (priority < 9)
- pri = THREAD_PRIORITY_ABOVE_NORMAL;
- else if (priority < 10)
- pri = THREAD_PRIORITY_HIGHEST;
-
- if (threadHandle == 0)
- threadHandle = GetCurrentThread();
-
- SetThreadPriority (threadHandle, pri);
- }
-
- void Thread::setCurrentThreadAffinityMask (const uint32 affinityMask) throw()
- {
- SetThreadAffinityMask (GetCurrentThread(), affinityMask);
- }
-
- static HANDLE sleepEvent = 0;
-
- void juce_initialiseThreadEvents() throw()
- {
- if (sleepEvent == 0)
- #ifdef JUCE_DEBUG
- sleepEvent = CreateEvent (0, 0, 0, _T("Juce Sleep Event"));
- #else
- sleepEvent = CreateEvent (0, 0, 0, 0);
- #endif
- }
-
- void Thread::yield() throw()
- {
- Sleep (0);
- }
-
- void JUCE_CALLTYPE Thread::sleep (const int millisecs) throw()
- {
- if (millisecs >= 10)
- {
- Sleep (millisecs);
- }
- else
- {
- jassert (sleepEvent != 0);
-
- // unlike Sleep() this is guaranteed to return to the current thread after
- // the time expires, so we'll use this for short waits, which are more likely
- // to need to be accurate
- WaitForSingleObject (sleepEvent, millisecs);
- }
- }
-
- static int lastProcessPriority = -1;
-
- // called by WindowDriver because Windows does wierd things to process priority
- // when you swap apps, and this forces an update when the app is brought to the front.
- void juce_repeatLastProcessPriority() throw()
- {
- if (lastProcessPriority >= 0) // (avoid changing this if it's not been explicitly set by the app..)
- {
- DWORD p;
-
- switch (lastProcessPriority)
- {
- case Process::LowPriority:
- p = IDLE_PRIORITY_CLASS;
- break;
-
- case Process::NormalPriority:
- p = NORMAL_PRIORITY_CLASS;
- break;
-
- case Process::HighPriority:
- p = HIGH_PRIORITY_CLASS;
- break;
-
- case Process::RealtimePriority:
- p = REALTIME_PRIORITY_CLASS;
- break;
-
- default:
- jassertfalse // bad priority value
- return;
- }
-
- SetPriorityClass (GetCurrentProcess(), p);
- }
- }
-
- void Process::setPriority (ProcessPriority prior)
- {
- if (lastProcessPriority != (int) prior)
- {
- lastProcessPriority = (int) prior;
- juce_repeatLastProcessPriority();
- }
- }
-
- bool JUCE_API JUCE_CALLTYPE juce_isRunningUnderDebugger() throw()
- {
- return IsDebuggerPresent() != FALSE;
- }
-
- bool JUCE_CALLTYPE Process::isRunningUnderDebugger() throw()
- {
- return juce_isRunningUnderDebugger();
- }
-
- void Process::raisePrivilege()
- {
- jassertfalse // xxx not implemented
- }
-
- void Process::lowerPrivilege()
- {
- jassertfalse // xxx not implemented
- }
-
- void Process::terminate()
- {
- #if defined (JUCE_DEBUG) && JUCE_MSVC && JUCE_CHECK_MEMORY_LEAKS
- _CrtDumpMemoryLeaks();
- #endif
-
- // bullet in the head in case there's a problem shutting down..
- ExitProcess (0);
- }
-
- void* Process::loadDynamicLibrary (const String& name)
- {
- void* result = 0;
-
- JUCE_TRY
- {
- result = (void*) LoadLibrary (name);
- }
- JUCE_CATCH_ALL
-
- return result;
- }
-
- void Process::freeDynamicLibrary (void* h)
- {
- JUCE_TRY
- {
- if (h != 0)
- FreeLibrary ((HMODULE) h);
- }
- JUCE_CATCH_ALL
- }
-
- void* Process::getProcedureEntryPoint (void* h, const String& name)
- {
- return (h != 0) ? (void*) GetProcAddress ((HMODULE) h, name)
- : 0;
- }
-
- InterProcessLock::InterProcessLock (const String& name_) throw()
- : internal (0),
- name (name_),
- reentrancyLevel (0)
- {
- }
-
- InterProcessLock::~InterProcessLock() throw()
- {
- exit();
- }
-
- bool InterProcessLock::enter (const int timeOutMillisecs) throw()
- {
- if (reentrancyLevel++ == 0)
- {
- internal = CreateMutex (0, TRUE, name);
-
- if (internal != 0 && GetLastError() == ERROR_ALREADY_EXISTS)
- {
- if (timeOutMillisecs == 0
- || WaitForSingleObject (internal, (timeOutMillisecs < 0) ? INFINITE : timeOutMillisecs)
- == WAIT_TIMEOUT)
- {
- ReleaseMutex (internal);
- CloseHandle (internal);
- internal = 0;
- }
- }
- }
-
- return (internal != 0);
- }
-
- void InterProcessLock::exit() throw()
- {
- if (--reentrancyLevel == 0 && internal != 0)
- {
- ReleaseMutex (internal);
- CloseHandle (internal);
- internal = 0;
- }
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_win32_Threads.cpp *********/
-
- /********* Start of inlined file: juce_win32_DynamicLibraryLoader.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- DynamicLibraryLoader::DynamicLibraryLoader (const String& name)
- {
- libHandle = LoadLibrary (name);
- }
-
- DynamicLibraryLoader::~DynamicLibraryLoader()
- {
- FreeLibrary ((HMODULE) libHandle);
- }
-
- void* DynamicLibraryLoader::findProcAddress (const String& functionName)
- {
- return (void*) GetProcAddress ((HMODULE) libHandle, functionName);
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_win32_DynamicLibraryLoader.cpp *********/
-
- #if ! JUCE_ONLY_BUILD_CORE_LIBRARY
-
- /********* Start of inlined file: juce_win32_ASIO.cpp *********/
-
- #undef WINDOWS
-
- #if JUCE_ASIO
-
- /*
- This is very frustrating - we only need to use a handful of definitions from
- a couple of the header files in Steinberg's ASIO SDK, and it'd be easy to copy
- about 30 lines of code into this cpp file to create a fully stand-alone ASIO
- implementation...
-
- ..unfortunately that would break Steinberg's license agreement for use of
- their SDK, so I'm not allowed to do this.
-
- This means that anyone who wants to use JUCE's ASIO abilities will have to:
-
- 1) Agree to Steinberg's licensing terms and download the ASIO SDK
- (see www.steinberg.net/Steinberg/Developers.asp).
-
- 2) Rebuild the whole of JUCE, setting the global definition JUCE_ASIO (you
- can un-comment the "#define JUCE_ASIO" line in juce_Config.h
- if you prefer). Make sure that your header search path will find the
- iasiodrv.h file that comes with the SDK. (Only about 2-3 of the SDK header
- files are actually needed - so to simplify things, you could just copy
- these into your JUCE directory).
- */
- #include "iasiodrv.h" // if you're compiling and this line causes an error because
- // you don't have the ASIO SDK installed, you can disable ASIO
- // support by commenting-out the "#define JUCE_ASIO" line in
- // juce_Config.h
-
- BEGIN_JUCE_NAMESPACE
-
- // #define ASIO_DEBUGGING
-
- #ifdef ASIO_DEBUGGING
- #define log(a) { Logger::writeToLog (a); DBG (a) }
- #else
- #define log(a) {}
- #endif
-
- #ifdef ASIO_DEBUGGING
- static void logError (const String& context, long error)
- {
- String err ("unknown error");
-
- if (error == ASE_NotPresent)
- err = "Not Present";
- else if (error == ASE_HWMalfunction)
- err = "Hardware Malfunction";
- else if (error == ASE_InvalidParameter)
- err = "Invalid Parameter";
- else if (error == ASE_InvalidMode)
- err = "Invalid Mode";
- else if (error == ASE_SPNotAdvancing)
- err = "Sample position not advancing";
- else if (error == ASE_NoClock)
- err = "No Clock";
- else if (error == ASE_NoMemory)
- err = "Out of memory";
-
- log (T("!!error: ") + context + T(" - ") + err);
- }
- #else
- #define logError(a, b) {}
- #endif
-
- class ASIOAudioIODevice;
- static ASIOAudioIODevice* volatile currentASIODev[3] = { 0, 0, 0 };
-
- static const int maxASIOChannels = 160;
-
- class JUCE_API ASIOAudioIODevice : public AudioIODevice,
- private Timer
- {
- public:
- Component ourWindow;
-
- ASIOAudioIODevice (const String& name_, const CLSID classId_, const int slotNumber)
- : AudioIODevice (name_, T("ASIO")),
- asioObject (0),
- classId (classId_),
- currentBitDepth (16),
- currentSampleRate (0),
- tempBuffer (0),
- isOpen_ (false),
- isStarted (false),
- postOutput (true),
- insideControlPanelModalLoop (false),
- shouldUsePreferredSize (false)
- {
- name = name_;
-
- ourWindow.addToDesktop (0);
- windowHandle = ourWindow.getWindowHandle();
-
- jassert (currentASIODev [slotNumber] == 0);
- currentASIODev [slotNumber] = this;
-
- openDevice();
- }
-
- ~ASIOAudioIODevice()
- {
- for (int i = 0; i < numElementsInArray (currentASIODev); ++i)
- if (currentASIODev[i] == this)
- currentASIODev[i] = 0;
-
- close();
- log ("ASIO - exiting");
- removeCurrentDriver();
-
- juce_free (tempBuffer);
- }
-
- void updateSampleRates()
- {
- // find a list of sample rates..
- const double possibleSampleRates[] = { 44100.0, 48000.0, 88200.0, 96000.0, 176400.0, 192000.0 };
- sampleRates.clear();
-
- if (asioObject != 0)
- {
- for (int index = 0; index < numElementsInArray (possibleSampleRates); ++index)
- {
- const long err = asioObject->canSampleRate (possibleSampleRates[index]);
-
- if (err == 0)
- {
- sampleRates.add ((int) possibleSampleRates[index]);
- log (T("rate: ") + String ((int) possibleSampleRates[index]));
- }
- else if (err != ASE_NoClock)
- {
- logError (T("CanSampleRate"), err);
- }
- }
-
- if (sampleRates.size() == 0)
- {
- double cr = 0;
- const long err = asioObject->getSampleRate (&cr);
- log (T("No sample rates supported - current rate: ") + String ((int) cr));
-
- if (err == 0)
- sampleRates.add ((int) cr);
- }
- }
- }
-
- const StringArray getOutputChannelNames()
- {
- return outputChannelNames;
- }
-
- const StringArray getInputChannelNames()
- {
- return inputChannelNames;
- }
-
- int getNumSampleRates()
- {
- return sampleRates.size();
- }
-
- double getSampleRate (int index)
- {
- return sampleRates [index];
- }
-
- int getNumBufferSizesAvailable()
- {
- return bufferSizes.size();
- }
-
- int getBufferSizeSamples (int index)
- {
- return bufferSizes [index];
- }
-
- int getDefaultBufferSize()
- {
- return preferredSize;
- }
-
- const String open (const BitArray& inputChannels,
- const BitArray& outputChannels,
- double sr,
- int bufferSizeSamples)
- {
- close();
- currentCallback = 0;
-
- if (bufferSizeSamples <= 0)
- shouldUsePreferredSize = true;
-
- if (asioObject == 0 || ! isASIOOpen)
- {
- log ("Warning: device not open");
- const String err (openDevice());
-
- if (asioObject == 0 || ! isASIOOpen)
- return err;
- }
-
- isStarted = false;
- bufferIndex = -1;
- long err = 0;
-
- long newPreferredSize = 0;
-
- // if the preferred size has just changed, assume it's a control panel thing and use it as the new value.
- minSize = 0;
- maxSize = 0;
- newPreferredSize = 0;
- granularity = 0;
-
- if (asioObject->getBufferSize (&minSize, &maxSize, &newPreferredSize, &granularity) == 0)
- {
- if (preferredSize != 0 && newPreferredSize != 0 && newPreferredSize != preferredSize)
- shouldUsePreferredSize = true;
-
- preferredSize = newPreferredSize;
- }
-
- // unfortunate workaround for certain manufacturers whose drivers crash horribly if you make
- // dynamic changes to the buffer size...
- shouldUsePreferredSize = shouldUsePreferredSize
- || getName().containsIgnoreCase (T("Digidesign"));
-
- if (shouldUsePreferredSize)
- {
- log ("Using preferred size for buffer..");
-
- if ((err = asioObject->getBufferSize (&minSize, &maxSize, &preferredSize, &granularity)) == 0)
- {
- bufferSizeSamples = preferredSize;
- }
- else
- {
- bufferSizeSamples = 1024;
- logError ("GetBufferSize1", err);
- }
-
- shouldUsePreferredSize = false;
- }
-
- int sampleRate = roundDoubleToInt (sr);
- currentSampleRate = sampleRate;
- currentBlockSizeSamples = bufferSizeSamples;
- currentChansOut.clear();
- currentChansIn.clear();
- zeromem (inBuffers, sizeof (inBuffers));
- zeromem (outBuffers, sizeof (outBuffers));
-
- updateSampleRates();
-
- if (sampleRate == 0 || (sampleRates.size() > 0 && ! sampleRates.contains (sampleRate)))
- sampleRate = sampleRates[0];
-
- jassert (sampleRate != 0);
- if (sampleRate == 0)
- sampleRate = 44100;
-
- long numSources = 32;
- ASIOClockSource clocks[32];
- zeromem (clocks, sizeof (clocks));
- asioObject->getClockSources (clocks, &numSources);
- bool isSourceSet = false;
-
- // careful not to remove this loop because it does more than just logging!
- int i;
- for (i = 0; i < numSources; ++i)
- {
- String s ("clock: ");
- s += clocks[i].name;
-
- if (clocks[i].isCurrentSource)
- {
- isSourceSet = true;
- s << " (cur)";
- }
-
- log (s);
- }
-
- if (numSources > 1 && ! isSourceSet)
- {
- log ("setting clock source");
- asioObject->setClockSource (clocks[0].index);
- Thread::sleep (20);
- }
- else
- {
- if (numSources == 0)
- {
- log ("ASIO - no clock sources!");
- }
- }
-
- double cr = 0;
- err = asioObject->getSampleRate (&cr);
- if (err == 0)
- {
- currentSampleRate = cr;
- }
- else
- {
- logError ("GetSampleRate", err);
- currentSampleRate = 0;
- }
-
- error = String::empty;
- needToReset = false;
- isReSync = false;
- err = 0;
- bool buffersCreated = false;
-
- if (currentSampleRate != sampleRate)
- {
- log (T("ASIO samplerate: ") + String (currentSampleRate) + T(" to ") + String (sampleRate));
- err = asioObject->setSampleRate (sampleRate);
-
- if (err == ASE_NoClock && numSources > 0)
- {
- log ("trying to set a clock source..");
- Thread::sleep (10);
- err = asioObject->setClockSource (clocks[0].index);
- if (err != 0)
- {
- logError ("SetClock", err);
- }
-
- Thread::sleep (10);
- err = asioObject->setSampleRate (sampleRate);
- }
- }
-
- if (err == 0)
- {
- currentSampleRate = sampleRate;
-
- if (needToReset)
- {
- if (isReSync)
- {
- log ("Resync request");
- }
-
- log ("! Resetting ASIO after sample rate change");
- removeCurrentDriver();
-
- loadDriver();
- const String error (initDriver());
-
- if (error.isNotEmpty())
- {
- log (T("ASIOInit: ") + error);
- }
-
- needToReset = false;
- isReSync = false;
- }
-
- numActiveInputChans = 0;
- numActiveOutputChans = 0;
-
- ASIOBufferInfo* info = bufferInfos;
- int i;
- for (i = 0; i < totalNumInputChans; ++i)
- {
- if (inputChannels[i])
- {
- currentChansIn.setBit (i);
- info->isInput = 1;
- info->channelNum = i;
- info->buffers[0] = info->buffers[1] = 0;
- ++info;
- ++numActiveInputChans;
- }
- }
-
- for (i = 0; i < totalNumOutputChans; ++i)
- {
- if (outputChannels[i])
- {
- currentChansOut.setBit (i);
- info->isInput = 0;
- info->channelNum = i;
- info->buffers[0] = info->buffers[1] = 0;
- ++info;
- ++numActiveOutputChans;
- }
- }
-
- const int totalBuffers = numActiveInputChans + numActiveOutputChans;
-
- callbacks.sampleRateDidChange = &sampleRateChangedCallback;
-
- if (currentASIODev[0] == this)
- {
- callbacks.bufferSwitch = &bufferSwitchCallback0;
- callbacks.asioMessage = &asioMessagesCallback0;
- callbacks.bufferSwitchTimeInfo = &bufferSwitchTimeInfoCallback0;
- }
- else if (currentASIODev[1] == this)
- {
- callbacks.bufferSwitch = &bufferSwitchCallback1;
- callbacks.asioMessage = &asioMessagesCallback1;
- callbacks.bufferSwitchTimeInfo = &bufferSwitchTimeInfoCallback1;
- }
- else if (currentASIODev[2] == this)
- {
- callbacks.bufferSwitch = &bufferSwitchCallback2;
- callbacks.asioMessage = &asioMessagesCallback2;
- callbacks.bufferSwitchTimeInfo = &bufferSwitchTimeInfoCallback2;
- }
- else
- {
- jassertfalse
- }
-
- log ("disposing buffers");
- err = asioObject->disposeBuffers();
-
- log (T("creating buffers: ") + String (totalBuffers) + T(", ") + String (currentBlockSizeSamples));
- err = asioObject->createBuffers (bufferInfos,
- totalBuffers,
- currentBlockSizeSamples,
- &callbacks);
-
- if (err != 0)
- {
- currentBlockSizeSamples = preferredSize;
- logError ("create buffers 2", err);
-
- asioObject->disposeBuffers();
- err = asioObject->createBuffers (bufferInfos,
- totalBuffers,
- currentBlockSizeSamples,
- &callbacks);
- }
-
- if (err == 0)
- {
- buffersCreated = true;
-
- juce_free (tempBuffer);
-
- tempBuffer = (float*) juce_calloc (totalBuffers * currentBlockSizeSamples * sizeof (float) + 128);
-
- int n = 0;
- Array <int> types;
- currentBitDepth = 16;
-
- for (i = 0; i < jmin (totalNumInputChans, maxASIOChannels); ++i)
- {
- if (inputChannels[i])
- {
- inBuffers[n] = tempBuffer + (currentBlockSizeSamples * n);
-
- ASIOChannelInfo channelInfo;
- zerostruct (channelInfo);
-
- channelInfo.channel = i;
- channelInfo.isInput = 1;
- asioObject->getChannelInfo (&channelInfo);
-
- types.addIfNotAlreadyThere (channelInfo.type);
- typeToFormatParameters (channelInfo.type,
- inputChannelBitDepths[n],
- inputChannelBytesPerSample[n],
- inputChannelIsFloat[n],
- inputChannelLittleEndian[n]);
-
- currentBitDepth = jmax (currentBitDepth, inputChannelBitDepths[n]);
-
- ++n;
- }
- }
-
- jassert (numActiveInputChans == n);
- n = 0;
-
- for (i = 0; i < jmin (totalNumOutputChans, maxASIOChannels); ++i)
- {
- if (outputChannels[i])
- {
- outBuffers[n] = tempBuffer + (currentBlockSizeSamples * (numActiveInputChans + n));
-
- ASIOChannelInfo channelInfo;
- zerostruct (channelInfo);
-
- channelInfo.channel = i;
- channelInfo.isInput = 0;
- asioObject->getChannelInfo (&channelInfo);
-
- types.addIfNotAlreadyThere (channelInfo.type);
- typeToFormatParameters (channelInfo.type,
- outputChannelBitDepths[n],
- outputChannelBytesPerSample[n],
- outputChannelIsFloat[n],
- outputChannelLittleEndian[n]);
-
- currentBitDepth = jmax (currentBitDepth, outputChannelBitDepths[n]);
-
- ++n;
- }
- }
-
- jassert (numActiveOutputChans == n);
-
- for (i = types.size(); --i >= 0;)
- {
- log (T("channel format: ") + String (types[i]));
- }
-
- jassert (n <= totalBuffers);
-
- for (i = 0; i < numActiveOutputChans; ++i)
- {
- const int size = currentBlockSizeSamples * (outputChannelBitDepths[i] >> 3);
-
- if (bufferInfos [numActiveInputChans + i].buffers[0] == 0
- || bufferInfos [numActiveInputChans + i].buffers[1] == 0)
- {
- log ("!! Null buffers");
- }
- else
- {
- zeromem (bufferInfos[numActiveInputChans + i].buffers[0], size);
- zeromem (bufferInfos[numActiveInputChans + i].buffers[1], size);
- }
- }
-
- inputLatency = outputLatency = 0;
-
- if (asioObject->getLatencies (&inputLatency, &outputLatency) != 0)
- {
- log ("ASIO - no latencies");
- }
- else
- {
- log (T("ASIO latencies: ")
- + String ((int) outputLatency)
- + T(", ")
- + String ((int) inputLatency));
- }
-
- isOpen_ = true;
-
- log ("starting ASIO");
- calledback = false;
- err = asioObject->start();
-
- if (err != 0)
- {
- isOpen_ = false;
- log ("ASIO - stop on failure");
- Thread::sleep (10);
- asioObject->stop();
- error = "Can't start device";
- Thread::sleep (10);
- }
- else
- {
- int count = 300;
- while (--count > 0 && ! calledback)
- Thread::sleep (10);
-
- isStarted = true;
-
- if (! calledback)
- {
- error = "Device didn't start correctly";
- log ("ASIO didn't callback - stopping..");
- asioObject->stop();
- }
- }
- }
- else
- {
- error = "Can't create i/o buffers";
- }
- }
- else
- {
- error = "Can't set sample rate: ";
- error << sampleRate;
- }
-
- if (error.isNotEmpty())
- {
- logError (error, err);
-
- if (asioObject != 0 && buffersCreated)
- asioObject->disposeBuffers();
-
- Thread::sleep (20);
- isStarted = false;
- isOpen_ = false;
- close();
- }
-
- needToReset = false;
- isReSync = false;
-
- return error;
- }
-
- void close()
- {
- error = String::empty;
- stopTimer();
- stop();
-
- if (isASIOOpen && isOpen_)
- {
- const ScopedLock sl (callbackLock);
-
- isOpen_ = false;
- isStarted = false;
- needToReset = false;
- isReSync = false;
-
- log ("ASIO - stopping");
-
- if (asioObject != 0)
- {
- Thread::sleep (20);
- asioObject->stop();
- Thread::sleep (10);
- asioObject->disposeBuffers();
- }
-
- Thread::sleep (10);
- }
- }
-
- bool isOpen()
- {
- return isOpen_ || insideControlPanelModalLoop;
- }
-
- int getCurrentBufferSizeSamples()
- {
- return currentBlockSizeSamples;
- }
-
- double getCurrentSampleRate()
- {
- return currentSampleRate;
- }
-
- const BitArray getActiveOutputChannels() const
- {
- return currentChansOut;
- }
-
- const BitArray getActiveInputChannels() const
- {
- return currentChansIn;
- }
-
- int getCurrentBitDepth()
- {
- return currentBitDepth;
- }
-
- int getOutputLatencyInSamples()
- {
- return outputLatency + currentBlockSizeSamples / 4;
- }
-
- int getInputLatencyInSamples()
- {
- return inputLatency + currentBlockSizeSamples / 4;
- }
-
- void start (AudioIODeviceCallback* callback)
- {
- if (callback != 0)
- {
- callback->audioDeviceAboutToStart (this);
-
- const ScopedLock sl (callbackLock);
- currentCallback = callback;
- }
- }
-
- void stop()
- {
- AudioIODeviceCallback* const lastCallback = currentCallback;
-
- {
- const ScopedLock sl (callbackLock);
- currentCallback = 0;
- }
-
- if (lastCallback != 0)
- lastCallback->audioDeviceStopped();
- }
-
- bool isPlaying()
- {
- return isASIOOpen && (currentCallback != 0);
- }
-
- const String getLastError()
- {
- return error;
- }
-
- bool hasControlPanel() const
- {
- return true;
- }
-
- bool showControlPanel()
- {
- log ("ASIO - showing control panel");
-
- Component modalWindow (String::empty);
- modalWindow.setOpaque (true);
- modalWindow.addToDesktop (0);
- modalWindow.enterModalState();
- bool done = false;
-
- JUCE_TRY
- {
- close();
- insideControlPanelModalLoop = true;
-
- const uint32 started = Time::getMillisecondCounter();
-
- if (asioObject != 0)
- {
- asioObject->controlPanel();
-
- const int spent = (int) Time::getMillisecondCounter() - (int) started;
-
- log (T("spent: ") + String (spent));
-
- if (spent > 300)
- {
- shouldUsePreferredSize = true;
- done = true;
- }
- }
- }
- JUCE_CATCH_ALL
-
- insideControlPanelModalLoop = false;
- return done;
- }
-
- void resetRequest() throw()
- {
- needToReset = true;
- }
-
- void resyncRequest() throw()
- {
- needToReset = true;
- isReSync = true;
- }
-
- void timerCallback()
- {
- if (! insideControlPanelModalLoop)
- {
- stopTimer();
-
- // used to cause a reset
- log ("! ASIO restart request!");
-
- if (isOpen_)
- {
- AudioIODeviceCallback* const oldCallback = currentCallback;
-
- close();
- open (currentChansIn, currentChansOut,
- currentSampleRate, currentBlockSizeSamples);
-
- if (oldCallback != 0)
- start (oldCallback);
- }
- }
- else
- {
- startTimer (100);
- }
- }
-
- juce_UseDebuggingNewOperator
-
- private:
-
- IASIO* volatile asioObject;
- ASIOCallbacks callbacks;
-
- void* windowHandle;
- CLSID classId;
- String error;
-
- long totalNumInputChans, totalNumOutputChans;
- StringArray inputChannelNames, outputChannelNames;
-
- Array<int> sampleRates, bufferSizes;
- long inputLatency, outputLatency;
- long minSize, maxSize, preferredSize, granularity;
-
- int volatile currentBlockSizeSamples;
- int volatile currentBitDepth;
- double volatile currentSampleRate;
- BitArray currentChansOut, currentChansIn;
- AudioIODeviceCallback* volatile currentCallback;
- CriticalSection callbackLock;
-
- ASIOBufferInfo bufferInfos [maxASIOChannels];
- float* inBuffers [maxASIOChannels];
- float* outBuffers [maxASIOChannels];
-
- int inputChannelBitDepths [maxASIOChannels];
- int outputChannelBitDepths [maxASIOChannels];
- int inputChannelBytesPerSample [maxASIOChannels];
- int outputChannelBytesPerSample [maxASIOChannels];
- bool inputChannelIsFloat [maxASIOChannels];
- bool outputChannelIsFloat [maxASIOChannels];
- bool inputChannelLittleEndian [maxASIOChannels];
- bool outputChannelLittleEndian [maxASIOChannels];
-
- WaitableEvent event1;
- float* tempBuffer;
- int volatile bufferIndex, numActiveInputChans, numActiveOutputChans;
-
- bool isOpen_, isStarted;
- bool volatile isASIOOpen;
- bool volatile calledback;
- bool volatile littleEndian, postOutput, needToReset, isReSync;
- bool volatile insideControlPanelModalLoop;
- bool volatile shouldUsePreferredSize;
-
- void removeCurrentDriver()
- {
- if (asioObject != 0)
- {
- asioObject->Release();
- asioObject = 0;
- }
- }
-
- bool loadDriver()
- {
- removeCurrentDriver();
-
- JUCE_TRY
- {
- if (CoCreateInstance (classId, 0, CLSCTX_INPROC_SERVER,
- classId, (void**) &asioObject) == S_OK)
- {
- return true;
- }
- }
- JUCE_CATCH_ALL
-
- asioObject = 0;
-
- return false;
- }
-
- const String initDriver()
- {
- if (asioObject != 0)
- {
- char buffer [256];
- zeromem (buffer, sizeof (buffer));
-
- if (! asioObject->init (windowHandle))
- {
- asioObject->getErrorMessage (buffer);
- return String (buffer, sizeof (buffer) - 1);
- }
-
- // just in case any daft drivers expect this to be called..
- asioObject->getDriverName (buffer);
-
- return String::empty;
- }
-
- return "No Driver";
- }
-
- const String openDevice()
- {
- // use this in case the driver starts opening dialog boxes..
- Component modalWindow (String::empty);
- modalWindow.setOpaque (true);
- modalWindow.addToDesktop (0);
- modalWindow.enterModalState();
-
- // open the device and get its info..
- log (T("opening ASIO device: ") + getName());
-
- needToReset = false;
- isReSync = false;
- outputChannelNames.clear();
- inputChannelNames.clear();
- bufferSizes.clear();
- sampleRates.clear();
- isASIOOpen = false;
- isOpen_ = false;
- totalNumInputChans = 0;
- totalNumOutputChans = 0;
- numActiveInputChans = 0;
- numActiveOutputChans = 0;
- currentCallback = 0;
-
- error = String::empty;
-
- if (getName().isEmpty())
- return error;
-
- long err = 0;
-
- if (loadDriver())
- {
- if ((error = initDriver()).isEmpty())
- {
- numActiveInputChans = 0;
- numActiveOutputChans = 0;
- totalNumInputChans = 0;
- totalNumOutputChans = 0;
-
- if (asioObject != 0
- && (err = asioObject->getChannels (&totalNumInputChans, &totalNumOutputChans)) == 0)
- {
- log (String ((int) totalNumInputChans) + T(" in, ") + String ((int) totalNumOutputChans) + T(" out"));
-
- if ((err = asioObject->getBufferSize (&minSize, &maxSize, &preferredSize, &granularity)) == 0)
- {
- // find a list of buffer sizes..
- log (String ((int) minSize) + T(" ") + String ((int) maxSize) + T(" ") + String ((int)preferredSize) + T(" ") + String ((int)granularity));
-
- if (granularity >= 0)
- {
- granularity = jmax (1, (int) granularity);
-
- for (int i = jmax (minSize, (int) granularity); i < jmin (6400, maxSize); i += granularity)
- bufferSizes.addIfNotAlreadyThere (granularity * (i / granularity));
- }
- else if (granularity < 0)
- {
- for (int i = 0; i < 18; ++i)
- {
- const int s = (1 << i);
-
- if (s >= minSize && s <= maxSize)
- bufferSizes.add (s);
- }
- }
-
- if (! bufferSizes.contains (preferredSize))
- bufferSizes.insert (0, preferredSize);
-
- double currentRate = 0;
- asioObject->getSampleRate (¤tRate);
-
- if (currentRate <= 0.0 || currentRate > 192001.0)
- {
- log ("setting sample rate");
- err = asioObject->setSampleRate (44100.0);
- if (err != 0)
- {
- logError ("setting sample rate", err);
- }
-
- asioObject->getSampleRate (¤tRate);
- }
-
- currentSampleRate = currentRate;
-
- postOutput = (asioObject->outputReady() == 0);
- if (postOutput)
- {
- log ("ASIO outputReady = ok");
- }
-
- updateSampleRates();
-
- // ..because cubase does it at this point
- inputLatency = outputLatency = 0;
- if (asioObject->getLatencies (&inputLatency, &outputLatency) != 0)
- {
- log ("ASIO - no latencies");
- }
-
- log (String ("latencies: ")
- + String ((int) inputLatency)
- + T(", ") + String ((int) outputLatency));
-
- // create some dummy buffers now.. because cubase does..
- numActiveInputChans = 0;
- numActiveOutputChans = 0;
-
- ASIOBufferInfo* info = bufferInfos;
- int i, numChans = 0;
- for (i = 0; i < jmin (2, totalNumInputChans); ++i)
- {
- info->isInput = 1;
- info->channelNum = i;
- info->buffers[0] = info->buffers[1] = 0;
- ++info;
- ++numChans;
- }
-
- const int outputBufferIndex = numChans;
-
- for (i = 0; i < jmin (2, totalNumOutputChans); ++i)
- {
- info->isInput = 0;
- info->channelNum = i;
- info->buffers[0] = info->buffers[1] = 0;
- ++info;
- ++numChans;
- }
-
- callbacks.sampleRateDidChange = &sampleRateChangedCallback;
-
- if (currentASIODev[0] == this)
- {
- callbacks.bufferSwitch = &bufferSwitchCallback0;
- callbacks.asioMessage = &asioMessagesCallback0;
- callbacks.bufferSwitchTimeInfo = &bufferSwitchTimeInfoCallback0;
- }
- else if (currentASIODev[1] == this)
- {
- callbacks.bufferSwitch = &bufferSwitchCallback1;
- callbacks.asioMessage = &asioMessagesCallback1;
- callbacks.bufferSwitchTimeInfo = &bufferSwitchTimeInfoCallback1;
- }
- else if (currentASIODev[2] == this)
- {
- callbacks.bufferSwitch = &bufferSwitchCallback2;
- callbacks.asioMessage = &asioMessagesCallback2;
- callbacks.bufferSwitchTimeInfo = &bufferSwitchTimeInfoCallback2;
- }
- else
- {
- jassertfalse
- }
-
- log (T("creating buffers (dummy): ") + String (numChans)
- + T(", ") + String ((int) preferredSize));
-
- if (preferredSize > 0)
- {
- err = asioObject->createBuffers (bufferInfos, numChans, preferredSize, &callbacks);
- if (err != 0)
- {
- logError ("dummy buffers", err);
- }
- }
-
- long newInps = 0, newOuts = 0;
- asioObject->getChannels (&newInps, &newOuts);
-
- if (totalNumInputChans != newInps || totalNumOutputChans != newOuts)
- {
- totalNumInputChans = newInps;
- totalNumOutputChans = newOuts;
-
- log (String ((int) totalNumInputChans) + T(" in; ")
- + String ((int) totalNumOutputChans) + T(" out"));
- }
-
- updateSampleRates();
-
- ASIOChannelInfo channelInfo;
- channelInfo.type = 0;
-
- for (i = 0; i < totalNumInputChans; ++i)
- {
- zerostruct (channelInfo);
- channelInfo.channel = i;
- channelInfo.isInput = 1;
- asioObject->getChannelInfo (&channelInfo);
-
- inputChannelNames.add (String (channelInfo.name));
- }
-
- for (i = 0; i < totalNumOutputChans; ++i)
- {
- zerostruct (channelInfo);
- channelInfo.channel = i;
- channelInfo.isInput = 0;
- asioObject->getChannelInfo (&channelInfo);
-
- outputChannelNames.add (String (channelInfo.name));
-
- typeToFormatParameters (channelInfo.type,
- outputChannelBitDepths[i],
- outputChannelBytesPerSample[i],
- outputChannelIsFloat[i],
- outputChannelLittleEndian[i]);
-
- if (i < 2)
- {
- // clear the channels that are used with the dummy stuff
- const int bytesPerBuffer = preferredSize * (outputChannelBitDepths[i] >> 3);
- zeromem (bufferInfos [outputBufferIndex + i].buffers[0], bytesPerBuffer);
- zeromem (bufferInfos [outputBufferIndex + i].buffers[1], bytesPerBuffer);
- }
- }
-
- outputChannelNames.trim();
- inputChannelNames.trim();
- outputChannelNames.appendNumbersToDuplicates (false, true);
- inputChannelNames.appendNumbersToDuplicates (false, true);
-
- // start and stop because cubase does it..
- asioObject->getLatencies (&inputLatency, &outputLatency);
-
- if ((err = asioObject->start()) != 0)
- {
- // ignore an error here, as it might start later after setting other stuff up
- logError ("ASIO start", err);
- }
-
- Thread::sleep (100);
- asioObject->stop();
- }
- else
- {
- error = "Can't detect buffer sizes";
- }
- }
- else
- {
- error = "Can't detect asio channels";
- }
- }
- }
- else
- {
- error = "No such device";
- }
-
- if (error.isNotEmpty())
- {
- logError (error, err);
-
- if (asioObject != 0)
- asioObject->disposeBuffers();
-
- removeCurrentDriver();
- isASIOOpen = false;
- }
- else
- {
- isASIOOpen = true;
- log ("ASIO device open");
- }
-
- isOpen_ = false;
- needToReset = false;
- isReSync = false;
-
- return error;
- }
-
- void callback (const long index) throw()
- {
- if (isStarted)
- {
- bufferIndex = index;
- processBuffer();
- }
- else
- {
- if (postOutput && (asioObject != 0))
- asioObject->outputReady();
- }
-
- calledback = true;
- }
-
- void processBuffer() throw()
- {
- const ASIOBufferInfo* const infos = bufferInfos;
- const int bi = bufferIndex;
-
- const ScopedLock sl (callbackLock);
-
- if (needToReset)
- {
- needToReset = false;
-
- if (isReSync)
- {
- log ("! ASIO resync");
- isReSync = false;
- }
- else
- {
- startTimer (20);
- }
- }
-
- if (bi >= 0)
- {
- const int samps = currentBlockSizeSamples;
-
- if (currentCallback != 0)
- {
- int i;
- for (i = 0; i < numActiveInputChans; ++i)
- {
- float* const dst = inBuffers[i];
-
- jassert (dst != 0);
-
- const char* const src = (const char*) (infos[i].buffers[bi]);
-
- if (inputChannelIsFloat[i])
- {
- memcpy (dst, src, samps * sizeof (float));
- }
- else
- {
- jassert (dst == tempBuffer + (samps * i));
-
- switch (inputChannelBitDepths[i])
- {
- case 16:
- convertInt16ToFloat (src, dst, inputChannelBytesPerSample[i],
- samps, inputChannelLittleEndian[i]);
- break;
-
- case 24:
- convertInt24ToFloat (src, dst, inputChannelBytesPerSample[i],
- samps, inputChannelLittleEndian[i]);
- break;
-
- case 32:
- convertInt32ToFloat (src, dst, inputChannelBytesPerSample[i],
- samps, inputChannelLittleEndian[i]);
- break;
-
- case 64:
- jassertfalse
- break;
- }
- }
- }
-
- currentCallback->audioDeviceIOCallback ((const float**) inBuffers,
- numActiveInputChans,
- outBuffers,
- numActiveOutputChans,
- samps);
-
- for (i = 0; i < numActiveOutputChans; ++i)
- {
- float* const src = outBuffers[i];
-
- jassert (src != 0);
-
- char* const dst = (char*) (infos [numActiveInputChans + i].buffers[bi]);
-
- if (outputChannelIsFloat[i])
- {
- memcpy (dst, src, samps * sizeof (float));
- }
- else
- {
- jassert (src == tempBuffer + (samps * (numActiveInputChans + i)));
-
- switch (outputChannelBitDepths[i])
- {
- case 16:
- convertFloatToInt16 (src, dst, outputChannelBytesPerSample[i],
- samps, outputChannelLittleEndian[i]);
- break;
-
- case 24:
- convertFloatToInt24 (src, dst, outputChannelBytesPerSample[i],
- samps, outputChannelLittleEndian[i]);
- break;
-
- case 32:
- convertFloatToInt32 (src, dst, outputChannelBytesPerSample[i],
- samps, outputChannelLittleEndian[i]);
- break;
-
- case 64:
- jassertfalse
- break;
- }
- }
- }
- }
- else
- {
- for (int i = 0; i < numActiveOutputChans; ++i)
- {
- const int bytesPerBuffer = samps * (outputChannelBitDepths[i] >> 3);
- zeromem (infos[numActiveInputChans + i].buffers[bi], bytesPerBuffer);
- }
- }
- }
-
- if (postOutput)
- asioObject->outputReady();
- }
-
- static ASIOTime* bufferSwitchTimeInfoCallback0 (ASIOTime*, long index, long) throw()
- {
- if (currentASIODev[0] != 0)
- currentASIODev[0]->callback (index);
-
- return 0;
- }
-
- static ASIOTime* bufferSwitchTimeInfoCallback1 (ASIOTime*, long index, long) throw()
- {
- if (currentASIODev[1] != 0)
- currentASIODev[1]->callback (index);
-
- return 0;
- }
-
- static ASIOTime* bufferSwitchTimeInfoCallback2 (ASIOTime*, long index, long) throw()
- {
- if (currentASIODev[2] != 0)
- currentASIODev[2]->callback (index);
-
- return 0;
- }
-
- static void bufferSwitchCallback0 (long index, long) throw()
- {
- if (currentASIODev[0] != 0)
- currentASIODev[0]->callback (index);
- }
-
- static void bufferSwitchCallback1 (long index, long) throw()
- {
- if (currentASIODev[1] != 0)
- currentASIODev[1]->callback (index);
- }
-
- static void bufferSwitchCallback2 (long index, long) throw()
- {
- if (currentASIODev[2] != 0)
- currentASIODev[2]->callback (index);
- }
-
- static long asioMessagesCallback0 (long selector, long value, void*, double*) throw()
- {
- return asioMessagesCallback (selector, value, 0);
- }
-
- static long asioMessagesCallback1 (long selector, long value, void*, double*) throw()
- {
- return asioMessagesCallback (selector, value, 1);
- }
-
- static long asioMessagesCallback2 (long selector, long value, void*, double*) throw()
- {
- return asioMessagesCallback (selector, value, 2);
- }
-
- static long asioMessagesCallback (long selector, long value, const int deviceIndex) throw()
- {
- switch (selector)
- {
- case kAsioSelectorSupported:
- if (value == kAsioResetRequest
- || value == kAsioEngineVersion
- || value == kAsioResyncRequest
- || value == kAsioLatenciesChanged
- || value == kAsioSupportsInputMonitor)
- return 1;
- break;
-
- case kAsioBufferSizeChange:
- break;
-
- case kAsioResetRequest:
- if (currentASIODev[deviceIndex] != 0)
- currentASIODev[deviceIndex]->resetRequest();
-
- return 1;
-
- case kAsioResyncRequest:
- if (currentASIODev[deviceIndex] != 0)
- currentASIODev[deviceIndex]->resyncRequest();
-
- return 1;
-
- case kAsioLatenciesChanged:
- return 1;
-
- case kAsioEngineVersion:
- return 2;
-
- case kAsioSupportsTimeInfo:
- case kAsioSupportsTimeCode:
- return 0;
- }
-
- return 0;
- }
-
- static void sampleRateChangedCallback (ASIOSampleRate) throw()
- {
- }
-
- static void convertInt16ToFloat (const char* src,
- float* dest,
- const int srcStrideBytes,
- int numSamples,
- const bool littleEndian) throw()
- {
- const double g = 1.0 / 32768.0;
-
- if (littleEndian)
- {
- while (--numSamples >= 0)
- {
- *dest++ = (float) (g * (short) littleEndianShort (src));
- src += srcStrideBytes;
- }
- }
- else
- {
- while (--numSamples >= 0)
- {
- *dest++ = (float) (g * (short) bigEndianShort (src));
- src += srcStrideBytes;
- }
- }
- }
-
- static void convertFloatToInt16 (const float* src,
- char* dest,
- const int dstStrideBytes,
- int numSamples,
- const bool littleEndian) throw()
- {
- const double maxVal = (double) 0x7fff;
-
- if (littleEndian)
- {
- while (--numSamples >= 0)
- {
- *(uint16*) dest = swapIfBigEndian ((uint16) (short) roundDoubleToInt (jlimit (-maxVal, maxVal, maxVal * *src++)));
- dest += dstStrideBytes;
- }
- }
- else
- {
- while (--numSamples >= 0)
- {
- *(uint16*) dest = swapIfLittleEndian ((uint16) (short) roundDoubleToInt (jlimit (-maxVal, maxVal, maxVal * *src++)));
- dest += dstStrideBytes;
- }
- }
- }
-
- static void convertInt24ToFloat (const char* src,
- float* dest,
- const int srcStrideBytes,
- int numSamples,
- const bool littleEndian) throw()
- {
- const double g = 1.0 / 0x7fffff;
-
- if (littleEndian)
- {
- while (--numSamples >= 0)
- {
- *dest++ = (float) (g * littleEndian24Bit (src));
- src += srcStrideBytes;
- }
- }
- else
- {
- while (--numSamples >= 0)
- {
- *dest++ = (float) (g * bigEndian24Bit (src));
- src += srcStrideBytes;
- }
- }
- }
-
- static void convertFloatToInt24 (const float* src,
- char* dest,
- const int dstStrideBytes,
- int numSamples,
- const bool littleEndian) throw()
- {
- const double maxVal = (double) 0x7fffff;
-
- if (littleEndian)
- {
- while (--numSamples >= 0)
- {
- littleEndian24BitToChars ((uint32) roundDoubleToInt (jlimit (-maxVal, maxVal, maxVal * *src++)), dest);
- dest += dstStrideBytes;
- }
- }
- else
- {
- while (--numSamples >= 0)
- {
- bigEndian24BitToChars ((uint32) roundDoubleToInt (jlimit (-maxVal, maxVal, maxVal * *src++)), dest);
- dest += dstStrideBytes;
- }
- }
- }
-
- static void convertInt32ToFloat (const char* src,
- float* dest,
- const int srcStrideBytes,
- int numSamples,
- const bool littleEndian) throw()
- {
- const double g = 1.0 / 0x7fffffff;
-
- if (littleEndian)
- {
- while (--numSamples >= 0)
- {
- *dest++ = (float) (g * (int) littleEndianInt (src));
- src += srcStrideBytes;
- }
- }
- else
- {
- while (--numSamples >= 0)
- {
- *dest++ = (float) (g * (int) bigEndianInt (src));
- src += srcStrideBytes;
- }
- }
- }
-
- static void convertFloatToInt32 (const float* src,
- char* dest,
- const int dstStrideBytes,
- int numSamples,
- const bool littleEndian) throw()
- {
- const double maxVal = (double) 0x7fffffff;
-
- if (littleEndian)
- {
- while (--numSamples >= 0)
- {
- *(uint32*) dest = swapIfBigEndian ((uint32) roundDoubleToInt (jlimit (-maxVal, maxVal, maxVal * *src++)));
- dest += dstStrideBytes;
- }
- }
- else
- {
- while (--numSamples >= 0)
- {
- *(uint32*) dest = swapIfLittleEndian ((uint32) roundDoubleToInt (jlimit (-maxVal, maxVal, maxVal * *src++)));
- dest += dstStrideBytes;
- }
- }
- }
-
- static void typeToFormatParameters (const long type,
- int& bitDepth,
- int& byteStride,
- bool& formatIsFloat,
- bool& littleEndian) throw()
- {
- bitDepth = 0;
- littleEndian = false;
- formatIsFloat = false;
-
- switch (type)
- {
- case ASIOSTInt16MSB:
- case ASIOSTInt16LSB:
- case ASIOSTInt32MSB16:
- case ASIOSTInt32LSB16:
- bitDepth = 16; break;
-
- case ASIOSTFloat32MSB:
- case ASIOSTFloat32LSB:
- formatIsFloat = true;
- bitDepth = 32; break;
-
- case ASIOSTInt32MSB:
- case ASIOSTInt32LSB:
- bitDepth = 32; break;
-
- case ASIOSTInt24MSB:
- case ASIOSTInt24LSB:
- case ASIOSTInt32MSB24:
- case ASIOSTInt32LSB24:
- case ASIOSTInt32MSB18:
- case ASIOSTInt32MSB20:
- case ASIOSTInt32LSB18:
- case ASIOSTInt32LSB20:
- bitDepth = 24; break;
-
- case ASIOSTFloat64MSB:
- case ASIOSTFloat64LSB:
- default:
- bitDepth = 64;
- break;
- }
-
- switch (type)
- {
- case ASIOSTInt16MSB:
- case ASIOSTInt32MSB16:
- case ASIOSTFloat32MSB:
- case ASIOSTFloat64MSB:
- case ASIOSTInt32MSB:
- case ASIOSTInt32MSB18:
- case ASIOSTInt32MSB20:
- case ASIOSTInt32MSB24:
- case ASIOSTInt24MSB:
- littleEndian = false; break;
-
- case ASIOSTInt16LSB:
- case ASIOSTInt32LSB16:
- case ASIOSTFloat32LSB:
- case ASIOSTFloat64LSB:
- case ASIOSTInt32LSB:
- case ASIOSTInt32LSB18:
- case ASIOSTInt32LSB20:
- case ASIOSTInt32LSB24:
- case ASIOSTInt24LSB:
- littleEndian = true; break;
-
- default:
- break;
- }
-
- switch (type)
- {
- case ASIOSTInt16LSB:
- case ASIOSTInt16MSB:
- byteStride = 2; break;
-
- case ASIOSTInt24LSB:
- case ASIOSTInt24MSB:
- byteStride = 3; break;
-
- case ASIOSTInt32MSB16:
- case ASIOSTInt32LSB16:
- case ASIOSTInt32MSB:
- case ASIOSTInt32MSB18:
- case ASIOSTInt32MSB20:
- case ASIOSTInt32MSB24:
- case ASIOSTInt32LSB:
- case ASIOSTInt32LSB18:
- case ASIOSTInt32LSB20:
- case ASIOSTInt32LSB24:
- case ASIOSTFloat32LSB:
- case ASIOSTFloat32MSB:
- byteStride = 4; break;
-
- case ASIOSTFloat64MSB:
- case ASIOSTFloat64LSB:
- byteStride = 8; break;
-
- default:
- break;
- }
- }
- };
-
- class ASIOAudioIODeviceType : public AudioIODeviceType
- {
- public:
- ASIOAudioIODeviceType()
- : AudioIODeviceType (T("ASIO")),
- classIds (2),
- hasScanned (false)
- {
- CoInitialize (0);
- }
-
- ~ASIOAudioIODeviceType()
- {
- }
-
- void scanForDevices()
- {
- hasScanned = true;
-
- deviceNames.clear();
- classIds.clear();
-
- HKEY hk = 0;
- int index = 0;
-
- if (RegOpenKeyA (HKEY_LOCAL_MACHINE, "software\\asio", &hk) == ERROR_SUCCESS)
- {
- for (;;)
- {
- char name [256];
-
- if (RegEnumKeyA (hk, index++, name, 256) == ERROR_SUCCESS)
- {
- addDriverInfo (name, hk);
- }
- else
- {
- break;
- }
- }
-
- RegCloseKey (hk);
- }
- }
-
- const StringArray getDeviceNames (const bool /*wantInputNames*/) const
- {
- jassert (hasScanned); // need to call scanForDevices() before doing this
-
- return deviceNames;
- }
-
- int getDefaultDeviceIndex (const bool) const
- {
- jassert (hasScanned); // need to call scanForDevices() before doing this
-
- for (int i = deviceNames.size(); --i >= 0;)
- if (deviceNames[i].containsIgnoreCase (T("asio4all")))
- return i; // asio4all is a safe choice for a default..
-
- #if JUCE_DEBUG
- if (deviceNames.size() > 1 && deviceNames[0].containsIgnoreCase (T("digidesign")))
- return 1; // (the digi m-box driver crashes the app when you run
- // it in the debugger, which can be a bit annoying)
- #endif
-
- return 0;
- }
-
- static int findFreeSlot()
- {
- for (int i = 0; i < numElementsInArray (currentASIODev); ++i)
- if (currentASIODev[i] == 0)
- return i;
-
- jassertfalse; // unfortunately you can only have a finite number
- // of ASIO devices open at the same time..
- return -1;
- }
-
- int getIndexOfDevice (AudioIODevice* d, const bool /*asInput*/) const
- {
- jassert (hasScanned); // need to call scanForDevices() before doing this
-
- return d == 0 ? -1 : deviceNames.indexOf (d->getName());
- }
-
- bool hasSeparateInputsAndOutputs() const { return false; }
-
- AudioIODevice* createDevice (const String& outputDeviceName,
- const String& inputDeviceName)
- {
- jassert (inputDeviceName == outputDeviceName);
- (void) inputDeviceName;
- jassert (hasScanned); // need to call scanForDevices() before doing this
-
- const int index = deviceNames.indexOf (outputDeviceName);
-
- if (index >= 0)
- {
- const int freeSlot = findFreeSlot();
-
- if (freeSlot >= 0)
- return new ASIOAudioIODevice (outputDeviceName, *(classIds [index]), freeSlot);
- }
-
- return 0;
- }
-
- juce_UseDebuggingNewOperator
-
- private:
- StringArray deviceNames;
- OwnedArray <CLSID> classIds;
-
- bool hasScanned;
-
- static bool checkClassIsOk (const String& classId)
- {
- HKEY hk = 0;
- bool ok = false;
-
- if (RegOpenKeyA (HKEY_CLASSES_ROOT, "clsid", &hk) == ERROR_SUCCESS)
- {
- int index = 0;
-
- for (;;)
- {
- char buf [512];
-
- if (RegEnumKeyA (hk, index++, buf, 512) == ERROR_SUCCESS)
- {
- if (classId.equalsIgnoreCase (buf))
- {
- HKEY subKey, pathKey;
-
- if (RegOpenKeyExA (hk, buf, 0, KEY_READ, &subKey) == ERROR_SUCCESS)
- {
- if (RegOpenKeyExA (subKey, "InprocServer32", 0, KEY_READ, &pathKey) == ERROR_SUCCESS)
- {
- char pathName [600];
- DWORD dtype = REG_SZ;
- DWORD dsize = sizeof (pathName);
-
- if (RegQueryValueExA (pathKey, 0, 0, &dtype,
- (LPBYTE) pathName, &dsize) == ERROR_SUCCESS)
- {
- OFSTRUCT of;
- zerostruct (of);
-
- of.cBytes = sizeof (of);
-
- ok = (OpenFile (String (pathName), &of, OF_EXIST) != 0);
- }
-
- RegCloseKey (pathKey);
- }
-
- RegCloseKey (subKey);
- }
-
- break;
- }
- }
- else
- {
- break;
- }
- }
-
- RegCloseKey (hk);
- }
-
- return ok;
- }
-
- void addDriverInfo (const String& keyName, HKEY hk)
- {
- HKEY subKey;
-
- if (RegOpenKeyExA (hk, keyName, 0, KEY_READ, &subKey) == ERROR_SUCCESS)
- {
- char buf [256];
- DWORD dtype = REG_SZ;
- DWORD dsize = sizeof (buf);
- zeromem (buf, dsize);
-
- if (RegQueryValueExA (subKey, "clsid", 0, &dtype, (LPBYTE) buf, &dsize) == ERROR_SUCCESS)
- {
- if (dsize > 0 && checkClassIsOk (buf))
- {
- wchar_t classIdStr [130];
- MultiByteToWideChar (CP_ACP, 0, buf, -1, classIdStr, 128);
-
- String deviceName;
- CLSID classId;
-
- if (CLSIDFromString ((LPOLESTR) classIdStr, &classId) == S_OK)
- {
- dtype = REG_SZ;
- dsize = sizeof (buf);
-
- if (RegQueryValueExA (subKey, "description", 0, &dtype, (LPBYTE) buf, &dsize) == ERROR_SUCCESS)
- deviceName = buf;
- else
- deviceName = keyName;
-
- log (T("found ") + deviceName);
- deviceNames.add (deviceName);
- classIds.add (new CLSID (classId));
- }
- }
-
- RegCloseKey (subKey);
- }
- }
- }
-
- ASIOAudioIODeviceType (const ASIOAudioIODeviceType&);
- const ASIOAudioIODeviceType& operator= (const ASIOAudioIODeviceType&);
- };
-
- AudioIODeviceType* juce_createASIOAudioIODeviceType()
- {
- return new ASIOAudioIODeviceType();
- }
-
- AudioIODevice* juce_createASIOAudioIODeviceForGUID (const String& name,
- void* guid)
- {
- const int freeSlot = ASIOAudioIODeviceType::findFreeSlot();
-
- if (freeSlot < 0)
- return 0;
-
- return new ASIOAudioIODevice (name, *(CLSID*) guid, freeSlot);
- }
-
- END_JUCE_NAMESPACE
-
- #undef log
-
- #endif
- /********* End of inlined file: juce_win32_ASIO.cpp *********/
-
- /********* Start of inlined file: juce_win32_AudioCDReader.cpp *********/
- #ifdef _MSC_VER
- #pragma warning (disable: 4514)
- #pragma warning (push)
- #endif
-
- #include <stddef.h>
-
- #if JUCE_USE_CDBURNER
- // you'll need the Platform SDK for these headers - if you don't have it and don't
- // need to use CD-burning, then you might just want to disable the JUCE_USE_CDBURNER
- // flag in juce_Config.h to avoid these includes.
- #include <imapi.h>
- #include <imapierror.h>
- #endif
-
- BEGIN_JUCE_NAMESPACE
-
- #ifdef _MSC_VER
- #pragma warning (pop)
- #endif
-
- //***************************************************************************
- // %%% TARGET STATUS VALUES %%%
- //***************************************************************************
- #define STATUS_GOOD 0x00 // Status Good
- #define STATUS_CHKCOND 0x02 // Check Condition
- #define STATUS_CONDMET 0x04 // Condition Met
- #define STATUS_BUSY 0x08 // Busy
- #define STATUS_INTERM 0x10 // Intermediate
- #define STATUS_INTCDMET 0x14 // Intermediate-condition met
- #define STATUS_RESCONF 0x18 // Reservation conflict
- #define STATUS_COMTERM 0x22 // Command Terminated
- #define STATUS_QFULL 0x28 // Queue full
-
- //***************************************************************************
- // %%% SCSI MISCELLANEOUS EQUATES %%%
- //***************************************************************************
- #define MAXLUN 7 // Maximum Logical Unit Id
- #define MAXTARG 7 // Maximum Target Id
- #define MAX_SCSI_LUNS 64 // Maximum Number of SCSI LUNs
- #define MAX_NUM_HA 8 // Maximum Number of SCSI HA's
-
- //***************************************************************************
- // %%% Commands for all Device Types %%%
- //***************************************************************************
- #define SCSI_CHANGE_DEF 0x40 // Change Definition (Optional)
- #define SCSI_COMPARE 0x39 // Compare (O)
- #define SCSI_COPY 0x18 // Copy (O)
- #define SCSI_COP_VERIFY 0x3A // Copy and Verify (O)
- #define SCSI_INQUIRY 0x12 // Inquiry (MANDATORY)
- #define SCSI_LOG_SELECT 0x4C // Log Select (O)
- #define SCSI_LOG_SENSE 0x4D // Log Sense (O)
- #define SCSI_MODE_SEL6 0x15 // Mode Select 6-byte (Device Specific)
- #define SCSI_MODE_SEL10 0x55 // Mode Select 10-byte (Device Specific)
- #define SCSI_MODE_SEN6 0x1A // Mode Sense 6-byte (Device Specific)
- #define SCSI_MODE_SEN10 0x5A // Mode Sense 10-byte (Device Specific)
- #define SCSI_READ_BUFF 0x3C // Read Buffer (O)
- #define SCSI_REQ_SENSE 0x03 // Request Sense (MANDATORY)
- #define SCSI_SEND_DIAG 0x1D // Send Diagnostic (O)
- #define SCSI_TST_U_RDY 0x00 // Test Unit Ready (MANDATORY)
- #define SCSI_WRITE_BUFF 0x3B // Write Buffer (O)
-
- //***************************************************************************
- // %%% Commands Unique to Direct Access Devices %%%
- //***************************************************************************
- #define SCSI_COMPARE 0x39 // Compare (O)
- #define SCSI_FORMAT 0x04 // Format Unit (MANDATORY)
- #define SCSI_LCK_UN_CAC 0x36 // Lock Unlock Cache (O)
- #define SCSI_PREFETCH 0x34 // Prefetch (O)
- #define SCSI_MED_REMOVL 0x1E // Prevent/Allow medium Removal (O)
- #define SCSI_READ6 0x08 // Read 6-byte (MANDATORY)
- #define SCSI_READ10 0x28 // Read 10-byte (MANDATORY)
- #define SCSI_RD_CAPAC 0x25 // Read Capacity (MANDATORY)
- #define SCSI_RD_DEFECT 0x37 // Read Defect Data (O)
- #define SCSI_READ_LONG 0x3E // Read Long (O)
- #define SCSI_REASS_BLK 0x07 // Reassign Blocks (O)
- #define SCSI_RCV_DIAG 0x1C // Receive Diagnostic Results (O)
- #define SCSI_RELEASE 0x17 // Release Unit (MANDATORY)
- #define SCSI_REZERO 0x01 // Rezero Unit (O)
- #define SCSI_SRCH_DAT_E 0x31 // Search Data Equal (O)
- #define SCSI_SRCH_DAT_H 0x30 // Search Data High (O)
- #define SCSI_SRCH_DAT_L 0x32 // Search Data Low (O)
- #define SCSI_SEEK6 0x0B // Seek 6-Byte (O)
- #define SCSI_SEEK10 0x2B // Seek 10-Byte (O)
- #define SCSI_SEND_DIAG 0x1D // Send Diagnostics (MANDATORY)
- #define SCSI_SET_LIMIT 0x33 // Set Limits (O)
- #define SCSI_START_STP 0x1B // Start/Stop Unit (O)
- #define SCSI_SYNC_CACHE 0x35 // Synchronize Cache (O)
- #define SCSI_VERIFY 0x2F // Verify (O)
- #define SCSI_WRITE6 0x0A // Write 6-Byte (MANDATORY)
- #define SCSI_WRITE10 0x2A // Write 10-Byte (MANDATORY)
- #define SCSI_WRT_VERIFY 0x2E // Write and Verify (O)
- #define SCSI_WRITE_LONG 0x3F // Write Long (O)
- #define SCSI_WRITE_SAME 0x41 // Write Same (O)
-
- //***************************************************************************
- // %%% Commands Unique to Sequential Access Devices %%%
- //***************************************************************************
- #define SCSI_ERASE 0x19 // Erase (MANDATORY)
- #define SCSI_LOAD_UN 0x1b // Load/Unload (O)
- #define SCSI_LOCATE 0x2B // Locate (O)
- #define SCSI_RD_BLK_LIM 0x05 // Read Block Limits (MANDATORY)
- #define SCSI_READ_POS 0x34 // Read Position (O)
- #define SCSI_READ_REV 0x0F // Read Reverse (O)
- #define SCSI_REC_BF_DAT 0x14 // Recover Buffer Data (O)
- #define SCSI_RESERVE 0x16 // Reserve Unit (MANDATORY)
- #define SCSI_REWIND 0x01 // Rewind (MANDATORY)
- #define SCSI_SPACE 0x11 // Space (MANDATORY)
- #define SCSI_VERIFY_T 0x13 // Verify (Tape) (O)
- #define SCSI_WRT_FILE 0x10 // Write Filemarks (MANDATORY)
-
- //***************************************************************************
- // %%% Commands Unique to Printer Devices %%%
- //***************************************************************************
- #define SCSI_PRINT 0x0A // Print (MANDATORY)
- #define SCSI_SLEW_PNT 0x0B // Slew and Print (O)
- #define SCSI_STOP_PNT 0x1B // Stop Print (O)
- #define SCSI_SYNC_BUFF 0x10 // Synchronize Buffer (O)
-
- //***************************************************************************
- // %%% Commands Unique to Processor Devices %%%
- //***************************************************************************
- #define SCSI_RECEIVE 0x08 // Receive (O)
- #define SCSI_SEND 0x0A // Send (O)
-
- //***************************************************************************
- // %%% Commands Unique to Write-Once Devices %%%
- //***************************************************************************
- #define SCSI_MEDIUM_SCN 0x38 // Medium Scan (O)
- #define SCSI_SRCHDATE10 0x31 // Search Data Equal 10-Byte (O)
- #define SCSI_SRCHDATE12 0xB1 // Search Data Equal 12-Byte (O)
- #define SCSI_SRCHDATH10 0x30 // Search Data High 10-Byte (O)
- #define SCSI_SRCHDATH12 0xB0 // Search Data High 12-Byte (O)
- #define SCSI_SRCHDATL10 0x32 // Search Data Low 10-Byte (O)
- #define SCSI_SRCHDATL12 0xB2 // Search Data Low 12-Byte (O)
- #define SCSI_SET_LIM_10 0x33 // Set Limits 10-Byte (O)
- #define SCSI_SET_LIM_12 0xB3 // Set Limits 10-Byte (O)
- #define SCSI_VERIFY10 0x2F // Verify 10-Byte (O)
- #define SCSI_VERIFY12 0xAF // Verify 12-Byte (O)
- #define SCSI_WRITE12 0xAA // Write 12-Byte (O)
- #define SCSI_WRT_VER10 0x2E // Write and Verify 10-Byte (O)
- #define SCSI_WRT_VER12 0xAE // Write and Verify 12-Byte (O)
-
- //***************************************************************************
- // %%% Commands Unique to CD-ROM Devices %%%
- //***************************************************************************
- #define SCSI_PLAYAUD_10 0x45 // Play Audio 10-Byte (O)
- #define SCSI_PLAYAUD_12 0xA5 // Play Audio 12-Byte 12-Byte (O)
- #define SCSI_PLAYAUDMSF 0x47 // Play Audio MSF (O)
- #define SCSI_PLAYA_TKIN 0x48 // Play Audio Track/Index (O)
- #define SCSI_PLYTKREL10 0x49 // Play Track Relative 10-Byte (O)
- #define SCSI_PLYTKREL12 0xA9 // Play Track Relative 12-Byte (O)
- #define SCSI_READCDCAP 0x25 // Read CD-ROM Capacity (MANDATORY)
- #define SCSI_READHEADER 0x44 // Read Header (O)
- #define SCSI_SUBCHANNEL 0x42 // Read Subchannel (O)
- #define SCSI_READ_TOC 0x43 // Read TOC (O)
-
- //***************************************************************************
- // %%% Commands Unique to Scanner Devices %%%
- //***************************************************************************
- #define SCSI_GETDBSTAT 0x34 // Get Data Buffer Status (O)
- #define SCSI_GETWINDOW 0x25 // Get Window (O)
- #define SCSI_OBJECTPOS 0x31 // Object Postion (O)
- #define SCSI_SCAN 0x1B // Scan (O)
- #define SCSI_SETWINDOW 0x24 // Set Window (MANDATORY)
-
- //***************************************************************************
- // %%% Commands Unique to Optical Memory Devices %%%
- //***************************************************************************
- #define SCSI_UpdateBlk 0x3D // Update Block (O)
-
- //***************************************************************************
- // %%% Commands Unique to Medium Changer Devices %%%
- //***************************************************************************
- #define SCSI_EXCHMEDIUM 0xA6 // Exchange Medium (O)
- #define SCSI_INITELSTAT 0x07 // Initialize Element Status (O)
- #define SCSI_POSTOELEM 0x2B // Position to Element (O)
- #define SCSI_REQ_VE_ADD 0xB5 // Request Volume Element Address (O)
- #define SCSI_SENDVOLTAG 0xB6 // Send Volume Tag (O)
-
- //***************************************************************************
- // %%% Commands Unique to Communication Devices %%%
- //***************************************************************************
- #define SCSI_GET_MSG_6 0x08 // Get Message 6-Byte (MANDATORY)
- #define SCSI_GET_MSG_10 0x28 // Get Message 10-Byte (O)
- #define SCSI_GET_MSG_12 0xA8 // Get Message 12-Byte (O)
- #define SCSI_SND_MSG_6 0x0A // Send Message 6-Byte (MANDATORY)
- #define SCSI_SND_MSG_10 0x2A // Send Message 10-Byte (O)
- #define SCSI_SND_MSG_12 0xAA // Send Message 12-Byte (O)
-
- //***************************************************************************
- // %%% Request Sense Data Format %%%
- //***************************************************************************
- typedef struct {
- BYTE ErrorCode; // Error Code (70H or 71H)
- BYTE SegmentNum; // Number of current segment descriptor
- BYTE SenseKey; // Sense Key(See bit definitions too)
- BYTE InfoByte0; // Information MSB
- BYTE InfoByte1; // Information MID
- BYTE InfoByte2; // Information MID
- BYTE InfoByte3; // Information LSB
- BYTE AddSenLen; // Additional Sense Length
- BYTE ComSpecInf0; // Command Specific Information MSB
- BYTE ComSpecInf1; // Command Specific Information MID
- BYTE ComSpecInf2; // Command Specific Information MID
- BYTE ComSpecInf3; // Command Specific Information LSB
- BYTE AddSenseCode; // Additional Sense Code
- BYTE AddSenQual; // Additional Sense Code Qualifier
- BYTE FieldRepUCode; // Field Replaceable Unit Code
- BYTE SenKeySpec15; // Sense Key Specific 15th byte
- BYTE SenKeySpec16; // Sense Key Specific 16th byte
- BYTE SenKeySpec17; // Sense Key Specific 17th byte
- BYTE AddSenseBytes; // Additional Sense Bytes
- } SENSE_DATA_FMT;
-
- //***************************************************************************
- // %%% REQUEST SENSE ERROR CODE %%%
- //***************************************************************************
- #define SERROR_CURRENT 0x70 // Current Errors
- #define SERROR_DEFERED 0x71 // Deferred Errors
-
- //***************************************************************************
- // %%% REQUEST SENSE BIT DEFINITIONS %%%
- //***************************************************************************
- #define SENSE_VALID 0x80 // Byte 0 Bit 7
- #define SENSE_FILEMRK 0x80 // Byte 2 Bit 7
- #define SENSE_EOM 0x40 // Byte 2 Bit 6
- #define SENSE_ILI 0x20 // Byte 2 Bit 5
-
- //***************************************************************************
- // %%% REQUEST SENSE SENSE KEY DEFINITIONS %%%
- //***************************************************************************
- #define KEY_NOSENSE 0x00 // No Sense
- #define KEY_RECERROR 0x01 // Recovered Error
- #define KEY_NOTREADY 0x02 // Not Ready
- #define KEY_MEDIUMERR 0x03 // Medium Error
- #define KEY_HARDERROR 0x04 // Hardware Error
- #define KEY_ILLGLREQ 0x05 // Illegal Request
- #define KEY_UNITATT 0x06 // Unit Attention
- #define KEY_DATAPROT 0x07 // Data Protect
- #define KEY_BLANKCHK 0x08 // Blank Check
- #define KEY_VENDSPEC 0x09 // Vendor Specific
- #define KEY_COPYABORT 0x0A // Copy Abort
- #define KEY_EQUAL 0x0C // Equal (Search)
- #define KEY_VOLOVRFLW 0x0D // Volume Overflow
- #define KEY_MISCOMP 0x0E // Miscompare (Search)
- #define KEY_RESERVED 0x0F // Reserved
-
- //***************************************************************************
- // %%% PERIPHERAL DEVICE TYPE DEFINITIONS %%%
- //***************************************************************************
- #define DTYPE_DASD 0x00 // Disk Device
- #define DTYPE_SEQD 0x01 // Tape Device
- #define DTYPE_PRNT 0x02 // Printer
- #define DTYPE_PROC 0x03 // Processor
- #define DTYPE_WORM 0x04 // Write-once read-multiple
- #define DTYPE_CROM 0x05 // CD-ROM device
- #define DTYPE_SCAN 0x06 // Scanner device
- #define DTYPE_OPTI 0x07 // Optical memory device
- #define DTYPE_JUKE 0x08 // Medium Changer device
- #define DTYPE_COMM 0x09 // Communications device
- #define DTYPE_RESL 0x0A // Reserved (low)
- #define DTYPE_RESH 0x1E // Reserved (high)
- #define DTYPE_UNKNOWN 0x1F // Unknown or no device type
-
- //***************************************************************************
- // %%% ANSI APPROVED VERSION DEFINITIONS %%%
- //***************************************************************************
- #define ANSI_MAYBE 0x0 // Device may or may not be ANSI approved stand
- #define ANSI_SCSI1 0x1 // Device complies to ANSI X3.131-1986 (SCSI-1)
- #define ANSI_SCSI2 0x2 // Device complies to SCSI-2
- #define ANSI_RESLO 0x3 // Reserved (low)
- #define ANSI_RESHI 0x7 // Reserved (high)
-
- typedef struct
- {
- USHORT Length;
- UCHAR ScsiStatus;
- UCHAR PathId;
- UCHAR TargetId;
- UCHAR Lun;
- UCHAR CdbLength;
- UCHAR SenseInfoLength;
- UCHAR DataIn;
- ULONG DataTransferLength;
- ULONG TimeOutValue;
- ULONG DataBufferOffset;
- ULONG SenseInfoOffset;
- UCHAR Cdb[16];
- } SCSI_PASS_THROUGH, *PSCSI_PASS_THROUGH;
-
- typedef struct
- {
- USHORT Length;
- UCHAR ScsiStatus;
- UCHAR PathId;
- UCHAR TargetId;
- UCHAR Lun;
- UCHAR CdbLength;
- UCHAR SenseInfoLength;
- UCHAR DataIn;
- ULONG DataTransferLength;
- ULONG TimeOutValue;
- PVOID DataBuffer;
- ULONG SenseInfoOffset;
- UCHAR Cdb[16];
- } SCSI_PASS_THROUGH_DIRECT, *PSCSI_PASS_THROUGH_DIRECT;
-
- typedef struct
- {
- SCSI_PASS_THROUGH_DIRECT spt;
- ULONG Filler;
- UCHAR ucSenseBuf[32];
- } SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER, *PSCSI_PASS_THROUGH_DIRECT_WITH_BUFFER;
-
- typedef struct
- {
- ULONG Length;
- UCHAR PortNumber;
- UCHAR PathId;
- UCHAR TargetId;
- UCHAR Lun;
- } SCSI_ADDRESS, *PSCSI_ADDRESS;
-
- #define METHOD_BUFFERED 0
- #define METHOD_IN_DIRECT 1
- #define METHOD_OUT_DIRECT 2
- #define METHOD_NEITHER 3
-
- #define FILE_ANY_ACCESS 0
- #ifndef FILE_READ_ACCESS
- #define FILE_READ_ACCESS (0x0001)
- #endif
- #ifndef FILE_WRITE_ACCESS
- #define FILE_WRITE_ACCESS (0x0002)
- #endif
-
- #define IOCTL_SCSI_BASE 0x00000004
-
- #define SCSI_IOCTL_DATA_OUT 0
- #define SCSI_IOCTL_DATA_IN 1
- #define SCSI_IOCTL_DATA_UNSPECIFIED 2
-
- #define CTL_CODE2( DevType, Function, Method, Access ) ( \
- ((DevType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \
- )
-
- #define IOCTL_SCSI_PASS_THROUGH CTL_CODE2( IOCTL_SCSI_BASE, 0x0401, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS )
- #define IOCTL_SCSI_GET_CAPABILITIES CTL_CODE2( IOCTL_SCSI_BASE, 0x0404, METHOD_BUFFERED, FILE_ANY_ACCESS)
- #define IOCTL_SCSI_PASS_THROUGH_DIRECT CTL_CODE2( IOCTL_SCSI_BASE, 0x0405, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS )
- #define IOCTL_SCSI_GET_ADDRESS CTL_CODE2( IOCTL_SCSI_BASE, 0x0406, METHOD_BUFFERED, FILE_ANY_ACCESS )
-
- #define SENSE_LEN 14
- #define SRB_DIR_SCSI 0x00
- #define SRB_POSTING 0x01
- #define SRB_ENABLE_RESIDUAL_COUNT 0x04
- #define SRB_DIR_IN 0x08
- #define SRB_DIR_OUT 0x10
- #define SRB_EVENT_NOTIFY 0x40
- #define RESIDUAL_COUNT_SUPPORTED 0x02
- #define MAX_SRB_TIMEOUT 1080001u
- #define DEFAULT_SRB_TIMEOUT 1080001u
-
- #define SC_HA_INQUIRY 0x00
- #define SC_GET_DEV_TYPE 0x01
- #define SC_EXEC_SCSI_CMD 0x02
- #define SC_ABORT_SRB 0x03
- #define SC_RESET_DEV 0x04
- #define SC_SET_HA_PARMS 0x05
- #define SC_GET_DISK_INFO 0x06
- #define SC_RESCAN_SCSI_BUS 0x07
- #define SC_GETSET_TIMEOUTS 0x08
-
- #define SS_PENDING 0x00
- #define SS_COMP 0x01
- #define SS_ABORTED 0x02
- #define SS_ABORT_FAIL 0x03
- #define SS_ERR 0x04
- #define SS_INVALID_CMD 0x80
- #define SS_INVALID_HA 0x81
- #define SS_NO_DEVICE 0x82
- #define SS_INVALID_SRB 0xE0
- #define SS_OLD_MANAGER 0xE1
- #define SS_BUFFER_ALIGN 0xE1
- #define SS_ILLEGAL_MODE 0xE2
- #define SS_NO_ASPI 0xE3
- #define SS_FAILED_INIT 0xE4
- #define SS_ASPI_IS_BUSY 0xE5
- #define SS_BUFFER_TO_BIG 0xE6
- #define SS_BUFFER_TOO_BIG 0xE6
- #define SS_MISMATCHED_COMPONENTS 0xE7
- #define SS_NO_ADAPTERS 0xE8
- #define SS_INSUFFICIENT_RESOURCES 0xE9
- #define SS_ASPI_IS_SHUTDOWN 0xEA
- #define SS_BAD_INSTALL 0xEB
-
- #define HASTAT_OK 0x00
- #define HASTAT_SEL_TO 0x11
- #define HASTAT_DO_DU 0x12
- #define HASTAT_BUS_FREE 0x13
- #define HASTAT_PHASE_ERR 0x14
- #define HASTAT_TIMEOUT 0x09
- #define HASTAT_COMMAND_TIMEOUT 0x0B
- #define HASTAT_MESSAGE_REJECT 0x0D
- #define HASTAT_BUS_RESET 0x0E
- #define HASTAT_PARITY_ERROR 0x0F
- #define HASTAT_REQUEST_SENSE_FAILED 0x10
-
- #define PACKED
- #pragma pack(1)
-
- typedef struct
- {
- BYTE SRB_Cmd;
- BYTE SRB_Status;
- BYTE SRB_HaID;
- BYTE SRB_Flags;
- DWORD SRB_Hdr_Rsvd;
- BYTE HA_Count;
- BYTE HA_SCSI_ID;
- BYTE HA_ManagerId[16];
- BYTE HA_Identifier[16];
- BYTE HA_Unique[16];
- WORD HA_Rsvd1;
- BYTE pad[20];
- } PACKED SRB_HAInquiry, *PSRB_HAInquiry, FAR *LPSRB_HAInquiry;
-
- typedef struct
- {
- BYTE SRB_Cmd;
- BYTE SRB_Status;
- BYTE SRB_HaID;
- BYTE SRB_Flags;
- DWORD SRB_Hdr_Rsvd;
- BYTE SRB_Target;
- BYTE SRB_Lun;
- BYTE SRB_DeviceType;
- BYTE SRB_Rsvd1;
- BYTE pad[68];
- } PACKED SRB_GDEVBlock, *PSRB_GDEVBlock, FAR *LPSRB_GDEVBlock;
-
- typedef struct
- {
- BYTE SRB_Cmd;
- BYTE SRB_Status;
- BYTE SRB_HaID;
- BYTE SRB_Flags;
- DWORD SRB_Hdr_Rsvd;
- BYTE SRB_Target;
- BYTE SRB_Lun;
- WORD SRB_Rsvd1;
- DWORD SRB_BufLen;
- BYTE FAR *SRB_BufPointer;
- BYTE SRB_SenseLen;
- BYTE SRB_CDBLen;
- BYTE SRB_HaStat;
- BYTE SRB_TargStat;
- VOID FAR *SRB_PostProc;
- BYTE SRB_Rsvd2[20];
- BYTE CDBByte[16];
- BYTE SenseArea[SENSE_LEN+2];
- } PACKED SRB_ExecSCSICmd, *PSRB_ExecSCSICmd, FAR *LPSRB_ExecSCSICmd;
-
- typedef struct
- {
- BYTE SRB_Cmd;
- BYTE SRB_Status;
- BYTE SRB_HaId;
- BYTE SRB_Flags;
- DWORD SRB_Hdr_Rsvd;
- } PACKED SRB, *PSRB, FAR *LPSRB;
-
- #pragma pack()
-
- struct CDDeviceInfo
- {
- char vendor[9];
- char productId[17];
- char rev[5];
- char vendorSpec[21];
-
- BYTE ha;
- BYTE tgt;
- BYTE lun;
- char scsiDriveLetter; // will be 0 if not using scsi
- };
-
- class CDReadBuffer
- {
- public:
- int startFrame;
- int numFrames;
- int dataStartOffset;
- int dataLength;
- BYTE* buffer;
- int bufferSize;
- int index;
- bool wantsIndex;
-
- CDReadBuffer (const int numberOfFrames)
- : startFrame (0),
- numFrames (0),
- dataStartOffset (0),
- dataLength (0),
- index (0),
- wantsIndex (false)
- {
- bufferSize = 2352 * numberOfFrames;
- buffer = (BYTE*) malloc (bufferSize);
- }
-
- ~CDReadBuffer()
- {
- free (buffer);
- }
-
- bool isZero() const
- {
- BYTE* p = buffer + dataStartOffset;
-
- for (int i = dataLength; --i >= 0;)
- if (*p++ != 0)
- return false;
-
- return true;
- }
- };
-
- class CDDeviceHandle;
-
- class CDController
- {
- public:
- CDController();
- virtual ~CDController();
-
- virtual bool read (CDReadBuffer* t) = 0;
- virtual void shutDown();
-
- bool readAudio (CDReadBuffer* t, CDReadBuffer* overlapBuffer = 0);
- int getLastIndex();
-
- public:
- bool initialised;
-
- CDDeviceHandle* deviceInfo;
- int framesToCheck, framesOverlap;
-
- void prepare (SRB_ExecSCSICmd& s);
- void perform (SRB_ExecSCSICmd& s);
- void setPaused (bool paused);
- };
-
- #pragma pack(1)
-
- struct TOCTRACK
- {
- BYTE rsvd;
- BYTE ADR;
- BYTE trackNumber;
- BYTE rsvd2;
- BYTE addr[4];
- };
-
- struct TOC
- {
- WORD tocLen;
- BYTE firstTrack;
- BYTE lastTrack;
- TOCTRACK tracks[100];
- };
-
- #pragma pack()
-
- enum
- {
- READTYPE_ANY = 0,
- READTYPE_ATAPI1 = 1,
- READTYPE_ATAPI2 = 2,
- READTYPE_READ6 = 3,
- READTYPE_READ10 = 4,
- READTYPE_READ_D8 = 5,
- READTYPE_READ_D4 = 6,
- READTYPE_READ_D4_1 = 7,
- READTYPE_READ10_2 = 8
- };
-
- class CDDeviceHandle
- {
- public:
- CDDeviceHandle (const CDDeviceInfo* const device)
- : scsiHandle (0),
- readType (READTYPE_ANY),
- controller (0)
- {
- memcpy (&info, device, sizeof (info));
- }
-
- ~CDDeviceHandle()
- {
- if (controller != 0)
- {
- controller->shutDown();
- delete controller;
- }
-
- if (scsiHandle != 0)
- CloseHandle (scsiHandle);
- }
-
- bool readTOC (TOC* lpToc, bool useMSF);
- bool readAudio (CDReadBuffer* buffer, CDReadBuffer* overlapBuffer = 0);
- void openDrawer (bool shouldBeOpen);
-
- CDDeviceInfo info;
- HANDLE scsiHandle;
- BYTE readType;
-
- private:
- CDController* controller;
-
- bool testController (const int readType,
- CDController* const newController,
- CDReadBuffer* const bufferToUse);
- };
-
- DWORD (*fGetASPI32SupportInfo)(void);
- DWORD (*fSendASPI32Command)(LPSRB);
-
- static HINSTANCE winAspiLib = 0;
- static bool usingScsi = false;
- static bool initialised = false;
-
- static bool InitialiseCDRipper()
- {
- if (! initialised)
- {
- initialised = true;
-
- OSVERSIONINFO info;
- info.dwOSVersionInfoSize = sizeof (info);
- GetVersionEx (&info);
-
- usingScsi = (info.dwPlatformId == VER_PLATFORM_WIN32_NT) && (info.dwMajorVersion > 4);
-
- if (! usingScsi)
- {
- fGetASPI32SupportInfo = 0;
- fSendASPI32Command = 0;
- winAspiLib = LoadLibrary (_T("WNASPI32.DLL"));
-
- if (winAspiLib != 0)
- {
- fGetASPI32SupportInfo = (DWORD(*)(void)) GetProcAddress (winAspiLib, "GetASPI32SupportInfo");
- fSendASPI32Command = (DWORD(*)(LPSRB)) GetProcAddress (winAspiLib, "SendASPI32Command");
-
- if (fGetASPI32SupportInfo == 0 || fSendASPI32Command == 0)
- return false;
- }
- else
- {
- usingScsi = true;
- }
- }
- }
-
- return true;
- }
-
- static void DeinitialiseCDRipper()
- {
- if (winAspiLib != 0)
- {
- fGetASPI32SupportInfo = 0;
- fSendASPI32Command = 0;
- FreeLibrary (winAspiLib);
- winAspiLib = 0;
- }
-
- initialised = false;
- }
-
- static HANDLE CreateSCSIDeviceHandle (char driveLetter)
- {
- TCHAR devicePath[8];
- devicePath[0] = '\\';
- devicePath[1] = '\\';
- devicePath[2] = '.';
- devicePath[3] = '\\';
- devicePath[4] = driveLetter;
- devicePath[5] = ':';
- devicePath[6] = 0;
-
- OSVERSIONINFO info;
- info.dwOSVersionInfoSize = sizeof (info);
- GetVersionEx (&info);
-
- DWORD flags = GENERIC_READ;
-
- if ((info.dwPlatformId == VER_PLATFORM_WIN32_NT) && (info.dwMajorVersion > 4))
- flags = GENERIC_READ | GENERIC_WRITE;
-
- HANDLE h = CreateFile (devicePath, flags, FILE_SHARE_WRITE | FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
-
- if (h == INVALID_HANDLE_VALUE)
- {
- flags ^= GENERIC_WRITE;
- h = CreateFile (devicePath, flags, FILE_SHARE_WRITE | FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
- }
-
- return h;
- }
-
- static DWORD performScsiPassThroughCommand (const LPSRB_ExecSCSICmd srb,
- const char driveLetter,
- HANDLE& deviceHandle,
- const bool retryOnFailure = true)
- {
- SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER s;
- zerostruct (s);
-
- s.spt.Length = sizeof (SCSI_PASS_THROUGH);
- s.spt.CdbLength = srb->SRB_CDBLen;
-
- s.spt.DataIn = (BYTE) ((srb->SRB_Flags & SRB_DIR_IN)
- ? SCSI_IOCTL_DATA_IN
- : ((srb->SRB_Flags & SRB_DIR_OUT)
- ? SCSI_IOCTL_DATA_OUT
- : SCSI_IOCTL_DATA_UNSPECIFIED));
-
- s.spt.DataTransferLength = srb->SRB_BufLen;
- s.spt.TimeOutValue = 5;
- s.spt.DataBuffer = srb->SRB_BufPointer;
- s.spt.SenseInfoOffset = offsetof (SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER, ucSenseBuf);
-
- memcpy (s.spt.Cdb, srb->CDBByte, srb->SRB_CDBLen);
-
- srb->SRB_Status = SS_ERR;
- srb->SRB_TargStat = 0x0004;
-
- DWORD bytesReturned = 0;
-
- if (DeviceIoControl (deviceHandle, IOCTL_SCSI_PASS_THROUGH_DIRECT,
- &s, sizeof (s),
- &s, sizeof (s),
- &bytesReturned, 0) != 0)
- {
- srb->SRB_Status = SS_COMP;
- }
- else if (retryOnFailure)
- {
- const DWORD error = GetLastError();
-
- if ((error == ERROR_MEDIA_CHANGED) || (error == ERROR_INVALID_HANDLE))
- {
- if (error != ERROR_INVALID_HANDLE)
- CloseHandle (deviceHandle);
-
- deviceHandle = CreateSCSIDeviceHandle (driveLetter);
-
- return performScsiPassThroughCommand (srb, driveLetter, deviceHandle, false);
- }
- }
-
- return srb->SRB_Status;
- }
-
- // Controller types..
-
- class ControllerType1 : public CDController
- {
- public:
- ControllerType1() {}
- ~ControllerType1() {}
-
- bool read (CDReadBuffer* rb)
- {
- if (rb->numFrames * 2352 > rb->bufferSize)
- return false;
-
- SRB_ExecSCSICmd s;
- prepare (s);
- s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY;
- s.SRB_BufLen = rb->bufferSize;
- s.SRB_BufPointer = rb->buffer;
- s.SRB_CDBLen = 12;
- s.CDBByte[0] = 0xBE;
- s.CDBByte[3] = (BYTE)((rb->startFrame >> 16) & 0xFF);
- s.CDBByte[4] = (BYTE)((rb->startFrame >> 8) & 0xFF);
- s.CDBByte[5] = (BYTE)(rb->startFrame & 0xFF);
- s.CDBByte[8] = (BYTE)(rb->numFrames & 0xFF);
- s.CDBByte[9] = (BYTE)((deviceInfo->readType == READTYPE_ATAPI1) ? 0x10 : 0xF0);
- perform (s);
-
- if (s.SRB_Status != SS_COMP)
- return false;
-
- rb->dataLength = rb->numFrames * 2352;
- rb->dataStartOffset = 0;
- return true;
- }
- };
-
- class ControllerType2 : public CDController
- {
- public:
- ControllerType2() {}
- ~ControllerType2() {}
-
- void shutDown()
- {
- if (initialised)
- {
- BYTE bufPointer[] = { 0, 0, 0, 8, 83, 0, 0, 0, 0, 0, 8, 0 };
-
- SRB_ExecSCSICmd s;
- prepare (s);
- s.SRB_Flags = SRB_EVENT_NOTIFY | SRB_ENABLE_RESIDUAL_COUNT;
- s.SRB_BufLen = 0x0C;
- s.SRB_BufPointer = bufPointer;
- s.SRB_CDBLen = 6;
- s.CDBByte[0] = 0x15;
- s.CDBByte[4] = 0x0C;
- perform (s);
- }
- }
-
- bool init()
- {
- SRB_ExecSCSICmd s;
- s.SRB_Status = SS_ERR;
-
- if (deviceInfo->readType == READTYPE_READ10_2)
- {
- BYTE bufPointer1[] = { 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 9, 48, 35, 6, 0, 0, 0, 0, 0, 128 };
- BYTE bufPointer2[] = { 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 9, 48, 1, 6, 32, 7, 0, 0, 0, 0 };
-
- for (int i = 0; i < 2; ++i)
- {
- prepare (s);
- s.SRB_Flags = SRB_EVENT_NOTIFY;
- s.SRB_BufLen = 0x14;
- s.SRB_BufPointer = (i == 0) ? bufPointer1 : bufPointer2;
- s.SRB_CDBLen = 6;
- s.CDBByte[0] = 0x15;
- s.CDBByte[1] = 0x10;
- s.CDBByte[4] = 0x14;
- perform (s);
-
- if (s.SRB_Status != SS_COMP)
- return false;
- }
- }
- else
- {
- BYTE bufPointer[] = { 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 9, 48 };
-
- prepare (s);
- s.SRB_Flags = SRB_EVENT_NOTIFY;
- s.SRB_BufLen = 0x0C;
- s.SRB_BufPointer = bufPointer;
- s.SRB_CDBLen = 6;
- s.CDBByte[0] = 0x15;
- s.CDBByte[4] = 0x0C;
- perform (s);
- }
-
- return s.SRB_Status == SS_COMP;
- }
-
- bool read (CDReadBuffer* rb)
- {
- if (rb->numFrames * 2352 > rb->bufferSize)
- return false;
-
- if (!initialised)
- {
- initialised = init();
-
- if (!initialised)
- return false;
- }
-
- SRB_ExecSCSICmd s;
- prepare (s);
- s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY;
- s.SRB_BufLen = rb->bufferSize;
- s.SRB_BufPointer = rb->buffer;
- s.SRB_CDBLen = 10;
- s.CDBByte[0] = 0x28;
- s.CDBByte[1] = (BYTE)(deviceInfo->info.lun << 5);
- s.CDBByte[3] = (BYTE)((rb->startFrame >> 16) & 0xFF);
- s.CDBByte[4] = (BYTE)((rb->startFrame >> 8) & 0xFF);
- s.CDBByte[5] = (BYTE)(rb->startFrame & 0xFF);
- s.CDBByte[8] = (BYTE)(rb->numFrames & 0xFF);
- perform (s);
-
- if (s.SRB_Status != SS_COMP)
- return false;
-
- rb->dataLength = rb->numFrames * 2352;
- rb->dataStartOffset = 0;
-
- return true;
- }
- };
-
- class ControllerType3 : public CDController
- {
- public:
- ControllerType3() {}
- ~ControllerType3() {}
-
- bool read (CDReadBuffer* rb)
- {
- if (rb->numFrames * 2352 > rb->bufferSize)
- return false;
-
- if (!initialised)
- {
- setPaused (false);
- initialised = true;
- }
-
- SRB_ExecSCSICmd s;
- prepare (s);
- s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY;
- s.SRB_BufLen = rb->numFrames * 2352;
- s.SRB_BufPointer = rb->buffer;
- s.SRB_CDBLen = 12;
- s.CDBByte[0] = 0xD8;
- s.CDBByte[3] = (BYTE)((rb->startFrame >> 16) & 0xFF);
- s.CDBByte[4] = (BYTE)((rb->startFrame >> 8) & 0xFF);
- s.CDBByte[5] = (BYTE)(rb->startFrame & 0xFF);
- s.CDBByte[9] = (BYTE)(rb->numFrames & 0xFF);
- perform (s);
-
- if (s.SRB_Status != SS_COMP)
- return false;
-
- rb->dataLength = rb->numFrames * 2352;
- rb->dataStartOffset = 0;
-
- return true;
- }
- };
-
- class ControllerType4 : public CDController
- {
- public:
- ControllerType4() {}
- ~ControllerType4() {}
-
- bool selectD4Mode()
- {
- BYTE bufPointer[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 48 };
-
- SRB_ExecSCSICmd s;
- prepare (s);
- s.SRB_Flags = SRB_EVENT_NOTIFY;
- s.SRB_CDBLen = 6;
- s.SRB_BufLen = 12;
- s.SRB_BufPointer = bufPointer;
- s.CDBByte[0] = 0x15;
- s.CDBByte[1] = 0x10;
- s.CDBByte[4] = 0x08;
- perform (s);
-
- return s.SRB_Status == SS_COMP;
- }
-
- bool read (CDReadBuffer* rb)
- {
- if (rb->numFrames * 2352 > rb->bufferSize)
- return false;
-
- if (!initialised)
- {
- setPaused (true);
-
- if (deviceInfo->readType == READTYPE_READ_D4_1)
- selectD4Mode();
-
- initialised = true;
- }
-
- SRB_ExecSCSICmd s;
- prepare (s);
- s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY;
- s.SRB_BufLen = rb->bufferSize;
- s.SRB_BufPointer = rb->buffer;
- s.SRB_CDBLen = 10;
- s.CDBByte[0] = 0xD4;
- s.CDBByte[3] = (BYTE)((rb->startFrame >> 16) & 0xFF);
- s.CDBByte[4] = (BYTE)((rb->startFrame >> 8) & 0xFF);
- s.CDBByte[5] = (BYTE)(rb->startFrame & 0xFF);
- s.CDBByte[8] = (BYTE)(rb->numFrames & 0xFF);
- perform (s);
-
- if (s.SRB_Status != SS_COMP)
- return false;
-
- rb->dataLength = rb->numFrames * 2352;
- rb->dataStartOffset = 0;
-
- return true;
- }
- };
-
- CDController::CDController() : initialised (false)
- {
- }
-
- CDController::~CDController()
- {
- }
-
- void CDController::prepare (SRB_ExecSCSICmd& s)
- {
- zerostruct (s);
-
- s.SRB_Cmd = SC_EXEC_SCSI_CMD;
- s.SRB_HaID = deviceInfo->info.ha;
- s.SRB_Target = deviceInfo->info.tgt;
- s.SRB_Lun = deviceInfo->info.lun;
- s.SRB_SenseLen = SENSE_LEN;
- }
-
- void CDController::perform (SRB_ExecSCSICmd& s)
- {
- HANDLE event = CreateEvent (0, TRUE, FALSE, 0);
- s.SRB_PostProc = (void*)event;
-
- ResetEvent (event);
-
- DWORD status = (usingScsi) ? performScsiPassThroughCommand ((LPSRB_ExecSCSICmd)&s,
- deviceInfo->info.scsiDriveLetter,
- deviceInfo->scsiHandle)
- : fSendASPI32Command ((LPSRB)&s);
-
- if (status == SS_PENDING)
- WaitForSingleObject (event, 4000);
-
- CloseHandle (event);
- }
-
- void CDController::setPaused (bool paused)
- {
- SRB_ExecSCSICmd s;
- prepare (s);
- s.SRB_Flags = SRB_EVENT_NOTIFY;
- s.SRB_CDBLen = 10;
- s.CDBByte[0] = 0x4B;
- s.CDBByte[8] = (BYTE) (paused ? 0 : 1);
- perform (s);
- }
-
- void CDController::shutDown()
- {
- }
-
- bool CDController::readAudio (CDReadBuffer* rb, CDReadBuffer* overlapBuffer)
- {
- if (overlapBuffer != 0)
- {
- const bool canDoJitter = (overlapBuffer->bufferSize >= 2352 * framesToCheck);
- const bool doJitter = canDoJitter && ! overlapBuffer->isZero();
-
- if (doJitter
- && overlapBuffer->startFrame > 0
- && overlapBuffer->numFrames > 0
- && overlapBuffer->dataLength > 0)
- {
- const int numFrames = rb->numFrames;
-
- if (overlapBuffer->startFrame == (rb->startFrame - framesToCheck))
- {
- rb->startFrame -= framesOverlap;
-
- if (framesToCheck < framesOverlap
- && numFrames + framesOverlap <= rb->bufferSize / 2352)
- rb->numFrames += framesOverlap;
- }
- else
- {
- overlapBuffer->dataLength = 0;
- overlapBuffer->startFrame = 0;
- overlapBuffer->numFrames = 0;
- }
- }
-
- if (! read (rb))
- return false;
-
- if (doJitter)
- {
- const int checkLen = framesToCheck * 2352;
- const int maxToCheck = rb->dataLength - checkLen;
-
- if (overlapBuffer->dataLength == 0 || overlapBuffer->isZero())
- return true;
-
- BYTE* const p = overlapBuffer->buffer + overlapBuffer->dataStartOffset;
- bool found = false;
-
- for (int i = 0; i < maxToCheck; ++i)
- {
- if (!memcmp (p, rb->buffer + i, checkLen))
- {
- i += checkLen;
- rb->dataStartOffset = i;
- rb->dataLength -= i;
- rb->startFrame = overlapBuffer->startFrame + framesToCheck;
- found = true;
- break;
- }
- }
-
- rb->numFrames = rb->dataLength / 2352;
- rb->dataLength = 2352 * rb->numFrames;
-
- if (!found)
- return false;
- }
-
- if (canDoJitter)
- {
- memcpy (overlapBuffer->buffer,
- rb->buffer + rb->dataStartOffset + 2352 * (rb->numFrames - framesToCheck),
- 2352 * framesToCheck);
-
- overlapBuffer->startFrame = rb->startFrame + rb->numFrames - framesToCheck;
- overlapBuffer->numFrames = framesToCheck;
- overlapBuffer->dataLength = 2352 * framesToCheck;
- overlapBuffer->dataStartOffset = 0;
- }
- else
- {
- overlapBuffer->startFrame = 0;
- overlapBuffer->numFrames = 0;
- overlapBuffer->dataLength = 0;
- }
-
- return true;
- }
- else
- {
- return read (rb);
- }
- }
-
- int CDController::getLastIndex()
- {
- char qdata[100];
-
- SRB_ExecSCSICmd s;
- prepare (s);
- s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY;
- s.SRB_BufLen = sizeof (qdata);
- s.SRB_BufPointer = (BYTE*)qdata;
- s.SRB_CDBLen = 12;
- s.CDBByte[0] = 0x42;
- s.CDBByte[1] = (BYTE)(deviceInfo->info.lun << 5);
- s.CDBByte[2] = 64;
- s.CDBByte[3] = 1; // get current position
- s.CDBByte[7] = 0;
- s.CDBByte[8] = (BYTE)sizeof (qdata);
- perform (s);
-
- if (s.SRB_Status == SS_COMP)
- return qdata[7];
-
- return 0;
- }
-
- bool CDDeviceHandle::readTOC (TOC* lpToc, bool useMSF)
- {
- HANDLE event = CreateEvent (0, TRUE, FALSE, 0);
-
- SRB_ExecSCSICmd s;
- zerostruct (s);
-
- s.SRB_Cmd = SC_EXEC_SCSI_CMD;
- s.SRB_HaID = info.ha;
- s.SRB_Target = info.tgt;
- s.SRB_Lun = info.lun;
- s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY;
- s.SRB_BufLen = 0x324;
- s.SRB_BufPointer = (BYTE*)lpToc;
- s.SRB_SenseLen = 0x0E;
- s.SRB_CDBLen = 0x0A;
- s.SRB_PostProc = (void*)event;
- s.CDBByte[0] = 0x43;
- s.CDBByte[1] = (BYTE)(useMSF ? 0x02 : 0x00);
- s.CDBByte[7] = 0x03;
- s.CDBByte[8] = 0x24;
-
- ResetEvent (event);
- DWORD status = (usingScsi) ? performScsiPassThroughCommand ((LPSRB_ExecSCSICmd)&s, info.scsiDriveLetter, scsiHandle)
- : fSendASPI32Command ((LPSRB)&s);
-
- if (status == SS_PENDING)
- WaitForSingleObject (event, 4000);
-
- CloseHandle (event);
- return (s.SRB_Status == SS_COMP);
- }
-
- bool CDDeviceHandle::readAudio (CDReadBuffer* const buffer,
- CDReadBuffer* const overlapBuffer)
- {
- if (controller == 0)
- {
- testController (READTYPE_ATAPI2, new ControllerType1(), buffer)
- || testController (READTYPE_ATAPI1, new ControllerType1(), buffer)
- || testController (READTYPE_READ10_2, new ControllerType2(), buffer)
- || testController (READTYPE_READ10, new ControllerType2(), buffer)
- || testController (READTYPE_READ_D8, new ControllerType3(), buffer)
- || testController (READTYPE_READ_D4, new ControllerType4(), buffer)
- || testController (READTYPE_READ_D4_1, new ControllerType4(), buffer);
- }
-
- buffer->index = 0;
-
- if ((controller != 0)
- && controller->readAudio (buffer, overlapBuffer))
- {
- if (buffer->wantsIndex)
- buffer->index = controller->getLastIndex();
-
- return true;
- }
-
- return false;
- }
-
- void CDDeviceHandle::openDrawer (bool shouldBeOpen)
- {
- if (shouldBeOpen)
- {
- if (controller != 0)
- {
- controller->shutDown();
- delete controller;
- controller = 0;
- }
-
- if (scsiHandle != 0)
- {
- CloseHandle (scsiHandle);
- scsiHandle = 0;
- }
- }
-
- SRB_ExecSCSICmd s;
- zerostruct (s);
-
- s.SRB_Cmd = SC_EXEC_SCSI_CMD;
- s.SRB_HaID = info.ha;
- s.SRB_Target = info.tgt;
- s.SRB_Lun = info.lun;
- s.SRB_SenseLen = SENSE_LEN;
- s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY;
- s.SRB_BufLen = 0;
- s.SRB_BufPointer = 0;
- s.SRB_CDBLen = 12;
- s.CDBByte[0] = 0x1b;
- s.CDBByte[1] = (BYTE)(info.lun << 5);
- s.CDBByte[4] = (BYTE)((shouldBeOpen) ? 2 : 3);
-
- HANDLE event = CreateEvent (0, TRUE, FALSE, 0);
- s.SRB_PostProc = (void*)event;
-
- ResetEvent (event);
-
- DWORD status = (usingScsi) ? performScsiPassThroughCommand ((LPSRB_ExecSCSICmd)&s, info.scsiDriveLetter, scsiHandle)
- : fSendASPI32Command ((LPSRB)&s);
-
- if (status == SS_PENDING)
- WaitForSingleObject (event, 4000);
-
- CloseHandle (event);
- }
-
- bool CDDeviceHandle::testController (const int type,
- CDController* const newController,
- CDReadBuffer* const rb)
- {
- controller = newController;
- readType = (BYTE)type;
-
- controller->deviceInfo = this;
- controller->framesToCheck = 1;
- controller->framesOverlap = 3;
-
- bool passed = false;
-
- memset (rb->buffer, 0xcd, rb->bufferSize);
-
- if (controller->read (rb))
- {
- passed = true;
- int* p = (int*) (rb->buffer + rb->dataStartOffset);
- int wrong = 0;
-
- for (int i = rb->dataLength / 4; --i >= 0;)
- {
- if (*p++ == (int) 0xcdcdcdcd)
- {
- if (++wrong == 4)
- {
- passed = false;
- break;
- }
- }
- else
- {
- wrong = 0;
- }
- }
- }
-
- if (! passed)
- {
- controller->shutDown();
- delete controller;
- controller = 0;
- }
-
- return passed;
- }
-
- static void GetAspiDeviceInfo (CDDeviceInfo* dev, BYTE ha, BYTE tgt, BYTE lun)
- {
- HANDLE event = CreateEvent (0, TRUE, FALSE, 0);
-
- const int bufSize = 128;
- BYTE buffer[bufSize];
- zeromem (buffer, bufSize);
-
- SRB_ExecSCSICmd s;
- zerostruct (s);
-
- s.SRB_Cmd = SC_EXEC_SCSI_CMD;
- s.SRB_HaID = ha;
- s.SRB_Target = tgt;
- s.SRB_Lun = lun;
- s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY;
- s.SRB_BufLen = bufSize;
- s.SRB_BufPointer = buffer;
- s.SRB_SenseLen = SENSE_LEN;
- s.SRB_CDBLen = 6;
- s.SRB_PostProc = (void*)event;
- s.CDBByte[0] = SCSI_INQUIRY;
- s.CDBByte[4] = 100;
-
- ResetEvent (event);
-
- if (fSendASPI32Command ((LPSRB)&s) == SS_PENDING)
- WaitForSingleObject (event, 4000);
-
- CloseHandle (event);
-
- if (s.SRB_Status == SS_COMP)
- {
- memcpy (dev->vendor, &buffer[8], 8);
- memcpy (dev->productId, &buffer[16], 16);
- memcpy (dev->rev, &buffer[32], 4);
- memcpy (dev->vendorSpec, &buffer[36], 20);
- }
- }
-
- static int FindCDDevices (CDDeviceInfo* const list,
- int maxItems)
- {
- int count = 0;
-
- if (usingScsi)
- {
- for (char driveLetter = 'b'; driveLetter <= 'z'; ++driveLetter)
- {
- TCHAR drivePath[8];
- drivePath[0] = driveLetter;
- drivePath[1] = ':';
- drivePath[2] = '\\';
- drivePath[3] = 0;
-
- if (GetDriveType (drivePath) == DRIVE_CDROM)
- {
- HANDLE h = CreateSCSIDeviceHandle (driveLetter);
-
- if (h != INVALID_HANDLE_VALUE)
- {
- BYTE buffer[100], passThroughStruct[1024];
- zeromem (buffer, sizeof (buffer));
- zeromem (passThroughStruct, sizeof (passThroughStruct));
-
- PSCSI_PASS_THROUGH_DIRECT_WITH_BUFFER p = (PSCSI_PASS_THROUGH_DIRECT_WITH_BUFFER)passThroughStruct;
-
- p->spt.Length = sizeof (SCSI_PASS_THROUGH);
- p->spt.CdbLength = 6;
- p->spt.SenseInfoLength = 24;
- p->spt.DataIn = SCSI_IOCTL_DATA_IN;
- p->spt.DataTransferLength = 100;
- p->spt.TimeOutValue = 2;
- p->spt.DataBuffer = buffer;
- p->spt.SenseInfoOffset = offsetof (SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER, ucSenseBuf);
- p->spt.Cdb[0] = 0x12;
- p->spt.Cdb[4] = 100;
-
- DWORD bytesReturned = 0;
-
- if (DeviceIoControl (h, IOCTL_SCSI_PASS_THROUGH_DIRECT,
- p, sizeof (SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER),
- p, sizeof (SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER),
- &bytesReturned, 0) != 0)
- {
- zeromem (&list[count], sizeof (CDDeviceInfo));
-
- list[count].scsiDriveLetter = driveLetter;
-
- memcpy (list[count].vendor, &buffer[8], 8);
- memcpy (list[count].productId, &buffer[16], 16);
- memcpy (list[count].rev, &buffer[32], 4);
- memcpy (list[count].vendorSpec, &buffer[36], 20);
-
- zeromem (passThroughStruct, sizeof (passThroughStruct));
- PSCSI_ADDRESS scsiAddr = (PSCSI_ADDRESS)passThroughStruct;
-
- scsiAddr->Length = sizeof (SCSI_ADDRESS);
-
- if (DeviceIoControl (h, IOCTL_SCSI_GET_ADDRESS,
- 0, 0, scsiAddr, sizeof (SCSI_ADDRESS),
- &bytesReturned, 0) != 0)
- {
- list[count].ha = scsiAddr->PortNumber;
- list[count].tgt = scsiAddr->TargetId;
- list[count].lun = scsiAddr->Lun;
- ++count;
- }
- }
-
- CloseHandle (h);
- }
- }
- }
- }
- else
- {
- const DWORD d = fGetASPI32SupportInfo();
- BYTE status = HIBYTE (LOWORD (d));
-
- if (status != SS_COMP || status == SS_NO_ADAPTERS)
- return 0;
-
- const int numAdapters = LOBYTE (LOWORD (d));
-
- for (BYTE ha = 0; ha < numAdapters; ++ha)
- {
- SRB_HAInquiry s;
- zerostruct (s);
-
- s.SRB_Cmd = SC_HA_INQUIRY;
- s.SRB_HaID = ha;
- fSendASPI32Command ((LPSRB)&s);
-
- if (s.SRB_Status == SS_COMP)
- {
- maxItems = (int)s.HA_Unique[3];
-
- if (maxItems == 0)
- maxItems = 8;
-
- for (BYTE tgt = 0; tgt < maxItems; ++tgt)
- {
- for (BYTE lun = 0; lun < 8; ++lun)
- {
- SRB_GDEVBlock sb;
- zerostruct (sb);
-
- sb.SRB_Cmd = SC_GET_DEV_TYPE;
- sb.SRB_HaID = ha;
- sb.SRB_Target = tgt;
- sb.SRB_Lun = lun;
- fSendASPI32Command ((LPSRB) &sb);
-
- if (sb.SRB_Status == SS_COMP
- && sb.SRB_DeviceType == DTYPE_CROM)
- {
- zeromem (&list[count], sizeof (CDDeviceInfo));
-
- list[count].ha = ha;
- list[count].tgt = tgt;
- list[count].lun = lun;
-
- GetAspiDeviceInfo (&(list[count]), ha, tgt, lun);
-
- ++count;
- }
- }
- }
- }
- }
- }
-
- return count;
- }
-
- static int ripperUsers = 0;
- static bool initialisedOk = false;
-
- class DeinitialiseTimer : private Timer,
- private DeletedAtShutdown
- {
- DeinitialiseTimer (const DeinitialiseTimer&);
- const DeinitialiseTimer& operator= (const DeinitialiseTimer&);
-
- public:
- DeinitialiseTimer()
- {
- startTimer (4000);
- }
-
- ~DeinitialiseTimer()
- {
- if (--ripperUsers == 0)
- DeinitialiseCDRipper();
- }
-
- void timerCallback()
- {
- delete this;
- }
-
- juce_UseDebuggingNewOperator
- };
-
- static void incUserCount()
- {
- if (ripperUsers++ == 0)
- initialisedOk = InitialiseCDRipper();
- }
-
- static void decUserCount()
- {
- new DeinitialiseTimer();
- }
-
- struct CDDeviceWrapper
- {
- CDDeviceHandle* cdH;
- CDReadBuffer* overlapBuffer;
- bool jitter;
- };
-
- static int getAddressOf (const TOCTRACK* const t)
- {
- return (((DWORD)t->addr[0]) << 24) + (((DWORD)t->addr[1]) << 16) +
- (((DWORD)t->addr[2]) << 8) + ((DWORD)t->addr[3]);
- }
-
- static int getMSFAddressOf (const TOCTRACK* const t)
- {
- return 60 * t->addr[1] + t->addr[2];
- }
-
- static const int samplesPerFrame = 44100 / 75;
- static const int bytesPerFrame = samplesPerFrame * 4;
-
- const StringArray AudioCDReader::getAvailableCDNames()
- {
- StringArray results;
- incUserCount();
-
- if (initialisedOk)
- {
- CDDeviceInfo list[8];
- const int num = FindCDDevices (list, 8);
-
- decUserCount();
-
- for (int i = 0; i < num; ++i)
- {
- String s;
-
- if (list[i].scsiDriveLetter > 0)
- s << String::charToString (list[i].scsiDriveLetter).toUpperCase() << T(": ");
-
- s << String (list[i].vendor).trim()
- << T(" ") << String (list[i].productId).trim()
- << T(" ") << String (list[i].rev).trim();
-
- results.add (s);
- }
- }
-
- return results;
- }
-
- static CDDeviceHandle* openHandle (const CDDeviceInfo* const device)
- {
- SRB_GDEVBlock s;
- zerostruct (s);
-
- s.SRB_Cmd = SC_GET_DEV_TYPE;
- s.SRB_HaID = device->ha;
- s.SRB_Target = device->tgt;
- s.SRB_Lun = device->lun;
-
- if (usingScsi)
- {
- HANDLE h = CreateSCSIDeviceHandle (device->scsiDriveLetter);
-
- if (h != INVALID_HANDLE_VALUE)
- {
- CDDeviceHandle* cdh = new CDDeviceHandle (device);
- cdh->scsiHandle = h;
- return cdh;
- }
- }
- else
- {
- if (fSendASPI32Command ((LPSRB)&s) == SS_COMP
- && s.SRB_DeviceType == DTYPE_CROM)
- {
- return new CDDeviceHandle (device);
- }
- }
-
- return 0;
- }
-
- AudioCDReader* AudioCDReader::createReaderForCD (const int deviceIndex)
- {
- incUserCount();
-
- if (initialisedOk)
- {
- CDDeviceInfo list[8];
- const int num = FindCDDevices (list, 8);
-
- if (((unsigned int) deviceIndex) < (unsigned int) num)
- {
- CDDeviceHandle* const handle = openHandle (&(list[deviceIndex]));
-
- if (handle != 0)
- {
- CDDeviceWrapper* const d = new CDDeviceWrapper();
- d->cdH = handle;
- d->overlapBuffer = new CDReadBuffer(3);
-
- return new AudioCDReader (d);
- }
- }
- }
-
- decUserCount();
- return 0;
- }
-
- AudioCDReader::AudioCDReader (void* handle_)
- : AudioFormatReader (0, T("CD Audio")),
- handle (handle_),
- indexingEnabled (false),
- lastIndex (0),
- firstFrameInBuffer (0),
- samplesInBuffer (0)
- {
- jassert (handle_ != 0);
-
- refreshTrackLengths();
-
- sampleRate = 44100.0;
- bitsPerSample = 16;
- lengthInSamples = getPositionOfTrackStart (numTracks);
- numChannels = 2;
- usesFloatingPointData = false;
-
- buffer.setSize (4 * bytesPerFrame, true);
- }
-
- AudioCDReader::~AudioCDReader()
- {
- CDDeviceWrapper* const device = (CDDeviceWrapper*)handle;
-
- delete device->cdH;
- delete device->overlapBuffer;
- delete device;
-
- decUserCount();
- }
-
- bool AudioCDReader::read (int** destSamples,
- int64 startSampleInFile,
- int numSamples)
- {
- CDDeviceWrapper* const device = (CDDeviceWrapper*)handle;
-
- bool ok = true;
- int offset = 0;
-
- if (startSampleInFile < 0)
- {
- int* l = destSamples[0];
- int* r = destSamples[1];
-
- numSamples += (int) startSampleInFile;
- offset -= (int) startSampleInFile;
-
- while (++startSampleInFile <= 0)
- {
- *l++ = 0;
-
- if (r != 0)
- *r++ = 0;
- }
- }
-
- while (numSamples > 0)
- {
- const int bufferStartSample = firstFrameInBuffer * samplesPerFrame;
- const int bufferEndSample = bufferStartSample + samplesInBuffer;
-
- if (startSampleInFile >= bufferStartSample
- && startSampleInFile < bufferEndSample)
- {
- const int toDo = (int) jmin ((int64) numSamples, bufferEndSample - startSampleInFile);
-
- int* const l = destSamples[0] + offset;
- int* const r = destSamples[1] + offset;
- const short* src = (const short*) buffer.getData();
- src += 2 * (startSampleInFile - bufferStartSample);
-
- for (int i = 0; i < toDo; ++i)
- {
- l[i] = src [i << 1] << 16;
-
- if (r != 0)
- r[i] = src [(i << 1) + 1] << 16;
- }
-
- offset += toDo;
- startSampleInFile += toDo;
- numSamples -= toDo;
- }
- else
- {
- const int framesInBuffer = buffer.getSize() / bytesPerFrame;
- const int frameNeeded = (int) (startSampleInFile / samplesPerFrame);
-
- if (firstFrameInBuffer + framesInBuffer != frameNeeded)
- {
- device->overlapBuffer->dataLength = 0;
- device->overlapBuffer->startFrame = 0;
- device->overlapBuffer->numFrames = 0;
- device->jitter = false;
- }
-
- firstFrameInBuffer = frameNeeded;
- lastIndex = 0;
-
- CDReadBuffer readBuffer (framesInBuffer + 4);
- readBuffer.wantsIndex = indexingEnabled;
-
- int i;
- for (i = 5; --i >= 0;)
- {
- readBuffer.startFrame = frameNeeded;
- readBuffer.numFrames = framesInBuffer;
-
- if (device->cdH->readAudio (&readBuffer, (device->jitter) ? device->overlapBuffer : 0))
- break;
- else
- device->overlapBuffer->dataLength = 0;
- }
-
- if (i >= 0)
- {
- memcpy ((char*) buffer.getData(),
- readBuffer.buffer + readBuffer.dataStartOffset,
- readBuffer.dataLength);
-
- samplesInBuffer = readBuffer.dataLength >> 2;
- lastIndex = readBuffer.index;
- }
- else
- {
- int* l = destSamples[0] + offset;
- int* r = destSamples[1] + offset;
-
- while (--numSamples >= 0)
- {
- *l++ = 0;
-
- if (r != 0)
- *r++ = 0;
- }
-
- // sometimes the read fails for just the very last couple of blocks, so
- // we'll ignore and errors in the last half-second of the disk..
- ok = startSampleInFile > (trackStarts [numTracks] - 20000);
- break;
- }
- }
- }
-
- return ok;
- }
-
- bool AudioCDReader::isCDStillPresent() const
- {
- TOC toc;
- zerostruct (toc);
-
- return ((CDDeviceWrapper*)handle)->cdH->readTOC (&toc, false);
- }
-
- int AudioCDReader::getNumTracks() const
- {
- return numTracks;
- }
-
- int AudioCDReader::getPositionOfTrackStart (int trackNum) const
- {
- return (trackNum >= 0 && trackNum <= numTracks) ? trackStarts [trackNum] * samplesPerFrame
- : 0;
- }
-
- void AudioCDReader::refreshTrackLengths()
- {
- zeromem (trackStarts, sizeof (trackStarts));
- zeromem (audioTracks, sizeof (audioTracks));
-
- TOC toc;
- zerostruct (toc);
-
- if (((CDDeviceWrapper*)handle)->cdH->readTOC (&toc, false))
- {
- numTracks = 1 + toc.lastTrack - toc.firstTrack;
-
- for (int i = 0; i <= numTracks; ++i)
- {
- trackStarts[i] = getAddressOf (&toc.tracks[i]);
- audioTracks[i] = ((toc.tracks[i].ADR & 4) == 0);
- }
- }
- else
- {
- numTracks = 0;
- }
- }
-
- bool AudioCDReader::isTrackAudio (int trackNum) const
- {
- return (trackNum >= 0 && trackNum <= numTracks) ? audioTracks [trackNum]
- : false;
- }
-
- void AudioCDReader::enableIndexScanning (bool b)
- {
- indexingEnabled = b;
- }
-
- int AudioCDReader::getLastIndex() const
- {
- return lastIndex;
- }
-
- const int framesPerIndexRead = 4;
-
- int AudioCDReader::getIndexAt (int samplePos)
- {
- CDDeviceWrapper* const device = (CDDeviceWrapper*) handle;
-
- const int frameNeeded = samplePos / samplesPerFrame;
-
- device->overlapBuffer->dataLength = 0;
- device->overlapBuffer->startFrame = 0;
- device->overlapBuffer->numFrames = 0;
- device->jitter = false;
-
- firstFrameInBuffer = 0;
- lastIndex = 0;
-
- CDReadBuffer readBuffer (4 + framesPerIndexRead);
- readBuffer.wantsIndex = true;
-
- int i;
- for (i = 5; --i >= 0;)
- {
- readBuffer.startFrame = frameNeeded;
- readBuffer.numFrames = framesPerIndexRead;
-
- if (device->cdH->readAudio (&readBuffer, (false) ? device->overlapBuffer : 0))
- break;
- }
-
- if (i >= 0)
- return readBuffer.index;
-
- return -1;
- }
-
- const Array <int> AudioCDReader::findIndexesInTrack (const int trackNumber)
- {
- Array <int> indexes;
-
- const int trackStart = getPositionOfTrackStart (trackNumber);
- const int trackEnd = getPositionOfTrackStart (trackNumber + 1);
-
- bool needToScan = true;
-
- if (trackEnd - trackStart > 20 * 44100)
- {
- // check the end of the track for indexes before scanning the whole thing
- needToScan = false;
- int pos = jmax (trackStart, trackEnd - 44100 * 5);
- bool seenAnIndex = false;
-
- while (pos <= trackEnd - samplesPerFrame)
- {
- const int index = getIndexAt (pos);
-
- if (index == 0)
- {
- // lead-out, so skip back a bit if we've not found any indexes yet..
- if (seenAnIndex)
- break;
-
- pos -= 44100 * 5;
-
- if (pos < trackStart)
- break;
- }
- else
- {
- if (index > 0)
- seenAnIndex = true;
-
- if (index > 1)
- {
- needToScan = true;
- break;
- }
-
- pos += samplesPerFrame * framesPerIndexRead;
- }
- }
- }
-
- if (needToScan)
- {
- CDDeviceWrapper* const device = (CDDeviceWrapper*) handle;
-
- int pos = trackStart;
- int last = -1;
-
- while (pos < trackEnd - samplesPerFrame * 10)
- {
- const int frameNeeded = pos / samplesPerFrame;
-
- device->overlapBuffer->dataLength = 0;
- device->overlapBuffer->startFrame = 0;
- device->overlapBuffer->numFrames = 0;
- device->jitter = false;
-
- firstFrameInBuffer = 0;
-
- CDReadBuffer readBuffer (4);
- readBuffer.wantsIndex = true;
-
- int i;
- for (i = 5; --i >= 0;)
- {
- readBuffer.startFrame = frameNeeded;
- readBuffer.numFrames = framesPerIndexRead;
-
- if (device->cdH->readAudio (&readBuffer, (false) ? device->overlapBuffer : 0))
- break;
- }
-
- if (i < 0)
- break;
-
- if (readBuffer.index > last && readBuffer.index > 1)
- {
- last = readBuffer.index;
- indexes.add (pos);
- }
-
- pos += samplesPerFrame * framesPerIndexRead;
- }
-
- indexes.removeValue (trackStart);
- }
-
- return indexes;
- }
-
- int AudioCDReader::getCDDBId()
- {
- refreshTrackLengths();
-
- if (numTracks > 0)
- {
- TOC toc;
- zerostruct (toc);
-
- if (((CDDeviceWrapper*) handle)->cdH->readTOC (&toc, true))
- {
- int n = 0;
-
- for (int i = numTracks; --i >= 0;)
- {
- int j = getMSFAddressOf (&toc.tracks[i]);
-
- while (j > 0)
- {
- n += (j % 10);
- j /= 10;
- }
- }
-
- if (n != 0)
- {
- const int t = getMSFAddressOf (&toc.tracks[numTracks])
- - getMSFAddressOf (&toc.tracks[0]);
-
- return ((n % 0xff) << 24) | (t << 8) | numTracks;
- }
- }
- }
-
- return 0;
- }
-
- void AudioCDReader::ejectDisk()
- {
- ((CDDeviceWrapper*) handle)->cdH->openDrawer (true);
- }
-
- #if JUCE_USE_CDBURNER
-
- static IDiscRecorder* enumCDBurners (StringArray* list, int indexToOpen, IDiscMaster** master)
- {
- CoInitialize (0);
-
- IDiscMaster* dm;
- IDiscRecorder* result = 0;
-
- if (SUCCEEDED (CoCreateInstance (CLSID_MSDiscMasterObj, 0,
- CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER,
- IID_IDiscMaster,
- (void**) &dm)))
- {
- if (SUCCEEDED (dm->Open()))
- {
- IEnumDiscRecorders* drEnum = 0;
-
- if (SUCCEEDED (dm->EnumDiscRecorders (&drEnum)))
- {
- IDiscRecorder* dr = 0;
- DWORD dummy;
- int index = 0;
-
- while (drEnum->Next (1, &dr, &dummy) == S_OK)
- {
- if (indexToOpen == index)
- {
- result = dr;
- break;
- }
- else if (list != 0)
- {
- BSTR path;
-
- if (SUCCEEDED (dr->GetPath (&path)))
- list->add ((const WCHAR*) path);
- }
-
- ++index;
- dr->Release();
- }
-
- drEnum->Release();
- }
-
- /*if (redbookFormat != 0)
- {
- IEnumDiscMasterFormats* mfEnum;
-
- if (SUCCEEDED (dm->EnumDiscMasterFormats (&mfEnum)))
- {
- IID formatIID;
- DWORD dummy;
-
- while (mfEnum->Next (1, &formatIID, &dummy) == S_OK)
- {
- }
-
- mfEnum->Release();
- }
-
- redbookFormat
- }*/
-
- if (master == 0)
- dm->Close();
- }
-
- if (master != 0)
- *master = dm;
- else
- dm->Release();
- }
-
- return result;
- }
-
- const StringArray AudioCDBurner::findAvailableDevices()
- {
- StringArray devs;
- enumCDBurners (&devs, -1, 0);
- return devs;
- }
-
- AudioCDBurner* AudioCDBurner::openDevice (const int deviceIndex)
- {
- AudioCDBurner* b = new AudioCDBurner (deviceIndex);
-
- if (b->internal == 0)
- deleteAndZero (b);
-
- return b;
- }
-
- class CDBurnerInfo : public IDiscMasterProgressEvents
- {
- public:
- CDBurnerInfo()
- : refCount (1),
- progress (0),
- shouldCancel (false),
- listener (0)
- {
- }
-
- ~CDBurnerInfo()
- {
- }
-
- HRESULT __stdcall QueryInterface (REFIID id, void __RPC_FAR* __RPC_FAR* result)
- {
- if (result == 0)
- return E_POINTER;
-
- if (id == IID_IUnknown || id == IID_IDiscMasterProgressEvents)
- {
- AddRef();
- *result = this;
- return S_OK;
- }
-
- *result = 0;
- return E_NOINTERFACE;
- }
-
- ULONG __stdcall AddRef() { return ++refCount; }
- ULONG __stdcall Release() { jassert (refCount > 0); const int r = --refCount; if (r == 0) delete this; return r; }
-
- HRESULT __stdcall QueryCancel (boolean* pbCancel)
- {
- if (listener != 0 && ! shouldCancel)
- shouldCancel = listener->audioCDBurnProgress (progress);
-
- *pbCancel = shouldCancel;
-
- return S_OK;
- }
-
- HRESULT __stdcall NotifyBlockProgress (long nCompleted, long nTotal)
- {
- progress = nCompleted / (float) nTotal;
- shouldCancel = listener != 0 && listener->audioCDBurnProgress (progress);
-
- return E_NOTIMPL;
- }
-
- HRESULT __stdcall NotifyPnPActivity (void) { return E_NOTIMPL; }
- HRESULT __stdcall NotifyAddProgress (long /*nCompletedSteps*/, long /*nTotalSteps*/) { return E_NOTIMPL; }
- HRESULT __stdcall NotifyTrackProgress (long /*nCurrentTrack*/, long /*nTotalTracks*/) { return E_NOTIMPL; }
- HRESULT __stdcall NotifyPreparingBurn (long /*nEstimatedSeconds*/) { return E_NOTIMPL; }
- HRESULT __stdcall NotifyClosingDisc (long /*nEstimatedSeconds*/) { return E_NOTIMPL; }
- HRESULT __stdcall NotifyBurnComplete (HRESULT /*status*/) { return E_NOTIMPL; }
- HRESULT __stdcall NotifyEraseComplete (HRESULT /*status*/) { return E_NOTIMPL; }
-
- IDiscMaster* discMaster;
- IDiscRecorder* discRecorder;
- IRedbookDiscMaster* redbook;
- AudioCDBurner::BurnProgressListener* listener;
- float progress;
- bool shouldCancel;
-
- private:
- int refCount;
- };
-
- AudioCDBurner::AudioCDBurner (const int deviceIndex)
- : internal (0)
- {
- IDiscMaster* discMaster;
- IDiscRecorder* dr = enumCDBurners (0, deviceIndex, &discMaster);
-
- if (dr != 0)
- {
- IRedbookDiscMaster* redbook;
- HRESULT hr = discMaster->SetActiveDiscMasterFormat (IID_IRedbookDiscMaster, (void**) &redbook);
-
- hr = discMaster->SetActiveDiscRecorder (dr);
-
- CDBurnerInfo* const info = new CDBurnerInfo();
- internal = info;
-
- info->discMaster = discMaster;
- info->discRecorder = dr;
- info->redbook = redbook;
- }
- }
-
- AudioCDBurner::~AudioCDBurner()
- {
- CDBurnerInfo* const info = (CDBurnerInfo*) internal;
-
- if (info != 0)
- {
- info->discRecorder->Close();
- info->redbook->Release();
- info->discRecorder->Release();
- info->discMaster->Release();
-
- info->Release();
- }
- }
-
- bool AudioCDBurner::isDiskPresent() const
- {
- CDBurnerInfo* const info = (CDBurnerInfo*) internal;
-
- HRESULT hr = info->discRecorder->OpenExclusive();
-
- long type, flags;
- hr = info->discRecorder->QueryMediaType (&type, &flags);
-
- info->discRecorder->Close();
- return hr == S_OK && type != 0 && (flags & MEDIA_WRITABLE) != 0;
- }
-
- int AudioCDBurner::getNumAvailableAudioBlocks() const
- {
- CDBurnerInfo* const info = (CDBurnerInfo*) internal;
- long blocksFree = 0;
- info->redbook->GetAvailableAudioTrackBlocks (&blocksFree);
- return blocksFree;
- }
-
- const String AudioCDBurner::burn (AudioCDBurner::BurnProgressListener* listener,
- const bool ejectDiscAfterwards,
- const bool performFakeBurnForTesting)
- {
- CDBurnerInfo* const info = (CDBurnerInfo*) internal;
-
- info->listener = listener;
- info->progress = 0;
- info->shouldCancel = false;
-
- UINT_PTR cookie;
- HRESULT hr = info->discMaster->ProgressAdvise (info, &cookie);
-
- hr = info->discMaster->RecordDisc (performFakeBurnForTesting,
- ejectDiscAfterwards);
-
- String error;
- if (hr != S_OK)
- {
- const char* e = "Couldn't open or write to the CD device";
-
- if (hr == IMAPI_E_USERABORT)
- e = "User cancelled the write operation";
- else if (hr == IMAPI_E_MEDIUM_NOTPRESENT || hr == IMAPI_E_TRACKOPEN)
- e = "No Disk present";
-
- error = e;
- }
-
- info->discMaster->ProgressUnadvise (cookie);
- info->listener = 0;
-
- return error;
- }
-
- bool AudioCDBurner::addAudioTrack (AudioSource* source, int numSamples)
- {
- if (source == 0)
- return false;
-
- CDBurnerInfo* const info = (CDBurnerInfo*) internal;
-
- long bytesPerBlock;
- HRESULT hr = info->redbook->GetAudioBlockSize (&bytesPerBlock);
-
- const int samplesPerBlock = bytesPerBlock / 4;
- bool ok = true;
-
- hr = info->redbook->CreateAudioTrack ((long) numSamples / (bytesPerBlock * 4));
-
- byte* const buffer = (byte*) juce_malloc (bytesPerBlock);
-
- AudioSampleBuffer sourceBuffer (2, samplesPerBlock);
- int samplesDone = 0;
-
- source->prepareToPlay (samplesPerBlock, 44100.0);
-
- while (ok)
- {
- {
- AudioSourceChannelInfo info;
- info.buffer = &sourceBuffer;
- info.numSamples = samplesPerBlock;
- info.startSample = 0;
- sourceBuffer.clear();
-
- source->getNextAudioBlock (info);
- }
-
- zeromem (buffer, bytesPerBlock);
-
- AudioDataConverters::convertFloatToInt16LE (sourceBuffer.getSampleData (0, 0),
- buffer, samplesPerBlock, 4);
-
- AudioDataConverters::convertFloatToInt16LE (sourceBuffer.getSampleData (1, 0),
- buffer + 2, samplesPerBlock, 4);
-
- hr = info->redbook->AddAudioTrackBlocks (buffer, bytesPerBlock);
-
- if (hr != S_OK)
- ok = false;
-
- samplesDone += samplesPerBlock;
-
- if (samplesDone >= numSamples)
- break;
- }
-
- juce_free (buffer);
-
- hr = info->redbook->CloseAudioTrack();
-
- delete source;
-
- return ok && hr == S_OK;
- }
-
- #endif
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_win32_AudioCDReader.cpp *********/
-
- /********* Start of inlined file: juce_win32_DirectSound.cpp *********/
-
- extern "C"
- {
-
- // Declare just the minimum number of interfaces for the DSound objects that we need..
- typedef struct typeDSBUFFERDESC
- {
- DWORD dwSize;
- DWORD dwFlags;
- DWORD dwBufferBytes;
- DWORD dwReserved;
- LPWAVEFORMATEX lpwfxFormat;
- GUID guid3DAlgorithm;
- } DSBUFFERDESC;
-
- struct IDirectSoundBuffer;
-
- #undef INTERFACE
- #define INTERFACE IDirectSound
- DECLARE_INTERFACE_(IDirectSound, IUnknown)
- {
- STDMETHOD(QueryInterface) (THIS_ REFIID, LPVOID*) PURE;
- STDMETHOD_(ULONG,AddRef) (THIS) PURE;
- STDMETHOD_(ULONG,Release) (THIS) PURE;
- STDMETHOD(CreateSoundBuffer) (THIS_ DSBUFFERDESC*, IDirectSoundBuffer**, LPUNKNOWN) PURE;
- STDMETHOD(GetCaps) (THIS_ void*) PURE;
- STDMETHOD(DuplicateSoundBuffer) (THIS_ IDirectSoundBuffer*, IDirectSoundBuffer**) PURE;
- STDMETHOD(SetCooperativeLevel) (THIS_ HWND, DWORD) PURE;
- STDMETHOD(Compact) (THIS) PURE;
- STDMETHOD(GetSpeakerConfig) (THIS_ LPDWORD) PURE;
- STDMETHOD(SetSpeakerConfig) (THIS_ DWORD) PURE;
- STDMETHOD(Initialize) (THIS_ const GUID*) PURE;
- };
-
- #undef INTERFACE
- #define INTERFACE IDirectSoundBuffer
- DECLARE_INTERFACE_(IDirectSoundBuffer, IUnknown)
- {
- STDMETHOD(QueryInterface) (THIS_ REFIID, LPVOID*) PURE;
- STDMETHOD_(ULONG,AddRef) (THIS) PURE;
- STDMETHOD_(ULONG,Release) (THIS) PURE;
- STDMETHOD(GetCaps) (THIS_ void*) PURE;
- STDMETHOD(GetCurrentPosition) (THIS_ LPDWORD, LPDWORD) PURE;
- STDMETHOD(GetFormat) (THIS_ LPWAVEFORMATEX, DWORD, LPDWORD) PURE;
- STDMETHOD(GetVolume) (THIS_ LPLONG) PURE;
- STDMETHOD(GetPan) (THIS_ LPLONG) PURE;
- STDMETHOD(GetFrequency) (THIS_ LPDWORD) PURE;
- STDMETHOD(GetStatus) (THIS_ LPDWORD) PURE;
- STDMETHOD(Initialize) (THIS_ IDirectSound*, DSBUFFERDESC*) PURE;
- STDMETHOD(Lock) (THIS_ DWORD, DWORD, LPVOID*, LPDWORD, LPVOID*, LPDWORD, DWORD) PURE;
- STDMETHOD(Play) (THIS_ DWORD, DWORD, DWORD) PURE;
- STDMETHOD(SetCurrentPosition) (THIS_ DWORD) PURE;
- STDMETHOD(SetFormat) (THIS_ const WAVEFORMATEX*) PURE;
- STDMETHOD(SetVolume) (THIS_ LONG) PURE;
- STDMETHOD(SetPan) (THIS_ LONG) PURE;
- STDMETHOD(SetFrequency) (THIS_ DWORD) PURE;
- STDMETHOD(Stop) (THIS) PURE;
- STDMETHOD(Unlock) (THIS_ LPVOID, DWORD, LPVOID, DWORD) PURE;
- STDMETHOD(Restore) (THIS) PURE;
- };
-
- typedef struct typeDSCBUFFERDESC
- {
- DWORD dwSize;
- DWORD dwFlags;
- DWORD dwBufferBytes;
- DWORD dwReserved;
- LPWAVEFORMATEX lpwfxFormat;
- } DSCBUFFERDESC;
-
- struct IDirectSoundCaptureBuffer;
-
- #undef INTERFACE
- #define INTERFACE IDirectSoundCapture
- DECLARE_INTERFACE_(IDirectSoundCapture, IUnknown)
- {
- STDMETHOD(QueryInterface) (THIS_ REFIID, LPVOID*) PURE;
- STDMETHOD_(ULONG,AddRef) (THIS) PURE;
- STDMETHOD_(ULONG,Release) (THIS) PURE;
- STDMETHOD(CreateCaptureBuffer) (THIS_ DSCBUFFERDESC*, IDirectSoundCaptureBuffer**, LPUNKNOWN) PURE;
- STDMETHOD(GetCaps) (THIS_ void*) PURE;
- STDMETHOD(Initialize) (THIS_ const GUID*) PURE;
- };
-
- #undef INTERFACE
- #define INTERFACE IDirectSoundCaptureBuffer
- DECLARE_INTERFACE_(IDirectSoundCaptureBuffer, IUnknown)
- {
- STDMETHOD(QueryInterface) (THIS_ REFIID, LPVOID*) PURE;
- STDMETHOD_(ULONG,AddRef) (THIS) PURE;
- STDMETHOD_(ULONG,Release) (THIS) PURE;
- STDMETHOD(GetCaps) (THIS_ void*) PURE;
- STDMETHOD(GetCurrentPosition) (THIS_ LPDWORD, LPDWORD) PURE;
- STDMETHOD(GetFormat) (THIS_ LPWAVEFORMATEX, DWORD, LPDWORD) PURE;
- STDMETHOD(GetStatus) (THIS_ LPDWORD) PURE;
- STDMETHOD(Initialize) (THIS_ IDirectSoundCapture*, DSCBUFFERDESC*) PURE;
- STDMETHOD(Lock) (THIS_ DWORD, DWORD, LPVOID*, LPDWORD, LPVOID*, LPDWORD, DWORD) PURE;
- STDMETHOD(Start) (THIS_ DWORD) PURE;
- STDMETHOD(Stop) (THIS) PURE;
- STDMETHOD(Unlock) (THIS_ LPVOID, DWORD, LPVOID, DWORD) PURE;
- };
-
- };
-
- BEGIN_JUCE_NAMESPACE
-
- static const String getDSErrorMessage (HRESULT hr)
- {
- const char* result = 0;
-
- switch (hr)
- {
- case MAKE_HRESULT(1, 0x878, 10):
- result = "Device already allocated";
- break;
- case MAKE_HRESULT(1, 0x878, 30):
- result = "Control unavailable";
- break;
- case E_INVALIDARG:
- result = "Invalid parameter";
- break;
- case MAKE_HRESULT(1, 0x878, 50):
- result = "Invalid call";
- break;
- case E_FAIL:
- result = "Generic error";
- break;
- case MAKE_HRESULT(1, 0x878, 70):
- result = "Priority level error";
- break;
- case E_OUTOFMEMORY:
- result = "Out of memory";
- break;
- case MAKE_HRESULT(1, 0x878, 100):
- result = "Bad format";
- break;
- case E_NOTIMPL:
- result = "Unsupported function";
- break;
- case MAKE_HRESULT(1, 0x878, 120):
- result = "No driver";
- break;
- case MAKE_HRESULT(1, 0x878, 130):
- result = "Already initialised";
- break;
- case CLASS_E_NOAGGREGATION:
- result = "No aggregation";
- break;
- case MAKE_HRESULT(1, 0x878, 150):
- result = "Buffer lost";
- break;
- case MAKE_HRESULT(1, 0x878, 160):
- result = "Another app has priority";
- break;
- case MAKE_HRESULT(1, 0x878, 170):
- result = "Uninitialised";
- break;
- case E_NOINTERFACE:
- result = "No interface";
- break;
- case S_OK:
- result = "No error";
- break;
-
- default:
- return "Unknown error: " + String ((int) hr);
- }
-
- return result;
- }
-
- #define DS_DEBUGGING 1
-
- #ifdef DS_DEBUGGING
- #define CATCH JUCE_CATCH_EXCEPTION
- #undef log
- #define log(a) Logger::writeToLog(a);
- #undef logError
- #define logError(a) logDSError(a, __LINE__);
-
- static void logDSError (HRESULT hr, int lineNum)
- {
- if (hr != S_OK)
- {
- String error ("DS error at line ");
- error << lineNum << T(" - ") << getDSErrorMessage (hr);
- log (error);
- }
- }
- #else
- #define CATCH JUCE_CATCH_ALL
- #define log(a)
- #define logError(a)
- #endif
-
- #define DSOUND_FUNCTION(functionName, params) \
- typedef HRESULT (WINAPI *type##functionName) params; \
- static type##functionName ds##functionName = 0;
-
- #define DSOUND_FUNCTION_LOAD(functionName) \
- ds##functionName = (type##functionName) GetProcAddress (h, #functionName); \
- jassert (ds##functionName != 0);
-
- typedef BOOL (CALLBACK *LPDSENUMCALLBACKW) (LPGUID, LPCWSTR, LPCWSTR, LPVOID);
- typedef BOOL (CALLBACK *LPDSENUMCALLBACKA) (LPGUID, LPCSTR, LPCSTR, LPVOID);
-
- DSOUND_FUNCTION (DirectSoundCreate, (const GUID*, IDirectSound**, LPUNKNOWN))
- DSOUND_FUNCTION (DirectSoundCaptureCreate, (const GUID*, IDirectSoundCapture**, LPUNKNOWN))
- DSOUND_FUNCTION (DirectSoundEnumerateW, (LPDSENUMCALLBACKW, LPVOID))
- DSOUND_FUNCTION (DirectSoundCaptureEnumerateW, (LPDSENUMCALLBACKW, LPVOID))
-
- static void initialiseDSoundFunctions()
- {
- if (dsDirectSoundCreate == 0)
- {
- HMODULE h = LoadLibraryA ("dsound.dll");
-
- DSOUND_FUNCTION_LOAD (DirectSoundCreate)
- DSOUND_FUNCTION_LOAD (DirectSoundCaptureCreate)
- DSOUND_FUNCTION_LOAD (DirectSoundEnumerateW)
- DSOUND_FUNCTION_LOAD (DirectSoundCaptureEnumerateW)
- }
- }
-
- class DSoundInternalOutChannel
- {
- String name;
- LPGUID guid;
- int sampleRate, bufferSizeSamples;
- float* leftBuffer;
- float* rightBuffer;
-
- IDirectSound* pDirectSound;
- IDirectSoundBuffer* pOutputBuffer;
- DWORD writeOffset;
- int totalBytesPerBuffer;
- int bytesPerBuffer;
- unsigned int lastPlayCursor;
-
- public:
- int bitDepth;
- bool doneFlag;
-
- DSoundInternalOutChannel (const String& name_,
- LPGUID guid_,
- int rate,
- int bufferSize,
- float* left,
- float* right)
- : name (name_),
- guid (guid_),
- sampleRate (rate),
- bufferSizeSamples (bufferSize),
- leftBuffer (left),
- rightBuffer (right),
- pDirectSound (0),
- pOutputBuffer (0),
- bitDepth (16)
- {
- }
-
- ~DSoundInternalOutChannel()
- {
- close();
- }
-
- void close()
- {
- HRESULT hr;
-
- if (pOutputBuffer != 0)
- {
- JUCE_TRY
- {
- log (T("closing dsound out: ") + name);
- hr = pOutputBuffer->Stop();
- logError (hr);
- }
- CATCH
-
- JUCE_TRY
- {
- hr = pOutputBuffer->Release();
- logError (hr);
- }
- CATCH
-
- pOutputBuffer = 0;
- }
-
- if (pDirectSound != 0)
- {
- JUCE_TRY
- {
- hr = pDirectSound->Release();
- logError (hr);
- }
- CATCH
-
- pDirectSound = 0;
- }
- }
-
- const String open()
- {
- log (T("opening dsound out device: ") + name
- + T(" rate=") + String (sampleRate)
- + T(" bits=") + String (bitDepth)
- + T(" buf=") + String (bufferSizeSamples));
-
- pDirectSound = 0;
- pOutputBuffer = 0;
- writeOffset = 0;
-
- String error;
- HRESULT hr = E_NOINTERFACE;
-
- if (dsDirectSoundCreate != 0)
- hr = dsDirectSoundCreate (guid, &pDirectSound, 0);
-
- if (hr == S_OK)
- {
- bytesPerBuffer = (bufferSizeSamples * (bitDepth >> 2)) & ~15;
- totalBytesPerBuffer = (3 * bytesPerBuffer) & ~15;
- const int numChannels = 2;
-
- hr = pDirectSound->SetCooperativeLevel (GetDesktopWindow(), 2 /* DSSCL_PRIORITY */);
- logError (hr);
-
- if (hr == S_OK)
- {
- IDirectSoundBuffer* pPrimaryBuffer;
-
- DSBUFFERDESC primaryDesc;
- zerostruct (primaryDesc);
-
- primaryDesc.dwSize = sizeof (DSBUFFERDESC);
- primaryDesc.dwFlags = 1 /* DSBCAPS_PRIMARYBUFFER */;
- primaryDesc.dwBufferBytes = 0;
- primaryDesc.lpwfxFormat = 0;
-
- log ("opening dsound out step 2");
- hr = pDirectSound->CreateSoundBuffer (&primaryDesc, &pPrimaryBuffer, 0);
- logError (hr);
-
- if (hr == S_OK)
- {
- WAVEFORMATEX wfFormat;
- wfFormat.wFormatTag = WAVE_FORMAT_PCM;
- wfFormat.nChannels = (unsigned short) numChannels;
- wfFormat.nSamplesPerSec = sampleRate;
- wfFormat.wBitsPerSample = (unsigned short) bitDepth;
- wfFormat.nBlockAlign = (unsigned short) (wfFormat.nChannels * wfFormat.wBitsPerSample / 8);
- wfFormat.nAvgBytesPerSec = wfFormat.nSamplesPerSec * wfFormat.nBlockAlign;
- wfFormat.cbSize = 0;
-
- hr = pPrimaryBuffer->SetFormat (&wfFormat);
- logError (hr);
-
- if (hr == S_OK)
- {
- DSBUFFERDESC secondaryDesc;
- zerostruct (secondaryDesc);
-
- secondaryDesc.dwSize = sizeof (DSBUFFERDESC);
- secondaryDesc.dwFlags = 0x8000 /* DSBCAPS_GLOBALFOCUS */
- | 0x10000 /* DSBCAPS_GETCURRENTPOSITION2 */;
- secondaryDesc.dwBufferBytes = totalBytesPerBuffer;
- secondaryDesc.lpwfxFormat = &wfFormat;
-
- hr = pDirectSound->CreateSoundBuffer (&secondaryDesc, &pOutputBuffer, 0);
- logError (hr);
-
- if (hr == S_OK)
- {
- log ("opening dsound out step 3");
-
- DWORD dwDataLen;
- unsigned char* pDSBuffData;
-
- hr = pOutputBuffer->Lock (0, totalBytesPerBuffer,
- (LPVOID*) &pDSBuffData, &dwDataLen, 0, 0, 0);
- logError (hr);
-
- if (hr == S_OK)
- {
- zeromem (pDSBuffData, dwDataLen);
-
- hr = pOutputBuffer->Unlock (pDSBuffData, dwDataLen, 0, 0);
-
- if (hr == S_OK)
- {
- hr = pOutputBuffer->SetCurrentPosition (0);
-
- if (hr == S_OK)
- {
- hr = pOutputBuffer->Play (0, 0, 1 /* DSBPLAY_LOOPING */);
-
- if (hr == S_OK)
- return String::empty;
- }
- }
- }
- }
- }
- }
- }
- }
-
- error = getDSErrorMessage (hr);
- close();
- return error;
- }
-
- void synchronisePosition()
- {
- if (pOutputBuffer != 0)
- {
- DWORD playCursor;
- pOutputBuffer->GetCurrentPosition (&playCursor, &writeOffset);
- }
- }
-
- bool service()
- {
- if (pOutputBuffer == 0)
- return true;
-
- DWORD playCursor, writeCursor;
- HRESULT hr = pOutputBuffer->GetCurrentPosition (&playCursor, &writeCursor);
-
- if (hr != S_OK)
- {
- logError (hr);
- jassertfalse
- return true;
- }
-
- int playWriteGap = writeCursor - playCursor;
- if (playWriteGap < 0)
- playWriteGap += totalBytesPerBuffer;
-
- int bytesEmpty = playCursor - writeOffset;
-
- if (bytesEmpty < 0)
- bytesEmpty += totalBytesPerBuffer;
-
- if (bytesEmpty > (totalBytesPerBuffer - playWriteGap))
- {
- writeOffset = writeCursor;
- bytesEmpty = totalBytesPerBuffer - playWriteGap;
- }
-
- if (bytesEmpty >= bytesPerBuffer)
- {
- LPBYTE lpbuf1 = 0;
- LPBYTE lpbuf2 = 0;
- DWORD dwSize1 = 0;
- DWORD dwSize2 = 0;
-
- HRESULT hr = pOutputBuffer->Lock (writeOffset,
- bytesPerBuffer,
- (void**) &lpbuf1, &dwSize1,
- (void**) &lpbuf2, &dwSize2, 0);
-
- if (hr == MAKE_HRESULT (1, 0x878, 150)) // DSERR_BUFFERLOST
- {
- pOutputBuffer->Restore();
-
- hr = pOutputBuffer->Lock (writeOffset,
- bytesPerBuffer,
- (void**) &lpbuf1, &dwSize1,
- (void**) &lpbuf2, &dwSize2, 0);
- }
-
- if (hr == S_OK)
- {
- if (bitDepth == 16)
- {
- const float gainL = 32767.0f;
- const float gainR = 32767.0f;
-
- int* dest = (int*)lpbuf1;
- const float* left = leftBuffer;
- const float* right = rightBuffer;
- int samples1 = dwSize1 >> 2;
- int samples2 = dwSize2 >> 2;
-
- if (left == 0)
- {
- while (--samples1 >= 0)
- {
- int r = roundFloatToInt (gainR * *right++);
-
- if (r < -32768)
- r = -32768;
- else if (r > 32767)
- r = 32767;
-
- *dest++ = (r << 16);
- }
-
- dest = (int*)lpbuf2;
-
- while (--samples2 >= 0)
- {
- int r = roundFloatToInt (gainR * *right++);
-
- if (r < -32768)
- r = -32768;
- else if (r > 32767)
- r = 32767;
-
- *dest++ = (r << 16);
- }
- }
- else if (right == 0)
- {
- while (--samples1 >= 0)
- {
- int l = roundFloatToInt (gainL * *left++);
-
- if (l < -32768)
- l = -32768;
- else if (l > 32767)
- l = 32767;
-
- l &= 0xffff;
-
- *dest++ = l;
- }
-
- dest = (int*)lpbuf2;
-
- while (--samples2 >= 0)
- {
- int l = roundFloatToInt (gainL * *left++);
-
- if (l < -32768)
- l = -32768;
- else if (l > 32767)
- l = 32767;
-
- l &= 0xffff;
-
- *dest++ = l;
- }
- }
- else
- {
- while (--samples1 >= 0)
- {
- int l = roundFloatToInt (gainL * *left++);
-
- if (l < -32768)
- l = -32768;
- else if (l > 32767)
- l = 32767;
-
- l &= 0xffff;
-
- int r = roundFloatToInt (gainR * *right++);
-
- if (r < -32768)
- r = -32768;
- else if (r > 32767)
- r = 32767;
-
- *dest++ = (r << 16) | l;
- }
-
- dest = (int*)lpbuf2;
-
- while (--samples2 >= 0)
- {
- int l = roundFloatToInt (gainL * *left++);
-
- if (l < -32768)
- l = -32768;
- else if (l > 32767)
- l = 32767;
-
- l &= 0xffff;
-
- int r = roundFloatToInt (gainR * *right++);
-
- if (r < -32768)
- r = -32768;
- else if (r > 32767)
- r = 32767;
-
- *dest++ = (r << 16) | l;
- }
- }
- }
- else
- {
- jassertfalse
- }
-
- writeOffset = (writeOffset + dwSize1 + dwSize2) % totalBytesPerBuffer;
-
- pOutputBuffer->Unlock (lpbuf1, dwSize1, lpbuf2, dwSize2);
- }
- else
- {
- jassertfalse
- logError (hr);
- }
-
- bytesEmpty -= bytesPerBuffer;
-
- return true;
- }
- else
- {
- return false;
- }
- }
- };
-
- struct DSoundInternalInChannel
- {
- String name;
- LPGUID guid;
- int sampleRate, bufferSizeSamples;
- float* leftBuffer;
- float* rightBuffer;
-
- IDirectSound* pDirectSound;
- IDirectSoundCapture* pDirectSoundCapture;
- IDirectSoundCaptureBuffer* pInputBuffer;
-
- public:
- unsigned int readOffset;
- int bytesPerBuffer, totalBytesPerBuffer;
- int bitDepth;
- bool doneFlag;
-
- DSoundInternalInChannel (const String& name_,
- LPGUID guid_,
- int rate,
- int bufferSize,
- float* left,
- float* right)
- : name (name_),
- guid (guid_),
- sampleRate (rate),
- bufferSizeSamples (bufferSize),
- leftBuffer (left),
- rightBuffer (right),
- pDirectSound (0),
- pDirectSoundCapture (0),
- pInputBuffer (0),
- bitDepth (16)
- {
- }
-
- ~DSoundInternalInChannel()
- {
- close();
- }
-
- void close()
- {
- HRESULT hr;
-
- if (pInputBuffer != 0)
- {
- JUCE_TRY
- {
- log (T("closing dsound in: ") + name);
- hr = pInputBuffer->Stop();
- logError (hr);
- }
- CATCH
-
- JUCE_TRY
- {
- hr = pInputBuffer->Release();
- logError (hr);
- }
- CATCH
-
- pInputBuffer = 0;
- }
-
- if (pDirectSoundCapture != 0)
- {
- JUCE_TRY
- {
- hr = pDirectSoundCapture->Release();
- logError (hr);
- }
- CATCH
-
- pDirectSoundCapture = 0;
- }
-
- if (pDirectSound != 0)
- {
- JUCE_TRY
- {
- hr = pDirectSound->Release();
- logError (hr);
- }
- CATCH
-
- pDirectSound = 0;
- }
- }
-
- const String open()
- {
- log (T("opening dsound in device: ") + name
- + T(" rate=") + String (sampleRate) + T(" bits=") + String (bitDepth) + T(" buf=") + String (bufferSizeSamples));
-
- pDirectSound = 0;
- pDirectSoundCapture = 0;
- pInputBuffer = 0;
- readOffset = 0;
- totalBytesPerBuffer = 0;
-
- String error;
- HRESULT hr = E_NOINTERFACE;
-
- if (dsDirectSoundCaptureCreate != 0)
- hr = dsDirectSoundCaptureCreate (guid, &pDirectSoundCapture, 0);
-
- logError (hr);
-
- if (hr == S_OK)
- {
- const int numChannels = 2;
- bytesPerBuffer = (bufferSizeSamples * (bitDepth >> 2)) & ~15;
- totalBytesPerBuffer = (3 * bytesPerBuffer) & ~15;
-
- WAVEFORMATEX wfFormat;
- wfFormat.wFormatTag = WAVE_FORMAT_PCM;
- wfFormat.nChannels = (unsigned short)numChannels;
- wfFormat.nSamplesPerSec = sampleRate;
- wfFormat.wBitsPerSample = (unsigned short)bitDepth;
- wfFormat.nBlockAlign = (unsigned short)(wfFormat.nChannels * (wfFormat.wBitsPerSample / 8));
- wfFormat.nAvgBytesPerSec = wfFormat.nSamplesPerSec * wfFormat.nBlockAlign;
- wfFormat.cbSize = 0;
-
- DSCBUFFERDESC captureDesc;
- zerostruct (captureDesc);
-
- captureDesc.dwSize = sizeof (DSCBUFFERDESC);
- captureDesc.dwFlags = 0;
- captureDesc.dwBufferBytes = totalBytesPerBuffer;
- captureDesc.lpwfxFormat = &wfFormat;
-
- log (T("opening dsound in step 2"));
- hr = pDirectSoundCapture->CreateCaptureBuffer (&captureDesc, &pInputBuffer, 0);
-
- logError (hr);
-
- if (hr == S_OK)
- {
- hr = pInputBuffer->Start (1 /* DSCBSTART_LOOPING */);
- logError (hr);
-
- if (hr == S_OK)
- return String::empty;
- }
- }
-
- error = getDSErrorMessage (hr);
- close();
-
- return error;
- }
-
- void synchronisePosition()
- {
- if (pInputBuffer != 0)
- {
- DWORD capturePos;
- pInputBuffer->GetCurrentPosition (&capturePos, (DWORD*)&readOffset);
- }
- }
-
- bool service()
- {
- if (pInputBuffer == 0)
- return true;
-
- DWORD capturePos, readPos;
- HRESULT hr = pInputBuffer->GetCurrentPosition (&capturePos, &readPos);
- logError (hr);
-
- if (hr != S_OK)
- return true;
-
- int bytesFilled = readPos - readOffset;
- if (bytesFilled < 0)
- bytesFilled += totalBytesPerBuffer;
-
- if (bytesFilled >= bytesPerBuffer)
- {
- LPBYTE lpbuf1 = 0;
- LPBYTE lpbuf2 = 0;
- DWORD dwsize1 = 0;
- DWORD dwsize2 = 0;
-
- HRESULT hr = pInputBuffer->Lock (readOffset,
- bytesPerBuffer,
- (void**) &lpbuf1, &dwsize1,
- (void**) &lpbuf2, &dwsize2, 0);
-
- if (hr == S_OK)
- {
- if (bitDepth == 16)
- {
- const float g = 1.0f / 32768.0f;
-
- float* destL = leftBuffer;
- float* destR = rightBuffer;
- int samples1 = dwsize1 >> 2;
- int samples2 = dwsize2 >> 2;
-
- const short* src = (const short*)lpbuf1;
-
- if (destL == 0)
- {
- while (--samples1 >= 0)
- {
- ++src;
- *destR++ = *src++ * g;
- }
-
- src = (const short*)lpbuf2;
-
- while (--samples2 >= 0)
- {
- ++src;
- *destR++ = *src++ * g;
- }
- }
- else if (destR == 0)
- {
- while (--samples1 >= 0)
- {
- *destL++ = *src++ * g;
- ++src;
- }
-
- src = (const short*)lpbuf2;
-
- while (--samples2 >= 0)
- {
- *destL++ = *src++ * g;
- ++src;
- }
- }
- else
- {
- while (--samples1 >= 0)
- {
- *destL++ = *src++ * g;
- *destR++ = *src++ * g;
- }
-
- src = (const short*)lpbuf2;
-
- while (--samples2 >= 0)
- {
- *destL++ = *src++ * g;
- *destR++ = *src++ * g;
- }
- }
- }
- else
- {
- jassertfalse
- }
-
- readOffset = (readOffset + dwsize1 + dwsize2) % totalBytesPerBuffer;
-
- pInputBuffer->Unlock (lpbuf1, dwsize1, lpbuf2, dwsize2);
- }
- else
- {
- logError (hr);
- jassertfalse
- }
-
- bytesFilled -= bytesPerBuffer;
-
- return true;
- }
- else
- {
- return false;
- }
- }
- };
-
- class DSoundAudioIODevice : public AudioIODevice,
- public Thread
- {
- public:
- DSoundAudioIODevice (const String& deviceName,
- const int outputDeviceIndex_,
- const int inputDeviceIndex_)
- : AudioIODevice (deviceName, "DirectSound"),
- Thread ("Juce DSound"),
- isOpen_ (false),
- isStarted (false),
- outputDeviceIndex (outputDeviceIndex_),
- inputDeviceIndex (inputDeviceIndex_),
- inChans (4),
- outChans (4),
- numInputBuffers (0),
- numOutputBuffers (0),
- totalSamplesOut (0),
- sampleRate (0.0),
- inputBuffers (0),
- outputBuffers (0),
- callback (0),
- bufferSizeSamples (0)
- {
- if (outputDeviceIndex_ >= 0)
- {
- outChannels.add (TRANS("Left"));
- outChannels.add (TRANS("Right"));
- }
-
- if (inputDeviceIndex_ >= 0)
- {
- inChannels.add (TRANS("Left"));
- inChannels.add (TRANS("Right"));
- }
- }
-
- ~DSoundAudioIODevice()
- {
- close();
- }
-
- const StringArray getOutputChannelNames()
- {
- return outChannels;
- }
-
- const StringArray getInputChannelNames()
- {
- return inChannels;
- }
-
- int getNumSampleRates()
- {
- return 4;
- }
-
- double getSampleRate (int index)
- {
- const double samps[] = { 44100.0, 48000.0, 88200.0, 96000.0 };
-
- return samps [jlimit (0, 3, index)];
- }
-
- int getNumBufferSizesAvailable()
- {
- return 50;
- }
-
- int getBufferSizeSamples (int index)
- {
- int n = 64;
- for (int i = 0; i < index; ++i)
- n += (n < 512) ? 32
- : ((n < 1024) ? 64
- : ((n < 2048) ? 128 : 256));
-
- return n;
- }
-
- int getDefaultBufferSize()
- {
- return 2560;
- }
-
- const String open (const BitArray& inputChannels,
- const BitArray& outputChannels,
- double sampleRate,
- int bufferSizeSamples)
- {
- lastError = openDevice (inputChannels, outputChannels, sampleRate, bufferSizeSamples);
- isOpen_ = lastError.isEmpty();
-
- return lastError;
- }
-
- void close()
- {
- stop();
-
- if (isOpen_)
- {
- closeDevice();
- isOpen_ = false;
- }
- }
-
- bool isOpen()
- {
- return isOpen_ && isThreadRunning();
- }
-
- int getCurrentBufferSizeSamples()
- {
- return bufferSizeSamples;
- }
-
- double getCurrentSampleRate()
- {
- return sampleRate;
- }
-
- int getCurrentBitDepth()
- {
- int i, bits = 256;
-
- for (i = inChans.size(); --i >= 0;)
- bits = jmin (bits, inChans[i]->bitDepth);
-
- for (i = outChans.size(); --i >= 0;)
- bits = jmin (bits, outChans[i]->bitDepth);
-
- if (bits > 32)
- bits = 16;
-
- return bits;
- }
-
- const BitArray getActiveOutputChannels() const
- {
- return enabledOutputs;
- }
-
- const BitArray getActiveInputChannels() const
- {
- return enabledInputs;
- }
-
- int getOutputLatencyInSamples()
- {
- return (int) (getCurrentBufferSizeSamples() * 1.5);
- }
-
- int getInputLatencyInSamples()
- {
- return getOutputLatencyInSamples();
- }
-
- void start (AudioIODeviceCallback* call)
- {
- if (isOpen_ && call != 0 && ! isStarted)
- {
- if (! isThreadRunning())
- {
- // something gone wrong and the thread's stopped..
- isOpen_ = false;
- return;
- }
-
- call->audioDeviceAboutToStart (this);
-
- const ScopedLock sl (startStopLock);
- callback = call;
- isStarted = true;
- }
- }
-
- void stop()
- {
- if (isStarted)
- {
- AudioIODeviceCallback* const callbackLocal = callback;
-
- {
- const ScopedLock sl (startStopLock);
- isStarted = false;
- }
-
- if (callbackLocal != 0)
- callbackLocal->audioDeviceStopped();
- }
- }
-
- bool isPlaying()
- {
- return isStarted && isOpen_ && isThreadRunning();
- }
-
- const String getLastError()
- {
- return lastError;
- }
-
- juce_UseDebuggingNewOperator
-
- StringArray inChannels, outChannels;
- int outputDeviceIndex, inputDeviceIndex;
-
- private:
- bool isOpen_;
- bool isStarted;
- String lastError;
-
- OwnedArray <DSoundInternalInChannel> inChans;
- OwnedArray <DSoundInternalOutChannel> outChans;
- WaitableEvent startEvent;
-
- int numInputBuffers, numOutputBuffers, bufferSizeSamples;
- int volatile totalSamplesOut;
- int64 volatile lastBlockTime;
- double sampleRate;
- BitArray enabledInputs, enabledOutputs;
- float** inputBuffers;
- float** outputBuffers;
-
- AudioIODeviceCallback* callback;
- CriticalSection startStopLock;
-
- DSoundAudioIODevice (const DSoundAudioIODevice&);
- const DSoundAudioIODevice& operator= (const DSoundAudioIODevice&);
-
- const String openDevice (const BitArray& inputChannels,
- const BitArray& outputChannels,
- double sampleRate_,
- int bufferSizeSamples_);
-
- void closeDevice()
- {
- isStarted = false;
- stopThread (5000);
-
- inChans.clear();
- outChans.clear();
-
- int i;
- for (i = 0; i < numInputBuffers; ++i)
- juce_free (inputBuffers[i]);
-
- delete[] inputBuffers;
- inputBuffers = 0;
- numInputBuffers = 0;
-
- for (i = 0; i < numOutputBuffers; ++i)
- juce_free (outputBuffers[i]);
-
- delete[] outputBuffers;
- outputBuffers = 0;
- numOutputBuffers = 0;
- }
-
- void resync()
- {
- int i;
- for (i = outChans.size(); --i >= 0;)
- outChans.getUnchecked(i)->close();
-
- for (i = inChans.size(); --i >= 0;)
- inChans.getUnchecked(i)->close();
-
- if (threadShouldExit())
- return;
-
- // boost our priority while opening the devices to try to get better sync between them
- const int oldThreadPri = GetThreadPriority (GetCurrentThread());
- const int oldProcPri = GetPriorityClass (GetCurrentProcess());
- SetThreadPriority (GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
- SetPriorityClass (GetCurrentProcess(), REALTIME_PRIORITY_CLASS);
-
- for (i = outChans.size(); --i >= 0;)
- outChans.getUnchecked(i)->open();
-
- for (i = inChans.size(); --i >= 0;)
- inChans.getUnchecked(i)->open();
-
- if (! threadShouldExit())
- {
- sleep (5);
-
- for (i = 0; i < outChans.size(); ++i)
- outChans.getUnchecked(i)->synchronisePosition();
-
- for (i = 0; i < inChans.size(); ++i)
- inChans.getUnchecked(i)->synchronisePosition();
- }
-
- SetThreadPriority (GetCurrentThread(), oldThreadPri);
- SetPriorityClass (GetCurrentProcess(), oldProcPri);
- }
-
- public:
- void run()
- {
- while (! threadShouldExit())
- {
- if (wait (100))
- break;
- }
-
- const int latencyMs = (int) (bufferSizeSamples * 1000.0 / sampleRate);
- const int maxTimeMS = jmax (5, 3 * latencyMs);
-
- while (! threadShouldExit())
- {
- int numToDo = 0;
- uint32 startTime = Time::getMillisecondCounter();
-
- int i;
- for (i = inChans.size(); --i >= 0;)
- {
- inChans.getUnchecked(i)->doneFlag = false;
- ++numToDo;
- }
-
- for (i = outChans.size(); --i >= 0;)
- {
- outChans.getUnchecked(i)->doneFlag = false;
- ++numToDo;
- }
-
- if (numToDo > 0)
- {
- const int maxCount = 3;
- int count = maxCount;
-
- for (;;)
- {
- for (i = inChans.size(); --i >= 0;)
- {
- DSoundInternalInChannel* const in = inChans.getUnchecked(i);
-
- if ((! in->doneFlag) && in->service())
- {
- in->doneFlag = true;
- --numToDo;
- }
- }
-
- for (i = outChans.size(); --i >= 0;)
- {
- DSoundInternalOutChannel* const out = outChans.getUnchecked(i);
-
- if ((! out->doneFlag) && out->service())
- {
- out->doneFlag = true;
- --numToDo;
- }
- }
-
- if (numToDo <= 0)
- break;
-
- if (Time::getMillisecondCounter() > startTime + maxTimeMS)
- {
- resync();
- break;
- }
-
- if (--count <= 0)
- {
- Sleep (1);
- count = maxCount;
- }
-
- if (threadShouldExit())
- return;
- }
- }
- else
- {
- sleep (1);
- }
-
- const ScopedLock sl (startStopLock);
-
- if (isStarted)
- {
- JUCE_TRY
- {
- callback->audioDeviceIOCallback ((const float**) inputBuffers,
- numInputBuffers,
- outputBuffers,
- numOutputBuffers,
- bufferSizeSamples);
- }
- JUCE_CATCH_EXCEPTION
-
- totalSamplesOut += bufferSizeSamples;
- }
- else
- {
- for (i = 0; i < numOutputBuffers; ++i)
- if (outputBuffers[i] != 0)
- zeromem (outputBuffers[i], bufferSizeSamples * sizeof (float));
-
- totalSamplesOut = 0;
- sleep (1);
- }
- }
- }
- };
-
- class DSoundAudioIODeviceType : public AudioIODeviceType
- {
- public:
- DSoundAudioIODeviceType()
- : AudioIODeviceType (T("DirectSound")),
- hasScanned (false)
- {
- initialiseDSoundFunctions();
- }
-
- ~DSoundAudioIODeviceType()
- {
- }
-
- void scanForDevices()
- {
- hasScanned = true;
-
- outputDeviceNames.clear();
- outputGuids.clear();
- inputDeviceNames.clear();
- inputGuids.clear();
-
- if (dsDirectSoundEnumerateW != 0)
- {
- dsDirectSoundEnumerateW (outputEnumProcW, this);
- dsDirectSoundCaptureEnumerateW (inputEnumProcW, this);
- }
- }
-
- const StringArray getDeviceNames (const bool wantInputNames) const
- {
- jassert (hasScanned); // need to call scanForDevices() before doing this
-
- return wantInputNames ? inputDeviceNames
- : outputDeviceNames;
- }
-
- int getDefaultDeviceIndex (const bool /*forInput*/) const
- {
- jassert (hasScanned); // need to call scanForDevices() before doing this
- return 0;
- }
-
- int getIndexOfDevice (AudioIODevice* device, const bool asInput) const
- {
- jassert (hasScanned); // need to call scanForDevices() before doing this
-
- DSoundAudioIODevice* const d = dynamic_cast <DSoundAudioIODevice*> (device);
- if (d == 0)
- return -1;
-
- return asInput ? d->inputDeviceIndex
- : d->outputDeviceIndex;
- }
-
- bool hasSeparateInputsAndOutputs() const { return true; }
-
- AudioIODevice* createDevice (const String& outputDeviceName,
- const String& inputDeviceName)
- {
- jassert (hasScanned); // need to call scanForDevices() before doing this
-
- const int outputIndex = outputDeviceNames.indexOf (outputDeviceName);
- const int inputIndex = inputDeviceNames.indexOf (inputDeviceName);
-
- if (outputIndex >= 0 || inputIndex >= 0)
- return new DSoundAudioIODevice (outputDeviceName.isNotEmpty() ? outputDeviceName
- : inputDeviceName,
- outputIndex, inputIndex);
-
- return 0;
- }
-
- juce_UseDebuggingNewOperator
-
- StringArray outputDeviceNames;
- OwnedArray <GUID> outputGuids;
-
- StringArray inputDeviceNames;
- OwnedArray <GUID> inputGuids;
-
- private:
- bool hasScanned;
-
- BOOL outputEnumProc (LPGUID lpGUID, String desc)
- {
- desc = desc.trim();
-
- if (desc.isNotEmpty())
- {
- const String origDesc (desc);
-
- int n = 2;
- while (outputDeviceNames.contains (desc))
- desc = origDesc + T(" (") + String (n++) + T(")");
-
- outputDeviceNames.add (desc);
-
- if (lpGUID != 0)
- outputGuids.add (new GUID (*lpGUID));
- else
- outputGuids.add (0);
- }
-
- return TRUE;
- }
-
- static BOOL CALLBACK outputEnumProcW (LPGUID lpGUID, LPCWSTR description, LPCWSTR, LPVOID object)
- {
- return ((DSoundAudioIODeviceType*) object)
- ->outputEnumProc (lpGUID, String (description));
- }
-
- static BOOL CALLBACK outputEnumProcA (LPGUID lpGUID, LPCTSTR description, LPCTSTR, LPVOID object)
- {
- return ((DSoundAudioIODeviceType*) object)
- ->outputEnumProc (lpGUID, String (description));
- }
-
- BOOL CALLBACK inputEnumProc (LPGUID lpGUID, String desc)
- {
- desc = desc.trim();
-
- if (desc.isNotEmpty())
- {
- const String origDesc (desc);
-
- int n = 2;
- while (inputDeviceNames.contains (desc))
- desc = origDesc + T(" (") + String (n++) + T(")");
-
- inputDeviceNames.add (desc);
-
- if (lpGUID != 0)
- inputGuids.add (new GUID (*lpGUID));
- else
- inputGuids.add (0);
- }
-
- return TRUE;
- }
-
- static BOOL CALLBACK inputEnumProcW (LPGUID lpGUID, LPCWSTR description, LPCWSTR, LPVOID object)
- {
- return ((DSoundAudioIODeviceType*) object)
- ->inputEnumProc (lpGUID, String (description));
- }
-
- static BOOL CALLBACK inputEnumProcA (LPGUID lpGUID, LPCTSTR description, LPCTSTR, LPVOID object)
- {
- return ((DSoundAudioIODeviceType*) object)
- ->inputEnumProc (lpGUID, String (description));
- }
-
- DSoundAudioIODeviceType (const DSoundAudioIODeviceType&);
- const DSoundAudioIODeviceType& operator= (const DSoundAudioIODeviceType&);
- };
-
- AudioIODeviceType* juce_createDefaultAudioIODeviceType()
- {
- return new DSoundAudioIODeviceType();
- }
-
- const String DSoundAudioIODevice::openDevice (const BitArray& inputChannels,
- const BitArray& outputChannels,
- double sampleRate_,
- int bufferSizeSamples_)
- {
- closeDevice();
- totalSamplesOut = 0;
-
- sampleRate = sampleRate_;
-
- if (bufferSizeSamples_ <= 0)
- bufferSizeSamples_ = 960; // use as a default size if none is set.
-
- bufferSizeSamples = bufferSizeSamples_ & ~7;
-
- DSoundAudioIODeviceType dlh;
- dlh.scanForDevices();
-
- enabledInputs = inputChannels;
- enabledInputs.setRange (inChannels.size(),
- enabledInputs.getHighestBit() + 1 - inChannels.size(),
- false);
-
- numInputBuffers = enabledInputs.countNumberOfSetBits();
- inputBuffers = new float* [numInputBuffers + 2];
- zeromem (inputBuffers, sizeof (float*) * numInputBuffers + 2);
- int i, numIns = 0;
-
- for (i = 0; i <= enabledInputs.getHighestBit(); i += 2)
- {
- float* left = 0;
- float* right = 0;
-
- if (enabledInputs[i])
- left = inputBuffers[numIns++] = (float*) juce_calloc ((bufferSizeSamples + 16) * sizeof (float));
-
- if (enabledInputs[i + 1])
- right = inputBuffers[numIns++] = (float*) juce_calloc ((bufferSizeSamples + 16) * sizeof (float));
-
- if (left != 0 || right != 0)
- inChans.add (new DSoundInternalInChannel (dlh.inputDeviceNames [inputDeviceIndex],
- dlh.inputGuids [inputDeviceIndex],
- (int) sampleRate, bufferSizeSamples,
- left, right));
- }
-
- enabledOutputs = outputChannels;
- enabledOutputs.setRange (outChannels.size(),
- enabledOutputs.getHighestBit() + 1 - outChannels.size(),
- false);
-
- numOutputBuffers = enabledOutputs.countNumberOfSetBits();
- outputBuffers = new float* [numOutputBuffers + 2];
- zeromem (outputBuffers, sizeof (float*) * numOutputBuffers + 2);
- int numOuts = 0;
-
- for (i = 0; i <= enabledOutputs.getHighestBit(); i += 2)
- {
- float* left = 0;
- float* right = 0;
-
- if (enabledOutputs[i])
- left = outputBuffers[numOuts++] = (float*) juce_calloc ((bufferSizeSamples + 16) * sizeof (float));
-
- if (enabledOutputs[i + 1])
- right = outputBuffers[numOuts++] = (float*) juce_calloc ((bufferSizeSamples + 16) * sizeof (float));
-
- if (left != 0 || right != 0)
- outChans.add (new DSoundInternalOutChannel (dlh.outputDeviceNames[outputDeviceIndex],
- dlh.outputGuids [outputDeviceIndex],
- (int) sampleRate, bufferSizeSamples,
- left, right));
- }
-
- String error;
-
- // boost our priority while opening the devices to try to get better sync between them
- const int oldThreadPri = GetThreadPriority (GetCurrentThread());
- const int oldProcPri = GetPriorityClass (GetCurrentProcess());
- SetThreadPriority (GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
- SetPriorityClass (GetCurrentProcess(), REALTIME_PRIORITY_CLASS);
-
- for (i = 0; i < outChans.size(); ++i)
- {
- error = outChans[i]->open();
-
- if (error.isNotEmpty())
- {
- error = T("Error opening ") + dlh.outputDeviceNames[i]
- + T(": \"") + error + T("\"");
- break;
- }
- }
-
- if (error.isEmpty())
- {
- for (i = 0; i < inChans.size(); ++i)
- {
- error = inChans[i]->open();
-
- if (error.isNotEmpty())
- {
- error = T("Error opening ") + dlh.inputDeviceNames[i]
- + T(": \"") + error + T("\"");
- break;
- }
- }
- }
-
- if (error.isEmpty())
- {
- totalSamplesOut = 0;
-
- for (i = 0; i < outChans.size(); ++i)
- outChans.getUnchecked(i)->synchronisePosition();
-
- for (i = 0; i < inChans.size(); ++i)
- inChans.getUnchecked(i)->synchronisePosition();
-
- startThread (9);
- sleep (10);
-
- notify();
- }
- else
- {
- log (error);
- }
-
- SetThreadPriority (GetCurrentThread(), oldThreadPri);
- SetPriorityClass (GetCurrentProcess(), oldProcPri);
-
- return error;
- }
-
- #undef log
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_win32_DirectSound.cpp *********/
-
- /********* Start of inlined file: juce_win32_FileChooser.cpp *********/
- #ifdef _MSC_VER
- #pragma warning (disable: 4514)
- #pragma warning (push)
- #endif
-
- #include <shlobj.h>
-
- BEGIN_JUCE_NAMESPACE
-
- #ifdef _MSC_VER
- #pragma warning (pop)
- #endif
-
- static const void* defaultDirPath = 0;
- static String returnedString; // need this to get non-existent pathnames from the directory chooser
- static Component* currentExtraFileWin = 0;
-
- static bool areThereAnyAlwaysOnTopWindows()
- {
- for (int i = Desktop::getInstance().getNumComponents(); --i >= 0;)
- {
- Component* c = Desktop::getInstance().getComponent (i);
-
- if (c != 0 && c->isAlwaysOnTop() && c->isShowing())
- return true;
- }
-
- return false;
- }
-
- static int CALLBACK browseCallbackProc (HWND hWnd, UINT msg, LPARAM lParam, LPARAM /*lpData*/)
- {
- if (msg == BFFM_INITIALIZED)
- {
- SendMessage (hWnd, BFFM_SETSELECTIONW, TRUE, (LPARAM) defaultDirPath);
- }
- else if (msg == BFFM_VALIDATEFAILEDW)
- {
- returnedString = (LPCWSTR) lParam;
- }
- else if (msg == BFFM_VALIDATEFAILEDA)
- {
- returnedString = (const char*) lParam;
- }
-
- return 0;
- }
-
- void juce_setWindowStyleBit (HWND h, int styleType, int feature, bool bitIsSet);
-
- static UINT_PTR CALLBACK openCallback (HWND hdlg, UINT uiMsg, WPARAM /*wParam*/, LPARAM lParam)
- {
- if (currentExtraFileWin != 0)
- {
- if (uiMsg == WM_INITDIALOG)
- {
- HWND dialogH = GetParent (hdlg);
- jassert (dialogH != 0);
- if (dialogH == 0)
- dialogH = hdlg;
-
- RECT r, cr;
- GetWindowRect (dialogH, &r);
- GetClientRect (dialogH, &cr);
-
- SetWindowPos (dialogH, 0,
- r.left, r.top,
- currentExtraFileWin->getWidth() + jmax (150, r.right - r.left),
- jmax (150, r.bottom - r.top),
- SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER);
-
- currentExtraFileWin->setBounds (cr.right, cr.top, currentExtraFileWin->getWidth(), cr.bottom - cr.top);
- currentExtraFileWin->getChildComponent(0)->setBounds (0, 0, currentExtraFileWin->getWidth(), currentExtraFileWin->getHeight());
-
- SetParent ((HWND) currentExtraFileWin->getWindowHandle(), (HWND) dialogH);
- juce_setWindowStyleBit ((HWND)currentExtraFileWin->getWindowHandle(), GWL_STYLE, WS_CHILD, (dialogH != 0));
- juce_setWindowStyleBit ((HWND)currentExtraFileWin->getWindowHandle(), GWL_STYLE, WS_POPUP, (dialogH == 0));
- }
- else if (uiMsg == WM_NOTIFY)
- {
- LPOFNOTIFY ofn = (LPOFNOTIFY) lParam;
-
- if (ofn->hdr.code == CDN_SELCHANGE)
- {
- FilePreviewComponent* comp = (FilePreviewComponent*) currentExtraFileWin->getChildComponent(0);
-
- if (comp != 0)
- {
- TCHAR path [MAX_PATH * 2];
- path[0] = 0;
- CommDlg_OpenSave_GetFilePath (GetParent (hdlg), (LPARAM) &path, MAX_PATH);
-
- const String fn ((const WCHAR*) path);
-
- comp->selectedFileChanged (File (fn));
- }
- }
- }
- }
-
- return 0;
- }
-
- class FPComponentHolder : public Component
- {
- public:
- FPComponentHolder()
- {
- setVisible (true);
- setOpaque (true);
- }
-
- ~FPComponentHolder()
- {
- }
-
- void paint (Graphics& g)
- {
- g.fillAll (Colours::lightgrey);
- }
-
- private:
- FPComponentHolder (const FPComponentHolder&);
- const FPComponentHolder& operator= (const FPComponentHolder&);
- };
-
- void FileChooser::showPlatformDialog (OwnedArray<File>& results,
- const String& title,
- const File& currentFileOrDirectory,
- const String& filter,
- bool selectsDirectory,
- bool isSaveDialogue,
- bool warnAboutOverwritingExistingFiles,
- bool selectMultipleFiles,
- FilePreviewComponent* extraInfoComponent)
- {
- const int numCharsAvailable = 32768;
- MemoryBlock filenameSpace ((numCharsAvailable + 1) * sizeof (WCHAR), true);
- WCHAR* const fname = (WCHAR*) filenameSpace.getData();
- int fnameIdx = 0;
-
- JUCE_TRY
- {
- // use a modal window as the parent for this dialog box
- // to block input from other app windows
- const Rectangle mainMon (Desktop::getInstance().getMainMonitorArea());
-
- Component w (String::empty);
- w.setBounds (mainMon.getX() + mainMon.getWidth() / 4,
- mainMon.getY() + mainMon.getHeight() / 4,
- 0, 0);
- w.setOpaque (true);
- w.setAlwaysOnTop (areThereAnyAlwaysOnTopWindows());
- w.addToDesktop (0);
-
- if (extraInfoComponent == 0)
- w.enterModalState();
-
- String initialDir;
-
- if (currentFileOrDirectory.isDirectory())
- {
- initialDir = currentFileOrDirectory.getFullPathName();
- }
- else
- {
- currentFileOrDirectory.getFileName().copyToBuffer (fname, numCharsAvailable);
-
- initialDir = currentFileOrDirectory.getParentDirectory().getFullPathName();
- }
-
- if (currentExtraFileWin->isValidComponent())
- {
- jassertfalse
- return;
- }
-
- if (selectsDirectory)
- {
- LPITEMIDLIST list = 0;
- filenameSpace.fillWith (0);
-
- {
- BROWSEINFO bi;
- zerostruct (bi);
-
- bi.hwndOwner = (HWND) w.getWindowHandle();
- bi.pszDisplayName = fname;
- bi.lpszTitle = title;
- bi.lpfn = browseCallbackProc;
- #ifdef BIF_USENEWUI
- bi.ulFlags = BIF_USENEWUI | BIF_VALIDATE;
- #else
- bi.ulFlags = 0x50;
- #endif
- defaultDirPath = (const WCHAR*) initialDir;
-
- list = SHBrowseForFolder (&bi);
-
- if (! SHGetPathFromIDListW (list, fname))
- {
- fname[0] = 0;
- returnedString = String::empty;
- }
- }
-
- LPMALLOC al;
- if (list != 0 && SUCCEEDED (SHGetMalloc (&al)))
- al->Free (list);
-
- defaultDirPath = 0;
-
- if (returnedString.isNotEmpty())
- {
- const String stringFName (fname);
-
- results.add (new File (File (stringFName).getSiblingFile (returnedString)));
- returnedString = String::empty;
-
- return;
- }
- }
- else
- {
- DWORD flags = OFN_EXPLORER | OFN_PATHMUSTEXIST | OFN_NOCHANGEDIR | OFN_HIDEREADONLY;
-
- if (warnAboutOverwritingExistingFiles)
- flags |= OFN_OVERWRITEPROMPT;
-
- if (selectMultipleFiles)
- flags |= OFN_ALLOWMULTISELECT;
-
- if (extraInfoComponent != 0)
- {
- flags |= OFN_ENABLEHOOK;
-
- currentExtraFileWin = new FPComponentHolder();
- currentExtraFileWin->addAndMakeVisible (extraInfoComponent);
- currentExtraFileWin->setSize (jlimit (20, 800, extraInfoComponent->getWidth()),
- extraInfoComponent->getHeight());
- currentExtraFileWin->addToDesktop (0);
-
- currentExtraFileWin->enterModalState();
- }
-
- {
- WCHAR filters [1024];
- zeromem (filters, sizeof (filters));
- filter.copyToBuffer (filters, 1024);
- filter.copyToBuffer (filters + filter.length() + 1,
- 1022 - filter.length());
-
- OPENFILENAMEW of;
- zerostruct (of);
-
- #ifdef OPENFILENAME_SIZE_VERSION_400W
- of.lStructSize = OPENFILENAME_SIZE_VERSION_400W;
- #else
- of.lStructSize = sizeof (of);
- #endif
- of.hwndOwner = (HWND) w.getWindowHandle();
- of.lpstrFilter = filters;
- of.nFilterIndex = 1;
- of.lpstrFile = fname;
- of.nMaxFile = numCharsAvailable;
- of.lpstrInitialDir = initialDir;
- of.lpstrTitle = title;
- of.Flags = flags;
-
- if (extraInfoComponent != 0)
- of.lpfnHook = &openCallback;
-
- if (isSaveDialogue)
- {
- if (! GetSaveFileName (&of))
- fname[0] = 0;
- else
- fnameIdx = of.nFileOffset;
- }
- else
- {
- if (! GetOpenFileName (&of))
- fname[0] = 0;
- else
- fnameIdx = of.nFileOffset;
- }
- }
- }
- }
- #if JUCE_CATCH_UNHANDLED_EXCEPTIONS
- catch (...)
- {
- fname[0] = 0;
- }
- #endif
-
- deleteAndZero (currentExtraFileWin);
-
- const WCHAR* const files = fname;
-
- if (selectMultipleFiles && fnameIdx > 0 && files [fnameIdx - 1] == 0)
- {
- const WCHAR* filename = files + fnameIdx;
-
- while (*filename != 0)
- {
- const String filepath (String (files) + T("\\") + String (filename));
- results.add (new File (filepath));
- filename += CharacterFunctions::length (filename) + 1;
- }
- }
- else if (files[0] != 0)
- {
- results.add (new File (files));
- }
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_win32_FileChooser.cpp *********/
-
- /********* Start of inlined file: juce_win32_Fonts.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- static int CALLBACK wfontEnum2 (ENUMLOGFONTEXW* lpelfe,
- NEWTEXTMETRICEXW*,
- int type,
- LPARAM lParam)
- {
- if (lpelfe != 0 && type == TRUETYPE_FONTTYPE)
- {
- const String fontName (lpelfe->elfLogFont.lfFaceName);
-
- ((StringArray*) lParam)->addIfNotAlreadyThere (fontName.removeCharacters (T("@")));
- }
-
- return 1;
- }
-
- static int CALLBACK wfontEnum1 (ENUMLOGFONTEXW* lpelfe,
- NEWTEXTMETRICEXW*,
- int type,
- LPARAM lParam)
- {
- if (lpelfe != 0
- && ((type & (DEVICE_FONTTYPE | RASTER_FONTTYPE)) == 0))
- {
- LOGFONTW lf;
- zerostruct (lf);
-
- lf.lfWeight = FW_DONTCARE;
- lf.lfOutPrecision = OUT_TT_ONLY_PRECIS;
- lf.lfQuality = DEFAULT_QUALITY;
- lf.lfCharSet = DEFAULT_CHARSET;
- lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
- lf.lfPitchAndFamily = FF_DONTCARE;
-
- const String fontName (lpelfe->elfLogFont.lfFaceName);
- fontName.copyToBuffer (lf.lfFaceName, LF_FACESIZE - 1);
-
- HDC dc = CreateCompatibleDC (0);
- EnumFontFamiliesEx (dc, &lf,
- (FONTENUMPROCW) &wfontEnum2,
- lParam, 0);
- DeleteDC (dc);
- }
-
- return 1;
- }
-
- const StringArray Font::findAllTypefaceNames() throw()
- {
- StringArray results;
- HDC dc = CreateCompatibleDC (0);
-
- {
- LOGFONTW lf;
- zerostruct (lf);
-
- lf.lfWeight = FW_DONTCARE;
- lf.lfOutPrecision = OUT_TT_ONLY_PRECIS;
- lf.lfQuality = DEFAULT_QUALITY;
- lf.lfCharSet = DEFAULT_CHARSET;
- lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
- lf.lfPitchAndFamily = FF_DONTCARE;
- lf.lfFaceName[0] = 0;
-
- EnumFontFamiliesEx (dc, &lf,
- (FONTENUMPROCW) &wfontEnum1,
- (LPARAM) &results, 0);
- }
-
- DeleteDC (dc);
-
- results.sort (true);
- return results;
- }
-
- extern bool juce_IsRunningInWine() throw();
-
- void Font::getDefaultFontNames (String& defaultSans,
- String& defaultSerif,
- String& defaultFixed) throw()
- {
- if (juce_IsRunningInWine())
- {
- // If we're running in Wine, then use fonts that might be available on Linux..
- defaultSans = "Bitstream Vera Sans";
- defaultSerif = "Bitstream Vera Serif";
- defaultFixed = "Bitstream Vera Sans Mono";
- }
- else
- {
- defaultSans = "Verdana";
- defaultSerif = "Times";
- defaultFixed = "Lucida Console";
- }
- }
-
- class FontDCHolder : private DeletedAtShutdown
- {
- HDC dc;
- String fontName;
- KERNINGPAIR* kps;
- int numKPs;
- bool bold, italic;
- int size;
-
- FontDCHolder (const FontDCHolder&);
- const FontDCHolder& operator= (const FontDCHolder&);
-
- public:
- HFONT fontH;
-
- FontDCHolder() throw()
- : dc (0),
- kps (0),
- numKPs (0),
- bold (false),
- italic (false),
- size (0)
- {
- }
-
- ~FontDCHolder() throw()
- {
- if (dc != 0)
- {
- DeleteDC (dc);
- DeleteObject (fontH);
- juce_free (kps);
- }
-
- clearSingletonInstance();
- }
-
- juce_DeclareSingleton_SingleThreaded_Minimal (FontDCHolder);
-
- HDC loadFont (const String& fontName_,
- const bool bold_,
- const bool italic_,
- const int size_) throw()
- {
- if (fontName != fontName_ || bold != bold_ || italic != italic_ || size != size_)
- {
- fontName = fontName_;
- bold = bold_;
- italic = italic_;
- size = size_;
-
- if (dc != 0)
- {
- DeleteDC (dc);
- DeleteObject (fontH);
-
- juce_free (kps);
- kps = 0;
- }
-
- fontH = 0;
-
- dc = CreateCompatibleDC (0);
- SetMapperFlags (dc, 0);
- SetMapMode (dc, MM_TEXT);
-
- LOGFONTW lfw;
- zerostruct (lfw);
-
- lfw.lfCharSet = DEFAULT_CHARSET;
- lfw.lfClipPrecision = CLIP_DEFAULT_PRECIS;
- lfw.lfOutPrecision = OUT_OUTLINE_PRECIS;
- lfw.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
- lfw.lfQuality = PROOF_QUALITY;
- lfw.lfItalic = (BYTE) (italic ? TRUE : FALSE);
- lfw.lfWeight = bold ? FW_BOLD : FW_NORMAL;
- fontName.copyToBuffer (lfw.lfFaceName, LF_FACESIZE - 1);
-
- lfw.lfHeight = size > 0 ? size : -256;
- HFONT standardSizedFont = CreateFontIndirect (&lfw);
-
- if (standardSizedFont != 0)
- {
- if (SelectObject (dc, standardSizedFont) != 0)
- {
- fontH = standardSizedFont;
-
- if (size == 0)
- {
- OUTLINETEXTMETRIC otm;
- if (GetOutlineTextMetrics (dc, sizeof (otm), &otm) != 0)
- {
- lfw.lfHeight = -(int) otm.otmEMSquare;
- fontH = CreateFontIndirect (&lfw);
-
- SelectObject (dc, fontH);
- DeleteObject (standardSizedFont);
- }
- }
- }
- else
- {
- jassertfalse
- }
- }
- else
- {
- jassertfalse
- }
- }
-
- return dc;
- }
-
- KERNINGPAIR* getKerningPairs (int& numKPs_) throw()
- {
- if (kps == 0)
- {
- numKPs = GetKerningPairs (dc, 0, 0);
- kps = (KERNINGPAIR*) juce_calloc (sizeof (KERNINGPAIR) * numKPs);
- GetKerningPairs (dc, numKPs, kps);
- }
-
- numKPs_ = numKPs;
- return kps;
- }
- };
-
- juce_ImplementSingleton_SingleThreaded (FontDCHolder);
-
- static bool addGlyphToTypeface (HDC dc,
- juce_wchar character,
- Typeface& dest,
- bool addKerning)
- {
- Path destShape;
- GLYPHMETRICS gm;
-
- float height;
- BOOL ok = false;
-
- {
- const WCHAR charToTest[] = { (WCHAR) character, 0 };
- WORD index = 0;
-
- if (GetGlyphIndices (dc, charToTest, 1, &index, GGI_MARK_NONEXISTING_GLYPHS) != GDI_ERROR
- && index == 0xffff)
- {
- return false;
- }
- }
-
- TEXTMETRIC tm;
- ok = GetTextMetrics (dc, &tm);
-
- height = (float) tm.tmHeight;
-
- if (! ok)
- {
- dest.addGlyph (character, destShape, 0);
- return true;
- }
-
- const float scaleX = 1.0f / height;
- const float scaleY = -1.0f / height;
- static const MAT2 identityMatrix = { { 0, 1 }, { 0, 0 }, { 0, 0 }, { 0, 1 } };
-
- const int bufSize = GetGlyphOutline (dc, character, GGO_NATIVE,
- &gm, 0, 0, &identityMatrix);
-
- if (bufSize > 0)
- {
- char* const data = (char*) juce_malloc (bufSize);
-
- GetGlyphOutline (dc, character, GGO_NATIVE, &gm,
- bufSize, data, &identityMatrix);
-
- const TTPOLYGONHEADER* pheader = (TTPOLYGONHEADER*) data;
-
- while ((char*) pheader < data + bufSize)
- {
- #define remapX(v) (scaleX * (v).x.value)
- #define remapY(v) (scaleY * (v).y.value)
-
- float x = remapX (pheader->pfxStart);
- float y = remapY (pheader->pfxStart);
-
- destShape.startNewSubPath (x, y);
-
- const TTPOLYCURVE* curve = (const TTPOLYCURVE*) ((const char*) pheader + sizeof (TTPOLYGONHEADER));
- const char* const curveEnd = ((const char*) pheader) + pheader->cb;
-
- while ((const char*) curve < curveEnd)
- {
- if (curve->wType == TT_PRIM_LINE)
- {
- for (int i = 0; i < curve->cpfx; ++i)
- {
- x = remapX (curve->apfx [i]);
- y = remapY (curve->apfx [i]);
-
- destShape.lineTo (x, y);
- }
- }
- else if (curve->wType == TT_PRIM_QSPLINE)
- {
- for (int i = 0; i < curve->cpfx - 1; ++i)
- {
- const float x2 = remapX (curve->apfx [i]);
- const float y2 = remapY (curve->apfx [i]);
- float x3, y3;
-
- if (i < curve->cpfx - 2)
- {
- x3 = 0.5f * (x2 + remapX (curve->apfx [i + 1]));
- y3 = 0.5f * (y2 + remapY (curve->apfx [i + 1]));
- }
- else
- {
- x3 = remapX (curve->apfx [i + 1]);
- y3 = remapY (curve->apfx [i + 1]);
- }
-
- destShape.quadraticTo (x2, y2, x3, y3);
-
- x = x3;
- y = y3;
- }
- }
-
- curve = (const TTPOLYCURVE*) &(curve->apfx [curve->cpfx]);
- }
-
- pheader = (const TTPOLYGONHEADER*) curve;
-
- destShape.closeSubPath();
- }
-
- juce_free (data);
- }
-
- dest.addGlyph (character, destShape, gm.gmCellIncX / height);
-
- if (addKerning)
- {
- int numKPs;
- const KERNINGPAIR* const kps = FontDCHolder::getInstance()->getKerningPairs (numKPs);
-
- for (int i = 0; i < numKPs; ++i)
- {
- if (kps[i].wFirst == character)
- {
- dest.addKerningPair (kps[i].wFirst,
- kps[i].wSecond,
- kps[i].iKernAmount / height);
- }
- }
- }
-
- return true;
- }
-
- bool Typeface::findAndAddSystemGlyph (juce_wchar character) throw()
- {
- HDC dc = FontDCHolder::getInstance()->loadFont (getName(), isBold(), isItalic(), 0);
- return addGlyphToTypeface (dc, character, *this, true);
- }
-
- /*Image* Typeface::renderGlyphToImage (juce_wchar character, float& topLeftX, float& topLeftY)
- {
- HDC dc = FontDCHolder::getInstance()->loadFont (getName(), isBold(), isItalic(), hintingSize);
-
- int bufSize;
- GLYPHMETRICS gm;
-
- const UINT format = GGO_GRAY2_BITMAP;
- const int shift = 6;
-
- if (wGetGlyphOutlineW != 0)
- bufSize = wGetGlyphOutlineW (dc, character, format, &gm, 0, 0, &identityMatrix);
- else
- bufSize = GetGlyphOutline (dc, character, format, &gm, 0, 0, &identityMatrix);
-
- Image* im = new Image (Image::SingleChannel, jmax (1, gm.gmBlackBoxX), jmax (1, gm.gmBlackBoxY), true);
-
- if (bufSize > 0)
- {
- topLeftX = (float) gm.gmptGlyphOrigin.x;
- topLeftY = (float) -gm.gmptGlyphOrigin.y;
-
- uint8* const data = (uint8*) juce_calloc (bufSize);
-
- if (wGetGlyphOutlineW != 0)
- wGetGlyphOutlineW (dc, character, format, &gm, bufSize, data, &identityMatrix);
- else
- GetGlyphOutline (dc, character, format, &gm, bufSize, data, &identityMatrix);
-
- const int stride = ((gm.gmBlackBoxX + 3) & ~3);
-
- for (int y = gm.gmBlackBoxY; --y >= 0;)
- {
- for (int x = gm.gmBlackBoxX; --x >= 0;)
- {
- const int level = data [x + y * stride] << shift;
-
- if (level > 0)
- im->setPixelAt (x, y, Colour ((uint8) 0xff, (uint8) 0xff, (uint8) 0xff, (uint8) jmin (0xff, level)));
- }
- }
-
- juce_free (data);
- }
-
- return im;
- }*/
-
- void Typeface::initialiseTypefaceCharacteristics (const String& fontName,
- bool bold,
- bool italic,
- bool addAllGlyphsToFont) throw()
- {
- clear();
-
- HDC dc = FontDCHolder::getInstance()->loadFont (fontName, bold, italic, 0);
-
- float height;
- int firstChar, lastChar;
-
- {
- TEXTMETRIC tm;
- GetTextMetrics (dc, &tm);
-
- height = (float) tm.tmHeight;
- firstChar = tm.tmFirstChar;
- lastChar = tm.tmLastChar;
-
- setAscent (tm.tmAscent / height);
- setDefaultCharacter (tm.tmDefaultChar);
- }
-
- setName (fontName);
- setBold (bold);
- setItalic (italic);
-
- if (addAllGlyphsToFont)
- {
- for (int character = firstChar; character <= lastChar; ++character)
- addGlyphToTypeface (dc, (juce_wchar) character, *this, false);
-
- int numKPs;
- const KERNINGPAIR* const kps = FontDCHolder::getInstance()->getKerningPairs (numKPs);
-
- for (int i = 0; i < numKPs; ++i)
- {
- addKerningPair (kps[i].wFirst,
- kps[i].wSecond,
- kps[i].iKernAmount / height);
- }
- }
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_win32_Fonts.cpp *********/
-
- /********* Start of inlined file: juce_win32_Messaging.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- static const unsigned int specialId = WM_APP + 0x4400;
- static const unsigned int broadcastId = WM_APP + 0x4403;
- static const unsigned int specialCallbackId = WM_APP + 0x4402;
-
- static const TCHAR* const messageWindowName = _T("JUCEWindow");
-
- HWND juce_messageWindowHandle = 0;
-
- extern long improbableWindowNumber; // defined in windowing.cpp
-
- static LRESULT CALLBACK juce_MessageWndProc (HWND h,
- const UINT message,
- const WPARAM wParam,
- const LPARAM lParam) throw()
- {
- JUCE_TRY
- {
- if (h == juce_messageWindowHandle)
- {
- if (message == specialCallbackId)
- {
- MessageCallbackFunction* const func = (MessageCallbackFunction*) wParam;
- return (LRESULT) (*func) ((void*) lParam);
- }
- else if (message == specialId)
- {
- // these are trapped early in the dispatch call, but must also be checked
- // here in case there are windows modal dialog boxes doing their own
- // dispatch loop and not calling our version
-
- MessageManager::getInstance()->deliverMessage ((void*) lParam);
- return 0;
- }
- else if (message == broadcastId)
- {
- String* const messageString = (String*) lParam;
- MessageManager::getInstance()->deliverBroadcastMessage (*messageString);
- delete messageString;
- return 0;
- }
- else if (message == WM_COPYDATA && ((const COPYDATASTRUCT*) lParam)->dwData == broadcastId)
- {
- const String messageString ((const juce_wchar*) ((const COPYDATASTRUCT*) lParam)->lpData,
- ((const COPYDATASTRUCT*) lParam)->cbData / sizeof (juce_wchar));
-
- PostMessage (juce_messageWindowHandle, broadcastId, 0, (LPARAM) new String (messageString));
- return 0;
- }
- }
- }
- JUCE_CATCH_EXCEPTION
-
- return DefWindowProc (h, message, wParam, lParam);
- }
-
- bool juce_dispatchNextMessageOnSystemQueue (const bool returnIfNoPendingMessages)
- {
- MSG m;
-
- if (returnIfNoPendingMessages && ! PeekMessage (&m, (HWND) 0, 0, 0, 0))
- return false;
-
- if (GetMessage (&m, (HWND) 0, 0, 0) > 0)
- {
- if (m.message == specialId
- && m.hwnd == juce_messageWindowHandle)
- {
- MessageManager::getInstance()->deliverMessage ((void*) m.lParam);
- }
- else
- {
- if (GetWindowLong (m.hwnd, GWLP_USERDATA) != improbableWindowNumber
- && (m.message == WM_LBUTTONDOWN || m.message == WM_RBUTTONDOWN))
- {
- // if it's someone else's window being clicked on, and the focus is
- // currently on a juce window, pass the kb focus over..
- HWND currentFocus = GetFocus();
-
- if (currentFocus == 0 || GetWindowLong (currentFocus, GWLP_USERDATA) == improbableWindowNumber)
- SetFocus (m.hwnd);
- }
-
- TranslateMessage (&m);
- DispatchMessage (&m);
- }
- }
-
- return true;
- }
-
- bool juce_postMessageToSystemQueue (void* message)
- {
- return PostMessage (juce_messageWindowHandle, specialId, 0, (LPARAM) message) != 0;
- }
-
- void* MessageManager::callFunctionOnMessageThread (MessageCallbackFunction* callback,
- void* userData)
- {
- if (MessageManager::getInstance()->isThisTheMessageThread())
- {
- return (*callback) (userData);
- }
- else
- {
- // If a thread has a MessageManagerLock and then tries to call this method, it'll
- // deadlock because the message manager is blocked from running, and can't
- // call your function..
- jassert (! MessageManager::getInstance()->currentThreadHasLockedMessageManager());
-
- return (void*) SendMessage (juce_messageWindowHandle,
- specialCallbackId,
- (WPARAM) callback,
- (LPARAM) userData);
- }
- }
-
- static BOOL CALLBACK BroadcastEnumWindowProc (HWND hwnd, LPARAM lParam)
- {
- if (hwnd != juce_messageWindowHandle)
- (reinterpret_cast <VoidArray*> (lParam))->add ((void*) hwnd);
-
- return TRUE;
- }
-
- void MessageManager::broadcastMessage (const String& value) throw()
- {
- VoidArray windows;
- EnumWindows (&BroadcastEnumWindowProc, (LPARAM) &windows);
-
- const String localCopy (value);
-
- COPYDATASTRUCT data;
- data.dwData = broadcastId;
- data.cbData = (localCopy.length() + 1) * sizeof (juce_wchar);
- data.lpData = (void*) (const juce_wchar*) localCopy;
-
- for (int i = windows.size(); --i >= 0;)
- {
- HWND hwnd = (HWND) windows.getUnchecked(i);
-
- TCHAR windowName [64]; // no need to read longer strings than this
- GetWindowText (hwnd, windowName, 64);
- windowName [63] = 0;
-
- if (String (windowName) == String (messageWindowName))
- {
- DWORD_PTR result;
- SendMessageTimeout (hwnd, WM_COPYDATA,
- (WPARAM) juce_messageWindowHandle,
- (LPARAM) &data,
- SMTO_BLOCK | SMTO_ABORTIFHUNG,
- 8000,
- &result);
- }
- }
- }
-
- static const String getMessageWindowClassName()
- {
- // this name has to be different for each app/dll instance because otherwise
- // poor old Win32 can get a bit confused (even despite it not being a process-global
- // window class).
-
- static int number = 0;
- if (number == 0)
- number = 0x7fffffff & (int) Time::getHighResolutionTicks();
-
- return T("JUCEcs_") + String (number);
- }
-
- void MessageManager::doPlatformSpecificInitialisation()
- {
- OleInitialize (0);
-
- const String className (getMessageWindowClassName());
-
- HMODULE hmod = (HMODULE) PlatformUtilities::getCurrentModuleInstanceHandle();
-
- WNDCLASSEX wc;
- zerostruct (wc);
-
- wc.cbSize = sizeof (wc);
- wc.lpfnWndProc = (WNDPROC) juce_MessageWndProc;
- wc.cbWndExtra = 4;
- wc.hInstance = hmod;
- wc.lpszClassName = className;
-
- RegisterClassEx (&wc);
-
- juce_messageWindowHandle = CreateWindow (wc.lpszClassName,
- messageWindowName,
- 0, 0, 0, 0, 0, 0, 0,
- hmod, 0);
- }
-
- void MessageManager::doPlatformSpecificShutdown()
- {
- DestroyWindow (juce_messageWindowHandle);
- UnregisterClass (getMessageWindowClassName(), 0);
- OleUninitialize();
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_win32_Messaging.cpp *********/
-
- /********* Start of inlined file: juce_win32_Midi.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- #if JUCE_MSVC
- #pragma warning (disable: 4312)
- #endif
-
- using ::free;
-
- static const int midiBufferSize = 1024 * 10;
- static const int numInHeaders = 32;
- static const int inBufferSize = 256;
- static Array <void*, CriticalSection> activeMidiThreads;
-
- class MidiInThread : public Thread
- {
- public:
-
- MidiInThread (MidiInput* const input_,
- MidiInputCallback* const callback_)
- : Thread ("Juce Midi"),
- hIn (0),
- input (input_),
- callback (callback_),
- isStarted (false),
- startTime (0),
- pendingLength(0)
- {
- for (int i = numInHeaders; --i >= 0;)
- {
- zeromem (&hdr[i], sizeof (MIDIHDR));
- hdr[i].lpData = inData[i];
- hdr[i].dwBufferLength = inBufferSize;
- }
- };
-
- ~MidiInThread()
- {
- stop();
-
- if (hIn != 0)
- {
- int count = 5;
- while (--count >= 0)
- {
- if (midiInClose (hIn) == MMSYSERR_NOERROR)
- break;
-
- Sleep (20);
- }
- }
- }
-
- void handle (const uint32 message, const uint32 timeStamp) throw()
- {
- const int byte = message & 0xff;
- if (byte < 0x80)
- return;
-
- const int numBytes = MidiMessage::getMessageLengthFromFirstByte ((uint8) byte);
-
- const double time = timeStampToTime (timeStamp);
-
- lock.enter();
- if (pendingLength < midiBufferSize - 12)
- {
- char* const p = pending + pendingLength;
- *(double*) p = time;
- *(uint32*) (p + 8) = numBytes;
- *(uint32*) (p + 12) = message;
- pendingLength += 12 + numBytes;
- }
- else
- {
- jassertfalse // midi buffer overflow! You might need to increase the size..
- }
-
- lock.exit();
- notify();
- }
-
- void handleSysEx (MIDIHDR* const hdr, const uint32 timeStamp) throw()
- {
- const int num = hdr->dwBytesRecorded;
-
- if (num > 0)
- {
- const double time = timeStampToTime (timeStamp);
-
- lock.enter();
-
- if (pendingLength < midiBufferSize - (8 + num))
- {
- char* const p = pending + pendingLength;
- *(double*) p = time;
- *(uint32*) (p + 8) = num;
- memcpy (p + 12, hdr->lpData, num);
- pendingLength += 12 + num;
- }
- else
- {
- jassertfalse // midi buffer overflow! You might need to increase the size..
- }
-
- lock.exit();
- notify();
- }
- }
-
- void writeBlock (const int i) throw()
- {
- hdr[i].dwBytesRecorded = 0;
- MMRESULT res = midiInPrepareHeader (hIn, &hdr[i], sizeof (MIDIHDR));
- jassert (res == MMSYSERR_NOERROR);
- res = midiInAddBuffer (hIn, &hdr[i], sizeof (MIDIHDR));
- jassert (res == MMSYSERR_NOERROR);
- }
-
- void run()
- {
- MemoryBlock pendingCopy (64);
-
- while (! threadShouldExit())
- {
- for (int i = 0; i < numInHeaders; ++i)
- {
- if ((hdr[i].dwFlags & WHDR_DONE) != 0)
- {
- MMRESULT res = midiInUnprepareHeader (hIn, &hdr[i], sizeof (MIDIHDR));
- (void) res;
- jassert (res == MMSYSERR_NOERROR);
- writeBlock (i);
- }
- }
-
- lock.enter();
-
- int len = pendingLength;
-
- if (len > 0)
- {
- pendingCopy.ensureSize (len);
- pendingCopy.copyFrom (pending, 0, len);
- pendingLength = 0;
- }
-
- lock.exit();
-
- //xxx needs to figure out if blocks are broken up or not
-
- if (len == 0)
- {
- wait (500);
- }
- else
- {
- const char* p = (const char*) pendingCopy.getData();
-
- while (len > 0)
- {
- const double time = *(const double*) p;
- const int messageLen = *(const int*) (p + 8);
-
- const MidiMessage message ((const uint8*) (p + 12), messageLen, time);
-
- callback->handleIncomingMidiMessage (input, message);
-
- p += 12 + messageLen;
- len -= 12 + messageLen;
- }
- }
- }
- }
-
- void start() throw()
- {
- jassert (hIn != 0);
- if (hIn != 0 && ! isStarted)
- {
- stop();
-
- activeMidiThreads.addIfNotAlreadyThere (this);
-
- int i;
- for (i = 0; i < numInHeaders; ++i)
- writeBlock (i);
-
- startTime = Time::getMillisecondCounter();
- MMRESULT res = midiInStart (hIn);
-
- jassert (res == MMSYSERR_NOERROR);
-
- if (res == MMSYSERR_NOERROR)
- {
- isStarted = true;
- pendingLength = 0;
- startThread (6);
- }
- }
- }
-
- void stop() throw()
- {
- if (isStarted)
- {
- stopThread (5000);
-
- midiInReset (hIn);
- midiInStop (hIn);
-
- activeMidiThreads.removeValue (this);
-
- lock.enter();
- lock.exit();
-
- for (int i = numInHeaders; --i >= 0;)
- {
- if ((hdr[i].dwFlags & WHDR_DONE) != 0)
- {
- int c = 10;
- while (--c >= 0 && midiInUnprepareHeader (hIn, &hdr[i], sizeof (MIDIHDR)) == MIDIERR_STILLPLAYING)
- Sleep (20);
-
- jassert (c >= 0);
- }
- }
-
- isStarted = false;
- pendingLength = 0;
- }
- }
-
- juce_UseDebuggingNewOperator
-
- HMIDIIN hIn;
-
- private:
- MidiInput* input;
- MidiInputCallback* callback;
- bool isStarted;
- uint32 startTime;
- CriticalSection lock;
-
- MIDIHDR hdr [numInHeaders];
- char inData [numInHeaders] [inBufferSize];
-
- int pendingLength;
- char pending [midiBufferSize];
-
- double timeStampToTime (uint32 timeStamp) throw()
- {
- timeStamp += startTime;
-
- const uint32 now = Time::getMillisecondCounter();
- if (timeStamp > now)
- {
- if (timeStamp > now + 2)
- --startTime;
-
- timeStamp = now;
- }
-
- return 0.001 * timeStamp;
- }
-
- MidiInThread (const MidiInThread&);
- const MidiInThread& operator= (const MidiInThread&);
- };
-
- static void CALLBACK midiInCallback (HMIDIIN,
- UINT uMsg,
- DWORD_PTR dwInstance,
- DWORD_PTR midiMessage,
- DWORD_PTR timeStamp)
- {
- MidiInThread* const thread = (MidiInThread*) dwInstance;
-
- if (thread != 0 && activeMidiThreads.contains (thread))
- {
- if (uMsg == MIM_DATA)
- thread->handle ((uint32) midiMessage, (uint32) timeStamp);
- else if (uMsg == MIM_LONGDATA)
- thread->handleSysEx ((MIDIHDR*) midiMessage, (uint32) timeStamp);
- }
- }
-
- const StringArray MidiInput::getDevices()
- {
- StringArray s;
- const int num = midiInGetNumDevs();
-
- for (int i = 0; i < num; ++i)
- {
- MIDIINCAPS mc;
- zerostruct (mc);
-
- if (midiInGetDevCaps (i, &mc, sizeof (mc)) == MMSYSERR_NOERROR)
- s.add (String (mc.szPname, sizeof (mc.szPname)));
- }
-
- return s;
- }
-
- int MidiInput::getDefaultDeviceIndex()
- {
- return 0;
- }
-
- MidiInput* MidiInput::openDevice (const int index, MidiInputCallback* const callback)
- {
- if (callback == 0)
- return 0;
-
- UINT deviceId = MIDI_MAPPER;
- int n = 0;
- String name;
-
- const int num = midiInGetNumDevs();
-
- for (int i = 0; i < num; ++i)
- {
- MIDIINCAPS mc;
- zerostruct (mc);
-
- if (midiInGetDevCaps (i, &mc, sizeof (mc)) == MMSYSERR_NOERROR)
- {
- if (index == n)
- {
- deviceId = i;
- name = String (mc.szPname, sizeof (mc.szPname));
- break;
- }
-
- ++n;
- }
- }
-
- MidiInput* const in = new MidiInput (name);
- MidiInThread* const thread = new MidiInThread (in, callback);
-
- HMIDIIN h;
- HRESULT err = midiInOpen (&h, deviceId,
- (DWORD_PTR) &midiInCallback,
- (DWORD_PTR) thread,
- CALLBACK_FUNCTION);
-
- if (err == MMSYSERR_NOERROR)
- {
- thread->hIn = h;
- in->internal = (void*) thread;
- return in;
- }
- else
- {
- delete in;
- delete thread;
- return 0;
- }
- }
-
- MidiInput::MidiInput (const String& name_)
- : name (name_),
- internal (0)
- {
- }
-
- MidiInput::~MidiInput()
- {
- if (internal != 0)
- {
- MidiInThread* const thread = (MidiInThread*) internal;
- delete thread;
- }
- }
-
- void MidiInput::start()
- {
- ((MidiInThread*) internal)->start();
- }
-
- void MidiInput::stop()
- {
- ((MidiInThread*) internal)->stop();
- }
-
- struct MidiOutHandle
- {
- int refCount;
- UINT deviceId;
- HMIDIOUT handle;
-
- juce_UseDebuggingNewOperator
- };
-
- static VoidArray handles (4);
-
- const StringArray MidiOutput::getDevices()
- {
- StringArray s;
- const int num = midiOutGetNumDevs();
-
- for (int i = 0; i < num; ++i)
- {
- MIDIOUTCAPS mc;
- zerostruct (mc);
-
- if (midiOutGetDevCaps (i, &mc, sizeof (mc)) == MMSYSERR_NOERROR)
- s.add (String (mc.szPname, sizeof (mc.szPname)));
- }
-
- return s;
- }
-
- int MidiOutput::getDefaultDeviceIndex()
- {
- const int num = midiOutGetNumDevs();
- int n = 0;
-
- for (int i = 0; i < num; ++i)
- {
- MIDIOUTCAPS mc;
- zerostruct (mc);
-
- if (midiOutGetDevCaps (i, &mc, sizeof (mc)) == MMSYSERR_NOERROR)
- {
- if ((mc.wTechnology & MOD_MAPPER) != 0)
- return n;
-
- ++n;
- }
- }
-
- return 0;
- }
-
- MidiOutput* MidiOutput::openDevice (int index)
- {
- UINT deviceId = MIDI_MAPPER;
- const int num = midiOutGetNumDevs();
- int i, n = 0;
-
- for (i = 0; i < num; ++i)
- {
- MIDIOUTCAPS mc;
- zerostruct (mc);
-
- if (midiOutGetDevCaps (i, &mc, sizeof (mc)) == MMSYSERR_NOERROR)
- {
- // use the microsoft sw synth as a default - best not to allow deviceId
- // to be MIDI_MAPPER, or else device sharing breaks
- if (String (mc.szPname, sizeof (mc.szPname)).containsIgnoreCase (T("microsoft")))
- deviceId = i;
-
- if (index == n)
- {
- deviceId = i;
- break;
- }
-
- ++n;
- }
- }
-
- for (i = handles.size(); --i >= 0;)
- {
- MidiOutHandle* const han = (MidiOutHandle*) handles.getUnchecked(i);
-
- if (han != 0 && han->deviceId == deviceId)
- {
- han->refCount++;
-
- MidiOutput* const out = new MidiOutput();
- out->internal = (void*) han;
- return out;
- }
- }
-
- for (i = 4; --i >= 0;)
- {
- HMIDIOUT h = 0;
- MMRESULT res = midiOutOpen (&h, deviceId, 0, 0, CALLBACK_NULL);
-
- if (res == MMSYSERR_NOERROR)
- {
- MidiOutHandle* const han = new MidiOutHandle();
- han->deviceId = deviceId;
- han->refCount = 1;
- han->handle = h;
- handles.add (han);
-
- MidiOutput* const out = new MidiOutput();
- out->internal = (void*) han;
- return out;
- }
- else if (res == MMSYSERR_ALLOCATED)
- {
- Sleep (100);
- }
- else
- {
- break;
- }
- }
-
- return 0;
- }
-
- MidiOutput::~MidiOutput()
- {
- MidiOutHandle* const h = (MidiOutHandle*) internal;
-
- if (handles.contains ((void*) h) && --(h->refCount) == 0)
- {
- midiOutClose (h->handle);
- handles.removeValue ((void*) h);
- delete h;
- }
- }
-
- void MidiOutput::reset()
- {
- const MidiOutHandle* const h = (MidiOutHandle*) internal;
- midiOutReset (h->handle);
- }
-
- bool MidiOutput::getVolume (float& leftVol,
- float& rightVol)
- {
- const MidiOutHandle* const handle = (const MidiOutHandle*) internal;
-
- DWORD n;
- if (midiOutGetVolume (handle->handle, &n) == MMSYSERR_NOERROR)
- {
- const unsigned short* const nn = (const unsigned short*) &n;
- rightVol = nn[0] / (float) 0xffff;
- leftVol = nn[1] / (float) 0xffff;
- return true;
- }
- else
- {
- rightVol = leftVol = 1.0f;
- return false;
- }
- }
-
- void MidiOutput::setVolume (float leftVol,
- float rightVol)
- {
- const MidiOutHandle* const handle = (MidiOutHandle*) internal;
-
- DWORD n;
- unsigned short* const nn = (unsigned short*) &n;
- nn[0] = (unsigned short) jlimit (0, 0xffff, (int)(rightVol * 0xffff));
- nn[1] = (unsigned short) jlimit (0, 0xffff, (int)(leftVol * 0xffff));
- midiOutSetVolume (handle->handle, n);
- }
-
- void MidiOutput::sendMessageNow (const MidiMessage& message)
- {
- const MidiOutHandle* const handle = (const MidiOutHandle*) internal;
-
- if (message.getRawDataSize() > 3
- || message.isSysEx())
- {
- MIDIHDR h;
- zerostruct (h);
-
- h.lpData = (char*) message.getRawData();
- h.dwBufferLength = message.getRawDataSize();
- h.dwBytesRecorded = message.getRawDataSize();
-
- if (midiOutPrepareHeader (handle->handle, &h, sizeof (MIDIHDR)) == MMSYSERR_NOERROR)
- {
- MMRESULT res = midiOutLongMsg (handle->handle, &h, sizeof (MIDIHDR));
-
- if (res == MMSYSERR_NOERROR)
- {
- while ((h.dwFlags & MHDR_DONE) == 0)
- Sleep (1);
-
- int count = 500; // 1 sec timeout
-
- while (--count >= 0)
- {
- res = midiOutUnprepareHeader (handle->handle, &h, sizeof (MIDIHDR));
-
- if (res == MIDIERR_STILLPLAYING)
- Sleep (2);
- else
- break;
- }
- }
- }
- }
- else
- {
- midiOutShortMsg (handle->handle,
- *(unsigned int*) message.getRawData());
- }
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_win32_Midi.cpp *********/
-
- /********* Start of inlined file: juce_win32_WebBrowserComponent.cpp *********/
-
- #ifdef _MSC_VER
- #pragma warning (disable: 4514)
- #pragma warning (push)
- #endif
-
- #include <comutil.h>
- #include <Exdisp.h>
- #include <exdispid.h>
-
- #ifdef _MSC_VER
- #pragma warning (pop)
- #pragma warning (disable: 4312 4244)
- #endif
-
- BEGIN_JUCE_NAMESPACE
-
- class WebBrowserComponentInternal : public ActiveXControlComponent
- {
- public:
-
- WebBrowserComponentInternal()
- : browser (0),
- connectionPoint (0),
- adviseCookie (0)
- {
- }
-
- ~WebBrowserComponentInternal()
- {
- if (connectionPoint != 0)
- connectionPoint->Unadvise (adviseCookie);
-
- if (browser != 0)
- browser->Release();
- }
-
- void createBrowser()
- {
- createControl (&CLSID_WebBrowser);
- browser = (IWebBrowser2*) queryInterface (&IID_IWebBrowser2);
-
- IConnectionPointContainer* connectionPointContainer = (IConnectionPointContainer*) queryInterface (&IID_IConnectionPointContainer);
-
- if (connectionPointContainer != 0)
- {
- connectionPointContainer->FindConnectionPoint (DIID_DWebBrowserEvents2,
- &connectionPoint);
-
- if (connectionPoint != 0)
- {
- WebBrowserComponent* const owner = dynamic_cast <WebBrowserComponent*> (getParentComponent());
- jassert (owner != 0);
-
- EventHandler* handler = new EventHandler (owner);
- connectionPoint->Advise (handler, &adviseCookie);
- }
- }
- }
-
- void goToURL (const String& url,
- const StringArray* headers,
- const MemoryBlock* postData)
- {
- if (browser != 0)
- {
- LPSAFEARRAY sa = 0;
- _variant_t flags, frame, postDataVar, headersVar;
-
- if (headers != 0)
- headersVar = (const tchar*) headers->joinIntoString ("\r\n");
-
- if (postData != 0 && postData->getSize() > 0)
- {
- LPSAFEARRAY sa = SafeArrayCreateVector (VT_UI1, 0, postData->getSize());
-
- if (sa != 0)
- {
- void* data = 0;
- SafeArrayAccessData (sa, &data);
- jassert (data != 0);
-
- if (data != 0)
- {
- postData->copyTo (data, 0, postData->getSize());
- SafeArrayUnaccessData (sa);
-
- VARIANT postDataVar2;
- VariantInit (&postDataVar2);
- V_VT (&postDataVar2) = VT_ARRAY | VT_UI1;
- V_ARRAY (&postDataVar2) = sa;
-
- postDataVar = postDataVar2;
- }
- }
- }
-
- browser->Navigate ((BSTR) (const OLECHAR*) url,
- &flags, &frame,
- &postDataVar, &headersVar);
-
- if (sa != 0)
- SafeArrayDestroy (sa);
- }
- }
-
- IWebBrowser2* browser;
-
- juce_UseDebuggingNewOperator
-
- private:
- IConnectionPoint* connectionPoint;
- DWORD adviseCookie;
-
- class EventHandler : public IDispatch
- {
- public:
- EventHandler (WebBrowserComponent* owner_)
- : owner (owner_),
- refCount (0)
- {
- }
-
- ~EventHandler()
- {
- }
-
- HRESULT __stdcall QueryInterface (REFIID id, void __RPC_FAR* __RPC_FAR* result)
- {
- if (id == IID_IUnknown || id == IID_IDispatch || id == DIID_DWebBrowserEvents2)
- {
- AddRef();
- *result = this;
- return S_OK;
- }
-
- *result = 0;
- return E_NOINTERFACE;
- }
-
- ULONG __stdcall AddRef() { return ++refCount; }
- ULONG __stdcall Release() { jassert (refCount > 0); const int r = --refCount; if (r == 0) delete this; return r; }
-
- HRESULT __stdcall GetTypeInfoCount (UINT __RPC_FAR*) { return E_NOTIMPL; }
- HRESULT __stdcall GetTypeInfo (UINT, LCID, ITypeInfo __RPC_FAR *__RPC_FAR*) { return E_NOTIMPL; }
- HRESULT __stdcall GetIDsOfNames (REFIID, LPOLESTR __RPC_FAR*, UINT, LCID, DISPID __RPC_FAR*) { return E_NOTIMPL; }
-
- HRESULT __stdcall Invoke (DISPID dispIdMember, REFIID /*riid*/, LCID /*lcid*/,
- WORD /*wFlags*/, DISPPARAMS __RPC_FAR* pDispParams,
- VARIANT __RPC_FAR* /*pVarResult*/, EXCEPINFO __RPC_FAR* /*pExcepInfo*/,
- UINT __RPC_FAR* /*puArgErr*/)
- {
- switch (dispIdMember)
- {
- case DISPID_BEFORENAVIGATE2:
- {
- VARIANT* const vurl = pDispParams->rgvarg[5].pvarVal;
-
- String url;
-
- if ((vurl->vt & VT_BYREF) != 0)
- url = *vurl->pbstrVal;
- else
- url = vurl->bstrVal;
-
- *pDispParams->rgvarg->pboolVal
- = owner->pageAboutToLoad (url) ? VARIANT_FALSE
- : VARIANT_TRUE;
-
- return S_OK;
- }
-
- default:
- break;
- }
-
- return E_NOTIMPL;
- }
-
- juce_UseDebuggingNewOperator
-
- private:
- WebBrowserComponent* const owner;
- int refCount;
-
- EventHandler (const EventHandler&);
- const EventHandler& operator= (const EventHandler&);
- };
- };
-
- WebBrowserComponent::WebBrowserComponent()
- : browser (0),
- blankPageShown (false)
- {
- setOpaque (true);
- addAndMakeVisible (browser = new WebBrowserComponentInternal());
- }
-
- WebBrowserComponent::~WebBrowserComponent()
- {
- delete browser;
- }
-
- void WebBrowserComponent::goToURL (const String& url,
- const StringArray* headers,
- const MemoryBlock* postData)
- {
- lastURL = url;
-
- lastHeaders.clear();
- if (headers != 0)
- lastHeaders = *headers;
-
- lastPostData.setSize (0);
- if (postData != 0)
- lastPostData = *postData;
-
- blankPageShown = false;
-
- browser->goToURL (url, headers, postData);
- }
-
- void WebBrowserComponent::stop()
- {
- if (browser->browser != 0)
- browser->browser->Stop();
- }
-
- void WebBrowserComponent::goBack()
- {
- lastURL = String::empty;
- blankPageShown = false;
-
- if (browser->browser != 0)
- browser->browser->GoBack();
- }
-
- void WebBrowserComponent::goForward()
- {
- lastURL = String::empty;
-
- if (browser->browser != 0)
- browser->browser->GoForward();
- }
-
- void WebBrowserComponent::paint (Graphics& g)
- {
- if (browser->browser == 0)
- g.fillAll (Colours::white);
- }
-
- void WebBrowserComponent::checkWindowAssociation()
- {
- if (isShowing())
- {
- if (browser->browser == 0 && getPeer() != 0)
- {
- browser->createBrowser();
- reloadLastURL();
- }
- else
- {
- if (blankPageShown)
- goBack();
- }
- }
- else
- {
- if (browser != 0 && ! blankPageShown)
- {
- // when the component becomes invisible, some stuff like flash
- // carries on playing audio, so we need to force it onto a blank
- // page to avoid this..
-
- blankPageShown = true;
- browser->goToURL ("about:blank", 0, 0);
- }
- }
- }
-
- void WebBrowserComponent::reloadLastURL()
- {
- if (lastURL.isNotEmpty())
- {
- goToURL (lastURL, &lastHeaders, &lastPostData);
- lastURL = String::empty;
- }
- }
-
- void WebBrowserComponent::parentHierarchyChanged()
- {
- checkWindowAssociation();
- }
-
- void WebBrowserComponent::moved()
- {
- }
-
- void WebBrowserComponent::resized()
- {
- browser->setSize (getWidth(), getHeight());
- }
-
- void WebBrowserComponent::visibilityChanged()
- {
- checkWindowAssociation();
- }
-
- bool WebBrowserComponent::pageAboutToLoad (const String&)
- {
- return true;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_win32_WebBrowserComponent.cpp *********/
-
- /********* Start of inlined file: juce_win32_Windowing.cpp *********/
- #ifdef _MSC_VER
- #pragma warning (disable: 4514)
- #pragma warning (push)
- #endif
-
- #include <float.h>
- #include <windowsx.h>
- #include <shlobj.h>
-
- #if JUCE_OPENGL
- #include <gl/gl.h>
- #endif
-
- #ifdef _MSC_VER
- #pragma warning (pop)
- #pragma warning (disable: 4312 4244)
- #endif
-
- #undef GetSystemMetrics // multimon overrides this for some reason and causes a mess..
-
- // these are in the windows SDK, but need to be repeated here for GCC..
- #ifndef GET_APPCOMMAND_LPARAM
- #define FAPPCOMMAND_MASK 0xF000
- #define GET_APPCOMMAND_LPARAM(lParam) ((short) (HIWORD (lParam) & ~FAPPCOMMAND_MASK))
- #define APPCOMMAND_MEDIA_NEXTTRACK 11
- #define APPCOMMAND_MEDIA_PREVIOUSTRACK 12
- #define APPCOMMAND_MEDIA_STOP 13
- #define APPCOMMAND_MEDIA_PLAY_PAUSE 14
- #define WM_APPCOMMAND 0x0319
- #endif
-
- BEGIN_JUCE_NAMESPACE
-
- extern void juce_repeatLastProcessPriority() throw(); // in juce_win32_Threads.cpp
- extern void juce_CheckCurrentlyFocusedTopLevelWindow() throw(); // in juce_TopLevelWindow.cpp
- extern bool juce_IsRunningInWine() throw();
-
- #ifndef ULW_ALPHA
- #define ULW_ALPHA 0x00000002
- #endif
-
- #ifndef AC_SRC_ALPHA
- #define AC_SRC_ALPHA 0x01
- #endif
-
- #define DEBUG_REPAINT_TIMES 0
-
- static HPALETTE palette = 0;
- static bool createPaletteIfNeeded = true;
- static bool shouldDeactivateTitleBar = true;
- static bool screenSaverAllowed = true;
-
- static HICON createHICONFromImage (const Image& image, const BOOL isIcon, int hotspotX, int hotspotY) throw();
- #define WM_TRAYNOTIFY WM_USER + 100
-
- using ::abs;
-
- typedef BOOL (WINAPI* UpdateLayeredWinFunc) (HWND, HDC, POINT*, SIZE*, HDC, POINT*, COLORREF, BLENDFUNCTION*, DWORD);
- static UpdateLayeredWinFunc updateLayeredWindow = 0;
-
- bool Desktop::canUseSemiTransparentWindows() throw()
- {
- if (updateLayeredWindow == 0)
- {
- if (! juce_IsRunningInWine())
- {
- HMODULE user32Mod = GetModuleHandle (_T("user32.dll"));
- updateLayeredWindow = (UpdateLayeredWinFunc) GetProcAddress (user32Mod, "UpdateLayeredWindow");
- }
- }
-
- return updateLayeredWindow != 0;
- }
-
- #undef DefWindowProc
- #define DefWindowProc DefWindowProcW
-
- const int extendedKeyModifier = 0x10000;
-
- const int KeyPress::spaceKey = VK_SPACE;
- const int KeyPress::returnKey = VK_RETURN;
- const int KeyPress::escapeKey = VK_ESCAPE;
- const int KeyPress::backspaceKey = VK_BACK;
- const int KeyPress::deleteKey = VK_DELETE | extendedKeyModifier;
- const int KeyPress::insertKey = VK_INSERT | extendedKeyModifier;
- const int KeyPress::tabKey = VK_TAB;
- const int KeyPress::leftKey = VK_LEFT | extendedKeyModifier;
- const int KeyPress::rightKey = VK_RIGHT | extendedKeyModifier;
- const int KeyPress::upKey = VK_UP | extendedKeyModifier;
- const int KeyPress::downKey = VK_DOWN | extendedKeyModifier;
- const int KeyPress::homeKey = VK_HOME | extendedKeyModifier;
- const int KeyPress::endKey = VK_END | extendedKeyModifier;
- const int KeyPress::pageUpKey = VK_PRIOR | extendedKeyModifier;
- const int KeyPress::pageDownKey = VK_NEXT | extendedKeyModifier;
- const int KeyPress::F1Key = VK_F1 | extendedKeyModifier;
- const int KeyPress::F2Key = VK_F2 | extendedKeyModifier;
- const int KeyPress::F3Key = VK_F3 | extendedKeyModifier;
- const int KeyPress::F4Key = VK_F4 | extendedKeyModifier;
- const int KeyPress::F5Key = VK_F5 | extendedKeyModifier;
- const int KeyPress::F6Key = VK_F6 | extendedKeyModifier;
- const int KeyPress::F7Key = VK_F7 | extendedKeyModifier;
- const int KeyPress::F8Key = VK_F8 | extendedKeyModifier;
- const int KeyPress::F9Key = VK_F9 | extendedKeyModifier;
- const int KeyPress::F10Key = VK_F10 | extendedKeyModifier;
- const int KeyPress::F11Key = VK_F11 | extendedKeyModifier;
- const int KeyPress::F12Key = VK_F12 | extendedKeyModifier;
- const int KeyPress::F13Key = VK_F13 | extendedKeyModifier;
- const int KeyPress::F14Key = VK_F14 | extendedKeyModifier;
- const int KeyPress::F15Key = VK_F15 | extendedKeyModifier;
- const int KeyPress::F16Key = VK_F16 | extendedKeyModifier;
- const int KeyPress::numberPad0 = VK_NUMPAD0 | extendedKeyModifier;
- const int KeyPress::numberPad1 = VK_NUMPAD1 | extendedKeyModifier;
- const int KeyPress::numberPad2 = VK_NUMPAD2 | extendedKeyModifier;
- const int KeyPress::numberPad3 = VK_NUMPAD3 | extendedKeyModifier;
- const int KeyPress::numberPad4 = VK_NUMPAD4 | extendedKeyModifier;
- const int KeyPress::numberPad5 = VK_NUMPAD5 | extendedKeyModifier;
- const int KeyPress::numberPad6 = VK_NUMPAD6 | extendedKeyModifier;
- const int KeyPress::numberPad7 = VK_NUMPAD7 | extendedKeyModifier;
- const int KeyPress::numberPad8 = VK_NUMPAD8 | extendedKeyModifier;
- const int KeyPress::numberPad9 = VK_NUMPAD9 | extendedKeyModifier;
- const int KeyPress::numberPadAdd = VK_ADD | extendedKeyModifier;
- const int KeyPress::numberPadSubtract = VK_SUBTRACT | extendedKeyModifier;
- const int KeyPress::numberPadMultiply = VK_MULTIPLY | extendedKeyModifier;
- const int KeyPress::numberPadDivide = VK_DIVIDE | extendedKeyModifier;
- const int KeyPress::numberPadSeparator = VK_SEPARATOR | extendedKeyModifier;
- const int KeyPress::numberPadDecimalPoint = VK_DECIMAL | extendedKeyModifier;
- const int KeyPress::numberPadEquals = 0x92 /*VK_OEM_NEC_EQUAL*/ | extendedKeyModifier;
- const int KeyPress::numberPadDelete = VK_DELETE | extendedKeyModifier;
- const int KeyPress::playKey = 0x30000;
- const int KeyPress::stopKey = 0x30001;
- const int KeyPress::fastForwardKey = 0x30002;
- const int KeyPress::rewindKey = 0x30003;
-
- class WindowsBitmapImage : public Image
- {
- public:
-
- HBITMAP hBitmap;
- BITMAPV4HEADER bitmapInfo;
- HDC hdc;
- unsigned char* bitmapData;
-
- WindowsBitmapImage (const PixelFormat format_,
- const int w, const int h, const bool clearImage)
- : Image (format_, w, h)
- {
- jassert (format_ == RGB || format_ == ARGB);
-
- pixelStride = (format_ == RGB) ? 3 : 4;
-
- zerostruct (bitmapInfo);
- bitmapInfo.bV4Size = sizeof (BITMAPV4HEADER);
- bitmapInfo.bV4Width = w;
- bitmapInfo.bV4Height = h;
- bitmapInfo.bV4Planes = 1;
- bitmapInfo.bV4BitCount = (unsigned short) (pixelStride * 8);
-
- if (format_ == ARGB)
- {
- bitmapInfo.bV4AlphaMask = 0xff000000;
- bitmapInfo.bV4RedMask = 0xff0000;
- bitmapInfo.bV4GreenMask = 0xff00;
- bitmapInfo.bV4BlueMask = 0xff;
- bitmapInfo.bV4V4Compression = BI_BITFIELDS;
- }
- else
- {
- bitmapInfo.bV4V4Compression = BI_RGB;
- }
-
- lineStride = -((w * pixelStride + 3) & ~3);
-
- HDC dc = GetDC (0);
- hdc = CreateCompatibleDC (dc);
- ReleaseDC (0, dc);
-
- SetMapMode (hdc, MM_TEXT);
-
- hBitmap = CreateDIBSection (hdc,
- (BITMAPINFO*) &(bitmapInfo),
- DIB_RGB_COLORS,
- (void**) &bitmapData,
- 0, 0);
-
- SelectObject (hdc, hBitmap);
-
- if (format_ == ARGB && clearImage)
- zeromem (bitmapData, abs (h * lineStride));
-
- imageData = bitmapData - (lineStride * (h - 1));
- }
-
- ~WindowsBitmapImage()
- {
- DeleteDC (hdc);
- DeleteObject (hBitmap);
- imageData = 0; // to stop the base class freeing this
- }
-
- void blitToWindow (HWND hwnd, HDC dc, const bool transparent,
- const int x, const int y,
- const RectangleList& maskedRegion) throw()
- {
- static HDRAWDIB hdd = 0;
- static bool needToCreateDrawDib = true;
-
- if (needToCreateDrawDib)
- {
- needToCreateDrawDib = false;
-
- HDC dc = GetDC (0);
- const int n = GetDeviceCaps (dc, BITSPIXEL);
- ReleaseDC (0, dc);
-
- // only open if we're not palettised
- if (n > 8)
- hdd = DrawDibOpen();
- }
-
- if (createPaletteIfNeeded)
- {
- HDC dc = GetDC (0);
- const int n = GetDeviceCaps (dc, BITSPIXEL);
- ReleaseDC (0, dc);
-
- if (n <= 8)
- palette = CreateHalftonePalette (dc);
-
- createPaletteIfNeeded = false;
- }
-
- if (palette != 0)
- {
- SelectPalette (dc, palette, FALSE);
- RealizePalette (dc);
- SetStretchBltMode (dc, HALFTONE);
- }
-
- SetMapMode (dc, MM_TEXT);
-
- if (transparent)
- {
- POINT p, pos;
- SIZE size;
-
- RECT windowBounds;
- GetWindowRect (hwnd, &windowBounds);
-
- p.x = -x;
- p.y = -y;
- pos.x = windowBounds.left;
- pos.y = windowBounds.top;
- size.cx = windowBounds.right - windowBounds.left;
- size.cy = windowBounds.bottom - windowBounds.top;
-
- BLENDFUNCTION bf;
- bf.AlphaFormat = AC_SRC_ALPHA;
- bf.BlendFlags = 0;
- bf.BlendOp = AC_SRC_OVER;
- bf.SourceConstantAlpha = 0xff;
-
- if (! maskedRegion.isEmpty())
- {
- for (RectangleList::Iterator i (maskedRegion); i.next();)
- {
- const Rectangle& r = *i.getRectangle();
- ExcludeClipRect (hdc, r.getX(), r.getY(), r.getRight(), r.getBottom());
- }
- }
-
- updateLayeredWindow (hwnd, 0, &pos, &size, hdc, &p, 0, &bf, ULW_ALPHA);
- }
- else
- {
- int savedDC = 0;
-
- if (! maskedRegion.isEmpty())
- {
- savedDC = SaveDC (dc);
-
- for (RectangleList::Iterator i (maskedRegion); i.next();)
- {
- const Rectangle& r = *i.getRectangle();
- ExcludeClipRect (dc, r.getX(), r.getY(), r.getRight(), r.getBottom());
- }
- }
-
- const int w = getWidth();
- const int h = getHeight();
-
- if (hdd == 0)
- {
- StretchDIBits (dc,
- x, y, w, h,
- 0, 0, w, h,
- bitmapData, (const BITMAPINFO*) &bitmapInfo,
- DIB_RGB_COLORS, SRCCOPY);
- }
- else
- {
- DrawDibDraw (hdd, dc, x, y, -1, -1,
- (BITMAPINFOHEADER*) &bitmapInfo, bitmapData,
- 0, 0, w, h, 0);
- }
-
- if (! maskedRegion.isEmpty())
- RestoreDC (dc, savedDC);
- }
- }
-
- juce_UseDebuggingNewOperator
-
- private:
- WindowsBitmapImage (const WindowsBitmapImage&);
- const WindowsBitmapImage& operator= (const WindowsBitmapImage&);
- };
-
- long improbableWindowNumber = 0xf965aa01; // also referenced by messaging.cpp
-
- static int currentModifiers = 0;
- static int modifiersAtLastCallback = 0;
-
- static void updateKeyModifiers() throw()
- {
- currentModifiers &= ~(ModifierKeys::shiftModifier
- | ModifierKeys::ctrlModifier
- | ModifierKeys::altModifier);
-
- if ((GetKeyState (VK_SHIFT) & 0x8000) != 0)
- currentModifiers |= ModifierKeys::shiftModifier;
-
- if ((GetKeyState (VK_CONTROL) & 0x8000) != 0)
- currentModifiers |= ModifierKeys::ctrlModifier;
-
- if ((GetKeyState (VK_MENU) & 0x8000) != 0)
- currentModifiers |= ModifierKeys::altModifier;
-
- if ((GetKeyState (VK_RMENU) & 0x8000) != 0)
- currentModifiers &= ~(ModifierKeys::ctrlModifier | ModifierKeys::altModifier);
- }
-
- void ModifierKeys::updateCurrentModifiers() throw()
- {
- currentModifierFlags = currentModifiers;
- }
-
- bool KeyPress::isKeyCurrentlyDown (const int keyCode) throw()
- {
- SHORT k = (SHORT) keyCode;
-
- if ((keyCode & extendedKeyModifier) == 0
- && (k >= (SHORT) T('a') && k <= (SHORT) T('z')))
- k += (SHORT) T('A') - (SHORT) T('a');
-
- const SHORT translatedValues[] = { (SHORT) ',', VK_OEM_COMMA,
- (SHORT) '+', VK_OEM_PLUS,
- (SHORT) '-', VK_OEM_MINUS,
- (SHORT) '.', VK_OEM_PERIOD,
- (SHORT) ';', VK_OEM_1,
- (SHORT) ':', VK_OEM_1,
- (SHORT) '/', VK_OEM_2,
- (SHORT) '?', VK_OEM_2,
- (SHORT) '[', VK_OEM_4,
- (SHORT) ']', VK_OEM_6 };
-
- for (int i = 0; i < numElementsInArray (translatedValues); i += 2)
- if (k == translatedValues [i])
- k = translatedValues [i + 1];
-
- return (GetKeyState (k) & 0x8000) != 0;
- }
-
- const ModifierKeys ModifierKeys::getCurrentModifiersRealtime() throw()
- {
- updateKeyModifiers();
-
- currentModifiers &= ~ModifierKeys::allMouseButtonModifiers;
-
- if ((GetKeyState (VK_LBUTTON) & 0x8000) != 0)
- currentModifiers |= ModifierKeys::leftButtonModifier;
-
- if ((GetKeyState (VK_RBUTTON) & 0x8000) != 0)
- currentModifiers |= ModifierKeys::rightButtonModifier;
-
- if ((GetKeyState (VK_MBUTTON) & 0x8000) != 0)
- currentModifiers |= ModifierKeys::middleButtonModifier;
-
- return ModifierKeys (currentModifiers);
- }
-
- static int64 getMouseEventTime() throw()
- {
- static int64 eventTimeOffset = 0;
- static DWORD lastMessageTime = 0;
- const DWORD thisMessageTime = GetMessageTime();
-
- if (thisMessageTime < lastMessageTime || lastMessageTime == 0)
- {
- lastMessageTime = thisMessageTime;
- eventTimeOffset = Time::currentTimeMillis() - thisMessageTime;
- }
-
- return eventTimeOffset + thisMessageTime;
- }
-
- class Win32ComponentPeer : public ComponentPeer
- {
- public:
-
- Win32ComponentPeer (Component* const component,
- const int windowStyleFlags)
- : ComponentPeer (component, windowStyleFlags),
- dontRepaint (false),
- fullScreen (false),
- isDragging (false),
- isMouseOver (false),
- hasCreatedCaret (false),
- currentWindowIcon (0),
- taskBarIcon (0),
- dropTarget (0)
- {
- MessageManager::getInstance()
- ->callFunctionOnMessageThread (&createWindowCallback, (void*) this);
-
- setTitle (component->getName());
-
- if ((windowStyleFlags & windowHasDropShadow) != 0
- && Desktop::canUseSemiTransparentWindows())
- {
- shadower = component->getLookAndFeel().createDropShadowerForComponent (component);
-
- if (shadower != 0)
- shadower->setOwner (component);
- }
- else
- {
- shadower = 0;
- }
- }
-
- ~Win32ComponentPeer()
- {
- setTaskBarIcon (0);
- deleteAndZero (shadower);
-
- // do this before the next bit to avoid messages arriving for this window
- // before it's destroyed
- SetWindowLongPtr (hwnd, GWLP_USERDATA, 0);
-
- MessageManager::getInstance()
- ->callFunctionOnMessageThread (&destroyWindowCallback, (void*) hwnd);
-
- if (currentWindowIcon != 0)
- DestroyIcon (currentWindowIcon);
-
- if (dropTarget != 0)
- {
- dropTarget->Release();
- dropTarget = 0;
- }
- }
-
- void* getNativeHandle() const
- {
- return (void*) hwnd;
- }
-
- void setVisible (bool shouldBeVisible)
- {
- ShowWindow (hwnd, shouldBeVisible ? SW_SHOWNA : SW_HIDE);
-
- if (shouldBeVisible)
- InvalidateRect (hwnd, 0, 0);
- else
- lastPaintTime = 0;
- }
-
- void setTitle (const String& title)
- {
- SetWindowText (hwnd, title);
- }
-
- void setPosition (int x, int y)
- {
- offsetWithinParent (x, y);
- SetWindowPos (hwnd, 0,
- x - windowBorder.getLeft(),
- y - windowBorder.getTop(),
- 0, 0,
- SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOOWNERZORDER);
- }
-
- void repaintNowIfTransparent()
- {
- if (isTransparent() && lastPaintTime > 0 && Time::getMillisecondCounter() > lastPaintTime + 30)
- handlePaintMessage();
- }
-
- void updateBorderSize()
- {
- WINDOWINFO info;
- info.cbSize = sizeof (info);
-
- if (GetWindowInfo (hwnd, &info))
- {
- windowBorder = BorderSize (info.rcClient.top - info.rcWindow.top,
- info.rcClient.left - info.rcWindow.left,
- info.rcWindow.bottom - info.rcClient.bottom,
- info.rcWindow.right - info.rcClient.right);
- }
- }
-
- void setSize (int w, int h)
- {
- SetWindowPos (hwnd, 0, 0, 0,
- w + windowBorder.getLeftAndRight(),
- h + windowBorder.getTopAndBottom(),
- SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOOWNERZORDER);
-
- updateBorderSize();
-
- repaintNowIfTransparent();
- }
-
- void setBounds (int x, int y, int w, int h, const bool isNowFullScreen)
- {
- fullScreen = isNowFullScreen;
- offsetWithinParent (x, y);
-
- SetWindowPos (hwnd, 0,
- x - windowBorder.getLeft(),
- y - windowBorder.getTop(),
- w + windowBorder.getLeftAndRight(),
- h + windowBorder.getTopAndBottom(),
- SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOOWNERZORDER);
-
- updateBorderSize();
-
- repaintNowIfTransparent();
- }
-
- void getBounds (int& x, int& y, int& w, int& h) const
- {
- RECT r;
- GetWindowRect (hwnd, &r);
-
- x = r.left;
- y = r.top;
- w = r.right - x;
- h = r.bottom - y;
-
- HWND parentH = GetParent (hwnd);
- if (parentH != 0)
- {
- GetWindowRect (parentH, &r);
- x -= r.left;
- y -= r.top;
- }
-
- x += windowBorder.getLeft();
- y += windowBorder.getTop();
- w -= windowBorder.getLeftAndRight();
- h -= windowBorder.getTopAndBottom();
- }
-
- int getScreenX() const
- {
- RECT r;
- GetWindowRect (hwnd, &r);
- return r.left + windowBorder.getLeft();
- }
-
- int getScreenY() const
- {
- RECT r;
- GetWindowRect (hwnd, &r);
- return r.top + windowBorder.getTop();
- }
-
- void relativePositionToGlobal (int& x, int& y)
- {
- RECT r;
- GetWindowRect (hwnd, &r);
-
- x += r.left + windowBorder.getLeft();
- y += r.top + windowBorder.getTop();
- }
-
- void globalPositionToRelative (int& x, int& y)
- {
- RECT r;
- GetWindowRect (hwnd, &r);
-
- x -= r.left + windowBorder.getLeft();
- y -= r.top + windowBorder.getTop();
- }
-
- void setMinimised (bool shouldBeMinimised)
- {
- if (shouldBeMinimised != isMinimised())
- ShowWindow (hwnd, shouldBeMinimised ? SW_MINIMIZE : SW_SHOWNORMAL);
- }
-
- bool isMinimised() const
- {
- WINDOWPLACEMENT wp;
- wp.length = sizeof (WINDOWPLACEMENT);
- GetWindowPlacement (hwnd, &wp);
-
- return wp.showCmd == SW_SHOWMINIMIZED;
- }
-
- void setFullScreen (bool shouldBeFullScreen)
- {
- setMinimised (false);
-
- if (fullScreen != shouldBeFullScreen)
- {
- fullScreen = shouldBeFullScreen;
- const ComponentDeletionWatcher deletionChecker (component);
-
- if (! fullScreen)
- {
- const Rectangle boundsCopy (lastNonFullscreenBounds);
-
- if (hasTitleBar())
- ShowWindow (hwnd, SW_SHOWNORMAL);
-
- if (! boundsCopy.isEmpty())
- {
- setBounds (boundsCopy.getX(),
- boundsCopy.getY(),
- boundsCopy.getWidth(),
- boundsCopy.getHeight(),
- false);
- }
- }
- else
- {
- if (hasTitleBar())
- ShowWindow (hwnd, SW_SHOWMAXIMIZED);
- else
- SendMessageW (hwnd, WM_SETTINGCHANGE, 0, 0);
- }
-
- if (! deletionChecker.hasBeenDeleted())
- handleMovedOrResized();
- }
- }
-
- bool isFullScreen() const
- {
- if (! hasTitleBar())
- return fullScreen;
-
- WINDOWPLACEMENT wp;
- wp.length = sizeof (wp);
- GetWindowPlacement (hwnd, &wp);
-
- return wp.showCmd == SW_SHOWMAXIMIZED;
- }
-
- bool contains (int x, int y, bool trueIfInAChildWindow) const
- {
- RECT r;
- GetWindowRect (hwnd, &r);
-
- POINT p;
- p.x = x + r.left + windowBorder.getLeft();
- p.y = y + r.top + windowBorder.getTop();
-
- HWND w = WindowFromPoint (p);
-
- return w == hwnd || (trueIfInAChildWindow && (IsChild (hwnd, w) != 0));
- }
-
- const BorderSize getFrameSize() const
- {
- return windowBorder;
- }
-
- bool setAlwaysOnTop (bool alwaysOnTop)
- {
- const bool oldDeactivate = shouldDeactivateTitleBar;
- shouldDeactivateTitleBar = ((styleFlags & windowIsTemporary) == 0);
-
- SetWindowPos (hwnd, alwaysOnTop ? HWND_TOPMOST : HWND_NOTOPMOST,
- 0, 0, 0, 0,
- SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOSENDCHANGING);
-
- shouldDeactivateTitleBar = oldDeactivate;
-
- if (shadower != 0)
- shadower->componentBroughtToFront (*component);
-
- return true;
- }
-
- void toFront (bool makeActive)
- {
- setMinimised (false);
-
- const bool oldDeactivate = shouldDeactivateTitleBar;
- shouldDeactivateTitleBar = ((styleFlags & windowIsTemporary) == 0);
-
- MessageManager::getInstance()
- ->callFunctionOnMessageThread (makeActive ? &toFrontCallback1
- : &toFrontCallback2,
- (void*) hwnd);
-
- shouldDeactivateTitleBar = oldDeactivate;
-
- if (! makeActive)
- {
- // in this case a broughttofront call won't have occured, so do it now..
- handleBroughtToFront();
- }
- }
-
- void toBehind (ComponentPeer* other)
- {
- Win32ComponentPeer* const otherPeer = dynamic_cast <Win32ComponentPeer*> (other);
-
- jassert (otherPeer != 0); // wrong type of window?
-
- if (otherPeer != 0)
- {
- setMinimised (false);
-
- SetWindowPos (hwnd, otherPeer->hwnd, 0, 0, 0, 0,
- SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOSENDCHANGING);
- }
- }
-
- bool isFocused() const
- {
- return MessageManager::getInstance()
- ->callFunctionOnMessageThread (&getFocusCallback, 0) == (void*) hwnd;
- }
-
- void grabFocus()
- {
- const bool oldDeactivate = shouldDeactivateTitleBar;
- shouldDeactivateTitleBar = ((styleFlags & windowIsTemporary) == 0);
-
- MessageManager::getInstance()
- ->callFunctionOnMessageThread (&setFocusCallback, (void*) hwnd);
-
- shouldDeactivateTitleBar = oldDeactivate;
- }
-
- void textInputRequired (int /*x*/, int /*y*/)
- {
- if (! hasCreatedCaret)
- {
- hasCreatedCaret = true;
- CreateCaret (hwnd, (HBITMAP) 1, 0, 0);
- }
-
- ShowCaret (hwnd);
- SetCaretPos (0, 0);
- }
-
- void repaint (int x, int y, int w, int h)
- {
- const RECT r = { x, y, x + w, y + h };
- InvalidateRect (hwnd, &r, FALSE);
- }
-
- void performAnyPendingRepaintsNow()
- {
- MSG m;
- if (component->isVisible() && PeekMessage (&m, hwnd, WM_PAINT, WM_PAINT, PM_REMOVE))
- DispatchMessage (&m);
- }
-
- static Win32ComponentPeer* getOwnerOfWindow (HWND h) throw()
- {
- if (h != 0 && GetWindowLongPtr (h, GWLP_USERDATA) == improbableWindowNumber)
- return (Win32ComponentPeer*) GetWindowLongPtr (h, 8);
-
- return 0;
- }
-
- void setTaskBarIcon (const Image* const image)
- {
- if (image != 0)
- {
- HICON hicon = createHICONFromImage (*image, TRUE, 0, 0);
-
- if (taskBarIcon == 0)
- {
- taskBarIcon = new NOTIFYICONDATA();
- taskBarIcon->cbSize = sizeof (NOTIFYICONDATA);
- taskBarIcon->hWnd = (HWND) hwnd;
- taskBarIcon->uID = (int) (pointer_sized_int) hwnd;
- taskBarIcon->uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
- taskBarIcon->uCallbackMessage = WM_TRAYNOTIFY;
- taskBarIcon->hIcon = hicon;
- taskBarIcon->szTip[0] = 0;
-
- Shell_NotifyIcon (NIM_ADD, taskBarIcon);
- }
- else
- {
- HICON oldIcon = taskBarIcon->hIcon;
-
- taskBarIcon->hIcon = hicon;
- taskBarIcon->uFlags = NIF_ICON;
- Shell_NotifyIcon (NIM_MODIFY, taskBarIcon);
-
- DestroyIcon (oldIcon);
- }
-
- DestroyIcon (hicon);
- }
- else if (taskBarIcon != 0)
- {
- taskBarIcon->uFlags = 0;
- Shell_NotifyIcon (NIM_DELETE, taskBarIcon);
- DestroyIcon (taskBarIcon->hIcon);
- deleteAndZero (taskBarIcon);
- }
- }
-
- void setTaskBarIconToolTip (const String& toolTip) const
- {
- if (taskBarIcon != 0)
- {
- taskBarIcon->uFlags = NIF_TIP;
- toolTip.copyToBuffer (taskBarIcon->szTip, sizeof (taskBarIcon->szTip) - 1);
- Shell_NotifyIcon (NIM_MODIFY, taskBarIcon);
- }
- }
-
- juce_UseDebuggingNewOperator
-
- bool dontRepaint;
-
- private:
- HWND hwnd;
- DropShadower* shadower;
- bool fullScreen, isDragging, isMouseOver, hasCreatedCaret;
- BorderSize windowBorder;
- HICON currentWindowIcon;
- NOTIFYICONDATA* taskBarIcon;
- IDropTarget* dropTarget;
-
- class TemporaryImage : public Timer
- {
- public:
-
- TemporaryImage()
- : image (0)
- {
- }
-
- ~TemporaryImage()
- {
- delete image;
- }
-
- WindowsBitmapImage* getImage (const bool transparent, const int w, const int h) throw()
- {
- const Image::PixelFormat format = transparent ? Image::ARGB : Image::RGB;
-
- if (image == 0 || image->getWidth() < w || image->getHeight() < h || image->getFormat() != format)
- {
- delete image;
- image = new WindowsBitmapImage (format, (w + 31) & ~31, (h + 31) & ~31, false);
- }
-
- startTimer (3000);
- return image;
- }
-
- void timerCallback()
- {
- stopTimer();
- deleteAndZero (image);
- }
-
- private:
- WindowsBitmapImage* image;
-
- TemporaryImage (const TemporaryImage&);
- const TemporaryImage& operator= (const TemporaryImage&);
- };
-
- TemporaryImage offscreenImageGenerator;
-
- class WindowClassHolder : public DeletedAtShutdown
- {
- public:
- WindowClassHolder()
- : windowClassName ("JUCE_")
- {
- // this name has to be different for each app/dll instance because otherwise
- // poor old Win32 can get a bit confused (even despite it not being a process-global
- // window class).
- windowClassName << (int) (Time::currentTimeMillis() & 0x7fffffff);
-
- HINSTANCE moduleHandle = (HINSTANCE) PlatformUtilities::getCurrentModuleInstanceHandle();
-
- TCHAR moduleFile [1024];
- moduleFile[0] = 0;
- GetModuleFileName (moduleHandle, moduleFile, 1024);
- WORD iconNum = 0;
-
- WNDCLASSEX wcex;
- wcex.cbSize = sizeof (wcex);
- wcex.style = CS_OWNDC;
- wcex.lpfnWndProc = (WNDPROC) windowProc;
- wcex.lpszClassName = windowClassName;
- wcex.cbClsExtra = 0;
- wcex.cbWndExtra = 32;
- wcex.hInstance = moduleHandle;
- wcex.hIcon = ExtractAssociatedIcon (moduleHandle, moduleFile, &iconNum);
- iconNum = 1;
- wcex.hIconSm = ExtractAssociatedIcon (moduleHandle, moduleFile, &iconNum);
- wcex.hCursor = 0;
- wcex.hbrBackground = 0;
- wcex.lpszMenuName = 0;
-
- RegisterClassEx (&wcex);
- }
-
- ~WindowClassHolder()
- {
- if (ComponentPeer::getNumPeers() == 0)
- UnregisterClass (windowClassName, (HINSTANCE) PlatformUtilities::getCurrentModuleInstanceHandle());
-
- clearSingletonInstance();
- }
-
- String windowClassName;
-
- juce_DeclareSingleton_SingleThreaded_Minimal (WindowClassHolder);
- };
-
- static void* createWindowCallback (void* userData)
- {
- ((Win32ComponentPeer*) userData)->createWindow();
- return 0;
- }
-
- void createWindow()
- {
- DWORD exstyle = WS_EX_ACCEPTFILES;
- DWORD type = WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
-
- if (hasTitleBar())
- {
- type |= WS_OVERLAPPED;
- exstyle |= WS_EX_APPWINDOW;
-
- if ((styleFlags & windowHasCloseButton) != 0)
- {
- type |= WS_SYSMENU;
- }
- else
- {
- // annoyingly, windows won't let you have a min/max button without a close button
- jassert ((styleFlags & (windowHasMinimiseButton | windowHasMaximiseButton)) == 0);
- }
-
- if ((styleFlags & windowIsResizable) != 0)
- type |= WS_THICKFRAME;
- }
- else
- {
- type |= WS_POPUP | WS_SYSMENU;
-
- if ((styleFlags & windowAppearsOnTaskbar) == 0)
- exstyle |= WS_EX_TOOLWINDOW;
- else
- exstyle |= WS_EX_APPWINDOW;
- }
-
- if ((styleFlags & windowHasMinimiseButton) != 0)
- type |= WS_MINIMIZEBOX;
-
- if ((styleFlags & windowHasMaximiseButton) != 0)
- type |= WS_MAXIMIZEBOX;
-
- if ((styleFlags & windowIgnoresMouseClicks) != 0)
- exstyle |= WS_EX_TRANSPARENT;
-
- if ((styleFlags & windowIsSemiTransparent) != 0
- && Desktop::canUseSemiTransparentWindows())
- exstyle |= WS_EX_LAYERED;
-
- hwnd = CreateWindowEx (exstyle, WindowClassHolder::getInstance()->windowClassName, L"", type, 0, 0, 0, 0, 0, 0, 0, 0);
-
- if (hwnd != 0)
- {
- SetWindowLongPtr (hwnd, 0, 0);
- SetWindowLongPtr (hwnd, 8, (LONG_PTR) this);
- SetWindowLongPtr (hwnd, GWLP_USERDATA, improbableWindowNumber);
-
- if (dropTarget == 0)
- dropTarget = new JuceDropTarget (this);
-
- RegisterDragDrop (hwnd, dropTarget);
-
- updateBorderSize();
-
- // Calling this function here is (for some reason) necessary to make Windows
- // correctly enable the menu items that we specify in the wm_initmenu message.
- GetSystemMenu (hwnd, false);
- }
- else
- {
- jassertfalse
- }
- }
-
- static void* destroyWindowCallback (void* handle)
- {
- RevokeDragDrop ((HWND) handle);
- DestroyWindow ((HWND) handle);
- return 0;
- }
-
- static void* toFrontCallback1 (void* h)
- {
- SetForegroundWindow ((HWND) h);
- return 0;
- }
-
- static void* toFrontCallback2 (void* h)
- {
- SetWindowPos ((HWND) h, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOSENDCHANGING);
- return 0;
- }
-
- static void* setFocusCallback (void* h)
- {
- SetFocus ((HWND) h);
- return 0;
- }
-
- static void* getFocusCallback (void*)
- {
- return (void*) GetFocus();
- }
-
- void offsetWithinParent (int& x, int& y) const
- {
- if (isTransparent())
- {
- HWND parentHwnd = GetParent (hwnd);
-
- if (parentHwnd != 0)
- {
- RECT parentRect;
- GetWindowRect (parentHwnd, &parentRect);
- x += parentRect.left;
- y += parentRect.top;
- }
- }
- }
-
- bool isTransparent() const
- {
- return (GetWindowLong (hwnd, GWL_EXSTYLE) & WS_EX_LAYERED) != 0;
- }
-
- inline bool hasTitleBar() const throw() { return (styleFlags & windowHasTitleBar) != 0; }
-
- void setIcon (const Image& newIcon)
- {
- HICON hicon = createHICONFromImage (newIcon, TRUE, 0, 0);
-
- if (hicon != 0)
- {
- SendMessage (hwnd, WM_SETICON, ICON_BIG, (LPARAM) hicon);
- SendMessage (hwnd, WM_SETICON, ICON_SMALL, (LPARAM) hicon);
-
- if (currentWindowIcon != 0)
- DestroyIcon (currentWindowIcon);
-
- currentWindowIcon = hicon;
- }
- }
-
- void handlePaintMessage()
- {
- #if DEBUG_REPAINT_TIMES
- const double paintStart = Time::getMillisecondCounterHiRes();
- #endif
- HRGN rgn = CreateRectRgn (0, 0, 0, 0);
- const int regionType = GetUpdateRgn (hwnd, rgn, false);
-
- PAINTSTRUCT paintStruct;
- HDC dc = BeginPaint (hwnd, &paintStruct); // Note this can immediately generate a WM_NCPAINT
- // message and become re-entrant, but that's OK
-
- // if something in a paint handler calls, e.g. a message box, this can become reentrant and
- // corrupt the image it's using to paint into, so do a check here.
- static bool reentrant = false;
- if (reentrant)
- {
- DeleteObject (rgn);
- EndPaint (hwnd, &paintStruct);
- return;
- }
-
- reentrant = true;
-
- // this is the rectangle to update..
- int x = paintStruct.rcPaint.left;
- int y = paintStruct.rcPaint.top;
- int w = paintStruct.rcPaint.right - x;
- int h = paintStruct.rcPaint.bottom - y;
-
- const bool transparent = isTransparent();
-
- if (transparent)
- {
- // it's not possible to have a transparent window with a title bar at the moment!
- jassert (! hasTitleBar());
-
- RECT r;
- GetWindowRect (hwnd, &r);
- x = y = 0;
- w = r.right - r.left;
- h = r.bottom - r.top;
- }
-
- if (w > 0 && h > 0)
- {
- clearMaskedRegion();
-
- WindowsBitmapImage* const offscreenImage = offscreenImageGenerator.getImage (transparent, w, h);
-
- LowLevelGraphicsSoftwareRenderer context (*offscreenImage);
-
- RectangleList* const contextClip = context.getRawClipRegion();
- contextClip->clear();
-
- context.setOrigin (-x, -y);
-
- bool needToPaintAll = true;
-
- if (regionType == COMPLEXREGION && ! transparent)
- {
- HRGN clipRgn = CreateRectRgnIndirect (&paintStruct.rcPaint);
- CombineRgn (rgn, rgn, clipRgn, RGN_AND);
- DeleteObject (clipRgn);
-
- char rgnData [8192];
- const DWORD res = GetRegionData (rgn, sizeof (rgnData), (RGNDATA*) rgnData);
-
- if (res > 0 && res <= sizeof (rgnData))
- {
- const RGNDATAHEADER* const hdr = &(((const RGNDATA*) rgnData)->rdh);
-
- if (hdr->iType == RDH_RECTANGLES
- && hdr->rcBound.right - hdr->rcBound.left >= w
- && hdr->rcBound.bottom - hdr->rcBound.top >= h)
- {
- needToPaintAll = false;
-
- const RECT* rects = (const RECT*) (rgnData + sizeof (RGNDATAHEADER));
- int num = ((RGNDATA*) rgnData)->rdh.nCount;
-
- while (--num >= 0)
- {
- // (need to move this one pixel to the left because of a win32 bug)
- const int cx = jmax (x, rects->left - 1);
- const int cy = rects->top;
- const int cw = rects->right - cx;
- const int ch = rects->bottom - rects->top;
-
- if (cx + cw - x <= w && cy + ch - y <= h)
- {
- contextClip->addWithoutMerging (Rectangle (cx - x, cy - y, cw, ch));
- }
- else
- {
- needToPaintAll = true;
- break;
- }
-
- ++rects;
- }
- }
- }
- }
-
- if (needToPaintAll)
- {
- contextClip->clear();
- contextClip->addWithoutMerging (Rectangle (0, 0, w, h));
- }
-
- if (transparent)
- {
- RectangleList::Iterator i (*contextClip);
-
- while (i.next())
- {
- const Rectangle& r = *i.getRectangle();
- offscreenImage->clear (r.getX(), r.getY(), r.getWidth(), r.getHeight());
- }
- }
-
- // if the component's not opaque, this won't draw properly unless the platform can support this
- jassert (Desktop::canUseSemiTransparentWindows() || component->isOpaque());
-
- updateCurrentModifiers();
-
- handlePaint (context);
-
- if (! dontRepaint)
- offscreenImage->blitToWindow (hwnd, dc, transparent, x, y, maskedRegion);
- }
-
- DeleteObject (rgn);
- EndPaint (hwnd, &paintStruct);
- reentrant = false;
-
- #ifndef JUCE_GCC //xxx should add this fn for gcc..
- _fpreset(); // because some graphics cards can unmask FP exceptions
- #endif
-
- lastPaintTime = Time::getMillisecondCounter();
-
- #if DEBUG_REPAINT_TIMES
- const double elapsed = Time::getMillisecondCounterHiRes() - paintStart;
- Logger::outputDebugString (T("repaint time: ") + String (elapsed, 2));
- #endif
- }
-
- void doMouseMove (const int x, const int y)
- {
- static uint32 lastMouseTime = 0;
- // this can be set to throttle the mouse-messages to less than a
- // certain number per second, as things can get unresponsive
- // if each drag or move callback has to do a lot of work.
- const int maxMouseMovesPerSecond = 60;
-
- const int64 mouseEventTime = getMouseEventTime();
-
- if (! isMouseOver)
- {
- isMouseOver = true;
-
- TRACKMOUSEEVENT tme;
- tme.cbSize = sizeof (tme);
- tme.dwFlags = TME_LEAVE;
- tme.hwndTrack = hwnd;
- tme.dwHoverTime = 0;
-
- if (! TrackMouseEvent (&tme))
- {
- jassertfalse;
- }
-
- updateKeyModifiers();
- handleMouseEnter (x, y, mouseEventTime);
- }
- else if (! isDragging)
- {
- if (((unsigned int) x) < (unsigned int) component->getWidth()
- && ((unsigned int) y) < (unsigned int) component->getHeight())
- {
- RECT r;
- GetWindowRect (hwnd, &r);
-
- POINT p;
- p.x = x + r.left + windowBorder.getLeft();
- p.y = y + r.top + windowBorder.getTop();
-
- if (WindowFromPoint (p) == hwnd)
- {
- const uint32 now = Time::getMillisecondCounter();
-
- if (now > lastMouseTime + 1000 / maxMouseMovesPerSecond)
- {
- lastMouseTime = now;
- handleMouseMove (x, y, mouseEventTime);
- }
- }
- }
- }
- else
- {
- const uint32 now = Time::getMillisecondCounter();
-
- if (now > lastMouseTime + 1000 / maxMouseMovesPerSecond)
- {
- lastMouseTime = now;
- handleMouseDrag (x, y, mouseEventTime);
- }
- }
- }
-
- void doMouseDown (const int x, const int y, const WPARAM wParam)
- {
- if (GetCapture() != hwnd)
- SetCapture (hwnd);
-
- doMouseMove (x, y);
-
- currentModifiers &= ~ModifierKeys::allMouseButtonModifiers;
-
- if ((wParam & MK_LBUTTON) != 0)
- currentModifiers |= ModifierKeys::leftButtonModifier;
-
- if ((wParam & MK_RBUTTON) != 0)
- currentModifiers |= ModifierKeys::rightButtonModifier;
-
- if ((wParam & MK_MBUTTON) != 0)
- currentModifiers |= ModifierKeys::middleButtonModifier;
-
- updateKeyModifiers();
- isDragging = true;
-
- handleMouseDown (x, y, getMouseEventTime());
- }
-
- void doMouseUp (const int x, const int y, const WPARAM wParam)
- {
- int numButtons = 0;
-
- if ((wParam & MK_LBUTTON) != 0)
- ++numButtons;
-
- if ((wParam & MK_RBUTTON) != 0)
- ++numButtons;
-
- if ((wParam & MK_MBUTTON) != 0)
- ++numButtons;
-
- const int oldModifiers = currentModifiers;
-
- // update the currentmodifiers only after the callback, so the callback
- // knows which button was released.
- currentModifiers &= ~ModifierKeys::allMouseButtonModifiers;
-
- if ((wParam & MK_LBUTTON) != 0)
- currentModifiers |= ModifierKeys::leftButtonModifier;
-
- if ((wParam & MK_RBUTTON) != 0)
- currentModifiers |= ModifierKeys::rightButtonModifier;
-
- if ((wParam & MK_MBUTTON) != 0)
- currentModifiers |= ModifierKeys::middleButtonModifier;
-
- updateKeyModifiers();
- isDragging = false;
-
- // release the mouse capture if the user's not still got a button down
- if (numButtons == 0 && hwnd == GetCapture())
- ReleaseCapture();
-
- handleMouseUp (oldModifiers, x, y, getMouseEventTime());
- }
-
- void doCaptureChanged()
- {
- if (isDragging)
- {
- RECT wr;
- GetWindowRect (hwnd, &wr);
-
- const DWORD mp = GetMessagePos();
-
- doMouseUp (GET_X_LPARAM (mp) - wr.left - windowBorder.getLeft(),
- GET_Y_LPARAM (mp) - wr.top - windowBorder.getTop(),
- getMouseEventTime());
- }
- }
-
- void doMouseExit()
- {
- if (isMouseOver)
- {
- isMouseOver = false;
- RECT wr;
- GetWindowRect (hwnd, &wr);
-
- const DWORD mp = GetMessagePos();
-
- handleMouseExit (GET_X_LPARAM (mp) - wr.left - windowBorder.getLeft(),
- GET_Y_LPARAM (mp) - wr.top - windowBorder.getTop(),
- getMouseEventTime());
- }
- }
-
- void doMouseWheel (const WPARAM wParam, const bool isVertical)
- {
- updateKeyModifiers();
-
- const int amount = jlimit (-1000, 1000, (int) (0.75f * (short) HIWORD (wParam)));
-
- handleMouseWheel (isVertical ? 0 : amount,
- isVertical ? amount : 0,
- getMouseEventTime());
- }
-
- void sendModifierKeyChangeIfNeeded()
- {
- if (modifiersAtLastCallback != currentModifiers)
- {
- modifiersAtLastCallback = currentModifiers;
- handleModifierKeysChange();
- }
- }
-
- bool doKeyUp (const WPARAM key)
- {
- updateKeyModifiers();
-
- switch (key)
- {
- case VK_SHIFT:
- case VK_CONTROL:
- case VK_MENU:
- case VK_CAPITAL:
- case VK_LWIN:
- case VK_RWIN:
- case VK_APPS:
- case VK_NUMLOCK:
- case VK_SCROLL:
- case VK_LSHIFT:
- case VK_RSHIFT:
- case VK_LCONTROL:
- case VK_LMENU:
- case VK_RCONTROL:
- case VK_RMENU:
- sendModifierKeyChangeIfNeeded();
- }
-
- return handleKeyUpOrDown();
- }
-
- bool doKeyDown (const WPARAM key)
- {
- updateKeyModifiers();
- bool used = false;
-
- switch (key)
- {
- case VK_SHIFT:
- case VK_LSHIFT:
- case VK_RSHIFT:
- case VK_CONTROL:
- case VK_LCONTROL:
- case VK_RCONTROL:
- case VK_MENU:
- case VK_LMENU:
- case VK_RMENU:
- case VK_LWIN:
- case VK_RWIN:
- case VK_CAPITAL:
- case VK_NUMLOCK:
- case VK_SCROLL:
- case VK_APPS:
- sendModifierKeyChangeIfNeeded();
- break;
-
- case VK_LEFT:
- case VK_RIGHT:
- case VK_UP:
- case VK_DOWN:
- case VK_PRIOR:
- case VK_NEXT:
- case VK_HOME:
- case VK_END:
- case VK_DELETE:
- case VK_INSERT:
- case VK_F1:
- case VK_F2:
- case VK_F3:
- case VK_F4:
- case VK_F5:
- case VK_F6:
- case VK_F7:
- case VK_F8:
- case VK_F9:
- case VK_F10:
- case VK_F11:
- case VK_F12:
- case VK_F13:
- case VK_F14:
- case VK_F15:
- case VK_F16:
- used = handleKeyUpOrDown();
- used = handleKeyPress (extendedKeyModifier | (int) key, 0) || used;
- break;
-
- case VK_ADD:
- case VK_SUBTRACT:
- case VK_MULTIPLY:
- case VK_DIVIDE:
- case VK_SEPARATOR:
- case VK_DECIMAL:
- used = handleKeyUpOrDown();
- break;
-
- default:
- used = handleKeyUpOrDown();
-
- {
- MSG msg;
-
- if (! PeekMessage (&msg, hwnd, WM_CHAR, WM_DEADCHAR, PM_NOREMOVE))
- {
- // if there isn't a WM_CHAR or WM_DEADCHAR message pending, we need to
- // manually generate the key-press event that matches this key-down.
-
- const UINT keyChar = MapVirtualKey (key, 2);
- used = handleKeyPress ((int) LOWORD (keyChar), 0) || used;
- }
- }
-
- break;
- }
-
- return used;
- }
-
- bool doKeyChar (int key, const LPARAM flags)
- {
- updateKeyModifiers();
-
- juce_wchar textChar = (juce_wchar) key;
-
- const int virtualScanCode = (flags >> 16) & 0xff;
-
- if (key >= '0' && key <= '9')
- {
- switch (virtualScanCode) // check for a numeric keypad scan-code
- {
- case 0x52:
- case 0x4f:
- case 0x50:
- case 0x51:
- case 0x4b:
- case 0x4c:
- case 0x4d:
- case 0x47:
- case 0x48:
- case 0x49:
- key = (key - '0') + KeyPress::numberPad0;
- break;
- default:
- break;
- }
- }
- else
- {
- // convert the scan code to an unmodified character code..
- const UINT virtualKey = MapVirtualKey (virtualScanCode, 1);
- UINT keyChar = MapVirtualKey (virtualKey, 2);
-
- keyChar = LOWORD (keyChar);
-
- if (keyChar != 0)
- key = (int) keyChar;
-
- // avoid sending junk text characters for some control-key combinations
- if (textChar < ' ' && (currentModifiers & (ModifierKeys::ctrlModifier | ModifierKeys::altModifier)) != 0)
- textChar = 0;
- }
-
- return handleKeyPress (key, textChar);
- }
-
- bool doAppCommand (const LPARAM lParam)
- {
- int key = 0;
-
- switch (GET_APPCOMMAND_LPARAM (lParam))
- {
- case APPCOMMAND_MEDIA_PLAY_PAUSE:
- key = KeyPress::playKey;
- break;
-
- case APPCOMMAND_MEDIA_STOP:
- key = KeyPress::stopKey;
- break;
-
- case APPCOMMAND_MEDIA_NEXTTRACK:
- key = KeyPress::fastForwardKey;
- break;
-
- case APPCOMMAND_MEDIA_PREVIOUSTRACK:
- key = KeyPress::rewindKey;
- break;
- }
-
- if (key != 0)
- {
- updateKeyModifiers();
-
- if (hwnd == GetActiveWindow())
- {
- handleKeyPress (key, 0);
- return true;
- }
- }
-
- return false;
- }
-
- class JuceDropTarget : public IDropTarget
- {
- public:
- JuceDropTarget (Win32ComponentPeer* const owner_)
- : owner (owner_),
- refCount (1)
- {
- }
-
- virtual ~JuceDropTarget()
- {
- jassert (refCount == 0);
- }
-
- HRESULT __stdcall QueryInterface (REFIID id, void __RPC_FAR* __RPC_FAR* result)
- {
- if (id == IID_IUnknown || id == IID_IDropTarget)
- {
- AddRef();
- *result = this;
- return S_OK;
- }
-
- *result = 0;
- return E_NOINTERFACE;
- }
-
- ULONG __stdcall AddRef() { return ++refCount; }
- ULONG __stdcall Release() { jassert (refCount > 0); const int r = --refCount; if (r == 0) delete this; return r; }
-
- HRESULT __stdcall DragEnter (IDataObject* pDataObject, DWORD /*grfKeyState*/, POINTL mousePos, DWORD* pdwEffect)
- {
- updateFileList (pDataObject);
- int x = mousePos.x, y = mousePos.y;
- owner->globalPositionToRelative (x, y);
- owner->handleFileDragMove (files, x, y);
- *pdwEffect = DROPEFFECT_COPY;
- return S_OK;
- }
-
- HRESULT __stdcall DragLeave()
- {
- owner->handleFileDragExit (files);
- return S_OK;
- }
-
- HRESULT __stdcall DragOver (DWORD /*grfKeyState*/, POINTL mousePos, DWORD* pdwEffect)
- {
- int x = mousePos.x, y = mousePos.y;
- owner->globalPositionToRelative (x, y);
- owner->handleFileDragMove (files, x, y);
- *pdwEffect = DROPEFFECT_COPY;
- return S_OK;
- }
-
- HRESULT __stdcall Drop (IDataObject* pDataObject, DWORD /*grfKeyState*/, POINTL mousePos, DWORD* pdwEffect)
- {
- updateFileList (pDataObject);
- int x = mousePos.x, y = mousePos.y;
- owner->globalPositionToRelative (x, y);
- owner->handleFileDragDrop (files, x, y);
- *pdwEffect = DROPEFFECT_COPY;
- return S_OK;
- }
-
- private:
- Win32ComponentPeer* const owner;
- int refCount;
- StringArray files;
-
- void updateFileList (IDataObject* const pDataObject)
- {
- files.clear();
-
- FORMATETC format = { CF_HDROP, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
- STGMEDIUM medium = { TYMED_HGLOBAL, { 0 }, 0 };
-
- if (pDataObject->GetData (&format, &medium) == S_OK)
- {
- const SIZE_T totalLen = GlobalSize (medium.hGlobal);
- const LPDROPFILES pDropFiles = (const LPDROPFILES) GlobalLock (medium.hGlobal);
- unsigned int i = 0;
-
- if (pDropFiles->fWide)
- {
- const WCHAR* const fname = (WCHAR*) (((const char*) pDropFiles) + sizeof (DROPFILES));
-
- for (;;)
- {
- unsigned int len = 0;
- while (i + len < totalLen && fname [i + len] != 0)
- ++len;
-
- if (len == 0)
- break;
-
- files.add (String (fname + i, len));
- i += len + 1;
- }
- }
- else
- {
- const char* const fname = ((const char*) pDropFiles) + sizeof (DROPFILES);
-
- for (;;)
- {
- unsigned int len = 0;
- while (i + len < totalLen && fname [i + len] != 0)
- ++len;
-
- if (len == 0)
- break;
-
- files.add (String (fname + i, len));
- i += len + 1;
- }
- }
-
- GlobalUnlock (medium.hGlobal);
- }
- }
-
- JuceDropTarget (const JuceDropTarget&);
- const JuceDropTarget& operator= (const JuceDropTarget&);
- };
-
- void doSettingChange()
- {
- Desktop::getInstance().refreshMonitorSizes();
-
- if (fullScreen && ! isMinimised())
- {
- const Rectangle r (component->getParentMonitorArea());
-
- SetWindowPos (hwnd, 0,
- r.getX(), r.getY(), r.getWidth(), r.getHeight(),
- SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER | SWP_NOSENDCHANGING);
- }
- }
-
- public:
- static LRESULT CALLBACK windowProc (HWND h, UINT message, WPARAM wParam, LPARAM lParam)
- {
- Win32ComponentPeer* const peer = getOwnerOfWindow (h);
-
- if (peer != 0)
- return peer->peerWindowProc (h, message, wParam, lParam);
-
- return DefWindowProc (h, message, wParam, lParam);
- }
-
- private:
- LRESULT peerWindowProc (HWND h, UINT message, WPARAM wParam, LPARAM lParam)
- {
- {
- const MessageManagerLock messLock;
-
- if (isValidPeer (this))
- {
- switch (message)
- {
- case WM_NCHITTEST:
- if (hasTitleBar())
- break;
-
- return HTCLIENT;
-
- case WM_PAINT:
- handlePaintMessage();
- return 0;
-
- case WM_NCPAINT:
- if (wParam != 1)
- handlePaintMessage();
-
- if (hasTitleBar())
- break;
-
- return 0;
-
- case WM_ERASEBKGND:
- case WM_NCCALCSIZE:
- if (hasTitleBar())
- break;
-
- return 1;
-
- case WM_MOUSEMOVE:
- doMouseMove (GET_X_LPARAM (lParam), GET_Y_LPARAM (lParam));
- return 0;
-
- case WM_MOUSELEAVE:
- doMouseExit();
- return 0;
-
- case WM_LBUTTONDOWN:
- case WM_MBUTTONDOWN:
- case WM_RBUTTONDOWN:
- doMouseDown (GET_X_LPARAM (lParam), GET_Y_LPARAM (lParam), wParam);
- return 0;
-
- case WM_LBUTTONUP:
- case WM_MBUTTONUP:
- case WM_RBUTTONUP:
- doMouseUp (GET_X_LPARAM (lParam), GET_Y_LPARAM (lParam), wParam);
- return 0;
-
- case WM_CAPTURECHANGED:
- doCaptureChanged();
- return 0;
-
- case WM_NCMOUSEMOVE:
- if (hasTitleBar())
- break;
-
- return 0;
-
- case 0x020A: /* WM_MOUSEWHEEL */
- doMouseWheel (wParam, true);
- return 0;
-
- case 0x020E: /* WM_MOUSEHWHEEL */
- doMouseWheel (wParam, false);
- return 0;
-
- case WM_WINDOWPOSCHANGING:
- if ((styleFlags & (windowHasTitleBar | windowIsResizable)) == (windowHasTitleBar | windowIsResizable))
- {
- WINDOWPOS* const wp = (WINDOWPOS*) lParam;
-
- if ((wp->flags & (SWP_NOMOVE | SWP_NOSIZE)) != (SWP_NOMOVE | SWP_NOSIZE))
- {
- if (constrainer != 0)
- {
- const Rectangle current (component->getX() - windowBorder.getLeft(),
- component->getY() - windowBorder.getTop(),
- component->getWidth() + windowBorder.getLeftAndRight(),
- component->getHeight() + windowBorder.getTopAndBottom());
-
- constrainer->checkBounds (wp->x, wp->y, wp->cx, wp->cy,
- current,
- Desktop::getInstance().getAllMonitorDisplayAreas().getBounds(),
- wp->y != current.getY() && wp->y + wp->cy == current.getBottom(),
- wp->x != current.getX() && wp->x + wp->cx == current.getRight(),
- wp->y == current.getY() && wp->y + wp->cy != current.getBottom(),
- wp->x == current.getX() && wp->x + wp->cx != current.getRight());
- }
- }
- }
-
- return 0;
-
- case WM_WINDOWPOSCHANGED:
- handleMovedOrResized();
-
- if (dontRepaint)
- break; // needed for non-accelerated openGL windows to draw themselves correctly..
- else
- return 0;
-
- case WM_KEYDOWN:
- case WM_SYSKEYDOWN:
- if (doKeyDown (wParam))
- return 0;
-
- break;
-
- case WM_KEYUP:
- case WM_SYSKEYUP:
- if (doKeyUp (wParam))
- return 0;
-
- break;
-
- case WM_CHAR:
- if (doKeyChar ((int) wParam, lParam))
- return 0;
-
- break;
-
- case WM_APPCOMMAND:
- if (doAppCommand (lParam))
- return TRUE;
-
- break;
-
- case WM_SETFOCUS:
- updateKeyModifiers();
- handleFocusGain();
- break;
-
- case WM_KILLFOCUS:
- if (hasCreatedCaret)
- {
- hasCreatedCaret = false;
- DestroyCaret();
- }
-
- handleFocusLoss();
- break;
-
- case WM_ACTIVATEAPP:
- // Windows does weird things to process priority when you swap apps,
- // so this forces an update when the app is brought to the front
- if (wParam != FALSE)
- juce_repeatLastProcessPriority();
-
- juce_CheckCurrentlyFocusedTopLevelWindow();
- modifiersAtLastCallback = -1;
- return 0;
-
- case WM_ACTIVATE:
- if (LOWORD (wParam) == WA_ACTIVE || LOWORD (wParam) == WA_CLICKACTIVE)
- {
- modifiersAtLastCallback = -1;
- updateKeyModifiers();
-
- if (isMinimised())
- {
- component->repaint();
- handleMovedOrResized();
-
- if (! isValidMessageListener())
- return 0;
- }
-
- if (LOWORD (wParam) == WA_CLICKACTIVE
- && component->isCurrentlyBlockedByAnotherModalComponent())
- {
- int mx, my;
- component->getMouseXYRelative (mx, my);
- Component* const underMouse = component->getComponentAt (mx, my);
-
- if (underMouse != 0 && underMouse->isCurrentlyBlockedByAnotherModalComponent())
- Component::getCurrentlyModalComponent()->inputAttemptWhenModal();
-
- return 0;
- }
-
- handleBroughtToFront();
- return 0;
- }
-
- break;
-
- case WM_NCACTIVATE:
- // while a temporary window is being shown, prevent Windows from deactivating the
- // title bars of our main windows.
- if (wParam == 0 && ! shouldDeactivateTitleBar)
- wParam = TRUE; // change this and let it get passed to the DefWindowProc.
-
- break;
-
- case WM_MOUSEACTIVATE:
- if (! component->getMouseClickGrabsKeyboardFocus())
- return MA_NOACTIVATE;
-
- break;
-
- case WM_SHOWWINDOW:
- if (wParam != 0)
- handleBroughtToFront();
-
- break;
-
- case WM_CLOSE:
- handleUserClosingWindow();
- return 0;
-
- case WM_QUIT:
- JUCEApplication::quit();
- return 0;
-
- case WM_TRAYNOTIFY:
- if (component->isCurrentlyBlockedByAnotherModalComponent())
- {
- if (lParam == WM_LBUTTONDOWN || lParam == WM_RBUTTONDOWN
- || lParam == WM_LBUTTONDBLCLK || lParam == WM_LBUTTONDBLCLK)
- {
- Component* const current = Component::getCurrentlyModalComponent();
-
- if (current != 0)
- current->inputAttemptWhenModal();
- }
- }
- else
- {
- const int oldModifiers = currentModifiers;
-
- MouseEvent e (0, 0, ModifierKeys::getCurrentModifiersRealtime(), component,
- getMouseEventTime(), 0, 0, getMouseEventTime(), 1, false);
-
- if (lParam == WM_LBUTTONDOWN || lParam == WM_LBUTTONDBLCLK)
- e.mods = ModifierKeys (e.mods.getRawFlags() | ModifierKeys::leftButtonModifier);
- else if (lParam == WM_RBUTTONDOWN || lParam == WM_RBUTTONDBLCLK)
- e.mods = ModifierKeys (e.mods.getRawFlags() | ModifierKeys::rightButtonModifier);
-
- if (lParam == WM_LBUTTONDOWN || lParam == WM_RBUTTONDOWN)
- {
- SetFocus (hwnd);
- SetForegroundWindow (hwnd);
-
- component->mouseDown (e);
- }
- else if (lParam == WM_LBUTTONUP || lParam == WM_RBUTTONUP)
- {
- e.mods = ModifierKeys (oldModifiers);
- component->mouseUp (e);
- }
- else if (lParam == WM_LBUTTONDBLCLK || lParam == WM_LBUTTONDBLCLK)
- {
- e.mods = ModifierKeys (oldModifiers);
- component->mouseDoubleClick (e);
- }
- else if (lParam == WM_MOUSEMOVE)
- {
- component->mouseMove (e);
- }
- }
-
- break;
-
- case WM_SYNCPAINT:
- return 0;
-
- case WM_PALETTECHANGED:
- InvalidateRect (h, 0, 0);
- break;
-
- case WM_DISPLAYCHANGE:
- InvalidateRect (h, 0, 0);
- createPaletteIfNeeded = true;
- // intentional fall-through...
- case WM_SETTINGCHANGE: // note the fall-through in the previous case!
- doSettingChange();
- break;
-
- case WM_INITMENU:
- if (! hasTitleBar())
- {
- if (isFullScreen())
- {
- EnableMenuItem ((HMENU) wParam, SC_RESTORE, MF_BYCOMMAND | MF_ENABLED);
- EnableMenuItem ((HMENU) wParam, SC_MOVE, MF_BYCOMMAND | MF_GRAYED);
- }
- else if (! isMinimised())
- {
- EnableMenuItem ((HMENU) wParam, SC_MAXIMIZE, MF_BYCOMMAND | MF_GRAYED);
- }
- }
- break;
-
- case WM_SYSCOMMAND:
- switch (wParam & 0xfff0)
- {
- case SC_CLOSE:
- if (hasTitleBar())
- {
- PostMessage (h, WM_CLOSE, 0, 0);
- return 0;
- }
- break;
-
- case SC_KEYMENU:
- if (hasTitleBar() && h == GetCapture())
- ReleaseCapture();
-
- break;
-
- case SC_MAXIMIZE:
- setFullScreen (true);
- return 0;
-
- case SC_MINIMIZE:
- if (! hasTitleBar())
- {
- setMinimised (true);
- return 0;
- }
- break;
-
- case SC_RESTORE:
- if (hasTitleBar())
- {
- if (isFullScreen())
- {
- setFullScreen (false);
- return 0;
- }
- }
- else
- {
- if (isMinimised())
- setMinimised (false);
- else if (isFullScreen())
- setFullScreen (false);
-
- return 0;
- }
-
- break;
-
- case SC_MONITORPOWER:
- case SC_SCREENSAVE:
- if (! screenSaverAllowed)
- return 0;
-
- break;
- }
-
- break;
-
- case WM_NCLBUTTONDOWN:
- case WM_NCRBUTTONDOWN:
- case WM_NCMBUTTONDOWN:
- if (component->isCurrentlyBlockedByAnotherModalComponent())
- {
- Component* const current = Component::getCurrentlyModalComponent();
-
- if (current != 0)
- current->inputAttemptWhenModal();
- }
-
- break;
-
- //case WM_IME_STARTCOMPOSITION;
- // return 0;
-
- case WM_GETDLGCODE:
- return DLGC_WANTALLKEYS;
-
- default:
- break;
- }
- }
- }
-
- // (the message manager lock exits before calling this, to avoid deadlocks if
- // this calls into non-juce windows)
- return DefWindowProc (h, message, wParam, lParam);
- }
-
- Win32ComponentPeer (const Win32ComponentPeer&);
- const Win32ComponentPeer& operator= (const Win32ComponentPeer&);
- };
-
- ComponentPeer* Component::createNewPeer (int styleFlags, void* /*nativeWindowToAttachTo*/)
- {
- return new Win32ComponentPeer (this, styleFlags);
- }
-
- juce_ImplementSingleton_SingleThreaded (Win32ComponentPeer::WindowClassHolder);
-
- void SystemTrayIconComponent::setIconImage (const Image& newImage)
- {
- Win32ComponentPeer* const wp = dynamic_cast <Win32ComponentPeer*> (getPeer());
-
- if (wp != 0)
- wp->setTaskBarIcon (&newImage);
- }
-
- void SystemTrayIconComponent::setIconTooltip (const String& tooltip)
- {
- Win32ComponentPeer* const wp = dynamic_cast <Win32ComponentPeer*> (getPeer());
-
- if (wp != 0)
- wp->setTaskBarIconToolTip (tooltip);
- }
-
- void juce_setWindowStyleBit (HWND h, const int styleType, const int feature, const bool bitIsSet) throw()
- {
- DWORD val = GetWindowLong (h, styleType);
-
- if (bitIsSet)
- val |= feature;
- else
- val &= ~feature;
-
- SetWindowLongPtr (h, styleType, val);
- SetWindowPos (h, 0, 0, 0, 0, 0,
- SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER
- | SWP_NOOWNERZORDER | SWP_FRAMECHANGED | SWP_NOSENDCHANGING);
- }
-
- bool Process::isForegroundProcess() throw()
- {
- HWND fg = GetForegroundWindow();
-
- if (fg == 0)
- return true;
-
- DWORD processId = 0;
- GetWindowThreadProcessId (fg, &processId);
-
- return processId == GetCurrentProcessId();
- }
-
- void Desktop::getMousePosition (int& x, int& y) throw()
- {
- POINT mousePos;
- GetCursorPos (&mousePos);
- x = mousePos.x;
- y = mousePos.y;
- }
-
- void Desktop::setMousePosition (int x, int y) throw()
- {
- SetCursorPos (x, y);
- }
-
- void Desktop::setScreenSaverEnabled (const bool isEnabled) throw()
- {
- screenSaverAllowed = isEnabled;
- }
-
- bool Desktop::isScreenSaverEnabled() throw()
- {
- return screenSaverAllowed;
- }
-
- static BOOL CALLBACK enumMonitorsProc (HMONITOR, HDC, LPRECT r, LPARAM userInfo)
- {
- Array <Rectangle>* const monitorCoords = (Array <Rectangle>*) userInfo;
-
- monitorCoords->add (Rectangle (r->left, r->top, r->right - r->left, r->bottom - r->top));
-
- return TRUE;
- }
-
- void juce_updateMultiMonitorInfo (Array <Rectangle>& monitorCoords, const bool clipToWorkArea) throw()
- {
- EnumDisplayMonitors (0, 0, &enumMonitorsProc, (LPARAM) &monitorCoords);
-
- // make sure the first in the list is the main monitor
- for (int i = 1; i < monitorCoords.size(); ++i)
- if (monitorCoords[i].getX() == 0 && monitorCoords[i].getY() == 0)
- monitorCoords.swap (i, 0);
-
- if (monitorCoords.size() == 0)
- {
- RECT r;
- GetWindowRect (GetDesktopWindow(), &r);
-
- monitorCoords.add (Rectangle (r.left, r.top, r.right - r.left, r.bottom - r.top));
- }
-
- if (clipToWorkArea)
- {
- // clip the main monitor to the active non-taskbar area
- RECT r;
- SystemParametersInfo (SPI_GETWORKAREA, 0, &r, 0);
-
- Rectangle& screen = monitorCoords.getReference (0);
-
- screen.setPosition (jmax (screen.getX(), r.left),
- jmax (screen.getY(), r.top));
-
- screen.setSize (jmin (screen.getRight(), r.right) - screen.getX(),
- jmin (screen.getBottom(), r.bottom) - screen.getY());
- }
- }
-
- static Image* createImageFromHBITMAP (HBITMAP bitmap) throw()
- {
- Image* im = 0;
-
- if (bitmap != 0)
- {
- BITMAP bm;
-
- if (GetObject (bitmap, sizeof (BITMAP), &bm)
- && bm.bmWidth > 0 && bm.bmHeight > 0)
- {
- HDC tempDC = GetDC (0);
- HDC dc = CreateCompatibleDC (tempDC);
- ReleaseDC (0, tempDC);
-
- SelectObject (dc, bitmap);
-
- im = new Image (Image::ARGB, bm.bmWidth, bm.bmHeight, true);
-
- for (int y = bm.bmHeight; --y >= 0;)
- {
- for (int x = bm.bmWidth; --x >= 0;)
- {
- COLORREF col = GetPixel (dc, x, y);
-
- im->setPixelAt (x, y, Colour ((uint8) GetRValue (col),
- (uint8) GetGValue (col),
- (uint8) GetBValue (col)));
- }
- }
-
- DeleteDC (dc);
- }
- }
-
- return im;
- }
-
- static Image* createImageFromHICON (HICON icon) throw()
- {
- ICONINFO info;
-
- if (GetIconInfo (icon, &info))
- {
- Image* const mask = createImageFromHBITMAP (info.hbmMask);
-
- if (mask == 0)
- return 0;
-
- Image* const image = createImageFromHBITMAP (info.hbmColor);
-
- if (image == 0)
- return mask;
-
- for (int y = image->getHeight(); --y >= 0;)
- {
- for (int x = image->getWidth(); --x >= 0;)
- {
- const float brightness = mask->getPixelAt (x, y).getBrightness();
-
- if (brightness > 0.0f)
- image->multiplyAlphaAt (x, y, 1.0f - brightness);
- }
- }
-
- delete mask;
- return image;
- }
-
- return 0;
- }
-
- static HICON createHICONFromImage (const Image& image, const BOOL isIcon, int hotspotX, int hotspotY) throw()
- {
- HBITMAP mask = CreateBitmap (image.getWidth(), image.getHeight(), 1, 1, 0);
-
- ICONINFO info;
- info.fIcon = isIcon;
- info.xHotspot = hotspotX;
- info.yHotspot = hotspotY;
- info.hbmMask = mask;
- HICON hi = 0;
-
- if (SystemStats::getOperatingSystemType() >= SystemStats::WinXP)
- {
- WindowsBitmapImage bitmap (Image::ARGB, image.getWidth(), image.getHeight(), true);
- Graphics g (bitmap);
- g.drawImageAt (&image, 0, 0);
-
- info.hbmColor = bitmap.hBitmap;
- hi = CreateIconIndirect (&info);
- }
- else
- {
- HBITMAP colour = CreateCompatibleBitmap (GetDC (0), image.getWidth(), image.getHeight());
-
- HDC colDC = CreateCompatibleDC (GetDC (0));
- HDC alphaDC = CreateCompatibleDC (GetDC (0));
- SelectObject (colDC, colour);
- SelectObject (alphaDC, mask);
-
- for (int y = image.getHeight(); --y >= 0;)
- {
- for (int x = image.getWidth(); --x >= 0;)
- {
- const Colour c (image.getPixelAt (x, y));
-
- SetPixel (colDC, x, y, COLORREF (c.getRed() | (c.getGreen() << 8) | (c.getBlue() << 16)));
- SetPixel (alphaDC, x, y, COLORREF (0xffffff - (c.getAlpha() | (c.getAlpha() << 8) | (c.getAlpha() << 16))));
- }
- }
-
- DeleteDC (colDC);
- DeleteDC (alphaDC);
-
- info.hbmColor = colour;
- hi = CreateIconIndirect (&info);
- DeleteObject (colour);
- }
-
- DeleteObject (mask);
- return hi;
- }
-
- Image* juce_createIconForFile (const File& file)
- {
- Image* image = 0;
-
- TCHAR filename [1024];
- file.getFullPathName().copyToBuffer (filename, 1023);
- WORD iconNum = 0;
-
- HICON icon = ExtractAssociatedIcon ((HINSTANCE) PlatformUtilities::getCurrentModuleInstanceHandle(),
- filename, &iconNum);
-
- if (icon != 0)
- {
- image = createImageFromHICON (icon);
- DestroyIcon (icon);
- }
-
- return image;
- }
-
- void* juce_createMouseCursorFromImage (const Image& image, int hotspotX, int hotspotY) throw()
- {
- const int maxW = GetSystemMetrics (SM_CXCURSOR);
- const int maxH = GetSystemMetrics (SM_CYCURSOR);
-
- const Image* im = ℑ
- Image* newIm = 0;
-
- if (image.getWidth() > maxW || image.getHeight() > maxH)
- {
- im = newIm = image.createCopy (maxW, maxH);
-
- hotspotX = (hotspotX * maxW) / image.getWidth();
- hotspotY = (hotspotY * maxH) / image.getHeight();
- }
-
- void* cursorH = 0;
-
- const SystemStats::OperatingSystemType os = SystemStats::getOperatingSystemType();
-
- if (os == SystemStats::WinXP)
- {
- cursorH = (void*) createHICONFromImage (*im, FALSE, hotspotX, hotspotY);
- }
- else
- {
- const int stride = (maxW + 7) >> 3;
- uint8* const andPlane = (uint8*) juce_calloc (stride * maxH);
- uint8* const xorPlane = (uint8*) juce_calloc (stride * maxH);
- int index = 0;
-
- for (int y = 0; y < maxH; ++y)
- {
- for (int x = 0; x < maxW; ++x)
- {
- const unsigned char bit = (unsigned char) (1 << (7 - (x & 7)));
-
- const Colour pixelColour (im->getPixelAt (x, y));
-
- if (pixelColour.getAlpha() < 127)
- andPlane [index + (x >> 3)] |= bit;
- else if (pixelColour.getBrightness() >= 0.5f)
- xorPlane [index + (x >> 3)] |= bit;
- }
-
- index += stride;
- }
-
- cursorH = CreateCursor (0, hotspotX, hotspotY, maxW, maxH, andPlane, xorPlane);
-
- juce_free (andPlane);
- juce_free (xorPlane);
- }
-
- delete newIm;
- return cursorH;
- }
-
- void juce_deleteMouseCursor (void* const cursorHandle, const bool isStandard) throw()
- {
- if (cursorHandle != 0 && ! isStandard)
- DestroyCursor ((HCURSOR) cursorHandle);
- }
-
- void* juce_createStandardMouseCursor (MouseCursor::StandardCursorType type) throw()
- {
- LPCTSTR cursorName = IDC_ARROW;
-
- switch (type)
- {
- case MouseCursor::NormalCursor:
- cursorName = IDC_ARROW;
- break;
-
- case MouseCursor::NoCursor:
- return 0;
-
- case MouseCursor::DraggingHandCursor:
- {
- static void* dragHandCursor = 0;
-
- if (dragHandCursor == 0)
- {
- static const unsigned char dragHandData[] =
- { 71,73,70,56,57,97,16,0,16,0,145,2,0,0,0,0,255,255,255,0,0,0,0,0,0,33,249,4,1,0,0,2,0,44,0,0,0,0,16,0,
- 16,0,0,2,52,148,47,0,200,185,16,130,90,12,74,139,107,84,123,39, 132,117,151,116,132,146,248,60,209,138,
- 98,22,203,114,34,236,37,52,77,217,247,154,191,119,110,240,193,128,193,95,163,56,60,234,98,135,2,0,59 };
-
- Image* const image = ImageFileFormat::loadFrom ((const char*) dragHandData, sizeof (dragHandData));
- dragHandCursor = juce_createMouseCursorFromImage (*image, 8, 7);
- delete image;
- }
-
- return dragHandCursor;
- }
-
- case MouseCursor::WaitCursor:
- cursorName = IDC_WAIT;
- break;
-
- case MouseCursor::IBeamCursor:
- cursorName = IDC_IBEAM;
- break;
-
- case MouseCursor::PointingHandCursor:
- cursorName = MAKEINTRESOURCE(32649);
- break;
-
- case MouseCursor::LeftRightResizeCursor:
- case MouseCursor::LeftEdgeResizeCursor:
- case MouseCursor::RightEdgeResizeCursor:
- cursorName = IDC_SIZEWE;
- break;
-
- case MouseCursor::UpDownResizeCursor:
- case MouseCursor::TopEdgeResizeCursor:
- case MouseCursor::BottomEdgeResizeCursor:
- cursorName = IDC_SIZENS;
- break;
-
- case MouseCursor::TopLeftCornerResizeCursor:
- case MouseCursor::BottomRightCornerResizeCursor:
- cursorName = IDC_SIZENWSE;
- break;
-
- case MouseCursor::TopRightCornerResizeCursor:
- case MouseCursor::BottomLeftCornerResizeCursor:
- cursorName = IDC_SIZENESW;
- break;
-
- case MouseCursor::UpDownLeftRightResizeCursor:
- cursorName = IDC_SIZEALL;
- break;
-
- case MouseCursor::CrosshairCursor:
- cursorName = IDC_CROSS;
- break;
-
- case MouseCursor::CopyingCursor:
- // can't seem to find one of these in the win32 list..
- break;
- }
-
- HCURSOR cursorH = LoadCursor (0, cursorName);
-
- if (cursorH == 0)
- cursorH = LoadCursor (0, IDC_ARROW);
-
- return (void*) cursorH;
- }
-
- void MouseCursor::showInWindow (ComponentPeer*) const throw()
- {
- SetCursor ((HCURSOR) getHandle());
- }
-
- void MouseCursor::showInAllWindows() const throw()
- {
- showInWindow (0);
- }
-
- class JuceDropSource : public IDropSource
- {
- int refCount;
-
- public:
- JuceDropSource()
- : refCount (1)
- {
- }
-
- virtual ~JuceDropSource()
- {
- jassert (refCount == 0);
- }
-
- HRESULT __stdcall QueryInterface (REFIID id, void __RPC_FAR* __RPC_FAR* result)
- {
- if (id == IID_IUnknown || id == IID_IDropSource)
- {
- AddRef();
- *result = this;
- return S_OK;
- }
-
- *result = 0;
- return E_NOINTERFACE;
- }
-
- ULONG __stdcall AddRef() { return ++refCount; }
- ULONG __stdcall Release() { jassert (refCount > 0); const int r = --refCount; if (r == 0) delete this; return r; }
-
- HRESULT __stdcall QueryContinueDrag (BOOL escapePressed, DWORD keys)
- {
- if (escapePressed)
- return DRAGDROP_S_CANCEL;
-
- if ((keys & (MK_LBUTTON | MK_RBUTTON)) == 0)
- return DRAGDROP_S_DROP;
-
- return S_OK;
- }
-
- HRESULT __stdcall GiveFeedback (DWORD)
- {
- return DRAGDROP_S_USEDEFAULTCURSORS;
- }
- };
-
- class JuceEnumFormatEtc : public IEnumFORMATETC
- {
- public:
- JuceEnumFormatEtc (const FORMATETC* const format_)
- : refCount (1),
- format (format_),
- index (0)
- {
- }
-
- virtual ~JuceEnumFormatEtc()
- {
- jassert (refCount == 0);
- }
-
- HRESULT __stdcall QueryInterface (REFIID id, void __RPC_FAR* __RPC_FAR* result)
- {
- if (id == IID_IUnknown || id == IID_IEnumFORMATETC)
- {
- AddRef();
- *result = this;
- return S_OK;
- }
-
- *result = 0;
- return E_NOINTERFACE;
- }
-
- ULONG __stdcall AddRef() { return ++refCount; }
- ULONG __stdcall Release() { jassert (refCount > 0); const int r = --refCount; if (r == 0) delete this; return r; }
-
- HRESULT __stdcall Clone (IEnumFORMATETC** result)
- {
- if (result == 0)
- return E_POINTER;
-
- JuceEnumFormatEtc* const newOne = new JuceEnumFormatEtc (format);
- newOne->index = index;
-
- *result = newOne;
- return S_OK;
- }
-
- HRESULT __stdcall Next (ULONG celt, LPFORMATETC lpFormatEtc, ULONG* pceltFetched)
- {
- if (pceltFetched != 0)
- *pceltFetched = 0;
- else if (celt != 1)
- return S_FALSE;
-
- if (index == 0 && celt > 0 && lpFormatEtc != 0)
- {
- copyFormatEtc (lpFormatEtc [0], *format);
- ++index;
-
- if (pceltFetched != 0)
- *pceltFetched = 1;
-
- return S_OK;
- }
-
- return S_FALSE;
- }
-
- HRESULT __stdcall Skip (ULONG celt)
- {
- if (index + (int) celt >= 1)
- return S_FALSE;
-
- index += celt;
- return S_OK;
- }
-
- HRESULT __stdcall Reset()
- {
- index = 0;
- return S_OK;
- }
-
- private:
- int refCount;
- const FORMATETC* const format;
- int index;
-
- static void copyFormatEtc (FORMATETC& dest, const FORMATETC& source)
- {
- dest = source;
-
- if (source.ptd != 0)
- {
- dest.ptd = (DVTARGETDEVICE*) CoTaskMemAlloc (sizeof (DVTARGETDEVICE));
- *(dest.ptd) = *(source.ptd);
- }
- }
-
- JuceEnumFormatEtc (const JuceEnumFormatEtc&);
- const JuceEnumFormatEtc& operator= (const JuceEnumFormatEtc&);
- };
-
- class JuceDataObject : public IDataObject
- {
- JuceDropSource* const dropSource;
- const FORMATETC* const format;
- const STGMEDIUM* const medium;
- int refCount;
-
- JuceDataObject (const JuceDataObject&);
- const JuceDataObject& operator= (const JuceDataObject&);
-
- public:
- JuceDataObject (JuceDropSource* const dropSource_,
- const FORMATETC* const format_,
- const STGMEDIUM* const medium_)
- : dropSource (dropSource_),
- format (format_),
- medium (medium_),
- refCount (1)
- {
- }
-
- virtual ~JuceDataObject()
- {
- jassert (refCount == 0);
- }
-
- HRESULT __stdcall QueryInterface (REFIID id, void __RPC_FAR* __RPC_FAR* result)
- {
- if (id == IID_IUnknown || id == IID_IDataObject)
- {
- AddRef();
- *result = this;
- return S_OK;
- }
-
- *result = 0;
- return E_NOINTERFACE;
- }
-
- ULONG __stdcall AddRef() { return ++refCount; }
- ULONG __stdcall Release() { jassert (refCount > 0); const int r = --refCount; if (r == 0) delete this; return r; }
-
- HRESULT __stdcall GetData (FORMATETC __RPC_FAR* pFormatEtc, STGMEDIUM __RPC_FAR* pMedium)
- {
- if (pFormatEtc->tymed == format->tymed
- && pFormatEtc->cfFormat == format->cfFormat
- && pFormatEtc->dwAspect == format->dwAspect)
- {
- pMedium->tymed = format->tymed;
- pMedium->pUnkForRelease = 0;
-
- if (format->tymed == TYMED_HGLOBAL)
- {
- const SIZE_T len = GlobalSize (medium->hGlobal);
- void* const src = GlobalLock (medium->hGlobal);
- void* const dst = GlobalAlloc (GMEM_FIXED, len);
-
- memcpy (dst, src, len);
-
- GlobalUnlock (medium->hGlobal);
-
- pMedium->hGlobal = dst;
- return S_OK;
- }
- }
-
- return DV_E_FORMATETC;
- }
-
- HRESULT __stdcall QueryGetData (FORMATETC __RPC_FAR* f)
- {
- if (f == 0)
- return E_INVALIDARG;
-
- if (f->tymed == format->tymed
- && f->cfFormat == format->cfFormat
- && f->dwAspect == format->dwAspect)
- return S_OK;
-
- return DV_E_FORMATETC;
- }
-
- HRESULT __stdcall GetCanonicalFormatEtc (FORMATETC __RPC_FAR*, FORMATETC __RPC_FAR* pFormatEtcOut)
- {
- pFormatEtcOut->ptd = 0;
- return E_NOTIMPL;
- }
-
- HRESULT __stdcall EnumFormatEtc (DWORD direction, IEnumFORMATETC __RPC_FAR *__RPC_FAR *result)
- {
- if (result == 0)
- return E_POINTER;
-
- if (direction == DATADIR_GET)
- {
- *result = new JuceEnumFormatEtc (format);
- return S_OK;
- }
-
- *result = 0;
- return E_NOTIMPL;
- }
-
- HRESULT __stdcall GetDataHere (FORMATETC __RPC_FAR*, STGMEDIUM __RPC_FAR*) { return DATA_E_FORMATETC; }
- HRESULT __stdcall SetData (FORMATETC __RPC_FAR*, STGMEDIUM __RPC_FAR*, BOOL) { return E_NOTIMPL; }
- HRESULT __stdcall DAdvise (FORMATETC __RPC_FAR*, DWORD, IAdviseSink __RPC_FAR*, DWORD __RPC_FAR*) { return OLE_E_ADVISENOTSUPPORTED; }
- HRESULT __stdcall DUnadvise (DWORD) { return E_NOTIMPL; }
- HRESULT __stdcall EnumDAdvise (IEnumSTATDATA __RPC_FAR *__RPC_FAR *) { return OLE_E_ADVISENOTSUPPORTED; }
- };
-
- static HDROP createHDrop (const StringArray& fileNames) throw()
- {
- int totalChars = 0;
- for (int i = fileNames.size(); --i >= 0;)
- totalChars += fileNames[i].length() + 1;
-
- HDROP hDrop = (HDROP) GlobalAlloc (GMEM_MOVEABLE | GMEM_ZEROINIT,
- sizeof (DROPFILES)
- + sizeof (WCHAR) * (totalChars + 2));
-
- if (hDrop != 0)
- {
- LPDROPFILES pDropFiles = (LPDROPFILES) GlobalLock (hDrop);
- pDropFiles->pFiles = sizeof (DROPFILES);
-
- pDropFiles->fWide = true;
-
- WCHAR* fname = (WCHAR*) (((char*) pDropFiles) + sizeof (DROPFILES));
-
- for (int i = 0; i < fileNames.size(); ++i)
- {
- fileNames[i].copyToBuffer (fname, 2048);
- fname += fileNames[i].length() + 1;
- }
-
- *fname = 0;
-
- GlobalUnlock (hDrop);
- }
-
- return hDrop;
- }
-
- static bool performDragDrop (FORMATETC* const format, STGMEDIUM* const medium, const DWORD whatToDo) throw()
- {
- JuceDropSource* const source = new JuceDropSource();
- JuceDataObject* const data = new JuceDataObject (source, format, medium);
-
- DWORD effect;
- const HRESULT res = DoDragDrop (data, source, whatToDo, &effect);
-
- data->Release();
- source->Release();
-
- return res == DRAGDROP_S_DROP;
- }
-
- bool DragAndDropContainer::performExternalDragDropOfFiles (const StringArray& files, const bool canMove)
- {
- FORMATETC format = { CF_HDROP, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
- STGMEDIUM medium = { TYMED_HGLOBAL, { 0 }, 0 };
-
- medium.hGlobal = createHDrop (files);
-
- return performDragDrop (&format, &medium, canMove ? (DROPEFFECT_COPY | DROPEFFECT_MOVE)
- : DROPEFFECT_COPY);
- }
-
- bool DragAndDropContainer::performExternalDragDropOfText (const String& text)
- {
- FORMATETC format = { CF_TEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
- STGMEDIUM medium = { TYMED_HGLOBAL, { 0 }, 0 };
-
- const int numChars = text.length();
-
- medium.hGlobal = GlobalAlloc (GMEM_MOVEABLE | GMEM_ZEROINIT, (numChars + 2) * sizeof (WCHAR));
- char* d = (char*) GlobalLock (medium.hGlobal);
-
- text.copyToBuffer ((WCHAR*) d, numChars + 1);
- format.cfFormat = CF_UNICODETEXT;
-
- GlobalUnlock (medium.hGlobal);
-
- return performDragDrop (&format, &medium, DROPEFFECT_COPY | DROPEFFECT_MOVE);
- }
-
- #if JUCE_OPENGL
-
- #define WGL_EXT_FUNCTION_INIT(extType, extFunc) \
- ((extFunc = (extType) wglGetProcAddress (#extFunc)) != 0)
-
- typedef const char* (WINAPI* PFNWGLGETEXTENSIONSSTRINGARBPROC) (HDC hdc);
- typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues);
- typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATARBPROC) (HDC hdc, const int* piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);
- typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC) (int interval);
- typedef int (WINAPI * PFNWGLGETSWAPINTERVALEXTPROC) (void);
-
- #define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000
- #define WGL_DRAW_TO_WINDOW_ARB 0x2001
- #define WGL_ACCELERATION_ARB 0x2003
- #define WGL_SWAP_METHOD_ARB 0x2007
- #define WGL_SUPPORT_OPENGL_ARB 0x2010
- #define WGL_PIXEL_TYPE_ARB 0x2013
- #define WGL_DOUBLE_BUFFER_ARB 0x2011
- #define WGL_COLOR_BITS_ARB 0x2014
- #define WGL_RED_BITS_ARB 0x2015
- #define WGL_GREEN_BITS_ARB 0x2017
- #define WGL_BLUE_BITS_ARB 0x2019
- #define WGL_ALPHA_BITS_ARB 0x201B
- #define WGL_DEPTH_BITS_ARB 0x2022
- #define WGL_STENCIL_BITS_ARB 0x2023
- #define WGL_FULL_ACCELERATION_ARB 0x2027
- #define WGL_ACCUM_RED_BITS_ARB 0x201E
- #define WGL_ACCUM_GREEN_BITS_ARB 0x201F
- #define WGL_ACCUM_BLUE_BITS_ARB 0x2020
- #define WGL_ACCUM_ALPHA_BITS_ARB 0x2021
- #define WGL_STEREO_ARB 0x2012
- #define WGL_SAMPLE_BUFFERS_ARB 0x2041
- #define WGL_SAMPLES_ARB 0x2042
- #define WGL_TYPE_RGBA_ARB 0x202B
-
- static void getWglExtensions (HDC dc, StringArray& result) throw()
- {
- PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB = 0;
-
- if (WGL_EXT_FUNCTION_INIT (PFNWGLGETEXTENSIONSSTRINGARBPROC, wglGetExtensionsStringARB))
- result.addTokens (String (wglGetExtensionsStringARB (dc)), false);
- else
- jassertfalse // If this fails, it may be because you didn't activate the openGL context
- }
-
- class WindowedGLContext : public OpenGLContext
- {
- public:
- WindowedGLContext (Component* const component_,
- HGLRC contextToShareWith,
- const OpenGLPixelFormat& pixelFormat)
- : renderContext (0),
- nativeWindow (0),
- dc (0),
- component (component_)
- {
- jassert (component != 0);
-
- createNativeWindow();
-
- // Use a default pixel format that should be supported everywhere
- PIXELFORMATDESCRIPTOR pfd;
- zerostruct (pfd);
- pfd.nSize = sizeof (pfd);
- pfd.nVersion = 1;
- pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
- pfd.iPixelType = PFD_TYPE_RGBA;
- pfd.cColorBits = 24;
- pfd.cDepthBits = 16;
-
- const int format = ChoosePixelFormat (dc, &pfd);
-
- if (format != 0)
- SetPixelFormat (dc, format, &pfd);
-
- renderContext = wglCreateContext (dc);
- makeActive();
-
- setPixelFormat (pixelFormat);
-
- if (contextToShareWith != 0 && renderContext != 0)
- wglShareLists (contextToShareWith, renderContext);
- }
-
- ~WindowedGLContext()
- {
- makeInactive();
-
- wglDeleteContext (renderContext);
-
- ReleaseDC ((HWND) nativeWindow->getNativeHandle(), dc);
- delete nativeWindow;
- }
-
- bool makeActive() const throw()
- {
- jassert (renderContext != 0);
- return wglMakeCurrent (dc, renderContext) != 0;
- }
-
- bool makeInactive() const throw()
- {
- return (! isActive()) || (wglMakeCurrent (0, 0) != 0);
- }
-
- bool isActive() const throw()
- {
- return wglGetCurrentContext() == renderContext;
- }
-
- const OpenGLPixelFormat getPixelFormat() const
- {
- OpenGLPixelFormat pf;
-
- makeActive();
- StringArray availableExtensions;
- getWglExtensions (dc, availableExtensions);
-
- fillInPixelFormatDetails (GetPixelFormat (dc), pf, availableExtensions);
- return pf;
- }
-
- void* getRawContext() const throw()
- {
- return renderContext;
- }
-
- bool setPixelFormat (const OpenGLPixelFormat& pixelFormat)
- {
- makeActive();
-
- PIXELFORMATDESCRIPTOR pfd;
- zerostruct (pfd);
- pfd.nSize = sizeof (pfd);
- pfd.nVersion = 1;
- pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER;
- pfd.iPixelType = PFD_TYPE_RGBA;
- pfd.iLayerType = PFD_MAIN_PLANE;
- pfd.cColorBits = pixelFormat.redBits + pixelFormat.greenBits + pixelFormat.blueBits;
- pfd.cRedBits = pixelFormat.redBits;
- pfd.cGreenBits = pixelFormat.greenBits;
- pfd.cBlueBits = pixelFormat.blueBits;
- pfd.cAlphaBits = pixelFormat.alphaBits;
- pfd.cDepthBits = pixelFormat.depthBufferBits;
- pfd.cStencilBits = pixelFormat.stencilBufferBits;
- pfd.cAccumBits = pixelFormat.accumulationBufferRedBits + pixelFormat.accumulationBufferGreenBits
- + pixelFormat.accumulationBufferBlueBits + pixelFormat.accumulationBufferAlphaBits;
- pfd.cAccumRedBits = pixelFormat.accumulationBufferRedBits;
- pfd.cAccumGreenBits = pixelFormat.accumulationBufferGreenBits;
- pfd.cAccumBlueBits = pixelFormat.accumulationBufferBlueBits;
- pfd.cAccumAlphaBits = pixelFormat.accumulationBufferAlphaBits;
-
- int format = 0;
-
- PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB = 0;
-
- StringArray availableExtensions;
- getWglExtensions (dc, availableExtensions);
-
- if (availableExtensions.contains ("WGL_ARB_pixel_format")
- && WGL_EXT_FUNCTION_INIT (PFNWGLCHOOSEPIXELFORMATARBPROC, wglChoosePixelFormatARB))
- {
- int attributes[64];
- int n = 0;
-
- attributes[n++] = WGL_DRAW_TO_WINDOW_ARB;
- attributes[n++] = GL_TRUE;
- attributes[n++] = WGL_SUPPORT_OPENGL_ARB;
- attributes[n++] = GL_TRUE;
- attributes[n++] = WGL_ACCELERATION_ARB;
- attributes[n++] = WGL_FULL_ACCELERATION_ARB;
- attributes[n++] = WGL_DOUBLE_BUFFER_ARB;
- attributes[n++] = GL_TRUE;
- attributes[n++] = WGL_PIXEL_TYPE_ARB;
- attributes[n++] = WGL_TYPE_RGBA_ARB;
-
- attributes[n++] = WGL_COLOR_BITS_ARB;
- attributes[n++] = pfd.cColorBits;
- attributes[n++] = WGL_RED_BITS_ARB;
- attributes[n++] = pixelFormat.redBits;
- attributes[n++] = WGL_GREEN_BITS_ARB;
- attributes[n++] = pixelFormat.greenBits;
- attributes[n++] = WGL_BLUE_BITS_ARB;
- attributes[n++] = pixelFormat.blueBits;
- attributes[n++] = WGL_ALPHA_BITS_ARB;
- attributes[n++] = pixelFormat.alphaBits;
- attributes[n++] = WGL_DEPTH_BITS_ARB;
- attributes[n++] = pixelFormat.depthBufferBits;
-
- if (pixelFormat.stencilBufferBits > 0)
- {
- attributes[n++] = WGL_STENCIL_BITS_ARB;
- attributes[n++] = pixelFormat.stencilBufferBits;
- }
-
- attributes[n++] = WGL_ACCUM_RED_BITS_ARB;
- attributes[n++] = pixelFormat.accumulationBufferRedBits;
- attributes[n++] = WGL_ACCUM_GREEN_BITS_ARB;
- attributes[n++] = pixelFormat.accumulationBufferGreenBits;
- attributes[n++] = WGL_ACCUM_BLUE_BITS_ARB;
- attributes[n++] = pixelFormat.accumulationBufferBlueBits;
- attributes[n++] = WGL_ACCUM_ALPHA_BITS_ARB;
- attributes[n++] = pixelFormat.accumulationBufferAlphaBits;
-
- if (availableExtensions.contains ("WGL_ARB_multisample")
- && pixelFormat.fullSceneAntiAliasingNumSamples > 0)
- {
- attributes[n++] = WGL_SAMPLE_BUFFERS_ARB;
- attributes[n++] = 1;
- attributes[n++] = WGL_SAMPLES_ARB;
- attributes[n++] = pixelFormat.fullSceneAntiAliasingNumSamples;
- }
-
- attributes[n++] = 0;
-
- UINT formatsCount;
- const BOOL ok = wglChoosePixelFormatARB (dc, attributes, 0, 1, &format, &formatsCount);
- (void) ok;
- jassert (ok);
- }
- else
- {
- format = ChoosePixelFormat (dc, &pfd);
- }
-
- if (format != 0)
- {
- makeInactive();
-
- // win32 can't change the pixel format of a window, so need to delete the
- // old one and create a new one..
- jassert (nativeWindow != 0);
- ReleaseDC ((HWND) nativeWindow->getNativeHandle(), dc);
- delete nativeWindow;
-
- createNativeWindow();
-
- if (SetPixelFormat (dc, format, &pfd))
- {
- wglDeleteContext (renderContext);
- renderContext = wglCreateContext (dc);
-
- jassert (renderContext != 0);
- return renderContext != 0;
- }
- }
-
- return false;
- }
-
- void updateWindowPosition (int x, int y, int w, int h, int)
- {
- SetWindowPos ((HWND) nativeWindow->getNativeHandle(), 0,
- x, y, w, h,
- SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOOWNERZORDER);
- }
-
- void repaint()
- {
- int x, y, w, h;
- nativeWindow->getBounds (x, y, w, h);
- nativeWindow->repaint (0, 0, w, h);
- }
-
- void swapBuffers()
- {
- SwapBuffers (dc);
- }
-
- bool setSwapInterval (const int numFramesPerSwap)
- {
- makeActive();
-
- StringArray availableExtensions;
- getWglExtensions (dc, availableExtensions);
-
- PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = 0;
-
- return availableExtensions.contains ("WGL_EXT_swap_control")
- && WGL_EXT_FUNCTION_INIT (PFNWGLSWAPINTERVALEXTPROC, wglSwapIntervalEXT)
- && wglSwapIntervalEXT (numFramesPerSwap) != FALSE;
- }
-
- int getSwapInterval() const
- {
- makeActive();
-
- StringArray availableExtensions;
- getWglExtensions (dc, availableExtensions);
-
- PFNWGLGETSWAPINTERVALEXTPROC wglGetSwapIntervalEXT = 0;
-
- if (availableExtensions.contains ("WGL_EXT_swap_control")
- && WGL_EXT_FUNCTION_INIT (PFNWGLGETSWAPINTERVALEXTPROC, wglGetSwapIntervalEXT))
- return wglGetSwapIntervalEXT();
-
- return 0;
- }
-
- void findAlternativeOpenGLPixelFormats (OwnedArray <OpenGLPixelFormat>& results)
- {
- jassert (isActive());
-
- StringArray availableExtensions;
- getWglExtensions (dc, availableExtensions);
-
- PFNWGLGETPIXELFORMATATTRIBIVARBPROC wglGetPixelFormatAttribivARB = 0;
- int numTypes = 0;
-
- if (availableExtensions.contains("WGL_ARB_pixel_format")
- && WGL_EXT_FUNCTION_INIT (PFNWGLGETPIXELFORMATATTRIBIVARBPROC, wglGetPixelFormatAttribivARB))
- {
- int attributes = WGL_NUMBER_PIXEL_FORMATS_ARB;
-
- if (! wglGetPixelFormatAttribivARB (dc, 1, 0, 1, &attributes, &numTypes))
- jassertfalse
- }
- else
- {
- numTypes = DescribePixelFormat (dc, 0, 0, 0);
- }
-
- OpenGLPixelFormat pf;
-
- for (int i = 0; i < numTypes; ++i)
- {
- if (fillInPixelFormatDetails (i + 1, pf, availableExtensions))
- {
- bool alreadyListed = false;
- for (int j = results.size(); --j >= 0;)
- if (pf == *results.getUnchecked(j))
- alreadyListed = true;
-
- if (! alreadyListed)
- results.add (new OpenGLPixelFormat (pf));
- }
- }
- }
-
- juce_UseDebuggingNewOperator
-
- HGLRC renderContext;
-
- private:
- Win32ComponentPeer* nativeWindow;
- Component* const component;
- HDC dc;
-
- void createNativeWindow()
- {
- nativeWindow = new Win32ComponentPeer (component, 0);
- nativeWindow->dontRepaint = true;
- nativeWindow->setVisible (true);
-
- HWND hwnd = (HWND) nativeWindow->getNativeHandle();
-
- Win32ComponentPeer* const peer = dynamic_cast <Win32ComponentPeer*> (component->getTopLevelComponent()->getPeer());
-
- if (peer != 0)
- {
- SetParent (hwnd, (HWND) peer->getNativeHandle());
- juce_setWindowStyleBit (hwnd, GWL_STYLE, WS_CHILD, true);
- juce_setWindowStyleBit (hwnd, GWL_STYLE, WS_POPUP, false);
- }
-
- dc = GetDC (hwnd);
- }
-
- bool fillInPixelFormatDetails (const int pixelFormatIndex,
- OpenGLPixelFormat& result,
- const StringArray& availableExtensions) const throw()
- {
- PFNWGLGETPIXELFORMATATTRIBIVARBPROC wglGetPixelFormatAttribivARB = 0;
-
- if (availableExtensions.contains ("WGL_ARB_pixel_format")
- && WGL_EXT_FUNCTION_INIT (PFNWGLGETPIXELFORMATATTRIBIVARBPROC, wglGetPixelFormatAttribivARB))
- {
- int attributes[32];
- int numAttributes = 0;
-
- attributes[numAttributes++] = WGL_DRAW_TO_WINDOW_ARB;
- attributes[numAttributes++] = WGL_SUPPORT_OPENGL_ARB;
- attributes[numAttributes++] = WGL_ACCELERATION_ARB;
- attributes[numAttributes++] = WGL_DOUBLE_BUFFER_ARB;
- attributes[numAttributes++] = WGL_PIXEL_TYPE_ARB;
- attributes[numAttributes++] = WGL_RED_BITS_ARB;
- attributes[numAttributes++] = WGL_GREEN_BITS_ARB;
- attributes[numAttributes++] = WGL_BLUE_BITS_ARB;
- attributes[numAttributes++] = WGL_ALPHA_BITS_ARB;
- attributes[numAttributes++] = WGL_DEPTH_BITS_ARB;
- attributes[numAttributes++] = WGL_STENCIL_BITS_ARB;
- attributes[numAttributes++] = WGL_ACCUM_RED_BITS_ARB;
- attributes[numAttributes++] = WGL_ACCUM_GREEN_BITS_ARB;
- attributes[numAttributes++] = WGL_ACCUM_BLUE_BITS_ARB;
- attributes[numAttributes++] = WGL_ACCUM_ALPHA_BITS_ARB;
-
- if (availableExtensions.contains ("WGL_ARB_multisample"))
- attributes[numAttributes++] = WGL_SAMPLES_ARB;
-
- int values[32];
- zeromem (values, sizeof (values));
-
- if (wglGetPixelFormatAttribivARB (dc, pixelFormatIndex, 0, numAttributes, attributes, values))
- {
- int n = 0;
- bool isValidFormat = (values[n++] == GL_TRUE); // WGL_DRAW_TO_WINDOW_ARB
- isValidFormat = (values[n++] == GL_TRUE) && isValidFormat; // WGL_SUPPORT_OPENGL_ARB
- isValidFormat = (values[n++] == WGL_FULL_ACCELERATION_ARB) && isValidFormat; // WGL_ACCELERATION_ARB
- isValidFormat = (values[n++] == GL_TRUE) && isValidFormat; // WGL_DOUBLE_BUFFER_ARB:
- isValidFormat = (values[n++] == WGL_TYPE_RGBA_ARB) && isValidFormat; // WGL_PIXEL_TYPE_ARB
- result.redBits = values[n++]; // WGL_RED_BITS_ARB
- result.greenBits = values[n++]; // WGL_GREEN_BITS_ARB
- result.blueBits = values[n++]; // WGL_BLUE_BITS_ARB
- result.alphaBits = values[n++]; // WGL_ALPHA_BITS_ARB
- result.depthBufferBits = values[n++]; // WGL_DEPTH_BITS_ARB
- result.stencilBufferBits = values[n++]; // WGL_STENCIL_BITS_ARB
- result.accumulationBufferRedBits = values[n++]; // WGL_ACCUM_RED_BITS_ARB
- result.accumulationBufferGreenBits = values[n++]; // WGL_ACCUM_GREEN_BITS_ARB
- result.accumulationBufferBlueBits = values[n++]; // WGL_ACCUM_BLUE_BITS_ARB
- result.accumulationBufferAlphaBits = values[n++]; // WGL_ACCUM_ALPHA_BITS_ARB
- result.fullSceneAntiAliasingNumSamples = values[n++]; // WGL_SAMPLES_ARB
-
- return isValidFormat;
- }
- else
- {
- jassertfalse
- }
- }
- else
- {
- PIXELFORMATDESCRIPTOR pfd;
-
- if (DescribePixelFormat (dc, pixelFormatIndex, sizeof (pfd), &pfd))
- {
- result.redBits = pfd.cRedBits;
- result.greenBits = pfd.cGreenBits;
- result.blueBits = pfd.cBlueBits;
- result.alphaBits = pfd.cAlphaBits;
- result.depthBufferBits = pfd.cDepthBits;
- result.stencilBufferBits = pfd.cStencilBits;
- result.accumulationBufferRedBits = pfd.cAccumRedBits;
- result.accumulationBufferGreenBits = pfd.cAccumGreenBits;
- result.accumulationBufferBlueBits = pfd.cAccumBlueBits;
- result.accumulationBufferAlphaBits = pfd.cAccumAlphaBits;
- result.fullSceneAntiAliasingNumSamples = 0;
-
- return true;
- }
- else
- {
- jassertfalse
- }
- }
-
- return false;
- }
-
- WindowedGLContext (const WindowedGLContext&);
- const WindowedGLContext& operator= (const WindowedGLContext&);
- };
-
- OpenGLContext* OpenGLContext::createContextForWindow (Component* const component,
- const OpenGLPixelFormat& pixelFormat,
- const OpenGLContext* const contextToShareWith)
- {
- WindowedGLContext* c = new WindowedGLContext (component,
- contextToShareWith != 0 ? (HGLRC) contextToShareWith->getRawContext() : 0,
- pixelFormat);
-
- if (c->renderContext == 0)
- deleteAndZero (c);
-
- return c;
- }
-
- void juce_glViewport (const int w, const int h)
- {
- glViewport (0, 0, w, h);
- }
-
- void OpenGLPixelFormat::getAvailablePixelFormats (Component* component,
- OwnedArray <OpenGLPixelFormat>& results)
- {
- Component tempComp;
-
- {
- WindowedGLContext wc (component, 0, OpenGLPixelFormat (8, 8, 16, 0));
- wc.makeActive();
- wc.findAlternativeOpenGLPixelFormats (results);
- }
- }
-
- #endif
-
- class JuceIStorage : public IStorage
- {
- int refCount;
-
- public:
- JuceIStorage() : refCount (1) {}
-
- virtual ~JuceIStorage()
- {
- jassert (refCount == 0);
- }
-
- HRESULT __stdcall QueryInterface (REFIID id, void __RPC_FAR* __RPC_FAR* result)
- {
- if (id == IID_IUnknown || id == IID_IStorage)
- {
- AddRef();
- *result = this;
- return S_OK;
- }
-
- *result = 0;
- return E_NOINTERFACE;
- }
-
- ULONG __stdcall AddRef() { return ++refCount; }
- ULONG __stdcall Release() { const int r = --refCount; if (r == 0) delete this; return r; }
-
- HRESULT __stdcall CreateStream (const WCHAR*, DWORD, DWORD, DWORD, IStream**) { return E_NOTIMPL; }
- HRESULT __stdcall OpenStream (const WCHAR*, void*, DWORD, DWORD, IStream**) { return E_NOTIMPL; }
- HRESULT __stdcall CreateStorage (const WCHAR*, DWORD, DWORD, DWORD, IStorage**) { return E_NOTIMPL; }
- HRESULT __stdcall OpenStorage (const WCHAR*, IStorage*, DWORD, SNB, DWORD, IStorage**) { return E_NOTIMPL; }
- HRESULT __stdcall CopyTo (DWORD, IID const*, SNB, IStorage*) { return E_NOTIMPL; }
- HRESULT __stdcall MoveElementTo (const OLECHAR*,IStorage*, const OLECHAR*, DWORD) { return E_NOTIMPL; }
- HRESULT __stdcall Commit (DWORD) { return E_NOTIMPL; }
- HRESULT __stdcall Revert() { return E_NOTIMPL; }
- HRESULT __stdcall EnumElements (DWORD, void*, DWORD, IEnumSTATSTG**) { return E_NOTIMPL; }
- HRESULT __stdcall DestroyElement (const OLECHAR*) { return E_NOTIMPL; }
- HRESULT __stdcall RenameElement (const WCHAR*, const WCHAR*) { return E_NOTIMPL; }
- HRESULT __stdcall SetElementTimes (const WCHAR*, FILETIME const*, FILETIME const*, FILETIME const*) { return E_NOTIMPL; }
- HRESULT __stdcall SetClass (REFCLSID) { return S_OK; }
- HRESULT __stdcall SetStateBits (DWORD, DWORD) { return E_NOTIMPL; }
- HRESULT __stdcall Stat (STATSTG*, DWORD) { return E_NOTIMPL; }
-
- juce_UseDebuggingNewOperator
- };
-
- class JuceOleInPlaceFrame : public IOleInPlaceFrame
- {
- int refCount;
- HWND window;
-
- public:
- JuceOleInPlaceFrame (HWND window_)
- : refCount (1),
- window (window_)
- {
- }
-
- virtual ~JuceOleInPlaceFrame()
- {
- jassert (refCount == 0);
- }
-
- HRESULT __stdcall QueryInterface (REFIID id, void __RPC_FAR* __RPC_FAR* result)
- {
- if (id == IID_IUnknown || id == IID_IOleInPlaceFrame)
- {
- AddRef();
- *result = this;
- return S_OK;
- }
-
- *result = 0;
- return E_NOINTERFACE;
- }
-
- ULONG __stdcall AddRef() { return ++refCount; }
- ULONG __stdcall Release() { const int r = --refCount; if (r == 0) delete this; return r; }
-
- HRESULT __stdcall GetWindow (HWND* lphwnd) { *lphwnd = window; return S_OK; }
- HRESULT __stdcall ContextSensitiveHelp (BOOL) { return E_NOTIMPL; }
- HRESULT __stdcall GetBorder (LPRECT) { return E_NOTIMPL; }
- HRESULT __stdcall RequestBorderSpace (LPCBORDERWIDTHS) { return E_NOTIMPL; }
- HRESULT __stdcall SetBorderSpace (LPCBORDERWIDTHS) { return E_NOTIMPL; }
- HRESULT __stdcall SetActiveObject (IOleInPlaceActiveObject*, LPCOLESTR) { return S_OK; }
- HRESULT __stdcall InsertMenus (HMENU, LPOLEMENUGROUPWIDTHS) { return E_NOTIMPL; }
- HRESULT __stdcall SetMenu (HMENU, HOLEMENU, HWND) { return S_OK; }
- HRESULT __stdcall RemoveMenus (HMENU) { return E_NOTIMPL; }
- HRESULT __stdcall SetStatusText (LPCOLESTR) { return S_OK; }
- HRESULT __stdcall EnableModeless (BOOL) { return S_OK; }
- HRESULT __stdcall TranslateAccelerator(LPMSG, WORD) { return E_NOTIMPL; }
-
- juce_UseDebuggingNewOperator
- };
-
- class JuceIOleInPlaceSite : public IOleInPlaceSite
- {
- int refCount;
- HWND window;
- JuceOleInPlaceFrame* frame;
-
- public:
- JuceIOleInPlaceSite (HWND window_)
- : refCount (1),
- window (window_)
- {
- frame = new JuceOleInPlaceFrame (window);
- }
-
- virtual ~JuceIOleInPlaceSite()
- {
- jassert (refCount == 0);
- frame->Release();
- }
-
- HRESULT __stdcall QueryInterface (REFIID id, void __RPC_FAR* __RPC_FAR* result)
- {
- if (id == IID_IUnknown || id == IID_IOleInPlaceSite)
- {
- AddRef();
- *result = this;
- return S_OK;
- }
-
- *result = 0;
- return E_NOINTERFACE;
- }
-
- ULONG __stdcall AddRef() { return ++refCount; }
- ULONG __stdcall Release() { const int r = --refCount; if (r == 0) delete this; return r; }
-
- HRESULT __stdcall GetWindow (HWND* lphwnd) { *lphwnd = window; return S_OK; }
- HRESULT __stdcall ContextSensitiveHelp (BOOL) { return E_NOTIMPL; }
- HRESULT __stdcall CanInPlaceActivate() { return S_OK; }
- HRESULT __stdcall OnInPlaceActivate() { return S_OK; }
- HRESULT __stdcall OnUIActivate() { return S_OK; }
-
- HRESULT __stdcall GetWindowContext (LPOLEINPLACEFRAME* lplpFrame, LPOLEINPLACEUIWINDOW* lplpDoc, LPRECT, LPRECT, LPOLEINPLACEFRAMEINFO lpFrameInfo)
- {
- frame->AddRef();
- *lplpFrame = frame;
- *lplpDoc = 0;
- lpFrameInfo->fMDIApp = FALSE;
- lpFrameInfo->hwndFrame = window;
- lpFrameInfo->haccel = 0;
- lpFrameInfo->cAccelEntries = 0;
- return S_OK;
- }
-
- HRESULT __stdcall Scroll (SIZE) { return E_NOTIMPL; }
- HRESULT __stdcall OnUIDeactivate (BOOL) { return S_OK; }
- HRESULT __stdcall OnInPlaceDeactivate() { return S_OK; }
- HRESULT __stdcall DiscardUndoState() { return E_NOTIMPL; }
- HRESULT __stdcall DeactivateAndUndo() { return E_NOTIMPL; }
- HRESULT __stdcall OnPosRectChange (LPCRECT) { return S_OK; }
-
- juce_UseDebuggingNewOperator
- };
-
- class JuceIOleClientSite : public IOleClientSite
- {
- int refCount;
- JuceIOleInPlaceSite* inplaceSite;
-
- public:
- JuceIOleClientSite (HWND window)
- : refCount (1)
- {
- inplaceSite = new JuceIOleInPlaceSite (window);
- }
-
- virtual ~JuceIOleClientSite()
- {
- jassert (refCount == 0);
- inplaceSite->Release();
- }
-
- HRESULT __stdcall QueryInterface (REFIID id, void __RPC_FAR* __RPC_FAR* result)
- {
- if (id == IID_IUnknown || id == IID_IOleClientSite)
- {
- AddRef();
- *result = this;
- return S_OK;
- }
- else if (id == IID_IOleInPlaceSite)
- {
- inplaceSite->AddRef();
- *result = inplaceSite;
- return S_OK;
- }
-
- *result = 0;
- return E_NOINTERFACE;
- }
-
- ULONG __stdcall AddRef() { return ++refCount; }
- ULONG __stdcall Release() { const int r = --refCount; if (r == 0) delete this; return r; }
-
- HRESULT __stdcall SaveObject() { return E_NOTIMPL; }
- HRESULT __stdcall GetMoniker (DWORD, DWORD, IMoniker**) { return E_NOTIMPL; }
- HRESULT __stdcall GetContainer (LPOLECONTAINER* ppContainer) { *ppContainer = 0; return E_NOINTERFACE; }
- HRESULT __stdcall ShowObject() { return S_OK; }
- HRESULT __stdcall OnShowWindow (BOOL) { return E_NOTIMPL; }
- HRESULT __stdcall RequestNewObjectLayout() { return E_NOTIMPL; }
-
- juce_UseDebuggingNewOperator
- };
-
- class ActiveXControlData : public ComponentMovementWatcher
- {
- ActiveXControlComponent* const owner;
- bool wasShowing;
-
- public:
- HWND controlHWND;
- IStorage* storage;
- IOleClientSite* clientSite;
- IOleObject* control;
-
- ActiveXControlData (HWND hwnd,
- ActiveXControlComponent* const owner_)
- : ComponentMovementWatcher (owner_),
- owner (owner_),
- wasShowing (owner_ != 0 && owner_->isShowing()),
- controlHWND (0),
- storage (new JuceIStorage()),
- clientSite (new JuceIOleClientSite (hwnd)),
- control (0)
- {
- }
-
- ~ActiveXControlData()
- {
- if (control != 0)
- {
- control->Close (OLECLOSE_NOSAVE);
- control->Release();
- }
-
- clientSite->Release();
- storage->Release();
- }
-
- void componentMovedOrResized (bool /*wasMoved*/, bool /*wasResized*/)
- {
- Component* const topComp = owner->getTopLevelComponent();
-
- if (topComp->getPeer() != 0)
- {
- int x = 0, y = 0;
- owner->relativePositionToOtherComponent (topComp, x, y);
-
- owner->setControlBounds (Rectangle (x, y, owner->getWidth(), owner->getHeight()));
- }
- }
-
- void componentPeerChanged()
- {
- const bool isShowingNow = owner->isShowing();
-
- if (wasShowing != isShowingNow)
- {
- wasShowing = isShowingNow;
-
- owner->setControlVisible (isShowingNow);
- }
- }
-
- void componentVisibilityChanged (Component&)
- {
- componentPeerChanged();
- }
-
- static bool doesWindowMatch (const ActiveXControlComponent* const ax, HWND hwnd)
- {
- return ((ActiveXControlData*) ax->control)->controlHWND == hwnd;
- }
- };
-
- static VoidArray activeXComps;
-
- static HWND getHWND (const ActiveXControlComponent* const component)
- {
- HWND hwnd = 0;
-
- const IID iid = IID_IOleWindow;
- IOleWindow* const window = (IOleWindow*) component->queryInterface (&iid);
-
- if (window != 0)
- {
- window->GetWindow (&hwnd);
- window->Release();
- }
-
- return hwnd;
- }
-
- static void offerActiveXMouseEventToPeer (ComponentPeer* const peer, HWND hwnd, UINT message, LPARAM lParam)
- {
- RECT activeXRect, peerRect;
- GetWindowRect (hwnd, &activeXRect);
- GetWindowRect ((HWND) peer->getNativeHandle(), &peerRect);
-
- const int mx = GET_X_LPARAM (lParam) + activeXRect.left - peerRect.left;
- const int my = GET_Y_LPARAM (lParam) + activeXRect.top - peerRect.top;
- const int64 mouseEventTime = getMouseEventTime();
-
- const int oldModifiers = currentModifiers;
- ModifierKeys::getCurrentModifiersRealtime(); // to update the mouse button flags
-
- switch (message)
- {
- case WM_MOUSEMOVE:
- if (ModifierKeys (currentModifiers).isAnyMouseButtonDown())
- peer->handleMouseDrag (mx, my, mouseEventTime);
- else
- peer->handleMouseMove (mx, my, mouseEventTime);
- break;
-
- case WM_LBUTTONDOWN:
- case WM_MBUTTONDOWN:
- case WM_RBUTTONDOWN:
- peer->handleMouseDown (mx, my, mouseEventTime);
- break;
-
- case WM_LBUTTONUP:
- case WM_MBUTTONUP:
- case WM_RBUTTONUP:
- peer->handleMouseUp (oldModifiers, mx, my, mouseEventTime);
- break;
-
- default:
- break;
- }
- }
-
- // intercepts events going to an activeX control, so we can sneakily use the mouse events
- static LRESULT CALLBACK activeXHookWndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
- {
- for (int i = activeXComps.size(); --i >= 0;)
- {
- const ActiveXControlComponent* const ax = (const ActiveXControlComponent*) activeXComps.getUnchecked(i);
-
- if (ActiveXControlData::doesWindowMatch (ax, hwnd))
- {
- switch (message)
- {
- case WM_MOUSEMOVE:
- case WM_LBUTTONDOWN:
- case WM_MBUTTONDOWN:
- case WM_RBUTTONDOWN:
- case WM_LBUTTONUP:
- case WM_MBUTTONUP:
- case WM_RBUTTONUP:
- case WM_LBUTTONDBLCLK:
- case WM_MBUTTONDBLCLK:
- case WM_RBUTTONDBLCLK:
- if (ax->isShowing())
- {
- ComponentPeer* const peer = ax->getPeer();
-
- if (peer != 0)
- {
- offerActiveXMouseEventToPeer (peer, hwnd, message, lParam);
-
- if (! ax->areMouseEventsAllowed())
- return 0;
- }
- }
- break;
-
- default:
- break;
- }
-
- return CallWindowProc ((WNDPROC) (ax->originalWndProc), hwnd, message, wParam, lParam);
- }
- }
-
- return DefWindowProc (hwnd, message, wParam, lParam);
- }
-
- ActiveXControlComponent::ActiveXControlComponent()
- : originalWndProc (0),
- control (0),
- mouseEventsAllowed (true)
- {
- activeXComps.add (this);
- }
-
- ActiveXControlComponent::~ActiveXControlComponent()
- {
- deleteControl();
- activeXComps.removeValue (this);
- }
-
- void ActiveXControlComponent::paint (Graphics& g)
- {
- if (control == 0)
- g.fillAll (Colours::lightgrey);
- }
-
- bool ActiveXControlComponent::createControl (const void* controlIID)
- {
- deleteControl();
- ComponentPeer* const peer = getPeer();
-
- // the component must have already been added to a real window when you call this!
- jassert (dynamic_cast <Win32ComponentPeer*> (peer) != 0);
-
- if (dynamic_cast <Win32ComponentPeer*> (peer) != 0)
- {
- int x = 0, y = 0;
- relativePositionToOtherComponent (getTopLevelComponent(), x, y);
-
- HWND hwnd = (HWND) peer->getNativeHandle();
-
- ActiveXControlData* const info = new ActiveXControlData (hwnd, this);
-
- HRESULT hr;
- if ((hr = OleCreate (*(const IID*) controlIID, IID_IOleObject, 1 /*OLERENDER_DRAW*/, 0,
- info->clientSite, info->storage,
- (void**) &(info->control))) == S_OK)
- {
- info->control->SetHostNames (L"Juce", 0);
-
- if (OleSetContainedObject (info->control, TRUE) == S_OK)
- {
- RECT rect;
- rect.left = x;
- rect.top = y;
- rect.right = x + getWidth();
- rect.bottom = y + getHeight();
-
- if (info->control->DoVerb (OLEIVERB_SHOW, 0, info->clientSite, 0, hwnd, &rect) == S_OK)
- {
- control = info;
- setControlBounds (Rectangle (x, y, getWidth(), getHeight()));
-
- info->controlHWND = getHWND (this);
-
- if (info->controlHWND != 0)
- {
- originalWndProc = (void*) GetWindowLongPtr ((HWND) info->controlHWND, GWLP_WNDPROC);
- SetWindowLongPtr ((HWND) info->controlHWND, GWLP_WNDPROC, (LONG_PTR) activeXHookWndProc);
- }
-
- return true;
- }
- }
- }
-
- delete info;
- }
-
- return false;
- }
-
- void ActiveXControlComponent::deleteControl()
- {
- ActiveXControlData* const info = (ActiveXControlData*) control;
-
- if (info != 0)
- {
- delete info;
- control = 0;
- originalWndProc = 0;
- }
- }
-
- void* ActiveXControlComponent::queryInterface (const void* iid) const
- {
- ActiveXControlData* const info = (ActiveXControlData*) control;
-
- void* result = 0;
-
- if (info != 0 && info->control != 0
- && info->control->QueryInterface (*(const IID*) iid, &result) == S_OK)
- return result;
-
- return 0;
- }
-
- void ActiveXControlComponent::setControlBounds (const Rectangle& newBounds) const
- {
- HWND hwnd = ((ActiveXControlData*) control)->controlHWND;
-
- if (hwnd != 0)
- MoveWindow (hwnd, newBounds.getX(), newBounds.getY(), newBounds.getWidth(), newBounds.getHeight(), TRUE);
- }
-
- void ActiveXControlComponent::setControlVisible (const bool shouldBeVisible) const
- {
- HWND hwnd = ((ActiveXControlData*) control)->controlHWND;
-
- if (hwnd != 0)
- ShowWindow (hwnd, shouldBeVisible ? SW_SHOWNA : SW_HIDE);
- }
-
- void ActiveXControlComponent::setMouseEventsAllowed (const bool eventsCanReachControl)
- {
- mouseEventsAllowed = eventsCanReachControl;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_win32_Windowing.cpp *********/
-
- #endif
-
- /********* Start of inlined file: juce_win32_AutoLinkLibraries.h *********/
- // Auto-links to various win32 libs that are needed by library calls..
- #pragma comment(lib, "kernel32.lib")
- #pragma comment(lib, "user32.lib")
- #pragma comment(lib, "shell32.lib")
- #pragma comment(lib, "gdi32.lib")
- #pragma comment(lib, "vfw32.lib")
- #pragma comment(lib, "comdlg32.lib")
- #pragma comment(lib, "winmm.lib")
- #pragma comment(lib, "wininet.lib")
- #pragma comment(lib, "ole32.lib")
- #pragma comment(lib, "advapi32.lib")
- #pragma comment(lib, "ws2_32.lib")
- #pragma comment(lib, "comsupp.lib")
-
- #if JUCE_OPENGL
- #pragma comment(lib, "OpenGL32.Lib")
- #pragma comment(lib, "GlU32.Lib")
- #endif
-
- #if JUCE_QUICKTIME
- #pragma comment (lib, "QTMLClient.lib")
- #endif
- /********* End of inlined file: juce_win32_AutoLinkLibraries.h *********/
-
- #endif
-
- //==============================================================================
- #if JUCE_LINUX
-
- /********* Start of inlined file: juce_linux_Files.cpp *********/
-
- /********* Start of inlined file: linuxincludes.h *********/
- #ifndef __LINUXINCLUDES_JUCEHEADER__
- #define __LINUXINCLUDES_JUCEHEADER__
-
- // Linux Header Files:
- #include <unistd.h>
- #include <stdlib.h>
- #include <sched.h>
- #include <pthread.h>
- #include <sys/time.h>
- #include <errno.h>
-
- /* Remove this macro if you're having problems compiling the cpu affinity
- calls (the API for these has changed about quite a bit in various Linux
- versions, and a lot of distros seem to ship with obsolete versions)
- */
- #ifndef SUPPORT_AFFINITIES
- #define SUPPORT_AFFINITIES 1
- #endif
-
- #endif // __LINUXINCLUDES_JUCEHEADER__
- /********* End of inlined file: linuxincludes.h *********/
-
- #include <sys/stat.h>
- #include <sys/dir.h>
- #include <sys/ptrace.h>
- #include <sys/vfs.h> // for statfs
- #include <sys/wait.h>
- #include <unistd.h>
- #include <fnmatch.h>
- #include <utime.h>
- #include <pwd.h>
- #include <fcntl.h>
-
- #define U_ISOFS_SUPER_MAGIC (short) 0x9660 // linux/iso_fs.h
- #define U_MSDOS_SUPER_MAGIC (short) 0x4d44 // linux/msdos_fs.h
- #define U_NFS_SUPER_MAGIC (short) 0x6969 // linux/nfs_fs.h
- #define U_SMB_SUPER_MAGIC (short) 0x517B // linux/smb_fs.h
-
- BEGIN_JUCE_NAMESPACE
-
- /*
- Note that a lot of methods that you'd expect to find in this file actually
- live in juce_posix_SharedCode.cpp!
- */
-
- /********* Start of inlined file: juce_posix_SharedCode.cpp *********/
- /*
- This file contains posix routines that are common to both the Linux and Mac builds.
-
- It gets included directly in the cpp files for these platforms.
- */
-
- CriticalSection::CriticalSection() throw()
- {
- pthread_mutexattr_t atts;
- pthread_mutexattr_init (&atts);
- pthread_mutexattr_settype (&atts, PTHREAD_MUTEX_RECURSIVE);
- pthread_mutex_init (&internal, &atts);
- }
-
- CriticalSection::~CriticalSection() throw()
- {
- pthread_mutex_destroy (&internal);
- }
-
- void CriticalSection::enter() const throw()
- {
- pthread_mutex_lock (&internal);
- }
-
- bool CriticalSection::tryEnter() const throw()
- {
- return pthread_mutex_trylock (&internal) == 0;
- }
-
- void CriticalSection::exit() const throw()
- {
- pthread_mutex_unlock (&internal);
- }
-
- struct EventStruct
- {
- pthread_cond_t condition;
- pthread_mutex_t mutex;
- bool triggered;
- };
-
- WaitableEvent::WaitableEvent() throw()
- {
- EventStruct* const es = new EventStruct();
- es->triggered = false;
-
- pthread_cond_init (&es->condition, 0);
- pthread_mutex_init (&es->mutex, 0);
-
- internal = es;
- }
-
- WaitableEvent::~WaitableEvent() throw()
- {
- EventStruct* const es = (EventStruct*) internal;
-
- pthread_cond_destroy (&es->condition);
- pthread_mutex_destroy (&es->mutex);
-
- delete es;
- }
-
- bool WaitableEvent::wait (const int timeOutMillisecs) const throw()
- {
- EventStruct* const es = (EventStruct*) internal;
-
- bool ok = true;
- pthread_mutex_lock (&es->mutex);
-
- if (timeOutMillisecs < 0)
- {
- while (! es->triggered)
- pthread_cond_wait (&es->condition, &es->mutex);
- }
- else
- {
- while (! es->triggered)
- {
- struct timeval t;
- gettimeofday (&t, 0);
-
- struct timespec time;
- time.tv_sec = t.tv_sec + (timeOutMillisecs / 1000);
- time.tv_nsec = (t.tv_usec + ((timeOutMillisecs % 1000) * 1000)) * 1000;
-
- if (time.tv_nsec >= 1000000000)
- {
- time.tv_nsec -= 1000000000;
- time.tv_sec++;
- }
-
- if (pthread_cond_timedwait (&es->condition, &es->mutex, &time) == ETIMEDOUT)
- {
- ok = false;
- break;
- }
- }
- }
-
- es->triggered = false;
-
- pthread_mutex_unlock (&es->mutex);
- return ok;
- }
-
- void WaitableEvent::signal() const throw()
- {
- EventStruct* const es = (EventStruct*) internal;
-
- pthread_mutex_lock (&es->mutex);
- es->triggered = true;
- pthread_cond_broadcast (&es->condition);
- pthread_mutex_unlock (&es->mutex);
- }
-
- void WaitableEvent::reset() const throw()
- {
- EventStruct* const es = (EventStruct*) internal;
-
- pthread_mutex_lock (&es->mutex);
- es->triggered = false;
- pthread_mutex_unlock (&es->mutex);
- }
-
- void JUCE_CALLTYPE Thread::sleep (int millisecs) throw()
- {
- struct timespec time;
- time.tv_sec = millisecs / 1000;
- time.tv_nsec = (millisecs % 1000) * 1000000;
- nanosleep (&time, 0);
- }
-
- const tchar File::separator = T('/');
- const tchar* File::separatorString = T("/");
-
- bool juce_copyFile (const String& s, const String& d) throw();
-
- static bool juce_stat (const String& fileName, struct stat& info) throw()
- {
- return fileName.isNotEmpty()
- && (stat (fileName.toUTF8(), &info) == 0);
- }
-
- bool juce_isDirectory (const String& fileName) throw()
- {
- struct stat info;
-
- return fileName.isEmpty()
- || (juce_stat (fileName, info)
- && ((info.st_mode & S_IFDIR) != 0));
- }
-
- bool juce_fileExists (const String& fileName, const bool dontCountDirectories) throw()
- {
- if (fileName.isEmpty())
- return false;
-
- const char* const fileNameUTF8 = fileName.toUTF8();
- bool exists = access (fileNameUTF8, F_OK) == 0;
-
- if (exists && dontCountDirectories)
- {
- struct stat info;
- const int res = stat (fileNameUTF8, &info);
-
- if (res == 0 && (info.st_mode & S_IFDIR) != 0)
- exists = false;
- }
-
- return exists;
- }
-
- int64 juce_getFileSize (const String& fileName) throw()
- {
- struct stat info;
- return juce_stat (fileName, info) ? info.st_size : 0;
- }
-
- bool juce_canWriteToFile (const String& fileName) throw()
- {
- return access (fileName.toUTF8(), W_OK) == 0;
- }
-
- bool juce_deleteFile (const String& fileName) throw()
- {
- const char* const fileNameUTF8 = fileName.toUTF8();
-
- if (juce_isDirectory (fileName))
- return rmdir (fileNameUTF8) == 0;
- else
- return remove (fileNameUTF8) == 0;
- }
-
- bool juce_moveFile (const String& source, const String& dest) throw()
- {
- if (rename (source.toUTF8(), dest.toUTF8()) == 0)
- return true;
-
- if (juce_canWriteToFile (source)
- && juce_copyFile (source, dest))
- {
- if (juce_deleteFile (source))
- return true;
-
- juce_deleteFile (dest);
- }
-
- return false;
- }
-
- void juce_createDirectory (const String& fileName) throw()
- {
- mkdir (fileName.toUTF8(), 0777);
- }
-
- void* juce_fileOpen (const String& fileName, bool forWriting) throw()
- {
- const char* const fileNameUTF8 = fileName.toUTF8();
- int flags = O_RDONLY;
-
- if (forWriting)
- {
- if (juce_fileExists (fileName, false))
- {
- const int f = open (fileNameUTF8, O_RDWR, 00644);
-
- if (f != -1)
- lseek (f, 0, SEEK_END);
-
- return (void*) f;
- }
- else
- {
- flags = O_RDWR + O_CREAT;
- }
- }
-
- return (void*) open (fileNameUTF8, flags, 00644);
- }
-
- void juce_fileClose (void* handle) throw()
- {
- if (handle != 0)
- close ((int) (pointer_sized_int) handle);
- }
-
- int juce_fileRead (void* handle, void* buffer, int size) throw()
- {
- if (handle != 0)
- return read ((int) (pointer_sized_int) handle, buffer, size);
-
- return 0;
- }
-
- int juce_fileWrite (void* handle, const void* buffer, int size) throw()
- {
- if (handle != 0)
- return write ((int) (pointer_sized_int) handle, buffer, size);
-
- return 0;
- }
-
- int64 juce_fileSetPosition (void* handle, int64 pos) throw()
- {
- if (handle != 0 && lseek ((int) (pointer_sized_int) handle, pos, SEEK_SET) == pos)
- return pos;
-
- return -1;
- }
-
- int64 juce_fileGetPosition (void* handle) throw()
- {
- if (handle != 0)
- return lseek ((int) (pointer_sized_int) handle, 0, SEEK_CUR);
- else
- return -1;
- }
-
- void juce_fileFlush (void* handle) throw()
- {
- if (handle != 0)
- fsync ((int) (pointer_sized_int) handle);
- }
-
- // if this file doesn't exist, find a parent of it that does..
- static bool doStatFS (const File* file, struct statfs& result) throw()
- {
- File f (*file);
-
- for (int i = 5; --i >= 0;)
- {
- if (f.exists())
- break;
-
- f = f.getParentDirectory();
- }
-
- return statfs (f.getFullPathName().toUTF8(), &result) == 0;
- }
-
- int64 File::getBytesFreeOnVolume() const throw()
- {
- int64 free_space = 0;
-
- struct statfs buf;
- if (doStatFS (this, buf))
- // Note: this returns space available to non-super user
- free_space = (int64) buf.f_bsize * (int64) buf.f_bavail;
-
- return free_space;
- }
-
- const String juce_getVolumeLabel (const String& filenameOnVolume,
- int& volumeSerialNumber) throw()
- {
- // There is no equivalent on Linux
- volumeSerialNumber = 0;
- return String::empty;
- }
-
- #if JUCE_64BIT
- #define filedesc ((long long) internal)
- #else
- #define filedesc ((int) internal)
- #endif
-
- InterProcessLock::InterProcessLock (const String& name_) throw()
- : internal (0),
- name (name_),
- reentrancyLevel (0)
- {
- #if JUCE_MAC
- // (don't use getSpecialLocation() to avoid the temp folder being different for each app)
- const File temp (File (T("~/Library/Caches/Juce")).getChildFile (name));
- #else
- const File temp (File::getSpecialLocation (File::tempDirectory).getChildFile (name));
- #endif
-
- temp.create();
-
- internal = (void*) open (temp.getFullPathName().toUTF8(), O_RDWR);
- }
-
- InterProcessLock::~InterProcessLock() throw()
- {
- while (reentrancyLevel > 0)
- this->exit();
-
- close (filedesc);
- }
-
- bool InterProcessLock::enter (const int timeOutMillisecs) throw()
- {
- if (internal == 0)
- return false;
-
- if (reentrancyLevel != 0)
- return true;
-
- const int64 endTime = Time::currentTimeMillis() + timeOutMillisecs;
-
- struct flock fl;
- zerostruct (fl);
- fl.l_whence = SEEK_SET;
- fl.l_type = F_WRLCK;
-
- for (;;)
- {
- const int result = fcntl (filedesc, F_SETLK, &fl);
-
- if (result >= 0)
- {
- ++reentrancyLevel;
- return true;
- }
-
- if (errno != EINTR)
- {
- if (timeOutMillisecs == 0
- || (timeOutMillisecs > 0 && Time::currentTimeMillis() >= endTime))
- break;
-
- Thread::sleep (10);
- }
- }
-
- return false;
- }
-
- void InterProcessLock::exit() throw()
- {
- if (reentrancyLevel > 0 && internal != 0)
- {
- --reentrancyLevel;
-
- struct flock fl;
- zerostruct (fl);
- fl.l_whence = SEEK_SET;
- fl.l_type = F_UNLCK;
-
- for (;;)
- {
- const int result = fcntl (filedesc, F_SETLKW, &fl);
-
- if (result >= 0 || errno != EINTR)
- break;
- }
- }
- }
- /********* End of inlined file: juce_posix_SharedCode.cpp *********/
-
- static File executableFile;
-
- void juce_getFileTimes (const String& fileName,
- int64& modificationTime,
- int64& accessTime,
- int64& creationTime) throw()
- {
- modificationTime = 0;
- accessTime = 0;
- creationTime = 0;
-
- struct stat info;
- const int res = stat (fileName.toUTF8(), &info);
- if (res == 0)
- {
- modificationTime = (int64) info.st_mtime * 1000;
- accessTime = (int64) info.st_atime * 1000;
- creationTime = (int64) info.st_ctime * 1000;
- }
- }
-
- bool juce_setFileTimes (const String& fileName,
- int64 modificationTime,
- int64 accessTime,
- int64 creationTime) throw()
- {
- struct utimbuf times;
- times.actime = (time_t) (accessTime / 1000);
- times.modtime = (time_t) (modificationTime / 1000);
-
- return utime (fileName.toUTF8(), ×) == 0;
- }
-
- bool juce_setFileReadOnly (const String& fileName, bool isReadOnly) throw()
- {
- struct stat info;
- const int res = stat (fileName.toUTF8(), &info);
- if (res != 0)
- return false;
-
- info.st_mode &= 0777; // Just permissions
-
- if( isReadOnly )
- info.st_mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH);
- else
- // Give everybody write permission?
- info.st_mode |= S_IWUSR | S_IWGRP | S_IWOTH;
-
- return chmod (fileName.toUTF8(), info.st_mode) == 0;
- }
-
- bool juce_copyFile (const String& s, const String& d) throw()
- {
- const File source (s), dest (d);
-
- FileInputStream* in = source.createInputStream();
- bool ok = false;
-
- if (in != 0)
- {
- if (dest.deleteFile())
- {
- FileOutputStream* const out = dest.createOutputStream();
-
- if (out != 0)
- {
- const int bytesCopied = out->writeFromInputStream (*in, -1);
- delete out;
-
- ok = (bytesCopied == source.getSize());
-
- if (! ok)
- dest.deleteFile();
- }
- }
-
- delete in;
- }
-
- return ok;
- }
-
- const StringArray juce_getFileSystemRoots() throw()
- {
- StringArray s;
- s.add (T("/"));
- return s;
- }
-
- bool File::isOnCDRomDrive() const throw()
- {
- struct statfs buf;
-
- if (statfs (getFullPathName().toUTF8(), &buf) == 0)
- return (buf.f_type == U_ISOFS_SUPER_MAGIC);
-
- // Assume not if this fails for some reason
- return false;
- }
-
- bool File::isOnHardDisk() const throw()
- {
- struct statfs buf;
-
- if (statfs (getFullPathName().toUTF8(), &buf) == 0)
- {
- switch (buf.f_type)
- {
- case U_ISOFS_SUPER_MAGIC: // CD-ROM
- case U_MSDOS_SUPER_MAGIC: // Probably floppy (but could be mounted FAT filesystem)
- case U_NFS_SUPER_MAGIC: // Network NFS
- case U_SMB_SUPER_MAGIC: // Network Samba
- return false;
-
- default:
- // Assume anything else is a hard-disk (but note it could
- // be a RAM disk. There isn't a good way of determining
- // this for sure)
- return true;
- }
- }
-
- // Assume so if this fails for some reason
- return true;
- }
-
- bool File::isHidden() const throw()
- {
- return getFileName().startsWithChar (T('.'));
- }
-
- const File File::getSpecialLocation (const SpecialLocationType type)
- {
- switch (type)
- {
- case userHomeDirectory:
- {
- const char* homeDir = getenv ("HOME");
-
- if (homeDir == 0)
- {
- struct passwd* const pw = getpwuid (getuid());
- if (pw != 0)
- homeDir = pw->pw_dir;
- }
-
- return File (String::fromUTF8 ((const uint8*) homeDir));
- }
-
- case userDocumentsDirectory:
- case userMusicDirectory:
- case userMoviesDirectory:
- case userApplicationDataDirectory:
- return File ("~");
-
- case userDesktopDirectory:
- return File ("~/Desktop");
-
- case commonApplicationDataDirectory:
- return File ("/var");
-
- case globalApplicationsDirectory:
- return File ("/usr");
-
- case tempDirectory:
- {
- File tmp ("/var/tmp");
-
- if (! tmp.isDirectory())
- {
- tmp = T("/tmp");
-
- if (! tmp.isDirectory())
- tmp = File::getCurrentWorkingDirectory();
- }
-
- return tmp;
- }
-
- case currentExecutableFile:
- case currentApplicationFile:
- // if this fails, it's probably because juce_setCurrentExecutableFileName()
- // was never called to set the filename - this should be done by the juce
- // main() function, so maybe you've hacked it to use your own custom main()?
- jassert (executableFile.exists());
-
- return executableFile;
-
- default:
- jassertfalse // unknown type?
- break;
- }
-
- return File::nonexistent;
- }
-
- void juce_setCurrentExecutableFileName (const String& filename) throw()
- {
- executableFile = File::getCurrentWorkingDirectory().getChildFile (filename);
- }
-
- const File File::getCurrentWorkingDirectory() throw()
- {
- char buf [2048];
- getcwd (buf, sizeof(buf));
- return File (String::fromUTF8 ((const uint8*) buf));
- }
-
- bool File::setAsCurrentWorkingDirectory() const throw()
- {
- return chdir (getFullPathName().toUTF8()) == 0;
- }
-
- struct FindFileStruct
- {
- String parentDir, wildCard;
- DIR* dir;
-
- bool getNextMatch (String& result, bool* const isDir, bool* const isHidden, int64* const fileSize,
- Time* const modTime, Time* const creationTime, bool* const isReadOnly) throw()
- {
- const char* const wildcardUTF8 = wildCard.toUTF8();
-
- for (;;)
- {
- struct dirent* const de = readdir (dir);
-
- if (de == 0)
- break;
-
- if (fnmatch (wildcardUTF8, de->d_name, FNM_CASEFOLD) == 0)
- {
- result = String::fromUTF8 ((const uint8*) de->d_name);
-
- const String path (parentDir + result);
-
- if (isDir != 0 || fileSize != 0)
- {
- struct stat info;
- const bool statOk = (stat (path.toUTF8(), &info) == 0);
-
- if (isDir != 0)
- *isDir = path.isEmpty() || (statOk && ((info.st_mode & S_IFDIR) != 0));
-
- if (isHidden != 0)
- *isHidden = (de->d_name[0] == '.');
-
- if (fileSize != 0)
- *fileSize = statOk ? info.st_size : 0;
- }
-
- if (modTime != 0 || creationTime != 0)
- {
- int64 m, a, c;
- juce_getFileTimes (path, m, a, c);
-
- if (modTime != 0)
- *modTime = m;
-
- if (creationTime != 0)
- *creationTime = c;
- }
-
- if (isReadOnly != 0)
- *isReadOnly = ! juce_canWriteToFile (path);
-
- return true;
- }
- }
-
- return false;
- }
- };
-
- // returns 0 on failure
- void* juce_findFileStart (const String& directory, const String& wildCard, String& firstResultFile,
- bool* isDir, bool* isHidden, int64* fileSize, Time* modTime,
- Time* creationTime, bool* isReadOnly) throw()
- {
- DIR* d = opendir (directory.toUTF8());
-
- if (d != 0)
- {
- FindFileStruct* ff = new FindFileStruct();
- ff->parentDir = directory;
-
- if (!ff->parentDir.endsWithChar (File::separator))
- ff->parentDir += File::separator;
-
- ff->wildCard = wildCard;
- if (wildCard == T("*.*"))
- ff->wildCard = T("*");
-
- ff->dir = d;
-
- if (ff->getNextMatch (firstResultFile, isDir, isHidden, fileSize, modTime, creationTime, isReadOnly))
- {
- return ff;
- }
- else
- {
- firstResultFile = String::empty;
- isDir = false;
- isHidden = false;
- closedir (d);
- delete ff;
- }
- }
-
- return 0;
- }
-
- bool juce_findFileNext (void* handle, String& resultFile,
- bool* isDir, bool* isHidden, int64* fileSize, Time* modTime, Time* creationTime, bool* isReadOnly) throw()
- {
- FindFileStruct* const ff = (FindFileStruct*) handle;
-
- if (ff != 0)
- return ff->getNextMatch (resultFile, isDir, isHidden, fileSize, modTime, creationTime, isReadOnly);
-
- return false;
- }
-
- void juce_findFileClose (void* handle) throw()
- {
- FindFileStruct* const ff = (FindFileStruct*) handle;
-
- if (ff != 0)
- {
- closedir (ff->dir);
- delete ff;
- }
- }
-
- bool juce_launchFile (const String& fileName,
- const String& parameters) throw()
- {
- String cmdString (fileName);
- cmdString << " " << parameters;
-
- if (URL::isProbablyAWebsiteURL (cmdString) || URL::isProbablyAnEmailAddress (cmdString))
- {
- // create a command that tries to launch a bunch of likely browsers
- const char* const browserNames[] = { "/etc/alternatives/x-www-browser", "firefox", "mozilla", "konqueror", "opera" };
-
- StringArray cmdLines;
-
- for (int i = 0; i < numElementsInArray (browserNames); ++i)
- cmdLines.add (String (browserNames[i]) + T(" ") + cmdString.trim().quoted());
-
- cmdString = cmdLines.joinIntoString (T(" || "));
- }
-
- char* const argv[4] = { "/bin/sh", "-c", (char*) cmdString.toUTF8(), 0 };
-
- const int cpid = fork();
-
- if (cpid == 0)
- {
- setsid();
-
- // Child process
- execve (argv[0], argv, environ);
- exit (0);
- }
-
- return cpid >= 0;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_linux_Files.cpp *********/
-
- /********* Start of inlined file: juce_linux_NamedPipe.cpp *********/
-
- /********* Start of inlined file: juce_mac_NamedPipe.cpp *********/
-
- #include <sys/stat.h>
- #include <sys/dir.h>
- #include <fcntl.h>
-
- // As well as being for the mac, this file is included by the linux build.
-
- #if ! JUCE_MAC
- #include <sys/wait.h>
- #include <errno.h>
- #include <unistd.h>
- #endif
-
- BEGIN_JUCE_NAMESPACE
-
- struct NamedPipeInternal
- {
- String pipeInName, pipeOutName;
- int pipeIn, pipeOut;
-
- bool volatile createdPipe, blocked, stopReadOperation;
-
- static void signalHandler (int) {}
- };
-
- void NamedPipe::cancelPendingReads()
- {
- while (internal != 0 && ((NamedPipeInternal*) internal)->blocked)
- {
- NamedPipeInternal* const intern = (NamedPipeInternal*) internal;
-
- intern->stopReadOperation = true;
-
- char buffer [1] = { 0 };
- ::write (intern->pipeIn, buffer, 1);
-
- int timeout = 2000;
- while (intern->blocked && --timeout >= 0)
- Thread::sleep (2);
-
- intern->stopReadOperation = false;
- }
- }
-
- void NamedPipe::close()
- {
- NamedPipeInternal* const intern = (NamedPipeInternal*) internal;
-
- if (intern != 0)
- {
- internal = 0;
-
- if (intern->pipeIn != -1)
- ::close (intern->pipeIn);
-
- if (intern->pipeOut != -1)
- ::close (intern->pipeOut);
-
- if (intern->createdPipe)
- {
- unlink (intern->pipeInName);
- unlink (intern->pipeOutName);
- }
-
- delete intern;
- }
- }
-
- bool NamedPipe::openInternal (const String& pipeName, const bool createPipe)
- {
- close();
-
- NamedPipeInternal* const intern = new NamedPipeInternal();
- internal = intern;
- intern->createdPipe = createPipe;
- intern->blocked = false;
- intern->stopReadOperation = false;
-
- signal (SIGPIPE, NamedPipeInternal::signalHandler);
- siginterrupt (SIGPIPE, 1);
-
- const String pipePath (T("/tmp/") + File::createLegalFileName (pipeName));
-
- intern->pipeInName = pipePath + T("_in");
- intern->pipeOutName = pipePath + T("_out");
- intern->pipeIn = -1;
- intern->pipeOut = -1;
-
- if (createPipe)
- {
- if ((mkfifo (intern->pipeInName, 0666) && errno != EEXIST)
- || (mkfifo (intern->pipeOutName, 0666) && errno != EEXIST))
- {
- delete intern;
- internal = 0;
-
- return false;
- }
- }
-
- return true;
- }
-
- int NamedPipe::read (void* destBuffer, int maxBytesToRead, int /*timeOutMilliseconds*/)
- {
- int bytesRead = -1;
- NamedPipeInternal* const intern = (NamedPipeInternal*) internal;
-
- if (intern != 0)
- {
- intern->blocked = true;
-
- if (intern->pipeIn == -1)
- {
- if (intern->createdPipe)
- intern->pipeIn = ::open (intern->pipeInName, O_RDWR);
- else
- intern->pipeIn = ::open (intern->pipeOutName, O_RDWR);
-
- if (intern->pipeIn == -1)
- {
- intern->blocked = false;
- return -1;
- }
- }
-
- bytesRead = 0;
-
- char* p = (char*) destBuffer;
-
- while (bytesRead < maxBytesToRead)
- {
- const int bytesThisTime = maxBytesToRead - bytesRead;
- const int numRead = ::read (intern->pipeIn, p, bytesThisTime);
-
- if (numRead <= 0 || intern->stopReadOperation)
- {
- bytesRead = -1;
- break;
- }
-
- bytesRead += numRead;
- p += bytesRead;
- }
-
- intern->blocked = false;
- }
-
- return bytesRead;
- }
-
- int NamedPipe::write (const void* sourceBuffer, int numBytesToWrite, int timeOutMilliseconds)
- {
- int bytesWritten = -1;
- NamedPipeInternal* const intern = (NamedPipeInternal*) internal;
-
- if (intern != 0)
- {
- if (intern->pipeOut == -1)
- {
- if (intern->createdPipe)
- intern->pipeOut = ::open (intern->pipeOutName, O_WRONLY);
- else
- intern->pipeOut = ::open (intern->pipeInName, O_WRONLY);
-
- if (intern->pipeOut == -1)
- {
- return -1;
- }
- }
-
- const char* p = (const char*) sourceBuffer;
- bytesWritten = 0;
-
- const uint32 timeOutTime = Time::getMillisecondCounter() + timeOutMilliseconds;
-
- while (bytesWritten < numBytesToWrite
- && (timeOutMilliseconds < 0 || Time::getMillisecondCounter() < timeOutTime))
- {
- const int bytesThisTime = numBytesToWrite - bytesWritten;
- const int numWritten = ::write (intern->pipeOut, p, bytesThisTime);
-
- if (numWritten <= 0)
- {
- bytesWritten = -1;
- break;
- }
-
- bytesWritten += numWritten;
- p += bytesWritten;
- }
- }
-
- return bytesWritten;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_mac_NamedPipe.cpp *********/
-
- /********* End of inlined file: juce_linux_NamedPipe.cpp *********/
-
- /********* Start of inlined file: juce_linux_Network.cpp *********/
-
- #include <netdb.h>
- #include <arpa/inet.h>
- #include <netinet/in.h>
- #include <sys/types.h>
- #include <sys/ioctl.h>
- #include <sys/socket.h>
- #include <sys/wait.h>
- #include <linux/if.h>
-
- BEGIN_JUCE_NAMESPACE
-
- // we'll borrow the mac's socket-based http streaming code..
-
- /********* Start of inlined file: juce_mac_HTTPStream.h *********/
- // (This file gets included by the mac + linux networking code)
-
- /** A HTTP input stream that uses sockets.
- */
- class JUCE_HTTPSocketStream
- {
- public:
-
- JUCE_HTTPSocketStream()
- : readPosition (0),
- socketHandle (-1),
- levelsOfRedirection (0),
- timeoutSeconds (15)
- {
- }
-
- ~JUCE_HTTPSocketStream()
- {
- closeSocket();
- }
-
- bool open (const String& url,
- const String& headers,
- const MemoryBlock& postData,
- const bool isPost,
- URL::OpenStreamProgressCallback* callback,
- void* callbackContext,
- int timeOutMs)
- {
- closeSocket();
-
- uint32 timeOutTime = Time::getMillisecondCounter();
-
- if (timeOutMs == 0)
- timeOutTime += 60000;
- else if (timeOutMs < 0)
- timeOutTime = 0xffffffff;
- else
- timeOutTime += timeOutMs;
-
- String hostName, hostPath;
- int hostPort;
-
- if (! decomposeURL (url, hostName, hostPath, hostPort))
- return false;
-
- const struct hostent* host = 0;
- int port = 0;
-
- String proxyName, proxyPath;
- int proxyPort = 0;
-
- String proxyURL (getenv ("http_proxy"));
- if (proxyURL.startsWithIgnoreCase (T("http://")))
- {
- if (! decomposeURL (proxyURL, proxyName, proxyPath, proxyPort))
- return false;
-
- host = gethostbyname ((const char*) proxyName.toUTF8());
- port = proxyPort;
- }
- else
- {
- host = gethostbyname ((const char*) hostName.toUTF8());
- port = hostPort;
- }
-
- if (host == 0)
- return false;
-
- struct sockaddr_in address;
- zerostruct (address);
- memcpy ((void*) &address.sin_addr, (const void*) host->h_addr, host->h_length);
- address.sin_family = host->h_addrtype;
- address.sin_port = htons (port);
-
- socketHandle = socket (host->h_addrtype, SOCK_STREAM, 0);
-
- if (socketHandle == -1)
- return false;
-
- int receiveBufferSize = 16384;
- setsockopt (socketHandle, SOL_SOCKET, SO_RCVBUF, (char*) &receiveBufferSize, sizeof (receiveBufferSize));
- setsockopt (socketHandle, SOL_SOCKET, SO_KEEPALIVE, 0, 0);
-
- #if JUCE_MAC
- setsockopt (socketHandle, SOL_SOCKET, SO_NOSIGPIPE, 0, 0);
- #endif
-
- if (connect (socketHandle, (struct sockaddr*) &address, sizeof (address)) == -1)
- {
- closeSocket();
- return false;
- }
-
- const MemoryBlock requestHeader (createRequestHeader (hostName, hostPort,
- proxyName, proxyPort,
- hostPath, url,
- headers, postData,
- isPost));
- int totalHeaderSent = 0;
-
- while (totalHeaderSent < requestHeader.getSize())
- {
- if (Time::getMillisecondCounter() > timeOutTime)
- {
- closeSocket();
- return false;
- }
-
- const int numToSend = jmin (1024, requestHeader.getSize() - totalHeaderSent);
-
- if (send (socketHandle,
- ((const char*) requestHeader.getData()) + totalHeaderSent,
- numToSend, 0)
- != numToSend)
- {
- closeSocket();
- return false;
- }
-
- totalHeaderSent += numToSend;
-
- if (callback != 0 && ! callback (callbackContext, totalHeaderSent, requestHeader.getSize()))
- {
- closeSocket();
- return false;
- }
- }
-
- const String responseHeader (readResponse (timeOutTime));
-
- if (responseHeader.isNotEmpty())
- {
- //DBG (responseHeader);
-
- StringArray lines;
- lines.addLines (responseHeader);
-
- // NB - using charToString() here instead of just T(" "), because that was
- // causing a mysterious gcc internal compiler error...
- const int statusCode = responseHeader.fromFirstOccurrenceOf (String::charToString (T(' ')), false, false)
- .substring (0, 3)
- .getIntValue();
-
- //int contentLength = findHeaderItem (lines, T("Content-Length:")).getIntValue();
- //bool isChunked = findHeaderItem (lines, T("Transfer-Encoding:")).equalsIgnoreCase ("chunked");
-
- String location (findHeaderItem (lines, T("Location:")));
-
- if (statusCode >= 300 && statusCode < 400
- && location.isNotEmpty())
- {
- if (! location.startsWithIgnoreCase (T("http://")))
- location = T("http://") + location;
-
- if (levelsOfRedirection++ < 3)
- return open (location, headers, postData, isPost, callback, callbackContext, timeOutMs);
- }
- else
- {
- levelsOfRedirection = 0;
- return true;
- }
- }
-
- closeSocket();
- return false;
- }
-
- int read (void* buffer, int bytesToRead)
- {
- fd_set readbits;
- FD_ZERO (&readbits);
- FD_SET (socketHandle, &readbits);
-
- struct timeval tv;
- tv.tv_sec = timeoutSeconds;
- tv.tv_usec = 0;
-
- if (select (socketHandle + 1, &readbits, 0, 0, &tv) <= 0)
- return 0; // (timeout)
-
- const int bytesRead = jmax (0, recv (socketHandle, buffer, bytesToRead, MSG_WAITALL));
- readPosition += bytesRead;
- return bytesRead;
- }
-
- int readPosition;
-
- juce_UseDebuggingNewOperator
-
- private:
- int socketHandle, levelsOfRedirection;
- const int timeoutSeconds;
-
- void closeSocket()
- {
- if (socketHandle >= 0)
- close (socketHandle);
-
- socketHandle = -1;
- }
-
- const MemoryBlock createRequestHeader (const String& hostName,
- const int hostPort,
- const String& proxyName,
- const int proxyPort,
- const String& hostPath,
- const String& originalURL,
- const String& headers,
- const MemoryBlock& postData,
- const bool isPost)
- {
- String header (isPost ? "POST " : "GET ");
-
- if (proxyName.isEmpty())
- {
- header << hostPath << " HTTP/1.0\r\nHost: "
- << hostName << ':' << hostPort;
- }
- else
- {
- header << originalURL << " HTTP/1.0\r\nHost: "
- << proxyName << ':' << proxyPort;
- }
-
- header << "\r\nUser-Agent: JUCE/"
- << JUCE_MAJOR_VERSION << '.' << JUCE_MINOR_VERSION
- << "\r\nConnection: Close\r\nContent-Length: "
- << postData.getSize() << "\r\n"
- << headers << "\r\n";
-
- MemoryBlock mb;
- mb.append (header.toUTF8(), (int) strlen (header.toUTF8()));
- mb.append (postData.getData(), postData.getSize());
-
- return mb;
- }
-
- const String readResponse (const uint32 timeOutTime)
- {
- int bytesRead = 0, numConsecutiveLFs = 0;
- MemoryBlock buffer (1024, true);
-
- while (numConsecutiveLFs < 2 && bytesRead < 32768
- && Time::getMillisecondCounter() <= timeOutTime)
- {
- fd_set readbits;
- FD_ZERO (&readbits);
- FD_SET (socketHandle, &readbits);
-
- struct timeval tv;
- tv.tv_sec = timeoutSeconds;
- tv.tv_usec = 0;
-
- if (select (socketHandle + 1, &readbits, 0, 0, &tv) <= 0)
- return String::empty; // (timeout)
-
- buffer.ensureSize (bytesRead + 8, true);
- char* const dest = (char*) buffer.getData() + bytesRead;
-
- if (recv (socketHandle, dest, 1, 0) == -1)
- return String::empty;
-
- const char lastByte = *dest;
- ++bytesRead;
-
- if (lastByte == '\n')
- ++numConsecutiveLFs;
- else if (lastByte != '\r')
- numConsecutiveLFs = 0;
- }
-
- const String header (String::fromUTF8 ((const uint8*) buffer.getData()));
-
- if (header.startsWithIgnoreCase (T("HTTP/")))
- return header.trimEnd();
-
- return String::empty;
- }
-
- static bool decomposeURL (const String& url,
- String& host, String& path, int& port)
- {
- if (! url.startsWithIgnoreCase (T("http://")))
- return false;
-
- const int nextSlash = url.indexOfChar (7, '/');
- int nextColon = url.indexOfChar (7, ':');
- if (nextColon > nextSlash && nextSlash > 0)
- nextColon = -1;
-
- if (nextColon >= 0)
- {
- host = url.substring (7, nextColon);
-
- if (nextSlash >= 0)
- port = url.substring (nextColon + 1, nextSlash).getIntValue();
- else
- port = url.substring (nextColon + 1).getIntValue();
- }
- else
- {
- port = 80;
-
- if (nextSlash >= 0)
- host = url.substring (7, nextSlash);
- else
- host = url.substring (7);
- }
-
- if (nextSlash >= 0)
- path = url.substring (nextSlash);
- else
- path = T("/");
-
- return true;
- }
-
- static const String findHeaderItem (const StringArray& lines, const String& itemName)
- {
- for (int i = 0; i < lines.size(); ++i)
- if (lines[i].startsWithIgnoreCase (itemName))
- return lines[i].substring (itemName.length()).trim();
-
- return String::empty;
- }
- };
-
- bool juce_isOnLine()
- {
- return true;
- }
-
- void* juce_openInternetFile (const String& url,
- const String& headers,
- const MemoryBlock& postData,
- const bool isPost,
- URL::OpenStreamProgressCallback* callback,
- void* callbackContext,
- int timeOutMs)
- {
- JUCE_HTTPSocketStream* const s = new JUCE_HTTPSocketStream();
-
- if (s->open (url, headers, postData, isPost,
- callback, callbackContext, timeOutMs))
- return s;
-
- delete s;
- return 0;
- }
-
- void juce_closeInternetFile (void* handle)
- {
- JUCE_HTTPSocketStream* const s = (JUCE_HTTPSocketStream*) handle;
-
- if (s != 0)
- delete s;
- }
-
- int juce_readFromInternetFile (void* handle, void* buffer, int bytesToRead)
- {
- JUCE_HTTPSocketStream* const s = (JUCE_HTTPSocketStream*) handle;
-
- if (s != 0)
- return s->read (buffer, bytesToRead);
-
- return 0;
- }
-
- int juce_seekInInternetFile (void* handle, int newPosition)
- {
- JUCE_HTTPSocketStream* const s = (JUCE_HTTPSocketStream*) handle;
-
- if (s != 0)
- return s->readPosition;
-
- return 0;
- }
- /********* End of inlined file: juce_mac_HTTPStream.h *********/
-
- int SystemStats::getMACAddresses (int64* addresses, int maxNum, const bool littleEndian) throw()
- {
- int numResults = 0;
-
- const int s = socket (AF_INET, SOCK_DGRAM, 0);
- if (s != -1)
- {
- char buf [1024];
- struct ifconf ifc;
- ifc.ifc_len = sizeof (buf);
- ifc.ifc_buf = buf;
- ioctl (s, SIOCGIFCONF, &ifc);
-
- for (unsigned int i = 0; i < ifc.ifc_len / sizeof (struct ifreq); ++i)
- {
- struct ifreq ifr;
- strcpy (ifr.ifr_name, ifc.ifc_req[i].ifr_name);
-
- if (ioctl (s, SIOCGIFFLAGS, &ifr) == 0
- && (ifr.ifr_flags & IFF_LOOPBACK) == 0
- && ioctl (s, SIOCGIFHWADDR, &ifr) == 0
- && numResults < maxNum)
- {
- int64 a = 0;
- for (int j = 6; --j >= 0;)
- a = (a << 8) | ifr.ifr_hwaddr.sa_data[j];
-
- *addresses++ = a;
- ++numResults;
- }
- }
-
- close (s);
- }
-
- return numResults;
- }
-
- bool PlatformUtilities::launchEmailWithAttachments (const String& targetEmailAddress,
- const String& emailSubject,
- const String& bodyText,
- const StringArray& filesToAttach)
- {
- jassertfalse // xxx todo
-
- return false;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_linux_Network.cpp *********/
-
- /********* Start of inlined file: juce_linux_SystemStats.cpp *********/
-
- #include <sys/sysinfo.h>
- #include <dlfcn.h>
-
- #ifndef CPU_ISSET
- #undef SUPPORT_AFFINITIES
- #endif
-
- BEGIN_JUCE_NAMESPACE
-
- /*static juce_noinline unsigned int getCPUIDWord (int* familyModel, int* extFeatures) throw()
- {
- unsigned int cpu = 0;
- unsigned int ext = 0;
- unsigned int family = 0;
- unsigned int dummy = 0;
-
- #if JUCE_64BIT
- __asm__ ("cpuid"
- : "=a" (family), "=b" (ext), "=c" (dummy), "=d" (cpu) : "a" (1));
-
- #else
- __asm__ ("push %%ebx; cpuid; mov %%ebx, %%edi; pop %%ebx"
- : "=a" (family), "=D" (ext), "=c" (dummy), "=d" (cpu) : "a" (1));
- #endif
-
- if (familyModel != 0)
- *familyModel = family;
-
- if (extFeatures != 0)
- *extFeatures = ext;
-
- return cpu;
- }*/
-
- void Logger::outputDebugString (const String& text) throw()
- {
- fprintf (stdout, text.toUTF8());
- fprintf (stdout, "\n");
- }
-
- void Logger::outputDebugPrintf (const tchar* format, ...) throw()
- {
- String text;
- va_list args;
- va_start (args, format);
- text.vprintf(format, args);
- outputDebugString(text);
- }
-
- SystemStats::OperatingSystemType SystemStats::getOperatingSystemType() throw()
- {
- return Linux;
- }
-
- const String SystemStats::getOperatingSystemName() throw()
- {
- return T("Linux");
- }
-
- bool SystemStats::isOperatingSystem64Bit() throw()
- {
- #if JUCE_64BIT
- return true;
- #else
- //xxx not sure how to find this out?..
- return false;
- #endif
- }
-
- static const String getCpuInfo (const char* key, bool lastOne = false) throw()
- {
- String info;
- char buf [256];
-
- FILE* f = fopen ("/proc/cpuinfo", "r");
-
- while (f != 0 && fgets (buf, sizeof(buf), f))
- {
- if (strncmp (buf, key, strlen (key)) == 0)
- {
- char* p = buf;
-
- while (*p && *p != '\n')
- ++p;
-
- if (*p != 0)
- *p = 0;
-
- p = buf;
-
- while (*p != 0 && *p != ':')
- ++p;
-
- if (*p != 0 && *(p + 1) != 0)
- info = p + 2;
-
- if (! lastOne)
- break;
- }
- }
-
- fclose (f);
- return info;
- }
-
- bool SystemStats::hasMMX() throw()
- {
- return getCpuInfo ("flags").contains (T("mmx"));
- }
-
- bool SystemStats::hasSSE() throw()
- {
- return getCpuInfo ("flags").contains (T("sse"));
- }
-
- bool SystemStats::hasSSE2() throw()
- {
- return getCpuInfo ("flags").contains (T("sse2"));
- }
-
- bool SystemStats::has3DNow() throw()
- {
- return getCpuInfo ("flags").contains (T("3dnow"));
- }
-
- const String SystemStats::getCpuVendor() throw()
- {
- return getCpuInfo ("vendor_id");
- }
-
- int SystemStats::getCpuSpeedInMegaherz() throw()
- {
- const String speed (getCpuInfo ("cpu MHz"));
-
- return (int) (speed.getFloatValue() + 0.5f);
- }
-
- int SystemStats::getMemorySizeInMegabytes() throw()
- {
- struct sysinfo sysi;
-
- if (sysinfo (&sysi) == 0)
- return (sysi.totalram * sysi.mem_unit / (1024 * 1024));
-
- return 0;
- }
-
- uint32 juce_millisecondsSinceStartup() throw()
- {
- static unsigned int calibrate = 0;
- static bool calibrated = false;
- timeval t;
- unsigned int ret = 0;
-
- if (! gettimeofday (&t, 0))
- {
- if (! calibrated)
- {
- struct sysinfo sysi;
-
- if (sysinfo (&sysi) == 0)
- // Safe to assume system was not brought up earlier than 1970!
- calibrate = t.tv_sec - sysi.uptime;
-
- calibrated = true;
- }
-
- ret = 1000 * (t.tv_sec - calibrate) + (t.tv_usec / 1000);
- }
-
- return ret;
- }
-
- double Time::getMillisecondCounterHiRes() throw()
- {
- return getHighResolutionTicks() * 0.001;
- }
-
- int64 Time::getHighResolutionTicks() throw()
- {
- timeval t;
- if (gettimeofday (&t, 0))
- return 0;
-
- return ((int64) t.tv_sec * (int64) 1000000) + (int64) t.tv_usec;
- }
-
- int64 Time::getHighResolutionTicksPerSecond() throw()
- {
- // Microseconds
- return 1000000;
- }
-
- bool Time::setSystemTimeToThisTime() const throw()
- {
- timeval t;
- t.tv_sec = millisSinceEpoch % 1000000;
- t.tv_usec = millisSinceEpoch - t.tv_sec;
-
- return settimeofday (&t, NULL) ? false : true;
- }
-
- int SystemStats::getPageSize() throw()
- {
- static int systemPageSize = 0;
-
- if (systemPageSize == 0)
- systemPageSize = sysconf (_SC_PAGESIZE);
-
- return systemPageSize;
- }
-
- int SystemStats::getNumCpus() throw()
- {
- const int lastCpu = getCpuInfo ("processor", true).getIntValue();
-
- return lastCpu + 1;
- }
-
- void SystemStats::initialiseStats() throw()
- {
- // Process starts off as root when running suid
- Process::lowerPrivilege();
-
- String s (SystemStats::getJUCEVersion());
- }
-
- void PlatformUtilities::fpuReset()
- {
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_linux_SystemStats.cpp *********/
-
- /********* Start of inlined file: juce_linux_Threads.cpp *********/
-
- #include <dlfcn.h>
- #include <sys/file.h>
- #include <sys/types.h>
- #include <sys/ptrace.h>
-
- BEGIN_JUCE_NAMESPACE
-
- /*
- Note that a lot of methods that you'd expect to find in this file actually
- live in juce_posix_SharedCode.cpp!
- */
-
- #ifndef CPU_ISSET
- #undef SUPPORT_AFFINITIES
- #endif
-
- void JUCE_API juce_threadEntryPoint (void*);
-
- void* threadEntryProc (void* value) throw()
- {
- // New threads start off as root when running suid
- Process::lowerPrivilege();
-
- juce_threadEntryPoint (value);
- return 0;
- }
-
- void* juce_createThread (void* userData) throw()
- {
- pthread_t handle = 0;
-
- if (pthread_create (&handle, 0, threadEntryProc, userData) == 0)
- {
- pthread_detach (handle);
- return (void*)handle;
- }
-
- return 0;
- }
-
- void juce_killThread (void* handle) throw()
- {
- if (handle != 0)
- pthread_cancel ((pthread_t)handle);
- }
-
- void juce_setCurrentThreadName (const String& /*name*/) throw()
- {
- }
-
- int Thread::getCurrentThreadId() throw()
- {
- return (int) pthread_self();
- }
-
- /*
- * This is all a bit non-ideal... the trouble is that on Linux you
- * need to call setpriority to affect the dynamic priority for
- * non-realtime processes, but this requires the pid, which is not
- * accessible from the pthread_t. We could get it by calling getpid
- * once each thread has started, but then we would need a list of
- * running threads etc etc.
- * Also there is no such thing as IDLE priority on Linux.
- * For the moment, map idle, low and normal process priorities to
- * SCHED_OTHER, with the thread priority ignored for these classes.
- * Map high priority processes to the lower half of the SCHED_RR
- * range, and realtime to the upper half
- */
-
- // priority 1 to 10 where 5=normal, 1=low. If the handle is 0, sets the
- // priority of the current thread
- void juce_setThreadPriority (void* handle, int priority) throw()
- {
- struct sched_param param;
- int policy, maxp, minp, pri;
-
- if (handle == 0)
- handle = (void*) pthread_self();
-
- if (pthread_getschedparam ((pthread_t) handle, &policy, ¶m) == 0
- && policy != SCHED_OTHER)
- {
- minp = sched_get_priority_min(policy);
- maxp = sched_get_priority_max(policy);
-
- pri = ((maxp - minp) / 2) * (priority - 1) / 9;
-
- if (param.__sched_priority >= (minp + (maxp - minp) / 2))
- // Realtime process priority
- param.__sched_priority = minp + ((maxp - minp) / 2) + pri;
- else
- // High process priority
- param.__sched_priority = minp + pri;
-
- param.sched_priority = jlimit (1, 127, 1 + (priority * 126) / 11);
-
- pthread_setschedparam ((pthread_t) handle, policy, ¶m);
- }
- }
-
- void Thread::setCurrentThreadAffinityMask (const uint32 affinityMask) throw()
- {
- #if SUPPORT_AFFINITIES
- cpu_set_t affinity;
- CPU_ZERO (&affinity);
-
- for (int i = 0; i < 32; ++i)
- if ((affinityMask & (1 << i)) != 0)
- CPU_SET (i, &affinity);
-
- /*
- N.B. If this line causes a compile error, then you've probably not got the latest
- version of glibc installed.
-
- If you don't want to update your copy of glibc and don't care about cpu affinities,
- then you can just disable all this stuff by removing the SUPPORT_AFFINITIES macro
- from the linuxincludes.h file.
- */
- sched_setaffinity (getpid(), sizeof (cpu_set_t), &affinity);
- sched_yield();
-
- #else
- /* affinities aren't supported because either the appropriate header files weren't found,
- or the SUPPORT_AFFINITIES macro was turned off in linuxheaders.h
- */
- jassertfalse
- #endif
- }
-
- void Thread::yield() throw()
- {
- sched_yield();
- }
-
- // sets the process to 0=low priority, 1=normal, 2=high, 3=realtime
- void Process::setPriority (ProcessPriority prior)
- {
- struct sched_param param;
- int policy, maxp, minp;
-
- const int p = (int) prior;
-
- if (p <= 1)
- policy = SCHED_OTHER;
- else
- policy = SCHED_RR;
-
- minp = sched_get_priority_min (policy);
- maxp = sched_get_priority_max (policy);
-
- if (p < 2)
- param.__sched_priority = 0;
- else if (p == 2 )
- // Set to middle of lower realtime priority range
- param.__sched_priority = minp + (maxp - minp) / 4;
- else
- // Set to middle of higher realtime priority range
- param.__sched_priority = minp + (3 * (maxp - minp) / 4);
-
- pthread_setschedparam (pthread_self(), policy, ¶m);
- }
-
- void Process::terminate()
- {
- exit (0);
- }
-
- bool JUCE_CALLTYPE juce_isRunningUnderDebugger() throw()
- {
- static char testResult = 0;
-
- if (testResult == 0)
- {
- testResult = (char) ptrace (PT_TRACE_ME, 0, 0, 0);
-
- if (testResult >= 0)
- {
- ptrace (PT_DETACH, 0, (caddr_t) 1, 0);
- testResult = 1;
- }
- }
-
- return testResult < 0;
- }
-
- bool JUCE_CALLTYPE Process::isRunningUnderDebugger() throw()
- {
- return juce_isRunningUnderDebugger();
- }
-
- void Process::raisePrivilege()
- {
- // If running suid root, change effective user
- // to root
- if (geteuid() != 0 && getuid() == 0)
- {
- setreuid (geteuid(), getuid());
- setregid (getegid(), getgid());
- }
- }
-
- void Process::lowerPrivilege()
- {
- // If runing suid root, change effective user
- // back to real user
- if (geteuid() == 0 && getuid() != 0)
- {
- setreuid (geteuid(), getuid());
- setregid (getegid(), getgid());
- }
- }
-
- #if JUCE_BUILD_GUI_CLASSES
- void* Process::loadDynamicLibrary (const String& name)
- {
- return dlopen ((const char*) name.toUTF8(), RTLD_LOCAL | RTLD_NOW);
- }
-
- void Process::freeDynamicLibrary (void* handle)
- {
- dlclose(handle);
- }
-
- void* Process::getProcedureEntryPoint (void* libraryHandle, const String& procedureName)
- {
- return dlsym (libraryHandle, (const char*) procedureName);
- }
- #endif
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_linux_Threads.cpp *********/
-
- #if ! JUCE_ONLY_BUILD_CORE_LIBRARY
-
- /********* Start of inlined file: juce_linux_Audio.cpp *********/
-
- #if JUCE_BUILD_GUI_CLASSES
-
- #if JUCE_ALSA
-
- /* Got an include error here? If so, you've either not got ALSA installed, or you've
- not got your paths set up correctly to find its header files.
-
- The package you need to install to get ASLA support is "libasound2-dev".
-
- If you don't have the ALSA library and don't want to build Juce with audio support,
- just disable the JUCE_ALSA flag in juce_Config.h
- */
- #include <alsa/asoundlib.h>
-
- BEGIN_JUCE_NAMESPACE
-
- static const int maxNumChans = 64;
-
- static void getDeviceSampleRates (snd_pcm_t* handle, Array <int>& rates)
- {
- const int ratesToTry[] = { 22050, 32000, 44100, 48000, 88200, 96000, 176400, 192000, 0 };
-
- snd_pcm_hw_params_t* hwParams;
- snd_pcm_hw_params_alloca (&hwParams);
-
- for (int i = 0; ratesToTry[i] != 0; ++i)
- {
- if (snd_pcm_hw_params_any (handle, hwParams) >= 0
- && snd_pcm_hw_params_test_rate (handle, hwParams, ratesToTry[i], 0) == 0)
- {
- rates.addIfNotAlreadyThere (ratesToTry[i]);
- }
- }
- }
-
- static void getDeviceNumChannels (snd_pcm_t* handle, unsigned int* minChans, unsigned int* maxChans)
- {
- snd_pcm_hw_params_t *params;
- snd_pcm_hw_params_alloca (¶ms);
-
- if (snd_pcm_hw_params_any (handle, params) >= 0)
- {
- snd_pcm_hw_params_get_channels_min (params, minChans);
- snd_pcm_hw_params_get_channels_max (params, maxChans);
- }
- }
-
- static void getDeviceProperties (const String& id,
- unsigned int& minChansOut,
- unsigned int& maxChansOut,
- unsigned int& minChansIn,
- unsigned int& maxChansIn,
- Array <int>& rates)
- {
- if (id.isEmpty())
- return;
-
- snd_ctl_t* handle;
-
- if (snd_ctl_open (&handle, id.upToLastOccurrenceOf (T(","), false, false), SND_CTL_NONBLOCK) >= 0)
- {
- snd_pcm_info_t* info;
- snd_pcm_info_alloca (&info);
-
- snd_pcm_info_set_stream (info, SND_PCM_STREAM_PLAYBACK);
- snd_pcm_info_set_device (info, id.fromLastOccurrenceOf (T(","), false, false).getIntValue());
- snd_pcm_info_set_subdevice (info, 0);
-
- if (snd_ctl_pcm_info (handle, info) >= 0)
- {
- snd_pcm_t* pcmHandle;
- if (snd_pcm_open (&pcmHandle, id, SND_PCM_STREAM_PLAYBACK, SND_PCM_ASYNC | SND_PCM_NONBLOCK ) >= 0)
- {
- getDeviceNumChannels (pcmHandle, &minChansOut, &maxChansOut);
- getDeviceSampleRates (pcmHandle, rates);
-
- snd_pcm_close (pcmHandle);
- }
- }
-
- snd_pcm_info_set_stream (info, SND_PCM_STREAM_CAPTURE);
-
- if (snd_ctl_pcm_info (handle, info) >= 0)
- {
- snd_pcm_t* pcmHandle;
- if (snd_pcm_open (&pcmHandle, id, SND_PCM_STREAM_CAPTURE, SND_PCM_ASYNC | SND_PCM_NONBLOCK ) >= 0)
- {
- getDeviceNumChannels (pcmHandle, &minChansIn, &maxChansIn);
-
- if (rates.size() == 0)
- getDeviceSampleRates (pcmHandle, rates);
-
- snd_pcm_close (pcmHandle);
- }
- }
-
- snd_ctl_close (handle);
- }
- }
-
- class ALSADevice
- {
- public:
- ALSADevice (const String& id,
- const bool forInput)
- : handle (0),
- bitDepth (16),
- numChannelsRunning (0),
- isInput (forInput),
- sampleFormat (AudioDataConverters::int16LE)
- {
- failed (snd_pcm_open (&handle, id,
- forInput ? SND_PCM_STREAM_CAPTURE : SND_PCM_STREAM_PLAYBACK,
- SND_PCM_ASYNC));
- }
-
- ~ALSADevice()
- {
- if (handle != 0)
- snd_pcm_close (handle);
- }
-
- bool setParameters (unsigned int sampleRate, int numChannels, int bufferSize)
- {
- if (handle == 0)
- return false;
-
- snd_pcm_hw_params_t* hwParams;
- snd_pcm_hw_params_alloca (&hwParams);
-
- if (failed (snd_pcm_hw_params_any (handle, hwParams)))
- return false;
-
- if (snd_pcm_hw_params_set_access (handle, hwParams, SND_PCM_ACCESS_RW_NONINTERLEAVED) >= 0)
- isInterleaved = false;
- else if (snd_pcm_hw_params_set_access (handle, hwParams, SND_PCM_ACCESS_RW_INTERLEAVED) >= 0)
- isInterleaved = true;
- else
- {
- jassertfalse
- return false;
- }
-
- const int formatsToTry[] = { SND_PCM_FORMAT_FLOAT_LE, 32, AudioDataConverters::float32LE,
- SND_PCM_FORMAT_FLOAT_BE, 32, AudioDataConverters::float32BE,
- SND_PCM_FORMAT_S32_LE, 32, AudioDataConverters::int32LE,
- SND_PCM_FORMAT_S32_BE, 32, AudioDataConverters::int32BE,
- SND_PCM_FORMAT_S24_LE, 24, AudioDataConverters::int24LE,
- SND_PCM_FORMAT_S24_BE, 24, AudioDataConverters::int24BE,
- SND_PCM_FORMAT_S16_LE, 16, AudioDataConverters::int16LE,
- SND_PCM_FORMAT_S16_BE, 16, AudioDataConverters::int16BE };
- bitDepth = 0;
-
- for (int i = 0; i < numElementsInArray (formatsToTry); i += 3)
- {
- if (snd_pcm_hw_params_set_format (handle, hwParams, (_snd_pcm_format) formatsToTry [i]) >= 0)
- {
- bitDepth = formatsToTry [i + 1];
- sampleFormat = (AudioDataConverters::DataFormat) formatsToTry [i + 2];
- break;
- }
- }
-
- if (bitDepth == 0)
- {
- error = "device doesn't support a compatible PCM format";
- DBG (T("ALSA error: ") + error + T("\n"));
- return false;
- }
-
- int dir = 0;
- unsigned int periods = 4;
- snd_pcm_uframes_t samplesPerPeriod = bufferSize;
-
- if (failed (snd_pcm_hw_params_set_rate_near (handle, hwParams, &sampleRate, 0))
- || failed (snd_pcm_hw_params_set_channels (handle, hwParams, numChannels))
- || failed (snd_pcm_hw_params_set_periods_near (handle, hwParams, &periods, &dir))
- || failed (snd_pcm_hw_params_set_period_size_near (handle, hwParams, &samplesPerPeriod, &dir))
- || failed (snd_pcm_hw_params (handle, hwParams)))
- {
- return false;
- }
-
- snd_pcm_sw_params_t* swParams;
- snd_pcm_sw_params_alloca (&swParams);
-
- if (failed (snd_pcm_sw_params_current (handle, swParams))
- || failed (snd_pcm_sw_params_set_silence_threshold (handle, swParams, 0))
- || failed (snd_pcm_sw_params_set_silence_size (handle, swParams, 0))
- || failed (snd_pcm_sw_params_set_start_threshold (handle, swParams, samplesPerPeriod))
- || failed (snd_pcm_sw_params_set_stop_threshold (handle, swParams, INT_MAX))
- || failed (snd_pcm_sw_params (handle, swParams)))
- {
- return false;
- }
-
- /*
- #ifdef JUCE_DEBUG
- // enable this to dump the config of the devices that get opened
- snd_output_t* out;
- snd_output_stdio_attach (&out, stderr, 0);
- snd_pcm_hw_params_dump (hwParams, out);
- snd_pcm_sw_params_dump (swParams, out);
- #endif
- */
-
- numChannelsRunning = numChannels;
-
- return true;
- }
-
- bool write (float** const data, const int numSamples)
- {
- if (isInterleaved)
- {
- scratch.ensureSize (sizeof (float) * numSamples * numChannelsRunning, false);
- float* interleaved = (float*) scratch;
-
- AudioDataConverters::interleaveSamples ((const float**) data, interleaved, numSamples, numChannelsRunning);
- AudioDataConverters::convertFloatToFormat (sampleFormat, interleaved, interleaved, numSamples * numChannelsRunning);
-
- snd_pcm_sframes_t num = snd_pcm_writei (handle, (void*) interleaved, numSamples);
-
- if (failed (num) && num != -EPIPE && num != -ESTRPIPE)
- return false;
- }
- else
- {
- for (int i = 0; i < numChannelsRunning; ++i)
- if (data[i] != 0)
- AudioDataConverters::convertFloatToFormat (sampleFormat, data[i], data[i], numSamples);
-
- snd_pcm_sframes_t num = snd_pcm_writen (handle, (void**) data, numSamples);
-
- if (failed (num))
- {
- if (num == -EPIPE)
- {
- if (failed (snd_pcm_prepare (handle)))
- return false;
- }
- else if (num != -ESTRPIPE)
- return false;
- }
- }
-
- return true;
- }
-
- bool read (float** const data, const int numSamples)
- {
- if (isInterleaved)
- {
- scratch.ensureSize (sizeof (float) * numSamples * numChannelsRunning, false);
- float* interleaved = (float*) scratch;
-
- snd_pcm_sframes_t num = snd_pcm_readi (handle, (void*) interleaved, numSamples);
-
- if (failed (num))
- {
- if (num == -EPIPE)
- {
- if (failed (snd_pcm_prepare (handle)))
- return false;
- }
- else if (num != -ESTRPIPE)
- return false;
- }
-
- AudioDataConverters::convertFormatToFloat (sampleFormat, interleaved, interleaved, numSamples * numChannelsRunning);
- AudioDataConverters::deinterleaveSamples (interleaved, data, numSamples, numChannelsRunning);
- }
- else
- {
- snd_pcm_sframes_t num = snd_pcm_readn (handle, (void**) data, numSamples);
-
- if (failed (num) && num != -EPIPE && num != -ESTRPIPE)
- return false;
-
- for (int i = 0; i < numChannelsRunning; ++i)
- if (data[i] != 0)
- AudioDataConverters::convertFormatToFloat (sampleFormat, data[i], data[i], numSamples);
- }
-
- return true;
- }
-
- juce_UseDebuggingNewOperator
-
- snd_pcm_t* handle;
- String error;
- int bitDepth, numChannelsRunning;
-
- private:
- const bool isInput;
- bool isInterleaved;
- MemoryBlock scratch;
- AudioDataConverters::DataFormat sampleFormat;
-
- bool failed (const int errorNum)
- {
- if (errorNum >= 0)
- return false;
-
- error = snd_strerror (errorNum);
- DBG (T("ALSA error: ") + error + T("\n"));
- return true;
- }
- };
-
- class ALSAThread : public Thread
- {
- public:
- ALSAThread (const String& inputId_,
- const String& outputId_)
- : Thread ("Juce ALSA"),
- sampleRate (0),
- bufferSize (0),
- callback (0),
- inputId (inputId_),
- outputId (outputId_),
- outputDevice (0),
- inputDevice (0),
- numCallbacks (0),
- totalNumInputChannels (0),
- totalNumOutputChannels (0)
- {
- zeromem (outputChannelData, sizeof (outputChannelData));
- zeromem (outputChannelDataForCallback, sizeof (outputChannelDataForCallback));
- zeromem (inputChannelData, sizeof (inputChannelData));
- zeromem (inputChannelDataForCallback, sizeof (inputChannelDataForCallback));
-
- initialiseRatesAndChannels();
- }
-
- ~ALSAThread()
- {
- close();
- }
-
- void open (const BitArray& inputChannels,
- const BitArray& outputChannels,
- const double sampleRate_,
- const int bufferSize_)
- {
- close();
-
- error = String::empty;
- sampleRate = sampleRate_;
- bufferSize = bufferSize_;
- currentInputChans.clear();
- currentOutputChans.clear();
-
- if (inputChannels.getHighestBit() >= 0)
- {
- for (int i = 0; i <= inputChannels.getHighestBit(); ++i)
- {
- inputChannelData [i] = (float*) juce_calloc (sizeof (float) * bufferSize);
-
- if (inputChannels[i])
- {
- inputChannelDataForCallback [totalNumInputChannels++] = inputChannelData [i];
- currentInputChans.setBit (i);
- }
- }
- }
-
- if (outputChannels.getHighestBit() >= 0)
- {
- for (int i = 0; i <= outputChannels.getHighestBit(); ++i)
- {
- outputChannelData [i] = (float*) juce_calloc (sizeof (float) * bufferSize);
-
- if (outputChannels[i])
- {
- outputChannelDataForCallback [totalNumOutputChannels++] = outputChannelData [i];
- currentOutputChans.setBit (i);
- }
- }
- }
-
- if (totalNumOutputChannels > 0 && outputId.isNotEmpty())
- {
- outputDevice = new ALSADevice (outputId, false);
-
- if (outputDevice->error.isNotEmpty())
- {
- error = outputDevice->error;
- deleteAndZero (outputDevice);
- return;
- }
-
- if (! outputDevice->setParameters ((unsigned int) sampleRate,
- currentOutputChans.getHighestBit() + 1,
- bufferSize))
- {
- error = outputDevice->error;
- deleteAndZero (outputDevice);
- return;
- }
- }
-
- if (totalNumInputChannels > 0 && inputId.isNotEmpty())
- {
- inputDevice = new ALSADevice (inputId, true);
-
- if (inputDevice->error.isNotEmpty())
- {
- error = inputDevice->error;
- deleteAndZero (inputDevice);
- return;
- }
-
- if (! inputDevice->setParameters ((unsigned int) sampleRate,
- currentInputChans.getHighestBit() + 1,
- bufferSize))
- {
- error = inputDevice->error;
- deleteAndZero (inputDevice);
- return;
- }
- }
-
- if (outputDevice == 0 && inputDevice == 0)
- {
- error = "no channels";
- return;
- }
-
- if (outputDevice != 0 && inputDevice != 0)
- {
- snd_pcm_link (outputDevice->handle, inputDevice->handle);
- }
-
- if (inputDevice != 0 && failed (snd_pcm_prepare (inputDevice->handle)))
- return;
-
- if (outputDevice != 0 && failed (snd_pcm_prepare (outputDevice->handle)))
- return;
-
- startThread (9);
-
- int count = 1000;
-
- while (numCallbacks == 0)
- {
- sleep (5);
-
- if (--count < 0 || ! isThreadRunning())
- {
- error = "device didn't start";
- break;
- }
- }
- }
-
- void close()
- {
- stopThread (6000);
-
- deleteAndZero (inputDevice);
- deleteAndZero (outputDevice);
-
- for (int i = 0; i < maxNumChans; ++i)
- {
- juce_free (inputChannelData [i]);
- juce_free (outputChannelData [i]);
- }
-
- zeromem (outputChannelData, sizeof (outputChannelData));
- zeromem (outputChannelDataForCallback, sizeof (outputChannelDataForCallback));
- zeromem (inputChannelData, sizeof (inputChannelData));
- zeromem (inputChannelDataForCallback, sizeof (inputChannelDataForCallback));
- totalNumOutputChannels = 0;
- totalNumInputChannels = 0;
-
- numCallbacks = 0;
- }
-
- void setCallback (AudioIODeviceCallback* const newCallback) throw()
- {
- const ScopedLock sl (callbackLock);
- callback = newCallback;
- }
-
- void run()
- {
- while (! threadShouldExit())
- {
- if (inputDevice != 0)
- {
- if (! inputDevice->read (inputChannelData, bufferSize))
- {
- DBG ("ALSA: read failure");
- break;
- }
- }
-
- if (threadShouldExit())
- break;
-
- {
- const ScopedLock sl (callbackLock);
- ++numCallbacks;
-
- if (callback != 0)
- {
- callback->audioDeviceIOCallback ((const float**) inputChannelDataForCallback,
- totalNumInputChannels,
- outputChannelDataForCallback,
- totalNumOutputChannels,
- bufferSize);
- }
- else
- {
- for (int i = 0; i < totalNumOutputChannels; ++i)
- zeromem (outputChannelDataForCallback[i], sizeof (float) * bufferSize);
- }
- }
-
- if (outputDevice != 0)
- {
- failed (snd_pcm_wait (outputDevice->handle, 2000));
-
- if (threadShouldExit())
- break;
-
- failed (snd_pcm_avail_update (outputDevice->handle));
-
- if (! outputDevice->write (outputChannelData, bufferSize))
- {
- DBG ("ALSA: write failure");
- break;
- }
- }
- }
- }
-
- int getBitDepth() const throw()
- {
- if (outputDevice != 0)
- return outputDevice->bitDepth;
-
- if (inputDevice != 0)
- return inputDevice->bitDepth;
-
- return 16;
- }
-
- juce_UseDebuggingNewOperator
-
- String error;
- double sampleRate;
- int bufferSize;
- BitArray currentInputChans, currentOutputChans;
-
- Array <int> sampleRates;
- StringArray channelNamesOut, channelNamesIn;
- AudioIODeviceCallback* callback;
-
- private:
-
- const String inputId, outputId;
- ALSADevice* outputDevice;
- ALSADevice* inputDevice;
- int numCallbacks;
-
- CriticalSection callbackLock;
-
- float* outputChannelData [maxNumChans];
- float* outputChannelDataForCallback [maxNumChans];
- int totalNumInputChannels;
- float* inputChannelData [maxNumChans];
- float* inputChannelDataForCallback [maxNumChans];
- int totalNumOutputChannels;
-
- unsigned int minChansOut, maxChansOut;
- unsigned int minChansIn, maxChansIn;
-
- bool failed (const int errorNum) throw()
- {
- if (errorNum >= 0)
- return false;
-
- error = snd_strerror (errorNum);
- DBG (T("ALSA error: ") + error + T("\n"));
- return true;
- }
-
- void initialiseRatesAndChannels() throw()
- {
- sampleRates.clear();
- channelNamesOut.clear();
- channelNamesIn.clear();
- minChansOut = 0;
- maxChansOut = 0;
- minChansIn = 0;
- maxChansIn = 0;
- unsigned int dummy = 0;
-
- getDeviceProperties (inputId, dummy, dummy, minChansIn, maxChansIn, sampleRates);
- getDeviceProperties (outputId, minChansOut, maxChansOut, dummy, dummy, sampleRates);
-
- unsigned int i;
- for (i = 0; i < maxChansOut; ++i)
- channelNamesOut.add (T("channel ") + String ((int) i + 1));
-
- for (i = 0; i < maxChansIn; ++i)
- channelNamesIn.add (T("channel ") + String ((int) i + 1));
- }
- };
-
- class ALSAAudioIODevice : public AudioIODevice
- {
- public:
- ALSAAudioIODevice (const String& deviceName,
- const String& inputId_,
- const String& outputId_)
- : AudioIODevice (deviceName, T("ALSA")),
- inputId (inputId_),
- outputId (outputId_),
- isOpen_ (false),
- isStarted (false),
- internal (0)
- {
- internal = new ALSAThread (inputId, outputId);
- }
-
- ~ALSAAudioIODevice()
- {
- delete internal;
- }
-
- const StringArray getOutputChannelNames()
- {
- return internal->channelNamesOut;
- }
-
- const StringArray getInputChannelNames()
- {
- return internal->channelNamesIn;
- }
-
- int getNumSampleRates()
- {
- return internal->sampleRates.size();
- }
-
- double getSampleRate (int index)
- {
- return internal->sampleRates [index];
- }
-
- int getNumBufferSizesAvailable()
- {
- return 50;
- }
-
- int getBufferSizeSamples (int index)
- {
- int n = 16;
- for (int i = 0; i < index; ++i)
- n += n < 64 ? 16
- : (n < 512 ? 32
- : (n < 1024 ? 64
- : (n < 2048 ? 128 : 256)));
-
- return n;
- }
-
- int getDefaultBufferSize()
- {
- return 512;
- }
-
- const String open (const BitArray& inputChannels,
- const BitArray& outputChannels,
- double sampleRate,
- int bufferSizeSamples)
- {
- close();
-
- if (bufferSizeSamples <= 0)
- bufferSizeSamples = getDefaultBufferSize();
-
- if (sampleRate <= 0)
- {
- for (int i = 0; i < getNumSampleRates(); ++i)
- {
- if (getSampleRate (i) >= 44100)
- {
- sampleRate = getSampleRate (i);
- break;
- }
- }
- }
-
- internal->open (inputChannels, outputChannels,
- sampleRate, bufferSizeSamples);
-
- isOpen_ = internal->error.isEmpty();
- return internal->error;
- }
-
- void close()
- {
- stop();
- internal->close();
- isOpen_ = false;
- }
-
- bool isOpen()
- {
- return isOpen_;
- }
-
- int getCurrentBufferSizeSamples()
- {
- return internal->bufferSize;
- }
-
- double getCurrentSampleRate()
- {
- return internal->sampleRate;
- }
-
- int getCurrentBitDepth()
- {
- return internal->getBitDepth();
- }
-
- const BitArray getActiveOutputChannels() const
- {
- return internal->currentOutputChans;
- }
-
- const BitArray getActiveInputChannels() const
- {
- return internal->currentInputChans;
- }
-
- int getOutputLatencyInSamples()
- {
- return 0;
- }
-
- int getInputLatencyInSamples()
- {
- return 0;
- }
-
- void start (AudioIODeviceCallback* callback)
- {
- if (! isOpen_)
- callback = 0;
-
- internal->setCallback (callback);
-
- if (callback != 0)
- callback->audioDeviceAboutToStart (this);
-
- isStarted = (callback != 0);
- }
-
- void stop()
- {
- AudioIODeviceCallback* const oldCallback = internal->callback;
-
- start (0);
-
- if (oldCallback != 0)
- oldCallback->audioDeviceStopped();
- }
-
- bool isPlaying()
- {
- return isStarted && internal->error.isEmpty();
- }
-
- const String getLastError()
- {
- return internal->error;
- }
-
- String inputId, outputId;
-
- private:
- bool isOpen_, isStarted;
- ALSAThread* internal;
- };
-
- class ALSAAudioIODeviceType : public AudioIODeviceType
- {
- public:
-
- ALSAAudioIODeviceType()
- : AudioIODeviceType (T("ALSA")),
- hasScanned (false)
- {
- }
-
- ~ALSAAudioIODeviceType()
- {
- }
-
- void scanForDevices()
- {
- if (hasScanned)
- return;
-
- hasScanned = true;
- inputNames.clear();
- inputIds.clear();
- outputNames.clear();
- outputIds.clear();
-
- snd_ctl_t* handle;
- snd_ctl_card_info_t* info;
- snd_ctl_card_info_alloca (&info);
-
- int cardNum = -1;
-
- while (outputIds.size() + inputIds.size() <= 32)
- {
- snd_card_next (&cardNum);
-
- if (cardNum < 0)
- break;
-
- if (snd_ctl_open (&handle, T("hw:") + String (cardNum), SND_CTL_NONBLOCK) >= 0)
- {
- if (snd_ctl_card_info (handle, info) >= 0)
- {
- String cardId (snd_ctl_card_info_get_id (info));
-
- if (cardId.removeCharacters (T("0123456789")).isEmpty())
- cardId = String (cardNum);
-
- int device = -1;
-
- for (;;)
- {
- if (snd_ctl_pcm_next_device (handle, &device) < 0 || device < 0)
- break;
-
- String id, name;
- id << "hw:" << cardId << ',' << device;
-
- bool isInput, isOutput;
-
- if (testDevice (id, isInput, isOutput))
- {
- name << snd_ctl_card_info_get_name (info);
-
- if (name.isEmpty())
- name = id;
-
- if (isInput)
- {
- inputNames.add (name);
- inputIds.add (id);
- }
-
- if (isOutput)
- {
- outputNames.add (name);
- outputIds.add (id);
- }
- }
- }
- }
-
- snd_ctl_close (handle);
- }
- }
-
- inputNames.appendNumbersToDuplicates (false, true);
- outputNames.appendNumbersToDuplicates (false, true);
- }
-
- const StringArray getDeviceNames (const bool wantInputNames) const
- {
- jassert (hasScanned); // need to call scanForDevices() before doing this
-
- return wantInputNames ? inputNames : outputNames;
- }
-
- int getDefaultDeviceIndex (const bool forInput) const
- {
- jassert (hasScanned); // need to call scanForDevices() before doing this
- return 0;
- }
-
- bool hasSeparateInputsAndOutputs() const { return true; }
-
- int getIndexOfDevice (AudioIODevice* device, const bool asInput) const
- {
- jassert (hasScanned); // need to call scanForDevices() before doing this
-
- ALSAAudioIODevice* const d = dynamic_cast <ALSAAudioIODevice*> (device);
- if (d == 0)
- return -1;
-
- return asInput ? inputIds.indexOf (d->inputId)
- : outputIds.indexOf (d->outputId);
- }
-
- AudioIODevice* createDevice (const String& outputDeviceName,
- const String& inputDeviceName)
- {
- jassert (hasScanned); // need to call scanForDevices() before doing this
-
- const int inputIndex = inputNames.indexOf (inputDeviceName);
- const int outputIndex = outputNames.indexOf (outputDeviceName);
-
- String deviceName (outputDeviceName);
- if (deviceName.isEmpty())
- deviceName = inputDeviceName;
-
- if (index >= 0)
- return new ALSAAudioIODevice (deviceName,
- inputIds [inputIndex],
- outputIds [outputIndex]);
-
- return 0;
- }
-
- juce_UseDebuggingNewOperator
-
- private:
- StringArray inputNames, outputNames, inputIds, outputIds;
- bool hasScanned;
-
- static bool testDevice (const String& id, bool& isInput, bool& isOutput)
- {
- unsigned int minChansOut = 0, maxChansOut = 0;
- unsigned int minChansIn = 0, maxChansIn = 0;
- Array <int> rates;
-
- getDeviceProperties (id, minChansOut, maxChansOut, minChansIn, maxChansIn, rates);
-
- DBG (T("ALSA device: ") + id
- + T(" outs=") + String ((int) minChansOut) + T("-") + String ((int) maxChansOut)
- + T(" ins=") + String ((int) minChansIn) + T("-") + String ((int) maxChansIn)
- + T(" rates=") + String (rates.size()));
-
- isInput = maxChansIn > 0;
- isOutput = maxChansOut > 0;
-
- return (isInput || isOutput) && rates.size() > 0;
- }
-
- ALSAAudioIODeviceType (const ALSAAudioIODeviceType&);
- const ALSAAudioIODeviceType& operator= (const ALSAAudioIODeviceType&);
- };
-
- AudioIODeviceType* juce_createDefaultAudioIODeviceType()
- {
- return new ALSAAudioIODeviceType();
- }
-
- END_JUCE_NAMESPACE
-
- #else // if ALSA is turned off..
-
- BEGIN_JUCE_NAMESPACE
-
- AudioIODeviceType* juce_createDefaultAudioIODeviceType() { return 0; }
-
- END_JUCE_NAMESPACE
-
- #endif
-
- #endif
- /********* End of inlined file: juce_linux_Audio.cpp *********/
-
- /********* Start of inlined file: juce_linux_AudioCDReader.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- AudioCDReader::AudioCDReader()
- : AudioFormatReader (0, T("CD Audio"))
- {
- }
-
- const StringArray AudioCDReader::getAvailableCDNames()
- {
- StringArray names;
- return names;
- }
-
- AudioCDReader* AudioCDReader::createReaderForCD (const int index)
- {
- return 0;
- }
-
- AudioCDReader::~AudioCDReader()
- {
- }
-
- void AudioCDReader::refreshTrackLengths()
- {
- }
-
- bool AudioCDReader::read (int** destSamples,
- int64 startSampleInFile,
- int numSamples)
- {
- return false;
- }
-
- bool AudioCDReader::isCDStillPresent() const
- {
- return false;
- }
-
- int AudioCDReader::getNumTracks() const
- {
- return 0;
- }
-
- int AudioCDReader::getPositionOfTrackStart (int trackNum) const
- {
- return 0;
- }
-
- bool AudioCDReader::isTrackAudio (int trackNum) const
- {
- return false;
- }
-
- void AudioCDReader::enableIndexScanning (bool b)
- {
- }
-
- int AudioCDReader::getLastIndex() const
- {
- return 0;
- }
-
- const Array<int> AudioCDReader::findIndexesInTrack (const int trackNumber)
- {
- return Array<int>();
- }
-
- int AudioCDReader::getCDDBId()
- {
- return 0;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_linux_AudioCDReader.cpp *********/
-
- /********* Start of inlined file: juce_linux_FileChooser.cpp *********/
-
- #if JUCE_BUILD_GUI_CLASSES
-
- BEGIN_JUCE_NAMESPACE
-
- void FileChooser::showPlatformDialog (OwnedArray<File>& results,
- const String& title,
- const File& file,
- const String& filters,
- bool isDirectory,
- bool isSave,
- bool warnAboutOverwritingExistingFiles,
- bool selectMultipleFiles,
- FilePreviewComponent* previewComponent)
- {
- //xxx ain't got one!
- jassertfalse
- }
-
- END_JUCE_NAMESPACE
-
- #endif
- /********* End of inlined file: juce_linux_FileChooser.cpp *********/
-
- /********* Start of inlined file: juce_linux_Fonts.cpp *********/
-
- #if JUCE_BUILD_GUI_CLASSES
-
- /* Got a build error here? You'll need to install the freetype library...
-
- The name of the package to install is "libfreetype6-dev".
- */
- #include <ft2build.h>
- #include FT_FREETYPE_H
-
- BEGIN_JUCE_NAMESPACE
-
- class FreeTypeFontFace
- {
- public:
-
- enum FontStyle
- {
- Plain = 0,
- Bold = 1,
- Italic = 2
- };
-
- struct FontNameIndex
- {
- String fileName;
- int faceIndex;
- };
-
- FreeTypeFontFace (const String& familyName)
- : hasSerif (false),
- monospaced (false)
- {
- family = familyName;
- }
-
- void setFileName (const String& name,
- const int faceIndex,
- FontStyle style)
- {
- if (names[(int) style].fileName.isEmpty())
- {
- names[(int) style].fileName = name;
- names[(int) style].faceIndex = faceIndex;
- }
- }
-
- const String& getFamilyName() const throw()
- {
- return family;
- }
-
- const String& getFileName (int style, int* faceIndex) const throw()
- {
- *faceIndex = names [style].faceIndex;
- return names[style].fileName;
- }
-
- void setMonospaced (bool mono) { monospaced = mono; }
- bool getMonospaced () const throw() { return monospaced; }
-
- void setSerif (const bool serif) { hasSerif = serif; }
- bool getSerif () const throw() { return hasSerif; }
-
- private:
-
- String family;
- FontNameIndex names[4];
- bool hasSerif, monospaced;
- };
-
- class FreeTypeInterface : public DeletedAtShutdown
- {
- public:
-
- FreeTypeInterface() throw()
- : lastFace (0),
- lastBold (false),
- lastItalic (false)
- {
- if (FT_Init_FreeType (&ftLib) != 0)
- {
- ftLib = 0;
- DBG (T("Failed to initialize FreeType"));
- }
-
- StringArray fontDirs;
- fontDirs.addTokens (String (getenv ("JUCE_FONT_PATH")), T(";,"), 0);
- fontDirs.removeEmptyStrings (true);
-
- if (fontDirs.size() == 0)
- {
- XmlDocument fontsConfig (File ("/etc/fonts/fonts.conf"));
- XmlElement* const fontsInfo = fontsConfig.getDocumentElement();
-
- if (fontsInfo != 0)
- {
- forEachXmlChildElementWithTagName (*fontsInfo, e, T("dir"))
- {
- fontDirs.add (e->getAllSubText().trim());
- }
-
- delete fontsInfo;
- }
- }
-
- if (fontDirs.size() == 0)
- fontDirs.add ("/usr/X11R6/lib/X11/fonts");
-
- for (int i = 0; i < fontDirs.size(); ++i)
- enumerateFaces (fontDirs[i]);
- }
-
- ~FreeTypeInterface() throw()
- {
- if (lastFace != 0)
- FT_Done_Face (lastFace);
-
- if (ftLib != 0)
- FT_Done_FreeType (ftLib);
-
- clearSingletonInstance();
- }
-
- FreeTypeFontFace* findOrCreate (const String& familyName,
- const bool create = false) throw()
- {
- for (int i = 0; i < faces.size(); i++)
- if (faces[i]->getFamilyName() == familyName)
- return faces[i];
-
- if (! create)
- return NULL;
-
- FreeTypeFontFace* newFace = new FreeTypeFontFace (familyName);
- faces.add (newFace);
-
- return newFace;
- }
-
- // Enumerate all font faces available in a given directory
- void enumerateFaces (const String& path) throw()
- {
- File dirPath (path);
- if (path.isEmpty() || ! dirPath.isDirectory())
- return;
-
- DirectoryIterator di (dirPath, true);
-
- while (di.next())
- {
- File possible (di.getFile());
-
- if (possible.hasFileExtension (T("ttf"))
- || possible.hasFileExtension (T("pfb"))
- || possible.hasFileExtension (T("pcf")))
- {
- FT_Face face;
- int faceIndex = 0;
- int numFaces = 0;
-
- do
- {
- if (FT_New_Face (ftLib,
- possible.getFullPathName(),
- faceIndex,
- &face) == 0)
- {
- if (faceIndex == 0)
- numFaces = face->num_faces;
-
- if ((face->face_flags & FT_FACE_FLAG_SCALABLE) != 0)
- {
- FreeTypeFontFace* const newFace = findOrCreate (face->family_name, true);
- int style = (int) FreeTypeFontFace::Plain;
-
- if ((face->style_flags & FT_STYLE_FLAG_BOLD) != 0)
- style |= (int) FreeTypeFontFace::Bold;
-
- if ((face->style_flags & FT_STYLE_FLAG_ITALIC) != 0)
- style |= (int) FreeTypeFontFace::Italic;
-
- newFace->setFileName (possible.getFullPathName(), faceIndex, (FreeTypeFontFace::FontStyle) style);
-
- if ((face->face_flags & FT_FACE_FLAG_FIXED_WIDTH) != 0)
- newFace->setMonospaced (true);
- else
- newFace->setMonospaced (false);
-
- // Surely there must be a better way to do this?
- if (String (face->family_name).containsIgnoreCase (T("Sans"))
- || String (face->family_name).containsIgnoreCase (T("Verdana"))
- || String (face->family_name).containsIgnoreCase (T("Arial")))
- {
- newFace->setSerif (false);
- }
- else
- {
- newFace->setSerif (true);
- }
- }
-
- FT_Done_Face (face);
- }
-
- ++faceIndex;
- }
- while (faceIndex < numFaces);
- }
- }
- }
-
- // Create a FreeType face object for a given font
- FT_Face createFT_Face (const String& fontName,
- const bool bold,
- const bool italic) throw()
- {
- FT_Face face = NULL;
-
- if (fontName == lastFontName && bold == lastBold && italic == lastItalic)
- {
- face = lastFace;
- }
- else
- {
- if (lastFace)
- {
- FT_Done_Face (lastFace);
- lastFace = NULL;
- }
-
- lastFontName = fontName;
- lastBold = bold;
- lastItalic = italic;
-
- FreeTypeFontFace* const ftFace = findOrCreate (fontName);
-
- if (ftFace != 0)
- {
- int style = (int) FreeTypeFontFace::Plain;
-
- if (bold)
- style |= (int) FreeTypeFontFace::Bold;
-
- if (italic)
- style |= (int) FreeTypeFontFace::Italic;
-
- int faceIndex;
- String fileName (ftFace->getFileName (style, &faceIndex));
-
- if (fileName.isEmpty())
- {
- style ^= (int) FreeTypeFontFace::Bold;
-
- fileName = ftFace->getFileName (style, &faceIndex);
-
- if (fileName.isEmpty())
- {
- style ^= (int) FreeTypeFontFace::Bold;
- style ^= (int) FreeTypeFontFace::Italic;
-
- fileName = ftFace->getFileName (style, &faceIndex);
-
- if (! fileName.length())
- {
- style ^= (int) FreeTypeFontFace::Bold;
- fileName = ftFace->getFileName (style, &faceIndex);
- }
- }
- }
-
- if (! FT_New_Face (ftLib, (const char*) fileName, faceIndex, &lastFace))
- {
- face = lastFace;
-
- // If there isn't a unicode charmap then select the first one.
- if (FT_Select_Charmap (face, ft_encoding_unicode))
- FT_Set_Charmap (face, face->charmaps[0]);
- }
- }
- }
- return face;
- }
-
- bool addGlyph (FT_Face face, Typeface& dest, uint32 character) throw()
- {
- const unsigned int glyphIndex = FT_Get_Char_Index (face, character);
- const float height = (float) (face->ascender - face->descender);
- const float scaleX = 1.0f / height;
- const float scaleY = -1.0f / height;
- Path destShape;
-
- #define CONVERTX(val) (scaleX * (val).x)
- #define CONVERTY(val) (scaleY * (val).y)
-
- if (FT_Load_Glyph (face, glyphIndex, FT_LOAD_NO_SCALE
- | FT_LOAD_NO_BITMAP
- | FT_LOAD_IGNORE_TRANSFORM) != 0
- || face->glyph->format != ft_glyph_format_outline)
- {
- return false;
- }
-
- const FT_Outline* const outline = &face->glyph->outline;
- const short* const contours = outline->contours;
- const char* const tags = outline->tags;
- FT_Vector* const points = outline->points;
-
- for (int c = 0; c < outline->n_contours; c++)
- {
- const int startPoint = (c == 0) ? 0 : contours [c - 1] + 1;
- const int endPoint = contours[c];
-
- for (int p = startPoint; p <= endPoint; p++)
- {
- const float x = CONVERTX (points[p]);
- const float y = CONVERTY (points[p]);
-
- if (p == startPoint)
- {
- if (FT_CURVE_TAG (tags[p]) == FT_Curve_Tag_Conic)
- {
- float x2 = CONVERTX (points [endPoint]);
- float y2 = CONVERTY (points [endPoint]);
-
- if (FT_CURVE_TAG (tags[endPoint]) != FT_Curve_Tag_On)
- {
- x2 = (x + x2) * 0.5f;
- y2 = (y + y2) * 0.5f;
- }
-
- destShape.startNewSubPath (x2, y2);
- }
- else
- {
- destShape.startNewSubPath (x, y);
- }
- }
-
- if (FT_CURVE_TAG (tags[p]) == FT_Curve_Tag_On)
- {
- if (p != startPoint)
- destShape.lineTo (x, y);
- }
- else if (FT_CURVE_TAG (tags[p]) == FT_Curve_Tag_Conic)
- {
- const int nextIndex = (p == endPoint) ? startPoint : p + 1;
- float x2 = CONVERTX (points [nextIndex]);
- float y2 = CONVERTY (points [nextIndex]);
-
- if (FT_CURVE_TAG (tags [nextIndex]) == FT_Curve_Tag_Conic)
- {
- x2 = (x + x2) * 0.5f;
- y2 = (y + y2) * 0.5f;
- }
- else
- {
- ++p;
- }
-
- destShape.quadraticTo (x, y, x2, y2);
- }
- else if (FT_CURVE_TAG (tags[p]) == FT_Curve_Tag_Cubic)
- {
- if (p >= endPoint)
- return false;
-
- const int next1 = p + 1;
- const int next2 = (p == (endPoint - 1)) ? startPoint : p + 2;
-
- const float x2 = CONVERTX (points [next1]);
- const float y2 = CONVERTY (points [next1]);
- const float x3 = CONVERTX (points [next2]);
- const float y3 = CONVERTY (points [next2]);
-
- if (FT_CURVE_TAG (tags[next1]) != FT_Curve_Tag_Cubic
- || FT_CURVE_TAG (tags[next2]) != FT_Curve_Tag_On)
- return false;
-
- destShape.cubicTo (x, y, x2, y2, x3, y3);
- p += 2;
- }
- }
-
- destShape.closeSubPath();
- }
-
- dest.addGlyph (character, destShape, face->glyph->metrics.horiAdvance/height);
-
- if ((face->face_flags & FT_FACE_FLAG_KERNING) != 0)
- addKerning (face, dest, character, glyphIndex);
-
- return true;
- }
-
- void addKerning (FT_Face face, Typeface& dest, const uint32 character, const uint32 glyphIndex) throw()
- {
- const float height = (float) (face->ascender - face->descender);
-
- uint32 rightGlyphIndex;
- uint32 rightCharCode = FT_Get_First_Char (face, &rightGlyphIndex);
-
- while (rightGlyphIndex != 0)
- {
- FT_Vector kerning;
-
- if (FT_Get_Kerning (face, glyphIndex, rightGlyphIndex, ft_kerning_unscaled, &kerning) == 0)
- {
- if (kerning.x != 0)
- dest.addKerningPair (character, rightCharCode, kerning.x / height);
- }
-
- rightCharCode = FT_Get_Next_Char (face, rightCharCode, &rightGlyphIndex);
- }
- }
-
- // Add a glyph to a font
- bool addGlyphToFont (const uint32 character,
- const tchar* fontName, bool bold, bool italic,
- Typeface& dest) throw()
- {
- FT_Face face = createFT_Face (fontName, bold, italic);
-
- if (face != 0)
- return addGlyph (face, dest, character);
-
- return false;
- }
-
- // Create a Typeface object for given name/style
- bool createTypeface (const String& fontName,
- const bool bold, const bool italic,
- Typeface& dest,
- const bool addAllGlyphs) throw()
- {
- dest.clear();
- dest.setName (fontName);
- dest.setBold (bold);
- dest.setItalic (italic);
-
- FT_Face face = createFT_Face (fontName, bold, italic);
-
- if (face == 0)
- {
- #ifdef JUCE_DEBUG
- String msg (T("Failed to create typeface: "));
- msg << fontName << " " << (bold ? 'B' : ' ') << (italic ? 'I' : ' ');
- DBG (msg);
- #endif
- return face;
- }
-
- const float height = (float) (face->ascender - face->descender);
-
- dest.setAscent (face->ascender / height);
- dest.setDefaultCharacter (L' ');
-
- if (addAllGlyphs)
- {
- uint32 glyphIndex;
- uint32 charCode = FT_Get_First_Char (face, &glyphIndex);
-
- while (glyphIndex != 0)
- {
- addGlyph (face, dest, charCode);
- charCode = FT_Get_Next_Char (face, charCode, &glyphIndex);
- }
- }
-
- return true;
- }
-
- void getFamilyNames (StringArray& familyNames) const throw()
- {
- for (int i = 0; i < faces.size(); i++)
- familyNames.add (faces[i]->getFamilyName());
- }
-
- void getMonospacedNames (StringArray& monoSpaced) const throw()
- {
- for (int i = 0; i < faces.size(); i++)
- if (faces[i]->getMonospaced())
- monoSpaced.add (faces[i]->getFamilyName());
- }
-
- void getSerifNames (StringArray& serif) const throw()
- {
- for (int i = 0; i < faces.size(); i++)
- if (faces[i]->getSerif())
- serif.add (faces[i]->getFamilyName());
- }
-
- void getSansSerifNames (StringArray& sansSerif) const throw()
- {
- for (int i = 0; i < faces.size(); i++)
- if (! faces[i]->getSerif())
- sansSerif.add (faces[i]->getFamilyName());
- }
-
- juce_DeclareSingleton_SingleThreaded_Minimal (FreeTypeInterface)
-
- private:
-
- FT_Library ftLib;
- FT_Face lastFace;
- String lastFontName;
- bool lastBold, lastItalic;
- OwnedArray<FreeTypeFontFace> faces;
- };
-
- juce_ImplementSingleton_SingleThreaded (FreeTypeInterface)
-
- void Typeface::initialiseTypefaceCharacteristics (const String& fontName,
- bool bold, bool italic,
- bool addAllGlyphsToFont) throw()
- {
- FreeTypeInterface::getInstance()
- ->createTypeface (fontName, bold, italic, *this, addAllGlyphsToFont);
- }
-
- bool Typeface::findAndAddSystemGlyph (juce_wchar character) throw()
- {
- return FreeTypeInterface::getInstance()
- ->addGlyphToFont (character, getName(), isBold(), isItalic(), *this);
- }
-
- const StringArray Font::findAllTypefaceNames() throw()
- {
- StringArray s;
- FreeTypeInterface::getInstance()->getFamilyNames (s);
- s.sort (true);
- return s;
- }
-
- static const String pickBestFont (const StringArray& names,
- const char* const choicesString)
- {
- StringArray choices;
- choices.addTokens (String (choicesString), T(","), 0);
- choices.trim();
- choices.removeEmptyStrings();
-
- int i, j;
- for (j = 0; j < choices.size(); ++j)
- if (names.contains (choices[j], true))
- return choices[j];
-
- for (j = 0; j < choices.size(); ++j)
- for (i = 0; i < names.size(); i++)
- if (names[i].startsWithIgnoreCase (choices[j]))
- return names[i];
-
- for (j = 0; j < choices.size(); ++j)
- for (i = 0; i < names.size(); i++)
- if (names[i].containsIgnoreCase (choices[j]))
- return names[i];
-
- return names[0];
- }
-
- static const String linux_getDefaultSansSerifFontName()
- {
- StringArray allFonts;
- FreeTypeInterface::getInstance()->getSansSerifNames (allFonts);
-
- return pickBestFont (allFonts, "Verdana, Bitstream Vera Sans, Luxi Sans, Sans");
- }
-
- static const String linux_getDefaultSerifFontName()
- {
- StringArray allFonts;
- FreeTypeInterface::getInstance()->getSerifNames (allFonts);
-
- return pickBestFont (allFonts, "Bitstream Vera Serif, Times, Nimbus Roman, Serif");
- }
-
- static const String linux_getDefaultMonospacedFontName()
- {
- StringArray allFonts;
- FreeTypeInterface::getInstance()->getMonospacedNames (allFonts);
-
- return pickBestFont (allFonts, "Bitstream Vera Sans Mono, Courier, Sans Mono, Mono");
- }
-
- void Font::getDefaultFontNames (String& defaultSans, String& defaultSerif, String& defaultFixed) throw()
- {
- defaultSans = linux_getDefaultSansSerifFontName();
- defaultSerif = linux_getDefaultSerifFontName();
- defaultFixed = linux_getDefaultMonospacedFontName();
- }
-
- END_JUCE_NAMESPACE
-
- #endif
- /********* End of inlined file: juce_linux_Fonts.cpp *********/
-
- /********* Start of inlined file: juce_linux_Messaging.cpp *********/
-
- #if JUCE_BUILD_GUI_CLASSES
-
- #include <stdio.h>
- #include <signal.h>
- #include <X11/Xlib.h>
- #include <X11/Xatom.h>
- #include <X11/Xresource.h>
- #include <X11/Xutil.h>
-
- BEGIN_JUCE_NAMESPACE
-
- #ifdef JUCE_DEBUG
- #define JUCE_DEBUG_XERRORS 1
- #endif
-
- Display* display = 0; // This is also referenced from WindowDriver.cpp
- static Window juce_messageWindowHandle = None;
-
- #define SpecialAtom "JUCESpecialAtom"
- #define BroadcastAtom "JUCEBroadcastAtom"
- #define SpecialCallbackAtom "JUCESpecialCallbackAtom"
-
- static Atom specialId;
- static Atom broadcastId;
- static Atom specialCallbackId;
-
- // This is referenced from WindowDriver.cpp
- XContext improbableNumber;
-
- // Defined in WindowDriver.cpp
- extern void juce_windowMessageReceive (XEvent* event);
-
- struct MessageThreadFuncCall
- {
- MessageCallbackFunction* func;
- void* parameter;
- void* result;
- CriticalSection lock;
- WaitableEvent event;
- };
-
- static bool errorCondition = false;
- static XErrorHandler oldErrorHandler = (XErrorHandler) 0;
- static XIOErrorHandler oldIOErrorHandler = (XIOErrorHandler) 0;
-
- // (defined in another file to avoid problems including certain headers in this one)
- extern bool juce_isRunningAsApplication();
-
- // Usually happens when client-server connection is broken
- static int ioErrorHandler (Display* display)
- {
- DBG (T("ERROR: connection to X server broken.. terminating."));
-
- errorCondition = true;
-
- if (juce_isRunningAsApplication())
- Process::terminate();
-
- return 0;
- }
-
- // A protocol error has occurred
- static int errorHandler (Display* display, XErrorEvent* event)
- {
- #ifdef JUCE_DEBUG_XERRORS
- char errorStr[64] = { 0 };
- char requestStr[64] = { 0 };
-
- XGetErrorText (display, event->error_code, errorStr, 64);
-
- XGetErrorDatabaseText (display,
- "XRequest",
- (const char*) String (event->request_code),
- "Unknown",
- requestStr,
- 64);
-
- DBG (T("ERROR: X returned ") + String (errorStr) + T(" for operation ") + String (requestStr));
- #endif
-
- return 0;
- }
-
- static bool breakIn = false;
-
- // Breakin from keyboard
- static void sig_handler (int sig)
- {
- if (sig == SIGINT)
- {
- breakIn = true;
- return;
- }
-
- static bool reentrant = false;
-
- if (reentrant == false)
- {
- reentrant = true;
-
- // Illegal instruction
- fflush (stdout);
- Logger::outputDebugString ("ERROR: Program executed illegal instruction.. terminating");
-
- errorCondition = true;
-
- if (juce_isRunningAsApplication())
- Process::terminate();
- }
- else
- {
- if (juce_isRunningAsApplication())
- exit(0);
- }
- }
-
- void MessageManager::doPlatformSpecificInitialisation()
- {
- // Initialise xlib for multiple thread support
- static bool initThreadCalled = false;
-
- if (! initThreadCalled)
- {
- if (! XInitThreads())
- {
- // This is fatal! Print error and closedown
- Logger::outputDebugString ("Failed to initialise xlib thread support.");
-
- if (juce_isRunningAsApplication())
- Process::terminate();
-
- return;
- }
-
- initThreadCalled = true;
- }
-
- // This is called if the client/server connection is broken
- oldIOErrorHandler = XSetIOErrorHandler (ioErrorHandler);
-
- // This is called if a protocol error occurs
- oldErrorHandler = XSetErrorHandler (errorHandler);
-
- // Install signal handler for break-in
- struct sigaction saction;
- sigset_t maskSet;
- sigemptyset (&maskSet);
- saction.sa_handler = sig_handler;
- saction.sa_mask = maskSet;
- saction.sa_flags = 0;
- sigaction (SIGINT, &saction, NULL);
-
- #ifndef _DEBUG
- // Setup signal handlers for various fatal errors
- sigaction (SIGILL, &saction, NULL);
- sigaction (SIGBUS, &saction, NULL);
- sigaction (SIGFPE, &saction, NULL);
- sigaction (SIGSEGV, &saction, NULL);
- sigaction (SIGSYS, &saction, NULL);
- #endif
-
- String displayName (getenv ("DISPLAY"));
- if (displayName.isEmpty())
- displayName = T(":0.0");
-
- display = XOpenDisplay (displayName);
-
- if (display == 0)
- {
- // This is fatal! Print error and closedown
- Logger::outputDebugString ("Failed to open the X display.");
-
- if (juce_isRunningAsApplication())
- Process::terminate();
-
- return;
- }
-
- // Get defaults for various properties
- int screen = DefaultScreen (display);
- Window root = RootWindow (display, screen);
- Visual* visual = DefaultVisual (display, screen);
-
- // Create atoms for our ClientMessages (these cannot be deleted)
- specialId = XInternAtom (display, SpecialAtom, false);
- broadcastId = XInternAtom (display, BroadcastAtom, false);
- specialCallbackId = XInternAtom (display, SpecialCallbackAtom, false);
-
- // Create a context to store user data associated with Windows we
- // create in WindowDriver
- improbableNumber = XUniqueContext();
-
- // We're only interested in client messages for this window
- // which are always sent
- XSetWindowAttributes swa;
- swa.event_mask = NoEventMask;
-
- // Create our message window (this will never be mapped)
- juce_messageWindowHandle = XCreateWindow (display, root,
- 0, 0, 1, 1, 0, 0, InputOnly,
- visual, CWEventMask, &swa);
- }
-
- void MessageManager::doPlatformSpecificShutdown()
- {
- if (errorCondition == false)
- {
- XDestroyWindow (display, juce_messageWindowHandle);
- XCloseDisplay (display);
-
- // reset pointers
- juce_messageWindowHandle = 0;
- display = 0;
-
- // Restore original error handlers
- XSetIOErrorHandler (oldIOErrorHandler);
- oldIOErrorHandler = 0;
- XSetErrorHandler (oldErrorHandler);
- oldErrorHandler = 0;
- }
- }
-
- bool juce_postMessageToSystemQueue (void* message)
- {
- if (errorCondition)
- return false;
-
- XClientMessageEvent clientMsg;
- clientMsg.display = display;
- clientMsg.window = juce_messageWindowHandle;
- clientMsg.type = ClientMessage;
- clientMsg.format = 32;
- clientMsg.message_type = specialId;
- #if JUCE_64BIT
- clientMsg.data.l[0] = (long) (0x00000000ffffffff & (((uint64) message) >> 32));
- clientMsg.data.l[1] = (long) (0x00000000ffffffff & (long) message);
- #else
- clientMsg.data.l[0] = (long) message;
- #endif
-
- XSendEvent (display, juce_messageWindowHandle, false,
- NoEventMask, (XEvent*) &clientMsg);
-
- XFlush (display); // This is necessary to ensure the event is delivered
-
- return true;
- }
-
- void MessageManager::broadcastMessage (const String& value) throw()
- {
- }
-
- void* MessageManager::callFunctionOnMessageThread (MessageCallbackFunction* func,
- void* parameter)
- {
- void* retVal = 0;
-
- if (! errorCondition)
- {
- if (! isThisTheMessageThread())
- {
- static MessageThreadFuncCall messageFuncCallContext;
-
- const ScopedLock sl (messageFuncCallContext.lock);
-
- XClientMessageEvent clientMsg;
- clientMsg.display = display;
- clientMsg.window = juce_messageWindowHandle;
- clientMsg.type = ClientMessage;
- clientMsg.format = 32;
- clientMsg.message_type = specialCallbackId;
- #if JUCE_64BIT
- clientMsg.data.l[0] = (long) (0x00000000ffffffff & (((uint64) &messageFuncCallContext) >> 32));
- clientMsg.data.l[1] = (long) (0x00000000ffffffff & (uint64) &messageFuncCallContext);
- #else
- clientMsg.data.l[0] = (long) &messageFuncCallContext;
- #endif
-
- messageFuncCallContext.func = func;
- messageFuncCallContext.parameter = parameter;
-
- if (XSendEvent (display, juce_messageWindowHandle, false, NoEventMask, (XEvent*) &clientMsg) == 0)
- return 0;
-
- XFlush (display); // This is necessary to ensure the event is delivered
-
- // Wait for it to complete before continuing
- messageFuncCallContext.event.wait();
-
- retVal = messageFuncCallContext.result;
- }
- else
- {
- // Just call the function directly
- retVal = func (parameter);
- }
- }
-
- return retVal;
- }
-
- bool juce_dispatchNextMessageOnSystemQueue (bool returnIfNoPendingMessages)
- {
- if (errorCondition)
- return false;
-
- if (breakIn)
- {
- errorCondition = true;
-
- if (juce_isRunningAsApplication())
- Process::terminate();
-
- return false;
- }
-
- if (returnIfNoPendingMessages && ! XPending (display))
- return false;
-
- XEvent evt;
- XNextEvent (display, &evt);
-
- if (evt.type == ClientMessage && evt.xany.window == juce_messageWindowHandle)
- {
- XClientMessageEvent* const clientMsg = (XClientMessageEvent*) &evt;
-
- if (clientMsg->format != 32)
- {
- jassertfalse
- DBG ("Error: juce_dispatchNextMessageOnSystemQueue received malformed client message.");
- }
- else
- {
- JUCE_TRY
- {
- #if JUCE_64BIT
- void* const messagePtr
- = (void*) ((0xffffffff00000000 & (((uint64) clientMsg->data.l[0]) << 32))
- | (clientMsg->data.l[1] & 0x00000000ffffffff));
- #else
- void* const messagePtr = (void*) (clientMsg->data.l[0]);
- #endif
-
- if (clientMsg->message_type == specialId)
- {
- MessageManager::getInstance()->deliverMessage (messagePtr);
- }
- else if (clientMsg->message_type == specialCallbackId)
- {
- MessageThreadFuncCall* const call = (MessageThreadFuncCall*) messagePtr;
- MessageCallbackFunction* func = call->func;
- call->result = (*func) (call->parameter);
- call->event.signal();
- }
- else if (clientMsg->message_type == broadcastId)
- {
- #if 0
- TCHAR buffer[8192];
- zeromem (buffer, sizeof (buffer));
-
- if (GlobalGetAtomName ((ATOM) lParam, buffer, 8192) != 0)
- mq->deliverBroadcastMessage (String (buffer));
- #endif
- }
- else
- {
- DBG ("Error: juce_dispatchNextMessageOnSystemQueue received unknown client message.");
- }
- }
- JUCE_CATCH_ALL
- }
- }
- else if (evt.xany.window != juce_messageWindowHandle)
- {
- juce_windowMessageReceive (&evt);
- }
-
- return true;
- }
-
- END_JUCE_NAMESPACE
-
- #endif
- /********* End of inlined file: juce_linux_Messaging.cpp *********/
-
- /********* Start of inlined file: juce_linux_Midi.cpp *********/
-
- #if JUCE_BUILD_GUI_CLASSES
-
- #if JUCE_ALSA
-
- #include <alsa/asoundlib.h>
-
- BEGIN_JUCE_NAMESPACE
-
- static snd_seq_t* iterateDevices (const bool forInput,
- StringArray& deviceNamesFound,
- const int deviceIndexToOpen)
- {
- snd_seq_t* returnedHandle = 0;
- snd_seq_t* seqHandle;
-
- if (snd_seq_open (&seqHandle, "default", forInput ? SND_SEQ_OPEN_INPUT
- : SND_SEQ_OPEN_OUTPUT, 0) == 0)
- {
- snd_seq_system_info_t* systemInfo;
- snd_seq_client_info_t* clientInfo;
-
- if (snd_seq_system_info_malloc (&systemInfo) == 0)
- {
- if (snd_seq_system_info (seqHandle, systemInfo) == 0
- && snd_seq_client_info_malloc (&clientInfo) == 0)
- {
- int numClients = snd_seq_system_info_get_cur_clients (systemInfo);
-
- while (--numClients >= 0 && returnedHandle == 0)
- {
- if (snd_seq_query_next_client (seqHandle, clientInfo) == 0)
- {
- snd_seq_port_info_t* portInfo;
- if (snd_seq_port_info_malloc (&portInfo) == 0)
- {
- int numPorts = snd_seq_client_info_get_num_ports (clientInfo);
- const int client = snd_seq_client_info_get_client (clientInfo);
-
- snd_seq_port_info_set_client (portInfo, client);
- snd_seq_port_info_set_port (portInfo, -1);
-
- while (--numPorts >= 0)
- {
- if (snd_seq_query_next_port (seqHandle, portInfo) == 0
- && (snd_seq_port_info_get_capability (portInfo)
- & (forInput ? SND_SEQ_PORT_CAP_READ
- : SND_SEQ_PORT_CAP_WRITE)) != 0)
- {
- deviceNamesFound.add (snd_seq_client_info_get_name (clientInfo));
-
- if (deviceNamesFound.size() == deviceIndexToOpen + 1)
- {
- const int sourcePort = snd_seq_port_info_get_port (portInfo);
- const int sourceClient = snd_seq_client_info_get_client (clientInfo);
-
- if (sourcePort != -1)
- {
- snd_seq_set_client_name (seqHandle,
- forInput ? "Juce Midi Input"
- : "Juce Midi Output");
-
- const int portId
- = snd_seq_create_simple_port (seqHandle,
- forInput ? "Juce Midi In Port"
- : "Juce Midi Out Port",
- forInput ? (SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE)
- : (SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ),
- SND_SEQ_PORT_TYPE_MIDI_GENERIC);
-
- snd_seq_connect_from (seqHandle, portId, sourceClient, sourcePort);
-
- returnedHandle = seqHandle;
- break;
- }
- }
- }
- }
-
- snd_seq_port_info_free (portInfo);
- }
- }
- }
-
- snd_seq_client_info_free (clientInfo);
- }
-
- snd_seq_system_info_free (systemInfo);
- }
-
- if (returnedHandle == 0)
- snd_seq_close (seqHandle);
- }
-
- deviceNamesFound.appendNumbersToDuplicates (true, true);
-
- return returnedHandle;
- }
-
- static snd_seq_t* createDevice (const bool forInput,
- const String& deviceNameToOpen)
- {
- snd_seq_t* seqHandle = 0;
-
- if (snd_seq_open (&seqHandle, "default", forInput ? SND_SEQ_OPEN_INPUT
- : SND_SEQ_OPEN_OUTPUT, 0) == 0)
- {
- snd_seq_set_client_name (seqHandle,
- (const char*) (forInput ? (deviceNameToOpen + T(" Input"))
- : (deviceNameToOpen + T(" Output"))));
-
- const int portId
- = snd_seq_create_simple_port (seqHandle,
- forInput ? "in"
- : "out",
- forInput ? (SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE)
- : (SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ),
- forInput ? SND_SEQ_PORT_TYPE_APPLICATION
- : SND_SEQ_PORT_TYPE_MIDI_GENERIC);
-
- if (portId < 0)
- {
- snd_seq_close (seqHandle);
- seqHandle = 0;
- }
- }
-
- return seqHandle;
- }
-
- class MidiOutputDevice
- {
- public:
- MidiOutputDevice (MidiOutput* const midiOutput_,
- snd_seq_t* const seqHandle_)
- :
- midiOutput (midiOutput_),
- seqHandle (seqHandle_),
- maxEventSize (16 * 1024)
- {
- jassert (seqHandle != 0 && midiOutput != 0);
- snd_midi_event_new (maxEventSize, &midiParser);
- }
-
- ~MidiOutputDevice()
- {
- snd_midi_event_free (midiParser);
- snd_seq_close (seqHandle);
- }
-
- void sendMessageNow (const MidiMessage& message)
- {
- if (message.getRawDataSize() > maxEventSize)
- {
- maxEventSize = message.getRawDataSize();
- snd_midi_event_free (midiParser);
- snd_midi_event_new (maxEventSize, &midiParser);
- }
-
- snd_seq_event_t event;
- snd_seq_ev_clear (&event);
-
- snd_midi_event_encode (midiParser,
- message.getRawData(),
- message.getRawDataSize(),
- &event);
-
- snd_midi_event_reset_encode (midiParser);
-
- snd_seq_ev_set_source (&event, 0);
- snd_seq_ev_set_subs (&event);
- snd_seq_ev_set_direct (&event);
-
- snd_seq_event_output_direct (seqHandle, &event);
- }
-
- juce_UseDebuggingNewOperator
-
- private:
- MidiOutput* const midiOutput;
- snd_seq_t* const seqHandle;
- snd_midi_event_t* midiParser;
- int maxEventSize;
- };
-
- const StringArray MidiOutput::getDevices()
- {
- StringArray devices;
- iterateDevices (false, devices, -1);
- return devices;
- }
-
- int MidiOutput::getDefaultDeviceIndex()
- {
- return 0;
- }
-
- MidiOutput* MidiOutput::openDevice (int deviceIndex)
- {
- MidiOutput* newDevice = 0;
-
- StringArray devices;
- snd_seq_t* const handle = iterateDevices (false, devices, deviceIndex);
-
- if (handle != 0)
- {
- newDevice = new MidiOutput();
- newDevice->internal = new MidiOutputDevice (newDevice, handle);
- }
-
- return newDevice;
- }
-
- MidiOutput* MidiOutput::createNewDevice (const String& deviceName)
- {
- MidiOutput* newDevice = 0;
-
- snd_seq_t* const handle = createDevice (false, deviceName);
-
- if (handle != 0)
- {
- newDevice = new MidiOutput();
- newDevice->internal = new MidiOutputDevice (newDevice, handle);
- }
-
- return newDevice;
- }
-
- MidiOutput::~MidiOutput()
- {
- MidiOutputDevice* const device = (MidiOutputDevice*) internal;
- delete device;
- }
-
- void MidiOutput::reset()
- {
- }
-
- bool MidiOutput::getVolume (float& leftVol, float& rightVol)
- {
- return false;
- }
-
- void MidiOutput::setVolume (float leftVol, float rightVol)
- {
- }
-
- void MidiOutput::sendMessageNow (const MidiMessage& message)
- {
- ((MidiOutputDevice*) internal)->sendMessageNow (message);
- }
-
- class MidiInputThread : public Thread
- {
- public:
- MidiInputThread (MidiInput* const midiInput_,
- snd_seq_t* const seqHandle_,
- MidiInputCallback* const callback_)
- : Thread (T("Juce MIDI Input")),
- midiInput (midiInput_),
- seqHandle (seqHandle_),
- callback (callback_)
- {
- jassert (seqHandle != 0 && callback != 0 && midiInput != 0);
- }
-
- ~MidiInputThread()
- {
- snd_seq_close (seqHandle);
- }
-
- void run()
- {
- const int maxEventSize = 16 * 1024;
- snd_midi_event_t* midiParser;
-
- if (snd_midi_event_new (maxEventSize, &midiParser) >= 0)
- {
- uint8* const buffer = (uint8*) juce_malloc (maxEventSize);
-
- const int numPfds = snd_seq_poll_descriptors_count (seqHandle, POLLIN);
- struct pollfd* const pfd = (struct pollfd*) alloca (numPfds * sizeof (struct pollfd));
-
- snd_seq_poll_descriptors (seqHandle, pfd, numPfds, POLLIN);
-
- while (! threadShouldExit())
- {
- if (poll (pfd, numPfds, 500) > 0)
- {
- snd_seq_event_t* inputEvent = 0;
-
- snd_seq_nonblock (seqHandle, 1);
-
- do
- {
- if (snd_seq_event_input (seqHandle, &inputEvent) >= 0)
- {
- // xxx what about SYSEXes that are too big for the buffer?
- const int numBytes = snd_midi_event_decode (midiParser, buffer, maxEventSize, inputEvent);
-
- snd_midi_event_reset_decode (midiParser);
-
- if (numBytes > 0)
- {
- const MidiMessage message ((const uint8*) buffer,
- numBytes,
- Time::getMillisecondCounter() * 0.001);
-
- callback->handleIncomingMidiMessage (midiInput, message);
- }
-
- snd_seq_free_event (inputEvent);
- }
- }
- while (snd_seq_event_input_pending (seqHandle, 0) > 0);
-
- snd_seq_free_event (inputEvent);
- }
- }
-
- snd_midi_event_free (midiParser);
- juce_free (buffer);
- }
- };
-
- juce_UseDebuggingNewOperator
-
- private:
- MidiInput* const midiInput;
- snd_seq_t* const seqHandle;
- MidiInputCallback* const callback;
- };
-
- MidiInput::MidiInput (const String& name_)
- : name (name_),
- internal (0)
- {
- }
-
- MidiInput::~MidiInput()
- {
- stop();
- MidiInputThread* const thread = (MidiInputThread*) internal;
- delete thread;
- }
-
- void MidiInput::start()
- {
- ((MidiInputThread*) internal)->startThread();
- }
-
- void MidiInput::stop()
- {
- ((MidiInputThread*) internal)->stopThread (3000);
- }
-
- int MidiInput::getDefaultDeviceIndex()
- {
- return 0;
- }
-
- const StringArray MidiInput::getDevices()
- {
- StringArray devices;
- iterateDevices (true, devices, -1);
- return devices;
- }
-
- MidiInput* MidiInput::openDevice (int deviceIndex, MidiInputCallback* callback)
- {
- MidiInput* newDevice = 0;
-
- StringArray devices;
- snd_seq_t* const handle = iterateDevices (true, devices, deviceIndex);
-
- if (handle != 0)
- {
- newDevice = new MidiInput (devices [deviceIndex]);
- newDevice->internal = new MidiInputThread (newDevice, handle, callback);
- }
-
- return newDevice;
- }
-
- MidiInput* MidiInput::createNewDevice (const String& deviceName, MidiInputCallback* callback)
- {
- MidiInput* newDevice = 0;
-
- snd_seq_t* const handle = createDevice (true, deviceName);
-
- if (handle != 0)
- {
- newDevice = new MidiInput (deviceName);
- newDevice->internal = new MidiInputThread (newDevice, handle, callback);
- }
-
- return newDevice;
- }
-
- END_JUCE_NAMESPACE
-
- #else
-
- // (These are just stub functions if ALSA is unavailable...)
-
- BEGIN_JUCE_NAMESPACE
-
- const StringArray MidiOutput::getDevices() { return StringArray(); }
- int MidiOutput::getDefaultDeviceIndex() { return 0; }
- MidiOutput* MidiOutput::openDevice (int) { return 0; }
- MidiOutput* MidiOutput::createNewDevice (const String&) { return 0; }
- MidiOutput::~MidiOutput() {}
- void MidiOutput::reset() {}
- bool MidiOutput::getVolume (float&, float&) { return false; }
- void MidiOutput::setVolume (float, float) {}
- void MidiOutput::sendMessageNow (const MidiMessage&) {}
-
- MidiInput::MidiInput (const String& name_)
- : name (name_),
- internal (0)
- {}
-
- MidiInput::~MidiInput() {}
- void MidiInput::start() {}
- void MidiInput::stop() {}
- int MidiInput::getDefaultDeviceIndex() { return 0; }
- const StringArray MidiInput::getDevices() { return StringArray(); }
- MidiInput* MidiInput::openDevice (int, MidiInputCallback*) { return 0; }
- MidiInput* MidiInput::createNewDevice (const String&, MidiInputCallback*) { return 0; }
-
- END_JUCE_NAMESPACE
-
- #endif
-
- #endif
- /********* End of inlined file: juce_linux_Midi.cpp *********/
-
- /********* Start of inlined file: juce_linux_WebBrowserComponent.cpp *********/
-
- BEGIN_JUCE_NAMESPACE
-
- /*
- Sorry.. This class isn't implemented on Linux!
- */
-
- WebBrowserComponent::WebBrowserComponent()
- : browser (0),
- blankPageShown (false)
- {
- setOpaque (true);
- }
-
- WebBrowserComponent::~WebBrowserComponent()
- {
- }
-
- void WebBrowserComponent::goToURL (const String& url,
- const StringArray* headers,
- const MemoryBlock* postData)
- {
- lastURL = url;
-
- lastHeaders.clear();
- if (headers != 0)
- lastHeaders = *headers;
-
- lastPostData.setSize (0);
- if (postData != 0)
- lastPostData = *postData;
-
- blankPageShown = false;
-
- }
-
- void WebBrowserComponent::stop()
- {
- }
-
- void WebBrowserComponent::goBack()
- {
- lastURL = String::empty;
- blankPageShown = false;
-
- }
-
- void WebBrowserComponent::goForward()
- {
- lastURL = String::empty;
-
- }
-
- void WebBrowserComponent::paint (Graphics& g)
- {
- g.fillAll (Colours::white);
- }
-
- void WebBrowserComponent::checkWindowAssociation()
- {
- }
-
- void WebBrowserComponent::reloadLastURL()
- {
- if (lastURL.isNotEmpty())
- {
- goToURL (lastURL, &lastHeaders, &lastPostData);
- lastURL = String::empty;
- }
- }
-
- void WebBrowserComponent::parentHierarchyChanged()
- {
- checkWindowAssociation();
- }
-
- void WebBrowserComponent::moved()
- {
- }
-
- void WebBrowserComponent::resized()
- {
- }
-
- void WebBrowserComponent::visibilityChanged()
- {
- checkWindowAssociation();
- }
-
- bool WebBrowserComponent::pageAboutToLoad (const String& url)
- {
- return true;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_linux_WebBrowserComponent.cpp *********/
-
- /********* Start of inlined file: juce_linux_Windowing.cpp *********/
-
- #if JUCE_BUILD_GUI_CLASSES
-
- #include <X11/Xlib.h>
- #include <X11/Xutil.h>
- #include <X11/Xatom.h>
- #include <X11/Xmd.h>
- #include <X11/keysym.h>
- #include <X11/cursorfont.h>
- #include <dlfcn.h>
-
- #if JUCE_USE_XINERAMA
- /* If you're trying to use Xinerama, you'll need to install the "libxinerama-dev" package..
- */
- #include <X11/extensions/Xinerama.h>
- #endif
-
- #if JUCE_USE_XSHM
- #include <X11/extensions/XShm.h>
- #include <sys/shm.h>
- #include <sys/ipc.h>
- #endif
-
- #if JUCE_OPENGL
- /* Got an include error here?
-
- If you want to install OpenGL support, the packages to get are "mesa-common-dev"
- and "freeglut3-dev".
-
- Alternatively, you can turn off the JUCE_OPENGL flag in juce_Config.h if you
- want to disable it.
- */
- #include <GL/glx.h>
- #endif
-
- #undef KeyPress
-
- BEGIN_JUCE_NAMESPACE
-
- #define TAKE_FOCUS 0
- #define DELETE_WINDOW 1
-
- #define SYSTEM_TRAY_REQUEST_DOCK 0
- #define SYSTEM_TRAY_BEGIN_MESSAGE 1
- #define SYSTEM_TRAY_CANCEL_MESSAGE 2
-
- static const int repaintTimerPeriod = 1000 / 100; // 100 fps maximum
-
- static Atom wm_ChangeState = None;
- static Atom wm_State = None;
- static Atom wm_Protocols = None;
- static Atom wm_ProtocolList [2] = { None, None };
- static Atom wm_ActiveWin = None;
-
- #define ourDndVersion 3
- static Atom XA_XdndAware = None;
- static Atom XA_XdndEnter = None;
- static Atom XA_XdndLeave = None;
- static Atom XA_XdndPosition = None;
- static Atom XA_XdndStatus = None;
- static Atom XA_XdndDrop = None;
- static Atom XA_XdndFinished = None;
- static Atom XA_XdndSelection = None;
- static Atom XA_XdndProxy = None;
-
- static Atom XA_XdndTypeList = None;
- static Atom XA_XdndActionList = None;
- static Atom XA_XdndActionDescription = None;
- static Atom XA_XdndActionCopy = None;
- static Atom XA_XdndActionMove = None;
- static Atom XA_XdndActionLink = None;
- static Atom XA_XdndActionAsk = None;
- static Atom XA_XdndActionPrivate = None;
- static Atom XA_JXSelectionWindowProperty = None;
-
- static Atom XA_MimeTextPlain = None;
- static Atom XA_MimeTextUriList = None;
- static Atom XA_MimeRootDrop = None;
-
- static XErrorHandler oldHandler = 0;
- static int trappedErrorCode = 0;
-
- extern "C" int errorTrapHandler (Display* dpy, XErrorEvent* err)
- {
- trappedErrorCode = err->error_code;
- return 0;
- }
-
- static void trapErrors()
- {
- trappedErrorCode = 0;
- oldHandler = XSetErrorHandler (errorTrapHandler);
- }
-
- static bool untrapErrors()
- {
- XSetErrorHandler (oldHandler);
- return (trappedErrorCode == 0);
- }
-
- static bool isActiveApplication = false;
-
- bool Process::isForegroundProcess() throw()
- {
- return isActiveApplication;
- }
-
- // (used in the messaging code, declared here for build reasons)
- bool juce_isRunningAsApplication()
- {
- return JUCEApplication::getInstance() != 0;
- }
-
- // These are defined in juce_linux_Messaging.cpp
- extern Display* display;
- extern XContext improbableNumber;
-
- static const int eventMask = NoEventMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask
- | EnterWindowMask | LeaveWindowMask | PointerMotionMask | KeymapStateMask
- | ExposureMask | StructureNotifyMask | FocusChangeMask;
-
- static int pointerMap[5];
- static int lastMousePosX = 0, lastMousePosY = 0;
-
- enum MouseButtons
- {
- NoButton = 0,
- LeftButton = 1,
- MiddleButton = 2,
- RightButton = 3,
- WheelUp = 4,
- WheelDown = 5
- };
-
- static void getMousePos (int& x, int& y, int& mouseMods) throw()
- {
- Window root, child;
- int winx, winy;
- unsigned int mask;
-
- mouseMods = 0;
-
- if (XQueryPointer (display,
- RootWindow (display, DefaultScreen (display)),
- &root, &child,
- &x, &y, &winx, &winy, &mask) == False)
- {
- // Pointer not on the default screen
- x = y = -1;
- }
- else
- {
- if ((mask & Button1Mask) != 0)
- mouseMods |= ModifierKeys::leftButtonModifier;
-
- if ((mask & Button2Mask) != 0)
- mouseMods |= ModifierKeys::middleButtonModifier;
-
- if ((mask & Button3Mask) != 0)
- mouseMods |= ModifierKeys::rightButtonModifier;
- }
- }
-
- static int AltMask = 0;
- static int NumLockMask = 0;
- static bool numLock = 0;
- static bool capsLock = 0;
- static char keyStates [32];
-
- static void updateKeyStates (const int keycode, const bool press) throw()
- {
- const int keybyte = keycode >> 3;
- const int keybit = (1 << (keycode & 7));
-
- if (press)
- keyStates [keybyte] |= keybit;
- else
- keyStates [keybyte] &= ~keybit;
- }
-
- static bool keyDown (const int keycode) throw()
- {
- const int keybyte = keycode >> 3;
- const int keybit = (1 << (keycode & 7));
-
- return (keyStates [keybyte] & keybit) != 0;
- }
-
- static const int extendedKeyModifier = 0x10000000;
-
- bool KeyPress::isKeyCurrentlyDown (const int keyCode) throw()
- {
- int keysym;
-
- if (keyCode & extendedKeyModifier)
- {
- keysym = 0xff00 | (keyCode & 0xff);
- }
- else
- {
- keysym = keyCode;
-
- if (keysym == (XK_Tab & 0xff)
- || keysym == (XK_Return & 0xff)
- || keysym == (XK_Escape & 0xff)
- || keysym == (XK_BackSpace & 0xff))
- {
- keysym |= 0xff00;
- }
- }
-
- return keyDown (XKeysymToKeycode (display, keysym));
- }
-
- // Alt and Num lock are not defined by standard X
- // modifier constants: check what they're mapped to
- static void getModifierMapping() throw()
- {
- const int altLeftCode = XKeysymToKeycode (display, XK_Alt_L);
- const int numLockCode = XKeysymToKeycode (display, XK_Num_Lock);
-
- AltMask = 0;
- NumLockMask = 0;
-
- XModifierKeymap* mapping = XGetModifierMapping (display);
-
- if (mapping)
- {
- for (int i = 0; i < 8; i++)
- {
- if (mapping->modifiermap [i << 1] == altLeftCode)
- AltMask = 1 << i;
- else if (mapping->modifiermap [i << 1] == numLockCode)
- NumLockMask = 1 << i;
- }
-
- XFreeModifiermap (mapping);
- }
- }
-
- static int currentModifiers = 0;
-
- void ModifierKeys::updateCurrentModifiers() throw()
- {
- currentModifierFlags = currentModifiers;
- }
-
- const ModifierKeys ModifierKeys::getCurrentModifiersRealtime() throw()
- {
- int x, y, mouseMods;
- getMousePos (x, y, mouseMods);
-
- currentModifiers &= ~ModifierKeys::allMouseButtonModifiers;
- currentModifiers |= mouseMods;
-
- return ModifierKeys (currentModifiers);
- }
-
- static void updateKeyModifiers (const int status) throw()
- {
- currentModifiers &= ~(ModifierKeys::shiftModifier
- | ModifierKeys::ctrlModifier
- | ModifierKeys::altModifier);
-
- if (status & ShiftMask)
- currentModifiers |= ModifierKeys::shiftModifier;
-
- if (status & ControlMask)
- currentModifiers |= ModifierKeys::ctrlModifier;
-
- if (status & AltMask)
- currentModifiers |= ModifierKeys::altModifier;
-
- numLock = ((status & NumLockMask) != 0);
- capsLock = ((status & LockMask) != 0);
- }
-
- static bool updateKeyModifiersFromSym (KeySym sym, const bool press) throw()
- {
- int modifier = 0;
- bool isModifier = true;
-
- switch (sym)
- {
- case XK_Shift_L:
- case XK_Shift_R:
- modifier = ModifierKeys::shiftModifier;
- break;
-
- case XK_Control_L:
- case XK_Control_R:
- modifier = ModifierKeys::ctrlModifier;
- break;
-
- case XK_Alt_L:
- case XK_Alt_R:
- modifier = ModifierKeys::altModifier;
- break;
-
- case XK_Num_Lock:
- if (press)
- numLock = ! numLock;
-
- break;
-
- case XK_Caps_Lock:
- if (press)
- capsLock = ! capsLock;
-
- break;
-
- case XK_Scroll_Lock:
- break;
-
- default:
- isModifier = false;
- break;
- }
-
- if (modifier != 0)
- {
- if (press)
- currentModifiers |= modifier;
- else
- currentModifiers &= ~modifier;
- }
-
- return isModifier;
- }
-
- #if JUCE_USE_XSHM
- static bool isShmAvailable() throw()
- {
- static bool isChecked = false;
- static bool isAvailable = false;
-
- if (! isChecked)
- {
- isChecked = true;
-
- int major, minor;
- Bool pixmaps;
-
- if (XShmQueryVersion (display, &major, &minor, &pixmaps))
- {
- trapErrors();
-
- XShmSegmentInfo segmentInfo;
- zerostruct (segmentInfo);
- XImage* xImage = XShmCreateImage (display, DefaultVisual (display, DefaultScreen (display)),
- 24, ZPixmap, 0, &segmentInfo, 50, 50);
-
- if ((segmentInfo.shmid = shmget (IPC_PRIVATE,
- xImage->bytes_per_line * xImage->height,
- IPC_CREAT | 0777)) >= 0)
- {
- segmentInfo.shmaddr = (char*) shmat (segmentInfo.shmid, 0, 0);
-
- if (segmentInfo.shmaddr != (void*) -1)
- {
- segmentInfo.readOnly = False;
- xImage->data = segmentInfo.shmaddr;
- XSync (display, False);
-
- if (XShmAttach (display, &segmentInfo) != 0)
- {
- XSync (display, False);
- XShmDetach (display, &segmentInfo);
-
- isAvailable = true;
- }
- }
-
- XFlush (display);
- XDestroyImage (xImage);
-
- shmdt (segmentInfo.shmaddr);
- }
-
- shmctl (segmentInfo.shmid, IPC_RMID, 0);
-
- isAvailable &= untrapErrors();
- }
- }
-
- return isAvailable;
- }
- #endif
-
- class XBitmapImage : public Image
- {
- public:
-
- XBitmapImage (const PixelFormat format_, const int w, const int h,
- const bool clearImage, const bool is16Bit_)
- : Image (format_, w, h),
- is16Bit (is16Bit_)
- {
- jassert (format_ == RGB || format_ == ARGB);
-
- pixelStride = (format_ == RGB) ? 3 : 4;
- lineStride = ((w * pixelStride + 3) & ~3);
-
- Visual* const visual = DefaultVisual (display, DefaultScreen (display));
-
- #if JUCE_USE_XSHM
- usingXShm = false;
-
- if ((! is16Bit) && isShmAvailable())
- {
- zerostruct (segmentInfo);
-
- xImage = XShmCreateImage (display, visual, 24, ZPixmap, 0, &segmentInfo, w, h);
-
- if (xImage != 0)
- {
- if ((segmentInfo.shmid = shmget (IPC_PRIVATE,
- xImage->bytes_per_line * xImage->height,
- IPC_CREAT | 0777)) >= 0)
- {
- segmentInfo.shmaddr = (char*) shmat (segmentInfo.shmid, 0, 0);
-
- if (segmentInfo.shmaddr != (void*) -1)
- {
- segmentInfo.readOnly = False;
-
- xImage->data = segmentInfo.shmaddr;
- imageData = (uint8*) segmentInfo.shmaddr;
-
- XSync (display, False);
-
- if (XShmAttach (display, &segmentInfo) != 0)
- {
- XSync (display, False);
- usingXShm = true;
- }
- else
- {
- jassertfalse
- }
- }
- else
- {
- shmctl (segmentInfo.shmid, IPC_RMID, 0);
- }
- }
- }
- }
-
- if (! usingXShm)
- #endif
- {
- imageData = (uint8*) juce_malloc (lineStride * h);
-
- if (format_ == ARGB && clearImage)
- zeromem (imageData, h * lineStride);
-
- xImage = (XImage*) juce_calloc (sizeof (XImage));
-
- xImage->width = w;
- xImage->height = h;
- xImage->xoffset = 0;
- xImage->format = ZPixmap;
- xImage->data = (char*) imageData;
- xImage->byte_order = ImageByteOrder (display);
- xImage->bitmap_unit = BitmapUnit (display);
- xImage->bitmap_bit_order = BitmapBitOrder (display);
- xImage->bitmap_pad = 32;
- xImage->depth = pixelStride * 8;
- xImage->bytes_per_line = lineStride;
- xImage->bits_per_pixel = pixelStride * 8;
- xImage->red_mask = 0x00FF0000;
- xImage->green_mask = 0x0000FF00;
- xImage->blue_mask = 0x000000FF;
-
- if (is16Bit)
- {
- const int pixelStride = 2;
- const int lineStride = ((w * pixelStride + 3) & ~3);
-
- xImage->data = (char*) juce_malloc (lineStride * h);
- xImage->bitmap_pad = 16;
- xImage->depth = pixelStride * 8;
- xImage->bytes_per_line = lineStride;
- xImage->bits_per_pixel = pixelStride * 8;
- xImage->red_mask = visual->red_mask;
- xImage->green_mask = visual->green_mask;
- xImage->blue_mask = visual->blue_mask;
- }
-
- if (! XInitImage (xImage))
- {
- jassertfalse
- }
- }
- }
-
- ~XBitmapImage()
- {
- #if JUCE_USE_XSHM
- if (usingXShm)
- {
- XShmDetach (display, &segmentInfo);
-
- XFlush (display);
- XDestroyImage (xImage);
-
- shmdt (segmentInfo.shmaddr);
- shmctl (segmentInfo.shmid, IPC_RMID, 0);
- }
- else
- #endif
- {
- juce_free (xImage->data);
- xImage->data = 0;
- XDestroyImage (xImage);
- }
-
- if (! is16Bit)
- imageData = 0; // to stop the base class freeing this (for the 16-bit version we want it to free it)
- }
-
- void blitToWindow (Window window, int dx, int dy, int dw, int dh, int sx, int sy)
- {
- static GC gc = 0;
-
- if (gc == 0)
- gc = DefaultGC (display, DefaultScreen (display));
-
- if (is16Bit)
- {
- const uint32 rMask = xImage->red_mask;
- const uint32 rShiftL = jmax (0, getShiftNeeded (rMask));
- const uint32 rShiftR = jmax (0, -getShiftNeeded (rMask));
- const uint32 gMask = xImage->green_mask;
- const uint32 gShiftL = jmax (0, getShiftNeeded (gMask));
- const uint32 gShiftR = jmax (0, -getShiftNeeded (gMask));
- const uint32 bMask = xImage->blue_mask;
- const uint32 bShiftL = jmax (0, getShiftNeeded (bMask));
- const uint32 bShiftR = jmax (0, -getShiftNeeded (bMask));
-
- int ls, ps;
- const uint8* const pixels = lockPixelDataReadOnly (0, 0, getWidth(), getHeight(), ls, ps);
-
- jassert (! isARGB())
-
- for (int y = sy; y < sy + dh; ++y)
- {
- const uint8* p = pixels + y * ls + sx * ps;
-
- for (int x = sx; x < sx + dw; ++x)
- {
- const PixelRGB* const pixel = (const PixelRGB*) p;
- p += ps;
-
- XPutPixel (xImage, x, y,
- (((((uint32) pixel->getRed()) << rShiftL) >> rShiftR) & rMask)
- | (((((uint32) pixel->getGreen()) << gShiftL) >> gShiftR) & gMask)
- | (((((uint32) pixel->getBlue()) << bShiftL) >> bShiftR) & bMask));
- }
- }
-
- releasePixelDataReadOnly (pixels);
- }
-
- // blit results to screen.
- #if JUCE_USE_XSHM
- if (usingXShm)
- XShmPutImage (display, (::Drawable) window, gc, xImage, sx, sy, dx, dy, dw, dh, False);
- else
- #endif
- XPutImage (display, (::Drawable) window, gc, xImage, sx, sy, dx, dy, dw, dh);
- }
-
- juce_UseDebuggingNewOperator
-
- private:
- XImage* xImage;
- const bool is16Bit;
-
- #if JUCE_USE_XSHM
- XShmSegmentInfo segmentInfo;
- bool usingXShm;
- #endif
-
- static int getShiftNeeded (const uint32 mask) throw()
- {
- for (int i = 32; --i >= 0;)
- if (((mask >> i) & 1) != 0)
- return i - 7;
-
- jassertfalse
- return 0;
- }
- };
-
- #define checkMessageManagerIsLocked jassert (MessageManager::getInstance()->currentThreadHasLockedMessageManager());
-
- class LinuxComponentPeer : public ComponentPeer
- {
- public:
-
- LinuxComponentPeer (Component* const component, const int windowStyleFlags)
- : ComponentPeer (component, windowStyleFlags),
- windowH (0),
- parentWindow (0),
- wx (0),
- wy (0),
- ww (0),
- wh (0),
- taskbarImage (0),
- fullScreen (false),
- entered (false),
- mapped (false)
- {
- // it's dangerous to create a window on a thread other than the message thread..
- checkMessageManagerIsLocked
-
- repainter = new LinuxRepaintManager (this);
-
- createWindow();
-
- setTitle (component->getName());
- }
-
- ~LinuxComponentPeer()
- {
- // it's dangerous to delete a window on a thread other than the message thread..
- checkMessageManagerIsLocked
-
- deleteTaskBarIcon();
-
- destroyWindow();
-
- windowH = 0;
- delete repainter;
- }
-
- void* getNativeHandle() const
- {
- return (void*) windowH;
- }
-
- static LinuxComponentPeer* getPeerFor (Window windowHandle) throw()
- {
- XPointer peer = 0;
-
- if (! XFindContext (display, (XID) windowHandle, improbableNumber, &peer))
- {
- if (peer != 0 && ! ((LinuxComponentPeer*) peer)->isValidMessageListener())
- peer = 0;
- }
-
- return (LinuxComponentPeer*) peer;
- }
-
- void setVisible (bool shouldBeVisible)
- {
- if (shouldBeVisible)
- XMapWindow (display, windowH);
- else
- XUnmapWindow (display, windowH);
- }
-
- void setTitle (const String& title)
- {
- setWindowTitle (windowH, title);
- }
-
- void setPosition (int x, int y)
- {
- setBounds (x, y, ww, wh, false);
- }
-
- void setSize (int w, int h)
- {
- setBounds (wx, wy, w, h, false);
- }
-
- void setBounds (int x, int y, int w, int h, const bool isNowFullScreen)
- {
- fullScreen = isNowFullScreen;
-
- if (windowH != 0)
- {
- const ComponentDeletionWatcher deletionChecker (component);
-
- wx = x;
- wy = y;
- ww = jmax (1, w);
- wh = jmax (1, h);
-
- if (! mapped)
- {
- // Make sure the Window manager does what we want
- XSizeHints* hints = XAllocSizeHints();
- hints->flags = USSize | USPosition;
- hints->width = ww + windowBorder.getLeftAndRight();
- hints->height = wh + windowBorder.getTopAndBottom();
- hints->x = wx - windowBorder.getLeft();
- hints->y = wy - windowBorder.getTop();
- XSetWMNormalHints (display, windowH, hints);
- XFree (hints);
- }
-
- XMoveResizeWindow (display, windowH,
- wx - windowBorder.getLeft(),
- wy - windowBorder.getTop(),
- ww + windowBorder.getLeftAndRight(),
- wh + windowBorder.getTopAndBottom());
-
- if (! deletionChecker.hasBeenDeleted())
- {
- updateBorderSize();
- handleMovedOrResized();
- }
- }
- }
-
- void getBounds (int& x, int& y, int& w, int& h) const
- {
- x = wx;
- y = wy;
- w = ww;
- h = wh;
- }
-
- int getScreenX() const
- {
- return wx;
- }
-
- int getScreenY() const
- {
- return wy;
- }
-
- void relativePositionToGlobal (int& x, int& y)
- {
- x += wx;
- y += wy;
- }
-
- void globalPositionToRelative (int& x, int& y)
- {
- x -= wx;
- y -= wy;
- }
-
- void setMinimised (bool shouldBeMinimised)
- {
- if (shouldBeMinimised)
- {
- Window root = RootWindow (display, DefaultScreen (display));
-
- XClientMessageEvent clientMsg;
- clientMsg.display = display;
- clientMsg.window = windowH;
- clientMsg.type = ClientMessage;
- clientMsg.format = 32;
- clientMsg.message_type = wm_ChangeState;
- clientMsg.data.l[0] = IconicState;
-
- XSendEvent (display, root, false,
- SubstructureRedirectMask | SubstructureNotifyMask,
- (XEvent*) &clientMsg);
- }
- else
- {
- setVisible (true);
- }
- }
-
- bool isMinimised() const
- {
- bool minimised = false;
-
- unsigned char* stateProp;
- unsigned long nitems, bytesLeft;
- Atom actualType;
- int actualFormat;
-
- if (XGetWindowProperty (display, windowH, wm_State, 0, 64, False,
- wm_State, &actualType, &actualFormat, &nitems, &bytesLeft,
- &stateProp) == Success
- && actualType == wm_State
- && actualFormat == 32
- && nitems > 0)
- {
- if (((unsigned long*) stateProp)[0] == IconicState)
- minimised = true;
-
- XFree (stateProp);
- }
-
- return minimised;
- }
-
- void setFullScreen (const bool shouldBeFullScreen)
- {
- Rectangle r (lastNonFullscreenBounds); // (get a copy of this before de-minimising)
-
- setMinimised (false);
-
- if (fullScreen != shouldBeFullScreen)
- {
- if (shouldBeFullScreen)
- r = Desktop::getInstance().getMainMonitorArea();
-
- if (! r.isEmpty())
- setBounds (r.getX(), r.getY(), r.getWidth(), r.getHeight(), shouldBeFullScreen);
-
- getComponent()->repaint();
- }
- }
-
- bool isFullScreen() const
- {
- return fullScreen;
- }
-
- bool isChildWindowOf (Window possibleParent) const
- {
- Window* windowList = 0;
- uint32 windowListSize = 0;
- Window parent, root;
-
- if (XQueryTree (display, windowH, &root, &parent, &windowList, &windowListSize) != 0)
- {
- if (windowList != 0)
- XFree (windowList);
-
- return parent == possibleParent;
- }
-
- return false;
- }
-
- bool isFrontWindow() const
- {
- Window* windowList = 0;
- uint32 windowListSize = 0;
- bool result = false;
-
- Window parent, root = RootWindow (display, DefaultScreen (display));
-
- if (XQueryTree (display, root, &root, &parent, &windowList, &windowListSize) != 0)
- {
- for (int i = windowListSize; --i >= 0;)
- {
- LinuxComponentPeer* const peer = LinuxComponentPeer::getPeerFor (windowList[i]);
-
- if (peer != 0)
- {
- result = (peer == this);
- break;
- }
- }
- }
-
- if (windowList != 0)
- XFree (windowList);
-
- return result;
- }
-
- bool contains (int x, int y, bool trueIfInAChildWindow) const
- {
- jassert (x >= 0 && y >= 0 && x < ww && y < wh); // should only be called for points that are actually inside the bounds
-
- if (((unsigned int) x) >= (unsigned int) ww
- || ((unsigned int) y) >= (unsigned int) wh)
- return false;
-
- bool inFront = false;
-
- for (int i = 0; i < Desktop::getInstance().getNumComponents(); ++i)
- {
- Component* const c = Desktop::getInstance().getComponent (i);
-
- if (inFront)
- {
- if (c->contains (x + wx - c->getScreenX(),
- y + wy - c->getScreenY()))
- {
- return false;
- }
- }
- else if (c == getComponent())
- {
- inFront = true;
- }
- }
-
- if (trueIfInAChildWindow)
- return true;
-
- ::Window root, child;
- unsigned int bw, depth;
- int wx, wy, w, h;
-
- if (! XGetGeometry (display, (::Drawable) windowH, &root,
- &wx, &wy, (unsigned int*) &w, (unsigned int*) &h,
- &bw, &depth))
- {
- return false;
- }
-
- if (! XTranslateCoordinates (display, windowH, windowH, x, y, &wx, &wy, &child))
- return false;
-
- return child == None;
- }
-
- const BorderSize getFrameSize() const
- {
- return BorderSize();
- }
-
- bool setAlwaysOnTop (bool alwaysOnTop)
- {
- if (windowH != 0)
- {
- const bool wasVisible = component->isVisible();
-
- if (wasVisible)
- setVisible (false); // doesn't always seem to work if the window is visible when this is done..
-
- XSetWindowAttributes swa;
- swa.override_redirect = alwaysOnTop ? True : False;
-
- XChangeWindowAttributes (display, windowH, CWOverrideRedirect, &swa);
-
- if (wasVisible)
- setVisible (true);
- }
-
- return true;
- }
-
- void toFront (bool makeActive)
- {
- if (makeActive)
- {
- setVisible (true);
- grabFocus();
- }
-
- XEvent ev;
- ev.xclient.type = ClientMessage;
- ev.xclient.serial = 0;
- ev.xclient.send_event = True;
- ev.xclient.message_type = wm_ActiveWin;
- ev.xclient.window = windowH;
- ev.xclient.format = 32;
- ev.xclient.data.l[0] = 2;
- ev.xclient.data.l[1] = CurrentTime;
- ev.xclient.data.l[2] = 0;
- ev.xclient.data.l[3] = 0;
- ev.xclient.data.l[4] = 0;
-
- XSendEvent (display, RootWindow (display, DefaultScreen (display)),
- False,
- SubstructureRedirectMask | SubstructureNotifyMask,
- &ev);
-
- XSync (display, False);
-
- handleBroughtToFront();
- }
-
- void toBehind (ComponentPeer* other)
- {
- LinuxComponentPeer* const otherPeer = dynamic_cast <LinuxComponentPeer*> (other);
- jassert (otherPeer != 0); // wrong type of window?
-
- if (otherPeer != 0)
- {
- setMinimised (false);
-
- Window newStack[] = { otherPeer->windowH, windowH };
-
- XRestackWindows (display, newStack, 2);
- }
- }
-
- bool isFocused() const
- {
- int revert;
- Window focusedWindow = 0;
- XGetInputFocus (display, &focusedWindow, &revert);
-
- return focusedWindow == windowH;
- }
-
- void grabFocus()
- {
- XWindowAttributes atts;
-
- if (windowH != 0
- && XGetWindowAttributes (display, windowH, &atts)
- && atts.map_state == IsViewable
- && ! isFocused())
- {
- XSetInputFocus (display, windowH, RevertToParent, CurrentTime);
- isActiveApplication = true;
- }
- }
-
- void textInputRequired (int /*x*/, int /*y*/)
- {
- }
-
- void repaint (int x, int y, int w, int h)
- {
- if (Rectangle::intersectRectangles (x, y, w, h,
- 0, 0,
- getComponent()->getWidth(),
- getComponent()->getHeight()))
- {
- repainter->repaint (x, y, w, h);
- }
- }
-
- void performAnyPendingRepaintsNow()
- {
- repainter->performAnyPendingRepaintsNow();
- }
-
- void setIcon (const Image& newIcon)
- {
- const int dataSize = newIcon.getWidth() * newIcon.getHeight() + 2;
- uint32* const data = (uint32*) juce_malloc (dataSize);
-
- int index = 0;
- data[index++] = newIcon.getWidth();
- data[index++] = newIcon.getHeight();
-
- for (int y = 0; y < newIcon.getHeight(); ++y)
- for (int x = 0; x < newIcon.getWidth(); ++x)
- data[index++] = newIcon.getPixelAt (x, y).getARGB();
-
- XChangeProperty (display, windowH,
- XInternAtom (display, "_NET_WM_ICON", False),
- XA_CARDINAL, 32, PropModeReplace,
- (unsigned char*) data, dataSize);
-
- XSync (display, False);
-
- juce_free (data);
- }
-
- void handleWindowMessage (XEvent* event)
- {
- switch (event->xany.type)
- {
- case 2: // 'KeyPress'
- {
- XKeyEvent* const keyEvent = (XKeyEvent*) &event->xkey;
- updateKeyStates (keyEvent->keycode, true);
-
- char utf8 [64];
- zeromem (utf8, sizeof (utf8));
- KeySym sym;
- XLookupString (keyEvent, utf8, sizeof (utf8), &sym, 0);
-
- const juce_wchar unicodeChar = *(const juce_wchar*) String::fromUTF8 ((const uint8*) utf8, sizeof (utf8) - 1);
- int keyCode = (int) unicodeChar;
-
- if (keyCode < 0x20)
- keyCode = XKeycodeToKeysym (display, keyEvent->keycode,
- (currentModifiers & ModifierKeys::shiftModifier) != 0 ? 1 : 0);
-
- const int oldMods = currentModifiers;
- bool keyPressed = false;
-
- const bool keyDownChange = (sym != NoSymbol) && ! updateKeyModifiersFromSym (sym, true);
-
- if ((sym & 0xff00) == 0xff00)
- {
- // Translate keypad
- if (sym == XK_KP_Divide)
- keyCode = XK_slash;
- else if (sym == XK_KP_Multiply)
- keyCode = XK_asterisk;
- else if (sym == XK_KP_Subtract)
- keyCode = XK_hyphen;
- else if (sym == XK_KP_Add)
- keyCode = XK_plus;
- else if (sym == XK_KP_Enter)
- keyCode = XK_Return;
- else if (sym == XK_KP_Decimal)
- keyCode = numLock ? XK_period : XK_Delete;
- else if (sym == XK_KP_0)
- keyCode = numLock ? XK_0 : XK_Insert;
- else if (sym == XK_KP_1)
- keyCode = numLock ? XK_1 : XK_End;
- else if (sym == XK_KP_2)
- keyCode = numLock ? XK_2 : XK_Down;
- else if (sym == XK_KP_3)
- keyCode = numLock ? XK_3 : XK_Page_Down;
- else if (sym == XK_KP_4)
- keyCode = numLock ? XK_4 : XK_Left;
- else if (sym == XK_KP_5)
- keyCode = XK_5;
- else if (sym == XK_KP_6)
- keyCode = numLock ? XK_6 : XK_Right;
- else if (sym == XK_KP_7)
- keyCode = numLock ? XK_7 : XK_Home;
- else if (sym == XK_KP_8)
- keyCode = numLock ? XK_8 : XK_Up;
- else if (sym == XK_KP_9)
- keyCode = numLock ? XK_9 : XK_Page_Up;
-
- switch (sym)
- {
- case XK_Left:
- case XK_Right:
- case XK_Up:
- case XK_Down:
- case XK_Page_Up:
- case XK_Page_Down:
- case XK_End:
- case XK_Home:
- case XK_Delete:
- case XK_Insert:
- keyPressed = true;
- keyCode = (sym & 0xff) | extendedKeyModifier;
- break;
- case XK_Tab:
- case XK_Return:
- case XK_Escape:
- case XK_BackSpace:
- keyPressed = true;
- keyCode &= 0xff;
- break;
- default:
- {
- if (sym >= XK_F1 && sym <= XK_F16)
- {
- keyPressed = true;
- keyCode = (sym & 0xff) | extendedKeyModifier;
- }
- break;
- }
- }
- }
-
- if (utf8[0] != 0 || ((sym & 0xff00) == 0 && sym >= 8))
- keyPressed = true;
-
- if (oldMods != currentModifiers)
- handleModifierKeysChange();
-
- if (keyDownChange)
- handleKeyUpOrDown();
-
- if (keyPressed)
- handleKeyPress (keyCode, unicodeChar);
-
- break;
- }
-
- case KeyRelease:
- {
- const XKeyEvent* const keyEvent = (const XKeyEvent*) &event->xkey;
- updateKeyStates (keyEvent->keycode, false);
-
- KeySym sym = XKeycodeToKeysym (display, keyEvent->keycode, 0);
-
- const int oldMods = currentModifiers;
- const bool keyDownChange = (sym != NoSymbol) && ! updateKeyModifiersFromSym (sym, false);
-
- if (oldMods != currentModifiers)
- handleModifierKeysChange();
-
- if (keyDownChange)
- handleKeyUpOrDown();
-
- break;
- }
-
- case ButtonPress:
- {
- const XButtonPressedEvent* const buttonPressEvent = (const XButtonPressedEvent*) &event->xbutton;
-
- bool buttonMsg = false;
- bool wheelUpMsg = false;
- bool wheelDownMsg = false;
-
- const int map = pointerMap [buttonPressEvent->button - Button1];
-
- if (map == LeftButton)
- {
- currentModifiers |= ModifierKeys::leftButtonModifier;
- buttonMsg = true;
- }
- else if (map == RightButton)
- {
- currentModifiers |= ModifierKeys::rightButtonModifier;
- buttonMsg = true;
- }
- else if (map == MiddleButton)
- {
- currentModifiers |= ModifierKeys::middleButtonModifier;
- buttonMsg = true;
- }
- else if (map == WheelUp)
- {
- wheelUpMsg = true;
- }
- else if (map == WheelDown)
- {
- wheelDownMsg = true;
- }
-
- updateKeyModifiers (buttonPressEvent->state);
-
- if (buttonMsg)
- {
- toFront (true);
- handleMouseDown (buttonPressEvent->x, buttonPressEvent->y,
- getEventTime (buttonPressEvent->time));
- }
- else if (wheelUpMsg || wheelDownMsg)
- {
- handleMouseWheel (0, wheelDownMsg ? -84 : 84,
- getEventTime (buttonPressEvent->time));
- }
-
- lastMousePosX = lastMousePosY = 0x100000;
- break;
- }
-
- case ButtonRelease:
- {
- const XButtonReleasedEvent* const buttonRelEvent = (const XButtonReleasedEvent*) &event->xbutton;
-
- const int oldModifiers = currentModifiers;
- const int map = pointerMap [buttonRelEvent->button - Button1];
-
- if (map == LeftButton)
- currentModifiers &= ~ModifierKeys::leftButtonModifier;
- else if (map == RightButton)
- currentModifiers &= ~ModifierKeys::rightButtonModifier;
- else if (map == MiddleButton)
- currentModifiers &= ~ModifierKeys::middleButtonModifier;
-
- updateKeyModifiers (buttonRelEvent->state);
-
- handleMouseUp (oldModifiers,
- buttonRelEvent->x, buttonRelEvent->y,
- getEventTime (buttonRelEvent->time));
-
- lastMousePosX = lastMousePosY = 0x100000;
- break;
- }
-
- case MotionNotify:
- {
- const XPointerMovedEvent* const movedEvent = (const XPointerMovedEvent*) &event->xmotion;
-
- updateKeyModifiers (movedEvent->state);
-
- int x, y, mouseMods;
- getMousePos (x, y, mouseMods);
-
- if (lastMousePosX != x || lastMousePosY != y)
- {
- lastMousePosX = x;
- lastMousePosY = y;
-
- if (parentWindow != 0 && (styleFlags & windowHasTitleBar) == 0)
- {
- Window wRoot = 0, wParent = 0;
- Window* wChild = 0;
- unsigned int numChildren;
- XQueryTree (display, windowH, &wRoot, &wParent, &wChild, &numChildren);
-
- if (wParent != 0
- && wParent != windowH
- && wParent != wRoot)
- {
- parentWindow = wParent;
- updateBounds();
- x -= getScreenX();
- y -= getScreenY();
- }
- else
- {
- parentWindow = 0;
- x -= getScreenX();
- y -= getScreenY();
- }
- }
- else
- {
- x -= getScreenX();
- y -= getScreenY();
- }
-
- if ((currentModifiers & ModifierKeys::allMouseButtonModifiers) == 0)
- handleMouseMove (x, y, getEventTime (movedEvent->time));
- else
- handleMouseDrag (x, y, getEventTime (movedEvent->time));
- }
-
- break;
- }
-
- case EnterNotify:
- {
- lastMousePosX = lastMousePosY = 0x100000;
- const XEnterWindowEvent* const enterEvent = (const XEnterWindowEvent*) &event->xcrossing;
-
- if ((currentModifiers & ModifierKeys::allMouseButtonModifiers) == 0
- && ! entered)
- {
- updateKeyModifiers (enterEvent->state);
-
- handleMouseEnter (enterEvent->x, enterEvent->y, getEventTime (enterEvent->time));
-
- entered = true;
- }
-
- break;
- }
-
- case LeaveNotify:
- {
- const XLeaveWindowEvent* const leaveEvent = (const XLeaveWindowEvent*) &event->xcrossing;
-
- // Suppress the normal leave if we've got a pointer grab, or if
- // it's a bogus one caused by clicking a mouse button when running
- // in a Window manager
- if (((currentModifiers & ModifierKeys::allMouseButtonModifiers) == 0
- && leaveEvent->mode == NotifyNormal)
- || leaveEvent->mode == NotifyUngrab)
- {
- updateKeyModifiers (leaveEvent->state);
-
- handleMouseExit (leaveEvent->x, leaveEvent->y, getEventTime (leaveEvent->time));
-
- entered = false;
- }
-
- break;
- }
-
- case FocusIn:
- {
- isActiveApplication = true;
- if (isFocused())
- handleFocusGain();
-
- break;
- }
-
- case FocusOut:
- {
- isActiveApplication = false;
- if (! isFocused())
- handleFocusLoss();
-
- break;
- }
-
- case Expose:
- {
- // Batch together all pending expose events
- XExposeEvent* exposeEvent = (XExposeEvent*) &event->xexpose;
- XEvent nextEvent;
-
- if (exposeEvent->window != windowH)
- {
- Window child;
- XTranslateCoordinates (display, exposeEvent->window, windowH,
- exposeEvent->x, exposeEvent->y, &exposeEvent->x, &exposeEvent->y,
- &child);
- }
-
- repaint (exposeEvent->x, exposeEvent->y,
- exposeEvent->width, exposeEvent->height);
-
- while (XEventsQueued (display, QueuedAfterFlush) > 0)
- {
- XPeekEvent (display, (XEvent*) &nextEvent);
- if (nextEvent.type != Expose || nextEvent.xany.window != event->xany.window)
- break;
-
- XNextEvent (display, (XEvent*) &nextEvent);
- XExposeEvent* nextExposeEvent = (XExposeEvent*) &nextEvent.xexpose;
- repaint (nextExposeEvent->x, nextExposeEvent->y,
- nextExposeEvent->width, nextExposeEvent->height);
- }
-
- break;
- }
-
- case CirculateNotify:
- case CreateNotify:
- case DestroyNotify:
- // Think we can ignore these
- break;
-
- case ConfigureNotify:
- {
- updateBounds();
- updateBorderSize();
- handleMovedOrResized();
-
- // if the native title bar is dragged, need to tell any active menus, etc.
- if ((styleFlags & windowHasTitleBar) != 0
- && component->isCurrentlyBlockedByAnotherModalComponent())
- {
- Component* const currentModalComp = Component::getCurrentlyModalComponent();
-
- if (currentModalComp != 0)
- currentModalComp->inputAttemptWhenModal();
- }
-
- XConfigureEvent* const confEvent = (XConfigureEvent*) &event->xconfigure;
-
- if (confEvent->window == windowH
- && confEvent->above != 0
- && isFrontWindow())
- {
- handleBroughtToFront();
- }
-
- break;
- }
-
- case ReparentNotify:
- case GravityNotify:
- {
- parentWindow = 0;
- Window wRoot = 0;
- Window* wChild = 0;
- unsigned int numChildren;
- XQueryTree (display, windowH, &wRoot, &parentWindow, &wChild, &numChildren);
-
- if (parentWindow == windowH || parentWindow == wRoot)
- parentWindow = 0;
-
- updateBounds();
- updateBorderSize();
- handleMovedOrResized();
- break;
- }
-
- case MapNotify:
- mapped = true;
- handleBroughtToFront();
- break;
-
- case UnmapNotify:
- mapped = false;
- break;
-
- case MappingNotify:
- {
- XMappingEvent* mappingEvent = (XMappingEvent*) &event->xmapping;
-
- if (mappingEvent->request != MappingPointer)
- {
- // Deal with modifier/keyboard mapping
- XRefreshKeyboardMapping (mappingEvent);
- getModifierMapping();
- }
-
- break;
- }
-
- case ClientMessage:
- {
- const XClientMessageEvent* const clientMsg = (const XClientMessageEvent*) &event->xclient;
-
- if (clientMsg->message_type == wm_Protocols && clientMsg->format == 32)
- {
- const Atom atom = (Atom) clientMsg->data.l[0];
-
- if (atom == wm_ProtocolList [TAKE_FOCUS])
- {
- XWindowAttributes atts;
-
- if (clientMsg->window != 0
- && XGetWindowAttributes (display, clientMsg->window, &atts))
- {
- if (atts.map_state == IsViewable)
- XSetInputFocus (display, clientMsg->window, RevertToParent, clientMsg->data.l[1]);
- }
- }
- else if (atom == wm_ProtocolList [DELETE_WINDOW])
- {
- handleUserClosingWindow();
- }
- }
- else if (clientMsg->message_type == XA_XdndEnter)
- {
- handleDragAndDropEnter (clientMsg);
- }
- else if (clientMsg->message_type == XA_XdndLeave)
- {
- resetDragAndDrop();
- }
- else if (clientMsg->message_type == XA_XdndPosition)
- {
- handleDragAndDropPosition (clientMsg);
- }
- else if (clientMsg->message_type == XA_XdndDrop)
- {
- handleDragAndDropDrop (clientMsg);
- }
- else if (clientMsg->message_type == XA_XdndStatus)
- {
- handleDragAndDropStatus (clientMsg);
- }
- else if (clientMsg->message_type == XA_XdndFinished)
- {
- resetDragAndDrop();
- }
-
- break;
- }
-
- case SelectionNotify:
- handleDragAndDropSelection (event);
- break;
-
- case SelectionClear:
- case SelectionRequest:
- break;
-
- default:
- break;
- }
- }
-
- void showMouseCursor (Cursor cursor) throw()
- {
- XDefineCursor (display, windowH, cursor);
- }
-
- void setTaskBarIcon (const Image& image)
- {
- deleteTaskBarIcon();
- taskbarImage = image.createCopy();
-
- Screen* const screen = XDefaultScreenOfDisplay (display);
- const int screenNumber = XScreenNumberOfScreen (screen);
-
- char screenAtom[32];
- snprintf (screenAtom, sizeof (screenAtom), "_NET_SYSTEM_TRAY_S%d", screenNumber);
- Atom selectionAtom = XInternAtom (display, screenAtom, false);
-
- XGrabServer (display);
- Window managerWin = XGetSelectionOwner (display, selectionAtom);
-
- if (managerWin != None)
- XSelectInput (display, managerWin, StructureNotifyMask);
-
- XUngrabServer (display);
- XFlush (display);
-
- if (managerWin != None)
- {
- XEvent ev;
- zerostruct (ev);
- ev.xclient.type = ClientMessage;
- ev.xclient.window = managerWin;
- ev.xclient.message_type = XInternAtom (display, "_NET_SYSTEM_TRAY_OPCODE", False);
- ev.xclient.format = 32;
- ev.xclient.data.l[0] = CurrentTime;
- ev.xclient.data.l[1] = SYSTEM_TRAY_REQUEST_DOCK;
- ev.xclient.data.l[2] = windowH;
- ev.xclient.data.l[3] = 0;
- ev.xclient.data.l[4] = 0;
-
- XSendEvent (display, managerWin, False, NoEventMask, &ev);
- XSync (display, False);
- }
-
- // For older KDE's ...
- long atomData = 1;
- Atom trayAtom = XInternAtom (display, "KWM_DOCKWINDOW", false);
- XChangeProperty (display, windowH, trayAtom, trayAtom, 32, PropModeReplace, (unsigned char*) &atomData, 1);
-
- // For more recent KDE's...
- trayAtom = XInternAtom (display, "_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR", false);
- XChangeProperty (display, windowH, trayAtom, XA_WINDOW, 32, PropModeReplace, (unsigned char*) &windowH, 1);
- }
-
- void deleteTaskBarIcon()
- {
- deleteAndZero (taskbarImage);
- }
-
- const Image* getTaskbarIcon() const throw() { return taskbarImage; }
-
- juce_UseDebuggingNewOperator
-
- bool dontRepaint;
-
- private:
-
- class LinuxRepaintManager : public Timer
- {
- public:
- LinuxRepaintManager (LinuxComponentPeer* const peer_)
- : peer (peer_),
- image (0),
- lastTimeImageUsed (0)
- {
- #if JUCE_USE_XSHM
- useARGBImagesForRendering = isShmAvailable();
-
- if (useARGBImagesForRendering)
- {
- XShmSegmentInfo segmentinfo;
-
- XImage* const testImage
- = XShmCreateImage (display, DefaultVisual (display, DefaultScreen (display)),
- 24, ZPixmap, 0, &segmentinfo, 64, 64);
-
- useARGBImagesForRendering = (testImage->bits_per_pixel == 32);
- XDestroyImage (testImage);
- }
- #endif
- }
-
- ~LinuxRepaintManager()
- {
- delete image;
- }
-
- void timerCallback()
- {
- if (! regionsNeedingRepaint.isEmpty())
- {
- stopTimer();
- performAnyPendingRepaintsNow();
- }
- else if (Time::getApproximateMillisecondCounter() > lastTimeImageUsed + 3000)
- {
- stopTimer();
- deleteAndZero (image);
- }
- }
-
- void repaint (int x, int y, int w, int h)
- {
- if (! isTimerRunning())
- startTimer (repaintTimerPeriod);
-
- regionsNeedingRepaint.add (x, y, w, h);
- }
-
- void performAnyPendingRepaintsNow()
- {
- peer->clearMaskedRegion();
-
- const Rectangle totalArea (regionsNeedingRepaint.getBounds());
-
- if (! totalArea.isEmpty())
- {
- if (image == 0 || image->getWidth() < totalArea.getWidth()
- || image->getHeight() < totalArea.getHeight())
- {
- delete image;
-
- #if JUCE_USE_XSHM
- image = new XBitmapImage (useARGBImagesForRendering ? Image::ARGB
- : Image::RGB,
- #else
- image = new XBitmapImage (Image::RGB,
- #endif
- (totalArea.getWidth() + 31) & ~31,
- (totalArea.getHeight() + 31) & ~31,
- false,
- peer->depthIs16Bit);
- }
-
- startTimer (repaintTimerPeriod);
-
- LowLevelGraphicsSoftwareRenderer context (*image);
-
- context.setOrigin (-totalArea.getX(), -totalArea.getY());
-
- if (context.reduceClipRegion (regionsNeedingRepaint))
- peer->handlePaint (context);
-
- if (! peer->maskedRegion.isEmpty())
- regionsNeedingRepaint.subtract (peer->maskedRegion);
-
- for (RectangleList::Iterator i (regionsNeedingRepaint); i.next();)
- {
- const Rectangle& r = *i.getRectangle();
-
- image->blitToWindow (peer->windowH,
- r.getX(), r.getY(), r.getWidth(), r.getHeight(),
- r.getX() - totalArea.getX(), r.getY() - totalArea.getY());
- }
- }
-
- regionsNeedingRepaint.clear();
-
- lastTimeImageUsed = Time::getApproximateMillisecondCounter();
- startTimer (repaintTimerPeriod);
- }
-
- private:
- LinuxComponentPeer* const peer;
- XBitmapImage* image;
- uint32 lastTimeImageUsed;
- RectangleList regionsNeedingRepaint;
-
- #if JUCE_USE_XSHM
- bool useARGBImagesForRendering;
- #endif
- LinuxRepaintManager (const LinuxRepaintManager&);
- const LinuxRepaintManager& operator= (const LinuxRepaintManager&);
- };
-
- LinuxRepaintManager* repainter;
-
- friend class LinuxRepaintManager;
- Window windowH, parentWindow;
- int wx, wy, ww, wh;
- Image* taskbarImage;
- bool fullScreen, entered, mapped, depthIs16Bit;
- BorderSize windowBorder;
-
- void removeWindowDecorations (Window wndH)
- {
- Atom hints = XInternAtom (display, "_MOTIF_WM_HINTS", True);
-
- if (hints != None)
- {
- typedef struct
- {
- unsigned long flags;
- unsigned long functions;
- unsigned long decorations;
- long input_mode;
- unsigned long status;
- } MotifWmHints;
-
- MotifWmHints motifHints;
- zerostruct (motifHints);
- motifHints.flags = 2; /* MWM_HINTS_DECORATIONS */
- motifHints.decorations = 0;
-
- XChangeProperty (display, wndH, hints, hints, 32, PropModeReplace,
- (unsigned char*) &motifHints, 4);
- }
-
- hints = XInternAtom (display, "_WIN_HINTS", True);
-
- if (hints != None)
- {
- long gnomeHints = 0;
-
- XChangeProperty (display, wndH, hints, hints, 32, PropModeReplace,
- (unsigned char*) &gnomeHints, 1);
- }
-
- hints = XInternAtom (display, "KWM_WIN_DECORATION", True);
-
- if (hints != None)
- {
- long kwmHints = 2; /*KDE_tinyDecoration*/
-
- XChangeProperty (display, wndH, hints, hints, 32, PropModeReplace,
- (unsigned char*) &kwmHints, 1);
- }
-
- hints = XInternAtom (display, "_NET_WM_WINDOW_TYPE", True);
-
- if (hints != None)
- {
- long netHints [2];
- netHints[0] = XInternAtom (display, "_KDE_NET_WM_WINDOW_TYPE_OVERRIDE", True);
-
- if ((styleFlags & windowIsTemporary) != 0)
- netHints[1] = XInternAtom (display, "_NET_WM_WINDOW_TYPE_MENU", True);
- else
- netHints[1] = XInternAtom (display, "_NET_WM_WINDOW_TYPE_NORMAL", True);
-
- XChangeProperty (display, wndH, hints, XA_ATOM, 32, PropModeReplace,
- (unsigned char*) &netHints, 2);
- }
- }
-
- void addWindowButtons (Window wndH)
- {
- Atom hints = XInternAtom (display, "_MOTIF_WM_HINTS", True);
-
- if (hints != None)
- {
- typedef struct
- {
- unsigned long flags;
- unsigned long functions;
- unsigned long decorations;
- long input_mode;
- unsigned long status;
- } MotifWmHints;
-
- MotifWmHints motifHints;
- zerostruct (motifHints);
-
- motifHints.flags = 1 | 2; /* MWM_HINTS_FUNCTIONS | MWM_HINTS_DECORATIONS */
- motifHints.decorations = 2 /* MWM_DECOR_BORDER */ | 8 /* MWM_DECOR_TITLE */ | 16; /* MWM_DECOR_MENU */
-
- motifHints.functions = 4 /* MWM_FUNC_MOVE */;
-
- if ((styleFlags & windowHasCloseButton) != 0)
- motifHints.functions |= 32; /* MWM_FUNC_CLOSE */
-
- if ((styleFlags & windowHasMinimiseButton) != 0)
- {
- motifHints.functions |= 8; /* MWM_FUNC_MINIMIZE */
- motifHints.decorations |= 0x20; /* MWM_DECOR_MINIMIZE */
- }
-
- if ((styleFlags & windowHasMaximiseButton) != 0)
- {
- motifHints.functions |= 0x10; /* MWM_FUNC_MAXIMIZE */
- motifHints.decorations |= 0x40; /* MWM_DECOR_MAXIMIZE */
- }
-
- if ((styleFlags & windowIsResizable) != 0)
- {
- motifHints.functions |= 2; /* MWM_FUNC_RESIZE */
- motifHints.decorations |= 0x4; /* MWM_DECOR_RESIZEH */
- }
-
- XChangeProperty (display, wndH, hints, hints, 32, 0, (unsigned char*) &motifHints, 5);
- }
-
- hints = XInternAtom (display, "_NET_WM_ALLOWED_ACTIONS", True);
-
- if (hints != None)
- {
- long netHints [6];
- int num = 0;
-
- netHints [num++] = XInternAtom (display, "_NET_WM_ACTION_RESIZE", (styleFlags & windowIsResizable) ? True : False);
- netHints [num++] = XInternAtom (display, "_NET_WM_ACTION_FULLSCREEN", (styleFlags & windowHasMaximiseButton) ? True : False);
- netHints [num++] = XInternAtom (display, "_NET_WM_ACTION_MINIMIZE", (styleFlags & windowHasMinimiseButton) ? True : False);
- netHints [num++] = XInternAtom (display, "_NET_WM_ACTION_CLOSE", (styleFlags & windowHasCloseButton) ? True : False);
-
- XChangeProperty (display, wndH, hints, XA_ATOM, 32, PropModeReplace,
- (unsigned char*) &netHints, num);
- }
- }
-
- void createWindow()
- {
- static bool atomsInitialised = false;
-
- if (! atomsInitialised)
- {
- atomsInitialised = true;
-
- wm_Protocols = XInternAtom (display, "WM_PROTOCOLS", 1);
- wm_ProtocolList [TAKE_FOCUS] = XInternAtom (display, "WM_TAKE_FOCUS", 1);
- wm_ProtocolList [DELETE_WINDOW] = XInternAtom (display, "WM_DELETE_WINDOW", 1);
- wm_ChangeState = XInternAtom (display, "WM_CHANGE_STATE", 1);
- wm_State = XInternAtom (display, "WM_STATE", 1);
- wm_ActiveWin = XInternAtom (display, "_NET_ACTIVE_WINDOW", False);
-
- XA_XdndAware = XInternAtom (display, "XdndAware", 0);
- XA_XdndEnter = XInternAtom (display, "XdndEnter", 0);
- XA_XdndLeave = XInternAtom (display, "XdndLeave", 0);
- XA_XdndPosition = XInternAtom (display, "XdndPosition", 0);
- XA_XdndStatus = XInternAtom (display, "XdndStatus", 0);
- XA_XdndDrop = XInternAtom (display, "XdndDrop", 0);
- XA_XdndFinished = XInternAtom (display, "XdndFinished", 0);
- XA_XdndSelection = XInternAtom (display, "XdndSelection", 0);
- XA_XdndProxy = XInternAtom (display, "XdndProxy", 0);
-
- XA_XdndTypeList = XInternAtom (display, "XdndTypeList", 0);
- XA_XdndActionList = XInternAtom (display, "XdndActionList", 0);
- XA_XdndActionCopy = XInternAtom (display, "XdndActionCopy", 0);
- XA_XdndActionMove = XInternAtom (display, "XdndActionMove", 0);
- XA_XdndActionLink = XInternAtom (display, "XdndActionLink", 0);
- XA_XdndActionAsk = XInternAtom (display, "XdndActionAsk", 0);
- XA_XdndActionPrivate = XInternAtom (display, "XdndActionPrivate", 0);
- XA_XdndActionDescription = XInternAtom (display, "XdndActionDescription", 0);
-
- XA_JXSelectionWindowProperty = XInternAtom (display, "JXSelectionWindowProperty", 0);
-
- XA_MimeTextPlain = XInternAtom (display, "text/plain", 0);
- XA_MimeTextUriList = XInternAtom (display, "text/uri-list", 0);
- XA_MimeRootDrop = XInternAtom (display, "application/x-rootwindow-drop", 0);
- }
-
- resetDragAndDrop();
-
- XA_OtherMime = XA_MimeTextPlain; // xxx why??
- allowedMimeTypeAtoms [0] = XA_MimeTextPlain;
- allowedMimeTypeAtoms [1] = XA_OtherMime;
- allowedMimeTypeAtoms [2] = XA_MimeTextUriList;
-
- allowedActions [0] = XA_XdndActionMove;
- allowedActions [1] = XA_XdndActionCopy;
- allowedActions [2] = XA_XdndActionLink;
- allowedActions [3] = XA_XdndActionAsk;
- allowedActions [4] = XA_XdndActionPrivate;
-
- // Get defaults for various properties
- const int screen = DefaultScreen (display);
- Window root = RootWindow (display, screen);
-
- // Attempt to create a 24-bit window on the default screen. If this is not
- // possible then exit
- XVisualInfo desiredVisual;
- desiredVisual.screen = screen;
- desiredVisual.depth = 24;
- depthIs16Bit = false;
-
- int numVisuals;
- XVisualInfo* visuals = XGetVisualInfo (display, VisualScreenMask | VisualDepthMask,
- &desiredVisual, &numVisuals);
-
- if (numVisuals < 1 || visuals == 0)
- {
- XFree (visuals);
- desiredVisual.depth = 16;
-
- visuals = XGetVisualInfo (display, VisualScreenMask | VisualDepthMask,
- &desiredVisual, &numVisuals);
-
- if (numVisuals < 1 || visuals == 0)
- {
- Logger::outputDebugString ("ERROR: System doesn't support 24 or 16 bit RGB display.\n");
- Process::terminate();
- }
-
- depthIs16Bit = true;
- }
-
- XFree (visuals);
-
- // Set up the window attributes
- XSetWindowAttributes swa;
- swa.border_pixel = 0;
- swa.background_pixmap = None;
- swa.colormap = DefaultColormap (display, screen);
- swa.override_redirect = getComponent()->isAlwaysOnTop() ? True : False;
- swa.event_mask = eventMask;
-
- Window wndH = XCreateWindow (display, root,
- 0, 0, 1, 1,
- 0, 0, InputOutput, (Visual*) CopyFromParent,
- CWBorderPixel | CWColormap | CWBackPixmap | CWEventMask | CWOverrideRedirect,
- &swa);
-
- XGrabButton (display, AnyButton, AnyModifier, wndH, False,
- ButtonPressMask | ButtonReleaseMask | EnterWindowMask | LeaveWindowMask | PointerMotionMask,
- GrabModeAsync, GrabModeAsync, None, None);
-
- // Set the window context to identify the window handle object
- if (XSaveContext (display, (XID) wndH, improbableNumber, (XPointer) this))
- {
- // Failed
- jassertfalse
- Logger::outputDebugString ("Failed to create context information for window.\n");
- XDestroyWindow (display, wndH);
- wndH = 0;
- }
-
- // Set window manager hints
- XWMHints* wmHints = XAllocWMHints();
- wmHints->flags = InputHint | StateHint;
- wmHints->input = True; // Locally active input model
- wmHints->initial_state = NormalState;
- XSetWMHints (display, wndH, wmHints);
- XFree (wmHints);
-
- if ((styleFlags & windowIsSemiTransparent) != 0)
- {
- //xxx
- }
-
- if ((styleFlags & windowAppearsOnTaskbar) != 0)
- {
- //xxx
- }
-
- //XSetTransientForHint (display, wndH, RootWindow (display, DefaultScreen (display)));
-
- if ((styleFlags & windowHasTitleBar) == 0)
- removeWindowDecorations (wndH);
- else
- addWindowButtons (wndH);
-
- // Set window manager protocols
- XChangeProperty (display, wndH, wm_Protocols, XA_ATOM, 32, PropModeReplace,
- (unsigned char*) wm_ProtocolList, 2);
-
- // Set drag and drop flags
- XChangeProperty (display, wndH, XA_XdndTypeList, XA_ATOM, 32, PropModeReplace,
- (const unsigned char*) allowedMimeTypeAtoms, numElementsInArray (allowedMimeTypeAtoms));
-
- XChangeProperty (display, wndH, XA_XdndActionList, XA_ATOM, 32, PropModeReplace,
- (const unsigned char*) allowedActions, numElementsInArray (allowedActions));
-
- XChangeProperty (display, wndH, XA_XdndActionDescription, XA_STRING, 8, PropModeReplace,
- (const unsigned char*) "", 0);
-
- unsigned long dndVersion = ourDndVersion;
- XChangeProperty (display, wndH, XA_XdndAware, XA_ATOM, 32, PropModeReplace,
- (const unsigned char*) &dndVersion, 1);
-
- // Set window name
- setWindowTitle (wndH, getComponent()->getName());
-
- // Initialise the pointer and keyboard mapping
- // This is not the same as the logical pointer mapping the X server uses:
- // we don't mess with this.
- static bool mappingInitialised = false;
-
- if (! mappingInitialised)
- {
- mappingInitialised = true;
-
- const int numButtons = XGetPointerMapping (display, 0, 0);
-
- if (numButtons == 2)
- {
- pointerMap[0] = LeftButton;
- pointerMap[1] = RightButton;
- pointerMap[2] = pointerMap[3] = pointerMap[4] = NoButton;
- }
- else if (numButtons >= 3)
- {
- pointerMap[0] = LeftButton;
- pointerMap[1] = MiddleButton;
- pointerMap[2] = RightButton;
-
- if (numButtons >= 5)
- {
- pointerMap[3] = WheelUp;
- pointerMap[4] = WheelDown;
- }
- }
-
- getModifierMapping();
- }
-
- windowH = wndH;
- }
-
- void destroyWindow()
- {
- XPointer handlePointer;
- if (! XFindContext (display, (XID) windowH, improbableNumber, &handlePointer))
- XDeleteContext (display, (XID) windowH, improbableNumber);
-
- XDestroyWindow (display, windowH);
-
- // Wait for it to complete and then remove any events for this
- // window from the event queue.
- XSync (display, false);
-
- XEvent event;
- while (XCheckWindowEvent (display, windowH, eventMask, &event) == True)
- {}
- }
-
- static int64 getEventTime (::Time t) throw()
- {
- static int64 eventTimeOffset = 0x12345678;
- const int64 thisMessageTime = t;
-
- if (eventTimeOffset == 0x12345678)
- eventTimeOffset = Time::currentTimeMillis() - thisMessageTime;
-
- return eventTimeOffset + thisMessageTime;
- }
-
- static void setWindowTitle (Window xwin, const char* const title) throw()
- {
- XTextProperty nameProperty;
- char* strings[] = { (char*) title };
-
- if (XStringListToTextProperty (strings, 1, &nameProperty))
- {
- XSetWMName (display, xwin, &nameProperty);
- XSetWMIconName (display, xwin, &nameProperty);
-
- XFree (nameProperty.value);
- }
- }
-
- void updateBorderSize()
- {
- if ((styleFlags & windowHasTitleBar) == 0)
- {
- windowBorder = BorderSize (0);
- }
- else if (windowBorder.getTopAndBottom() == 0 && windowBorder.getLeftAndRight() == 0)
- {
- Atom hints = XInternAtom (display, "_NET_FRAME_EXTENTS", True);
-
- if (hints != None)
- {
- unsigned char* data = 0;
- unsigned long nitems, bytesLeft;
- Atom actualType;
- int actualFormat;
-
- if (XGetWindowProperty (display, windowH, hints, 0, 4, False,
- XA_CARDINAL, &actualType, &actualFormat, &nitems, &bytesLeft,
- &data) == Success)
- {
- const unsigned long* const sizes = (const unsigned long*) data;
-
- if (actualFormat == 32)
- windowBorder = BorderSize ((int) sizes[2], (int) sizes[0],
- (int) sizes[3], (int) sizes[1]);
-
- XFree (data);
- }
- }
- }
- }
-
- void updateBounds()
- {
- jassert (windowH != 0);
- if (windowH != 0)
- {
- Window root, child;
- unsigned int bw, depth;
-
- if (! XGetGeometry (display, (::Drawable) windowH, &root,
- &wx, &wy, (unsigned int*) &ww, (unsigned int*) &wh,
- &bw, &depth))
- {
- wx = wy = ww = wh = 0;
- }
- else if (! XTranslateCoordinates (display, windowH, root, 0, 0, &wx, &wy, &child))
- {
- wx = wy = 0;
- }
- }
- }
-
- void resetDragAndDrop()
- {
- dragAndDropFiles.clear();
- lastDropX = lastDropY = -1;
- dragAndDropCurrentMimeType = 0;
- dragAndDropSourceWindow = 0;
- srcMimeTypeAtomList.clear();
- }
-
- void sendDragAndDropMessage (XClientMessageEvent& msg)
- {
- msg.type = ClientMessage;
- msg.display = display;
- msg.window = dragAndDropSourceWindow;
- msg.format = 32;
- msg.data.l[0] = windowH;
-
- XSendEvent (display, dragAndDropSourceWindow, False, 0, (XEvent*) &msg);
- }
-
- void sendDragAndDropStatus (const bool acceptDrop, Atom dropAction)
- {
- XClientMessageEvent msg;
- zerostruct (msg);
- msg.message_type = XA_XdndStatus;
- msg.data.l[1] = (acceptDrop ? 1 : 0) | 2; // 2 indicates that we want to receive position messages
- msg.data.l[4] = dropAction;
-
- sendDragAndDropMessage (msg);
- }
-
- void sendDragAndDropLeave()
- {
- XClientMessageEvent msg;
- zerostruct (msg);
- msg.message_type = XA_XdndLeave;
- sendDragAndDropMessage (msg);
- }
-
- void sendDragAndDropFinish()
- {
- XClientMessageEvent msg;
- zerostruct (msg);
- msg.message_type = XA_XdndFinished;
- sendDragAndDropMessage (msg);
- }
-
- void handleDragAndDropStatus (const XClientMessageEvent* const clientMsg)
- {
- if ((clientMsg->data.l[1] & 1) == 0)
- {
- sendDragAndDropLeave();
-
- if (dragAndDropFiles.size() > 0)
- handleFileDragExit (dragAndDropFiles);
-
- dragAndDropFiles.clear();
- }
- }
-
- void handleDragAndDropPosition (const XClientMessageEvent* const clientMsg)
- {
- if (dragAndDropSourceWindow == 0)
- return;
-
- dragAndDropSourceWindow = clientMsg->data.l[0];
-
- const int dropX = ((int) clientMsg->data.l[2] >> 16) - getScreenX();
- const int dropY = ((int) clientMsg->data.l[2] & 0xffff) - getScreenY();
-
- if (lastDropX != dropX || lastDropY != dropY)
- {
- lastDropX = dropX;
- lastDropY = dropY;
-
- dragAndDropTimestamp = clientMsg->data.l[3];
-
- Atom targetAction = XA_XdndActionCopy;
-
- for (int i = numElementsInArray (allowedActions); --i >= 0;)
- {
- if ((Atom) clientMsg->data.l[4] == allowedActions[i])
- {
- targetAction = allowedActions[i];
- break;
- }
- }
-
- sendDragAndDropStatus (true, targetAction);
-
- if (dragAndDropFiles.size() == 0)
- updateDraggedFileList (clientMsg);
-
- if (dragAndDropFiles.size() > 0)
- handleFileDragMove (dragAndDropFiles, dropX, dropY);
- }
- }
-
- void handleDragAndDropDrop (const XClientMessageEvent* const clientMsg)
- {
- if (dragAndDropFiles.size() == 0)
- updateDraggedFileList (clientMsg);
-
- const StringArray files (dragAndDropFiles);
- const int lastX = lastDropX, lastY = lastDropY;
-
- sendDragAndDropFinish();
- resetDragAndDrop();
-
- if (files.size() > 0)
- handleFileDragDrop (files, lastX, lastY);
- }
-
- void handleDragAndDropEnter (const XClientMessageEvent* const clientMsg)
- {
- dragAndDropFiles.clear();
- srcMimeTypeAtomList.clear();
-
- dragAndDropCurrentMimeType = 0;
- const int dndCurrentVersion = (int) (clientMsg->data.l[1] & 0xff000000) >> 24;
-
- if (dndCurrentVersion < 3 || dndCurrentVersion > ourDndVersion)
- {
- dragAndDropSourceWindow = 0;
- return;
- }
-
- dragAndDropSourceWindow = clientMsg->data.l[0];
-
- if ((clientMsg->data.l[1] & 1) != 0)
- {
- Atom actual;
- int format;
- unsigned long count = 0, remaining = 0;
- unsigned char* data = 0;
-
- XGetWindowProperty (display, dragAndDropSourceWindow, XA_XdndTypeList,
- 0, 0x8000000L, False, XA_ATOM, &actual, &format,
- &count, &remaining, &data);
-
- if (data != 0)
- {
- if (actual == XA_ATOM && format == 32 && count != 0)
- {
- const unsigned long* const types = (const unsigned long*) data;
-
- for (unsigned int i = 0; i < count; ++i)
- if (types[i] != None)
- srcMimeTypeAtomList.add (types[i]);
- }
-
- XFree (data);
- }
- }
-
- if (srcMimeTypeAtomList.size() == 0)
- {
- for (int i = 2; i < 5; ++i)
- if (clientMsg->data.l[i] != None)
- srcMimeTypeAtomList.add (clientMsg->data.l[i]);
-
- if (srcMimeTypeAtomList.size() == 0)
- {
- dragAndDropSourceWindow = 0;
- return;
- }
- }
-
- for (int i = 0; i < srcMimeTypeAtomList.size() && dragAndDropCurrentMimeType == 0; ++i)
- for (int j = 0; j < numElementsInArray (allowedMimeTypeAtoms); ++j)
- if (srcMimeTypeAtomList[i] == allowedMimeTypeAtoms[j])
- dragAndDropCurrentMimeType = allowedMimeTypeAtoms[j];
-
- handleDragAndDropPosition (clientMsg);
- }
-
- void handleDragAndDropSelection (const XEvent* const evt)
- {
- dragAndDropFiles.clear();
-
- if (evt->xselection.property != 0)
- {
- StringArray lines;
-
- {
- MemoryBlock dropData;
-
- for (;;)
- {
- Atom actual;
- uint8* data = 0;
- unsigned long count = 0, remaining = 0;
- int format = 0;
-
- if (XGetWindowProperty (display, evt->xany.window, evt->xselection.property,
- dropData.getSize() / 4, 65536, 1, AnyPropertyType, &actual,
- &format, &count, &remaining, &data) == Success)
- {
- dropData.append (data, count * format / 8);
- XFree (data);
-
- if (remaining == 0)
- break;
- }
- else
- {
- XFree (data);
- break;
- }
- }
-
- lines.addLines (dropData.toString());
- }
-
- for (int i = 0; i < lines.size(); ++i)
- dragAndDropFiles.add (URL::removeEscapeChars (lines[i].fromFirstOccurrenceOf (T("file://"), false, true)));
-
- dragAndDropFiles.trim();
- dragAndDropFiles.removeEmptyStrings();
- }
- }
-
- void updateDraggedFileList (const XClientMessageEvent* const clientMsg)
- {
- dragAndDropFiles.clear();
-
- if (dragAndDropSourceWindow != None
- && dragAndDropCurrentMimeType != 0)
- {
- dragAndDropTimestamp = clientMsg->data.l[2];
-
- XConvertSelection (display,
- XA_XdndSelection,
- dragAndDropCurrentMimeType,
- XA_JXSelectionWindowProperty,
- windowH,
- dragAndDropTimestamp);
- }
- }
-
- StringArray dragAndDropFiles;
- int dragAndDropTimestamp, lastDropX, lastDropY;
-
- Atom XA_OtherMime, dragAndDropCurrentMimeType;
- Window dragAndDropSourceWindow;
-
- unsigned long allowedActions [5];
- unsigned long allowedMimeTypeAtoms [3];
- Array <Atom> srcMimeTypeAtomList;
- };
-
- ComponentPeer* Component::createNewPeer (int styleFlags, void* /*nativeWindowToAttachTo*/)
- {
- return new LinuxComponentPeer (this, styleFlags);
- }
-
- // (this callback is hooked up in the messaging code)
- void juce_windowMessageReceive (XEvent* event)
- {
- if (event->xany.window != None)
- {
- LinuxComponentPeer* const peer = LinuxComponentPeer::getPeerFor (event->xany.window);
-
- const MessageManagerLock messLock;
-
- if (ComponentPeer::isValidPeer (peer))
- peer->handleWindowMessage (event);
- }
- else
- {
- switch (event->xany.type)
- {
- case KeymapNotify:
- {
- const XKeymapEvent* const keymapEvent = (const XKeymapEvent*) &event->xkeymap;
- memcpy (keyStates, keymapEvent->key_vector, 32);
- break;
- }
-
- default:
- break;
- }
- }
- }
-
- void juce_updateMultiMonitorInfo (Array <Rectangle>& monitorCoords, const bool /*clipToWorkArea*/) throw()
- {
- #if JUCE_USE_XINERAMA
- int major_opcode, first_event, first_error;
-
- if (XQueryExtension (display, "XINERAMA", &major_opcode, &first_event, &first_error)
- && XineramaIsActive (display))
- {
- int numMonitors = 0;
- XineramaScreenInfo* const screens = XineramaQueryScreens (display, &numMonitors);
-
- if (screens != 0)
- {
- for (int i = numMonitors; --i >= 0;)
- {
- int index = screens[i].screen_number;
-
- if (index >= 0)
- {
- while (monitorCoords.size() < index)
- monitorCoords.add (Rectangle (0, 0, 0, 0));
-
- monitorCoords.set (index, Rectangle (screens[i].x_org,
- screens[i].y_org,
- screens[i].width,
- screens[i].height));
- }
- }
-
- XFree (screens);
- }
- }
-
- if (monitorCoords.size() == 0)
- #endif
- {
- Atom hints = XInternAtom (display, "_NET_WORKAREA", True);
-
- if (hints != None)
- {
- const int numMonitors = ScreenCount (display);
-
- for (int i = 0; i < numMonitors; ++i)
- {
- Window root = RootWindow (display, i);
-
- unsigned long nitems, bytesLeft;
- Atom actualType;
- int actualFormat;
- unsigned char* data = 0;
-
- if (XGetWindowProperty (display, root, hints, 0, 4, False,
- XA_CARDINAL, &actualType, &actualFormat, &nitems, &bytesLeft,
- &data) == Success)
- {
- const long* const position = (const long*) data;
-
- if (actualType == XA_CARDINAL && actualFormat == 32 && nitems == 4)
- monitorCoords.add (Rectangle (position[0], position[1],
- position[2], position[3]));
-
- XFree (data);
- }
- }
- }
-
- if (monitorCoords.size() == 0)
- {
- monitorCoords.add (Rectangle (0, 0,
- DisplayWidth (display, DefaultScreen (display)),
- DisplayHeight (display, DefaultScreen (display))));
- }
- }
- }
-
- bool Desktop::canUseSemiTransparentWindows() throw()
- {
- return false;
- }
-
- void Desktop::getMousePosition (int& x, int& y) throw()
- {
- int mouseMods;
- getMousePos (x, y, mouseMods);
- }
-
- void Desktop::setMousePosition (int x, int y) throw()
- {
- Window root = RootWindow (display, DefaultScreen (display));
- XWarpPointer (display, None, root, 0, 0, 0, 0, x, y);
- }
-
- static bool screenSaverAllowed = true;
-
- void Desktop::setScreenSaverEnabled (const bool isEnabled) throw()
- {
- if (screenSaverAllowed != isEnabled)
- {
- screenSaverAllowed = isEnabled;
-
- typedef void (*tXScreenSaverSuspend) (Display*, Bool);
- static tXScreenSaverSuspend xScreenSaverSuspend = 0;
-
- if (xScreenSaverSuspend == 0)
- {
- void* h = dlopen ("libXss.so", RTLD_GLOBAL | RTLD_NOW);
-
- if (h != 0)
- xScreenSaverSuspend = (tXScreenSaverSuspend) dlsym (h, "XScreenSaverSuspend");
- }
-
- if (xScreenSaverSuspend != 0)
- xScreenSaverSuspend (display, ! isEnabled);
- }
- }
-
- bool Desktop::isScreenSaverEnabled() throw()
- {
- return screenSaverAllowed;
- }
-
- void* juce_createMouseCursorFromImage (const Image& image, int hotspotX, int hotspotY) throw()
- {
- Window root = RootWindow (display, DefaultScreen (display));
- const unsigned int imageW = image.getWidth();
- const unsigned int imageH = image.getHeight();
- unsigned int cursorW, cursorH;
-
- if (! XQueryBestCursor (display, root, imageW, imageH, &cursorW, &cursorH))
- return 0;
-
- Image im (Image::ARGB, cursorW, cursorH, true);
- Graphics g (im);
-
- if (imageW > cursorW || imageH > cursorH)
- {
- hotspotX = (hotspotX * cursorW) / imageW;
- hotspotY = (hotspotY * cursorH) / imageH;
-
- g.drawImageWithin (&image, 0, 0, imageW, imageH,
- RectanglePlacement::xLeft | RectanglePlacement::yTop | RectanglePlacement::onlyReduceInSize,
- false);
- }
- else
- {
- g.drawImageAt (&image, 0, 0);
- }
-
- const int stride = (cursorW + 7) >> 3;
- uint8* const maskPlane = (uint8*) juce_calloc (stride * cursorH);
- uint8* const sourcePlane = (uint8*) juce_calloc (stride * cursorH);
-
- bool msbfirst = (BitmapBitOrder (display) == MSBFirst);
-
- for (int y = cursorH; --y >= 0;)
- {
- for (int x = cursorW; --x >= 0;)
- {
- const uint8 mask = (uint8) (1 << (msbfirst ? (7 - (x & 7)) : (x & 7)));
- const int offset = y * stride + (x >> 3);
-
- const Colour c (im.getPixelAt (x, y));
-
- if (c.getAlpha() >= 128)
- maskPlane[offset] |= mask;
-
- if (c.getBrightness() >= 0.5f)
- sourcePlane[offset] |= mask;
- }
- }
-
- Pixmap sourcePixmap = XCreatePixmapFromBitmapData (display, root, (char*) sourcePlane, cursorW, cursorH, 0xffff, 0, 1);
- Pixmap maskPixmap = XCreatePixmapFromBitmapData (display, root, (char*) maskPlane, cursorW, cursorH, 0xffff, 0, 1);
-
- juce_free (maskPlane);
- juce_free (sourcePlane);
-
- XColor white, black;
- black.red = black.green = black.blue = 0;
- white.red = white.green = white.blue = 0xffff;
-
- void* result = (void*) XCreatePixmapCursor (display, sourcePixmap, maskPixmap, &white, &black, hotspotX, hotspotY);
-
- XFreePixmap (display, sourcePixmap);
- XFreePixmap (display, maskPixmap);
-
- return result;
- }
-
- void juce_deleteMouseCursor (void* const cursorHandle, const bool) throw()
- {
- if (cursorHandle != None)
- XFreeCursor (display, (Cursor) cursorHandle);
- }
-
- void* juce_createStandardMouseCursor (MouseCursor::StandardCursorType type) throw()
- {
- unsigned int shape;
-
- switch (type)
- {
- case MouseCursor::NoCursor:
- {
- const Image im (Image::ARGB, 16, 16, true);
- return juce_createMouseCursorFromImage (im, 0, 0);
- }
-
- case MouseCursor::NormalCursor:
- return (void*) None; // Use parent cursor
-
- case MouseCursor::DraggingHandCursor:
- {
- static unsigned char dragHandData[] = {71,73,70,56,57,97,16,0,16,0,145,2,0,0,0,0,255,255,255,0,
- 0,0,0,0,0,33,249,4,1,0,0,2,0,44,0,0,0,0,16,0,
- 16,0,0,2,52,148,47,0,200,185,16,130,90,12,74,139,107,84,123,39,
- 132,117,151,116,132,146,248,60,209,138,98,22,203,114,34,236,37,52,77,217,
- 247,154,191,119,110,240,193,128,193,95,163,56,60,234,98,135,2,0,59 };
- const int dragHandDataSize = 99;
-
- Image* const im = ImageFileFormat::loadFrom ((const char*) dragHandData, dragHandDataSize);
- void* const dragHandCursor = juce_createMouseCursorFromImage (*im, 8, 7);
- delete im;
-
- return dragHandCursor;
- }
-
- case MouseCursor::CopyingCursor:
- {
- static unsigned char copyCursorData[] = {71,73,70,56,57,97,21,0,21,0,145,0,0,0,0,0,255,255,255,0,
- 128,128,255,255,255,33,249,4,1,0,0,3,0,44,0,0,0,0,21,0,
- 21,0,0,2,72,4,134,169,171,16,199,98,11,79,90,71,161,93,56,111,
- 78,133,218,215,137,31,82,154,100,200,86,91,202,142,12,108,212,87,235,174,
- 15,54,214,126,237,226,37,96,59,141,16,37,18,201,142,157,230,204,51,112,
- 252,114,147,74,83,5,50,68,147,208,217,16,71,149,252,124,5,0,59,0,0 };
- const int copyCursorSize = 119;
-
- Image* const im = ImageFileFormat::loadFrom ((const char*) copyCursorData, copyCursorSize);
- void* const copyCursor = juce_createMouseCursorFromImage (*im, 1, 3);
- delete im;
-
- return copyCursor;
- }
-
- case MouseCursor::WaitCursor:
- shape = XC_watch;
- break;
-
- case MouseCursor::IBeamCursor:
- shape = XC_xterm;
- break;
-
- case MouseCursor::PointingHandCursor:
- shape = XC_hand2;
- break;
-
- case MouseCursor::LeftRightResizeCursor:
- shape = XC_sb_h_double_arrow;
- break;
-
- case MouseCursor::UpDownResizeCursor:
- shape = XC_sb_v_double_arrow;
- break;
-
- case MouseCursor::UpDownLeftRightResizeCursor:
- shape = XC_fleur;
- break;
-
- case MouseCursor::TopEdgeResizeCursor:
- shape = XC_top_side;
- break;
-
- case MouseCursor::BottomEdgeResizeCursor:
- shape = XC_bottom_side;
- break;
-
- case MouseCursor::LeftEdgeResizeCursor:
- shape = XC_left_side;
- break;
-
- case MouseCursor::RightEdgeResizeCursor:
- shape = XC_right_side;
- break;
-
- case MouseCursor::TopLeftCornerResizeCursor:
- shape = XC_top_left_corner;
- break;
-
- case MouseCursor::TopRightCornerResizeCursor:
- shape = XC_top_right_corner;
- break;
-
- case MouseCursor::BottomLeftCornerResizeCursor:
- shape = XC_bottom_left_corner;
- break;
-
- case MouseCursor::BottomRightCornerResizeCursor:
- shape = XC_bottom_right_corner;
- break;
-
- case MouseCursor::CrosshairCursor:
- shape = XC_crosshair;
- break;
-
- default:
- return (void*) None; // Use parent cursor
- }
-
- return (void*) XCreateFontCursor (display, shape);
- }
-
- void MouseCursor::showInWindow (ComponentPeer* peer) const throw()
- {
- LinuxComponentPeer* const lp = dynamic_cast <LinuxComponentPeer*> (peer);
-
- if (lp != 0)
- lp->showMouseCursor ((Cursor) getHandle());
- }
-
- void MouseCursor::showInAllWindows() const throw()
- {
- for (int i = ComponentPeer::getNumPeers(); --i >= 0;)
- showInWindow (ComponentPeer::getPeer (i));
- }
-
- Image* juce_createIconForFile (const File& file)
- {
- return 0;
- }
-
- #if JUCE_OPENGL
-
- class WindowedGLContext : public OpenGLContext
- {
- public:
- WindowedGLContext (Component* const component,
- const OpenGLPixelFormat& pixelFormat_,
- GLXContext sharedContext)
- : renderContext (0),
- embeddedWindow (0),
- pixelFormat (pixelFormat_)
- {
- jassert (component != 0);
- LinuxComponentPeer* const peer = dynamic_cast <LinuxComponentPeer*> (component->getTopLevelComponent()->getPeer());
- if (peer == 0)
- return;
-
- XSync (display, False);
-
- GLint attribs [64];
- int n = 0;
- attribs[n++] = GLX_RGBA;
- attribs[n++] = GLX_DOUBLEBUFFER;
- attribs[n++] = GLX_RED_SIZE;
- attribs[n++] = pixelFormat.redBits;
- attribs[n++] = GLX_GREEN_SIZE;
- attribs[n++] = pixelFormat.greenBits;
- attribs[n++] = GLX_BLUE_SIZE;
- attribs[n++] = pixelFormat.blueBits;
- attribs[n++] = GLX_ALPHA_SIZE;
- attribs[n++] = pixelFormat.alphaBits;
- attribs[n++] = GLX_DEPTH_SIZE;
- attribs[n++] = pixelFormat.depthBufferBits;
- attribs[n++] = GLX_STENCIL_SIZE;
- attribs[n++] = pixelFormat.stencilBufferBits;
- attribs[n++] = GLX_ACCUM_RED_SIZE;
- attribs[n++] = pixelFormat.accumulationBufferRedBits;
- attribs[n++] = GLX_ACCUM_GREEN_SIZE;
- attribs[n++] = pixelFormat.accumulationBufferGreenBits;
- attribs[n++] = GLX_ACCUM_BLUE_SIZE;
- attribs[n++] = pixelFormat.accumulationBufferBlueBits;
- attribs[n++] = GLX_ACCUM_ALPHA_SIZE;
- attribs[n++] = pixelFormat.accumulationBufferAlphaBits;
-
- // xxx not sure how to do fullSceneAntiAliasingNumSamples on linux..
-
- attribs[n++] = None;
-
- XVisualInfo* const bestVisual = glXChooseVisual (display, DefaultScreen (display), attribs);
-
- if (bestVisual == 0)
- return;
-
- renderContext = glXCreateContext (display, bestVisual, sharedContext, GL_TRUE);
-
- Window windowH = (Window) peer->getNativeHandle();
-
- Colormap colourMap = XCreateColormap (display, windowH, bestVisual->visual, AllocNone);
- XSetWindowAttributes swa;
- swa.colormap = colourMap;
- swa.border_pixel = 0;
- swa.event_mask = ExposureMask | StructureNotifyMask;
-
- embeddedWindow = XCreateWindow (display, windowH,
- 0, 0, 1, 1, 0,
- bestVisual->depth,
- InputOutput,
- bestVisual->visual,
- CWBorderPixel | CWColormap | CWEventMask,
- &swa);
-
- XSaveContext (display, (XID) embeddedWindow, improbableNumber, (XPointer) peer);
-
- XMapWindow (display, embeddedWindow);
- XFreeColormap (display, colourMap);
-
- XFree (bestVisual);
- XSync (display, False);
- }
-
- ~WindowedGLContext()
- {
- makeInactive();
-
- glXDestroyContext (display, renderContext);
-
- XUnmapWindow (display, embeddedWindow);
- XDestroyWindow (display, embeddedWindow);
- }
-
- bool makeActive() const throw()
- {
- jassert (renderContext != 0);
-
- return glXMakeCurrent (display, embeddedWindow, renderContext)
- && XSync (display, False);
- }
-
- bool makeInactive() const throw()
- {
- return (! isActive()) || glXMakeCurrent (display, None, 0);
- }
-
- bool isActive() const throw()
- {
- return glXGetCurrentContext() == renderContext;
- }
-
- const OpenGLPixelFormat getPixelFormat() const
- {
- return pixelFormat;
- }
-
- void* getRawContext() const throw()
- {
- return renderContext;
- }
-
- void updateWindowPosition (int x, int y, int w, int h, int)
- {
- XMoveResizeWindow (display, embeddedWindow,
- x, y, jmax (1, w), jmax (1, h));
- }
-
- void swapBuffers()
- {
- glXSwapBuffers (display, embeddedWindow);
- }
-
- bool setSwapInterval (const int numFramesPerSwap)
- {
- // xxx needs doing..
- return false;
- }
-
- int getSwapInterval() const
- {
- // xxx needs doing..
- return 0;
- }
-
- void repaint()
- {
- }
-
- juce_UseDebuggingNewOperator
-
- GLXContext renderContext;
-
- private:
- Window embeddedWindow;
- OpenGLPixelFormat pixelFormat;
-
- WindowedGLContext (const WindowedGLContext&);
- const WindowedGLContext& operator= (const WindowedGLContext&);
- };
-
- OpenGLContext* OpenGLContext::createContextForWindow (Component* const component,
- const OpenGLPixelFormat& pixelFormat,
- const OpenGLContext* const contextToShareWith)
- {
- WindowedGLContext* c = new WindowedGLContext (component, pixelFormat,
- contextToShareWith != 0 ? (GLXContext) contextToShareWith->getRawContext() : 0);
-
- if (c->renderContext == 0)
- deleteAndZero (c);
-
- return c;
- }
-
- void juce_glViewport (const int w, const int h)
- {
- glViewport (0, 0, w, h);
- }
-
- void OpenGLPixelFormat::getAvailablePixelFormats (Component* component,
- OwnedArray <OpenGLPixelFormat>& results)
- {
- results.add (new OpenGLPixelFormat()); // xxx
- }
-
- #endif
-
- static void initClipboard (Window root, Atom* cutBuffers) throw()
- {
- static bool init = false;
-
- if (! init)
- {
- init = true;
-
- // Make sure all cut buffers exist before use
- for (int i = 0; i < 8; i++)
- {
- XChangeProperty (display, root, cutBuffers[i],
- XA_STRING, 8, PropModeAppend, NULL, 0);
- }
- }
- }
-
- // Clipboard implemented currently using cut buffers
- // rather than the more powerful selection method
- void SystemClipboard::copyTextToClipboard (const String& clipText) throw()
- {
- Window root = RootWindow (display, DefaultScreen (display));
- Atom cutBuffers[8] = { XA_CUT_BUFFER0, XA_CUT_BUFFER1, XA_CUT_BUFFER2, XA_CUT_BUFFER3,
- XA_CUT_BUFFER4, XA_CUT_BUFFER5, XA_CUT_BUFFER6, XA_CUT_BUFFER7 };
-
- initClipboard (root, cutBuffers);
-
- XRotateWindowProperties (display, root, cutBuffers, 8, 1);
- XChangeProperty (display, root, cutBuffers[0],
- XA_STRING, 8, PropModeReplace, (const unsigned char*) (const char*) clipText,
- clipText.length());
- }
-
- const String SystemClipboard::getTextFromClipboard() throw()
- {
- const int bufSize = 64; // in words
- String returnData;
- int byteOffset = 0;
-
- Window root = RootWindow (display, DefaultScreen (display));
-
- Atom cutBuffers[8] = { XA_CUT_BUFFER0, XA_CUT_BUFFER1, XA_CUT_BUFFER2, XA_CUT_BUFFER3,
- XA_CUT_BUFFER4, XA_CUT_BUFFER5, XA_CUT_BUFFER6, XA_CUT_BUFFER7 };
-
- initClipboard (root, cutBuffers);
-
- for (;;)
- {
- unsigned long bytesLeft = 0, nitems = 0;
- unsigned char* clipData = 0;
- int actualFormat = 0;
- Atom actualType;
-
- if (XGetWindowProperty (display, root, cutBuffers[0], byteOffset >> 2, bufSize,
- False, XA_STRING, &actualType, &actualFormat, &nitems, &bytesLeft,
- &clipData) == Success)
- {
- if (actualType == XA_STRING && actualFormat == 8)
- {
- byteOffset += nitems;
- returnData += String ((const char*) clipData, nitems);
- }
- else
- {
- bytesLeft = 0;
- }
-
- if (clipData != 0)
- XFree (clipData);
- }
-
- if (bytesLeft == 0)
- break;
- }
-
- return returnData;
- }
-
- bool DragAndDropContainer::performExternalDragDropOfFiles (const StringArray& files, const bool canMoveFiles)
- {
- jassertfalse // not implemented!
- return false;
- }
-
- bool DragAndDropContainer::performExternalDragDropOfText (const String& text)
- {
- jassertfalse // not implemented!
- return false;
- }
-
- void SystemTrayIconComponent::setIconImage (const Image& newImage)
- {
- if (! isOnDesktop ())
- addToDesktop (0);
-
- LinuxComponentPeer* const wp = dynamic_cast <LinuxComponentPeer*> (getPeer());
-
- if (wp != 0)
- {
- wp->setTaskBarIcon (newImage);
-
- setVisible (true);
- toFront (false);
- repaint();
- }
- }
-
- void SystemTrayIconComponent::paint (Graphics& g)
- {
- LinuxComponentPeer* const wp = dynamic_cast <LinuxComponentPeer*> (getPeer());
-
- if (wp != 0)
- {
- const Image* const image = wp->getTaskbarIcon();
-
- if (image != 0)
- g.drawImageAt (image, 0, 0, false);
- }
- }
-
- void SystemTrayIconComponent::setIconTooltip (const String& tooltip)
- {
- // xxx not yet implemented!
- }
-
- void PlatformUtilities::beep()
- {
- fprintf (stdout, "\a");
- fflush (stdout);
- }
-
- bool AlertWindow::showNativeDialogBox (const String& title,
- const String& bodyText,
- bool isOkCancel)
- {
- // xxx this is supposed to pop up an alert!
- Logger::outputDebugString (title + ": " + bodyText);
-
- // use a non-native one for the time being..
- if (isOkCancel)
- return AlertWindow::showOkCancelBox (AlertWindow::NoIcon, title, bodyText);
- else
- AlertWindow::showMessageBox (AlertWindow::NoIcon, title, bodyText);
-
- return true;
- }
-
- const int KeyPress::spaceKey = XK_space & 0xff;
- const int KeyPress::returnKey = XK_Return & 0xff;
- const int KeyPress::escapeKey = XK_Escape & 0xff;
- const int KeyPress::backspaceKey = XK_BackSpace & 0xff;
- const int KeyPress::leftKey = (XK_Left & 0xff) | extendedKeyModifier;
- const int KeyPress::rightKey = (XK_Right & 0xff) | extendedKeyModifier;
- const int KeyPress::upKey = (XK_Up & 0xff) | extendedKeyModifier;
- const int KeyPress::downKey = (XK_Down & 0xff) | extendedKeyModifier;
- const int KeyPress::pageUpKey = (XK_Page_Up & 0xff) | extendedKeyModifier;
- const int KeyPress::pageDownKey = (XK_Page_Down & 0xff) | extendedKeyModifier;
- const int KeyPress::endKey = (XK_End & 0xff) | extendedKeyModifier;
- const int KeyPress::homeKey = (XK_Home & 0xff) | extendedKeyModifier;
- const int KeyPress::insertKey = (XK_Insert & 0xff) | extendedKeyModifier;
- const int KeyPress::deleteKey = (XK_Delete & 0xff) | extendedKeyModifier;
- const int KeyPress::tabKey = XK_Tab & 0xff;
- const int KeyPress::F1Key = (XK_F1 & 0xff) | extendedKeyModifier;
- const int KeyPress::F2Key = (XK_F2 & 0xff) | extendedKeyModifier;
- const int KeyPress::F3Key = (XK_F3 & 0xff) | extendedKeyModifier;
- const int KeyPress::F4Key = (XK_F4 & 0xff) | extendedKeyModifier;
- const int KeyPress::F5Key = (XK_F5 & 0xff) | extendedKeyModifier;
- const int KeyPress::F6Key = (XK_F6 & 0xff) | extendedKeyModifier;
- const int KeyPress::F7Key = (XK_F7 & 0xff) | extendedKeyModifier;
- const int KeyPress::F8Key = (XK_F8 & 0xff) | extendedKeyModifier;
- const int KeyPress::F9Key = (XK_F9 & 0xff) | extendedKeyModifier;
- const int KeyPress::F10Key = (XK_F10 & 0xff) | extendedKeyModifier;
- const int KeyPress::F11Key = (XK_F11 & 0xff) | extendedKeyModifier;
- const int KeyPress::F12Key = (XK_F12 & 0xff) | extendedKeyModifier;
- const int KeyPress::F13Key = (XK_F13 & 0xff) | extendedKeyModifier;
- const int KeyPress::F14Key = (XK_F14 & 0xff) | extendedKeyModifier;
- const int KeyPress::F15Key = (XK_F15 & 0xff) | extendedKeyModifier;
- const int KeyPress::F16Key = (XK_F16 & 0xff) | extendedKeyModifier;
- const int KeyPress::numberPad0 = (XK_KP_0 & 0xff) | extendedKeyModifier;
- const int KeyPress::numberPad1 = (XK_KP_1 & 0xff) | extendedKeyModifier;
- const int KeyPress::numberPad2 = (XK_KP_2 & 0xff) | extendedKeyModifier;
- const int KeyPress::numberPad3 = (XK_KP_3 & 0xff) | extendedKeyModifier;
- const int KeyPress::numberPad4 = (XK_KP_4 & 0xff) | extendedKeyModifier;
- const int KeyPress::numberPad5 = (XK_KP_5 & 0xff) | extendedKeyModifier;
- const int KeyPress::numberPad6 = (XK_KP_6 & 0xff) | extendedKeyModifier;
- const int KeyPress::numberPad7 = (XK_KP_7 & 0xff)| extendedKeyModifier;
- const int KeyPress::numberPad8 = (XK_KP_8 & 0xff)| extendedKeyModifier;
- const int KeyPress::numberPad9 = (XK_KP_9 & 0xff)| extendedKeyModifier;
- const int KeyPress::numberPadAdd = (XK_KP_Add & 0xff)| extendedKeyModifier;
- const int KeyPress::numberPadSubtract = (XK_KP_Subtract & 0xff)| extendedKeyModifier;
- const int KeyPress::numberPadMultiply = (XK_KP_Multiply & 0xff)| extendedKeyModifier;
- const int KeyPress::numberPadDivide = (XK_KP_Divide & 0xff)| extendedKeyModifier;
- const int KeyPress::numberPadSeparator = (XK_KP_Separator & 0xff)| extendedKeyModifier;
- const int KeyPress::numberPadDecimalPoint = (XK_KP_Decimal & 0xff)| extendedKeyModifier;
- const int KeyPress::numberPadEquals = (XK_KP_Equal & 0xff)| extendedKeyModifier;
- const int KeyPress::numberPadDelete = (XK_KP_Delete & 0xff)| extendedKeyModifier;
- const int KeyPress::playKey = (0xffeeff00) | extendedKeyModifier;
- const int KeyPress::stopKey = (0xffeeff01) | extendedKeyModifier;
- const int KeyPress::fastForwardKey = (0xffeeff02) | extendedKeyModifier;
- const int KeyPress::rewindKey = (0xffeeff03) | extendedKeyModifier;
-
- END_JUCE_NAMESPACE
-
- #endif
- /********* End of inlined file: juce_linux_Windowing.cpp *********/
-
- #endif
-
- #endif
-
- //==============================================================================
- #if JUCE_MAC
-
- /********* Start of inlined file: juce_mac_Files.cpp *********/
-
- #include <ApplicationServices/ApplicationServices.h>
- #include <sys/stat.h>
- #include <sys/dir.h>
- #include <sys/param.h>
- #include <sys/mount.h>
- #include <unistd.h>
- #include <fnmatch.h>
- #include <utime.h>
- #include <pwd.h>
- #include <fcntl.h>
-
- BEGIN_JUCE_NAMESPACE
-
- /*
- Note that a lot of methods that you'd expect to find in this file actually
- live in juce_posix_SharedCode.cpp!
- */
-
- /********* Start of inlined file: juce_posix_SharedCode.cpp *********/
- /*
- This file contains posix routines that are common to both the Linux and Mac builds.
-
- It gets included directly in the cpp files for these platforms.
- */
-
- CriticalSection::CriticalSection() throw()
- {
- pthread_mutexattr_t atts;
- pthread_mutexattr_init (&atts);
- pthread_mutexattr_settype (&atts, PTHREAD_MUTEX_RECURSIVE);
- pthread_mutex_init (&internal, &atts);
- }
-
- CriticalSection::~CriticalSection() throw()
- {
- pthread_mutex_destroy (&internal);
- }
-
- void CriticalSection::enter() const throw()
- {
- pthread_mutex_lock (&internal);
- }
-
- bool CriticalSection::tryEnter() const throw()
- {
- return pthread_mutex_trylock (&internal) == 0;
- }
-
- void CriticalSection::exit() const throw()
- {
- pthread_mutex_unlock (&internal);
- }
-
- struct EventStruct
- {
- pthread_cond_t condition;
- pthread_mutex_t mutex;
- bool triggered;
- };
-
- WaitableEvent::WaitableEvent() throw()
- {
- EventStruct* const es = new EventStruct();
- es->triggered = false;
-
- pthread_cond_init (&es->condition, 0);
- pthread_mutex_init (&es->mutex, 0);
-
- internal = es;
- }
-
- WaitableEvent::~WaitableEvent() throw()
- {
- EventStruct* const es = (EventStruct*) internal;
-
- pthread_cond_destroy (&es->condition);
- pthread_mutex_destroy (&es->mutex);
-
- delete es;
- }
-
- bool WaitableEvent::wait (const int timeOutMillisecs) const throw()
- {
- EventStruct* const es = (EventStruct*) internal;
-
- bool ok = true;
- pthread_mutex_lock (&es->mutex);
-
- if (timeOutMillisecs < 0)
- {
- while (! es->triggered)
- pthread_cond_wait (&es->condition, &es->mutex);
- }
- else
- {
- while (! es->triggered)
- {
- struct timeval t;
- gettimeofday (&t, 0);
-
- struct timespec time;
- time.tv_sec = t.tv_sec + (timeOutMillisecs / 1000);
- time.tv_nsec = (t.tv_usec + ((timeOutMillisecs % 1000) * 1000)) * 1000;
-
- if (time.tv_nsec >= 1000000000)
- {
- time.tv_nsec -= 1000000000;
- time.tv_sec++;
- }
-
- if (pthread_cond_timedwait (&es->condition, &es->mutex, &time) == ETIMEDOUT)
- {
- ok = false;
- break;
- }
- }
- }
-
- es->triggered = false;
-
- pthread_mutex_unlock (&es->mutex);
- return ok;
- }
-
- void WaitableEvent::signal() const throw()
- {
- EventStruct* const es = (EventStruct*) internal;
-
- pthread_mutex_lock (&es->mutex);
- es->triggered = true;
- pthread_cond_broadcast (&es->condition);
- pthread_mutex_unlock (&es->mutex);
- }
-
- void WaitableEvent::reset() const throw()
- {
- EventStruct* const es = (EventStruct*) internal;
-
- pthread_mutex_lock (&es->mutex);
- es->triggered = false;
- pthread_mutex_unlock (&es->mutex);
- }
-
- void JUCE_CALLTYPE Thread::sleep (int millisecs) throw()
- {
- struct timespec time;
- time.tv_sec = millisecs / 1000;
- time.tv_nsec = (millisecs % 1000) * 1000000;
- nanosleep (&time, 0);
- }
-
- const tchar File::separator = T('/');
- const tchar* File::separatorString = T("/");
-
- bool juce_copyFile (const String& s, const String& d) throw();
-
- static bool juce_stat (const String& fileName, struct stat& info) throw()
- {
- return fileName.isNotEmpty()
- && (stat (fileName.toUTF8(), &info) == 0);
- }
-
- bool juce_isDirectory (const String& fileName) throw()
- {
- struct stat info;
-
- return fileName.isEmpty()
- || (juce_stat (fileName, info)
- && ((info.st_mode & S_IFDIR) != 0));
- }
-
- bool juce_fileExists (const String& fileName, const bool dontCountDirectories) throw()
- {
- if (fileName.isEmpty())
- return false;
-
- const char* const fileNameUTF8 = fileName.toUTF8();
- bool exists = access (fileNameUTF8, F_OK) == 0;
-
- if (exists && dontCountDirectories)
- {
- struct stat info;
- const int res = stat (fileNameUTF8, &info);
-
- if (res == 0 && (info.st_mode & S_IFDIR) != 0)
- exists = false;
- }
-
- return exists;
- }
-
- int64 juce_getFileSize (const String& fileName) throw()
- {
- struct stat info;
- return juce_stat (fileName, info) ? info.st_size : 0;
- }
-
- bool juce_canWriteToFile (const String& fileName) throw()
- {
- return access (fileName.toUTF8(), W_OK) == 0;
- }
-
- bool juce_deleteFile (const String& fileName) throw()
- {
- const char* const fileNameUTF8 = fileName.toUTF8();
-
- if (juce_isDirectory (fileName))
- return rmdir (fileNameUTF8) == 0;
- else
- return remove (fileNameUTF8) == 0;
- }
-
- bool juce_moveFile (const String& source, const String& dest) throw()
- {
- if (rename (source.toUTF8(), dest.toUTF8()) == 0)
- return true;
-
- if (juce_canWriteToFile (source)
- && juce_copyFile (source, dest))
- {
- if (juce_deleteFile (source))
- return true;
-
- juce_deleteFile (dest);
- }
-
- return false;
- }
-
- void juce_createDirectory (const String& fileName) throw()
- {
- mkdir (fileName.toUTF8(), 0777);
- }
-
- void* juce_fileOpen (const String& fileName, bool forWriting) throw()
- {
- const char* const fileNameUTF8 = fileName.toUTF8();
- int flags = O_RDONLY;
-
- if (forWriting)
- {
- if (juce_fileExists (fileName, false))
- {
- const int f = open (fileNameUTF8, O_RDWR, 00644);
-
- if (f != -1)
- lseek (f, 0, SEEK_END);
-
- return (void*) f;
- }
- else
- {
- flags = O_RDWR + O_CREAT;
- }
- }
-
- return (void*) open (fileNameUTF8, flags, 00644);
- }
-
- void juce_fileClose (void* handle) throw()
- {
- if (handle != 0)
- close ((int) (pointer_sized_int) handle);
- }
-
- int juce_fileRead (void* handle, void* buffer, int size) throw()
- {
- if (handle != 0)
- return read ((int) (pointer_sized_int) handle, buffer, size);
-
- return 0;
- }
-
- int juce_fileWrite (void* handle, const void* buffer, int size) throw()
- {
- if (handle != 0)
- return write ((int) (pointer_sized_int) handle, buffer, size);
-
- return 0;
- }
-
- int64 juce_fileSetPosition (void* handle, int64 pos) throw()
- {
- if (handle != 0 && lseek ((int) (pointer_sized_int) handle, pos, SEEK_SET) == pos)
- return pos;
-
- return -1;
- }
-
- int64 juce_fileGetPosition (void* handle) throw()
- {
- if (handle != 0)
- return lseek ((int) (pointer_sized_int) handle, 0, SEEK_CUR);
- else
- return -1;
- }
-
- void juce_fileFlush (void* handle) throw()
- {
- if (handle != 0)
- fsync ((int) (pointer_sized_int) handle);
- }
-
- // if this file doesn't exist, find a parent of it that does..
- static bool doStatFS (const File* file, struct statfs& result) throw()
- {
- File f (*file);
-
- for (int i = 5; --i >= 0;)
- {
- if (f.exists())
- break;
-
- f = f.getParentDirectory();
- }
-
- return statfs (f.getFullPathName().toUTF8(), &result) == 0;
- }
-
- int64 File::getBytesFreeOnVolume() const throw()
- {
- int64 free_space = 0;
-
- struct statfs buf;
- if (doStatFS (this, buf))
- // Note: this returns space available to non-super user
- free_space = (int64) buf.f_bsize * (int64) buf.f_bavail;
-
- return free_space;
- }
-
- const String juce_getVolumeLabel (const String& filenameOnVolume,
- int& volumeSerialNumber) throw()
- {
- // There is no equivalent on Linux
- volumeSerialNumber = 0;
- return String::empty;
- }
-
- #if JUCE_64BIT
- #define filedesc ((long long) internal)
- #else
- #define filedesc ((int) internal)
- #endif
-
- InterProcessLock::InterProcessLock (const String& name_) throw()
- : internal (0),
- name (name_),
- reentrancyLevel (0)
- {
- #if JUCE_MAC
- // (don't use getSpecialLocation() to avoid the temp folder being different for each app)
- const File temp (File (T("~/Library/Caches/Juce")).getChildFile (name));
- #else
- const File temp (File::getSpecialLocation (File::tempDirectory).getChildFile (name));
- #endif
-
- temp.create();
-
- internal = (void*) open (temp.getFullPathName().toUTF8(), O_RDWR);
- }
-
- InterProcessLock::~InterProcessLock() throw()
- {
- while (reentrancyLevel > 0)
- this->exit();
-
- close (filedesc);
- }
-
- bool InterProcessLock::enter (const int timeOutMillisecs) throw()
- {
- if (internal == 0)
- return false;
-
- if (reentrancyLevel != 0)
- return true;
-
- const int64 endTime = Time::currentTimeMillis() + timeOutMillisecs;
-
- struct flock fl;
- zerostruct (fl);
- fl.l_whence = SEEK_SET;
- fl.l_type = F_WRLCK;
-
- for (;;)
- {
- const int result = fcntl (filedesc, F_SETLK, &fl);
-
- if (result >= 0)
- {
- ++reentrancyLevel;
- return true;
- }
-
- if (errno != EINTR)
- {
- if (timeOutMillisecs == 0
- || (timeOutMillisecs > 0 && Time::currentTimeMillis() >= endTime))
- break;
-
- Thread::sleep (10);
- }
- }
-
- return false;
- }
-
- void InterProcessLock::exit() throw()
- {
- if (reentrancyLevel > 0 && internal != 0)
- {
- --reentrancyLevel;
-
- struct flock fl;
- zerostruct (fl);
- fl.l_whence = SEEK_SET;
- fl.l_type = F_UNLCK;
-
- for (;;)
- {
- const int result = fcntl (filedesc, F_SETLKW, &fl);
-
- if (result >= 0 || errno != EINTR)
- break;
- }
- }
- }
- /********* End of inlined file: juce_posix_SharedCode.cpp *********/
-
- static File executableFile;
-
- void PlatformUtilities::copyToStr255 (Str255& d, const String& s)
- {
- unsigned char* t = (unsigned char*) d;
- t[0] = jmin (254, s.length());
- s.copyToBuffer ((char*) t + 1, 254);
- }
-
- void PlatformUtilities::copyToStr63 (Str63& d, const String& s)
- {
- unsigned char* t = (unsigned char*) d;
- t[0] = jmin (62, s.length());
- s.copyToBuffer ((char*) t + 1, 62);
- }
-
- const String PlatformUtilities::cfStringToJuceString (CFStringRef cfString)
- {
- String result;
-
- if (cfString != 0)
- {
- #if JUCE_STRINGS_ARE_UNICODE
- CFRange range = { 0, CFStringGetLength (cfString) };
- UniChar* const u = (UniChar*) juce_malloc (sizeof (UniChar) * (range.length + 1));
-
- CFStringGetCharacters (cfString, range, u);
- u[range.length] = 0;
-
- result = convertUTF16ToString (u);
-
- juce_free (u);
- #else
- const int len = CFStringGetLength (cfString);
- char* buffer = (char*) juce_malloc (len + 1);
- CFStringGetCString (cfString, buffer, len + 1, CFStringGetSystemEncoding());
- result = buffer;
- juce_free (buffer);
- #endif
- }
-
- return result;
- }
-
- CFStringRef PlatformUtilities::juceStringToCFString (const String& s)
- {
- #if JUCE_STRINGS_ARE_UNICODE
- const int len = s.length();
- const juce_wchar* t = (const juce_wchar*) s;
-
- UniChar* temp = (UniChar*) juce_malloc (sizeof (UniChar) * len + 4);
-
- for (int i = 0; i <= len; ++i)
- temp[i] = t[i];
-
- CFStringRef result = CFStringCreateWithCharacters (kCFAllocatorDefault, temp, len);
- juce_free (temp);
-
- return result;
-
- #else
- return CFStringCreateWithCString (kCFAllocatorDefault,
- (const char*) s,
- CFStringGetSystemEncoding());
- #endif
- }
-
- const String PlatformUtilities::convertUTF16ToString (const UniChar* utf16)
- {
- String s;
-
- while (*utf16 != 0)
- s += (juce_wchar) *utf16++;
-
- return s;
- }
-
- const String PlatformUtilities::convertToPrecomposedUnicode (const String& s)
- {
- UnicodeMapping map;
-
- map.unicodeEncoding = CreateTextEncoding (kTextEncodingUnicodeDefault,
- kUnicodeNoSubset,
- kTextEncodingDefaultFormat);
-
- map.otherEncoding = CreateTextEncoding (kTextEncodingUnicodeDefault,
- kUnicodeCanonicalCompVariant,
- kTextEncodingDefaultFormat);
-
- map.mappingVersion = kUnicodeUseLatestMapping;
-
- UnicodeToTextInfo conversionInfo = 0;
- String result;
-
- if (CreateUnicodeToTextInfo (&map, &conversionInfo) == noErr)
- {
- const int len = s.length();
-
- UniChar* const tempIn = (UniChar*) juce_calloc (sizeof (UniChar) * len + 4);
- UniChar* const tempOut = (UniChar*) juce_calloc (sizeof (UniChar) * len + 4);
-
- for (int i = 0; i <= len; ++i)
- tempIn[i] = s[i];
-
- ByteCount bytesRead = 0;
- ByteCount outputBufferSize = 0;
-
- if (ConvertFromUnicodeToText (conversionInfo,
- len * sizeof (UniChar), tempIn,
- kUnicodeDefaultDirectionMask,
- 0, 0, 0, 0,
- len * sizeof (UniChar), &bytesRead,
- &outputBufferSize, tempOut) == noErr)
- {
- result.preallocateStorage (bytesRead / sizeof (UniChar) + 2);
-
- tchar* t = const_cast <tchar*> ((const tchar*) result);
-
- int i;
- for (i = 0; i < bytesRead / sizeof (UniChar); ++i)
- t[i] = (tchar) tempOut[i];
-
- t[i] = 0;
- }
-
- juce_free (tempIn);
- juce_free (tempOut);
-
- DisposeUnicodeToTextInfo (&conversionInfo);
- }
-
- return result;
- }
-
- const unsigned int macTimeToUnixTimeDiff = 0x7c25be90;
-
- static uint64 utcDateTimeToUnixTime (const UTCDateTime& d) throw()
- {
- if (d.highSeconds == 0 && d.lowSeconds == 0 && d.fraction == 0)
- return 0;
-
- return (((((uint64) d.highSeconds) << 32) | (uint64) d.lowSeconds) * 1000)
- + ((d.fraction * 1000) >> 16)
- - 2082844800000ll;
- }
-
- static void unixTimeToUtcDateTime (uint64 t, UTCDateTime& d) throw()
- {
- if (t != 0)
- t += 2082844800000ll;
-
- d.highSeconds = (t / 1000) >> 32;
- d.lowSeconds = (t / 1000) & (uint64) 0xffffffff;
- d.fraction = ((t % 1000) << 16) / 1000;
- }
-
- void juce_getFileTimes (const String& fileName,
- int64& modificationTime,
- int64& accessTime,
- int64& creationTime) throw()
- {
- modificationTime = 0;
- accessTime = 0;
- creationTime = 0;
-
- FSRef fileRef;
- if (PlatformUtilities::makeFSRefFromPath (&fileRef, fileName))
- {
- FSRefParam info;
- zerostruct (info);
-
- info.ref = &fileRef;
- info.whichInfo = kFSCatInfoAllDates;
-
- FSCatalogInfo catInfo;
- info.catInfo = &catInfo;
-
- if (PBGetCatalogInfoSync (&info) == noErr)
- {
- creationTime = utcDateTimeToUnixTime (catInfo.createDate);
- accessTime = utcDateTimeToUnixTime (catInfo.accessDate);
- modificationTime = utcDateTimeToUnixTime (catInfo.contentModDate);
- }
- }
- }
-
- bool juce_setFileTimes (const String& fileName,
- int64 modificationTime,
- int64 accessTime,
- int64 creationTime) throw()
- {
- FSRef fileRef;
- if (PlatformUtilities::makeFSRefFromPath (&fileRef, fileName))
- {
- FSRefParam info;
- zerostruct (info);
-
- info.ref = &fileRef;
- info.whichInfo = kFSCatInfoAllDates;
-
- FSCatalogInfo catInfo;
- info.catInfo = &catInfo;
-
- if (PBGetCatalogInfoSync (&info) == noErr)
- {
- if (creationTime != 0)
- unixTimeToUtcDateTime (creationTime, catInfo.createDate);
-
- if (modificationTime != 0)
- unixTimeToUtcDateTime (modificationTime, catInfo.contentModDate);
-
- if (accessTime != 0)
- unixTimeToUtcDateTime (accessTime, catInfo.accessDate);
-
- return PBSetCatalogInfoSync (&info) == noErr;
- }
- }
-
- return false;
- }
-
- bool juce_setFileReadOnly (const String& fileName, bool isReadOnly) throw()
- {
- const char* const fileNameUTF8 = fileName.toUTF8();
-
- struct stat info;
- const int res = stat (fileNameUTF8, &info);
-
- bool ok = false;
-
- if (res == 0)
- {
- info.st_mode &= 0777; // Just permissions
-
- if (isReadOnly)
- info.st_mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH);
- else
- // Give everybody write permission?
- info.st_mode |= S_IWUSR | S_IWGRP | S_IWOTH;
-
- ok = chmod (fileNameUTF8, info.st_mode) == 0;
- }
-
- return ok;
- }
-
- bool juce_copyFile (const String& src, const String& dst) throw()
- {
- const File destFile (dst);
-
- if (! destFile.create())
- return false;
-
- FSRef srcRef, dstRef;
-
- if (! (PlatformUtilities::makeFSRefFromPath (&srcRef, src)
- && PlatformUtilities::makeFSRefFromPath (&dstRef, dst)))
- {
- return false;
- }
-
- int okForks = 0;
-
- CatPositionRec iter;
- iter.initialize = 0;
- HFSUniStr255 forkName;
-
- // can't just copy the data because this is a bloody Mac, so we need to copy each
- // fork separately...
- while (FSIterateForks (&srcRef, &iter, &forkName, 0, 0) == noErr)
- {
- SInt16 srcForkNum = 0, dstForkNum = 0;
- OSErr err = FSOpenFork (&srcRef, forkName.length, forkName.unicode, fsRdPerm, &srcForkNum);
-
- if (err == noErr)
- {
- err = FSOpenFork (&dstRef, forkName.length, forkName.unicode, fsRdWrPerm, &dstForkNum);
-
- if (err == noErr)
- {
- MemoryBlock buf (32768);
- SInt64 pos = 0;
-
- for (;;)
- {
- ByteCount bytesRead = 0;
- err = FSReadFork (srcForkNum, fsFromStart, pos, buf.getSize(), (char*) buf, &bytesRead);
-
- if (bytesRead > 0)
- {
- err = FSWriteFork (dstForkNum, fsFromStart, pos, bytesRead, (const char*) buf, &bytesRead);
- pos += bytesRead;
- }
-
- if (err != noErr)
- {
- if (err == eofErr)
- ++okForks;
-
- break;
- }
- }
-
- FSFlushFork (dstForkNum);
- FSCloseFork (dstForkNum);
- }
-
- FSCloseFork (srcForkNum);
- }
- }
-
- if (okForks > 0) // some files seem to be ok even if not all their forks get copied..
- {
- // copy permissions..
- struct stat info;
- if (juce_stat (src, info))
- chmod (dst.toUTF8(), info.st_mode & 0777);
-
- return true;
- }
-
- return false;
- }
-
- const StringArray juce_getFileSystemRoots() throw()
- {
- StringArray s;
- s.add (T("/"));
- return s;
- }
-
- static bool isFileOnDriveType (const File* const f, const char** types) throw()
- {
- struct statfs buf;
-
- if (doStatFS (f, buf))
- {
- const String type (buf.f_fstypename);
-
- while (*types != 0)
- if (type.equalsIgnoreCase (*types++))
- return true;
- }
-
- return false;
- }
-
- bool File::isOnCDRomDrive() const throw()
- {
- static const char* const cdTypes[] = { "cd9660", "cdfs", "cddafs", "udf", 0 };
-
- return isFileOnDriveType (this, (const char**) cdTypes);
- }
-
- bool File::isOnHardDisk() const throw()
- {
- static const char* const nonHDTypes[] = { "nfs", "smbfs", "ramfs", 0 };
-
- return ! (isOnCDRomDrive() || isFileOnDriveType (this, (const char**) nonHDTypes));
- }
-
- static bool juce_isHiddenFile (const String& path) throw()
- {
- FSRef ref;
- if (! PlatformUtilities::makeFSRefFromPath (&ref, path))
- return false;
-
- FSCatalogInfo info;
- FSGetCatalogInfo (&ref, kFSCatInfoNodeFlags | kFSCatInfoFinderInfo, &info, 0, 0, 0);
-
- if ((info.nodeFlags & kFSNodeIsDirectoryBit) != 0)
- return (((FolderInfo*) &info.finderInfo)->finderFlags & kIsInvisible) != 0;
-
- return (((FileInfo*) &info.finderInfo)->finderFlags & kIsInvisible) != 0;
- }
-
- bool File::isHidden() const throw()
- {
- return juce_isHiddenFile (getFullPathName());
- }
-
- const File File::getSpecialLocation (const SpecialLocationType type)
- {
- const char* resultPath = 0;
-
- switch (type)
- {
- case userHomeDirectory:
- resultPath = getenv ("HOME");
-
- if (resultPath == 0)
- {
- struct passwd* const pw = getpwuid (getuid());
- if (pw != 0)
- resultPath = pw->pw_dir;
- }
-
- break;
-
- case userDocumentsDirectory:
- resultPath = "~/Documents";
- break;
-
- case userDesktopDirectory:
- resultPath = "~/Desktop";
- break;
-
- case userApplicationDataDirectory:
- resultPath = "~/Library";
- break;
-
- case commonApplicationDataDirectory:
- resultPath = "/Library";
- break;
-
- case globalApplicationsDirectory:
- resultPath = "/Applications";
- break;
-
- case userMusicDirectory:
- resultPath = "~/Music";
- break;
-
- case userMoviesDirectory:
- resultPath = "~/Movies";
- break;
-
- case tempDirectory:
- {
- File tmp (T("~/Library/Caches/") + executableFile.getFileNameWithoutExtension());
-
- tmp.createDirectory();
- return tmp.getFullPathName();
- }
-
- case currentExecutableFile:
- return executableFile;
-
- case currentApplicationFile:
- {
- const File parent (executableFile.getParentDirectory());
-
- return parent.getFullPathName().endsWithIgnoreCase (T("Contents/MacOS"))
- ? parent.getParentDirectory().getParentDirectory()
- : executableFile;
- }
-
- default:
- jassertfalse // unknown type?
- break;
- }
-
- if (resultPath != 0)
- return File (PlatformUtilities::convertToPrecomposedUnicode (resultPath));
-
- return File::nonexistent;
- }
-
- void juce_setCurrentExecutableFileName (const String& filename) throw()
- {
- executableFile = File::getCurrentWorkingDirectory()
- .getChildFile (PlatformUtilities::convertToPrecomposedUnicode (filename));
- }
-
- void juce_setCurrentExecutableFileNameFromBundleId (const String& bundleId) throw()
- {
- CFStringRef bundleIdStringRef = PlatformUtilities::juceStringToCFString (bundleId);
- CFBundleRef bundleRef = CFBundleGetBundleWithIdentifier (bundleIdStringRef);
- CFRelease (bundleIdStringRef);
-
- if (bundleRef != 0)
- {
- CFURLRef exeURLRef = CFBundleCopyExecutableURL (bundleRef);
-
- if (exeURLRef != 0)
- {
- CFStringRef pathStringRef = CFURLCopyFileSystemPath (exeURLRef, kCFURLPOSIXPathStyle);
- CFRelease (exeURLRef);
-
- if (pathStringRef != 0)
- {
- juce_setCurrentExecutableFileName (PlatformUtilities::cfStringToJuceString (pathStringRef));
- CFRelease (pathStringRef);
- }
- }
- }
- }
-
- const File File::getCurrentWorkingDirectory() throw()
- {
- char buf [2048];
- getcwd (buf, sizeof(buf));
-
- return File (PlatformUtilities::convertToPrecomposedUnicode (buf));
- }
-
- bool File::setAsCurrentWorkingDirectory() const throw()
- {
- return chdir (getFullPathName().toUTF8()) == 0;
- }
-
- struct FindFileStruct
- {
- String parentDir, wildCard;
- DIR* dir;
-
- bool getNextMatch (String& result, bool* const isDir, bool* const isHidden, int64* const fileSize,
- Time* const modTime, Time* const creationTime, bool* const isReadOnly) throw()
- {
- const char* const wildCardUTF8 = wildCard.toUTF8();
-
- for (;;)
- {
- struct dirent* const de = readdir (dir);
-
- if (de == 0)
- break;
-
- if (fnmatch (wildCardUTF8, de->d_name, 0) == 0)
- {
- result = PlatformUtilities::convertToPrecomposedUnicode (String::fromUTF8 ((const uint8*) de->d_name));
-
- const String path (parentDir + result);
-
- if (isDir != 0 || fileSize != 0)
- {
- struct stat info;
- const bool statOk = juce_stat (path, info);
-
- if (isDir != 0)
- *isDir = path.isEmpty() || (statOk && ((info.st_mode & S_IFDIR) != 0));
-
- if (isHidden != 0)
- *isHidden = (de->d_name[0] == '.')
- || juce_isHiddenFile (path);
-
- if (fileSize != 0)
- *fileSize = statOk ? info.st_size : 0;
- }
-
- if (modTime != 0 || creationTime != 0)
- {
- int64 m, a, c;
- juce_getFileTimes (path, m, a, c);
-
- if (modTime != 0)
- *modTime = m;
-
- if (creationTime != 0)
- *creationTime = c;
- }
-
- if (isReadOnly != 0)
- *isReadOnly = ! juce_canWriteToFile (path);
-
- return true;
- }
- }
-
- return false;
- }
- };
-
- // returns 0 on failure
- void* juce_findFileStart (const String& directory, const String& wildCard, String& firstResultFile,
- bool* isDir, bool* isHidden, int64* fileSize, Time* modTime,
- Time* creationTime, bool* isReadOnly) throw()
- {
- DIR* const d = opendir (directory.toUTF8());
-
- if (d != 0)
- {
- FindFileStruct* const ff = new FindFileStruct();
- ff->parentDir = directory;
-
- if (!ff->parentDir.endsWithChar (File::separator))
- ff->parentDir += File::separator;
-
- ff->wildCard = wildCard;
- ff->dir = d;
-
- if (ff->getNextMatch (firstResultFile, isDir, isHidden, fileSize, modTime, creationTime, isReadOnly))
- {
- return ff;
- }
- else
- {
- firstResultFile = String::empty;
- isDir = false;
- closedir (d);
- delete ff;
- }
- }
-
- return 0;
- }
-
- bool juce_findFileNext (void* handle, String& resultFile,
- bool* isDir, bool* isHidden, int64* fileSize, Time* modTime, Time* creationTime, bool* isReadOnly) throw()
- {
- FindFileStruct* const ff = (FindFileStruct*) handle;
-
- if (ff != 0)
- return ff->getNextMatch (resultFile, isDir, isHidden, fileSize, modTime, creationTime, isReadOnly);
-
- return false;
- }
-
- void juce_findFileClose (void* handle) throw()
- {
- FindFileStruct* const ff = (FindFileStruct*)handle;
-
- if (ff != 0)
- {
- closedir (ff->dir);
- delete ff;
- }
- }
-
- bool juce_launchExecutable (const String& pathAndArguments) throw()
- {
- char* const argv[4] = { "/bin/sh", "-c", (char*) (const char*) pathAndArguments, 0 };
-
- const int cpid = fork();
-
- if (cpid == 0)
- {
- // Child process
- if (execve (argv[0], argv, 0) < 0)
- exit (0);
- }
- else
- {
- if (cpid < 0)
- return false;
- }
-
- return true;
- }
-
- bool juce_launchFile (const String& fileName,
- const String& parameters) throw()
- {
- bool ok = false;
-
- if (fileName.startsWithIgnoreCase (T("http:"))
- || fileName.startsWithIgnoreCase (T("https:"))
- || fileName.startsWithIgnoreCase (T("ftp:"))
- || fileName.startsWithIgnoreCase (T("file:")))
- {
- CFStringRef urlString = PlatformUtilities::juceStringToCFString (fileName);
-
- if (urlString != 0)
- {
- CFURLRef url = CFURLCreateWithString (kCFAllocatorDefault,
- urlString, 0);
- CFRelease (urlString);
-
- if (url != 0)
- {
- ok = (LSOpenCFURLRef (url, 0) == noErr);
- CFRelease (url);
- }
- }
- }
- else
- {
- FSRef ref;
- if (PlatformUtilities::makeFSRefFromPath (&ref, fileName))
- {
- if (juce_isDirectory (fileName) && parameters.isNotEmpty())
- {
- // if we're launching a bundled app with a document..
- StringArray docs;
- docs.addTokens (parameters, true);
- FSRef* docRefs = new FSRef [docs.size()];
-
- for (int i = 0; i < docs.size(); ++i)
- PlatformUtilities::makeFSRefFromPath (docRefs + i, docs[i]);
-
- LSLaunchFSRefSpec ors;
- ors.appRef = &ref;
- ors.numDocs = docs.size();
- ors.itemRefs = docRefs;
- ors.passThruParams = 0;
- ors.launchFlags = kLSLaunchDefaults;
- ors.asyncRefCon = 0;
-
- FSRef actual;
- ok = (LSOpenFromRefSpec (&ors, &actual) == noErr);
-
- delete docRefs;
- }
- else
- {
- if (parameters.isNotEmpty())
- ok = juce_launchExecutable (T("\"") + fileName + T("\" ") + parameters);
- else
- ok = (LSOpenFSRef (&ref, 0) == noErr);
- }
- }
- }
-
- return ok;
- }
-
- bool PlatformUtilities::makeFSSpecFromPath (FSSpec* fs, const String& path)
- {
- FSRef ref;
-
- return makeFSRefFromPath (&ref, path)
- && FSGetCatalogInfo (&ref, kFSCatInfoNone, 0, 0, fs, 0) == noErr;
- }
-
- bool PlatformUtilities::makeFSRefFromPath (FSRef* destFSRef, const String& path)
- {
- return FSPathMakeRef ((const UInt8*) path.toUTF8(), destFSRef, 0) == noErr;
- }
-
- const String PlatformUtilities::makePathFromFSRef (FSRef* file)
- {
- uint8 path [2048];
- zeromem (path, sizeof (path));
-
- String result;
-
- if (FSRefMakePath (file, (UInt8*) path, sizeof (path) - 1) == noErr)
- result = String::fromUTF8 (path);
-
- return PlatformUtilities::convertToPrecomposedUnicode (result);
- }
-
- OSType PlatformUtilities::getTypeOfFile (const String& filename)
- {
- FSRef fs;
- if (makeFSRefFromPath (&fs, filename))
- {
- LSItemInfoRecord info;
-
- if (LSCopyItemInfoForRef (&fs, kLSRequestTypeCreator, &info) == noErr)
- return info.filetype;
- }
-
- return 0;
- }
-
- bool PlatformUtilities::isBundle (const String& filename)
- {
- FSRef fs;
- if (makeFSRefFromPath (&fs, filename))
- {
- LSItemInfoRecord info;
-
- if (LSCopyItemInfoForRef (&fs, kLSItemInfoIsPackage, &info) == noErr)
- return (info.flags & kLSItemInfoIsPackage) != 0;
- }
-
- return false;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_mac_Files.cpp *********/
-
- /********* Start of inlined file: juce_mac_NamedPipe.cpp *********/
-
- #include <sys/stat.h>
- #include <sys/dir.h>
- #include <fcntl.h>
-
- // As well as being for the mac, this file is included by the linux build.
-
- #if ! JUCE_MAC
- #include <sys/wait.h>
- #include <errno.h>
- #include <unistd.h>
- #endif
-
- BEGIN_JUCE_NAMESPACE
-
- struct NamedPipeInternal
- {
- String pipeInName, pipeOutName;
- int pipeIn, pipeOut;
-
- bool volatile createdPipe, blocked, stopReadOperation;
-
- static void signalHandler (int) {}
- };
-
- void NamedPipe::cancelPendingReads()
- {
- while (internal != 0 && ((NamedPipeInternal*) internal)->blocked)
- {
- NamedPipeInternal* const intern = (NamedPipeInternal*) internal;
-
- intern->stopReadOperation = true;
-
- char buffer [1] = { 0 };
- ::write (intern->pipeIn, buffer, 1);
-
- int timeout = 2000;
- while (intern->blocked && --timeout >= 0)
- Thread::sleep (2);
-
- intern->stopReadOperation = false;
- }
- }
-
- void NamedPipe::close()
- {
- NamedPipeInternal* const intern = (NamedPipeInternal*) internal;
-
- if (intern != 0)
- {
- internal = 0;
-
- if (intern->pipeIn != -1)
- ::close (intern->pipeIn);
-
- if (intern->pipeOut != -1)
- ::close (intern->pipeOut);
-
- if (intern->createdPipe)
- {
- unlink (intern->pipeInName);
- unlink (intern->pipeOutName);
- }
-
- delete intern;
- }
- }
-
- bool NamedPipe::openInternal (const String& pipeName, const bool createPipe)
- {
- close();
-
- NamedPipeInternal* const intern = new NamedPipeInternal();
- internal = intern;
- intern->createdPipe = createPipe;
- intern->blocked = false;
- intern->stopReadOperation = false;
-
- signal (SIGPIPE, NamedPipeInternal::signalHandler);
- siginterrupt (SIGPIPE, 1);
-
- const String pipePath (T("/tmp/") + File::createLegalFileName (pipeName));
-
- intern->pipeInName = pipePath + T("_in");
- intern->pipeOutName = pipePath + T("_out");
- intern->pipeIn = -1;
- intern->pipeOut = -1;
-
- if (createPipe)
- {
- if ((mkfifo (intern->pipeInName, 0666) && errno != EEXIST)
- || (mkfifo (intern->pipeOutName, 0666) && errno != EEXIST))
- {
- delete intern;
- internal = 0;
-
- return false;
- }
- }
-
- return true;
- }
-
- int NamedPipe::read (void* destBuffer, int maxBytesToRead, int /*timeOutMilliseconds*/)
- {
- int bytesRead = -1;
- NamedPipeInternal* const intern = (NamedPipeInternal*) internal;
-
- if (intern != 0)
- {
- intern->blocked = true;
-
- if (intern->pipeIn == -1)
- {
- if (intern->createdPipe)
- intern->pipeIn = ::open (intern->pipeInName, O_RDWR);
- else
- intern->pipeIn = ::open (intern->pipeOutName, O_RDWR);
-
- if (intern->pipeIn == -1)
- {
- intern->blocked = false;
- return -1;
- }
- }
-
- bytesRead = 0;
-
- char* p = (char*) destBuffer;
-
- while (bytesRead < maxBytesToRead)
- {
- const int bytesThisTime = maxBytesToRead - bytesRead;
- const int numRead = ::read (intern->pipeIn, p, bytesThisTime);
-
- if (numRead <= 0 || intern->stopReadOperation)
- {
- bytesRead = -1;
- break;
- }
-
- bytesRead += numRead;
- p += bytesRead;
- }
-
- intern->blocked = false;
- }
-
- return bytesRead;
- }
-
- int NamedPipe::write (const void* sourceBuffer, int numBytesToWrite, int timeOutMilliseconds)
- {
- int bytesWritten = -1;
- NamedPipeInternal* const intern = (NamedPipeInternal*) internal;
-
- if (intern != 0)
- {
- if (intern->pipeOut == -1)
- {
- if (intern->createdPipe)
- intern->pipeOut = ::open (intern->pipeOutName, O_WRONLY);
- else
- intern->pipeOut = ::open (intern->pipeInName, O_WRONLY);
-
- if (intern->pipeOut == -1)
- {
- return -1;
- }
- }
-
- const char* p = (const char*) sourceBuffer;
- bytesWritten = 0;
-
- const uint32 timeOutTime = Time::getMillisecondCounter() + timeOutMilliseconds;
-
- while (bytesWritten < numBytesToWrite
- && (timeOutMilliseconds < 0 || Time::getMillisecondCounter() < timeOutTime))
- {
- const int bytesThisTime = numBytesToWrite - bytesWritten;
- const int numWritten = ::write (intern->pipeOut, p, bytesThisTime);
-
- if (numWritten <= 0)
- {
- bytesWritten = -1;
- break;
- }
-
- bytesWritten += numWritten;
- p += bytesWritten;
- }
- }
-
- return bytesWritten;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_mac_NamedPipe.cpp *********/
-
- /********* Start of inlined file: juce_mac_SystemStats.mm *********/
-
- /********* Start of inlined file: juce_mac_NativeHeaders.h *********/
- #ifndef __JUCE_MAC_NATIVEHEADERS_JUCEHEADER__
- #define __JUCE_MAC_NATIVEHEADERS_JUCEHEADER__
-
- #include <Cocoa/Cocoa.h>
-
- BEGIN_JUCE_NAMESPACE
-
- class AutoPool
- {
- public:
- AutoPool() { pool = [[NSAutoreleasePool alloc] init]; }
- ~AutoPool() { [pool release]; }
-
- private:
- NSAutoreleasePool* pool;
- };
-
- END_JUCE_NAMESPACE
-
- static const JUCE_NAMESPACE::String nsStringToJuce (NSString* s)
- {
- return JUCE_NAMESPACE::String::fromUTF8 ((JUCE_NAMESPACE::uint8*) [s UTF8String]);
- }
-
- static NSString* juceStringToNS (const JUCE_NAMESPACE::String& s)
- {
- return [NSString stringWithUTF8String: (const char*) s.toUTF8()];
- }
-
- #endif
- /********* End of inlined file: juce_mac_NativeHeaders.h *********/
-
- #include <AppKit/AppKit.h>
- #include <CoreAudio/HostTime.h>
- #include <ctime>
- #include <sys/resource.h>
-
- BEGIN_JUCE_NAMESPACE
-
- static int64 highResTimerFrequency;
-
- #if JUCE_INTEL
-
- static void juce_getCpuVendor (char* const v) throw()
- {
- int vendor[4];
- zerostruct (vendor);
- int dummy = 0;
-
- asm ("mov %%ebx, %%esi \n\t"
- "cpuid \n\t"
- "xchg %%esi, %%ebx"
- : "=a" (dummy), "=S" (vendor[0]), "=c" (vendor[2]), "=d" (vendor[1]) : "a" (0));
-
- memcpy (v, vendor, 16);
- }
-
- static unsigned int getCPUIDWord (unsigned int& familyModel, unsigned int& extFeatures) throw()
- {
- unsigned int cpu = 0;
- unsigned int ext = 0;
- unsigned int family = 0;
- unsigned int dummy = 0;
-
- asm ("mov %%ebx, %%esi \n\t"
- "cpuid \n\t"
- "xchg %%esi, %%ebx"
- : "=a" (family), "=S" (ext), "=c" (dummy), "=d" (cpu) : "a" (1));
-
- familyModel = family;
- extFeatures = ext;
- return cpu;
- }
-
- struct CPUFlags
- {
- bool hasMMX : 1;
- bool hasSSE : 1;
- bool hasSSE2 : 1;
- bool has3DNow : 1;
- };
-
- static CPUFlags cpuFlags;
-
- #endif
-
- void Logger::outputDebugString (const String& text) throw()
- {
- String withLineFeed (text + T("\n"));
- const char* const utf8 = withLineFeed.toUTF8();
- fwrite (utf8, strlen (utf8), 1, stdout);
- }
-
- void Logger::outputDebugPrintf (const tchar* format, ...) throw()
- {
- String text;
- va_list args;
- va_start (args, format);
- text.vprintf(format, args);
- outputDebugString (text);
- }
-
- int SystemStats::getMemorySizeInMegabytes() throw()
- {
- long bytes;
- if (Gestalt (gestaltPhysicalRAMSize, &bytes) == noErr)
- return (int) (((unsigned long) bytes) / (1024 * 1024));
-
- return 0;
- }
-
- SystemStats::OperatingSystemType SystemStats::getOperatingSystemType() throw()
- {
- return MacOSX;
- }
-
- const String SystemStats::getOperatingSystemName() throw()
- {
- return T("Mac OS X");
- }
-
- bool SystemStats::isOperatingSystem64Bit() throw()
- {
- #if JUCE_64BIT
- return true;
- #else
- //xxx not sure how to find this out?..
- return false;
- #endif
- }
-
- void SystemStats::initialiseStats() throw()
- {
- static bool initialised = false;
-
- if (! initialised)
- {
- initialised = true;
-
- [NSApplication sharedApplication];
- NSApplicationLoad();
-
- #if JUCE_INTEL
- {
- unsigned int familyModel, extFeatures;
- const unsigned int features = getCPUIDWord (familyModel, extFeatures);
-
- cpuFlags.hasMMX = ((features & (1 << 23)) != 0);
- cpuFlags.hasSSE = ((features & (1 << 25)) != 0);
- cpuFlags.hasSSE2 = ((features & (1 << 26)) != 0);
- cpuFlags.has3DNow = ((extFeatures & (1 << 31)) != 0);
- }
- #endif
-
- highResTimerFrequency = (int64) AudioGetHostClockFrequency();
-
- String s (SystemStats::getJUCEVersion());
-
- rlimit lim;
- getrlimit (RLIMIT_NOFILE, &lim);
- lim.rlim_cur = lim.rlim_max = RLIM_INFINITY;
- setrlimit (RLIMIT_NOFILE, &lim);
- }
- }
-
- bool SystemStats::hasMMX() throw()
- {
- #if JUCE_INTEL
- return cpuFlags.hasMMX;
- #else
- return false;
- #endif
- }
-
- bool SystemStats::hasSSE() throw()
- {
- #if JUCE_INTEL
- return cpuFlags.hasSSE;
- #else
- return false;
- #endif
- }
-
- bool SystemStats::hasSSE2() throw()
- {
- #if JUCE_INTEL
- return cpuFlags.hasSSE2;
- #else
- return false;
- #endif
- }
-
- bool SystemStats::has3DNow() throw()
- {
- #if JUCE_INTEL
- return cpuFlags.has3DNow;
- #else
- return false;
- #endif
- }
-
- const String SystemStats::getCpuVendor() throw()
- {
- #if JUCE_INTEL
- char v [16];
- juce_getCpuVendor (v);
- return String (v, 16);
- #else
- return String::empty;
- #endif
- }
-
- int SystemStats::getCpuSpeedInMegaherz() throw()
- {
- return GetCPUSpeed();
- }
-
- int SystemStats::getNumCpus() throw()
- {
- return MPProcessors();
- }
-
- static int64 juce_getMicroseconds() throw()
- {
- UnsignedWide t;
- Microseconds (&t);
- return (((int64) t.hi) << 32) | t.lo;
- }
-
- uint32 juce_millisecondsSinceStartup() throw()
- {
- return (uint32) (juce_getMicroseconds() / 1000);
- }
-
- double Time::getMillisecondCounterHiRes() throw()
- {
- // xxx might be more accurate to use a scaled AudioGetCurrentHostTime?
- return juce_getMicroseconds() * 0.001;
- }
-
- int64 Time::getHighResolutionTicks() throw()
- {
- return (int64) AudioGetCurrentHostTime();
- }
-
- int64 Time::getHighResolutionTicksPerSecond() throw()
- {
- return highResTimerFrequency;
- }
-
- int64 SystemStats::getClockCycleCounter() throw()
- {
- jassertfalse
- return 0;
- }
-
- bool Time::setSystemTimeToThisTime() const throw()
- {
- jassertfalse
- return false;
- }
-
- int SystemStats::getPageSize() throw()
- {
- jassertfalse
- return 512; //xxx
- }
-
- void PlatformUtilities::fpuReset()
- {
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_mac_SystemStats.mm *********/
-
- /********* Start of inlined file: juce_mac_Threads.cpp *********/
-
- #include <pthread.h>
- #include <sched.h>
- #include <sys/file.h>
- #include <sys/types.h>
- #include <sys/sysctl.h>
-
- BEGIN_JUCE_NAMESPACE
-
- /*
- Note that a lot of methods that you'd expect to find in this file actually
- live in juce_posix_SharedCode.cpp!
- */
-
- void JUCE_API juce_threadEntryPoint (void*);
-
- void* threadEntryProc (void* userData) throw()
- {
- juce_threadEntryPoint (userData);
- return 0;
- }
-
- void* juce_createThread (void* userData) throw()
- {
- pthread_t handle = 0;
-
- if (pthread_create (&handle, 0, threadEntryProc, userData) == 0)
- {
- pthread_detach (handle);
- return (void*) handle;
- }
-
- return 0;
- }
-
- void juce_killThread (void* handle) throw()
- {
- if (handle != 0)
- pthread_cancel ((pthread_t) handle);
- }
-
- void juce_setCurrentThreadName (const String& /*name*/) throw()
- {
- }
-
- int Thread::getCurrentThreadId() throw()
- {
- return (int) pthread_self();
- }
-
- void juce_setThreadPriority (void* handle, int priority) throw()
- {
- if (handle == 0)
- handle = (void*) pthread_self();
-
- struct sched_param param;
- int policy;
- pthread_getschedparam ((pthread_t) handle, &policy, ¶m);
- param.sched_priority = jlimit (1, 127, 1 + (priority * 126) / 11);
- pthread_setschedparam ((pthread_t) handle, policy, ¶m);
- }
-
- void Thread::yield() throw()
- {
- sched_yield();
- }
-
- void Thread::setCurrentThreadAffinityMask (const uint32 affinityMask) throw()
- {
- // xxx
- jassertfalse
- }
-
- bool JUCE_CALLTYPE juce_isRunningUnderDebugger() throw()
- {
- static char testResult = 0;
-
- if (testResult == 0)
- {
- struct kinfo_proc info;
- int m[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid() };
- size_t sz = sizeof (info);
- sysctl (m, 4, &info, &sz, 0, 0);
- testResult = ((info.kp_proc.p_flag & P_TRACED) != 0) ? 1 : -1;
- }
-
- return testResult > 0;
- }
-
- bool JUCE_CALLTYPE Process::isRunningUnderDebugger() throw()
- {
- return juce_isRunningUnderDebugger();
- }
-
- void Process::raisePrivilege()
- {
- jassertfalse
- }
-
- void Process::lowerPrivilege()
- {
- jassertfalse
- }
-
- void Process::terminate()
- {
- exit (0);
- }
-
- void Process::setPriority (ProcessPriority p)
- {
- // xxx
- }
-
- void* Process::loadDynamicLibrary (const String& name)
- {
- // xxx needs to use bundles
-
- FSSpec fs;
- if (PlatformUtilities::makeFSSpecFromPath (&fs, name))
- {
- CFragConnectionID connID;
- Ptr mainPtr;
- Str255 errorMessage;
- Str63 nm;
- PlatformUtilities::copyToStr63 (nm, name);
-
- const OSErr err = GetDiskFragment (&fs, 0, kCFragGoesToEOF, nm, kReferenceCFrag, &connID, &mainPtr, errorMessage);
- if (err == noErr)
- return (void*)connID;
- }
-
- return 0;
- }
-
- void Process::freeDynamicLibrary (void* handle)
- {
- if (handle != 0)
- CloseConnection ((CFragConnectionID*)&handle);
- }
-
- void* Process::getProcedureEntryPoint (void* h, const String& procedureName)
- {
- if (h != 0)
- {
- CFragSymbolClass cl;
- Ptr ptr;
- Str255 name;
- PlatformUtilities::copyToStr255 (name, procedureName);
-
- if (FindSymbol ((CFragConnectionID) h, name, &ptr, &cl) == noErr)
- {
- return ptr;
- }
- }
-
- return 0;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_mac_Threads.cpp *********/
-
- /********* Start of inlined file: juce_mac_Network.mm *********/
-
- #include <IOKit/IOKitLib.h>
- #include <IOKit/network/IOEthernetInterface.h>
- #include <IOKit/network/IONetworkInterface.h>
- #include <IOKit/network/IOEthernetController.h>
-
- #include <netdb.h>
- #include <arpa/inet.h>
- #include <netinet/in.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <sys/wait.h>
-
- BEGIN_JUCE_NAMESPACE
-
- /********* Start of inlined file: juce_mac_HTTPStream.h *********/
- // (This file gets included by the mac + linux networking code)
-
- /** A HTTP input stream that uses sockets.
- */
- class JUCE_HTTPSocketStream
- {
- public:
-
- JUCE_HTTPSocketStream()
- : readPosition (0),
- socketHandle (-1),
- levelsOfRedirection (0),
- timeoutSeconds (15)
- {
- }
-
- ~JUCE_HTTPSocketStream()
- {
- closeSocket();
- }
-
- bool open (const String& url,
- const String& headers,
- const MemoryBlock& postData,
- const bool isPost,
- URL::OpenStreamProgressCallback* callback,
- void* callbackContext,
- int timeOutMs)
- {
- closeSocket();
-
- uint32 timeOutTime = Time::getMillisecondCounter();
-
- if (timeOutMs == 0)
- timeOutTime += 60000;
- else if (timeOutMs < 0)
- timeOutTime = 0xffffffff;
- else
- timeOutTime += timeOutMs;
-
- String hostName, hostPath;
- int hostPort;
-
- if (! decomposeURL (url, hostName, hostPath, hostPort))
- return false;
-
- const struct hostent* host = 0;
- int port = 0;
-
- String proxyName, proxyPath;
- int proxyPort = 0;
-
- String proxyURL (getenv ("http_proxy"));
- if (proxyURL.startsWithIgnoreCase (T("http://")))
- {
- if (! decomposeURL (proxyURL, proxyName, proxyPath, proxyPort))
- return false;
-
- host = gethostbyname ((const char*) proxyName.toUTF8());
- port = proxyPort;
- }
- else
- {
- host = gethostbyname ((const char*) hostName.toUTF8());
- port = hostPort;
- }
-
- if (host == 0)
- return false;
-
- struct sockaddr_in address;
- zerostruct (address);
- memcpy ((void*) &address.sin_addr, (const void*) host->h_addr, host->h_length);
- address.sin_family = host->h_addrtype;
- address.sin_port = htons (port);
-
- socketHandle = socket (host->h_addrtype, SOCK_STREAM, 0);
-
- if (socketHandle == -1)
- return false;
-
- int receiveBufferSize = 16384;
- setsockopt (socketHandle, SOL_SOCKET, SO_RCVBUF, (char*) &receiveBufferSize, sizeof (receiveBufferSize));
- setsockopt (socketHandle, SOL_SOCKET, SO_KEEPALIVE, 0, 0);
-
- #if JUCE_MAC
- setsockopt (socketHandle, SOL_SOCKET, SO_NOSIGPIPE, 0, 0);
- #endif
-
- if (connect (socketHandle, (struct sockaddr*) &address, sizeof (address)) == -1)
- {
- closeSocket();
- return false;
- }
-
- const MemoryBlock requestHeader (createRequestHeader (hostName, hostPort,
- proxyName, proxyPort,
- hostPath, url,
- headers, postData,
- isPost));
- int totalHeaderSent = 0;
-
- while (totalHeaderSent < requestHeader.getSize())
- {
- if (Time::getMillisecondCounter() > timeOutTime)
- {
- closeSocket();
- return false;
- }
-
- const int numToSend = jmin (1024, requestHeader.getSize() - totalHeaderSent);
-
- if (send (socketHandle,
- ((const char*) requestHeader.getData()) + totalHeaderSent,
- numToSend, 0)
- != numToSend)
- {
- closeSocket();
- return false;
- }
-
- totalHeaderSent += numToSend;
-
- if (callback != 0 && ! callback (callbackContext, totalHeaderSent, requestHeader.getSize()))
- {
- closeSocket();
- return false;
- }
- }
-
- const String responseHeader (readResponse (timeOutTime));
-
- if (responseHeader.isNotEmpty())
- {
- //DBG (responseHeader);
-
- StringArray lines;
- lines.addLines (responseHeader);
-
- // NB - using charToString() here instead of just T(" "), because that was
- // causing a mysterious gcc internal compiler error...
- const int statusCode = responseHeader.fromFirstOccurrenceOf (String::charToString (T(' ')), false, false)
- .substring (0, 3)
- .getIntValue();
-
- //int contentLength = findHeaderItem (lines, T("Content-Length:")).getIntValue();
- //bool isChunked = findHeaderItem (lines, T("Transfer-Encoding:")).equalsIgnoreCase ("chunked");
-
- String location (findHeaderItem (lines, T("Location:")));
-
- if (statusCode >= 300 && statusCode < 400
- && location.isNotEmpty())
- {
- if (! location.startsWithIgnoreCase (T("http://")))
- location = T("http://") + location;
-
- if (levelsOfRedirection++ < 3)
- return open (location, headers, postData, isPost, callback, callbackContext, timeOutMs);
- }
- else
- {
- levelsOfRedirection = 0;
- return true;
- }
- }
-
- closeSocket();
- return false;
- }
-
- int read (void* buffer, int bytesToRead)
- {
- fd_set readbits;
- FD_ZERO (&readbits);
- FD_SET (socketHandle, &readbits);
-
- struct timeval tv;
- tv.tv_sec = timeoutSeconds;
- tv.tv_usec = 0;
-
- if (select (socketHandle + 1, &readbits, 0, 0, &tv) <= 0)
- return 0; // (timeout)
-
- const int bytesRead = jmax (0, recv (socketHandle, buffer, bytesToRead, MSG_WAITALL));
- readPosition += bytesRead;
- return bytesRead;
- }
-
- int readPosition;
-
- juce_UseDebuggingNewOperator
-
- private:
- int socketHandle, levelsOfRedirection;
- const int timeoutSeconds;
-
- void closeSocket()
- {
- if (socketHandle >= 0)
- close (socketHandle);
-
- socketHandle = -1;
- }
-
- const MemoryBlock createRequestHeader (const String& hostName,
- const int hostPort,
- const String& proxyName,
- const int proxyPort,
- const String& hostPath,
- const String& originalURL,
- const String& headers,
- const MemoryBlock& postData,
- const bool isPost)
- {
- String header (isPost ? "POST " : "GET ");
-
- if (proxyName.isEmpty())
- {
- header << hostPath << " HTTP/1.0\r\nHost: "
- << hostName << ':' << hostPort;
- }
- else
- {
- header << originalURL << " HTTP/1.0\r\nHost: "
- << proxyName << ':' << proxyPort;
- }
-
- header << "\r\nUser-Agent: JUCE/"
- << JUCE_MAJOR_VERSION << '.' << JUCE_MINOR_VERSION
- << "\r\nConnection: Close\r\nContent-Length: "
- << postData.getSize() << "\r\n"
- << headers << "\r\n";
-
- MemoryBlock mb;
- mb.append (header.toUTF8(), (int) strlen (header.toUTF8()));
- mb.append (postData.getData(), postData.getSize());
-
- return mb;
- }
-
- const String readResponse (const uint32 timeOutTime)
- {
- int bytesRead = 0, numConsecutiveLFs = 0;
- MemoryBlock buffer (1024, true);
-
- while (numConsecutiveLFs < 2 && bytesRead < 32768
- && Time::getMillisecondCounter() <= timeOutTime)
- {
- fd_set readbits;
- FD_ZERO (&readbits);
- FD_SET (socketHandle, &readbits);
-
- struct timeval tv;
- tv.tv_sec = timeoutSeconds;
- tv.tv_usec = 0;
-
- if (select (socketHandle + 1, &readbits, 0, 0, &tv) <= 0)
- return String::empty; // (timeout)
-
- buffer.ensureSize (bytesRead + 8, true);
- char* const dest = (char*) buffer.getData() + bytesRead;
-
- if (recv (socketHandle, dest, 1, 0) == -1)
- return String::empty;
-
- const char lastByte = *dest;
- ++bytesRead;
-
- if (lastByte == '\n')
- ++numConsecutiveLFs;
- else if (lastByte != '\r')
- numConsecutiveLFs = 0;
- }
-
- const String header (String::fromUTF8 ((const uint8*) buffer.getData()));
-
- if (header.startsWithIgnoreCase (T("HTTP/")))
- return header.trimEnd();
-
- return String::empty;
- }
-
- static bool decomposeURL (const String& url,
- String& host, String& path, int& port)
- {
- if (! url.startsWithIgnoreCase (T("http://")))
- return false;
-
- const int nextSlash = url.indexOfChar (7, '/');
- int nextColon = url.indexOfChar (7, ':');
- if (nextColon > nextSlash && nextSlash > 0)
- nextColon = -1;
-
- if (nextColon >= 0)
- {
- host = url.substring (7, nextColon);
-
- if (nextSlash >= 0)
- port = url.substring (nextColon + 1, nextSlash).getIntValue();
- else
- port = url.substring (nextColon + 1).getIntValue();
- }
- else
- {
- port = 80;
-
- if (nextSlash >= 0)
- host = url.substring (7, nextSlash);
- else
- host = url.substring (7);
- }
-
- if (nextSlash >= 0)
- path = url.substring (nextSlash);
- else
- path = T("/");
-
- return true;
- }
-
- static const String findHeaderItem (const StringArray& lines, const String& itemName)
- {
- for (int i = 0; i < lines.size(); ++i)
- if (lines[i].startsWithIgnoreCase (itemName))
- return lines[i].substring (itemName.length()).trim();
-
- return String::empty;
- }
- };
-
- bool juce_isOnLine()
- {
- return true;
- }
-
- void* juce_openInternetFile (const String& url,
- const String& headers,
- const MemoryBlock& postData,
- const bool isPost,
- URL::OpenStreamProgressCallback* callback,
- void* callbackContext,
- int timeOutMs)
- {
- JUCE_HTTPSocketStream* const s = new JUCE_HTTPSocketStream();
-
- if (s->open (url, headers, postData, isPost,
- callback, callbackContext, timeOutMs))
- return s;
-
- delete s;
- return 0;
- }
-
- void juce_closeInternetFile (void* handle)
- {
- JUCE_HTTPSocketStream* const s = (JUCE_HTTPSocketStream*) handle;
-
- if (s != 0)
- delete s;
- }
-
- int juce_readFromInternetFile (void* handle, void* buffer, int bytesToRead)
- {
- JUCE_HTTPSocketStream* const s = (JUCE_HTTPSocketStream*) handle;
-
- if (s != 0)
- return s->read (buffer, bytesToRead);
-
- return 0;
- }
-
- int juce_seekInInternetFile (void* handle, int newPosition)
- {
- JUCE_HTTPSocketStream* const s = (JUCE_HTTPSocketStream*) handle;
-
- if (s != 0)
- return s->readPosition;
-
- return 0;
- }
- /********* End of inlined file: juce_mac_HTTPStream.h *********/
-
- static bool GetEthernetIterator (io_iterator_t* matchingServices) throw()
- {
- mach_port_t masterPort;
-
- if (IOMasterPort (MACH_PORT_NULL, &masterPort) == KERN_SUCCESS)
- {
- CFMutableDictionaryRef dict = IOServiceMatching (kIOEthernetInterfaceClass);
-
- if (dict != 0)
- {
- CFMutableDictionaryRef propDict = CFDictionaryCreateMutable (kCFAllocatorDefault,
- 0,
- &kCFTypeDictionaryKeyCallBacks,
- &kCFTypeDictionaryValueCallBacks);
-
- if (propDict != 0)
- {
- CFDictionarySetValue (propDict, CFSTR (kIOPrimaryInterface), kCFBooleanTrue);
-
- CFDictionarySetValue (dict, CFSTR (kIOPropertyMatchKey), propDict);
- CFRelease (propDict);
- }
- }
-
- return IOServiceGetMatchingServices (masterPort, dict, matchingServices) == KERN_SUCCESS;
- }
-
- return false;
- }
-
- int SystemStats::getMACAddresses (int64* addresses, int maxNum, const bool littleEndian) throw()
- {
- int numResults = 0;
- io_iterator_t it;
-
- if (GetEthernetIterator (&it))
- {
- io_object_t i;
-
- while ((i = IOIteratorNext (it)) != 0)
- {
- io_object_t controller;
-
- if (IORegistryEntryGetParentEntry (i, kIOServicePlane, &controller) == KERN_SUCCESS)
- {
- CFTypeRef data = IORegistryEntryCreateCFProperty (controller,
- CFSTR (kIOMACAddress),
- kCFAllocatorDefault,
- 0);
- if (data != 0)
- {
- UInt8 addr [kIOEthernetAddressSize];
- zeromem (addr, sizeof (addr));
-
- CFDataGetBytes ((CFDataRef) data, CFRangeMake (0, sizeof (addr)), addr);
- CFRelease (data);
-
- int64 a = 0;
- for (int i = 6; --i >= 0;)
- a = (a << 8) | addr[i];
-
- if (! littleEndian)
- a = (int64) swapByteOrder ((uint64) a);
-
- if (numResults < maxNum)
- {
- *addresses++ = a;
- ++numResults;
- }
- }
-
- IOObjectRelease (controller);
- }
-
- IOObjectRelease (i);
- }
-
- IOObjectRelease (it);
- }
-
- return numResults;
- }
-
- bool PlatformUtilities::launchEmailWithAttachments (const String& targetEmailAddress,
- const String& emailSubject,
- const String& bodyText,
- const StringArray& filesToAttach)
- {
- const AutoPool pool;
-
- String script;
- script << "tell application \"Mail\"\r\n"
- "set newMessage to make new outgoing message with properties {subject:\""
- << emailSubject.replace (T("\""), T("\\\""))
- << "\", content:\""
- << bodyText.replace (T("\""), T("\\\""))
- << "\" & return & return}\r\n"
- "tell newMessage\r\n"
- "set visible to true\r\n"
- "set sender to \"sdfsdfsdfewf\"\r\n"
- "make new to recipient at end of to recipients with properties {address:\""
- << targetEmailAddress
- << "\"}\r\n";
-
- for (int i = 0; i < filesToAttach.size(); ++i)
- {
- script << "tell content\r\n"
- "make new attachment with properties {file name:\""
- << filesToAttach[i].replace (T("\""), T("\\\""))
- << "\"} at after the last paragraph\r\n"
- "end tell\r\n";
- }
-
- script << "end tell\r\n"
- "end tell\r\n";
-
- NSAppleScript* s = [[NSAppleScript alloc]
- initWithSource: [NSString stringWithUTF8String: (const char*) script.toUTF8()]];
- NSDictionary* error = 0;
- const bool ok = [s executeAndReturnError: &error] != nil;
- [s release];
-
- return ok;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_mac_Network.mm *********/
-
- #if ! JUCE_ONLY_BUILD_CORE_LIBRARY
-
- /********* Start of inlined file: juce_mac_AudioCDBurner.mm *********/
-
- #if JUCE_USE_CDBURNER
-
- #import <DiscRecording/DiscRecording.h>
-
- BEGIN_JUCE_NAMESPACE
-
- END_JUCE_NAMESPACE
-
- @interface OpenDiskDevice : NSObject
- {
- DRDevice* device;
-
- NSMutableArray* tracks;
- }
-
- - (OpenDiskDevice*) initWithDevice: (DRDevice*) device;
- - (void) dealloc;
- - (bool) isDiskPresent;
- - (int) getNumAvailableAudioBlocks;
- - (void) addSourceTrack: (JUCE_NAMESPACE::AudioSource*) source numSamples: (int) numSamples_;
- - (void) burn: (JUCE_NAMESPACE::AudioCDBurner::BurnProgressListener*) listener errorString: (JUCE_NAMESPACE::String*) error
- ejectAfterwards: (bool) shouldEject isFake: (bool) peformFakeBurnForTesting;
- @end
-
- @interface AudioTrackProducer : NSObject
- {
- JUCE_NAMESPACE::AudioSource* source;
- int readPosition, lengthInFrames;
- }
-
- - (AudioTrackProducer*) init: (int) lengthInFrames;
- - (AudioTrackProducer*) initWithAudioSource: (JUCE_NAMESPACE::AudioSource*) source numSamples: (int) lengthInSamples;
- - (void) dealloc;
- - (void) setupTrackProperties: (DRTrack*) track;
-
- - (void) cleanupTrackAfterBurn: (DRTrack*) track;
- - (BOOL) cleanupTrackAfterVerification:(DRTrack*)track;
- - (uint64_t) estimateLengthOfTrack:(DRTrack*)track;
- - (BOOL) prepareTrack:(DRTrack*)track forBurn:(DRBurn*)burn
- toMedia:(NSDictionary*)mediaInfo;
- - (BOOL) prepareTrackForVerification:(DRTrack*)track;
- - (uint32_t) produceDataForTrack:(DRTrack*)track intoBuffer:(char*)buffer
- length:(uint32_t)bufferLength atAddress:(uint64_t)address
- blockSize:(uint32_t)blockSize ioFlags:(uint32_t*)flags;
- - (uint32_t) producePreGapForTrack:(DRTrack*)track
- intoBuffer:(char*)buffer length:(uint32_t)bufferLength
- atAddress:(uint64_t)address blockSize:(uint32_t)blockSize
- ioFlags:(uint32_t*)flags;
- - (BOOL) verifyDataForTrack:(DRTrack*)track inBuffer:(const char*)buffer
- length:(uint32_t)bufferLength atAddress:(uint64_t)address
- blockSize:(uint32_t)blockSize ioFlags:(uint32_t*)flags;
- - (uint32_t) producePreGapForTrack:(DRTrack*)track
- intoBuffer:(char*)buffer length:(uint32_t)bufferLength
- atAddress:(uint64_t)address blockSize:(uint32_t)blockSize
- ioFlags:(uint32_t*)flags;
- @end
-
- @implementation OpenDiskDevice
-
- - (OpenDiskDevice*) initWithDevice: (DRDevice*) device_
- {
- [super init];
-
- device = device_;
- tracks = [[NSMutableArray alloc] init];
- return self;
- }
-
- - (void) dealloc
- {
- [tracks release];
- [super dealloc];
- }
-
- - (bool) isDiskPresent
- {
- return [device isValid]
- && [[[device status] objectForKey: DRDeviceMediaStateKey]
- isEqualTo: DRDeviceMediaStateMediaPresent];
- }
-
- - (int) getNumAvailableAudioBlocks
- {
- return [[[[device status] objectForKey: DRDeviceMediaInfoKey]
- objectForKey: DRDeviceMediaBlocksFreeKey] intValue];
- }
-
- - (void) addSourceTrack: (JUCE_NAMESPACE::AudioSource*) source_ numSamples: (int) numSamples_
- {
- AudioTrackProducer* p = [[AudioTrackProducer alloc] initWithAudioSource: source_ numSamples: numSamples_];
- DRTrack* t = [[DRTrack alloc] initWithProducer: p];
- [p setupTrackProperties: t];
-
- [tracks addObject: t];
-
- [t release];
- [p release];
- }
-
- - (void) burn: (JUCE_NAMESPACE::AudioCDBurner::BurnProgressListener*) listener errorString: (JUCE_NAMESPACE::String*) error
- ejectAfterwards: (bool) shouldEject isFake: (bool) peformFakeBurnForTesting
- {
- DRBurn* burn = [DRBurn burnForDevice: device];
-
- if (! [device acquireExclusiveAccess])
- {
- *error = "Couldn't open or write to the CD device";
- return;
- }
-
- [device acquireMediaReservation];
-
- NSMutableDictionary* d = [[burn properties] mutableCopy];
- [d autorelease];
- [d setObject: [NSNumber numberWithBool: peformFakeBurnForTesting] forKey: DRBurnTestingKey];
- [d setObject: [NSNumber numberWithBool: false] forKey: DRBurnVerifyDiscKey];
- [d setObject: (shouldEject ? DRBurnCompletionActionEject : DRBurnCompletionActionMount)
- forKey: DRBurnCompletionActionKey];
- [burn setProperties: d];
-
- [burn writeLayout: tracks];
-
- for (;;)
- {
- JUCE_NAMESPACE::Thread::sleep (300);
- float progress = [[[burn status] objectForKey: DRStatusPercentCompleteKey] floatValue];
-
- NSLog ([[burn status] description]);
-
- if (listener != 0 && listener->audioCDBurnProgress (progress))
- {
- [burn abort];
- *error = "User cancelled the write operation";
- break;
- }
-
- if ([[[burn status] objectForKey: DRStatusStateKey] isEqualTo: DRStatusStateFailed])
- {
- *error = "Write operation failed";
- break;
- }
- else if ([[[burn status] objectForKey: DRStatusStateKey] isEqualTo: DRStatusStateDone])
- {
- break;
- }
-
- NSString* err = (NSString*) [[[burn status] objectForKey: DRErrorStatusKey]
- objectForKey: DRErrorStatusErrorStringKey];
-
- if ([err length] > 0)
- {
- *error = JUCE_NAMESPACE::String::fromUTF8 ((JUCE_NAMESPACE::uint8*) [err UTF8String]);
- break;
- }
- }
-
- [device releaseMediaReservation];
- [device releaseExclusiveAccess];
- }
- @end
-
- @implementation AudioTrackProducer
-
- - (AudioTrackProducer*) init: (int) lengthInFrames_
- {
- lengthInFrames = lengthInFrames_;
- readPosition = 0;
- return self;
- }
-
- - (void) setupTrackProperties: (DRTrack*) track
- {
- NSMutableDictionary* p = [[track properties] mutableCopy];
- [p setObject:[DRMSF msfWithFrames: lengthInFrames] forKey: DRTrackLengthKey];
- [p setObject:[NSNumber numberWithUnsignedShort:2352] forKey: DRBlockSizeKey];
- [p setObject:[NSNumber numberWithInt:0] forKey: DRDataFormKey];
- [p setObject:[NSNumber numberWithInt:0] forKey: DRBlockTypeKey];
- [p setObject:[NSNumber numberWithInt:0] forKey: DRTrackModeKey];
- [p setObject:[NSNumber numberWithInt:0] forKey: DRSessionFormatKey];
-
- [track setProperties: p];
- [p release];
- }
-
- - (AudioTrackProducer*) initWithAudioSource: (JUCE_NAMESPACE::AudioSource*) source_ numSamples: (int) lengthInSamples
- {
- AudioTrackProducer* s = [self init: (lengthInSamples + 587) / 588];
-
- if (s != nil)
- s->source = source_;
-
- return s;
- }
-
- - (void) dealloc
- {
- if (source != 0)
- {
- source->releaseResources();
- delete source;
- }
-
- [super dealloc];
- }
-
- - (void) cleanupTrackAfterBurn: (DRTrack*) track
- {
- }
-
- - (BOOL) cleanupTrackAfterVerification:(DRTrack*)track
- {
- return true;
- }
-
- - (uint64_t) estimateLengthOfTrack:(DRTrack*)track
- {
- return lengthInFrames;
- }
-
- - (BOOL) prepareTrack:(DRTrack*)track forBurn:(DRBurn*)burn
- toMedia:(NSDictionary*)mediaInfo
- {
- if (source != 0)
- source->prepareToPlay (44100 / 75, 44100);
-
- readPosition = 0;
- return true;
- }
-
- - (BOOL) prepareTrackForVerification:(DRTrack*)track
- {
- if (source != 0)
- source->prepareToPlay (44100 / 75, 44100);
-
- return true;
- }
-
- - (uint32_t) produceDataForTrack:(DRTrack*)track intoBuffer:(char*)buffer
- length:(uint32_t)bufferLength atAddress:(uint64_t)address
- blockSize:(uint32_t)blockSize ioFlags:(uint32_t*)flags
- {
- if (source != 0)
- {
- const int numSamples = JUCE_NAMESPACE::jmin (bufferLength / 4, (lengthInFrames * (44100 / 75)) - readPosition);
-
- if (numSamples > 0)
- {
- JUCE_NAMESPACE::AudioSampleBuffer tempBuffer (2, numSamples);
-
- JUCE_NAMESPACE::AudioSourceChannelInfo info;
- info.buffer = &tempBuffer;
- info.startSample = 0;
- info.numSamples = numSamples;
-
- source->getNextAudioBlock (info);
-
- JUCE_NAMESPACE::AudioDataConverters::convertFloatToInt16LE (tempBuffer.getSampleData (0),
- buffer, numSamples, 4);
- JUCE_NAMESPACE::AudioDataConverters::convertFloatToInt16LE (tempBuffer.getSampleData (1),
- buffer + 2, numSamples, 4);
-
- readPosition += numSamples;
- }
-
- return numSamples * 4;
- }
-
- return 0;
- }
-
- - (uint32_t) producePreGapForTrack:(DRTrack*)track
- intoBuffer:(char*)buffer length:(uint32_t)bufferLength
- atAddress:(uint64_t)address blockSize:(uint32_t)blockSize
- ioFlags:(uint32_t*)flags
- {
- zeromem (buffer, bufferLength);
- return bufferLength;
- }
-
- - (BOOL) verifyDataForTrack:(DRTrack*)track inBuffer:(const char*)buffer
- length:(uint32_t)bufferLength atAddress:(uint64_t)address
- blockSize:(uint32_t)blockSize ioFlags:(uint32_t*)flags
- {
- return true;
- }
-
- @end
-
- BEGIN_JUCE_NAMESPACE
-
- AudioCDBurner::AudioCDBurner (const int deviceIndex)
- : internal (0)
- {
- const AutoPool pool;
- OpenDiskDevice* dev = [[OpenDiskDevice alloc] initWithDevice: [[DRDevice devices] objectAtIndex: deviceIndex]];
-
- internal = (void*) dev;
- }
-
- AudioCDBurner::~AudioCDBurner()
- {
- const AutoPool pool;
- OpenDiskDevice* dev = (OpenDiskDevice*) internal;
-
- if (dev != 0)
- [dev release];
- }
-
- AudioCDBurner* AudioCDBurner::openDevice (const int deviceIndex)
- {
- const AutoPool pool;
- AudioCDBurner* b = new AudioCDBurner (deviceIndex);
-
- if (b->internal == 0)
- deleteAndZero (b);
-
- return b;
- }
-
- static NSArray* findDiskBurnerDevices()
- {
- NSMutableArray* results = [NSMutableArray array];
- NSArray* devs = [DRDevice devices];
-
- if (devs != 0)
- {
- int num = [devs count];
- int i;
- for (i = 0; i < num; ++i)
- {
- NSDictionary* dic = [[devs objectAtIndex: i] info];
- NSString* name = [dic valueForKey: DRDeviceProductNameKey];
- if (name != nil)
- [results addObject: name];
- }
- }
-
- return results;
- }
-
- const StringArray AudioCDBurner::findAvailableDevices()
- {
- const AutoPool pool;
- NSArray* names = findDiskBurnerDevices();
- StringArray s;
-
- for (int i = 0; i < [names count]; ++i)
- s.add (String::fromUTF8 ((JUCE_NAMESPACE::uint8*) [[names objectAtIndex: i] UTF8String]));
-
- return s;
- }
-
- bool AudioCDBurner::isDiskPresent() const
- {
- OpenDiskDevice* dev = (OpenDiskDevice*) internal;
-
- return dev != 0 && [dev isDiskPresent];
- }
-
- int AudioCDBurner::getNumAvailableAudioBlocks() const
- {
- OpenDiskDevice* dev = (OpenDiskDevice*) internal;
-
- return [dev getNumAvailableAudioBlocks];
- }
-
- bool AudioCDBurner::addAudioTrack (AudioSource* source, int numSamps)
- {
- const AutoPool pool;
- OpenDiskDevice* dev = (OpenDiskDevice*) internal;
-
- if (dev != 0)
- {
- [dev addSourceTrack: source numSamples: numSamps];
- return true;
- }
-
- return false;
- }
-
- const String AudioCDBurner::burn (JUCE_NAMESPACE::AudioCDBurner::BurnProgressListener* listener,
- const bool ejectDiscAfterwards,
- const bool peformFakeBurnForTesting)
- {
- const AutoPool pool;
- JUCE_NAMESPACE::String error ("Couldn't open or write to the CD device");
-
- OpenDiskDevice* dev = (OpenDiskDevice*) internal;
-
- if (dev != 0)
- {
- error = JUCE_NAMESPACE::String::empty;
- [dev burn: listener
- errorString: &error
- ejectAfterwards: ejectDiscAfterwards
- isFake: peformFakeBurnForTesting];
- }
-
- return error;
- }
-
- END_JUCE_NAMESPACE
-
- #endif
- /********* End of inlined file: juce_mac_AudioCDBurner.mm *********/
-
- /********* Start of inlined file: juce_mac_CoreAudio.cpp *********/
-
- #include <CoreAudio/AudioHardware.h>
-
- BEGIN_JUCE_NAMESPACE
-
- #ifndef JUCE_COREAUDIO_ERROR_LOGGING_ENABLED
- #define JUCE_COREAUDIO_ERROR_LOGGING_ENABLED 1
- #endif
-
- #undef log
- #if JUCE_COREAUDIO_LOGGING_ENABLED
- #define log(a) Logger::writeToLog (a)
- #else
- #define log(a)
- #endif
-
- #undef OK
- #if JUCE_COREAUDIO_ERROR_LOGGING_ENABLED
- static bool logAnyErrors_CoreAudio (const OSStatus err, const int lineNum)
- {
- if (err == noErr)
- return true;
-
- Logger::writeToLog (T("CoreAudio error: ") + String (lineNum) + T(" - ") + String::toHexString ((int)err));
- jassertfalse
- return false;
- }
-
- #define OK(a) logAnyErrors_CoreAudio (a, __LINE__)
- #else
- #define OK(a) (a == noErr)
- #endif
-
- static const int maxNumChans = 96;
-
- class CoreAudioInternal : public Timer
- {
- public:
-
- CoreAudioInternal (AudioDeviceID id)
- : deviceID (id),
- started (false),
- audioBuffer (0),
- numInputChans (0),
- numOutputChans (0),
- callbacksAllowed (true),
- numInputChannelInfos (0),
- numOutputChannelInfos (0),
- inputLatency (0),
- outputLatency (0),
- callback (0),
- inputDevice (0),
- isSlaveDevice (false)
- {
- sampleRate = 0;
- bufferSize = 512;
-
- if (deviceID == 0)
- {
- error = TRANS("can't open device");
- }
- else
- {
- updateDetailsFromDevice();
-
- AudioDeviceAddPropertyListener (deviceID,
- kAudioPropertyWildcardChannel,
- kAudioPropertyWildcardSection,
- kAudioPropertyWildcardPropertyID,
- deviceListenerProc, this);
- }
- }
-
- ~CoreAudioInternal()
- {
- AudioDeviceRemovePropertyListener (deviceID,
- kAudioPropertyWildcardChannel,
- kAudioPropertyWildcardSection,
- kAudioPropertyWildcardPropertyID,
- deviceListenerProc);
-
- stop (false);
-
- juce_free (audioBuffer);
- delete inputDevice;
- }
-
- void setTempBufferSize (const int numChannels, const int numSamples)
- {
- juce_free (audioBuffer);
-
- audioBuffer = (float*) juce_calloc (32 + numChannels * numSamples * sizeof (float));
-
- zeromem (tempInputBuffers, sizeof (tempInputBuffers));
- zeromem (tempOutputBuffers, sizeof (tempOutputBuffers));
-
- int count = 0;
- int i;
- for (i = 0; i < numInputChans; ++i)
- tempInputBuffers[i] = audioBuffer + count++ * numSamples;
-
- for (i = 0; i < numOutputChans; ++i)
- tempOutputBuffers[i] = audioBuffer + count++ * numSamples;
- }
-
- // returns the number of actual available channels
- void fillInChannelInfo (bool input)
- {
- int chanNum = 0, activeChans = 0;
- UInt32 size;
-
- if (OK (AudioDeviceGetPropertyInfo (deviceID, 0, input, kAudioDevicePropertyStreamConfiguration, &size, 0)))
- {
- AudioBufferList* const bufList = (AudioBufferList*) juce_calloc (size);
-
- if (OK (AudioDeviceGetProperty (deviceID, 0, input, kAudioDevicePropertyStreamConfiguration, &size, bufList)))
- {
- const int numStreams = bufList->mNumberBuffers;
-
- for (int i = 0; i < numStreams; ++i)
- {
- const AudioBuffer& b = bufList->mBuffers[i];
-
- for (unsigned int j = 0; j < b.mNumberChannels; ++j)
- {
- if (input)
- {
- if (activeInputChans[chanNum])
- {
- inputChannelInfo [activeChans].sourceChannelNum = chanNum;
- inputChannelInfo [activeChans].streamNum = i;
- inputChannelInfo [activeChans].dataOffsetSamples = j;
- inputChannelInfo [activeChans].dataStrideSamples = b.mNumberChannels;
- ++activeChans;
- numInputChannelInfos = activeChans;
- }
-
- inChanNames.add (T("input ") + String (chanNum + 1));
- }
- else
- {
- if (activeOutputChans[chanNum])
- {
- outputChannelInfo [activeChans].sourceChannelNum = chanNum;
- outputChannelInfo [activeChans].streamNum = i;
- outputChannelInfo [activeChans].dataOffsetSamples = j;
- outputChannelInfo [activeChans].dataStrideSamples = b.mNumberChannels;
- ++activeChans;
- numOutputChannelInfos = activeChans;
- }
-
- outChanNames.add (T("output ") + String (chanNum + 1));
- }
-
- ++chanNum;
- }
- }
- }
-
- juce_free (bufList);
- }
- }
-
- void updateDetailsFromDevice()
- {
- stopTimer();
-
- if (deviceID == 0)
- return;
-
- const ScopedLock sl (callbackLock);
-
- Float64 sr;
- UInt32 size = sizeof (Float64);
- if (OK (AudioDeviceGetProperty (deviceID, 0, false, kAudioDevicePropertyNominalSampleRate, &size, &sr)))
- sampleRate = sr;
-
- UInt32 framesPerBuf;
- size = sizeof (framesPerBuf);
-
- if (OK (AudioDeviceGetProperty (deviceID, 0, false, kAudioDevicePropertyBufferFrameSize, &size, &framesPerBuf)))
- {
- bufferSize = framesPerBuf;
-
- if (bufferSize > 0)
- setTempBufferSize (numInputChans + numOutputChans, bufferSize);
- }
-
- bufferSizes.clear();
-
- if (OK (AudioDeviceGetPropertyInfo (deviceID, 0, false, kAudioDevicePropertyBufferFrameSizeRange, &size, 0)))
- {
- AudioValueRange* ranges = (AudioValueRange*) juce_calloc (size);
-
- if (OK (AudioDeviceGetProperty (deviceID, 0, false, kAudioDevicePropertyBufferFrameSizeRange, &size, ranges)))
- {
- bufferSizes.add ((int) ranges[0].mMinimum);
-
- for (int i = 32; i < 8192; i += 32)
- {
- for (int j = size / sizeof (AudioValueRange); --j >= 0;)
- {
- if (i >= ranges[j].mMinimum && i <= ranges[j].mMaximum)
- {
- bufferSizes.addIfNotAlreadyThere (i);
- break;
- }
- }
- }
-
- if (bufferSize > 0)
- bufferSizes.addIfNotAlreadyThere (bufferSize);
- }
-
- juce_free (ranges);
- }
-
- if (bufferSizes.size() == 0 && bufferSize > 0)
- bufferSizes.add (bufferSize);
-
- sampleRates.clear();
- const double possibleRates[] = { 44100.0, 48000.0, 88200.0, 96000.0, 176400.0, 192000.0 };
- String rates;
-
- if (OK (AudioDeviceGetPropertyInfo (deviceID, 0, false, kAudioDevicePropertyAvailableNominalSampleRates, &size, 0)))
- {
- AudioValueRange* ranges = (AudioValueRange*) juce_calloc (size);
-
- if (OK (AudioDeviceGetProperty (deviceID, 0, false, kAudioDevicePropertyAvailableNominalSampleRates, &size, ranges)))
- {
- for (int i = 0; i < numElementsInArray (possibleRates); ++i)
- {
- bool ok = false;
-
- for (int j = size / sizeof (AudioValueRange); --j >= 0;)
- if (possibleRates[i] >= ranges[j].mMinimum - 2 && possibleRates[i] <= ranges[j].mMaximum + 2)
- ok = true;
-
- if (ok)
- {
- sampleRates.add (possibleRates[i]);
- rates << possibleRates[i] << T(" ");
- }
- }
- }
-
- juce_free (ranges);
- }
-
- if (sampleRates.size() == 0 && sampleRate > 0)
- {
- sampleRates.add (sampleRate);
- rates << sampleRate;
- }
-
- log (T("sr: ") + rates);
-
- inputLatency = 0;
- outputLatency = 0;
- UInt32 lat;
- size = sizeof (UInt32);
- if (AudioDeviceGetProperty (deviceID, 0, true, kAudioDevicePropertyLatency, &size, &lat) == noErr)
- inputLatency = (int) lat;
-
- if (AudioDeviceGetProperty (deviceID, 0, false, kAudioDevicePropertyLatency, &size, &lat) == noErr)
- outputLatency = (int) lat;
-
- log (T("lat: ") + String (inputLatency) + T(" ") + String (outputLatency));
-
- inChanNames.clear();
- outChanNames.clear();
-
- zeromem (inputChannelInfo, sizeof (inputChannelInfo));
- zeromem (outputChannelInfo, sizeof (outputChannelInfo));
-
- fillInChannelInfo (true);
- fillInChannelInfo (false);
- }
-
- const StringArray getSources (bool input)
- {
- StringArray s;
- int num = 0;
- OSType* types = getAllDataSourcesForDevice (deviceID, input, num);
-
- if (types != 0)
- {
- for (int i = 0; i < num; ++i)
- {
- AudioValueTranslation avt;
- char buffer[256];
-
- avt.mInputData = (void*) &(types[i]);
- avt.mInputDataSize = sizeof (UInt32);
- avt.mOutputData = buffer;
- avt.mOutputDataSize = 256;
-
- UInt32 transSize = sizeof (avt);
- if (OK (AudioDeviceGetProperty (deviceID, 0, input, kAudioDevicePropertyDataSourceNameForID, &transSize, &avt)))
- {
- DBG (buffer);
- s.add (buffer);
- }
- }
-
- juce_free (types);
- }
-
- return s;
- }
-
- int getCurrentSourceIndex (bool input) const
- {
- OSType currentSourceID = 0;
- UInt32 size = 0;
- int result = -1;
-
- if (deviceID != 0
- && OK (AudioDeviceGetPropertyInfo (deviceID, 0, input, kAudioDevicePropertyDataSource, &size, 0)))
- {
- if (OK (AudioDeviceGetProperty (deviceID, 0, input, kAudioDevicePropertyDataSource, &size, ¤tSourceID)))
- {
- int num = 0;
- OSType* const types = getAllDataSourcesForDevice (deviceID, input, num);
-
- if (types != 0)
- {
- for (int i = 0; i < num; ++i)
- {
- if (types[num] == currentSourceID)
- {
- result = i;
- break;
- }
- }
-
- juce_free (types);
- }
- }
- }
-
- return result;
- }
-
- void setCurrentSourceIndex (int index, bool input)
- {
- if (deviceID != 0)
- {
- int num = 0;
- OSType* types = getAllDataSourcesForDevice (deviceID, input, num);
-
- if (types != 0)
- {
- if (((unsigned int) index) < num)
- {
- OSType typeId = types[index];
- AudioDeviceSetProperty (deviceID, 0, 0, input, kAudioDevicePropertyDataSource, sizeof (typeId), &typeId);
- }
-
- juce_free (types);
- }
- }
- }
-
- const String reopen (const BitArray& inputChannels,
- const BitArray& outputChannels,
- double newSampleRate,
- int bufferSizeSamples)
- {
- error = String::empty;
- log ("CoreAudio reopen");
- callbacksAllowed = false;
- stopTimer();
-
- stop (false);
-
- activeInputChans = inputChannels;
- activeOutputChans = outputChannels;
-
- activeInputChans.setRange (inChanNames.size(),
- activeInputChans.getHighestBit() + 1 - inChanNames.size(),
- false);
-
- activeOutputChans.setRange (outChanNames.size(),
- activeOutputChans.getHighestBit() + 1 - outChanNames.size(),
- false);
-
- numInputChans = activeInputChans.countNumberOfSetBits();
- numOutputChans = activeOutputChans.countNumberOfSetBits();
-
- // set sample rate
- Float64 sr = newSampleRate;
- UInt32 size = sizeof (sr);
- OK (AudioDeviceSetProperty (deviceID, 0, 0, false, kAudioDevicePropertyNominalSampleRate, size, &sr));
- OK (AudioDeviceSetProperty (deviceID, 0, 0, true, kAudioDevicePropertyNominalSampleRate, size, &sr));
-
- // change buffer size
- UInt32 framesPerBuf = bufferSizeSamples;
- size = sizeof (framesPerBuf);
-
- OK (AudioDeviceSetProperty (deviceID, 0, 0, false, kAudioDevicePropertyBufferFrameSize, size, &framesPerBuf));
- OK (AudioDeviceSetProperty (deviceID, 0, 0, true, kAudioDevicePropertyBufferFrameSize, size, &framesPerBuf));
-
- // wait for the changes to happen (on some devices)
- int i = 30;
- while (--i >= 0)
- {
- updateDetailsFromDevice();
-
- if (sampleRate == newSampleRate && bufferSizeSamples == bufferSize)
- break;
-
- Thread::sleep (100);
- }
-
- if (i < 0)
- error = "Couldn't change sample rate/buffer size";
-
- if (sampleRates.size() == 0)
- error = "Device has no available sample-rates";
-
- if (bufferSizes.size() == 0)
- error = "Device has no available buffer-sizes";
-
- if (inputDevice != 0 && error.isEmpty())
- error = inputDevice->reopen (inputChannels,
- outputChannels,
- newSampleRate,
- bufferSizeSamples);
-
- callbacksAllowed = true;
-
- return error;
- }
-
- bool start (AudioIODeviceCallback* cb)
- {
- if (! started)
- {
- callback = 0;
-
- if (deviceID != 0)
- {
- if (OK (AudioDeviceAddIOProc (deviceID, audioIOProc, (void*) this)))
- {
- if (OK (AudioDeviceStart (deviceID, audioIOProc)))
- {
- started = true;
- }
- else
- {
- OK (AudioDeviceRemoveIOProc (deviceID, audioIOProc));
- }
- }
- }
- }
-
- if (started)
- {
- const ScopedLock sl (callbackLock);
- callback = cb;
- }
-
- if (inputDevice != 0)
- return started && inputDevice->start (cb);
- else
- return started;
- }
-
- void stop (bool leaveInterruptRunning)
- {
- callbackLock.enter();
- callback = 0;
- callbackLock.exit();
-
- if (started
- && (deviceID != 0)
- && ! leaveInterruptRunning)
- {
- OK (AudioDeviceStop (deviceID, audioIOProc));
- OK (AudioDeviceRemoveIOProc (deviceID, audioIOProc));
- started = false;
-
- callbackLock.enter();
- callbackLock.exit();
-
- // wait until it's definately stopped calling back..
- for (int i = 40; --i >= 0;)
- {
- Thread::sleep (50);
-
- UInt32 running = 0;
- UInt32 size = sizeof (running);
- OK (AudioDeviceGetProperty (deviceID, 0, false, kAudioDevicePropertyDeviceIsRunning, &size, &running));
- if (running == 0)
- break;
- }
-
- callbackLock.enter();
- callbackLock.exit();
- }
-
- if (inputDevice != 0)
- inputDevice->stop (leaveInterruptRunning);
- }
-
- double getSampleRate() const
- {
- return sampleRate;
- }
-
- int getBufferSize() const
- {
- return bufferSize;
- }
-
- void audioCallback (const AudioBufferList* inInputData,
- AudioBufferList* outOutputData)
- {
- int i;
- const ScopedLock sl (callbackLock);
-
- if (callback != 0)
- {
- if (inputDevice == 0)
- {
- for (i = numInputChans; --i >= 0;)
- {
- const CallbackDetailsForChannel& info = inputChannelInfo[i];
- float* dest = tempInputBuffers [info.sourceChannelNum];
- const float* src = ((const float*) inInputData->mBuffers[info.streamNum].mData)
- + info.dataOffsetSamples;
- const int stride = info.dataStrideSamples;
-
- if (stride != 0) // if this is zero, info is invalid
- {
- for (int j = bufferSize; --j >= 0;)
- {
- *dest++ = *src;
- src += stride;
- }
- }
- }
- }
-
- if (! isSlaveDevice)
- {
- if (inputDevice == 0)
- {
- callback->audioDeviceIOCallback ((const float**) tempInputBuffers,
- numInputChans,
- tempOutputBuffers,
- numOutputChans,
- bufferSize);
- }
- else
- {
- jassert (inputDevice->bufferSize == bufferSize);
-
- callback->audioDeviceIOCallback ((const float**) inputDevice->tempInputBuffers,
- inputDevice->numInputChans,
- tempOutputBuffers,
- numOutputChans,
- bufferSize);
- }
-
- for (i = numOutputChans; --i >= 0;)
- {
- const CallbackDetailsForChannel& info = outputChannelInfo[i];
- const float* src = tempOutputBuffers [i];
- float* dest = ((float*) outOutputData->mBuffers[info.streamNum].mData)
- + info.dataOffsetSamples;
- const int stride = info.dataStrideSamples;
-
- if (stride != 0) // if this is zero, info is invalid
- {
- for (int j = bufferSize; --j >= 0;)
- {
- *dest = *src++;
- dest += stride;
- }
- }
- }
- }
- }
- else
- {
- for (i = jmin (numOutputChans, numOutputChannelInfos); --i >= 0;)
- {
- const CallbackDetailsForChannel& info = outputChannelInfo[i];
- float* dest = ((float*) outOutputData->mBuffers[info.streamNum].mData)
- + info.dataOffsetSamples;
- const int stride = info.dataStrideSamples;
-
- if (stride != 0) // if this is zero, info is invalid
- {
- for (int j = bufferSize; --j >= 0;)
- {
- *dest = 0.0f;
- dest += stride;
- }
- }
- }
- }
- }
-
- // called by callbacks
- void deviceDetailsChanged()
- {
- if (callbacksAllowed)
- startTimer (100);
- }
-
- void timerCallback()
- {
- stopTimer();
- log ("CoreAudio device changed callback");
-
- const double oldSampleRate = sampleRate;
- const int oldBufferSize = bufferSize;
- updateDetailsFromDevice();
-
- if (oldBufferSize != bufferSize || oldSampleRate != sampleRate)
- {
- callbacksAllowed = false;
- stop (false);
- updateDetailsFromDevice();
- callbacksAllowed = true;
- }
- }
-
- CoreAudioInternal* getRelatedDevice() const
- {
- UInt32 size = 0;
- CoreAudioInternal* result = 0;
-
- if (deviceID != 0
- && AudioDeviceGetPropertyInfo (deviceID, 0, false, kAudioDevicePropertyRelatedDevices, &size, 0) == noErr
- && size > 0)
- {
- AudioDeviceID* devs = (AudioDeviceID*) juce_calloc (size);
-
- if (OK (AudioDeviceGetProperty (deviceID, 0, false, kAudioDevicePropertyRelatedDevices, &size, devs)))
- {
- for (unsigned int i = 0; i < size / sizeof (AudioDeviceID); ++i)
- {
- if (devs[i] != deviceID && devs[i] != 0)
- {
- result = new CoreAudioInternal (devs[i]);
-
- if (result->error.isEmpty())
- {
- const bool thisIsInput = inChanNames.size() > 0 && outChanNames.size() == 0;
- const bool otherIsInput = result->inChanNames.size() > 0 && result->outChanNames.size() == 0;
-
- if (thisIsInput != otherIsInput
- || (inChanNames.size() + outChanNames.size() == 0)
- || (result->inChanNames.size() + result->outChanNames.size()) == 0)
- break;
- }
-
- deleteAndZero (result);
- }
- }
- }
-
- juce_free (devs);
- }
-
- return result;
- }
-
- juce_UseDebuggingNewOperator
-
- String error;
- int inputLatency, outputLatency;
- BitArray activeInputChans, activeOutputChans;
- StringArray inChanNames, outChanNames;
- Array <double> sampleRates;
- Array <int> bufferSizes;
- AudioIODeviceCallback* callback;
-
- CoreAudioInternal* inputDevice;
- bool isSlaveDevice;
-
- private:
- CriticalSection callbackLock;
- AudioDeviceID deviceID;
- bool started;
- double sampleRate;
- int bufferSize;
- float* audioBuffer;
- int numInputChans, numOutputChans;
- bool callbacksAllowed;
-
- struct CallbackDetailsForChannel
- {
- int sourceChannelNum;
- int streamNum;
- int dataOffsetSamples;
- int dataStrideSamples;
- };
-
- int numInputChannelInfos, numOutputChannelInfos;
- CallbackDetailsForChannel inputChannelInfo [maxNumChans];
- CallbackDetailsForChannel outputChannelInfo [maxNumChans];
- float* tempInputBuffers [maxNumChans];
- float* tempOutputBuffers [maxNumChans];
-
- CoreAudioInternal (const CoreAudioInternal&);
- const CoreAudioInternal& operator= (const CoreAudioInternal&);
-
- static OSStatus audioIOProc (AudioDeviceID inDevice,
- const AudioTimeStamp* inNow,
- const AudioBufferList* inInputData,
- const AudioTimeStamp* inInputTime,
- AudioBufferList* outOutputData,
- const AudioTimeStamp* inOutputTime,
- void* device)
- {
- ((CoreAudioInternal*) device)->audioCallback (inInputData, outOutputData);
- return noErr;
- }
-
- static OSStatus deviceListenerProc (AudioDeviceID inDevice,
- UInt32 inLine,
- Boolean isInput,
- AudioDevicePropertyID inPropertyID,
- void* inClientData)
- {
- CoreAudioInternal* const intern = (CoreAudioInternal*) inClientData;
-
- switch (inPropertyID)
- {
- case kAudioDevicePropertyBufferSize:
- case kAudioDevicePropertyBufferFrameSize:
- case kAudioDevicePropertyNominalSampleRate:
- case kAudioDevicePropertyStreamFormat:
- case kAudioDevicePropertyDeviceIsAlive:
- intern->deviceDetailsChanged();
- break;
-
- case kAudioDevicePropertyBufferSizeRange:
- case kAudioDevicePropertyVolumeScalar:
- case kAudioDevicePropertyMute:
- case kAudioDevicePropertyPlayThru:
- case kAudioDevicePropertyDataSource:
- case kAudioDevicePropertyDeviceIsRunning:
- break;
- }
-
- return noErr;
- }
-
- static OSType* getAllDataSourcesForDevice (AudioDeviceID deviceID, const bool input, int& num)
- {
- OSType* types = 0;
- UInt32 size = 0;
- num = 0;
-
- if (deviceID != 0
- && OK (AudioDeviceGetPropertyInfo (deviceID, 0, input, kAudioDevicePropertyDataSources, &size, 0)))
- {
- types = (OSType*) juce_calloc (size);
-
- if (OK (AudioDeviceGetProperty (deviceID, 0, input, kAudioDevicePropertyDataSources, &size, types)))
- {
- num = size / sizeof (OSType);
- }
- else
- {
- juce_free (types);
- types = 0;
- }
- }
-
- return types;
- }
- };
-
- class CoreAudioIODevice : public AudioIODevice
- {
- public:
- CoreAudioIODevice (const String& deviceName,
- AudioDeviceID inputDeviceId,
- const int inputIndex_,
- AudioDeviceID outputDeviceId,
- const int outputIndex_)
- : AudioIODevice (deviceName, "CoreAudio"),
- inputIndex (inputIndex_),
- outputIndex (outputIndex_),
- isOpen_ (false),
- isStarted (false)
- {
- internal = 0;
- CoreAudioInternal* device = 0;
-
- if (outputDeviceId == 0 || outputDeviceId == inputDeviceId)
- {
- jassert (inputDeviceId != 0);
-
- device = new CoreAudioInternal (inputDeviceId);
- lastError = device->error;
-
- if (lastError.isNotEmpty())
- deleteAndZero (device);
- }
- else
- {
- device = new CoreAudioInternal (outputDeviceId);
- lastError = device->error;
-
- if (lastError.isNotEmpty())
- {
- deleteAndZero (device);
- }
- else if (inputDeviceId != 0)
- {
- CoreAudioInternal* secondDevice = new CoreAudioInternal (inputDeviceId);
- lastError = device->error;
-
- if (lastError.isNotEmpty())
- {
- delete secondDevice;
- }
- else
- {
- device->inputDevice = secondDevice;
- secondDevice->isSlaveDevice = true;
- }
- }
- }
-
- internal = device;
-
- AudioHardwareAddPropertyListener (kAudioPropertyWildcardPropertyID,
- hardwareListenerProc, internal);
- }
-
- ~CoreAudioIODevice()
- {
- AudioHardwareRemovePropertyListener (kAudioPropertyWildcardPropertyID,
- hardwareListenerProc);
-
- delete internal;
- }
-
- const StringArray getOutputChannelNames()
- {
- return internal->outChanNames;
- }
-
- const StringArray getInputChannelNames()
- {
- if (internal->inputDevice != 0)
- return internal->inputDevice->inChanNames;
- else
- return internal->inChanNames;
- }
-
- int getNumSampleRates()
- {
- return internal->sampleRates.size();
- }
-
- double getSampleRate (int index)
- {
- return internal->sampleRates [index];
- }
-
- int getNumBufferSizesAvailable()
- {
- return internal->bufferSizes.size();
- }
-
- int getBufferSizeSamples (int index)
- {
- return internal->bufferSizes [index];
- }
-
- int getDefaultBufferSize()
- {
- for (int i = 0; i < getNumBufferSizesAvailable(); ++i)
- if (getBufferSizeSamples(i) >= 512)
- return getBufferSizeSamples(i);
-
- return 512;
- }
-
- const String open (const BitArray& inputChannels,
- const BitArray& outputChannels,
- double sampleRate,
- int bufferSizeSamples)
- {
- isOpen_ = true;
-
- if (bufferSizeSamples <= 0)
- bufferSizeSamples = getDefaultBufferSize();
-
- internal->reopen (inputChannels, outputChannels, sampleRate, bufferSizeSamples);
- lastError = internal->error;
- return lastError;
- }
-
- void close()
- {
- isOpen_ = false;
- }
-
- bool isOpen()
- {
- return isOpen_;
- }
-
- int getCurrentBufferSizeSamples()
- {
- return internal != 0 ? internal->getBufferSize() : 512;
- }
-
- double getCurrentSampleRate()
- {
- return internal != 0 ? internal->getSampleRate() : 0;
- }
-
- int getCurrentBitDepth()
- {
- return 32; // no way to find out, so just assume it's high..
- }
-
- const BitArray getActiveOutputChannels() const
- {
- return internal != 0 ? internal->activeOutputChans : BitArray();
- }
-
- const BitArray getActiveInputChannels() const
- {
- BitArray chans;
-
- if (internal != 0)
- {
- chans = internal->activeInputChans;
-
- if (internal->inputDevice != 0)
- chans.orWith (internal->inputDevice->activeInputChans);
- }
-
- return chans;
- }
-
- int getOutputLatencyInSamples()
- {
- if (internal == 0)
- return 0;
-
- // this seems like a good guess at getting the latency right - comparing
- // this with a round-trip measurement, it gets it to within a few millisecs
- // for the built-in mac soundcard
- return internal->outputLatency + internal->getBufferSize() * 2;
- }
-
- int getInputLatencyInSamples()
- {
- if (internal == 0)
- return 0;
-
- return internal->inputLatency + internal->getBufferSize() * 2;
- }
-
- void start (AudioIODeviceCallback* callback)
- {
- if (internal != 0 && ! isStarted)
- {
- if (callback != 0)
- callback->audioDeviceAboutToStart (this);
-
- isStarted = true;
- internal->start (callback);
- }
- }
-
- void stop()
- {
- if (isStarted && internal != 0)
- {
- AudioIODeviceCallback* const lastCallback = internal->callback;
-
- isStarted = false;
- internal->stop (true);
-
- if (lastCallback != 0)
- lastCallback->audioDeviceStopped();
- }
- }
-
- bool isPlaying()
- {
- if (internal->callback == 0)
- isStarted = false;
-
- return isStarted;
- }
-
- const String getLastError()
- {
- return lastError;
- }
-
- int inputIndex, outputIndex;
-
- juce_UseDebuggingNewOperator
-
- private:
- CoreAudioInternal* internal;
- bool isOpen_, isStarted;
- String lastError;
-
- static OSStatus hardwareListenerProc (AudioHardwarePropertyID inPropertyID, void* inClientData)
- {
- CoreAudioInternal* const intern = (CoreAudioInternal*) inClientData;
-
- switch (inPropertyID)
- {
- case kAudioHardwarePropertyDevices:
- intern->deviceDetailsChanged();
- break;
-
- case kAudioHardwarePropertyDefaultOutputDevice:
- case kAudioHardwarePropertyDefaultInputDevice:
- case kAudioHardwarePropertyDefaultSystemOutputDevice:
- break;
- }
-
- return noErr;
- }
-
- CoreAudioIODevice (const CoreAudioIODevice&);
- const CoreAudioIODevice& operator= (const CoreAudioIODevice&);
- };
-
- class CoreAudioIODeviceType : public AudioIODeviceType
- {
- public:
-
- CoreAudioIODeviceType()
- : AudioIODeviceType (T("CoreAudio")),
- hasScanned (false)
- {
- }
-
- ~CoreAudioIODeviceType()
- {
- }
-
- void scanForDevices()
- {
- hasScanned = true;
-
- inputDeviceNames.clear();
- outputDeviceNames.clear();
- inputIds.clear();
- outputIds.clear();
-
- UInt32 size;
- if (OK (AudioHardwareGetPropertyInfo (kAudioHardwarePropertyDevices, &size, 0)))
- {
- AudioDeviceID* const devs = (AudioDeviceID*) juce_calloc (size);
-
- if (OK (AudioHardwareGetProperty (kAudioHardwarePropertyDevices, &size, devs)))
- {
- static bool alreadyLogged = false;
- const int num = size / sizeof (AudioDeviceID);
- for (int i = 0; i < num; ++i)
- {
- char name[1024];
- size = sizeof (name);
- if (OK (AudioDeviceGetProperty (devs[i], 0, false, kAudioDevicePropertyDeviceName, &size, name)))
- {
- const String nameString (String::fromUTF8 ((const uint8*) name, strlen (name)));
-
- if (! alreadyLogged)
- log (T("CoreAudio device: ") + nameString);
-
- const int numIns = getNumChannels (devs[i], true);
- const int numOuts = getNumChannels (devs[i], false);
-
- if (numIns > 0)
- {
- inputDeviceNames.add (nameString);
- inputIds.add (devs[i]);
- }
-
- if (numOuts > 0)
- {
- outputDeviceNames.add (nameString);
- outputIds.add (devs[i]);
- }
- }
- }
-
- alreadyLogged = true;
- }
-
- juce_free (devs);
- }
-
- inputDeviceNames.appendNumbersToDuplicates (false, true);
- outputDeviceNames.appendNumbersToDuplicates (false, true);
- }
-
- const StringArray getDeviceNames (const bool wantInputNames) const
- {
- jassert (hasScanned); // need to call scanForDevices() before doing this
-
- if (wantInputNames)
- return inputDeviceNames;
- else
- return outputDeviceNames;
- }
-
- int getDefaultDeviceIndex (const bool forInput) const
- {
- jassert (hasScanned); // need to call scanForDevices() before doing this
-
- AudioDeviceID deviceID;
- UInt32 size = sizeof (deviceID);
-
- // if they're asking for any input channels at all, use the default input, so we
- // get the built-in mic rather than the built-in output with no inputs..
- if (AudioHardwareGetProperty (forInput ? kAudioHardwarePropertyDefaultInputDevice
- : kAudioHardwarePropertyDefaultOutputDevice,
- &size, &deviceID) == noErr)
- {
- if (forInput)
- {
- for (int i = inputIds.size(); --i >= 0;)
- if (inputIds[i] == deviceID)
- return i;
- }
- else
- {
- for (int i = outputIds.size(); --i >= 0;)
- if (outputIds[i] == deviceID)
- return i;
- }
- }
-
- return 0;
- }
-
- int getIndexOfDevice (AudioIODevice* device, const bool asInput) const
- {
- jassert (hasScanned); // need to call scanForDevices() before doing this
-
- CoreAudioIODevice* const d = dynamic_cast <CoreAudioIODevice*> (device);
- if (d == 0)
- return -1;
-
- return asInput ? d->inputIndex
- : d->outputIndex;
- }
-
- bool hasSeparateInputsAndOutputs() const { return true; }
-
- AudioIODevice* createDevice (const String& outputDeviceName,
- const String& inputDeviceName)
- {
- jassert (hasScanned); // need to call scanForDevices() before doing this
-
- const int inputIndex = inputDeviceNames.indexOf (inputDeviceName);
- const int outputIndex = outputDeviceNames.indexOf (outputDeviceName);
-
- String deviceName (outputDeviceName);
- if (deviceName.isEmpty())
- deviceName = inputDeviceName;
-
- if (index >= 0)
- return new CoreAudioIODevice (deviceName,
- inputIds [inputIndex],
- inputIndex,
- outputIds [outputIndex],
- outputIndex);
-
- return 0;
- }
-
- juce_UseDebuggingNewOperator
-
- private:
- StringArray inputDeviceNames, outputDeviceNames;
- Array <AudioDeviceID> inputIds, outputIds;
-
- bool hasScanned;
-
- static int getNumChannels (AudioDeviceID deviceID, bool input)
- {
- int total = 0;
- UInt32 size;
-
- if (OK (AudioDeviceGetPropertyInfo (deviceID, 0, input, kAudioDevicePropertyStreamConfiguration, &size, 0)))
- {
- AudioBufferList* const bufList = (AudioBufferList*) juce_calloc (size);
-
- if (OK (AudioDeviceGetProperty (deviceID, 0, input, kAudioDevicePropertyStreamConfiguration, &size, bufList)))
- {
- const int numStreams = bufList->mNumberBuffers;
-
- for (int i = 0; i < numStreams; ++i)
- {
- const AudioBuffer& b = bufList->mBuffers[i];
- total += b.mNumberChannels;
- }
- }
-
- juce_free (bufList);
- }
-
- return total;
- }
-
- CoreAudioIODeviceType (const CoreAudioIODeviceType&);
- const CoreAudioIODeviceType& operator= (const CoreAudioIODeviceType&);
- };
-
- AudioIODeviceType* juce_createDefaultAudioIODeviceType()
- {
- return new CoreAudioIODeviceType();
- }
-
- #undef log
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_mac_CoreAudio.cpp *********/
-
- /********* Start of inlined file: juce_mac_CoreMidi.cpp *********/
- #include <CoreMIDI/MIDIServices.h>
-
- BEGIN_JUCE_NAMESPACE
-
- #undef log
- #define log(a) Logger::writeToLog(a)
-
- static bool logAnyErrorsMidi (const OSStatus err, const int lineNum)
- {
- if (err == noErr)
- return true;
-
- log (T("CoreMidi error: ") + String (lineNum) + T(" - ") + String::toHexString ((int)err));
- jassertfalse
- return false;
- }
-
- #undef OK
- #define OK(a) logAnyErrorsMidi(a, __LINE__)
-
- static const String getEndpointName (MIDIEndpointRef endpoint, bool isExternal)
- {
- String result;
- CFStringRef str = 0;
-
- MIDIObjectGetStringProperty (endpoint, kMIDIPropertyName, &str);
-
- if (str != 0)
- {
- result = PlatformUtilities::cfStringToJuceString (str);
- CFRelease (str);
- str = 0;
- }
-
- MIDIEntityRef entity = 0;
- MIDIEndpointGetEntity (endpoint, &entity);
-
- if (entity == 0)
- return result; // probably virtual
-
- if (result.isEmpty())
- {
- // endpoint name has zero length - try the entity
- MIDIObjectGetStringProperty (entity, kMIDIPropertyName, &str);
-
- if (str != 0)
- {
- result += PlatformUtilities::cfStringToJuceString (str);
- CFRelease (str);
- str = 0;
- }
- }
-
- // now consider the device's name
- MIDIDeviceRef device = 0;
- MIDIEntityGetDevice (entity, &device);
- if (device == 0)
- return result;
-
- MIDIObjectGetStringProperty (device, kMIDIPropertyName, &str);
-
- if (str != 0)
- {
- const String s (PlatformUtilities::cfStringToJuceString (str));
- CFRelease (str);
-
- // if an external device has only one entity, throw away
- // the endpoint name and just use the device name
- if (isExternal && MIDIDeviceGetNumberOfEntities (device) < 2)
- {
- result = s;
- }
- else if (! result.startsWithIgnoreCase (s))
- {
- // prepend the device name to the entity name
- result = (s + T(" ") + result).trimEnd();
- }
- }
-
- return result;
- }
-
- static const String getConnectedEndpointName (MIDIEndpointRef endpoint)
- {
- String result;
-
- // Does the endpoint have connections?
- CFDataRef connections = 0;
- int numConnections = 0;
-
- MIDIObjectGetDataProperty (endpoint, kMIDIPropertyConnectionUniqueID, &connections);
-
- if (connections != 0)
- {
- numConnections = CFDataGetLength (connections) / sizeof (MIDIUniqueID);
-
- if (numConnections > 0)
- {
- const SInt32* pid = reinterpret_cast <const SInt32*> (CFDataGetBytePtr (connections));
-
- for (int i = 0; i < numConnections; ++i, ++pid)
- {
- MIDIUniqueID uid = EndianS32_BtoN (*pid);
- MIDIObjectRef connObject;
- MIDIObjectType connObjectType;
- OSStatus err = MIDIObjectFindByUniqueID (uid, &connObject, &connObjectType);
-
- if (err == noErr)
- {
- String s;
-
- if (connObjectType == kMIDIObjectType_ExternalSource
- || connObjectType == kMIDIObjectType_ExternalDestination)
- {
- // Connected to an external device's endpoint (10.3 and later).
- s = getEndpointName (static_cast <MIDIEndpointRef> (connObject), true);
- }
- else
- {
- // Connected to an external device (10.2) (or something else, catch-all)
- CFStringRef str = 0;
- MIDIObjectGetStringProperty (connObject, kMIDIPropertyName, &str);
-
- if (str != 0)
- {
- s = PlatformUtilities::cfStringToJuceString (str);
- CFRelease (str);
- }
- }
-
- if (s.isNotEmpty())
- {
- if (result.isNotEmpty())
- result += (", ");
-
- result += s;
- }
- }
- }
- }
-
- CFRelease (connections);
- }
-
- if (result.isNotEmpty())
- return result;
-
- // Here, either the endpoint had no connections, or we failed to obtain names for any of them.
- return getEndpointName (endpoint, false);
- }
-
- const StringArray MidiOutput::getDevices()
- {
- StringArray s;
-
- const ItemCount num = MIDIGetNumberOfDestinations();
- for (ItemCount i = 0; i < num; ++i)
- {
- MIDIEndpointRef dest = MIDIGetDestination (i);
-
- if (dest != 0)
- {
- String name (getConnectedEndpointName (dest));
-
- if (name.isEmpty())
- name = "<error>";
-
- s.add (name);
- }
- else
- {
- s.add ("<error>");
- }
- }
-
- return s;
- }
-
- int MidiOutput::getDefaultDeviceIndex()
- {
- return 0;
- }
-
- static MIDIClientRef globalMidiClient;
- static bool hasGlobalClientBeenCreated = false;
-
- static bool makeSureClientExists()
- {
- if (! hasGlobalClientBeenCreated)
- {
- String name (T("JUCE"));
-
- if (JUCEApplication::getInstance() != 0)
- name = JUCEApplication::getInstance()->getApplicationName();
-
- CFStringRef appName = PlatformUtilities::juceStringToCFString (name);
-
- hasGlobalClientBeenCreated = OK (MIDIClientCreate (appName, 0, 0, &globalMidiClient));
- CFRelease (appName);
- }
-
- return hasGlobalClientBeenCreated;
- }
-
- struct MidiPortAndEndpoint
- {
- MIDIPortRef port;
- MIDIEndpointRef endPoint;
- };
-
- MidiOutput* MidiOutput::openDevice (int index)
- {
- MidiOutput* mo = 0;
-
- if (((unsigned int) index) < (unsigned int) MIDIGetNumberOfDestinations())
- {
- MIDIEndpointRef endPoint = MIDIGetDestination (index);
-
- CFStringRef pname;
- if (OK (MIDIObjectGetStringProperty (endPoint, kMIDIPropertyName, &pname)))
- {
- log (T("CoreMidi - opening out: ") + PlatformUtilities::cfStringToJuceString (pname));
-
- if (makeSureClientExists())
- {
- MIDIPortRef port;
-
- if (OK (MIDIOutputPortCreate (globalMidiClient, pname, &port)))
- {
- MidiPortAndEndpoint* mpe = new MidiPortAndEndpoint();
- mpe->port = port;
- mpe->endPoint = endPoint;
-
- mo = new MidiOutput();
- mo->internal = (void*)mpe;
- }
- }
-
- CFRelease (pname);
- }
- }
-
- return mo;
- }
-
- MidiOutput::~MidiOutput()
- {
- MidiPortAndEndpoint* const mpe = (MidiPortAndEndpoint*)internal;
- MIDIPortDispose (mpe->port);
- delete mpe;
- }
-
- void MidiOutput::reset()
- {
- }
-
- bool MidiOutput::getVolume (float& leftVol, float& rightVol)
- {
- return false;
- }
-
- void MidiOutput::setVolume (float leftVol, float rightVol)
- {
- }
-
- void MidiOutput::sendMessageNow (const MidiMessage& message)
- {
- MidiPortAndEndpoint* const mpe = (MidiPortAndEndpoint*)internal;
-
- if (message.isSysEx())
- {
- MIDIPacketList* const packets = (MIDIPacketList*) juce_malloc (32 + message.getRawDataSize());
- packets->numPackets = 1;
- packets->packet[0].timeStamp = 0;
- packets->packet[0].length = message.getRawDataSize();
- memcpy (packets->packet[0].data, message.getRawData(), message.getRawDataSize());
-
- MIDISend (mpe->port, mpe->endPoint, packets);
- juce_free (packets);
- }
- else
- {
- MIDIPacketList packets;
- packets.numPackets = 1;
- packets.packet[0].timeStamp = 0;
- packets.packet[0].length = message.getRawDataSize();
- *(int*) (packets.packet[0].data) = *(const int*) message.getRawData();
-
- MIDISend (mpe->port, mpe->endPoint, &packets);
- }
- }
-
- const StringArray MidiInput::getDevices()
- {
- StringArray s;
-
- const ItemCount num = MIDIGetNumberOfSources();
- for (ItemCount i = 0; i < num; ++i)
- {
- MIDIEndpointRef source = MIDIGetSource (i);
-
- if (source != 0)
- {
- String name (getConnectedEndpointName (source));
-
- if (name.isEmpty())
- name = "<error>";
-
- s.add (name);
- }
- else
- {
- s.add ("<error>");
- }
- }
-
- return s;
- }
-
- int MidiInput::getDefaultDeviceIndex()
- {
- return 0;
- }
-
- struct MidiPortAndCallback
- {
- MidiInput* input;
- MIDIPortRef port;
- MIDIEndpointRef endPoint;
- MidiInputCallback* callback;
- MemoryBlock pendingData;
- int pendingBytes;
- double pendingDataTime;
- bool active;
- };
-
- static CriticalSection callbackLock;
- static VoidArray activeCallbacks;
-
- static void processSysex (MidiPortAndCallback* const mpe, const uint8*& d, int& size, const double time)
- {
- if (*d == 0xf0)
- {
- mpe->pendingBytes = 0;
- mpe->pendingDataTime = time;
- }
-
- mpe->pendingData.ensureSize (mpe->pendingBytes + size, false);
- uint8* totalMessage = (uint8*) mpe->pendingData.getData();
-
- uint8* dest = totalMessage + mpe->pendingBytes;
-
- while (size > 0)
- {
- if (mpe->pendingBytes > 0 && *d >= 0x80)
- {
- if (*d >= 0xfa || *d == 0xf8)
- {
- mpe->callback->handleIncomingMidiMessage (mpe->input, MidiMessage (*d, time));
- ++d;
- --size;
- }
- else
- {
- if (*d == 0xf7)
- {
- *dest++ = *d++;
- mpe->pendingBytes++;
- --size;
- }
-
- break;
- }
- }
- else
- {
- *dest++ = *d++;
- mpe->pendingBytes++;
- --size;
- }
- }
-
- if (totalMessage [mpe->pendingBytes - 1] == 0xf7)
- {
- mpe->callback->handleIncomingMidiMessage (mpe->input, MidiMessage (totalMessage,
- mpe->pendingBytes,
- mpe->pendingDataTime));
- mpe->pendingBytes = 0;
- }
- else
- {
- mpe->callback->handlePartialSysexMessage (mpe->input,
- totalMessage,
- mpe->pendingBytes,
- mpe->pendingDataTime);
- }
- }
-
- static void midiInputProc (const MIDIPacketList* pktlist,
- void* readProcRefCon,
- void* srcConnRefCon)
- {
- double time = Time::getMillisecondCounterHiRes() * 0.001;
- const double originalTime = time;
-
- MidiPortAndCallback* const mpe = (MidiPortAndCallback*) readProcRefCon;
- const ScopedLock sl (callbackLock);
-
- if (activeCallbacks.contains (mpe) && mpe->active)
- {
- const MIDIPacket* packet = &pktlist->packet[0];
-
- for (unsigned int i = 0; i < pktlist->numPackets; ++i)
- {
- const uint8* d = (const uint8*) (packet->data);
- int size = packet->length;
-
- while (size > 0)
- {
- time = originalTime;
-
- if (mpe->pendingBytes > 0 || d[0] == 0xf0)
- {
- processSysex (mpe, d, size, time);
- }
- else
- {
- int used = 0;
- const MidiMessage m (d, size, used, 0, time);
-
- if (used <= 0)
- {
- jassertfalse // malformed midi message
- break;
- }
- else
- {
- mpe->callback->handleIncomingMidiMessage (mpe->input, m);
- }
-
- size -= used;
- d += used;
- }
- }
-
- packet = MIDIPacketNext (packet);
- }
- }
- }
-
- MidiInput* MidiInput::openDevice (int index, MidiInputCallback* callback)
- {
- MidiInput* mi = 0;
-
- if (((unsigned int) index) < (unsigned int) MIDIGetNumberOfSources())
- {
- MIDIEndpointRef endPoint = MIDIGetSource (index);
-
- if (endPoint != 0)
- {
- CFStringRef pname;
-
- if (OK (MIDIObjectGetStringProperty (endPoint, kMIDIPropertyName, &pname)))
- {
- log (T("CoreMidi - opening inp: ") + PlatformUtilities::cfStringToJuceString (pname));
-
- if (makeSureClientExists())
- {
- MIDIPortRef port;
-
- MidiPortAndCallback* const mpe = new MidiPortAndCallback();
- mpe->active = false;
-
- if (OK (MIDIInputPortCreate (globalMidiClient, pname, midiInputProc, mpe, &port)))
- {
- if (OK (MIDIPortConnectSource (port, endPoint, 0)))
- {
- mpe->port = port;
- mpe->endPoint = endPoint;
- mpe->callback = callback;
- mpe->pendingBytes = 0;
- mpe->pendingData.ensureSize (128);
-
- mi = new MidiInput (getDevices() [index]);
- mpe->input = mi;
- mi->internal = (void*) mpe;
-
- const ScopedLock sl (callbackLock);
- activeCallbacks.add (mpe);
- }
- else
- {
- OK (MIDIPortDispose (port));
- delete mpe;
- }
- }
- else
- {
- delete mpe;
- }
- }
- }
-
- CFRelease (pname);
- }
- }
-
- return mi;
- }
-
- MidiInput::MidiInput (const String& name_)
- : name (name_)
- {
- }
-
- MidiInput::~MidiInput()
- {
- MidiPortAndCallback* const mpe = (MidiPortAndCallback*) internal;
- mpe->active = false;
-
- callbackLock.enter();
- activeCallbacks.removeValue (mpe);
- callbackLock.exit();
-
- OK (MIDIPortDisconnectSource (mpe->port, mpe->endPoint));
- OK (MIDIPortDispose (mpe->port));
- delete mpe;
- }
-
- void MidiInput::start()
- {
- MidiPortAndCallback* const mpe = (MidiPortAndCallback*) internal;
- const ScopedLock sl (callbackLock);
- mpe->active = true;
- }
-
- void MidiInput::stop()
- {
- MidiPortAndCallback* const mpe = (MidiPortAndCallback*) internal;
- const ScopedLock sl (callbackLock);
- mpe->active = false;
- }
-
- #undef log
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_mac_CoreMidi.cpp *********/
-
- /********* Start of inlined file: juce_mac_FileChooser.mm *********/
-
- #include <fnmatch.h>
-
- BEGIN_JUCE_NAMESPACE
-
- END_JUCE_NAMESPACE
-
- @interface JuceFileChooserDelegate : NSObject
- {
- JUCE_NAMESPACE::StringArray* filters;
- }
-
- - (JuceFileChooserDelegate*) initWithFilters: (JUCE_NAMESPACE::StringArray*) filters_;
- - (void) dealloc;
- - (BOOL) panel:(id) sender shouldShowFilename: (NSString*) filename;
-
- @end
-
- @implementation JuceFileChooserDelegate
- - (JuceFileChooserDelegate*) initWithFilters: (JUCE_NAMESPACE::StringArray*) filters_
- {
- [super init];
- filters = filters_;
- return self;
- }
-
- - (void) dealloc
- {
- delete filters;
- [super dealloc];
- }
-
- - (BOOL) panel:(id) sender shouldShowFilename: (NSString*) filename
- {
- const char* filenameUTF8 = (const char*) [filename UTF8String];
-
- for (int i = filters->size(); --i >= 0;)
- {
- const JUCE_NAMESPACE::String wildcard ((*filters)[i].toLowerCase());
-
- if (fnmatch (wildcard.toUTF8(), filenameUTF8, 0) == 0)
- return true;
- }
-
- return JUCE_NAMESPACE::File (nsStringToJuce (filename)).isDirectory();
- }
- @end
-
- BEGIN_JUCE_NAMESPACE
-
- void FileChooser::showPlatformDialog (OwnedArray<File>& results,
- const String& title,
- const File& currentFileOrDirectory,
- const String& filter,
- bool selectsDirectory,
- bool isSaveDialogue,
- bool warnAboutOverwritingExistingFiles,
- bool selectMultipleFiles,
- FilePreviewComponent* extraInfoComponent)
- {
- const AutoPool pool;
-
- StringArray* filters = new StringArray();
- filters->addTokens (filter.replaceCharacters (T(",:"), T(";;")), T(";"), 0);
- filters->trim();
- filters->removeEmptyStrings();
-
- JuceFileChooserDelegate* delegate = [[JuceFileChooserDelegate alloc] initWithFilters: filters];
- [delegate autorelease];
-
- NSSavePanel* panel = isSaveDialogue ? [NSSavePanel savePanel]
- : [NSOpenPanel openPanel];
-
- [panel setTitle: juceStringToNS (title)];
-
- if (! isSaveDialogue)
- {
- NSOpenPanel* openPanel = (NSOpenPanel*) panel;
- [openPanel setCanChooseDirectories: selectsDirectory];
- [openPanel setCanChooseFiles: ! selectsDirectory];
- [openPanel setAllowsMultipleSelection: selectMultipleFiles];
- }
-
- [panel setDelegate: delegate];
-
- String directory, filename;
-
- if (currentFileOrDirectory.isDirectory())
- {
- directory = currentFileOrDirectory.getFullPathName();
- }
- else
- {
- directory = currentFileOrDirectory.getParentDirectory().getFullPathName();
- filename = currentFileOrDirectory.getFileName();
- }
-
- if ([panel runModalForDirectory: juceStringToNS (directory)
- file: juceStringToNS (filename)]
- == NSOKButton)
- {
- if (isSaveDialogue)
- {
- results.add (new File (nsStringToJuce ([panel filename])));
- }
- else
- {
- NSOpenPanel* openPanel = (NSOpenPanel*) panel;
- NSArray* urls = [openPanel filenames];
- for (int i = 0; i < [urls count]; ++i)
- {
- NSString* f = [urls objectAtIndex: i];
- results.add (new File (nsStringToJuce (f)));
- }
- }
- }
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_mac_FileChooser.mm *********/
-
- /********* Start of inlined file: juce_mac_Fonts.mm *********/
-
- #include <ApplicationServices/ApplicationServices.h>
-
- BEGIN_JUCE_NAMESPACE
-
- static OSStatus pascal CubicMoveTo (const Float32Point *pt,
- void* callBackDataPtr)
- {
- Path* const p = (Path*) callBackDataPtr;
- p->startNewSubPath (pt->x, pt->y);
-
- return noErr;
- }
-
- static OSStatus pascal CubicLineTo (const Float32Point *pt,
- void* callBackDataPtr)
- {
- Path* const p = (Path*) callBackDataPtr;
- p->lineTo (pt->x, pt->y);
-
- return noErr;
- }
-
- static OSStatus pascal CubicCurveTo (const Float32Point *pt1,
- const Float32Point *pt2,
- const Float32Point *pt3,
- void* callBackDataPtr)
- {
- Path* const p = (Path*) callBackDataPtr;
- p->cubicTo (pt1->x, pt1->y,
- pt2->x, pt2->y,
- pt3->x, pt3->y);
-
- return noErr;
- }
-
- static OSStatus pascal CubicClosePath (void* callBackDataPtr)
- {
- Path* const p = (Path*) callBackDataPtr;
- p->closeSubPath();
-
- return noErr;
- }
-
- class ATSFontHelper
- {
- ATSUFontID fontId;
- ATSUStyle style;
-
- ATSCubicMoveToUPP moveToProc;
- ATSCubicLineToUPP lineToProc;
- ATSCubicCurveToUPP curveToProc;
- ATSCubicClosePathUPP closePathProc;
-
- float totalSize, ascent;
-
- TextToUnicodeInfo encodingInfo;
-
- public:
- String name;
- bool isBold, isItalic;
- float fontSize;
- int refCount;
-
- ATSFontHelper (const String& name_,
- const bool bold_,
- const bool italic_,
- const float size_)
- : fontId (0),
- name (name_),
- isBold (bold_),
- isItalic (italic_),
- fontSize (size_),
- refCount (1)
- {
- const char* const nameUtf8 = name_.toUTF8();
-
- ATSUFindFontFromName (const_cast <char*> (nameUtf8),
- strlen (nameUtf8),
- kFontFullName,
- kFontNoPlatformCode,
- kFontNoScriptCode,
- kFontNoLanguageCode,
- &fontId);
-
- ATSUCreateStyle (&style);
-
- ATSUAttributeTag attTypes[] = { kATSUFontTag,
- kATSUQDBoldfaceTag,
- kATSUQDItalicTag,
- kATSUSizeTag };
-
- ByteCount attSizes[] = { sizeof (ATSUFontID),
- sizeof (Boolean),
- sizeof (Boolean),
- sizeof (Fixed) };
-
- Boolean bold = bold_, italic = italic_;
- Fixed size = X2Fix (size_);
-
- ATSUAttributeValuePtr attValues[] = { &fontId,
- &bold,
- &italic,
- &size };
-
- ATSUSetAttributes (style, 4, attTypes, attSizes, attValues);
-
- moveToProc = NewATSCubicMoveToUPP (CubicMoveTo);
- lineToProc = NewATSCubicLineToUPP (CubicLineTo);
- curveToProc = NewATSCubicCurveToUPP (CubicCurveTo);
- closePathProc = NewATSCubicClosePathUPP (CubicClosePath);
-
- ascent = 0.0f;
- float kern, descent = 0.0f;
- getPathAndKerning (T('N'), T('O'), 0, kern, &ascent, &descent);
- totalSize = ascent + descent;
- }
-
- ~ATSFontHelper()
- {
- ATSUDisposeStyle (style);
-
- DisposeATSCubicMoveToUPP (moveToProc);
- DisposeATSCubicLineToUPP (lineToProc);
- DisposeATSCubicCurveToUPP (curveToProc);
- DisposeATSCubicClosePathUPP (closePathProc);
- }
-
- bool getPathAndKerning (const juce_wchar char1,
- const juce_wchar char2,
- Path* path,
- float& kerning,
- float* ascent,
- float* descent)
- {
- bool ok = false;
-
- UniChar buffer[4];
- buffer[0] = T(' ');
- buffer[1] = char1;
- buffer[2] = char2;
- buffer[3] = 0;
-
- UniCharCount count = kATSUToTextEnd;
- ATSUTextLayout layout;
- OSStatus err = ATSUCreateTextLayoutWithTextPtr (buffer,
- 0,
- 2,
- 2,
- 1,
- &count,
- &style,
- &layout);
- if (err == noErr)
- {
- ATSUSetTransientFontMatching (layout, true);
-
- ATSLayoutRecord* layoutRecords;
- ItemCount numRecords;
- Fixed* deltaYs;
- ItemCount numDeltaYs;
-
- ATSUDirectGetLayoutDataArrayPtrFromTextLayout (layout,
- 0,
- kATSUDirectDataLayoutRecordATSLayoutRecordCurrent,
- (void**) &layoutRecords,
- &numRecords);
-
- ATSUDirectGetLayoutDataArrayPtrFromTextLayout (layout,
- 0,
- kATSUDirectDataBaselineDeltaFixedArray,
- (void**) &deltaYs,
- &numDeltaYs);
-
- if (numRecords > 2)
- {
- kerning = (float) (Fix2X (layoutRecords[2].realPos)
- - Fix2X (layoutRecords[1].realPos));
-
- if (ascent != 0)
- {
- ATSUTextMeasurement asc;
- ByteCount actualSize;
-
- ATSUGetLineControl (layout,
- 0,
- kATSULineAscentTag,
- sizeof (ATSUTextMeasurement),
- &asc,
- &actualSize);
-
- *ascent = (float) Fix2X (asc);
- }
-
- if (descent != 0)
- {
- ATSUTextMeasurement desc;
- ByteCount actualSize;
-
- ATSUGetLineControl (layout,
- 0,
- kATSULineDescentTag,
- sizeof (ATSUTextMeasurement),
- &desc,
- &actualSize);
-
- *descent = (float) Fix2X (desc);
- }
-
- if (path != 0)
- {
- OSStatus callbackResult;
-
- ok = (ATSUGlyphGetCubicPaths (style,
- layoutRecords[1].glyphID,
- moveToProc,
- lineToProc,
- curveToProc,
- closePathProc,
- (void*) path,
- &callbackResult) == noErr);
-
- if (numDeltaYs > 0 && ok)
- {
- const float dy = (float) Fix2X (deltaYs[1]);
-
- path->applyTransform (AffineTransform::translation (0.0f, dy));
- }
- }
- else
- {
- ok = true;
- }
- }
-
- if (deltaYs != 0)
- ATSUDirectReleaseLayoutDataArrayPtr (0, kATSUDirectDataBaselineDeltaFixedArray,
- (void**) &deltaYs);
-
- if (layoutRecords != 0)
- ATSUDirectReleaseLayoutDataArrayPtr (0, kATSUDirectDataLayoutRecordATSLayoutRecordCurrent,
- (void**) &layoutRecords);
-
- ATSUDisposeTextLayout (layout);
- }
-
- return kerning;
- }
-
- float getAscent()
- {
- return ascent;
- }
-
- float getTotalHeight()
- {
- return totalSize;
- }
-
- juce_wchar getDefaultChar()
- {
- return 0;
- }
- };
-
- class ATSFontHelperCache : public Timer,
- public DeletedAtShutdown
- {
- VoidArray cache;
-
- public:
- ATSFontHelperCache()
- {
- }
-
- ~ATSFontHelperCache()
- {
- for (int i = cache.size(); --i >= 0;)
- {
- ATSFontHelper* const f = (ATSFontHelper*) cache.getUnchecked(i);
- delete f;
- }
-
- clearSingletonInstance();
- }
-
- ATSFontHelper* getFont (const String& name,
- const bool bold,
- const bool italic,
- const float size = 1024)
- {
- for (int i = cache.size(); --i >= 0;)
- {
- ATSFontHelper* const f = (ATSFontHelper*) cache.getUnchecked(i);
-
- if (f->name == name
- && f->isBold == bold
- && f->isItalic == italic
- && f->fontSize == size)
- {
- f->refCount++;
- return f;
- }
- }
-
- ATSFontHelper* const f = new ATSFontHelper (name, bold, italic, size);
- cache.add (f);
- return f;
- }
-
- void releaseFont (ATSFontHelper* f)
- {
- for (int i = cache.size(); --i >= 0;)
- {
- ATSFontHelper* const f2 = (ATSFontHelper*) cache.getUnchecked(i);
-
- if (f == f2)
- {
- f->refCount--;
-
- if (f->refCount == 0)
- startTimer (5000);
-
- break;
- }
- }
- }
-
- void timerCallback()
- {
- stopTimer();
-
- for (int i = cache.size(); --i >= 0;)
- {
- ATSFontHelper* const f = (ATSFontHelper*) cache.getUnchecked(i);
-
- if (f->refCount == 0)
- {
- cache.remove (i);
- delete f;
- }
- }
-
- if (cache.size() == 0)
- delete this;
- }
-
- juce_DeclareSingleton_SingleThreaded_Minimal (ATSFontHelperCache)
- };
-
- juce_ImplementSingleton_SingleThreaded (ATSFontHelperCache)
-
- void Typeface::initialiseTypefaceCharacteristics (const String& fontName,
- bool bold,
- bool italic,
- bool addAllGlyphsToFont) throw()
- {
- // This method is only safe to be called from the normal UI thread..
- jassert (MessageManager::getInstance()->isThisTheMessageThread());
-
- ATSFontHelper* const helper = ATSFontHelperCache::getInstance()
- ->getFont (fontName, bold, italic);
-
- clear();
- setAscent (helper->getAscent() / helper->getTotalHeight());
- setName (fontName);
- setDefaultCharacter (helper->getDefaultChar());
- setBold (bold);
- setItalic (italic);
-
- if (addAllGlyphsToFont)
- {
- //xxx
- jassertfalse
- }
-
- ATSFontHelperCache::getInstance()->releaseFont (helper);
- }
-
- bool Typeface::findAndAddSystemGlyph (juce_wchar character) throw()
- {
- // This method is only safe to be called from the normal UI thread..
- jassert (MessageManager::getInstance()->isThisTheMessageThread());
-
- ATSFontHelper* const helper = ATSFontHelperCache::getInstance()
- ->getFont (getName(), isBold(), isItalic());
-
- Path path;
- float width;
- bool foundOne = false;
-
- if (helper->getPathAndKerning (character, T('I'), &path, width, 0, 0))
- {
- path.applyTransform (AffineTransform::scale (1.0f / helper->getTotalHeight(),
- 1.0f / helper->getTotalHeight()));
-
- addGlyph (character, path, width / helper->getTotalHeight());
-
- for (int i = 0; i < glyphs.size(); ++i)
- {
- const TypefaceGlyphInfo* const g = (const TypefaceGlyphInfo*) glyphs.getUnchecked(i);
-
- float kerning;
- if (helper->getPathAndKerning (character, g->getCharacter(), 0, kerning, 0, 0))
- {
- kerning = (kerning - width) / helper->getTotalHeight();
-
- if (kerning != 0)
- addKerningPair (character, g->getCharacter(), kerning);
- }
-
- if (helper->getPathAndKerning (g->getCharacter(), character, 0, kerning, 0, 0))
- {
- kerning = kerning / helper->getTotalHeight() - g->width;
-
- if (kerning != 0)
- addKerningPair (g->getCharacter(), character, kerning);
- }
- }
-
- foundOne = true;
- }
-
- ATSFontHelperCache::getInstance()->releaseFont (helper);
- return foundOne;
- }
-
- const StringArray Font::findAllTypefaceNames() throw()
- {
- StringArray names;
- ATSFontIterator iter;
-
- if (ATSFontIteratorCreate (kATSFontContextGlobal,
- 0,
- 0,
- kATSOptionFlagsRestrictedScope,
- &iter) == noErr)
- {
- ATSFontRef font;
-
- while (ATSFontIteratorNext (iter, &font) == noErr)
- {
- CFStringRef name;
-
- if (ATSFontGetName (font,
- kATSOptionFlagsDefault,
- &name) == noErr)
- {
- const String nm (PlatformUtilities::cfStringToJuceString (name));
-
- if (nm.isNotEmpty())
- names.add (nm);
-
- CFRelease (name);
- }
- }
-
- ATSFontIteratorRelease (&iter);
- }
-
- // Use some totuous logic to eliminate bold/italic versions of fonts that we've already got
- // a plain version of. This is only necessary because of Carbon's total lack of support
- // for dealing with font families...
- for (int j = names.size(); --j >= 0;)
- {
- const char* const endings[] = { " bold", " italic", " bold italic", " bolditalic",
- " oblque", " bold oblique", " boldoblique" };
-
- for (int i = 0; i < numElementsInArray (endings); ++i)
- {
- const String ending (endings[i]);
-
- if (names[j].endsWithIgnoreCase (ending))
- {
- const String root (names[j].dropLastCharacters (ending.length()).trimEnd());
-
- if (names.contains (root)
- || names.contains (root + T(" plain"), true))
- {
- names.remove (j);
- break;
- }
- }
- }
- }
-
- names.sort (true);
- return names;
- }
-
- void Font::getDefaultFontNames (String& defaultSans, String& defaultSerif, String& defaultFixed) throw()
- {
- defaultSans = "Lucida Grande";
- defaultSerif = "Times New Roman";
- defaultFixed = "Monaco";
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_mac_Fonts.mm *********/
-
- /********* Start of inlined file: juce_mac_Messaging.mm *********/
-
- #include <Carbon/Carbon.h>
-
- BEGIN_JUCE_NAMESPACE
-
- #undef Point
-
- extern void juce_HandleProcessFocusChange();
- extern void juce_maximiseAllMinimisedWindows();
- extern void juce_InvokeMainMenuCommand (const HICommand& command);
- extern void juce_MainMenuAboutToBeUsed();
-
- struct CallbackMessagePayload
- {
- MessageCallbackFunction* function;
- void* parameter;
- void* volatile result;
- bool volatile hasBeenExecuted;
- };
-
- END_JUCE_NAMESPACE
-
- #if JUCE_COCOA
-
- NSString* juceMessageName = 0;
-
- @interface JuceAppDelegate : NSObject
- id oldDelegate;
- - (JuceAppDelegate*) init;
- - (void) dealloc;
- - (BOOL) application: (NSApplication*) theApplication openFile: (NSString*) filename;
- - (void) application: (NSApplication*) sender openFiles: (NSArray*) filenames;
- - (NSApplicationTerminateReply) applicationShouldTerminate: (NSApplication*) app;
- - (void) applicationDidBecomeActive: (NSNotification*) aNotification;
- - (void) applicationDidResignActive: (NSNotification*) aNotification;
- - (void) applicationWillUnhide: (NSNotification*) aNotification;
- - (void) customEvent: (NSNotification*) aNotification;
- - (void) performCallback: (id) info;
- @end
-
- @implementation JuceAppDelegate
-
- - (JuceAppDelegate*) init
- {
- [super init];
-
- NSNotificationCenter* center = [NSNotificationCenter defaultCenter];
-
- if (JUCE_NAMESPACE::JUCEApplication::getInstance() != 0)
- {
- oldDelegate = [NSApp delegate];
- [NSApp setDelegate: self];
- }
- else
- {
- oldDelegate = 0;
- [center addObserver: self selector: @selector (applicationDidResignActive:)
- name: NSApplicationDidResignActiveNotification object: NSApp];
-
- [center addObserver: self selector: @selector (applicationDidBecomeActive:)
- name: NSApplicationDidBecomeActiveNotification object: NSApp];
-
- [center addObserver: self selector: @selector (applicationWillUnhide:)
- name: NSApplicationWillUnhideNotification object: NSApp];
-
- }
-
- [center addObserver: self selector: @selector (customEvent:)
- name: juceMessageName object: nil];
-
- return self;
- }
-
- - (void) dealloc
- {
- if (oldDelegate != 0)
- [NSApp setDelegate: oldDelegate];
-
- [[NSNotificationCenter defaultCenter] removeObserver: self];
- [super dealloc];
- }
-
- - (NSApplicationTerminateReply) applicationShouldTerminate: (NSApplication*) app
- {
- if (JUCE_NAMESPACE::JUCEApplication::getInstance() != 0)
- JUCE_NAMESPACE::JUCEApplication::getInstance()->systemRequestedQuit();
-
- return NSTerminateLater;
- }
-
- - (BOOL) application: (NSApplication*) app openFile: (NSString*) filename
- {
- if (JUCE_NAMESPACE::JUCEApplication::getInstance() != 0)
- {
- JUCE_NAMESPACE::JUCEApplication::getInstance()->anotherInstanceStarted (nsStringToJuce (filename));
- return YES;
- }
-
- return NO;
- }
-
- - (void) application: (NSApplication*) sender openFiles: (NSArray*) filenames
- {
- JUCE_NAMESPACE::StringArray files;
- for (int i = 0; i < [filenames count]; ++i)
- files.add (nsStringToJuce ((NSString*) [filenames objectAtIndex: i]));
-
- if (files.size() > 0 && JUCE_NAMESPACE::JUCEApplication::getInstance() != 0)
- JUCE_NAMESPACE::JUCEApplication::getInstance()->anotherInstanceStarted (files.joinIntoString (T(" ")));
- }
-
- - (void) applicationDidBecomeActive: (NSNotification*) aNotification
- {
- JUCE_NAMESPACE::juce_HandleProcessFocusChange();
- }
-
- - (void) applicationDidResignActive: (NSNotification*) aNotification
- {
- JUCE_NAMESPACE::juce_HandleProcessFocusChange();
- }
-
- - (void) applicationWillUnhide: (NSNotification*) aNotification
- {
- JUCE_NAMESPACE::juce_maximiseAllMinimisedWindows();
- }
-
- - (void) customEvent: (NSNotification*) n
- {
- void* message = 0;
- [((NSData*) [n object]) getBytes: &message length: sizeof (message)];
-
- if (message != 0)
- JUCE_NAMESPACE::MessageManager::getInstance()->deliverMessage (message);
- }
-
- - (void) performCallback: (id) info
- {
- JUCE_NAMESPACE::CallbackMessagePayload* pl = (JUCE_NAMESPACE::CallbackMessagePayload*) info;
-
- if (pl != 0)
- {
- pl->result = (*pl->function) (pl->parameter);
- pl->hasBeenExecuted = true;
- }
- }
-
- @end
- #endif
-
- BEGIN_JUCE_NAMESPACE
-
- #if JUCE_COCOA
- static JuceAppDelegate* juceAppDelegate = 0;
-
- #else
- static int kJUCEClass = FOUR_CHAR_CODE ('JUCE');
- const int kJUCEKind = 1;
- const int kCallbackKind = 2;
-
- static pascal OSStatus EventHandlerProc (EventHandlerCallRef, EventRef theEvent, void* userData)
- {
- void* event = 0;
- GetEventParameter (theEvent, 'mess', typeVoidPtr, 0, sizeof (void*), 0, &event);
-
- if (event != 0)
- MessageManager::getInstance()->deliverMessage (event);
-
- return noErr;
- }
-
- static pascal OSStatus CallbackHandlerProc (EventHandlerCallRef, EventRef theEvent, void* userData)
- {
- CallbackMessagePayload* pl = 0;
- GetEventParameter (theEvent, 'mess', typeVoidPtr, 0, sizeof(pl), 0, &pl);
-
- if (pl != 0)
- {
- pl->result = (*pl->function) (pl->parameter);
- pl->hasBeenExecuted = true;
- }
-
- return noErr;
- }
-
- static pascal OSStatus MouseClickHandlerProc (EventHandlerCallRef, EventRef theEvent, void* userData)
- {
- ::Point where;
- GetEventParameter (theEvent, kEventParamMouseLocation, typeQDPoint, 0, sizeof(::Point), 0, &where);
- WindowRef window;
- if (FindWindow (where, &window) == inMenuBar)
- {
- // turn off the wait cursor before going in here..
- const int oldTimeBeforeWaitCursor = MessageManager::getInstance()->getTimeBeforeShowingWaitCursor();
- MessageManager::getInstance()->setTimeBeforeShowingWaitCursor (0);
-
- if (Component::getCurrentlyModalComponent() != 0)
- Component::getCurrentlyModalComponent()->inputAttemptWhenModal();
-
- juce_MainMenuAboutToBeUsed();
- MenuSelect (where);
- HiliteMenu (0);
-
- MessageManager::getInstance()->setTimeBeforeShowingWaitCursor (oldTimeBeforeWaitCursor);
- return noErr;
- }
-
- return eventNotHandledErr;
- }
-
- static pascal OSErr QuitAppleEventHandler (const AppleEvent *appleEvt, AppleEvent* reply, long refcon)
- {
- if (JUCEApplication::getInstance() != 0)
- JUCEApplication::getInstance()->systemRequestedQuit();
-
- return noErr;
- }
-
- static pascal OSErr OpenDocEventHandler (const AppleEvent *appleEvt, AppleEvent* reply, long refcon)
- {
- AEDescList docs;
- StringArray files;
-
- if (AEGetParamDesc (appleEvt, keyDirectObject, typeAEList, &docs) == noErr)
- {
- long num;
- if (AECountItems (&docs, &num) == noErr)
- {
- for (int i = 1; i <= num; ++i)
- {
- FSRef file;
- AEKeyword keyword;
- DescType type;
- Size size;
-
- if (AEGetNthPtr (&docs, i, typeFSRef, &keyword, &type,
- &file, sizeof (file), &size) == noErr)
- {
- const String path (PlatformUtilities::makePathFromFSRef (&file));
-
- if (path.isNotEmpty())
- files.add (path.quoted());
- }
- }
-
- if (files.size() > 0
- && JUCEApplication::getInstance() != 0)
- {
- JUCE_TRY
- {
- JUCEApplication::getInstance()
- ->anotherInstanceStarted (files.joinIntoString (T(" ")));
- }
- JUCE_CATCH_ALL
- }
- }
-
- AEDisposeDesc (&docs);
- };
-
- return noErr;
- }
-
- static pascal OSStatus AppEventHandlerProc (EventHandlerCallRef, EventRef theEvent, void* userData)
- {
- const UInt32 eventClass = GetEventClass (theEvent);
-
- if (eventClass == kEventClassCommand)
- {
- HICommand command;
-
- if (GetEventParameter (theEvent, kEventParamHICommand, typeHICommand, 0, sizeof (command), 0, &command) == noErr
- || GetEventParameter (theEvent, kEventParamDirectObject, typeHICommand, 0, sizeof (command), 0, &command) == noErr)
- {
- if (command.commandID == kHICommandQuit)
- {
- if (JUCEApplication::getInstance() != 0)
- JUCEApplication::getInstance()->systemRequestedQuit();
-
- return noErr;
- }
- else if (command.commandID == kHICommandMaximizeAll
- || command.commandID == kHICommandMaximizeWindow
- || command.commandID == kHICommandBringAllToFront)
- {
- juce_maximiseAllMinimisedWindows();
- return noErr;
- }
- else
- {
- juce_InvokeMainMenuCommand (command);
- }
- }
- }
- else if (eventClass == kEventClassApplication)
- {
- if (GetEventKind (theEvent) == kEventAppFrontSwitched)
- {
- juce_HandleProcessFocusChange();
- }
- else if (GetEventKind (theEvent) == kEventAppShown)
- {
- // this seems to blank the windows, so we need to do a repaint..
- for (int i = Desktop::getInstance().getNumComponents(); --i >= 0;)
- {
- Component* const c = Desktop::getInstance().getComponent (i);
-
- if (c != 0)
- c->repaint();
- }
- }
- }
-
- return eventNotHandledErr;
- }
-
- static EventQueueRef mainQueue;
- static EventHandlerRef juceEventHandler = 0;
- static EventHandlerRef callbackEventHandler = 0;
-
- #endif
-
- void MessageManager::doPlatformSpecificInitialisation()
- {
- static bool initialised = false;
-
- if (! initialised)
- {
- initialised = true;
-
- #if JUCE_COCOA
- // if we're linking a Juce app to one or more dynamic libraries, we'll need different values
- // for this so each module doesn't interfere with the others.
- UnsignedWide t;
- Microseconds (&t);
- kJUCEClass ^= t.lo;
-
- juceMessageName = juceStringToNS ("juce_" + String::toHexString ((int) t.lo));
-
- juceAppDelegate = [[JuceAppDelegate alloc] init];
- #else
- mainQueue = GetMainEventQueue();
- #endif
- }
-
- #if ! JUCE_COCOA
- const EventTypeSpec type1 = { kJUCEClass, kJUCEKind };
- InstallApplicationEventHandler (NewEventHandlerUPP (EventHandlerProc), 1, &type1, 0, &juceEventHandler);
-
- const EventTypeSpec type2 = { kJUCEClass, kCallbackKind };
- InstallApplicationEventHandler (NewEventHandlerUPP (CallbackHandlerProc), 1, &type2, 0, &callbackEventHandler);
-
- // only do this stuff if we're running as an application rather than a library..
- if (JUCEApplication::getInstance() != 0)
- {
- const EventTypeSpec type3 = { kEventClassMouse, kEventMouseDown };
- InstallApplicationEventHandler (NewEventHandlerUPP (MouseClickHandlerProc), 1, &type3, 0, 0);
-
- const EventTypeSpec type4[] = { { kEventClassApplication, kEventAppShown },
- { kEventClassApplication, kEventAppFrontSwitched },
- { kEventClassCommand, kEventProcessCommand } };
-
- InstallApplicationEventHandler (NewEventHandlerUPP (AppEventHandlerProc), 3, type4, 0, 0);
-
- AEInstallEventHandler (kCoreEventClass, kAEQuitApplication,
- NewAEEventHandlerUPP (QuitAppleEventHandler), 0, false);
-
- AEInstallEventHandler (kCoreEventClass, kAEOpenDocuments,
- NewAEEventHandlerUPP (OpenDocEventHandler), 0, false);
- }
- #endif
- }
-
- void MessageManager::doPlatformSpecificShutdown()
- {
- if (juceEventHandler != 0)
- {
- RemoveEventHandler (juceEventHandler);
- juceEventHandler = 0;
- }
-
- if (callbackEventHandler != 0)
- {
- RemoveEventHandler (callbackEventHandler);
- callbackEventHandler = 0;
- }
- }
-
- bool juce_postMessageToSystemQueue (void* message)
- {
- #if JUCE_COCOA
- [[NSNotificationCenter defaultCenter] postNotificationName: juceMessageName
- object: [NSData dataWithBytes: &message
- length: (int) sizeof (message)]];
-
- return true;
-
- #else
- jassert (mainQueue == GetMainEventQueue());
-
- EventRef event;
- if (CreateEvent (0, kJUCEClass, kJUCEKind, 0, kEventAttributeUserEvent, &event) == noErr)
- {
- SetEventParameter (event, 'mess', typeVoidPtr, sizeof (void*), &message);
- const bool ok = PostEventToQueue (mainQueue, event, kEventPriorityStandard) == noErr;
- ReleaseEvent (event);
- return ok;
- }
-
- return false;
- #endif
- }
-
- void MessageManager::broadcastMessage (const String& value) throw()
- {
- }
-
- void* MessageManager::callFunctionOnMessageThread (MessageCallbackFunction* callback,
- void* data)
- {
- if (isThisTheMessageThread())
- {
- return (*callback) (data);
- }
- else
- {
- CallbackMessagePayload cmp;
- cmp.function = callback;
- cmp.parameter = data;
- cmp.result = 0;
- cmp.hasBeenExecuted = false;
-
- #if JUCE_COCOA
- [juceAppDelegate performSelectorOnMainThread: @selector (performCallback:)
- withObject: (id) &cmp
- waitUntilDone: YES];
-
- return cmp.result;
-
- #else
- jassert (mainQueue == GetMainEventQueue());
-
- EventRef event;
- if (CreateEvent (0, kJUCEClass, kCallbackKind, 0, kEventAttributeUserEvent, &event) == noErr)
- {
- void* v = &cmp;
- SetEventParameter (event, 'mess', typeVoidPtr, sizeof (void*), &v);
-
- if (PostEventToQueue (mainQueue, event, kEventPriorityStandard) == noErr)
- {
- while (! cmp.hasBeenExecuted)
- Thread::yield();
-
- return cmp.result;
- }
- }
-
- return 0;
- #endif
- }
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_mac_Messaging.mm *********/
-
- /********* Start of inlined file: juce_mac_WebBrowserComponent.mm *********/
-
- #include <Cocoa/Cocoa.h>
- #include <WebKit/WebKit.h>
- #include <WebKit/HIWebView.h>
- #include <WebKit/WebPolicyDelegate.h>
- #include <WebKit/CarbonUtils.h>
-
- BEGIN_JUCE_NAMESPACE
-
- END_JUCE_NAMESPACE
-
- @interface DownloadClickDetector : NSObject
- {
- JUCE_NAMESPACE::WebBrowserComponent* ownerComponent;
- }
-
- - (DownloadClickDetector*) initWithOwner: (JUCE_NAMESPACE::WebBrowserComponent*) ownerComponent;
-
- - (void) webView: (WebView*) webView decidePolicyForNavigationAction: (NSDictionary*) actionInformation
- request: (NSURLRequest*) request
- frame: (WebFrame*) frame
- decisionListener: (id<WebPolicyDecisionListener>) listener;
- @end
-
- @implementation DownloadClickDetector
-
- - (DownloadClickDetector*) initWithOwner: (JUCE_NAMESPACE::WebBrowserComponent*) ownerComponent_
- {
- [super init];
- ownerComponent = ownerComponent_;
- return self;
- }
-
- - (void) webView: (WebView*) sender decidePolicyForNavigationAction: (NSDictionary *)actionInformation request:(NSURLRequest *)request frame:(WebFrame *)frame decisionListener:(id < WebPolicyDecisionListener >)listener
- {
- NSURL* url = [actionInformation valueForKey: @"WebActionOriginalURLKey"];
-
- if (ownerComponent->pageAboutToLoad (JUCE_NAMESPACE::String::fromUTF8 ((const JUCE_NAMESPACE::uint8*) [[url absoluteString] UTF8String])))
- [listener use];
- else
- [listener ignore];
- }
-
- @end
-
- BEGIN_JUCE_NAMESPACE
-
- class WebBrowserComponentInternal : public Timer
- {
- public:
- WebBrowserComponentInternal (WebBrowserComponent* owner_)
- : owner (owner_),
- view (0),
- webView (0)
- {
- HIWebViewCreate (&view);
-
- ComponentPeer* const peer = owner_->getPeer();
- jassert (peer != 0);
-
- if (view != 0 && peer != 0)
- {
- WindowRef parentWindow = (WindowRef) peer->getNativeHandle();
-
- WindowAttributes attributes;
- GetWindowAttributes (parentWindow, &attributes);
-
- HIViewRef parentView = 0;
-
- if ((attributes & kWindowCompositingAttribute) != 0)
- {
- HIViewRef root = HIViewGetRoot (parentWindow);
- HIViewFindByID (root, kHIViewWindowContentID, &parentView);
-
- if (parentView == 0)
- parentView = root;
- }
- else
- {
- GetRootControl (parentWindow, (ControlRef*) &parentView);
-
- if (parentView == 0)
- CreateRootControl (parentWindow, (ControlRef*) &parentView);
- }
-
- HIViewAddSubview (parentView, view);
- updateBounds();
- show();
-
- webView = HIWebViewGetWebView (view);
-
- clickListener = [[DownloadClickDetector alloc] initWithOwner: owner_];
- [webView setPolicyDelegate: clickListener];
- }
-
- startTimer (500);
- }
-
- ~WebBrowserComponentInternal()
- {
- [webView setPolicyDelegate: nil];
- [clickListener release];
-
- if (view != 0)
- CFRelease (view);
- }
-
- // Horrific bodge-workaround for the fact that the webview somehow hangs onto key
- // focus when you pop up a new window, no matter what that window does to
- // try to grab focus for itself. This catches such a situation and forces
- // focus away from the webview, then back to the place it should be..
- void timerCallback()
- {
- WindowRef viewWindow = HIViewGetWindow (view);
- WindowRef focusedWindow = GetUserFocusWindow();
-
- if (focusedWindow != viewWindow)
- {
- if (HIViewSubtreeContainsFocus (view))
- {
- HIViewAdvanceFocus (HIViewGetRoot (viewWindow), 0);
- HIViewAdvanceFocus (HIViewGetRoot (focusedWindow), 0);
- }
- }
- }
-
- void show()
- {
- HIViewSetVisible (view, true);
- }
-
- void hide()
- {
- HIViewSetVisible (view, false);
- }
-
- void goToURL (const String& url,
- const StringArray* headers,
- const MemoryBlock* postData)
- {
- char** headerNamesAsChars = 0;
- char** headerValuesAsChars = 0;
- int numHeaders = 0;
-
- if (headers != 0)
- {
- numHeaders = headers->size();
-
- headerNamesAsChars = (char**) juce_malloc (sizeof (char*) * numHeaders);
- headerValuesAsChars = (char**) juce_malloc (sizeof (char*) * numHeaders);
-
- int i;
- for (i = 0; i < numHeaders; ++i)
- {
- const String headerName ((*headers)[i].upToFirstOccurrenceOf (T(":"), false, false).trim());
- headerNamesAsChars[i] = (char*) juce_calloc (headerName.copyToUTF8 (0));
- headerName.copyToUTF8 ((JUCE_NAMESPACE::uint8*) headerNamesAsChars[i]);
-
- const String headerValue ((*headers)[i].fromFirstOccurrenceOf (T(":"), false, false).trim());
- headerValuesAsChars[i] = (char*) juce_calloc (headerValue.copyToUTF8 (0));
- headerValue.copyToUTF8 ((JUCE_NAMESPACE::uint8*) headerValuesAsChars[i]);
- }
- }
-
- sendWebViewToURL ((const char*) url.toUTF8(),
- (const char**) headerNamesAsChars,
- (const char**) headerValuesAsChars,
- numHeaders,
- postData != 0 ? (const char*) postData->getData() : 0,
- postData != 0 ? postData->getSize() : 0);
-
- for (int i = 0; i < numHeaders; ++i)
- {
- juce_free (headerNamesAsChars[i]);
- juce_free (headerValuesAsChars[i]);
- }
-
- juce_free (headerNamesAsChars);
- juce_free (headerValuesAsChars);
- }
-
- void goBack()
- {
- [webView goBack];
- }
-
- void goForward()
- {
- [webView goForward];
- }
-
- void stop()
- {
- [webView stopLoading: nil];
- }
-
- void updateBounds()
- {
- HIRect r;
- r.origin.x = (float) owner->getScreenX() - owner->getTopLevelComponent()->getScreenX();
- r.origin.y = (float) owner->getScreenY() - owner->getTopLevelComponent()->getScreenY();
- r.size.width = (float) owner->getWidth();
- r.size.height = (float) owner->getHeight();
- HIViewSetFrame (view, &r);
- }
-
- private:
- WebBrowserComponent* const owner;
- HIViewRef view;
- WebView* webView;
- DownloadClickDetector* clickListener;
-
- void sendWebViewToURL (const char* utf8URL,
- const char** headerNames,
- const char** headerValues,
- int numHeaders,
- const char* postData,
- int postDataSize)
- {
- NSMutableURLRequest* r = [NSMutableURLRequest
- requestWithURL: [NSURL URLWithString: [NSString stringWithUTF8String: utf8URL]]
- cachePolicy: NSURLRequestUseProtocolCachePolicy
- timeoutInterval: 30.0];
-
- if (postDataSize > 0)
- {
- [ r setHTTPMethod: @"POST"];
- [ r setHTTPBody: [NSData dataWithBytes: postData length: postDataSize]];
- }
-
- int i;
- for (i = 0; i < numHeaders; ++i)
- {
- [ r setValue: [NSString stringWithUTF8String: headerValues[i]]
- forHTTPHeaderField: [NSString stringWithUTF8String: headerNames[i]]];
- }
-
- [[webView mainFrame] stopLoading ];
- [[webView mainFrame] loadRequest: r];
- }
-
- WebBrowserComponentInternal (const WebBrowserComponentInternal&);
- const WebBrowserComponentInternal& operator= (const WebBrowserComponentInternal&);
- };
-
- WebBrowserComponent::WebBrowserComponent()
- : browser (0),
- associatedWindow (0),
- blankPageShown (false)
- {
- setOpaque (true);
- }
-
- WebBrowserComponent::~WebBrowserComponent()
- {
- deleteBrowser();
- }
-
- void WebBrowserComponent::goToURL (const String& url,
- const StringArray* headers,
- const MemoryBlock* postData)
- {
- lastURL = url;
-
- lastHeaders.clear();
- if (headers != 0)
- lastHeaders = *headers;
-
- lastPostData.setSize (0);
- if (postData != 0)
- lastPostData = *postData;
-
- blankPageShown = false;
-
- if (browser != 0)
- browser->goToURL (url, headers, postData);
- }
-
- void WebBrowserComponent::stop()
- {
- if (browser != 0)
- browser->stop();
- }
-
- void WebBrowserComponent::goBack()
- {
- lastURL = String::empty;
- blankPageShown = false;
-
- if (browser != 0)
- browser->goBack();
- }
-
- void WebBrowserComponent::goForward()
- {
- lastURL = String::empty;
-
- if (browser != 0)
- browser->goForward();
- }
-
- void WebBrowserComponent::paint (Graphics& g)
- {
- if (browser == 0)
- g.fillAll (Colours::white);
- }
-
- void WebBrowserComponent::checkWindowAssociation()
- {
- void* const window = getWindowHandle();
-
- if (window != associatedWindow
- || (browser == 0 && window != 0))
- {
- associatedWindow = window;
-
- deleteBrowser();
- createBrowser();
- }
-
- if (browser != 0)
- {
- if (associatedWindow != 0 && isShowing())
- {
- browser->show();
-
- if (blankPageShown)
- goBack();
- }
- else
- {
- if (! blankPageShown)
- {
- // when the component becomes invisible, some stuff like flash
- // carries on playing audio, so we need to force it onto a blank
- // page to avoid this..
-
- blankPageShown = true;
- browser->goToURL ("about:blank", 0, 0);
- }
-
- browser->hide();
- }
- }
- }
-
- void WebBrowserComponent::createBrowser()
- {
- deleteBrowser();
-
- if (isShowing())
- {
- WebInitForCarbon();
- browser = new WebBrowserComponentInternal (this);
- reloadLastURL();
- }
- }
-
- void WebBrowserComponent::deleteBrowser()
- {
- deleteAndZero (browser);
- }
-
- void WebBrowserComponent::reloadLastURL()
- {
- if (lastURL.isNotEmpty())
- {
- goToURL (lastURL, &lastHeaders, &lastPostData);
- lastURL = String::empty;
- }
- }
-
- void WebBrowserComponent::updateBrowserPosition()
- {
- if (getPeer() != 0 && browser != 0)
- browser->updateBounds();
- }
-
- void WebBrowserComponent::parentHierarchyChanged()
- {
- checkWindowAssociation();
- }
-
- void WebBrowserComponent::moved()
- {
- updateBrowserPosition();
- }
-
- void WebBrowserComponent::resized()
- {
- updateBrowserPosition();
- }
-
- void WebBrowserComponent::visibilityChanged()
- {
- checkWindowAssociation();
- }
-
- bool WebBrowserComponent::pageAboutToLoad (const String& url)
- {
- return true;
- }
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_mac_WebBrowserComponent.mm *********/
-
- /********* Start of inlined file: juce_mac_Windowing.mm *********/
-
- #include <Carbon/Carbon.h>
- #include <IOKit/IOKitLib.h>
- #include <IOKit/IOCFPlugIn.h>
- #include <IOKit/hid/IOHIDLib.h>
- #include <IOKit/hid/IOHIDKeys.h>
- #include <fnmatch.h>
-
- #if JUCE_OPENGL
- #include <AGL/agl.h>
- #endif
-
- BEGIN_JUCE_NAMESPACE
-
- #undef Point
-
- const WindowRegionCode windowRegionToUse = kWindowContentRgn;
-
- static HIObjectClassRef viewClassRef = 0;
- static CFStringRef juceHiViewClassNameCFString = 0;
- static ComponentPeer* juce_currentMouseTrackingPeer = 0;
-
- static VoidArray keysCurrentlyDown;
-
- bool KeyPress::isKeyCurrentlyDown (const int keyCode) throw()
- {
- if (keysCurrentlyDown.contains ((void*) keyCode))
- return true;
-
- if (keyCode >= 'A' && keyCode <= 'Z'
- && keysCurrentlyDown.contains ((void*) (int) CharacterFunctions::toLowerCase ((tchar) keyCode)))
- return true;
-
- if (keyCode >= 'a' && keyCode <= 'z'
- && keysCurrentlyDown.contains ((void*) (int) CharacterFunctions::toUpperCase ((tchar) keyCode)))
- return true;
-
- return false;
- }
-
- static VoidArray minimisedWindows;
-
- static void setWindowMinimised (WindowRef ref, const bool isMinimised)
- {
- if (isMinimised != minimisedWindows.contains (ref))
- CollapseWindow (ref, isMinimised);
- }
-
- void juce_maximiseAllMinimisedWindows()
- {
- const VoidArray minWin (minimisedWindows);
-
- for (int i = minWin.size(); --i >= 0;)
- setWindowMinimised ((WindowRef) (minWin[i]), false);
- }
-
- class HIViewComponentPeer;
- static HIViewComponentPeer* currentlyFocusedPeer = 0;
-
- static int currentModifiers = 0;
-
- static void updateModifiers (EventRef theEvent)
- {
- currentModifiers &= ~ (ModifierKeys::shiftModifier | ModifierKeys::ctrlModifier
- | ModifierKeys::altModifier | ModifierKeys::commandModifier);
-
- UInt32 m;
-
- if (theEvent != 0)
- GetEventParameter (theEvent, kEventParamKeyModifiers, typeUInt32, 0, sizeof(m), 0, &m);
- else
- m = GetCurrentEventKeyModifiers();
-
- if ((m & (shiftKey | rightShiftKey)) != 0)
- currentModifiers |= ModifierKeys::shiftModifier;
-
- if ((m & (controlKey | rightControlKey)) != 0)
- currentModifiers |= ModifierKeys::ctrlModifier;
-
- if ((m & (optionKey | rightOptionKey)) != 0)
- currentModifiers |= ModifierKeys::altModifier;
-
- if ((m & cmdKey) != 0)
- currentModifiers |= ModifierKeys::commandModifier;
- }
-
- void ModifierKeys::updateCurrentModifiers() throw()
- {
- currentModifierFlags = currentModifiers;
- }
-
- static int64 getEventTime (EventRef event)
- {
- const int64 millis = (int64) (1000.0 * (event != 0 ? GetEventTime (event)
- : GetCurrentEventTime()));
-
- static int64 offset = 0;
- if (offset == 0)
- offset = Time::currentTimeMillis() - millis;
-
- return offset + millis;
- }
-
- class MacBitmapImage : public Image
- {
- public:
-
- CGColorSpaceRef colourspace;
- CGDataProviderRef provider;
-
- MacBitmapImage (const PixelFormat format_,
- const int w, const int h, const bool clearImage)
- : Image (format_, w, h)
- {
- jassert (format_ == RGB || format_ == ARGB);
-
- pixelStride = (format_ == RGB) ? 3 : 4;
-
- lineStride = (w * pixelStride + 3) & ~3;
- const int imageSize = lineStride * h;
-
- if (clearImage)
- imageData = (uint8*) juce_calloc (imageSize);
- else
- imageData = (uint8*) juce_malloc (imageSize);
-
- //colourspace = CGColorSpaceCreateWithName (kCGColorSpaceUserRGB);
-
- CMProfileRef prof;
- CMGetSystemProfile (&prof);
- colourspace = CGColorSpaceCreateWithPlatformColorSpace (prof);
- provider = CGDataProviderCreateWithData (0, imageData, h * lineStride, 0);
- CMCloseProfile (prof);
- }
-
- MacBitmapImage::~MacBitmapImage()
- {
- CGDataProviderRelease (provider);
- CGColorSpaceRelease (colourspace);
-
- juce_free (imageData);
- imageData = 0; // to stop the base class freeing this
- }
-
- void blitToContext (CGContextRef context, const float dx, const float dy)
- {
- CGImageRef tempImage = CGImageCreate (getWidth(), getHeight(),
- 8, pixelStride << 3, lineStride, colourspace,
- #if MACOS_10_3_OR_EARLIER || JUCE_BIG_ENDIAN
- hasAlphaChannel() ? kCGImageAlphaPremultipliedFirst
- : kCGImageAlphaNone,
- #else
- hasAlphaChannel() ? kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst
- : kCGImageAlphaNone,
- #endif
- provider, 0, false,
- kCGRenderingIntentDefault);
-
- HIRect r;
- r.origin.x = dx;
- r.origin.y = dy;
- r.size.width = (float) getWidth();
- r.size.height = (float) getHeight();
-
- HIViewDrawCGImage (context, &r, tempImage);
-
- CGImageRelease (tempImage);
- }
-
- juce_UseDebuggingNewOperator
- };
-
- class MouseCheckTimer : private Timer,
- private DeletedAtShutdown
- {
- public:
- MouseCheckTimer()
- : lastX (0),
- lastY (0)
- {
- lastPeerUnderMouse = 0;
- resetMouseMoveChecker();
-
- #if ! MACOS_10_2_OR_EARLIER
- // Just putting this in here because it's a convenient object that'll get deleted at shutdown
- CGDisplayRegisterReconfigurationCallback (&displayChangeCallback, 0);
- #endif
- }
-
- ~MouseCheckTimer()
- {
- #if ! MACOS_10_2_OR_EARLIER
- CGDisplayRemoveReconfigurationCallback (&displayChangeCallback, 0);
- #endif
-
- clearSingletonInstance();
- }
-
- juce_DeclareSingleton_SingleThreaded_Minimal (MouseCheckTimer)
-
- bool hasEverHadAMouseMove;
-
- void moved (HIViewComponentPeer* const peer)
- {
- if (hasEverHadAMouseMove)
- startTimer (200);
-
- lastPeerUnderMouse = peer;
- }
-
- void resetMouseMoveChecker()
- {
- hasEverHadAMouseMove = false;
- startTimer (1000 / 16);
- }
-
- void timerCallback();
-
- private:
- HIViewComponentPeer* lastPeerUnderMouse;
- int lastX, lastY;
-
- #if ! MACOS_10_2_OR_EARLIER
- static void displayChangeCallback (CGDirectDisplayID, CGDisplayChangeSummaryFlags flags, void*)
- {
- Desktop::getInstance().refreshMonitorSizes();
- }
- #endif
- };
-
- juce_ImplementSingleton_SingleThreaded (MouseCheckTimer)
-
- #if JUCE_QUICKTIME
- extern void OfferMouseClickToQuickTime (WindowRef window, ::Point where, long when, long modifiers,
- Component* topLevelComp);
- #endif
-
- class HIViewComponentPeer : public ComponentPeer,
- private Timer
- {
- public:
-
- HIViewComponentPeer (Component* const component,
- const int windowStyleFlags,
- HIViewRef viewToAttachTo)
- : ComponentPeer (component, windowStyleFlags),
- fullScreen (false),
- isCompositingWindow (false),
- windowRef (0),
- viewRef (0)
- {
- repainter = new RepaintManager (this);
-
- eventHandlerRef = 0;
-
- if (viewToAttachTo != 0)
- {
- isSharedWindow = true;
- }
- else
- {
- isSharedWindow = false;
-
- WindowRef newWindow = createNewWindow (windowStyleFlags);
-
- GetRootControl (newWindow, (ControlRef*) &viewToAttachTo);
- jassert (viewToAttachTo != 0);
-
- HIViewRef growBox = 0;
- HIViewFindByID (HIViewGetRoot (newWindow), kHIViewWindowGrowBoxID, &growBox);
-
- if (growBox != 0)
- HIGrowBoxViewSetTransparent (growBox, true);
- }
-
- createNewHIView();
-
- HIViewAddSubview (viewToAttachTo, viewRef);
- HIViewSetVisible (viewRef, component->isVisible());
-
- setTitle (component->getName());
-
- if (component->isVisible() && ! isSharedWindow)
- {
- ShowWindow (windowRef);
- ActivateWindow (windowRef, component->getWantsKeyboardFocus());
- }
- }
-
- ~HIViewComponentPeer()
- {
- minimisedWindows.removeValue (windowRef);
-
- if (IsValidWindowPtr (windowRef))
- {
- if (! isSharedWindow)
- {
- CFRelease (viewRef);
- viewRef = 0;
-
- DisposeWindow (windowRef);
- }
- else
- {
- if (eventHandlerRef != 0)
- RemoveEventHandler (eventHandlerRef);
-
- CFRelease (viewRef);
- viewRef = 0;
- }
-
- windowRef = 0;
- }
-
- if (currentlyFocusedPeer == this)
- currentlyFocusedPeer = 0;
-
- delete repainter;
- }
-
- void* getNativeHandle() const
- {
- return windowRef;
- }
-
- void setVisible (bool shouldBeVisible)
- {
- HIViewSetVisible (viewRef, shouldBeVisible);
-
- if ((! isSharedWindow) && IsValidWindowPtr (windowRef))
- {
- if (shouldBeVisible)
- ShowWindow (windowRef);
- else
- HideWindow (windowRef);
-
- resizeViewToFitWindow();
-
- // If nothing else is focused, then grab the focus too
- if (shouldBeVisible
- && Component::getCurrentlyFocusedComponent() == 0
- && Process::isForegroundProcess())
- {
- component->toFront (true);
- }
- }
- }
-
- void setTitle (const String& title)
- {
- if ((! isSharedWindow) && IsValidWindowPtr (windowRef))
- {
- CFStringRef t = PlatformUtilities::juceStringToCFString (title);
- SetWindowTitleWithCFString (windowRef, t);
- CFRelease (t);
- }
- }
-
- void setPosition (int x, int y)
- {
- if (isSharedWindow)
- {
- HIViewPlaceInSuperviewAt (viewRef, x, y);
- }
- else if (IsValidWindowPtr (windowRef))
- {
- Rect r;
- GetWindowBounds (windowRef, windowRegionToUse, &r);
- r.right += x - r.left;
- r.bottom += y - r.top;
- r.left = x;
- r.top = y;
- SetWindowBounds (windowRef, windowRegionToUse, &r);
- }
- }
-
- void setSize (int w, int h)
- {
- w = jmax (0, w);
- h = jmax (0, h);
-
- if (w != getComponent()->getWidth()
- || h != getComponent()->getHeight())
- {
- repainter->repaint (0, 0, w, h);
- }
-
- if (isSharedWindow)
- {
- HIRect r;
- HIViewGetFrame (viewRef, &r);
- r.size.width = (float) w;
- r.size.height = (float) h;
- HIViewSetFrame (viewRef, &r);
- }
- else if (IsValidWindowPtr (windowRef))
- {
- Rect r;
- GetWindowBounds (windowRef, windowRegionToUse, &r);
- r.right = r.left + w;
- r.bottom = r.top + h;
- SetWindowBounds (windowRef, windowRegionToUse, &r);
- }
- }
-
- void setBounds (int x, int y, int w, int h, const bool isNowFullScreen)
- {
- fullScreen = isNowFullScreen;
- w = jmax (0, w);
- h = jmax (0, h);
-
- if (w != getComponent()->getWidth()
- || h != getComponent()->getHeight())
- {
- repainter->repaint (0, 0, w, h);
- }
-
- if (isSharedWindow)
- {
- HIRect r;
- r.origin.x = (float) x;
- r.origin.y = (float) y;
- r.size.width = (float) w;
- r.size.height = (float) h;
- HIViewSetFrame (viewRef, &r);
- }
- else if (IsValidWindowPtr (windowRef))
- {
- Rect r;
- r.left = x;
- r.top = y;
- r.right = x + w;
- r.bottom = y + h;
- SetWindowBounds (windowRef, windowRegionToUse, &r);
- }
- }
-
- void getBounds (int& x, int& y, int& w, int& h, const bool global) const
- {
- HIRect hiViewPos;
- HIViewGetFrame (viewRef, &hiViewPos);
-
- if (global)
- {
- HIViewRef content = 0;
- HIViewFindByID (HIViewGetRoot (windowRef), kHIViewWindowContentID, &content);
- HIPoint p = { 0.0f, 0.0f };
- HIViewConvertPoint (&p, viewRef, content);
-
- x = (int) p.x;
- y = (int) p.y;
-
- if (IsValidWindowPtr (windowRef))
- {
- Rect windowPos;
- GetWindowBounds (windowRef, kWindowContentRgn, &windowPos);
-
- x += windowPos.left;
- y += windowPos.top;
- }
- }
- else
- {
- x = (int) hiViewPos.origin.x;
- y = (int) hiViewPos.origin.y;
- }
-
- w = (int) hiViewPos.size.width;
- h = (int) hiViewPos.size.height;
- }
-
- void getBounds (int& x, int& y, int& w, int& h) const
- {
- getBounds (x, y, w, h, ! isSharedWindow);
- }
-
- int getScreenX() const
- {
- int x, y, w, h;
- getBounds (x, y, w, h, true);
- return x;
- }
-
- int getScreenY() const
- {
- int x, y, w, h;
- getBounds (x, y, w, h, true);
- return y;
- }
-
- void relativePositionToGlobal (int& x, int& y)
- {
- int wx, wy, ww, wh;
- getBounds (wx, wy, ww, wh, true);
-
- x += wx;
- y += wy;
- }
-
- void globalPositionToRelative (int& x, int& y)
- {
- int wx, wy, ww, wh;
- getBounds (wx, wy, ww, wh, true);
-
- x -= wx;
- y -= wy;
- }
-
- void setMinimised (bool shouldBeMinimised)
- {
- if (! isSharedWindow)
- setWindowMinimised (windowRef, shouldBeMinimised);
- }
-
- bool isMinimised() const
- {
- return minimisedWindows.contains (windowRef);
- }
-
- void setFullScreen (bool shouldBeFullScreen)
- {
- if (! isSharedWindow)
- {
- Rectangle r (lastNonFullscreenBounds);
-
- setMinimised (false);
-
- if (fullScreen != shouldBeFullScreen)
- {
- if (shouldBeFullScreen)
- r = Desktop::getInstance().getMainMonitorArea();
-
- // (can't call the component's setBounds method because that'll reset our fullscreen flag)
- if (r != getComponent()->getBounds() && ! r.isEmpty())
- setBounds (r.getX(), r.getY(), r.getWidth(), r.getHeight(), shouldBeFullScreen);
- }
- }
- }
-
- bool isFullScreen() const
- {
- return fullScreen;
- }
-
- bool contains (int x, int y, bool trueIfInAChildWindow) const
- {
- if (((unsigned int) x) >= (unsigned int) component->getWidth()
- || ((unsigned int) y) >= (unsigned int) component->getHeight()
- || ! IsValidWindowPtr (windowRef))
- return false;
-
- Rect r;
- GetWindowBounds (windowRef, windowRegionToUse, &r);
-
- ::Point p;
- p.h = r.left + x;
- p.v = r.top + y;
-
- WindowRef ref2 = 0;
- FindWindow (p, &ref2);
-
- if (windowRef != ref2)
- return false;
-
- if (trueIfInAChildWindow)
- return true;
-
- HIPoint p2;
- p2.x = (float) x;
- p2.y = (float) y;
- HIViewRef hit;
-
- HIViewGetSubviewHit (viewRef, &p2, true, &hit);
- return hit == 0 || hit == viewRef;
- }
-
- const BorderSize getFrameSize() const
- {
- return BorderSize();
- }
-
- bool setAlwaysOnTop (bool alwaysOnTop)
- {
- // can't do this so return false and let the component create a new window
- return false;
- }
-
- void toFront (bool makeActiveWindow)
- {
- makeActiveWindow = makeActiveWindow
- && component->isValidComponent()
- && (component->getWantsKeyboardFocus()
- || component->isCurrentlyModal());
-
- if (windowRef != FrontWindow()
- || (makeActiveWindow && ! IsWindowActive (windowRef))
- || ! Process::isForegroundProcess())
- {
- if (! Process::isForegroundProcess())
- {
- ProcessSerialNumber psn;
- GetCurrentProcess (&psn);
- SetFrontProcessWithOptions (&psn, kSetFrontProcessFrontWindowOnly);
- }
-
- if (IsValidWindowPtr (windowRef))
- {
- if (makeActiveWindow)
- {
- SelectWindow (windowRef);
- SetUserFocusWindow (windowRef);
- HIViewAdvanceFocus (viewRef, 0);
- }
- else
- {
- BringToFront (windowRef);
- }
-
- handleBroughtToFront();
- }
- }
- }
-
- void toBehind (ComponentPeer* other)
- {
- HIViewComponentPeer* const otherWindow = dynamic_cast <HIViewComponentPeer*> (other);
-
- if (other != 0 && windowRef != 0 && otherWindow->windowRef != 0)
- {
- if (windowRef == otherWindow->windowRef)
- {
- HIViewSetZOrder (viewRef, kHIViewZOrderBelow, otherWindow->viewRef);
- }
- else
- {
- SendBehind (windowRef, otherWindow->windowRef);
- }
- }
- }
-
- void setIcon (const Image& /*newIcon*/)
- {
- // to do..
- }
-
- void viewFocusGain()
- {
- const MessageManagerLock messLock;
-
- if (currentlyFocusedPeer != this)
- {
- if (ComponentPeer::isValidPeer (currentlyFocusedPeer))
- currentlyFocusedPeer->handleFocusLoss();
-
- currentlyFocusedPeer = this;
-
- handleFocusGain();
- }
- }
-
- void viewFocusLoss()
- {
- if (currentlyFocusedPeer == this)
- {
- currentlyFocusedPeer = 0;
- handleFocusLoss();
- }
- }
-
- bool isFocused() const
- {
- return windowRef == GetUserFocusWindow()
- && HIViewSubtreeContainsFocus (viewRef);
- }
-
- void grabFocus()
- {
- if ((! isFocused()) && IsValidWindowPtr (windowRef))
- {
- SetUserFocusWindow (windowRef);
- HIViewAdvanceFocus (viewRef, 0);
- }
- }
-
- void textInputRequired (int /*x*/, int /*y*/)
- {
- }
-
- void repaint (int x, int y, int w, int h)
- {
- if (Rectangle::intersectRectangles (x, y, w, h,
- 0, 0,
- getComponent()->getWidth(),
- getComponent()->getHeight()))
- {
- if ((getStyleFlags() & windowRepaintedExplictly) == 0)
- {
- if (isCompositingWindow)
- {
- #if MACOS_10_3_OR_EARLIER
- RgnHandle rgn = NewRgn();
- SetRectRgn (rgn, x, y, x + w, y + h);
- HIViewSetNeedsDisplayInRegion (viewRef, rgn, true);
- DisposeRgn (rgn);
- #else
- HIRect r;
- r.origin.x = x;
- r.origin.y = y;
- r.size.width = w;
- r.size.height = h;
-
- HIViewSetNeedsDisplayInRect (viewRef, &r, true);
- #endif
- }
- else
- {
- if (! isTimerRunning())
- startTimer (20);
- }
- }
-
- repainter->repaint (x, y, w, h);
- }
- }
-
- void timerCallback()
- {
- performAnyPendingRepaintsNow();
- }
-
- void performAnyPendingRepaintsNow()
- {
- stopTimer();
-
- if (component->isVisible())
- {
- #if MACOS_10_2_OR_EARLIER
- if (! isCompositingWindow)
- {
- Rect w;
- GetWindowBounds (windowRef, windowRegionToUse, &w);
-
- const int offsetInWindowX = component->getScreenX() - getScreenX();
- const int offsetInWindowY = component->getScreenY() - getScreenY();
-
- for (RectangleList::Iterator i (repainter->getRegionsNeedingRepaint()); i.next();)
- {
- const Rectangle& r = *i.getRectangle();
- w.left = offsetInWindowX + r.getX();
- w.top = offsetInWindowY + r.getY();
- w.right = offsetInWindowX + r.getRight();
- w.bottom = offsetInWindowY + r.getBottom();
- InvalWindowRect (windowRef, &w);
- }
- }
- else
- {
- EventRef theEvent;
-
- EventTypeSpec eventTypes[1];
- eventTypes[0].eventClass = kEventClassControl;
- eventTypes[0].eventKind = kEventControlDraw;
-
- int n = 3;
- while (--n >= 0
- && ReceiveNextEvent (1, eventTypes, kEventDurationNoWait, true, &theEvent) == noErr)
- {
- if (GetEventClass (theEvent) == kEventClassAppleEvent)
- {
- EventRecord eventRec;
- if (ConvertEventRefToEventRecord (theEvent, &eventRec))
- AEProcessAppleEvent (&eventRec);
- }
- else
- {
- EventTargetRef theTarget = GetEventDispatcherTarget();
- SendEventToEventTarget (theEvent, theTarget);
- }
-
- ReleaseEvent (theEvent);
- }
- }
- #else
- if (HIViewGetNeedsDisplay (viewRef) || repainter->isRepaintNeeded())
- HIViewRender (viewRef);
- #endif
- }
- }
-
- juce_UseDebuggingNewOperator
-
- WindowRef windowRef;
- HIViewRef viewRef;
-
- private:
- EventHandlerRef eventHandlerRef;
- bool fullScreen, isSharedWindow, isCompositingWindow;
- StringArray dragAndDropFiles;
-
- class RepaintManager : public Timer
- {
- public:
- RepaintManager (HIViewComponentPeer* const peer_)
- : peer (peer_),
- image (0)
- {
- }
-
- ~RepaintManager()
- {
- delete image;
- }
-
- void timerCallback()
- {
- stopTimer();
- deleteAndZero (image);
- }
-
- void repaint (int x, int y, int w, int h)
- {
- regionsNeedingRepaint.add (x, y, w, h);
- }
-
- bool isRepaintNeeded() const throw()
- {
- return ! regionsNeedingRepaint.isEmpty();
- }
-
- void repaintAnyRemainingRegions()
- {
- // if any regions have been invaldated during the paint callback,
- // we need to repaint them explicitly because the mac throws this
- // stuff away
- for (RectangleList::Iterator i (regionsNeedingRepaint); i.next();)
- {
- const Rectangle& r = *i.getRectangle();
- peer->repaint (r.getX(), r.getY(), r.getWidth(), r.getHeight());
- }
- }
-
- void paint (CGContextRef cgContext, int x, int y, int w, int h)
- {
- if (w > 0 && h > 0)
- {
- bool refresh = false;
- int imW = image != 0 ? image->getWidth() : 0;
- int imH = image != 0 ? image->getHeight() : 0;
-
- if (imW < w || imH < h)
- {
- imW = jmin (peer->getComponent()->getWidth(), (w + 31) & ~31);
- imH = jmin (peer->getComponent()->getHeight(), (h + 31) & ~31);
-
- delete image;
- image = new MacBitmapImage (peer->getComponent()->isOpaque() ? Image::RGB
- : Image::ARGB,
- imW, imH, false);
-
- refresh = true;
- }
- else if (imageX > x || imageY > y
- || imageX + imW < x + w
- || imageY + imH < y + h)
- {
- refresh = true;
- }
-
- if (refresh)
- {
- regionsNeedingRepaint.clear();
- regionsNeedingRepaint.addWithoutMerging (Rectangle (x, y, imW, imH));
- imageX = x;
- imageY = y;
- }
-
- LowLevelGraphicsSoftwareRenderer context (*image);
- context.setOrigin (-imageX, -imageY);
-
- if (context.reduceClipRegion (regionsNeedingRepaint))
- {
- regionsNeedingRepaint.clear();
-
- if (! peer->getComponent()->isOpaque())
- {
- for (RectangleList::Iterator i (*context.getRawClipRegion()); i.next();)
- {
- const Rectangle& r = *i.getRectangle();
- image->clear (r.getX(), r.getY(), r.getWidth(), r.getHeight());
- }
- }
-
- regionsNeedingRepaint.clear();
- peer->clearMaskedRegion();
- peer->handlePaint (context);
- }
- else
- {
- regionsNeedingRepaint.clear();
- }
-
- if (! peer->maskedRegion.isEmpty())
- {
- RectangleList total (Rectangle (x, y, w, h));
- total.subtract (peer->maskedRegion);
-
- CGRect* rects = (CGRect*) juce_malloc (sizeof (CGRect) * total.getNumRectangles());
- int n = 0;
-
- for (RectangleList::Iterator i (total); i.next();)
- {
- const Rectangle& r = *i.getRectangle();
- rects[n].origin.x = (int) r.getX();
- rects[n].origin.y = (int) r.getY();
- rects[n].size.width = roundFloatToInt (r.getWidth());
- rects[n++].size.height = roundFloatToInt (r.getHeight());
- }
-
- CGContextClipToRects (cgContext, rects, n);
- juce_free (rects);
- }
-
- if (peer->isSharedWindow)
- {
- CGRect clip;
- clip.origin.x = x;
- clip.origin.y = y;
- clip.size.width = jmin (w, peer->getComponent()->getWidth() - x);
- clip.size.height = jmin (h, peer->getComponent()->getHeight() - y);
-
- CGContextClipToRect (cgContext, clip);
- }
-
- image->blitToContext (cgContext, imageX, imageY);
- }
-
- startTimer (3000);
- }
-
- private:
- HIViewComponentPeer* const peer;
- MacBitmapImage* image;
- int imageX, imageY;
- RectangleList regionsNeedingRepaint;
-
- RepaintManager (const RepaintManager&);
- const RepaintManager& operator= (const RepaintManager&);
- };
-
- RepaintManager* repainter;
-
- friend class RepaintManager;
-
- static OSStatus handleFrameRepaintEvent (EventHandlerCallRef myHandler,
- EventRef theEvent,
- void* userData)
- {
- // don't draw the frame..
- return noErr;
- }
-
- OSStatus handleKeyEvent (EventRef theEvent, juce_wchar textCharacter)
- {
- updateModifiers (theEvent);
-
- UniChar unicodeChars [4];
- zeromem (unicodeChars, sizeof (unicodeChars));
- GetEventParameter (theEvent, kEventParamKeyUnicodes, typeUnicodeText, 0, sizeof (unicodeChars), 0, unicodeChars);
-
- int keyCode = (int) (unsigned int) unicodeChars[0];
-
- UInt32 rawKey = 0;
- GetEventParameter (theEvent, kEventParamKeyCode, typeUInt32, 0, sizeof (UInt32), 0, &rawKey);
-
- if ((currentModifiers & ModifierKeys::ctrlModifier) != 0
- && keyCode >= 1 && keyCode <= 26)
- {
- keyCode += ('A' - 1);
- }
- else
- {
- static const int keyTranslations[] =
- {
- 0, 's', 'd', 'f', 'h', 'g', 'z', 'x', 'c', 'v', 0xa7, 'b',
- 'q', 'w', 'e', 'r', 'y', 't', '1', '2', '3', '4', '6', '5',
- '=', '9', '7', '-', '8', '0', ']', 'o', 'u', '[', 'i', 'p',
- KeyPress::returnKey, 'l', 'j', '\'', 'k', ';', '\\', ',', '/',
- 'n', 'm', '.', 0, KeyPress::spaceKey, '`', KeyPress::backspaceKey, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, KeyPress::numberPadDecimalPoint,
- 0, KeyPress::numberPadMultiply, 0, KeyPress::numberPadAdd,
- 0, KeyPress::numberPadDelete, 0, 0, 0, KeyPress::numberPadDivide, KeyPress::returnKey,
- 0, KeyPress::numberPadSubtract, 0, 0, KeyPress::numberPadEquals, KeyPress::numberPad0,
- KeyPress::numberPad1, KeyPress::numberPad2, KeyPress::numberPad3,
- KeyPress::numberPad4, KeyPress::numberPad5, KeyPress::numberPad6,
- KeyPress::numberPad7, 0, KeyPress::numberPad8, KeyPress::numberPad9,
- 0, 0, 0, KeyPress::F5Key, KeyPress::F6Key, KeyPress::F7Key, KeyPress::F3Key,
- KeyPress::F8Key, KeyPress::F9Key, 0, KeyPress::F11Key, 0, KeyPress::F13Key,
- KeyPress::F16Key, KeyPress::F14Key, 0, KeyPress::F10Key, 0, KeyPress::F12Key,
- 0, KeyPress::F15Key, 0, KeyPress::homeKey, KeyPress::pageUpKey, 0, KeyPress::F4Key,
- KeyPress::endKey, KeyPress::F2Key, KeyPress::pageDownKey, KeyPress::F1Key,
- KeyPress::leftKey, KeyPress::rightKey, KeyPress::downKey, KeyPress::upKey, 0
- };
-
- if (((unsigned int) rawKey) < (unsigned int) numElementsInArray (keyTranslations)
- && keyTranslations [rawKey] != 0)
- {
- keyCode = keyTranslations [rawKey];
- }
-
- if ((rawKey == 0 && textCharacter != 0)
- || (CharacterFunctions::isLetterOrDigit ((juce_wchar) keyCode)
- && CharacterFunctions::isLetterOrDigit (textCharacter))) // correction for azerty-type layouts..
- {
- keyCode = CharacterFunctions::toLowerCase (textCharacter);
- }
- }
-
- if ((currentModifiers & (ModifierKeys::commandModifier | ModifierKeys::ctrlModifier)) != 0)
- textCharacter = 0;
-
- static juce_wchar lastTextCharacter = 0;
-
- switch (GetEventKind (theEvent))
- {
- case kEventRawKeyDown:
- {
- keysCurrentlyDown.addIfNotAlreadyThere ((void*) keyCode);
- lastTextCharacter = textCharacter;
-
- const bool used1 = handleKeyUpOrDown();
- const bool used2 = handleKeyPress (keyCode, textCharacter);
-
- if (used1 || used2)
- return noErr;
-
- break;
- }
-
- case kEventRawKeyUp:
- keysCurrentlyDown.removeValue ((void*) keyCode);
- lastTextCharacter = 0;
- if (handleKeyUpOrDown())
- return noErr;
-
- break;
-
- case kEventRawKeyRepeat:
- if (handleKeyPress (keyCode, lastTextCharacter))
- return noErr;
-
- break;
-
- case kEventRawKeyModifiersChanged:
- handleModifierKeysChange();
- break;
-
- default:
- jassertfalse
- break;
- }
-
- return eventNotHandledErr;
- }
-
- OSStatus handleTextInputEvent (EventRef theEvent)
- {
- UInt32 numBytesRequired = 0;
- GetEventParameter (theEvent, kEventParamTextInputSendText, typeUnicodeText, 0, 0, &numBytesRequired, 0);
-
- MemoryBlock buffer (numBytesRequired, true);
- UniChar* const uc = (UniChar*) buffer.getData();
- GetEventParameter (theEvent, kEventParamTextInputSendText, typeUnicodeText, 0, numBytesRequired, &numBytesRequired, uc);
-
- EventRef originalEvent;
- GetEventParameter (theEvent, kEventParamTextInputSendKeyboardEvent, typeEventRef, 0, sizeof (originalEvent), 0, &originalEvent);
-
- OSStatus res = noErr;
- for (int i = 0; i < numBytesRequired / sizeof (UniChar); ++i)
- res = handleKeyEvent (originalEvent, (juce_wchar) uc[i]);
-
- return res;
- }
-
- OSStatus handleMouseEvent (EventHandlerCallRef callRef, EventRef theEvent)
- {
- MouseCheckTimer::getInstance()->moved (this);
-
- ::Point where;
- GetEventParameter (theEvent, kEventParamMouseLocation, typeQDPoint, 0, sizeof (::Point), 0, &where);
- int x = where.h;
- int y = where.v;
- globalPositionToRelative (x, y);
-
- int64 time = getEventTime (theEvent);
-
- switch (GetEventKind (theEvent))
- {
- case kEventMouseMoved:
- MouseCheckTimer::getInstance()->hasEverHadAMouseMove = true;
- updateModifiers (theEvent);
- handleMouseMove (x, y, time);
- break;
-
- case kEventMouseDragged:
- updateModifiers (theEvent);
- handleMouseDrag (x, y, time);
- break;
-
- case kEventMouseDown:
- {
- if (! Process::isForegroundProcess())
- {
- ProcessSerialNumber psn;
- GetCurrentProcess (&psn);
- SetFrontProcessWithOptions (&psn, kSetFrontProcessFrontWindowOnly);
-
- toFront (true);
- }
-
- #if JUCE_QUICKTIME
- {
- long mods;
- GetEventParameter (theEvent, kEventParamKeyModifiers, typeUInt32, 0, sizeof (mods), 0, &mods);
-
- ::Point where;
- GetEventParameter (theEvent, kEventParamMouseLocation, typeQDPoint, 0, sizeof (::Point), 0, &where);
-
- OfferMouseClickToQuickTime (windowRef, where, EventTimeToTicks (GetEventTime (theEvent)), mods, component);
- }
- #endif
-
- if (component->isBroughtToFrontOnMouseClick()
- && ! component->isCurrentlyBlockedByAnotherModalComponent())
- {
- //ActivateWindow (windowRef, true);
- SelectWindow (windowRef);
- }
-
- EventMouseButton button;
- GetEventParameter (theEvent, kEventParamMouseButton, typeMouseButton, 0, sizeof (EventMouseButton), 0, &button);
-
- // need to clear all these flags because sometimes the mac can swallow (right) mouse-up events and
- // this makes a button get stuck down. Since there's no other way to tell what buttons are down,
- // this is all I can think of doing about it..
- currentModifiers &= ~(ModifierKeys::leftButtonModifier | ModifierKeys::rightButtonModifier | ModifierKeys::middleButtonModifier);
-
- if (button == kEventMouseButtonPrimary)
- currentModifiers |= ModifierKeys::leftButtonModifier;
- else if (button == kEventMouseButtonSecondary)
- currentModifiers |= ModifierKeys::rightButtonModifier;
- else if (button == kEventMouseButtonTertiary)
- currentModifiers |= ModifierKeys::middleButtonModifier;
-
- updateModifiers (theEvent);
-
- juce_currentMouseTrackingPeer = this; // puts the message dispatcher into mouse-tracking mode..
- handleMouseDown (x, y, time);
- break;
- }
-
- case kEventMouseUp:
- {
- const int oldModifiers = currentModifiers;
-
- EventMouseButton button;
- GetEventParameter (theEvent, kEventParamMouseButton, typeMouseButton, 0, sizeof (EventMouseButton), 0, &button);
-
- if (button == kEventMouseButtonPrimary)
- currentModifiers &= ~ModifierKeys::leftButtonModifier;
- else if (button == kEventMouseButtonSecondary)
- currentModifiers &= ~ModifierKeys::rightButtonModifier;
-
- updateModifiers (theEvent);
-
- juce_currentMouseTrackingPeer = 0;
- handleMouseUp (oldModifiers, x, y, time);
- break;
- }
-
- case kEventMouseWheelMoved:
- {
- EventMouseWheelAxis axis;
- GetEventParameter (theEvent, kEventParamMouseWheelAxis, typeMouseWheelAxis, 0, sizeof (axis), 0, &axis);
-
- SInt32 delta;
- GetEventParameter (theEvent, kEventParamMouseWheelDelta,
- typeLongInteger, 0, sizeof (delta), 0, &delta);
-
- updateModifiers (theEvent);
-
- handleMouseWheel (axis == kEventMouseWheelAxisX ? delta * 10 : 0,
- axis == kEventMouseWheelAxisX ? 0 : delta * 10,
- time);
-
- break;
- }
- }
-
- return noErr;
- }
-
- void doDragDropEnter (EventRef theEvent)
- {
- updateDragAndDropFileList (theEvent);
-
- if (dragAndDropFiles.size() > 0)
- {
- int x, y;
- component->getMouseXYRelative (x, y);
- handleFileDragMove (dragAndDropFiles, x, y);
- }
- }
-
- void doDragDropMove (EventRef theEvent)
- {
- if (dragAndDropFiles.size() > 0)
- {
- int x, y;
- component->getMouseXYRelative (x, y);
- handleFileDragMove (dragAndDropFiles, x, y);
- }
- }
-
- void doDragDropExit (EventRef theEvent)
- {
- if (dragAndDropFiles.size() > 0)
- handleFileDragExit (dragAndDropFiles);
- }
-
- void doDragDrop (EventRef theEvent)
- {
- updateDragAndDropFileList (theEvent);
-
- if (dragAndDropFiles.size() > 0)
- {
- int x, y;
- component->getMouseXYRelative (x, y);
- handleFileDragDrop (dragAndDropFiles, x, y);
- }
- }
-
- void updateDragAndDropFileList (EventRef theEvent)
- {
- dragAndDropFiles.clear();
-
- DragRef dragRef;
- if (GetEventParameter (theEvent, kEventParamDragRef, typeDragRef, 0, sizeof (dragRef), 0, &dragRef) == noErr)
- {
- UInt16 numItems = 0;
- if (CountDragItems (dragRef, &numItems) == noErr)
- {
- for (int i = 0; i < (int) numItems; ++i)
- {
- DragItemRef ref;
-
- if (GetDragItemReferenceNumber (dragRef, i + 1, &ref) == noErr)
- {
- const FlavorType flavorType = kDragFlavorTypeHFS;
-
- Size size = 0;
- if (GetFlavorDataSize (dragRef, ref, flavorType, &size) == noErr)
- {
- void* data = juce_calloc (size);
-
- if (GetFlavorData (dragRef, ref, flavorType, data, &size, 0) == noErr)
- {
- HFSFlavor* f = (HFSFlavor*) data;
- FSRef fsref;
-
- if (FSpMakeFSRef (&f->fileSpec, &fsref) == noErr)
- {
- const String path (PlatformUtilities::makePathFromFSRef (&fsref));
-
- if (path.isNotEmpty())
- dragAndDropFiles.add (path);
- }
- }
-
- juce_free (data);
- }
- }
- }
-
- dragAndDropFiles.trim();
- dragAndDropFiles.removeEmptyStrings();
- }
- }
- }
-
- void resizeViewToFitWindow()
- {
- HIRect r;
-
- if (isSharedWindow)
- {
- HIViewGetFrame (viewRef, &r);
- r.size.width = (float) component->getWidth();
- r.size.height = (float) component->getHeight();
- }
- else
- {
- r.origin.x = 0;
- r.origin.y = 0;
-
- Rect w;
- GetWindowBounds (windowRef, windowRegionToUse, &w);
-
- r.size.width = (float) (w.right - w.left);
- r.size.height = (float) (w.bottom - w.top);
- }
-
- HIViewSetFrame (viewRef, &r);
-
- #if MACOS_10_3_OR_EARLIER
- component->repaint();
- #endif
- }
-
- OSStatus hiViewDraw (EventRef theEvent)
- {
- CGContextRef context = 0;
- GetEventParameter (theEvent, kEventParamCGContextRef, typeCGContextRef, 0, sizeof (CGContextRef), 0, &context);
-
- CGrafPtr oldPort;
- CGrafPtr port = 0;
-
- if (context == 0)
- {
- GetEventParameter (theEvent, kEventParamGrafPort, typeGrafPtr, 0, sizeof (CGrafPtr), 0, &port);
-
- GetPort (&oldPort);
- SetPort (port);
-
- if (port != 0)
- QDBeginCGContext (port, &context);
-
- if (! isCompositingWindow)
- {
- Rect bounds;
- GetWindowBounds (windowRef, windowRegionToUse, &bounds);
- CGContextTranslateCTM (context, 0, bounds.bottom - bounds.top);
- CGContextScaleCTM (context, 1.0, -1.0);
- }
-
- if (isSharedWindow)
- {
- // NB - Had terrible problems trying to correctly get the position
- // of this view relative to the window, and this seems wrong, but
- // works better than any other method I've tried..
- HIRect hiViewPos;
- HIViewGetFrame (viewRef, &hiViewPos);
- CGContextTranslateCTM (context, hiViewPos.origin.x, hiViewPos.origin.y);
- }
- }
-
- #if MACOS_10_2_OR_EARLIER
- RgnHandle rgn = 0;
- GetEventParameter (theEvent, kEventParamRgnHandle, typeQDRgnHandle, 0, sizeof (RgnHandle), 0, &rgn);
-
- CGRect clip;
-
- // (avoid doing this in plugins because of some strange redraw bugs..)
- if (rgn != 0 && JUCEApplication::getInstance() != 0)
- {
- Rect bounds;
- GetRegionBounds (rgn, &bounds);
- clip.origin.x = bounds.left;
- clip.origin.y = bounds.top;
- clip.size.width = bounds.right - bounds.left;
- clip.size.height = bounds.bottom - bounds.top;
- }
- else
- {
- HIViewGetBounds (viewRef, &clip);
- clip.origin.x = 0;
- clip.origin.y = 0;
- }
- #else
- CGRect clip (CGContextGetClipBoundingBox (context));
- #endif
-
- clip = CGRectIntegral (clip);
-
- if (clip.origin.x < 0)
- {
- clip.size.width += clip.origin.x;
- clip.origin.x = 0;
- }
-
- if (clip.origin.y < 0)
- {
- clip.size.height += clip.origin.y;
- clip.origin.y = 0;
- }
-
- if (! component->isOpaque())
- CGContextClearRect (context, clip);
-
- repainter->paint (context,
- (int) clip.origin.x, (int) clip.origin.y,
- (int) clip.size.width, (int) clip.size.height);
-
- if (port != 0)
- {
- CGContextFlush (context);
- QDEndCGContext (port, &context);
-
- SetPort (oldPort);
- }
-
- repainter->repaintAnyRemainingRegions();
-
- return noErr;
- }
-
- OSStatus handleWindowClassEvent (EventRef theEvent)
- {
- switch (GetEventKind (theEvent))
- {
- case kEventWindowBoundsChanged:
- resizeViewToFitWindow();
- break; // allow other handlers in the event chain to also get a look at the events
-
- case kEventWindowBoundsChanging:
- if ((styleFlags & (windowIsResizable | windowHasTitleBar)) == (windowIsResizable | windowHasTitleBar))
- {
- UInt32 atts = 0;
- GetEventParameter (theEvent, kEventParamAttributes, typeUInt32,
- 0, sizeof (UInt32), 0, &atts);
-
- if ((atts & (kWindowBoundsChangeUserDrag | kWindowBoundsChangeUserResize)) != 0)
- {
- if (component->isCurrentlyBlockedByAnotherModalComponent())
- {
- Component* const modal = Component::getCurrentlyModalComponent();
- if (modal != 0)
- {
- static uint32 lastDragTime = 0;
- const uint32 now = Time::currentTimeMillis();
-
- if (now > lastDragTime + 1000)
- {
- lastDragTime = now;
- modal->inputAttemptWhenModal();
- }
-
- const Rectangle currentRect (getComponent()->getBounds());
- Rect current;
- current.left = currentRect.getX();
- current.top = currentRect.getY();
- current.right = currentRect.getRight();
- current.bottom = currentRect.getBottom();
-
- // stop the window getting dragged..
- SetEventParameter (theEvent, kEventParamCurrentBounds, typeQDRectangle,
- sizeof (Rect), ¤t);
-
- return noErr;
- }
- }
-
- if ((atts & kWindowBoundsChangeUserResize) != 0
- && constrainer != 0 && ! isSharedWindow)
- {
- Rect current;
- GetEventParameter (theEvent, kEventParamCurrentBounds, typeQDRectangle,
- 0, sizeof (Rect), 0, ¤t);
-
- int x = current.left;
- int y = current.top;
- int w = current.right - current.left;
- int h = current.bottom - current.top;
-
- const Rectangle currentRect (getComponent()->getBounds());
-
- constrainer->checkBounds (x, y, w, h, currentRect,
- Desktop::getInstance().getAllMonitorDisplayAreas().getBounds(),
- y != currentRect.getY() && y + h == currentRect.getBottom(),
- x != currentRect.getX() && x + w == currentRect.getRight(),
- y == currentRect.getY() && y + h != currentRect.getBottom(),
- x == currentRect.getX() && x + w != currentRect.getRight());
-
- current.left = x;
- current.top = y;
- current.right = x + w;
- current.bottom = y + h;
-
- SetEventParameter (theEvent, kEventParamCurrentBounds, typeQDRectangle,
- sizeof (Rect), ¤t);
-
- return noErr;
- }
- }
- }
- break;
-
- case kEventWindowFocusAcquired:
- keysCurrentlyDown.clear();
-
- if ((! isSharedWindow) || HIViewSubtreeContainsFocus (viewRef))
- viewFocusGain();
-
- break; // allow other handlers in the event chain to also get a look at the events
-
- case kEventWindowFocusRelinquish:
- keysCurrentlyDown.clear();
- viewFocusLoss();
-
- break; // allow other handlers in the event chain to also get a look at the events
-
- case kEventWindowCollapsed:
- minimisedWindows.addIfNotAlreadyThere (windowRef);
- handleMovedOrResized();
- break; // allow other handlers in the event chain to also get a look at the events
-
- case kEventWindowExpanded:
- minimisedWindows.removeValue (windowRef);
- handleMovedOrResized();
- break; // allow other handlers in the event chain to also get a look at the events
-
- case kEventWindowShown:
- break; // allow other handlers in the event chain to also get a look at the events
-
- case kEventWindowClose:
- if (isSharedWindow)
- break; // break to let the OS delete the window
-
- handleUserClosingWindow();
- return noErr; // avoids letting the OS to delete the window, we'll do that ourselves.
-
- default:
- break;
- }
-
- return eventNotHandledErr;
- }
-
- OSStatus handleWindowEventForPeer (EventHandlerCallRef callRef, EventRef theEvent)
- {
- switch (GetEventClass (theEvent))
- {
- case kEventClassMouse:
- {
- static HIViewComponentPeer* lastMouseDownPeer = 0;
-
- const UInt32 eventKind = GetEventKind (theEvent);
- HIViewRef view = 0;
-
- if (eventKind == kEventMouseDragged)
- {
- view = viewRef;
- }
- else
- {
- HIViewGetViewForMouseEvent (HIViewGetRoot (windowRef), theEvent, &view);
-
- if (view != viewRef)
- {
- if ((eventKind == kEventMouseUp
- || eventKind == kEventMouseExited)
- && ComponentPeer::isValidPeer (lastMouseDownPeer))
- {
- return lastMouseDownPeer->handleMouseEvent (callRef, theEvent);
- }
-
- return eventNotHandledErr;
- }
- }
-
- if (eventKind == kEventMouseDown
- || eventKind == kEventMouseDragged
- || eventKind == kEventMouseEntered)
- {
- lastMouseDownPeer = this;
- }
-
- return handleMouseEvent (callRef, theEvent);
- }
- break;
-
- case kEventClassWindow:
- return handleWindowClassEvent (theEvent);
-
- case kEventClassKeyboard:
- if (isFocused())
- return handleKeyEvent (theEvent, 0);
-
- break;
-
- case kEventClassTextInput:
- if (isFocused())
- return handleTextInputEvent (theEvent);
-
- break;
-
- default:
- break;
- }
-
- return eventNotHandledErr;
- }
-
- static pascal OSStatus handleWindowEvent (EventHandlerCallRef callRef, EventRef theEvent, void* userData)
- {
- MessageManager::delayWaitCursor();
-
- HIViewComponentPeer* const peer = (HIViewComponentPeer*) userData;
-
- const MessageManagerLock messLock;
-
- if (ComponentPeer::isValidPeer (peer))
- return peer->handleWindowEventForPeer (callRef, theEvent);
-
- return eventNotHandledErr;
- }
-
- static pascal OSStatus hiViewEventHandler (EventHandlerCallRef myHandler, EventRef theEvent, void* userData)
- {
- MessageManager::delayWaitCursor();
-
- const UInt32 eventKind = GetEventKind (theEvent);
- const UInt32 eventClass = GetEventClass (theEvent);
-
- if (eventClass == kEventClassHIObject)
- {
- switch (eventKind)
- {
- case kEventHIObjectConstruct:
- {
- void* data = juce_calloc (sizeof (void*));
- SetEventParameter (theEvent, kEventParamHIObjectInstance,
- typeVoidPtr, sizeof (void*), &data);
-
- return noErr;
- }
-
- case kEventHIObjectInitialize:
- GetEventParameter (theEvent, 'peer', typeVoidPtr, 0, sizeof (void*), 0, (void**) userData);
- return noErr;
-
- case kEventHIObjectDestruct:
- juce_free (userData);
- return noErr;
-
- default:
- break;
- }
- }
- else if (eventClass == kEventClassControl)
- {
- HIViewComponentPeer* const peer = *(HIViewComponentPeer**) userData;
- const MessageManagerLock messLock;
-
- if (! ComponentPeer::isValidPeer (peer))
- return eventNotHandledErr;
-
- switch (eventKind)
- {
- case kEventControlDraw:
- return peer->hiViewDraw (theEvent);
-
- case kEventControlBoundsChanged:
- {
- HIRect bounds;
- HIViewGetBounds (peer->viewRef, &bounds);
- peer->repaint (0, 0, roundFloatToInt (bounds.size.width), roundFloatToInt (bounds.size.height));
-
- peer->handleMovedOrResized();
- return noErr;
- }
-
- case kEventControlHitTest:
- {
- HIPoint where;
- GetEventParameter (theEvent, kEventParamMouseLocation, typeHIPoint, 0, sizeof (HIPoint), 0, &where);
-
- HIRect bounds;
- HIViewGetBounds (peer->viewRef, &bounds);
-
- ControlPartCode part = kControlNoPart;
-
- if (CGRectContainsPoint (bounds, where))
- part = 1;
-
- SetEventParameter (theEvent, kEventParamControlPart, typeControlPartCode, sizeof (ControlPartCode), &part);
- return noErr;
- }
- break;
-
- case kEventControlSetFocusPart:
- {
- ControlPartCode desiredFocus;
- if (GetEventParameter (theEvent, kEventParamControlPart, typeControlPartCode, 0, sizeof (ControlPartCode), 0, &desiredFocus) != noErr)
- break;
-
- if (desiredFocus == kControlNoPart)
- peer->viewFocusLoss();
- else
- peer->viewFocusGain();
-
- return noErr;
- }
- break;
-
- case kEventControlDragEnter:
- {
- #if MACOS_10_2_OR_EARLIER
- enum { kEventParamControlWouldAcceptDrop = 'cldg' };
- #endif
- Boolean accept = true;
- SetEventParameter (theEvent, kEventParamControlWouldAcceptDrop, typeBoolean, sizeof (accept), &accept);
-
- peer->doDragDropEnter (theEvent);
- return noErr;
- }
-
- case kEventControlDragWithin:
- peer->doDragDropMove (theEvent);
- return noErr;
-
- case kEventControlDragLeave:
- peer->doDragDropExit (theEvent);
- return noErr;
-
- case kEventControlDragReceive:
- peer->doDragDrop (theEvent);
- return noErr;
-
- case kEventControlOwningWindowChanged:
- return peer->ownerWindowChanged (theEvent);
-
- #if ! MACOS_10_2_OR_EARLIER
- case kEventControlGetFrameMetrics:
- {
- CallNextEventHandler (myHandler, theEvent);
- HIViewFrameMetrics metrics;
- GetEventParameter (theEvent, kEventParamControlFrameMetrics, typeControlFrameMetrics, 0, sizeof (metrics), 0, &metrics);
- metrics.top = metrics.bottom = 0;
- SetEventParameter (theEvent, kEventParamControlFrameMetrics, typeControlFrameMetrics, sizeof (metrics), &metrics);
- return noErr;
- }
- #endif
-
- case kEventControlInitialize:
- {
- UInt32 features = kControlSupportsDragAndDrop
- | kControlSupportsFocus
- | kControlHandlesTracking
- | kControlSupportsEmbedding
- | (1 << 8) /*kHIViewFeatureGetsFocusOnClick*/;
-
- SetEventParameter (theEvent, kEventParamControlFeatures, typeUInt32, sizeof (UInt32), &features);
- return noErr;
- }
-
- default:
- break;
- }
- }
-
- return eventNotHandledErr;
- }
-
- WindowRef createNewWindow (const int windowStyleFlags)
- {
- jassert (windowRef == 0);
-
- static ToolboxObjectClassRef customWindowClass = 0;
-
- if (customWindowClass == 0)
- {
- // Register our window class
- const EventTypeSpec customTypes[] = { { kEventClassWindow, kEventWindowDrawFrame } };
-
- UnsignedWide t;
- Microseconds (&t);
- const String randomString ((int) (t.lo & 0x7ffffff));
- const String juceWindowClassName (T("JUCEWindowClass_") + randomString);
- CFStringRef juceWindowClassNameCFString = PlatformUtilities::juceStringToCFString (juceWindowClassName);
-
- RegisterToolboxObjectClass (juceWindowClassNameCFString,
- 0, 1, customTypes,
- NewEventHandlerUPP (handleFrameRepaintEvent),
- 0, &customWindowClass);
-
- CFRelease (juceWindowClassNameCFString);
- }
-
- Rect pos;
- pos.left = getComponent()->getX();
- pos.top = getComponent()->getY();
- pos.right = getComponent()->getRight();
- pos.bottom = getComponent()->getBottom();
-
- int attributes = kWindowStandardHandlerAttribute | kWindowCompositingAttribute;
- if ((windowStyleFlags & windowHasDropShadow) == 0)
- attributes |= kWindowNoShadowAttribute;
-
- if ((windowStyleFlags & windowIgnoresMouseClicks) != 0)
- attributes |= kWindowIgnoreClicksAttribute;
-
- #if ! MACOS_10_3_OR_EARLIER
- if ((windowStyleFlags & windowIsTemporary) != 0)
- attributes |= kWindowDoesNotCycleAttribute;
- #endif
-
- WindowRef newWindow = 0;
-
- if ((windowStyleFlags & windowHasTitleBar) == 0)
- {
- attributes |= kWindowCollapseBoxAttribute;
-
- WindowDefSpec customWindowSpec;
- customWindowSpec.defType = kWindowDefObjectClass;
- customWindowSpec.u.classRef = customWindowClass;
-
- CreateCustomWindow (&customWindowSpec,
- ((windowStyleFlags & windowIsTemporary) != 0) ? kUtilityWindowClass :
- (getComponent()->isAlwaysOnTop() ? kUtilityWindowClass
- : kDocumentWindowClass),
- attributes,
- &pos,
- &newWindow);
- }
- else
- {
- if ((windowStyleFlags & windowHasCloseButton) != 0)
- attributes |= kWindowCloseBoxAttribute;
-
- if ((windowStyleFlags & windowHasMinimiseButton) != 0)
- attributes |= kWindowCollapseBoxAttribute;
-
- if ((windowStyleFlags & windowHasMaximiseButton) != 0)
- attributes |= kWindowFullZoomAttribute;
-
- if ((windowStyleFlags & windowIsResizable) != 0)
- attributes |= kWindowResizableAttribute | kWindowLiveResizeAttribute;
-
- CreateNewWindow (kDocumentWindowClass, attributes, &pos, &newWindow);
- }
-
- jassert (newWindow != 0);
- if (newWindow != 0)
- {
- HideWindow (newWindow);
-
- SetAutomaticControlDragTrackingEnabledForWindow (newWindow, true);
-
- if (! getComponent()->isOpaque())
- SetWindowAlpha (newWindow, 0.9999999f); // to fool it into giving the window an alpha-channel
- }
-
- return newWindow;
- }
-
- OSStatus ownerWindowChanged (EventRef theEvent)
- {
- WindowRef newWindow = 0;
- GetEventParameter (theEvent, kEventParamControlCurrentOwningWindow, typeWindowRef, 0, sizeof (newWindow), 0, &newWindow);
-
- if (windowRef != newWindow)
- {
- if (eventHandlerRef != 0)
- {
- RemoveEventHandler (eventHandlerRef);
- eventHandlerRef = 0;
- }
-
- windowRef = newWindow;
-
- if (windowRef != 0)
- {
- const EventTypeSpec eventTypes[] =
- {
- { kEventClassWindow, kEventWindowBoundsChanged },
- { kEventClassWindow, kEventWindowBoundsChanging },
- { kEventClassWindow, kEventWindowFocusAcquired },
- { kEventClassWindow, kEventWindowFocusRelinquish },
- { kEventClassWindow, kEventWindowCollapsed },
- { kEventClassWindow, kEventWindowExpanded },
- { kEventClassWindow, kEventWindowShown },
- { kEventClassWindow, kEventWindowClose },
- { kEventClassMouse, kEventMouseDown },
- { kEventClassMouse, kEventMouseUp },
- { kEventClassMouse, kEventMouseMoved },
- { kEventClassMouse, kEventMouseDragged },
- { kEventClassMouse, kEventMouseEntered },
- { kEventClassMouse, kEventMouseExited },
- { kEventClassMouse, kEventMouseWheelMoved },
- { kEventClassKeyboard, kEventRawKeyUp },
- { kEventClassKeyboard, kEventRawKeyRepeat },
- { kEventClassKeyboard, kEventRawKeyModifiersChanged },
- { kEventClassTextInput, kEventTextInputUnicodeForKeyEvent }
- };
-
- static EventHandlerUPP handleWindowEventUPP = 0;
-
- if (handleWindowEventUPP == 0)
- handleWindowEventUPP = NewEventHandlerUPP (handleWindowEvent);
-
- InstallWindowEventHandler (windowRef, handleWindowEventUPP,
- GetEventTypeCount (eventTypes), eventTypes,
- (void*) this, (EventHandlerRef*) &eventHandlerRef);
-
- WindowAttributes attributes;
- GetWindowAttributes (windowRef, &attributes);
-
- #if MACOS_10_3_OR_EARLIER
- isCompositingWindow = ((attributes & kWindowCompositingAttribute) != 0);
- #else
- isCompositingWindow = HIViewIsCompositingEnabled (viewRef);
- #endif
-
- SetAutomaticControlDragTrackingEnabledForWindow (newWindow, true);
-
- MouseCheckTimer::getInstance()->resetMouseMoveChecker();
- }
- }
-
- resizeViewToFitWindow();
- return noErr;
- }
-
- void createNewHIView()
- {
- jassert (viewRef == 0);
-
- if (viewClassRef == 0)
- {
- // Register our HIView class
- EventTypeSpec viewEvents[] =
- {
- { kEventClassHIObject, kEventHIObjectConstruct },
- { kEventClassHIObject, kEventHIObjectInitialize },
- { kEventClassHIObject, kEventHIObjectDestruct },
- { kEventClassControl, kEventControlInitialize },
- { kEventClassControl, kEventControlDraw },
- { kEventClassControl, kEventControlBoundsChanged },
- { kEventClassControl, kEventControlSetFocusPart },
- { kEventClassControl, kEventControlHitTest },
- { kEventClassControl, kEventControlDragEnter },
- { kEventClassControl, kEventControlDragLeave },
- { kEventClassControl, kEventControlDragWithin },
- { kEventClassControl, kEventControlDragReceive },
- { kEventClassControl, kEventControlOwningWindowChanged }
- };
-
- UnsignedWide t;
- Microseconds (&t);
- const String randomString ((int) (t.lo & 0x7ffffff));
- const String juceHiViewClassName (T("JUCEHIViewClass_") + randomString);
- juceHiViewClassNameCFString = PlatformUtilities::juceStringToCFString (juceHiViewClassName);
-
- HIObjectRegisterSubclass (juceHiViewClassNameCFString,
- kHIViewClassID, 0,
- NewEventHandlerUPP (hiViewEventHandler),
- GetEventTypeCount (viewEvents),
- viewEvents, 0,
- &viewClassRef);
- }
-
- EventRef event;
- CreateEvent (0, kEventClassHIObject, kEventHIObjectInitialize, GetCurrentEventTime(), kEventAttributeNone, &event);
-
- void* thisPointer = this;
- SetEventParameter (event, 'peer', typeVoidPtr, sizeof (void*), &thisPointer);
-
- HIObjectCreate (juceHiViewClassNameCFString, event, (HIObjectRef*) &viewRef);
-
- SetControlDragTrackingEnabled (viewRef, true);
-
- if (isSharedWindow)
- {
- setBounds (component->getX(), component->getY(),
- component->getWidth(), component->getHeight(), false);
- }
- }
- };
-
- bool juce_isHIViewCreatedByJuce (HIViewRef view)
- {
- return juceHiViewClassNameCFString != 0
- && HIObjectIsOfClass ((HIObjectRef) view, juceHiViewClassNameCFString);
- }
-
- bool juce_isWindowCreatedByJuce (WindowRef window)
- {
- for (int i = ComponentPeer::getNumPeers(); --i >= 0;)
- if (ComponentPeer::getPeer(i)->getNativeHandle() == window)
- return true;
-
- return false;
- }
-
- static void trackNextMouseEvent()
- {
- UInt32 mods;
- MouseTrackingResult result;
- ::Point where;
-
- if (TrackMouseLocationWithOptions ((GrafPtr) -1, 0, 0.01, //kEventDurationForever,
- &where, &mods, &result) != noErr
- || ! ComponentPeer::isValidPeer (juce_currentMouseTrackingPeer))
- {
- juce_currentMouseTrackingPeer = 0;
- return;
- }
-
- if (result == kMouseTrackingTimedOut)
- return;
-
- #if MACOS_10_3_OR_EARLIER
- const int x = where.h - juce_currentMouseTrackingPeer->getScreenX();
- const int y = where.v - juce_currentMouseTrackingPeer->getScreenY();
- #else
- HIPoint p;
- p.x = where.h;
- p.y = where.v;
- HIPointConvert (&p, kHICoordSpaceScreenPixel, 0,
- kHICoordSpaceView, ((HIViewComponentPeer*) juce_currentMouseTrackingPeer)->viewRef);
- const int x = p.x;
- const int y = p.y;
- #endif
-
- if (result == kMouseTrackingMouseDragged)
- {
- updateModifiers (0);
- juce_currentMouseTrackingPeer->handleMouseDrag (x, y, getEventTime (0));
-
- if (! ComponentPeer::isValidPeer (juce_currentMouseTrackingPeer))
- {
- juce_currentMouseTrackingPeer = 0;
- return;
- }
- }
- else if (result == kMouseTrackingMouseUp
- || result == kMouseTrackingUserCancelled
- || result == kMouseTrackingMouseMoved)
- {
- ComponentPeer* const oldPeer = juce_currentMouseTrackingPeer;
- juce_currentMouseTrackingPeer = 0;
-
- if (ComponentPeer::isValidPeer (oldPeer))
- {
- const int oldModifiers = currentModifiers;
- currentModifiers &= ~(ModifierKeys::leftButtonModifier | ModifierKeys::rightButtonModifier | ModifierKeys::middleButtonModifier);
- updateModifiers (0);
-
- oldPeer->handleMouseUp (oldModifiers, x, y, getEventTime (0));
- }
- }
- }
-
- bool juce_dispatchNextMessageOnSystemQueue (bool returnIfNoPendingMessages)
- {
- if (juce_currentMouseTrackingPeer != 0)
- trackNextMouseEvent();
-
- /* [[NSRunLoop mainRunLoop] acceptInputForMode: NSDefaultRunLoopMode
- beforeDate: returnIfNoPendingMessages
- ? [[NSDate date] addTimeInterval: 0.01]
- : [NSDate distantFuture]];
- */
- EventRef theEvent;
-
- if (ReceiveNextEvent (0, 0, (returnIfNoPendingMessages) ? kEventDurationNoWait
- : kEventDurationForever,
- true, &theEvent) == noErr)
- {
- if (GetEventClass (theEvent) == kEventClassAppleEvent)
- {
- EventRecord eventRec;
- if (ConvertEventRefToEventRecord (theEvent, &eventRec))
- AEProcessAppleEvent (&eventRec);
- }
- else
- {
- EventTargetRef theTarget = GetEventDispatcherTarget();
- SendEventToEventTarget (theEvent, theTarget);
- }
-
- ReleaseEvent (theEvent);
- return true;
- }
-
- return false;
- }
-
- ComponentPeer* Component::createNewPeer (int styleFlags, void* windowToAttachTo)
- {
- return new HIViewComponentPeer (this, styleFlags, (HIViewRef) windowToAttachTo);
- }
-
- void MouseCheckTimer::timerCallback()
- {
- if (ModifierKeys::getCurrentModifiersRealtime().isAnyMouseButtonDown())
- return;
-
- if (Process::isForegroundProcess())
- {
- bool stillOver = false;
- int x = 0, y = 0, w = 0, h = 0;
- int mx = 0, my = 0;
- const bool validWindow = ComponentPeer::isValidPeer (lastPeerUnderMouse);
-
- if (validWindow)
- {
- lastPeerUnderMouse->getBounds (x, y, w, h, true);
- Desktop::getMousePosition (mx, my);
-
- stillOver = (mx >= x && my >= y && mx < x + w && my < y + h);
-
- if (stillOver)
- {
- // check if it's over an embedded HIView
- int rx = mx, ry = my;
- lastPeerUnderMouse->globalPositionToRelative (rx, ry);
- HIPoint hipoint;
- hipoint.x = rx;
- hipoint.y = ry;
-
- HIViewRef root;
- GetRootControl ((WindowRef) lastPeerUnderMouse->getNativeHandle(), &root);
-
- HIViewRef hitview;
- if (HIViewGetSubviewHit (root, &hipoint, true, &hitview) == noErr && hitview != 0)
- {
- stillOver = HIObjectIsOfClass ((HIObjectRef) hitview, juceHiViewClassNameCFString);
- }
- }
- }
-
- if (! stillOver)
- {
- // mouse is outside our windows so set a normal cursor (only
- // if we're running as an app, not a plugin)
- if (JUCEApplication::getInstance() != 0)
- SetThemeCursor (kThemeArrowCursor);
-
- if (validWindow)
- lastPeerUnderMouse->handleMouseExit (mx - x, my - y, Time::currentTimeMillis());
-
- if (hasEverHadAMouseMove)
- stopTimer();
- }
-
- if ((! hasEverHadAMouseMove) && validWindow
- && (mx != lastX || my != lastY))
- {
- lastX = mx;
- lastY = my;
-
- if (stillOver)
- lastPeerUnderMouse->handleMouseMove (mx - x, my - y, Time::currentTimeMillis());
- }
- }
- }
-
- // called from juce_Messaging.cpp
- void juce_HandleProcessFocusChange()
- {
- keysCurrentlyDown.clear();
-
- if (HIViewComponentPeer::isValidPeer (currentlyFocusedPeer))
- {
- if (Process::isForegroundProcess())
- currentlyFocusedPeer->handleFocusGain();
- else
- currentlyFocusedPeer->handleFocusLoss();
- }
- }
-
- static bool performDrag (DragRef drag)
- {
- EventRecord event;
- event.what = mouseDown;
- event.message = 0;
- event.when = TickCount();
-
- int x, y;
- Desktop::getMousePosition (x, y);
- event.where.h = x;
- event.where.v = y;
-
- event.modifiers = GetCurrentKeyModifiers();
-
- RgnHandle rgn = NewRgn();
- RgnHandle rgn2 = NewRgn();
- SetRectRgn (rgn,
- event.where.h - 8, event.where.v - 8,
- event.where.h + 8, event.where.v + 8);
- CopyRgn (rgn, rgn2);
- InsetRgn (rgn2, 1, 1);
- DiffRgn (rgn, rgn2, rgn);
- DisposeRgn (rgn2);
-
- bool result = TrackDrag (drag, &event, rgn) == noErr;
-
- DisposeRgn (rgn);
- return result;
- }
-
- bool DragAndDropContainer::performExternalDragDropOfFiles (const StringArray& files, const bool canMoveFiles)
- {
- for (int i = ComponentPeer::getNumPeers(); --i >= 0;)
- ComponentPeer::getPeer (i)->performAnyPendingRepaintsNow();
-
- DragRef drag;
- bool result = false;
-
- if (NewDrag (&drag) == noErr)
- {
- for (int i = 0; i < files.size(); ++i)
- {
- HFSFlavor hfsData;
-
- if (PlatformUtilities::makeFSSpecFromPath (&hfsData.fileSpec, files[i]))
- {
- FInfo info;
- if (FSpGetFInfo (&hfsData.fileSpec, &info) == noErr)
- {
- hfsData.fileType = info.fdType;
- hfsData.fileCreator = info.fdCreator;
- hfsData.fdFlags = info.fdFlags;
-
- AddDragItemFlavor (drag, i + 1, kDragFlavorTypeHFS, &hfsData, sizeof (hfsData), 0);
- result = true;
- }
- }
- }
-
- SetDragAllowableActions (drag, canMoveFiles ? kDragActionAll
- : kDragActionCopy, false);
-
- if (result)
- result = performDrag (drag);
-
- DisposeDrag (drag);
- }
-
- return result;
- }
-
- bool DragAndDropContainer::performExternalDragDropOfText (const String& text)
- {
- jassertfalse // not implemented!
- return false;
- }
-
- bool Process::isForegroundProcess() throw()
- {
- ProcessSerialNumber psn, front;
- GetCurrentProcess (&psn);
- GetFrontProcess (&front);
-
- Boolean b;
- return (SameProcess (&psn, &front, &b) == noErr) && b;
- }
-
- bool Desktop::canUseSemiTransparentWindows() throw()
- {
- return true;
- }
-
- void Desktop::getMousePosition (int& x, int& y) throw()
- {
- CGrafPtr currentPort;
- GetPort (¤tPort);
-
- if (! IsValidPort (currentPort))
- {
- WindowRef front = FrontWindow();
-
- if (front != 0)
- {
- SetPortWindowPort (front);
- }
- else
- {
- x = y = 0;
- return;
- }
- }
-
- ::Point p;
- GetMouse (&p);
- LocalToGlobal (&p);
- x = p.h;
- y = p.v;
-
- SetPort (currentPort);
- }
-
- void Desktop::setMousePosition (int x, int y) throw()
- {
- // this rubbish needs to be done around the warp call, to avoid causing a
- // bizarre glitch..
- CGAssociateMouseAndMouseCursorPosition (false);
- CGSetLocalEventsSuppressionInterval (0);
-
- CGPoint pos = { x, y };
- CGWarpMouseCursorPosition (pos);
-
- CGAssociateMouseAndMouseCursorPosition (true);
- }
-
- const ModifierKeys ModifierKeys::getCurrentModifiersRealtime() throw()
- {
- return ModifierKeys (currentModifiers);
- }
-
- class ScreenSaverDefeater : public Timer,
- public DeletedAtShutdown
- {
- public:
- ScreenSaverDefeater() throw()
- {
- startTimer (10000);
- timerCallback();
- }
-
- ~ScreenSaverDefeater()
- {
- }
-
- void timerCallback()
- {
- if (Process::isForegroundProcess())
- UpdateSystemActivity (UsrActivity);
- }
- };
-
- static ScreenSaverDefeater* screenSaverDefeater = 0;
-
- void Desktop::setScreenSaverEnabled (const bool isEnabled) throw()
- {
- if (screenSaverDefeater == 0)
- screenSaverDefeater = new ScreenSaverDefeater();
- }
-
- bool Desktop::isScreenSaverEnabled() throw()
- {
- return screenSaverDefeater == 0;
- }
-
- void juce_updateMultiMonitorInfo (Array <Rectangle>& monitorCoords, const bool clipToWorkArea) throw()
- {
- int mainMonitorIndex = 0;
- CGDirectDisplayID mainDisplayID = CGMainDisplayID();
-
- CGDisplayCount count = 0;
- CGDirectDisplayID disps [8];
-
- if (CGGetOnlineDisplayList (numElementsInArray (disps), disps, &count) == noErr)
- {
- for (int i = 0; i < count; ++i)
- {
- if (mainDisplayID == disps[i])
- mainMonitorIndex = monitorCoords.size();
-
- GDHandle hGDevice;
-
- if (clipToWorkArea
- && DMGetGDeviceByDisplayID ((DisplayIDType) disps[i], &hGDevice, false) == noErr)
- {
- Rect rect;
- GetAvailableWindowPositioningBounds (hGDevice, &rect);
-
- monitorCoords.add (Rectangle (rect.left,
- rect.top,
- rect.right - rect.left,
- rect.bottom - rect.top));
- }
- else
- {
- const CGRect r (CGDisplayBounds (disps[i]));
-
- monitorCoords.add (Rectangle ((int) r.origin.x,
- (int) r.origin.y,
- (int) r.size.width,
- (int) r.size.height));
- }
- }
- }
-
- // make sure the first in the list is the main monitor
- if (mainMonitorIndex > 0)
- monitorCoords.swap (mainMonitorIndex, 0);
-
- jassert (monitorCoords.size() > 0);
-
- if (monitorCoords.size() == 0)
- monitorCoords.add (Rectangle (0, 0, 1024, 768));
- }
-
- static NSImage* juceImageToNSImage (const Image& image)
- {
- int lineStride, pixelStride;
- const uint8* pixels = image.lockPixelDataReadOnly (0, 0, image.getWidth(), image.getHeight(),
- lineStride, pixelStride);
-
- NSBitmapImageRep* rep = [[NSBitmapImageRep alloc]
- initWithBitmapDataPlanes: NULL
- pixelsWide: image.getWidth()
- pixelsHigh: image.getHeight()
- bitsPerSample: 8
- samplesPerPixel: image.hasAlphaChannel() ? 4 : 3
- hasAlpha: image.hasAlphaChannel()
- isPlanar: NO
- colorSpaceName: NSCalibratedRGBColorSpace
- bitmapFormat: (NSBitmapFormat) 0
- bytesPerRow: lineStride
- bitsPerPixel: pixelStride * 8];
-
- unsigned char* newData = [rep bitmapData];
- memcpy (newData, pixels, lineStride * image.getHeight());
- image.releasePixelDataReadOnly (pixels);
-
- NSImage* im = [[NSImage alloc] init];
- [im addRepresentation: rep];
- [rep release];
-
- return im;
- }
-
- void* juce_createMouseCursorFromImage (const Image& image, int hotspotX, int hotspotY) throw()
- {
- NSImage* im = juceImageToNSImage (image);
- [im autorelease];
-
- NSPoint hs;
- hs.x = (int) hotspotX;
- hs.y = (int) hotspotY;
-
- NSCursor* c = [[NSCursor alloc] initWithImage: im hotSpot: hs];
- return (void*) c;
- }
-
- static void* juce_cursorFromData (const unsigned char* data, const int size, float hx, float hy) throw()
- {
- Image* const im = ImageFileFormat::loadFrom ((const char*) data, size);
- jassert (im != 0);
-
- if (im == 0)
- return 0;
-
- void* const curs = juce_createMouseCursorFromImage (*im,
- (int) (hx * im->getWidth()),
- (int) (hy * im->getHeight()));
- delete im;
- return curs;
- }
-
- static void* juce_cursorFromWebKitFile (const char* filename, float hx, float hy)
- {
- File f ("/System/Library/Frameworks/WebKit.framework/Frameworks/WebCore.framework/Resources");
-
- MemoryBlock mb;
- if (f.getChildFile (filename).loadFileAsData (mb))
- return juce_cursorFromData ((const unsigned char*) mb.getData(), mb.getSize(), hx, hy);
-
- return 0;
- }
-
- void* juce_createStandardMouseCursor (MouseCursor::StandardCursorType type) throw()
- {
- NSCursor* c = 0;
-
- switch (type)
- {
- case MouseCursor::NormalCursor:
- c = [NSCursor arrowCursor];
- break;
-
- case MouseCursor::NoCursor:
- {
- Image blank (Image::ARGB, 8, 8, true);
- return juce_createMouseCursorFromImage (blank, 0, 0);
- }
-
- case MouseCursor::DraggingHandCursor:
- c = [NSCursor openHandCursor];
- break;
-
- case MouseCursor::CopyingCursor:
- return juce_cursorFromWebKitFile ("copyCursor.png", 0, 0);
-
- case MouseCursor::WaitCursor:
- c = [NSCursor arrowCursor]; // avoid this on the mac, let the OS provide the beachball
- break;
- //return juce_cursorFromWebKitFile ("waitCursor.png", 0.5f, 0.5f);
-
- case MouseCursor::IBeamCursor:
- c = [NSCursor IBeamCursor];
- break;
-
- case MouseCursor::PointingHandCursor:
- c = [NSCursor pointingHandCursor];
- break;
-
- case MouseCursor::LeftRightResizeCursor:
- c = [NSCursor resizeLeftRightCursor];
- break;
-
- case MouseCursor::LeftEdgeResizeCursor:
- c = [NSCursor resizeLeftCursor];
- break;
-
- case MouseCursor::RightEdgeResizeCursor:
- c = [NSCursor resizeRightCursor];
- break;
-
- case MouseCursor::UpDownResizeCursor:
- case MouseCursor::TopEdgeResizeCursor:
- case MouseCursor::BottomEdgeResizeCursor:
- return juce_cursorFromWebKitFile ("northSouthResizeCursor.png", 0.5f, 0.5f);
-
- case MouseCursor::TopLeftCornerResizeCursor:
- case MouseCursor::BottomRightCornerResizeCursor:
- return juce_cursorFromWebKitFile ("northWestSouthEastResizeCursor.png", 0.5f, 0.5f);
-
- case MouseCursor::TopRightCornerResizeCursor:
- case MouseCursor::BottomLeftCornerResizeCursor:
- return juce_cursorFromWebKitFile ("northEastSouthWestResizeCursor.png", 0.5f, 0.5f);
-
- case MouseCursor::UpDownLeftRightResizeCursor:
- return juce_cursorFromWebKitFile ("moveCursor.png", 0.5f, 0.5f);
-
- case MouseCursor::CrosshairCursor:
- c = [NSCursor crosshairCursor];
- break;
- }
-
- [c retain];
- return (void*) c;
- }
-
- void juce_deleteMouseCursor (void* const cursorHandle, const bool isStandard) throw()
- {
- NSCursor* c = (NSCursor*) cursorHandle;
- [c release];
- }
-
- void MouseCursor::showInAllWindows() const throw()
- {
- showInWindow (0);
- }
-
- void MouseCursor::showInWindow (ComponentPeer*) const throw()
- {
- NSCursor* const c = (NSCursor*) getHandle();
-
- if (c != 0)
- [c set];
- }
-
- Image* juce_createIconForFile (const File& file)
- {
- return 0;
- }
-
- class MainMenuHandler;
- static MainMenuHandler* mainMenu = 0;
-
- class MainMenuHandler : private MenuBarModelListener,
- private DeletedAtShutdown
- {
- public:
- MainMenuHandler() throw()
- : currentModel (0)
- {
- }
-
- ~MainMenuHandler() throw()
- {
- setMenu (0);
-
- jassert (mainMenu == this);
- mainMenu = 0;
- }
-
- void setMenu (MenuBarModel* const newMenuBarModel) throw()
- {
- if (currentModel != newMenuBarModel)
- {
- if (currentModel != 0)
- currentModel->removeListener (this);
-
- currentModel = newMenuBarModel;
-
- if (currentModel != 0)
- currentModel->addListener (this);
-
- menuBarItemsChanged (0);
- }
- }
-
- void menuBarItemsChanged (MenuBarModel*)
- {
- ClearMenuBar();
-
- if (currentModel != 0)
- {
- int menuId = 1000;
- const StringArray menuNames (currentModel->getMenuBarNames());
-
- for (int i = 0; i < menuNames.size(); ++i)
- {
- const PopupMenu menu (currentModel->getMenuForIndex (i, menuNames [i]));
-
- MenuRef m = createMenu (menu, menuNames [i], menuId, i);
-
- InsertMenu (m, 0);
- CFRelease (m);
- }
- }
- }
-
- void menuCommandInvoked (MenuBarModel*, const ApplicationCommandTarget::InvocationInfo& info)
- {
- MenuRef menu = 0;
- MenuItemIndex index = 0;
- GetIndMenuItemWithCommandID (0, info.commandID, 1, &menu, &index);
-
- if (menu != 0)
- {
- FlashMenuBar (GetMenuID (menu));
- FlashMenuBar (GetMenuID (menu));
- }
- }
-
- void invoke (const int commandId, ApplicationCommandManager* const commandManager, const int topLevelIndex) const
- {
- if (currentModel != 0)
- {
- if (commandManager != 0)
- {
- ApplicationCommandTarget::InvocationInfo info (commandId);
- info.invocationMethod = ApplicationCommandTarget::InvocationInfo::fromMenu;
-
- commandManager->invoke (info, true);
- }
-
- currentModel->menuItemSelected (commandId, topLevelIndex);
- }
- }
-
- MenuBarModel* currentModel;
-
- private:
- static MenuRef createMenu (const PopupMenu menu,
- const String& menuName,
- int& id,
- const int topLevelIndex)
- {
- MenuRef m = 0;
-
- if (CreateNewMenu (id++, kMenuAttrAutoDisable, &m) == noErr)
- {
- CFStringRef name = PlatformUtilities::juceStringToCFString (menuName);
- SetMenuTitleWithCFString (m, name);
- CFRelease (name);
-
- PopupMenu::MenuItemIterator iter (menu);
-
- while (iter.next())
- {
- MenuItemIndex index = 0;
-
- int flags = kMenuAttrAutoDisable | kMenuItemAttrIgnoreMeta | kMenuItemAttrNotPreviousAlternate;
- if (! iter.isEnabled)
- flags |= kMenuItemAttrDisabled;
-
- CFStringRef text = PlatformUtilities::juceStringToCFString (iter.itemName.upToFirstOccurrenceOf (T("<end>"), false, true));
-
- if (iter.isSeparator)
- {
- AppendMenuItemTextWithCFString (m, text, kMenuItemAttrSeparator, 0, &index);
- }
- else if (iter.isSectionHeader)
- {
- AppendMenuItemTextWithCFString (m, text, kMenuItemAttrSectionHeader, 0, &index);
- }
- else if (iter.subMenu != 0)
- {
- AppendMenuItemTextWithCFString (m, text, flags, id++, &index);
-
- MenuRef sub = createMenu (*iter.subMenu, iter.itemName, id, topLevelIndex);
- SetMenuItemHierarchicalMenu (m, index, sub);
- CFRelease (sub);
- }
- else
- {
- AppendMenuItemTextWithCFString (m, text, flags, iter.itemId, &index);
-
- if (iter.isTicked)
- CheckMenuItem (m, index, true);
-
- SetMenuItemProperty (m, index, 'juce', 'apcm', sizeof (void*), &iter.commandManager);
- SetMenuItemProperty (m, index, 'juce', 'topi', sizeof (int), &topLevelIndex);
-
- if (iter.commandManager != 0)
- {
- const Array <KeyPress> keyPresses (iter.commandManager->getKeyMappings()
- ->getKeyPressesAssignedToCommand (iter.itemId));
-
- if (keyPresses.size() > 0)
- {
- const KeyPress& kp = keyPresses.getReference(0);
- int mods = 0;
-
- if (kp.getModifiers().isShiftDown())
- mods |= kMenuShiftModifier;
- if (kp.getModifiers().isCtrlDown())
- mods |= kMenuControlModifier;
- if (kp.getModifiers().isAltDown())
- mods |= kMenuOptionModifier;
- if (! kp.getModifiers().isCommandDown())
- mods |= kMenuNoCommandModifier;
-
- tchar keyCode = (tchar) kp.getKeyCode();
-
- if (kp.getKeyCode() >= KeyPress::numberPad0
- && kp.getKeyCode() <= KeyPress::numberPad9)
- {
- keyCode = (tchar) ((T('0') - KeyPress::numberPad0) + kp.getKeyCode());
- }
-
- SetMenuItemCommandKey (m, index, true, 255);
-
- if (CharacterFunctions::isLetterOrDigit (keyCode)
- || CharacterFunctions::indexOfChar (T(",.;/\\'[]=-+_<>?{}\":"), keyCode, false) >= 0)
- {
- SetMenuItemModifiers (m, index, mods);
- SetMenuItemCommandKey (m, index, false, CharacterFunctions::toUpperCase (keyCode));
- }
- else
- {
- const SInt16 glyph = getGlyphForKeyCode (kp.getKeyCode());
-
- if (glyph != 0)
- {
- SetMenuItemModifiers (m, index, mods);
- SetMenuItemKeyGlyph (m, index, glyph);
- }
- }
-
- // if we set the key glyph to be a text char, and enable virtual
- // key triggering, it stops the menu automatically triggering the callback
- ChangeMenuItemAttributes (m, index, kMenuItemAttrUseVirtualKey, 0);
- }
- }
- }
-
- CFRelease (text);
- }
- }
-
- return m;
- }
-
- static SInt16 getGlyphForKeyCode (const int keyCode) throw()
- {
- if (keyCode == KeyPress::spaceKey)
- return kMenuSpaceGlyph;
- else if (keyCode == KeyPress::returnKey)
- return kMenuReturnGlyph;
- else if (keyCode == KeyPress::escapeKey)
- return kMenuEscapeGlyph;
- else if (keyCode == KeyPress::backspaceKey)
- return kMenuDeleteLeftGlyph;
- else if (keyCode == KeyPress::leftKey)
- return kMenuLeftArrowGlyph;
- else if (keyCode == KeyPress::rightKey)
- return kMenuRightArrowGlyph;
- else if (keyCode == KeyPress::upKey)
- return kMenuUpArrowGlyph;
- else if (keyCode == KeyPress::downKey)
- return kMenuDownArrowGlyph;
- else if (keyCode == KeyPress::pageUpKey)
- return kMenuPageUpGlyph;
- else if (keyCode == KeyPress::pageDownKey)
- return kMenuPageDownGlyph;
- else if (keyCode == KeyPress::endKey)
- return kMenuSoutheastArrowGlyph;
- else if (keyCode == KeyPress::homeKey)
- return kMenuNorthwestArrowGlyph;
- else if (keyCode == KeyPress::deleteKey)
- return kMenuDeleteRightGlyph;
- else if (keyCode == KeyPress::tabKey)
- return kMenuTabRightGlyph;
- else if (keyCode == KeyPress::F1Key)
- return kMenuF1Glyph;
- else if (keyCode == KeyPress::F2Key)
- return kMenuF2Glyph;
- else if (keyCode == KeyPress::F3Key)
- return kMenuF3Glyph;
- else if (keyCode == KeyPress::F4Key)
- return kMenuF4Glyph;
- else if (keyCode == KeyPress::F5Key)
- return kMenuF5Glyph;
- else if (keyCode == KeyPress::F6Key)
- return kMenuF6Glyph;
- else if (keyCode == KeyPress::F7Key)
- return kMenuF7Glyph;
- else if (keyCode == KeyPress::F8Key)
- return kMenuF8Glyph;
- else if (keyCode == KeyPress::F9Key)
- return kMenuF9Glyph;
- else if (keyCode == KeyPress::F10Key)
- return kMenuF10Glyph;
- else if (keyCode == KeyPress::F11Key)
- return kMenuF11Glyph;
- else if (keyCode == KeyPress::F12Key)
- return kMenuF12Glyph;
- else if (keyCode == KeyPress::F13Key)
- return kMenuF13Glyph;
- else if (keyCode == KeyPress::F14Key)
- return kMenuF14Glyph;
- else if (keyCode == KeyPress::F15Key)
- return kMenuF15Glyph;
-
- return 0;
- }
- };
-
- void MenuBarModel::setMacMainMenu (MenuBarModel* newMenuBarModel) throw()
- {
- if (getMacMainMenu() != newMenuBarModel)
- {
- if (newMenuBarModel == 0)
- {
- delete mainMenu;
- jassert (mainMenu == 0); // should be zeroed in the destructor
- }
- else
- {
- if (mainMenu == 0)
- mainMenu = new MainMenuHandler();
-
- mainMenu->setMenu (newMenuBarModel);
- }
- }
- }
-
- MenuBarModel* MenuBarModel::getMacMainMenu() throw()
- {
- return mainMenu != 0 ? mainMenu->currentModel : 0;
- }
-
- // these functions are called externally from the message handling code
- void juce_MainMenuAboutToBeUsed()
- {
- // force an update of the items just before the menu appears..
- if (mainMenu != 0)
- mainMenu->menuBarItemsChanged (0);
- }
-
- void juce_InvokeMainMenuCommand (const HICommand& command)
- {
- if (mainMenu != 0)
- {
- ApplicationCommandManager* commandManager = 0;
- int topLevelIndex = 0;
-
- if (GetMenuItemProperty (command.menu.menuRef, command.menu.menuItemIndex,
- 'juce', 'apcm', sizeof (commandManager), 0, &commandManager) == noErr
- && GetMenuItemProperty (command.menu.menuRef, command.menu.menuItemIndex,
- 'juce', 'topi', sizeof (topLevelIndex), 0, &topLevelIndex) == noErr)
- {
- mainMenu->invoke (command.commandID, commandManager, topLevelIndex);
- }
- }
- }
-
- void PlatformUtilities::beep()
- {
- SysBeep (30);
- }
-
- void SystemClipboard::copyTextToClipboard (const String& text) throw()
- {
- ClearCurrentScrap();
- ScrapRef ref;
- GetCurrentScrap (&ref);
-
- const int len = text.length();
- const int numBytes = sizeof (UniChar) * len;
- UniChar* const temp = (UniChar*) juce_calloc (numBytes);
-
- for (int i = 0; i < len; ++i)
- temp[i] = (UniChar) text[i];
-
- PutScrapFlavor (ref,
- kScrapFlavorTypeUnicode,
- kScrapFlavorMaskNone,
- numBytes,
- temp);
-
- juce_free (temp);
- }
-
- const String SystemClipboard::getTextFromClipboard() throw()
- {
- String result;
-
- ScrapRef ref;
- GetCurrentScrap (&ref);
- Size size = 0;
-
- if (GetScrapFlavorSize (ref, kScrapFlavorTypeUnicode, &size) == noErr
- && size > 0)
- {
- void* const data = juce_calloc (size + 8);
-
- if (GetScrapFlavorData (ref, kScrapFlavorTypeUnicode, &size, data) == noErr)
- {
- result = PlatformUtilities::convertUTF16ToString ((UniChar*) data);
- }
-
- juce_free (data);
- }
-
- return result;
- }
-
- bool AlertWindow::showNativeDialogBox (const String& title,
- const String& bodyText,
- bool isOkCancel)
- {
- Str255 tit, txt;
- PlatformUtilities::copyToStr255 (tit, title);
- PlatformUtilities::copyToStr255 (txt, bodyText);
-
- AlertStdAlertParamRec ar;
- ar.movable = true;
- ar.helpButton = false;
- ar.filterProc = 0;
- ar.defaultText = (const unsigned char*)-1;
- ar.cancelText = (const unsigned char*)((isOkCancel) ? -1 : 0);
- ar.otherText = 0;
- ar.defaultButton = kAlertStdAlertOKButton;
- ar.cancelButton = 0;
- ar.position = kWindowDefaultPosition;
-
- SInt16 result;
- StandardAlert (kAlertNoteAlert, tit, txt, &ar, &result);
- return result == kAlertStdAlertOKButton;
- }
-
- const int KeyPress::spaceKey = ' ';
- const int KeyPress::returnKey = kReturnCharCode;
- const int KeyPress::escapeKey = kEscapeCharCode;
- const int KeyPress::backspaceKey = kBackspaceCharCode;
- const int KeyPress::leftKey = kLeftArrowCharCode;
- const int KeyPress::rightKey = kRightArrowCharCode;
- const int KeyPress::upKey = kUpArrowCharCode;
- const int KeyPress::downKey = kDownArrowCharCode;
- const int KeyPress::pageUpKey = kPageUpCharCode;
- const int KeyPress::pageDownKey = kPageDownCharCode;
- const int KeyPress::endKey = kEndCharCode;
- const int KeyPress::homeKey = kHomeCharCode;
- const int KeyPress::deleteKey = kDeleteCharCode;
- const int KeyPress::insertKey = -1;
- const int KeyPress::tabKey = kTabCharCode;
- const int KeyPress::F1Key = 0x10110;
- const int KeyPress::F2Key = 0x10111;
- const int KeyPress::F3Key = 0x10112;
- const int KeyPress::F4Key = 0x10113;
- const int KeyPress::F5Key = 0x10114;
- const int KeyPress::F6Key = 0x10115;
- const int KeyPress::F7Key = 0x10116;
- const int KeyPress::F8Key = 0x10117;
- const int KeyPress::F9Key = 0x10118;
- const int KeyPress::F10Key = 0x10119;
- const int KeyPress::F11Key = 0x1011a;
- const int KeyPress::F12Key = 0x1011b;
- const int KeyPress::F13Key = 0x1011c;
- const int KeyPress::F14Key = 0x1011d;
- const int KeyPress::F15Key = 0x1011e;
- const int KeyPress::F16Key = 0x1011f;
- const int KeyPress::numberPad0 = 0x30020;
- const int KeyPress::numberPad1 = 0x30021;
- const int KeyPress::numberPad2 = 0x30022;
- const int KeyPress::numberPad3 = 0x30023;
- const int KeyPress::numberPad4 = 0x30024;
- const int KeyPress::numberPad5 = 0x30025;
- const int KeyPress::numberPad6 = 0x30026;
- const int KeyPress::numberPad7 = 0x30027;
- const int KeyPress::numberPad8 = 0x30028;
- const int KeyPress::numberPad9 = 0x30029;
- const int KeyPress::numberPadAdd = 0x3002a;
- const int KeyPress::numberPadSubtract = 0x3002b;
- const int KeyPress::numberPadMultiply = 0x3002c;
- const int KeyPress::numberPadDivide = 0x3002d;
- const int KeyPress::numberPadSeparator = 0x3002e;
- const int KeyPress::numberPadDecimalPoint = 0x3002f;
- const int KeyPress::numberPadEquals = 0x30030;
- const int KeyPress::numberPadDelete = 0x30031;
- const int KeyPress::playKey = 0x30000;
- const int KeyPress::stopKey = 0x30001;
- const int KeyPress::fastForwardKey = 0x30002;
- const int KeyPress::rewindKey = 0x30003;
-
- AppleRemoteDevice::AppleRemoteDevice()
- : device (0),
- queue (0),
- remoteId (0)
- {
- }
-
- AppleRemoteDevice::~AppleRemoteDevice()
- {
- stop();
- }
-
- static io_object_t getAppleRemoteDevice() throw()
- {
- CFMutableDictionaryRef dict = IOServiceMatching ("AppleIRController");
-
- io_iterator_t iter = 0;
- io_object_t iod = 0;
-
- if (IOServiceGetMatchingServices (kIOMasterPortDefault, dict, &iter) == kIOReturnSuccess
- && iter != 0)
- {
- iod = IOIteratorNext (iter);
- }
-
- IOObjectRelease (iter);
- return iod;
- }
-
- static bool createAppleRemoteInterface (io_object_t iod, void** device) throw()
- {
- jassert (*device == 0);
- io_name_t classname;
-
- if (IOObjectGetClass (iod, classname) == kIOReturnSuccess)
- {
- IOCFPlugInInterface** cfPlugInInterface = 0;
- SInt32 score = 0;
-
- if (IOCreatePlugInInterfaceForService (iod,
- kIOHIDDeviceUserClientTypeID,
- kIOCFPlugInInterfaceID,
- &cfPlugInInterface,
- &score) == kIOReturnSuccess)
- {
- HRESULT hr = (*cfPlugInInterface)->QueryInterface (cfPlugInInterface,
- CFUUIDGetUUIDBytes (kIOHIDDeviceInterfaceID),
- device);
-
- (void) hr;
-
- (*cfPlugInInterface)->Release (cfPlugInInterface);
- }
- }
-
- return *device != 0;
- }
-
- bool AppleRemoteDevice::start (const bool inExclusiveMode) throw()
- {
- if (queue != 0)
- return true;
-
- stop();
-
- bool result = false;
- io_object_t iod = getAppleRemoteDevice();
-
- if (iod != 0)
- {
- if (createAppleRemoteInterface (iod, &device) && open (inExclusiveMode))
- result = true;
- else
- stop();
-
- IOObjectRelease (iod);
- }
-
- return result;
- }
-
- void AppleRemoteDevice::stop() throw()
- {
- if (queue != 0)
- {
- (*(IOHIDQueueInterface**) queue)->stop ((IOHIDQueueInterface**) queue);
- (*(IOHIDQueueInterface**) queue)->dispose ((IOHIDQueueInterface**) queue);
- (*(IOHIDQueueInterface**) queue)->Release ((IOHIDQueueInterface**) queue);
- queue = 0;
- }
-
- if (device != 0)
- {
- (*(IOHIDDeviceInterface**) device)->close ((IOHIDDeviceInterface**) device);
- (*(IOHIDDeviceInterface**) device)->Release ((IOHIDDeviceInterface**) device);
- device = 0;
- }
- }
-
- bool AppleRemoteDevice::isActive() const throw()
- {
- return queue != 0;
- }
-
- static void appleRemoteQueueCallback (void* const target, const IOReturn result, void*, void*)
- {
- if (result == kIOReturnSuccess)
- ((AppleRemoteDevice*) target)->handleCallbackInternal();
- }
-
- bool AppleRemoteDevice::open (const bool openInExclusiveMode) throw()
- {
- #if ! MACOS_10_2_OR_EARLIER
- Array <int> cookies;
-
- CFArrayRef elements;
- IOHIDDeviceInterface122** const device122 = (IOHIDDeviceInterface122**) device;
-
- if ((*device122)->copyMatchingElements (device122, 0, &elements) != kIOReturnSuccess)
- return false;
-
- for (int i = 0; i < CFArrayGetCount (elements); ++i)
- {
- CFDictionaryRef element = (CFDictionaryRef) CFArrayGetValueAtIndex (elements, i);
-
- // get the cookie
- CFTypeRef object = CFDictionaryGetValue (element, CFSTR (kIOHIDElementCookieKey));
-
- if (object == 0 || CFGetTypeID (object) != CFNumberGetTypeID())
- continue;
-
- long number;
- if (! CFNumberGetValue ((CFNumberRef) object, kCFNumberLongType, &number))
- continue;
-
- cookies.add ((int) number);
- }
-
- CFRelease (elements);
-
- if ((*(IOHIDDeviceInterface**) device)
- ->open ((IOHIDDeviceInterface**) device,
- openInExclusiveMode ? kIOHIDOptionsTypeSeizeDevice
- : kIOHIDOptionsTypeNone) == KERN_SUCCESS)
- {
- queue = (*(IOHIDDeviceInterface**) device)->allocQueue ((IOHIDDeviceInterface**) device);
-
- if (queue != 0)
- {
- (*(IOHIDQueueInterface**) queue)->create ((IOHIDQueueInterface**) queue, 0, 12);
-
- for (int i = 0; i < cookies.size(); ++i)
- {
- IOHIDElementCookie cookie = (IOHIDElementCookie) cookies.getUnchecked(i);
- (*(IOHIDQueueInterface**) queue)->addElement ((IOHIDQueueInterface**) queue, cookie, 0);
- }
-
- CFRunLoopSourceRef eventSource;
-
- if ((*(IOHIDQueueInterface**) queue)
- ->createAsyncEventSource ((IOHIDQueueInterface**) queue, &eventSource) == KERN_SUCCESS)
- {
- if ((*(IOHIDQueueInterface**) queue)->setEventCallout ((IOHIDQueueInterface**) queue,
- appleRemoteQueueCallback, this, 0) == KERN_SUCCESS)
- {
- CFRunLoopAddSource (CFRunLoopGetCurrent(), eventSource, kCFRunLoopDefaultMode);
-
- (*(IOHIDQueueInterface**) queue)->start ((IOHIDQueueInterface**) queue);
-
- return true;
- }
- }
- }
- }
- #endif
-
- return false;
- }
-
- void AppleRemoteDevice::handleCallbackInternal()
- {
- int totalValues = 0;
- AbsoluteTime nullTime = { 0, 0 };
- char cookies [12];
- int numCookies = 0;
-
- while (numCookies < numElementsInArray (cookies))
- {
- IOHIDEventStruct e;
-
- if ((*(IOHIDQueueInterface**) queue)->getNextEvent ((IOHIDQueueInterface**) queue, &e, nullTime, 0) != kIOReturnSuccess)
- break;
-
- if ((int) e.elementCookie == 19)
- {
- remoteId = e.value;
- buttonPressed (switched, false);
- }
- else
- {
- totalValues += e.value;
- cookies [numCookies++] = (char) (pointer_sized_int) e.elementCookie;
- }
- }
-
- cookies [numCookies++] = 0;
-
- static const char buttonPatterns[] =
- {
- 14, 7, 6, 5, 14, 7, 6, 5, 0,
- 14, 8, 6, 5, 14, 8, 6, 5, 0,
- 14, 12, 11, 6, 5, 0,
- 14, 13, 11, 6, 5, 0,
- 14, 9, 6, 5, 14, 9, 6, 5, 0,
- 14, 10, 6, 5, 14, 10, 6, 5, 0,
- 14, 6, 5, 4, 2, 0,
- 14, 6, 5, 3, 2, 0,
- 14, 6, 5, 14, 6, 5, 0,
- 18, 14, 6, 5, 18, 14, 6, 5, 0,
- 19, 0
- };
-
- int buttonNum = (int) menuButton;
- int i = 0;
-
- while (i < numElementsInArray (buttonPatterns))
- {
- if (strcmp (cookies, buttonPatterns + i) == 0)
- {
- buttonPressed ((ButtonType) buttonNum, totalValues > 0);
- break;
- }
-
- i += strlen (buttonPatterns + i) + 1;
- ++buttonNum;
- }
- }
-
- #if JUCE_OPENGL
-
- class WindowedGLContext : public OpenGLContext
- {
- public:
- WindowedGLContext (Component* const component,
- const OpenGLPixelFormat& pixelFormat_,
- AGLContext sharedContext)
- : renderContext (0),
- pixelFormat (pixelFormat_)
- {
- jassert (component != 0);
-
- HIViewComponentPeer* const peer = dynamic_cast <HIViewComponentPeer*> (component->getTopLevelComponent()->getPeer());
- if (peer == 0)
- return;
-
- GLint attribs [64];
- int n = 0;
- attribs[n++] = AGL_RGBA;
- attribs[n++] = AGL_DOUBLEBUFFER;
- attribs[n++] = AGL_ACCELERATED;
- attribs[n++] = AGL_RED_SIZE;
- attribs[n++] = pixelFormat.redBits;
- attribs[n++] = AGL_GREEN_SIZE;
- attribs[n++] = pixelFormat.greenBits;
- attribs[n++] = AGL_BLUE_SIZE;
- attribs[n++] = pixelFormat.blueBits;
- attribs[n++] = AGL_ALPHA_SIZE;
- attribs[n++] = pixelFormat.alphaBits;
- attribs[n++] = AGL_DEPTH_SIZE;
- attribs[n++] = pixelFormat.depthBufferBits;
- attribs[n++] = AGL_STENCIL_SIZE;
- attribs[n++] = pixelFormat.stencilBufferBits;
- attribs[n++] = AGL_ACCUM_RED_SIZE;
- attribs[n++] = pixelFormat.accumulationBufferRedBits;
- attribs[n++] = AGL_ACCUM_GREEN_SIZE;
- attribs[n++] = pixelFormat.accumulationBufferGreenBits;
- attribs[n++] = AGL_ACCUM_BLUE_SIZE;
- attribs[n++] = pixelFormat.accumulationBufferBlueBits;
- attribs[n++] = AGL_ACCUM_ALPHA_SIZE;
- attribs[n++] = pixelFormat.accumulationBufferAlphaBits;
-
- // xxx not sure how to do fullSceneAntiAliasingNumSamples..
-
- attribs[n++] = AGL_SAMPLE_BUFFERS_ARB;
- attribs[n++] = 1;
- attribs[n++] = AGL_SAMPLES_ARB;
- attribs[n++] = 4;
- attribs[n++] = AGL_CLOSEST_POLICY;
- attribs[n++] = AGL_NO_RECOVERY;
- attribs[n++] = AGL_NONE;
-
- renderContext = aglCreateContext (aglChoosePixelFormat (0, 0, attribs),
- sharedContext);
-
- aglSetDrawable (renderContext, GetWindowPort (peer->windowRef));
- }
-
- ~WindowedGLContext()
- {
- makeInactive();
- aglSetDrawable (renderContext, 0);
- aglDestroyContext (renderContext);
- }
-
- bool makeActive() const throw()
- {
- jassert (renderContext != 0);
-
- return aglSetCurrentContext (renderContext);
- }
-
- bool makeInactive() const throw()
- {
- return (! isActive()) || aglSetCurrentContext (0);
- }
-
- bool isActive() const throw()
- {
- return aglGetCurrentContext() == renderContext;
- }
-
- const OpenGLPixelFormat getPixelFormat() const
- {
- return pixelFormat;
- }
-
- void* getRawContext() const throw()
- {
- return renderContext;
- }
-
- void updateWindowPosition (int x, int y, int w, int h, int outerWindowHeight)
- {
- GLint bufferRect[4];
- bufferRect[0] = x;
- bufferRect[1] = outerWindowHeight - (y + h);
- bufferRect[2] = w;
- bufferRect[3] = h;
-
- aglSetInteger (renderContext, AGL_BUFFER_RECT, bufferRect);
- aglEnable (renderContext, AGL_BUFFER_RECT);
- }
-
- void swapBuffers()
- {
- aglSwapBuffers (renderContext);
- }
-
- bool setSwapInterval (const int numFramesPerSwap)
- {
- return aglSetInteger (renderContext, AGL_SWAP_INTERVAL, (const GLint*) &numFramesPerSwap);
- }
-
- int getSwapInterval() const
- {
- GLint numFrames = 0;
- aglGetInteger (renderContext, AGL_SWAP_INTERVAL, &numFrames);
- return numFrames;
- }
-
- void repaint()
- {
- }
-
- juce_UseDebuggingNewOperator
-
- AGLContext renderContext;
-
- private:
- OpenGLPixelFormat pixelFormat;
-
- WindowedGLContext (const WindowedGLContext&);
- const WindowedGLContext& operator= (const WindowedGLContext&);
- };
-
- OpenGLContext* OpenGLContext::createContextForWindow (Component* const component,
- const OpenGLPixelFormat& pixelFormat,
- const OpenGLContext* const contextToShareWith)
- {
- WindowedGLContext* c = new WindowedGLContext (component, pixelFormat,
- contextToShareWith != 0 ? (AGLContext) contextToShareWith->getRawContext() : 0);
-
- if (c->renderContext == 0)
- deleteAndZero (c);
-
- return c;
- }
-
- void juce_glViewport (const int w, const int h)
- {
- glViewport (0, 0, w, h);
- }
-
- static int getAGLAttribute (AGLPixelFormat p, const GLint attrib)
- {
- GLint result = 0;
- aglDescribePixelFormat (p, attrib, &result);
- return result;
- }
-
- void OpenGLPixelFormat::getAvailablePixelFormats (Component* /*component*/,
- OwnedArray <OpenGLPixelFormat>& results)
- {
- GLint attribs [64];
- int n = 0;
- attribs[n++] = AGL_RGBA;
- attribs[n++] = AGL_DOUBLEBUFFER;
- attribs[n++] = AGL_ACCELERATED;
- attribs[n++] = AGL_NO_RECOVERY;
- attribs[n++] = AGL_NONE;
-
- AGLPixelFormat p = aglChoosePixelFormat (0, 0, attribs);
-
- while (p != 0)
- {
- OpenGLPixelFormat* const pf = new OpenGLPixelFormat();
- pf->redBits = getAGLAttribute (p, AGL_RED_SIZE);
- pf->greenBits = getAGLAttribute (p, AGL_GREEN_SIZE);
- pf->blueBits = getAGLAttribute (p, AGL_BLUE_SIZE);
- pf->alphaBits = getAGLAttribute (p, AGL_ALPHA_SIZE);
- pf->depthBufferBits = getAGLAttribute (p, AGL_DEPTH_SIZE);
- pf->stencilBufferBits = getAGLAttribute (p, AGL_STENCIL_SIZE);
- pf->accumulationBufferRedBits = getAGLAttribute (p, AGL_ACCUM_RED_SIZE);
- pf->accumulationBufferGreenBits = getAGLAttribute (p, AGL_ACCUM_GREEN_SIZE);
- pf->accumulationBufferBlueBits = getAGLAttribute (p, AGL_ACCUM_BLUE_SIZE);
- pf->accumulationBufferAlphaBits = getAGLAttribute (p, AGL_ACCUM_ALPHA_SIZE);
-
- results.add (pf);
-
- p = aglNextPixelFormat (p);
- }
- }
-
- #endif
-
- END_JUCE_NAMESPACE
- /********* End of inlined file: juce_mac_Windowing.mm *********/
-
- #endif
-
- #endif
|